aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2012-11-12 06:26:09 +0100
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2012-11-12 06:26:09 +0100
commit50de1043dc325c8e1adda94c6113607e741d4015 (patch)
tree46ffeb55fa3b5931bc1125858de6bf394487e5d4
parent59eb0628db77e1145db797406e4de9f97b70d8e2 (diff)
downloadsciteco-50de1043dc325c8e1adda94c6113607e741d4015.tar.gz
various arithmetic expression fixes: SUB must have higher precedence than ADD; fixed num_sign (unary minus) handling
-rw-r--r--expressions.cpp18
-rw-r--r--expressions.h2
-rw-r--r--parser.cpp2
3 files changed, 11 insertions, 11 deletions
diff --git a/expressions.cpp b/expressions.cpp
index 6999312..d9c5a1e 100644
--- a/expressions.cpp
+++ b/expressions.cpp
@@ -28,6 +28,11 @@ Expressions::push(gint64 number)
push(OP_NUMBER);
+ if (num_sign < 0) {
+ set_num_sign(1);
+ number *= -1;
+ }
+
numbers.undo_pop();
return numbers.push(number);
}
@@ -61,7 +66,7 @@ Expressions::add_digit(gchar digit)
{
gint64 n = args() > 0 ? pop_num() : 0;
- return push(n*radix + num_sign*(digit - '0'));
+ return push(n*radix + (n < 0 ? -1 : 1)*(digit - '0'));
}
Expressions::Operator
@@ -106,11 +111,7 @@ Expressions::calc(void)
gint64 vleft = pop_num();
switch (op) {
- case OP_POW:
- result = 1;
- while (vright--)
- result *= vleft;
- break;
+ 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;
@@ -129,14 +130,11 @@ Expressions::calc(void)
void
Expressions::eval(bool pop_brace)
{
- if (numbers.items() < 2)
- return;
-
for (;;) {
gint n = first_op();
Operator op;
- if (!n)
+ if (n < 2)
break;
op = operators.peek(n);
diff --git a/expressions.h b/expressions.h
index ef41b15..af501bb 100644
--- a/expressions.h
+++ b/expressions.h
@@ -114,8 +114,8 @@ public:
OP_MUL, // *
OP_DIV, // /
OP_MOD, // ^/
- OP_ADD, // +
OP_SUB, // -
+ OP_ADD, // +
OP_AND, // &
OP_OR, // #
// pseudo operators:
diff --git a/parser.cpp b/parser.cpp
index 6365277..f73bedd 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -412,6 +412,8 @@ StateStart::custom(gchar chr)
case '(':
BEGIN_EXEC(this);
if (expressions.num_sign < 0) {
+ expressions.set_num_sign(1);
+ expressions.eval();
expressions.push(-1);
expressions.push_calc(Expressions::OP_MUL);
}