diff options
Diffstat (limited to 'expressions.cpp')
-rw-r--r-- | expressions.cpp | 201 |
1 files changed, 0 insertions, 201 deletions
diff --git a/expressions.cpp b/expressions.cpp deleted file mode 100644 index ac06b43..0000000 --- a/expressions.cpp +++ /dev/null @@ -1,201 +0,0 @@ -#include <glib.h> - -#include "sciteco.h" -#include "undo.h" -#include "expressions.h" - -Expressions expressions; - -void -Expressions::set_num_sign(gint sign) -{ - undo.push_var<gint>(num_sign); - num_sign = sign; -} - -void -Expressions::set_radix(gint r) -{ - undo.push_var<gint>(radix); - radix = r; -} - -gint64 -Expressions::push(gint64 number) -{ - while (operators.items() && operators.peek() == OP_NEW) - pop_op(); - - push(OP_NUMBER); - - if (num_sign < 0) { - set_num_sign(1); - number *= -1; - } - - numbers.undo_pop(); - return numbers.push(number); -} - -gint64 -Expressions::pop_num(int index) -{ - gint64 n = 0; - - pop_op(); - if (numbers.items() > 0) { - n = numbers.pop(index); - numbers.undo_push(n, index); - } - - return n; -} - -gint64 -Expressions::pop_num_calc(int index, gint64 imply) -{ - eval(); - if (num_sign < 0) - set_num_sign(1); - - return args() > 0 ? pop_num(index) : imply; -} - -gint64 -Expressions::add_digit(gchar digit) -{ - gint64 n = args() > 0 ? pop_num() : 0; - - return push(n*radix + (n < 0 ? -1 : 1)*(digit - '0')); -} - -Expressions::Operator -Expressions::push(Expressions::Operator op) -{ - operators.undo_pop(); - return operators.push(op); -} - -Expressions::Operator -Expressions::push_calc(Expressions::Operator op) -{ - int first = first_op(); - - /* calculate if op has lower precedence than op on stack */ - if (first && operators.peek(first) <= op) - calc(); - - return push(op); -} - -Expressions::Operator -Expressions::pop_op(int index) -{ - Operator op = OP_NIL; - - if (operators.items() > 0) { - op = operators.pop(index); - operators.undo_push(op, index); - } - - return op; -} - -void -Expressions::calc(void) -{ - gint64 result; - - gint64 vright = pop_num(); - Operator op = pop_op(); - gint64 vleft = pop_num(); - - switch (op) { - case OP_POW: for (result = 1; vright--; result *= vleft); break; - case OP_MUL: result = vleft * vright; break; - case OP_DIV: result = vleft / vright; break; - case OP_MOD: result = vleft % vright; break; - case OP_ADD: result = vleft + vright; break; - case OP_SUB: result = vleft - vright; break; - case OP_AND: result = vleft & vright; break; - case OP_OR: result = vleft | vright; break; - default: - /* shouldn't happen */ - g_assert(false); - } - - push(result); -} - -void -Expressions::eval(bool pop_brace) -{ - for (;;) { - gint n = first_op(); - Operator op; - - if (n < 2) - break; - - op = operators.peek(n); - if (op == OP_LOOP) - break; - if (op == OP_BRACE) { - if (pop_brace) - pop_op(n); - break; - } - - calc(); - } -} - -int -Expressions::args(void) -{ - int n = 0; - int items = operators.items(); - - while (n < items && operators.peek(n+1) == OP_NUMBER) - n++; - - return n; -} - -int -Expressions::find_op(Operator op) -{ - int items = operators.items(); - - for (int i = 1; i <= items; i++) - if (operators.peek(i) == op) - return i; - - return 0; -} - -int -Expressions::first_op(void) -{ - int items = operators.items(); - - for (int i = 1; i <= items; i++) { - switch (operators.peek(i)) { - case OP_NUMBER: - case OP_NEW: - break; - default: - return i; - } - } - - return 0; -} - -void -Expressions::discard_args(void) -{ - eval(); - for (int i = args(); i; i--) - pop_num_calc(); -} |