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