Mercurial > hg-old > index.cgi
diff lwlib/lw_expr.c @ 387:a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
author | lost@l-w.ca |
---|---|
date | Wed, 14 Jul 2010 20:15:23 -0600 |
parents | eacdae8a1575 |
children | 67815606c5d9 |
line wrap: on
line diff
--- a/lwlib/lw_expr.c Sun May 16 13:03:17 2010 -0600 +++ b/lwlib/lw_expr.c Wed Jul 14 20:15:23 2010 -0600 @@ -49,6 +49,13 @@ return -1; } +int lw_expr_whichop(lw_expr_t e) +{ + if (e -> type == lw_expr_type_oper) + return e -> value; + return -1; +} + int lw_expr_specint(lw_expr_t e) { if (e -> type == lw_expr_type_special) @@ -198,7 +205,12 @@ struct lw_expr_opers *o; int c = 0; char buf[256]; - + + if (!E) + { + strcpy(buf, "(NULL)"); + return; + } for (o = E -> operands; o; o = o -> next) { c++; @@ -463,7 +475,9 @@ return 1; } -void lw_expr_simplify(lw_expr_t E, void *priv) +void lw_expr_simplify(lw_expr_t E, void *priv); + +void lw_expr_simplify_go(lw_expr_t E, void *priv) { struct lw_expr_opers *o; @@ -920,8 +934,80 @@ } return; } + + /* handle <int> times <plus> - expand the terms - only with exactly two operands */ + if (E -> value == lw_expr_oper_times) + { + lw_expr_t t1; + lw_expr_t E2; + lw_expr_t E3; + if (E -> operands && E -> operands -> next && !(E -> operands -> next -> next)) + { + if (E -> operands -> p -> type == lw_expr_type_int) + { + /* <int> TIMES <other> */ + E2 = E -> operands -> next -> p; + E3 = E -> operands -> p; + if (E2 -> type == lw_expr_type_oper && E2 -> value == lw_expr_oper_plus) + { + lw_free(E -> operands -> next); + lw_free(E -> operands); + E -> operands = NULL; + E -> value = lw_expr_oper_plus; + + for (o = E2 -> operands; o; o = o -> next) + { + t1 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_times, E3, o -> p); + lw_expr_add_operand(E, t1); + } + + lw_expr_destroy(E2); + lw_expr_destroy(E3); + } + } + else if (E -> operands -> next -> p -> type == lw_expr_type_int) + { + /* <other> TIMES <int> */ + E2 = E -> operands -> p; + E3 = E -> operands -> next -> p; + if (E2 -> type == lw_expr_type_oper && E2 -> value == lw_expr_oper_plus) + { + lw_free(E -> operands -> next); + lw_free(E -> operands); + E -> operands = NULL; + E -> value = lw_expr_oper_plus; + + for (o = E2 -> operands; o; o = o -> next) + { + t1 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_times, E3, o -> p); + lw_expr_add_operand(E, t1); + } + + lw_expr_destroy(E2); + lw_expr_destroy(E3); + } + } + } + } } +void lw_expr_simplify(lw_expr_t E, void *priv) +{ + lw_expr_t te; + int c; + do + { + te = lw_expr_copy(E); + lw_expr_simplify_go(E, priv); + c = 0; + if (lw_expr_compare(te, E) == 0) + c = 1; + lw_expr_destroy(te); + } + while (c); +} + + /* The following two functions are co-routines which evaluate an infix