Mercurial > hg-old > index.cgi
comparison 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 |
comparison
equal
deleted
inserted
replaced
386:af5f2c51db76 | 387:a741d2e4869f |
---|---|
43 } | 43 } |
44 | 44 |
45 int lw_expr_intval(lw_expr_t e) | 45 int lw_expr_intval(lw_expr_t e) |
46 { | 46 { |
47 if (e -> type == lw_expr_type_int) | 47 if (e -> type == lw_expr_type_int) |
48 return e -> value; | |
49 return -1; | |
50 } | |
51 | |
52 int lw_expr_whichop(lw_expr_t e) | |
53 { | |
54 if (e -> type == lw_expr_type_oper) | |
48 return e -> value; | 55 return e -> value; |
49 return -1; | 56 return -1; |
50 } | 57 } |
51 | 58 |
52 int lw_expr_specint(lw_expr_t e) | 59 int lw_expr_specint(lw_expr_t e) |
196 void lw_expr_print_aux(lw_expr_t E, char **obuf, int *buflen, int *bufloc) | 203 void lw_expr_print_aux(lw_expr_t E, char **obuf, int *buflen, int *bufloc) |
197 { | 204 { |
198 struct lw_expr_opers *o; | 205 struct lw_expr_opers *o; |
199 int c = 0; | 206 int c = 0; |
200 char buf[256]; | 207 char buf[256]; |
201 | 208 |
209 if (!E) | |
210 { | |
211 strcpy(buf, "(NULL)"); | |
212 return; | |
213 } | |
202 for (o = E -> operands; o; o = o -> next) | 214 for (o = E -> operands; o; o = o -> next) |
203 { | 215 { |
204 c++; | 216 c++; |
205 lw_expr_print_aux(o -> p, obuf, buflen, bufloc); | 217 lw_expr_print_aux(o -> p, obuf, buflen, bufloc); |
206 } | 218 } |
461 if (!lw_expr_compare(e1, e2)) | 473 if (!lw_expr_compare(e1, e2)) |
462 return 0; | 474 return 0; |
463 return 1; | 475 return 1; |
464 } | 476 } |
465 | 477 |
466 void lw_expr_simplify(lw_expr_t E, void *priv) | 478 void lw_expr_simplify(lw_expr_t E, void *priv); |
479 | |
480 void lw_expr_simplify_go(lw_expr_t E, void *priv) | |
467 { | 481 { |
468 struct lw_expr_opers *o; | 482 struct lw_expr_opers *o; |
469 | 483 |
470 // replace subtraction with O1 + -1(O2)... | 484 // replace subtraction with O1 + -1(O2)... |
471 // needed for like term collection | 485 // needed for like term collection |
918 } | 932 } |
919 } | 933 } |
920 } | 934 } |
921 return; | 935 return; |
922 } | 936 } |
923 } | 937 |
938 /* handle <int> times <plus> - expand the terms - only with exactly two operands */ | |
939 if (E -> value == lw_expr_oper_times) | |
940 { | |
941 lw_expr_t t1; | |
942 lw_expr_t E2; | |
943 lw_expr_t E3; | |
944 if (E -> operands && E -> operands -> next && !(E -> operands -> next -> next)) | |
945 { | |
946 if (E -> operands -> p -> type == lw_expr_type_int) | |
947 { | |
948 /* <int> TIMES <other> */ | |
949 E2 = E -> operands -> next -> p; | |
950 E3 = E -> operands -> p; | |
951 if (E2 -> type == lw_expr_type_oper && E2 -> value == lw_expr_oper_plus) | |
952 { | |
953 lw_free(E -> operands -> next); | |
954 lw_free(E -> operands); | |
955 E -> operands = NULL; | |
956 E -> value = lw_expr_oper_plus; | |
957 | |
958 for (o = E2 -> operands; o; o = o -> next) | |
959 { | |
960 t1 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_times, E3, o -> p); | |
961 lw_expr_add_operand(E, t1); | |
962 } | |
963 | |
964 lw_expr_destroy(E2); | |
965 lw_expr_destroy(E3); | |
966 } | |
967 } | |
968 else if (E -> operands -> next -> p -> type == lw_expr_type_int) | |
969 { | |
970 /* <other> TIMES <int> */ | |
971 E2 = E -> operands -> p; | |
972 E3 = E -> operands -> next -> p; | |
973 if (E2 -> type == lw_expr_type_oper && E2 -> value == lw_expr_oper_plus) | |
974 { | |
975 lw_free(E -> operands -> next); | |
976 lw_free(E -> operands); | |
977 E -> operands = NULL; | |
978 E -> value = lw_expr_oper_plus; | |
979 | |
980 for (o = E2 -> operands; o; o = o -> next) | |
981 { | |
982 t1 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_times, E3, o -> p); | |
983 lw_expr_add_operand(E, t1); | |
984 } | |
985 | |
986 lw_expr_destroy(E2); | |
987 lw_expr_destroy(E3); | |
988 } | |
989 } | |
990 } | |
991 } | |
992 } | |
993 | |
994 void lw_expr_simplify(lw_expr_t E, void *priv) | |
995 { | |
996 lw_expr_t te; | |
997 int c; | |
998 do | |
999 { | |
1000 te = lw_expr_copy(E); | |
1001 lw_expr_simplify_go(E, priv); | |
1002 c = 0; | |
1003 if (lw_expr_compare(te, E) == 0) | |
1004 c = 1; | |
1005 lw_expr_destroy(te); | |
1006 } | |
1007 while (c); | |
1008 } | |
1009 | |
924 | 1010 |
925 /* | 1011 /* |
926 | 1012 |
927 The following two functions are co-routines which evaluate an infix | 1013 The following two functions are co-routines which evaluate an infix |
928 expression. lw_expr_parse_term checks for unary prefix operators then, if | 1014 expression. lw_expr_parse_term checks for unary prefix operators then, if |