Mercurial > hg > dmlib
changeset 692:391310cfba26
Fix & precedence vs +.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 16 Apr 2013 17:28:32 +0300 |
parents | e7663dd15eea |
children | 837ad9dcc348 |
files | dmeval.c tests/testeval.sh |
diffstat | 2 files changed, 61 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/dmeval.c Tue Apr 16 17:05:38 2013 +0300 +++ b/dmeval.c Tue Apr 16 17:28:32 2013 +0300 @@ -883,24 +883,59 @@ node = NULL; break; - case OP_ADD: - case OP_SUB: - case OP_AND: - case OP_XOR: - case OP_OR: - - case OP_VAR: - case OP_CONST: + default: if (dm_eval_push_node(&list, node) == NULL) return -32; node = node->next; break; + } + else + if (pass == 2) + switch (node->op) + { + case OP_ADD: + // Pop previous node, f.e. 5*3 -> 5 + if ((tmp = dm_eval_pop_node(&list)) == NULL) + return -24; + + // Add subexpression node + if ((sub = dm_eval_add_node(&list, OP_SUBEXPR)) == NULL) + return -3; + + // Add popped node into subexpression + dm_eval_push_node(&(sub->subexpr), tmp); + + // Add this operator into subexpression + dm_eval_add_node(&(sub->subexpr), node->op); + + // Next node + node = node->next; + if (node == NULL) + return -72; + + if (node->op == OP_FUNC || node->op == OP_SUBEXPR) + { + // It's a function or sub-expression + if ((tmp = dm_eval_push_node(&(sub->subexpr), node)) == NULL) + return -178; + + if ((res = dm_eval_reorder_do(ev, node->subexpr, &(tmp->subexpr), pass)) != 0) + return res; + } + else + dm_eval_push_node(&(sub->subexpr), node); + + node = node->next; + break; default: - dm_eval_err(ev, "Invalid opcode %d in node %p.\n", node->op, node); - return -4; + if (dm_eval_push_node(&list, node) == NULL) + return -32; + + node = node->next; + break; } } @@ -911,13 +946,16 @@ int dm_eval_reorder(DMEvalContext *ev, DMEvalNode *node, DMEvalNode **result) { - DMEvalNode *tmp = NULL; + DMEvalNode *tmp = NULL, *tmp2 = NULL; int res; if ((res = dm_eval_reorder_do(ev, node, &tmp, 0)) != 0) return res; - return dm_eval_reorder_do(ev, tmp, result, 1); + if ((res = dm_eval_reorder_do(ev, tmp, &tmp2, 1)) != 0) + return res; + + return dm_eval_reorder_do(ev, tmp2, result, 2); }
--- a/tests/testeval.sh Tue Apr 16 17:05:38 2013 +0300 +++ b/tests/testeval.sh Tue Apr 16 17:28:32 2013 +0300 @@ -16,6 +16,11 @@ 3 * -1 + 5 << 1 7 + 3 << 2 * 3 7 * 3 << 4 - 3 +127&127 + 12&3 +1+3*5&7 +35&3 + 2 +9+5&(3 + 7) +(5*(7&3) + 1) " | while read f; do if test "x$f" != "x"; then printf "#include <stdio.h>\nint main(int argc, char *argv[])\n{\n (void) argc; (void) argv;\n printf(\"%%1.5f\\\\n\", (double) (%s));\n return 0;\n}\n" "$f" > "$CTEST.c" @@ -28,6 +33,12 @@ echo "RESULT MISMATCH: '$f'" echo " C test: $RES1" echo " eval: $RES2" + cat "$CTEST.c" + elif test "x$1" != "x"; then + echo "---------------------------------------------" + echo "FORMULA: '$f'" + echo " C test: $RES1" + echo " eval: $RES2" fi fi fi