diff options
| -rw-r--r-- | src/displayapp/screens/Calculator.cpp | 37 |
1 files changed, 14 insertions, 23 deletions
diff --git a/src/displayapp/screens/Calculator.cpp b/src/displayapp/screens/Calculator.cpp index c0a947d..c44f781 100644 --- a/src/displayapp/screens/Calculator.cpp +++ b/src/displayapp/screens/Calculator.cpp @@ -10,11 +10,8 @@ using namespace Pinetime::Applications::Screens; // Anonymous Namespace for all the structs namespace { - struct Node { - char op; - double val; - }; - template <typename X, uint8_t max_stack_len> struct StaticallyAllocatedStack { + template <typename X, uint8_t max_stack_len> struct Stack { + // Basic stack data type without dynamic allocations X data[max_stack_len]; uint8_t stack_len = 0; inline auto size() { return stack_len; } @@ -25,8 +22,13 @@ namespace { inline X& push() { return data[stack_len++]; } inline void push(X x) { X& datum{ push() }; datum = x; } }; - template <uint8_t max_stack_len> struct CalcStack : public StaticallyAllocatedStack<Node, max_stack_len> { - typedef StaticallyAllocatedStack<Node, max_stack_len> Super; + struct Node { + // if op == 0, the node represents a double value, otherwise it's an operator + char op; + double val; + }; + template <uint8_t max_stack_len> struct CalcStack : public Stack<Node, max_stack_len> { + typedef Stack<Node, max_stack_len> Super; inline Node& push() { return Super::push(); } inline void pushValue(double value) { Super::data[Super::stack_len].op = 0; @@ -37,6 +39,8 @@ namespace { Node* node0 = Super::data + Super::stack_len; node0->op = op; if (Super::stack_len > 1) { + // Evaluate subexpressions as soon as it's possible + // Inf and NaN take care of error handling in case of non-finite results Node* node1 = node0 - 1; if (node1->op == 0) { Node* node2 = node1 - 1; @@ -73,7 +77,7 @@ namespace { } }; - template <typename I, typename F, typename S> bool parseFloat(I& i, F& f, S& s) { + template <typename Input, typename Float, typename Sign> bool parseFloat(Input& i, Float& f, Sign& s) { f = 0; int8_t dot_position = -1; while (!i.empty()) { @@ -171,12 +175,12 @@ Calculator::Calculator(DisplayApp* app, Controllers::MotorController& motorContr } void Calculator::Eval() { - StaticallyAllocatedStack<char, 32> input; + Stack<char, 32> input; for (int8_t i = position - 1; i >= 0; i--) { input.push(text[i]); } CalcStack<16> output; - StaticallyAllocatedStack<char, 32> operators; + Stack<char, 32> operators; bool expectingNumber = true; int8_t sign = +1; double resultFloat; @@ -284,18 +288,6 @@ void Calculator::Eval() { } // perform the calculation resultFloat = output.top().val; -#if 0 - // This only seems to work in the simulator - if (!std::isfinite(resultFloat)) { - goto eval_error; - } - position = 0; - for (char s : std::to_string(resultFloat)) { - text[position++] = s; - } - text[position] = 0; -#else - // position = snprintf(text, 20, "%.9g", resultFloat); // make sure that the absolute value of the integral part of result fits in a 32 bit unsigned integer sign = (resultFloat < 0); if (sign) { @@ -326,7 +318,6 @@ void Calculator::Eval() { position--; } } -#endif return; eval_error: motorController.RunForDuration(10); |
