aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/expressions.c
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 /src/expressions.c
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.
Diffstat (limited to 'src/expressions.c')
-rw-r--r--src/expressions.c16
1 files changed, 10 insertions, 6 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;