diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-05-22 22:10:57 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-05-22 22:10:57 +0000 |
commit | 7f085e8bf5f5bdf0cc2b8e39123db7bfa9a0742a (patch) | |
tree | 5d811c1ccb0979361b493117ffaf6b841d8337a2 /NxWidgets/nxwm/src/chexcalculator.cxx | |
parent | 91f53fd2a857714c794e0ccc6d8c91c79f41684a (diff) | |
download | nuttx-7f085e8bf5f5bdf0cc2b8e39123db7bfa9a0742a.tar.gz nuttx-7f085e8bf5f5bdf0cc2b8e39123db7bfa9a0742a.tar.bz2 nuttx-7f085e8bf5f5bdf0cc2b8e39123db7bfa9a0742a.zip |
Add some minimal support for precedence of operations
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4762 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'NxWidgets/nxwm/src/chexcalculator.cxx')
-rw-r--r-- | NxWidgets/nxwm/src/chexcalculator.cxx | 181 |
1 files changed, 121 insertions, 60 deletions
diff --git a/NxWidgets/nxwm/src/chexcalculator.cxx b/NxWidgets/nxwm/src/chexcalculator.cxx index 48409f4d9..d865817b9 100644 --- a/NxWidgets/nxwm/src/chexcalculator.cxx +++ b/NxWidgets/nxwm/src/chexcalculator.cxx @@ -213,11 +213,13 @@ CHexCalculator::CHexCalculator(CTaskbar *taskbar, CApplicationWindow *window) // Reset other values - m_operand = 0; // No previously entered operand - m_accum = 0; // The accumulator is initially zero - m_memory = 0; // No value in memory - m_pending = (uint8_t)KEY_NONE; // No pending operation */ - m_hexMode = 0; // Decimal mode + m_accum = 0; // The accumulator is initially zero + m_memory = 0; // No value in memory + m_high.operation = (uint8_t)KEY_NONE; // No pending high precedence operation + m_high.value = 0; + m_low.operation = (uint8_t)KEY_NONE; // No pending high precedence operation + m_low.value = 0; + m_hexMode = 0; // Decimal mode // Add our personalized window label @@ -585,6 +587,55 @@ void CHexCalculator::labelKeypad(void) } /** + * Evaluate a binary operation. The result is left in m_accum. + * + * @param value1. The first value + * @param value2. The second value + * + * @return The result of the operation + */ + +int64_t CHexCalculator::evaluateBinaryOperation(uint8_t operation, int64_t value1, int64_t value2) +{ + switch (operation) + { + case KEY_NONE: // Do nothing if there is no pending operation + return 0; + + case KEY_XOR: // Exclusive OR + return value1 ^ value2; + + case KEY_DIVIDE: // Division + return value1 / value2; + + case KEY_RSH: // Right shift + return value1 >> value2; + + case KEY_LSH: // Left shift + return value1 << value2; + + case KEY_MULTIPLY: // Multiplication + return value1 * value2; + + case KEY_AND: // Bit-wise AND + return value1 & value2; + + case KEY_OR: // Bit-wise OR + return value1 | value2; + + case KEY_MINUS: // Subtraction + return value1 - value2; + + case KEY_PLUS: // Additions + return value1 + value2; + + default: + gdbg("ERROR: Unexpected pending operation %d\n", m_pending); + return 0; + } +} + +/** * Show the current value of the accumulator. */ @@ -692,78 +743,86 @@ void CHexCalculator::handleActionEvent(const NXWidgets::CWidgetEventArgs &e) } break; - // Binary operators + // Low precedence Binary operators case KEY_XOR: // Exclusive OR - case KEY_DIVIDE: // Division - case KEY_RSH: // Right shift - case KEY_LSH: // Left shift - case KEY_MULTIPLY: // Multiplication - case KEY_AND: // Bit-wise AND case KEY_OR: // Bit-wise OR case KEY_MINUS: // Subtraction case KEY_PLUS: // Additions { - m_operand = m_accum; - m_accum = 0; - m_pending = g_keyDesc[index].keyType; + // Is there a high precedence operation? + + if (m_high.operation != (uint8_t)KEY_NONE) + { + m_accum = evaluateBinaryOperation(m_high.operation, m_high.value, m_accum); + m_high.operation = (uint8_t)KEY_NONE; + m_high.value = 0; + } + + // Is there a pending low precedence operation? + + if (m_low.operation != (uint8_t)KEY_NONE) + { + m_accum = evaluateBinaryOperation(m_low.operation, m_low.value, m_accum); + } + + // Save the new low precedence operation + + m_low.operation = (uint8_t) g_keyDesc[index].keyType; + m_low.value = m_accum; + m_accum = 0; + updateText(); } break; - // Special operations - - case KEY_EQUAL: // Equal/Enter key - { - switch (m_pending) - { - case KEY_NONE: // Do nothing if there is no pending operation - return; + // High precedence Binary operators - case KEY_XOR: // Exclusive OR - m_accum ^= m_operand; - break; - - case KEY_DIVIDE: // Division - m_accum = m_operand / m_accum; - break; + case KEY_DIVIDE: // Division + case KEY_RSH: // Right shift + case KEY_LSH: // Left shift + case KEY_MULTIPLY: // Multiplication + case KEY_AND: // Bit-wise AND + { + // Is there a high precedence operation? - case KEY_RSH: // Right shift - m_accum = m_operand >> m_accum; - break; + if (m_high.operation != (uint8_t)KEY_NONE) + { + m_accum = evaluateBinaryOperation(m_high.operation, m_high.value, m_accum); + } - case KEY_LSH: // Left shift - m_accum = m_operand << m_accum; - break; + // Save the new high precedence operation - case KEY_MULTIPLY: // Multiplication - m_accum *= m_operand; - break; + m_high.operation = (uint8_t) g_keyDesc[index].keyType; + m_high.value = m_accum; + m_accum = 0; - case KEY_AND: // Bit-wise AND - m_accum &= m_operand; - break; + updateText(); + } + break; - case KEY_OR: // Bit-wise OR - m_accum |= m_operand; - break; + // Special operations + + case KEY_EQUAL: // Equal/Enter key + { + // Is there a high precedence operation? - case KEY_MINUS: // Subtraction - m_accum = m_operand - m_accum; - break; + if (m_high.operation != (uint8_t)KEY_NONE) + { + m_accum = evaluateBinaryOperation(m_high.operation, m_high.value, m_accum); + m_high.operation = (uint8_t)KEY_NONE; + m_high.value = 0; + } - case KEY_PLUS: // Additions - m_accum += m_operand; - break; + // Is there a pending low precedence operation? - default: - gdbg("ERROR: Unexpected pending operation %d\n", m_pending); - m_pending = KEY_NONE; - return; + if (m_low.operation != (uint8_t)KEY_NONE) + { + m_accum = evaluateBinaryOperation(m_low.operation, m_low.value, m_accum); + m_low.operation = (uint8_t)KEY_NONE; + m_low.value = 0; } - - m_operand = 0; - m_pending = KEY_NONE; + updateText(); } break; @@ -824,9 +883,11 @@ void CHexCalculator::handleActionEvent(const NXWidgets::CWidgetEventArgs &e) case KEY_CLR: // Clear all { - m_accum = 0; - m_operand = 0; - m_pending = KEY_NONE; + m_accum = 0; + m_high.operation = (uint8_t)KEY_NONE; + m_high.value = 0; + m_low.operation = (uint8_t)KEY_NONE; + m_low.value = 0; updateText(); } break; |