aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2024-11-25 23:15:43 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2024-11-25 23:15:43 +0300
commit8490013e558386d5584cbaba610268adad4ddd89 (patch)
tree53e9dee83287fd8be4809fc79b58610e6409a8a3
parent88d65fb8b736a8b3aa2b4c85e5517095a1134a49 (diff)
downloadsciteco-8490013e558386d5584cbaba610268adad4ddd89.tar.gz
fixed operator precedence application (fixup 5597bc72671d0128e6f0dba446c4dc8d47bf37d0)
* Using teco_expressions_eval() is wrong since it does not pay attention to precedences. If you have multiple higher precedence operators in a row, as in 2+3*4*5, the lower precedence operators would be resolved prematurely. * Instead we now call teco_expressions_calc() repeatedly but only for lower precedence operators on the stack top. This makes sure that as much of the expression as possible is evaluated at any given moment.
-rw-r--r--src/expressions.c16
-rw-r--r--tests/testsuite.at3
2 files changed, 12 insertions, 7 deletions
diff --git a/src/expressions.c b/src/expressions.c
index 8f9b2cd..63d3b2f 100644
--- a/src/expressions.c
+++ b/src/expressions.c
@@ -140,13 +140,17 @@ teco_expressions_push_op(teco_operator_t op)
gboolean
teco_expressions_push_calc(teco_operator_t op, GError **error)
{
- gint first = teco_expressions_first_op();
+ for (;;) {
+ gint first = teco_expressions_first_op();
- /* calculate if op has lower precedence than op on stack */
- if (first >= 0 &&
- teco_expressions_precedence(op) <= teco_expressions_precedence(teco_expressions_peek_op(first)) &&
- !teco_expressions_eval(FALSE, error))
- return FALSE;
+ /* calculate if op has lower precedence than op on stack */
+ if (first < 0 ||
+ teco_expressions_precedence(op) > teco_expressions_precedence(teco_expressions_peek_op(first)))
+ break;
+
+ if (!teco_expressions_calc(error))
+ return FALSE;
+ }
teco_expressions_push_op(op);
return TRUE;
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 74df3a0..44d1711 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -53,9 +53,10 @@ AT_CHECK([$SCITECO -e '+23='], 1, ignore, ignore)
AT_CLEANUP
AT_SETUP([Operator precedence])
+AT_CHECK([$SCITECO -e "(10-2-3)-5\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "(1-6*5)+29\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "(1-6*5-1)+30\"N(0/0)'"], 0, ignore, ignore)
-AT_CHECK([$SCITECO -e "(1-6*5-1*2)+31\"N(0/0)'"], 0, ignore, ignore)
+AT_CHECK([$SCITECO -e "(1-6*5-1*2*2)+33\"N(0/0)'"], 0, ignore, ignore)
AT_CLEANUP
AT_SETUP([Closing loops at the correct macro level])