2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
10 #define LKC_DIRECT_LINK
15 struct expr *expr_alloc_symbol(struct symbol *sym)
17 struct expr *e = malloc(sizeof(*e));
18 memset(e, 0, sizeof(*e));
24 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
26 struct expr *e = malloc(sizeof(*e));
27 memset(e, 0, sizeof(*e));
33 struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
35 struct expr *e = malloc(sizeof(*e));
36 memset(e, 0, sizeof(*e));
43 struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
45 struct expr *e = malloc(sizeof(*e));
46 memset(e, 0, sizeof(*e));
53 struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
57 return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
60 struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
64 return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
67 struct expr *expr_copy(struct expr *org)
74 e = malloc(sizeof(*org));
75 memcpy(e, org, sizeof(*org));
81 e->left.expr = expr_copy(org->left.expr);
85 e->left.sym = org->left.sym;
86 e->right.sym = org->right.sym;
91 e->left.expr = expr_copy(org->left.expr);
92 e->right.expr = expr_copy(org->right.expr);
95 printf("can't copy type %d\n", e->type);
104 void expr_free(struct expr *e)
113 expr_free(e->left.expr);
120 expr_free(e->left.expr);
121 expr_free(e->right.expr);
124 printf("how to free type %d?\n", e->type);
130 static int trans_count;
135 static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
137 if (e1->type == type) {
138 __expr_eliminate_eq(type, &e1->left.expr, &e2);
139 __expr_eliminate_eq(type, &e1->right.expr, &e2);
142 if (e2->type == type) {
143 __expr_eliminate_eq(type, &e1, &e2->left.expr);
144 __expr_eliminate_eq(type, &e1, &e2->right.expr);
147 if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
148 e1->left.sym == e2->left.sym &&
149 (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
151 if (!expr_eq(e1, e2))
154 expr_free(e1); expr_free(e2);
157 e1 = expr_alloc_symbol(&symbol_no);
158 e2 = expr_alloc_symbol(&symbol_no);
161 e1 = expr_alloc_symbol(&symbol_yes);
162 e2 = expr_alloc_symbol(&symbol_yes);
169 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
176 __expr_eliminate_eq(e1->type, ep1, ep2);
180 if (e1->type != e2->type) switch (e2->type) {
183 __expr_eliminate_eq(e2->type, ep1, ep2);
187 e1 = expr_eliminate_yn(e1);
188 e2 = expr_eliminate_yn(e2);
194 int expr_eq(struct expr *e1, struct expr *e2)
198 if (e1->type != e2->type)
203 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
205 return e1->left.sym == e2->left.sym;
207 return expr_eq(e1->left.expr, e2->left.expr);
212 old_count = trans_count;
213 expr_eliminate_eq(&e1, &e2);
214 res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
215 e1->left.sym == e2->left.sym);
218 trans_count = old_count;
227 expr_fprint(e1, stdout);
229 expr_fprint(e2, stdout);
236 struct expr *expr_eliminate_yn(struct expr *e)
240 if (e) switch (e->type) {
242 e->left.expr = expr_eliminate_yn(e->left.expr);
243 e->right.expr = expr_eliminate_yn(e->right.expr);
244 if (e->left.expr->type == E_SYMBOL) {
245 if (e->left.expr->left.sym == &symbol_no) {
246 expr_free(e->left.expr);
247 expr_free(e->right.expr);
249 e->left.sym = &symbol_no;
250 e->right.expr = NULL;
252 } else if (e->left.expr->left.sym == &symbol_yes) {
255 *e = *(e->right.expr);
260 if (e->right.expr->type == E_SYMBOL) {
261 if (e->right.expr->left.sym == &symbol_no) {
262 expr_free(e->left.expr);
263 expr_free(e->right.expr);
265 e->left.sym = &symbol_no;
266 e->right.expr = NULL;
268 } else if (e->right.expr->left.sym == &symbol_yes) {
271 *e = *(e->left.expr);
278 e->left.expr = expr_eliminate_yn(e->left.expr);
279 e->right.expr = expr_eliminate_yn(e->right.expr);
280 if (e->left.expr->type == E_SYMBOL) {
281 if (e->left.expr->left.sym == &symbol_no) {
284 *e = *(e->right.expr);
287 } else if (e->left.expr->left.sym == &symbol_yes) {
288 expr_free(e->left.expr);
289 expr_free(e->right.expr);
291 e->left.sym = &symbol_yes;
292 e->right.expr = NULL;
296 if (e->right.expr->type == E_SYMBOL) {
297 if (e->right.expr->left.sym == &symbol_no) {
300 *e = *(e->left.expr);
303 } else if (e->right.expr->left.sym == &symbol_yes) {
304 expr_free(e->left.expr);
305 expr_free(e->right.expr);
307 e->left.sym = &symbol_yes;
308 e->right.expr = NULL;
322 struct expr *expr_trans_bool(struct expr *e)
330 e->left.expr = expr_trans_bool(e->left.expr);
331 e->right.expr = expr_trans_bool(e->right.expr);
335 if (e->left.sym->type == S_TRISTATE) {
336 if (e->right.sym == &symbol_no) {
351 struct expr *expr_join_or(struct expr *e1, struct expr *e2)
354 struct symbol *sym1, *sym2;
357 return expr_copy(e1);
358 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
360 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
362 if (e1->type == E_NOT) {
364 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
366 sym1 = tmp->left.sym;
369 if (e2->type == E_NOT) {
370 if (e2->left.expr->type != E_SYMBOL)
372 sym2 = e2->left.expr->left.sym;
377 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
379 if (sym1->type == S_TRISTATE) {
380 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
381 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
382 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
383 // (a='y') || (a='m') -> (a!='n')
384 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
386 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
387 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
388 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
389 // (a='y') || (a='n') -> (a!='m')
390 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
392 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
393 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
394 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
395 // (a='m') || (a='n') -> (a!='y')
396 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
399 if (sym1->type == S_BOOLEAN && sym1 == sym2) {
400 if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
401 (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
402 return expr_alloc_symbol(&symbol_yes);
406 printf("optimize (");
407 expr_fprint(e1, stdout);
409 expr_fprint(e2, stdout);
415 struct expr *expr_join_and(struct expr *e1, struct expr *e2)
418 struct symbol *sym1, *sym2;
421 return expr_copy(e1);
422 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
424 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
426 if (e1->type == E_NOT) {
428 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
430 sym1 = tmp->left.sym;
433 if (e2->type == E_NOT) {
434 if (e2->left.expr->type != E_SYMBOL)
436 sym2 = e2->left.expr->left.sym;
441 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
444 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
445 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
446 // (a) && (a='y') -> (a='y')
447 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
449 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
450 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
451 // (a) && (a!='n') -> (a)
452 return expr_alloc_symbol(sym1);
454 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) ||
455 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod))
456 // (a) && (a!='m') -> (a='y')
457 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
459 if (sym1->type == S_TRISTATE) {
460 if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
461 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
462 sym2 = e1->right.sym;
463 if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
464 return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
465 : expr_alloc_symbol(&symbol_no);
467 if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
468 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
469 sym2 = e2->right.sym;
470 if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
471 return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
472 : expr_alloc_symbol(&symbol_no);
474 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
475 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
476 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
477 // (a!='y') && (a!='n') -> (a='m')
478 return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
480 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
481 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
482 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
483 // (a!='y') && (a!='m') -> (a='n')
484 return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
486 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
487 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
488 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
489 // (a!='m') && (a!='n') -> (a='m')
490 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
492 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
493 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
494 (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
495 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
500 printf("optimize (");
501 expr_fprint(e1, stdout);
503 expr_fprint(e2, stdout);
509 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
515 if (e1->type == type) {
516 expr_eliminate_dups1(type, &e1->left.expr, &e2);
517 expr_eliminate_dups1(type, &e1->right.expr, &e2);
520 if (e2->type == type) {
521 expr_eliminate_dups1(type, &e1, &e2->left.expr);
522 expr_eliminate_dups1(type, &e1, &e2->right.expr);
529 case E_OR: case E_AND:
530 expr_eliminate_dups1(e1->type, &e1, &e1);
537 tmp = expr_join_or(e1, e2);
539 expr_free(e1); expr_free(e2);
540 e1 = expr_alloc_symbol(&symbol_no);
546 tmp = expr_join_and(e1, e2);
548 expr_free(e1); expr_free(e2);
549 e1 = expr_alloc_symbol(&symbol_yes);
561 static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2)
565 struct expr *tmp, *tmp1, *tmp2;
567 if (e1->type == type) {
568 expr_eliminate_dups2(type, &e1->left.expr, &e2);
569 expr_eliminate_dups2(type, &e1->right.expr, &e2);
572 if (e2->type == type) {
573 expr_eliminate_dups2(type, &e1, &e2->left.expr);
574 expr_eliminate_dups2(type, &e1, &e2->right.expr);
581 expr_eliminate_dups2(e1->type, &e1, &e1);
582 // (FOO || BAR) && (!FOO && !BAR) -> n
583 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
584 tmp2 = expr_copy(e2);
585 tmp = expr_extract_eq_and(&tmp1, &tmp2);
586 if (expr_is_yes(tmp1)) {
588 e1 = expr_alloc_symbol(&symbol_no);
596 expr_eliminate_dups2(e1->type, &e1, &e1);
597 // (FOO && BAR) || (!FOO || !BAR) -> y
598 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
599 tmp2 = expr_copy(e2);
600 tmp = expr_extract_eq_or(&tmp1, &tmp2);
601 if (expr_is_no(tmp1)) {
603 e1 = expr_alloc_symbol(&symbol_yes);
617 struct expr *expr_eliminate_dups(struct expr *e)
623 oldcount = trans_count;
627 case E_OR: case E_AND:
628 expr_eliminate_dups1(e->type, &e, &e);
629 expr_eliminate_dups2(e->type, &e, &e);
635 e = expr_eliminate_yn(e);
637 trans_count = oldcount;
641 struct expr *expr_transform(struct expr *e)
654 e->left.expr = expr_transform(e->left.expr);
655 e->right.expr = expr_transform(e->right.expr);
660 if (e->left.sym->type != S_BOOLEAN)
662 if (e->right.sym == &symbol_no) {
664 e->left.expr = expr_alloc_symbol(e->left.sym);
668 if (e->right.sym == &symbol_mod) {
669 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
671 e->left.sym = &symbol_no;
675 if (e->right.sym == &symbol_yes) {
682 if (e->left.sym->type != S_BOOLEAN)
684 if (e->right.sym == &symbol_no) {
689 if (e->right.sym == &symbol_mod) {
690 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
692 e->left.sym = &symbol_yes;
696 if (e->right.sym == &symbol_yes) {
698 e->left.expr = expr_alloc_symbol(e->left.sym);
704 switch (e->left.expr->type) {
707 tmp = e->left.expr->left.expr;
711 e = expr_transform(e);
719 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
722 // !(a || b) -> !a && !b
725 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
727 tmp->right.expr = NULL;
728 e = expr_transform(e);
731 // !(a && b) -> !a || !b
734 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
736 tmp->right.expr = NULL;
737 e = expr_transform(e);
740 if (e->left.expr->left.sym == &symbol_yes) {
746 e->left.sym = &symbol_no;
749 if (e->left.expr->left.sym == &symbol_mod) {
755 e->left.sym = &symbol_mod;
758 if (e->left.expr->left.sym == &symbol_no) {
764 e->left.sym = &symbol_yes;
778 int expr_contains_symbol(struct expr *dep, struct symbol *sym)
786 return expr_contains_symbol(dep->left.expr, sym) ||
787 expr_contains_symbol(dep->right.expr, sym);
789 return dep->left.sym == sym;
792 return dep->left.sym == sym ||
793 dep->right.sym == sym;
795 return expr_contains_symbol(dep->left.expr, sym);
802 bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
809 return expr_depends_symbol(dep->left.expr, sym) ||
810 expr_depends_symbol(dep->right.expr, sym);
812 return dep->left.sym == sym;
814 if (dep->left.sym == sym) {
815 if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
820 if (dep->left.sym == sym) {
821 if (dep->right.sym == &symbol_no)
831 struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
833 struct expr *tmp = NULL;
834 expr_extract_eq(E_AND, &tmp, ep1, ep2);
836 *ep1 = expr_eliminate_yn(*ep1);
837 *ep2 = expr_eliminate_yn(*ep2);
842 struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
844 struct expr *tmp = NULL;
845 expr_extract_eq(E_OR, &tmp, ep1, ep2);
847 *ep1 = expr_eliminate_yn(*ep1);
848 *ep2 = expr_eliminate_yn(*ep2);
853 void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
857 if (e1->type == type) {
858 expr_extract_eq(type, ep, &e1->left.expr, &e2);
859 expr_extract_eq(type, ep, &e1->right.expr, &e2);
862 if (e2->type == type) {
863 expr_extract_eq(type, ep, ep1, &e2->left.expr);
864 expr_extract_eq(type, ep, ep1, &e2->right.expr);
867 if (expr_eq(e1, e2)) {
868 *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
871 e1 = expr_alloc_symbol(&symbol_yes);
872 e2 = expr_alloc_symbol(&symbol_yes);
873 } else if (type == E_OR) {
874 e1 = expr_alloc_symbol(&symbol_no);
875 e2 = expr_alloc_symbol(&symbol_no);
882 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
884 struct expr *e1, *e2;
887 e = expr_alloc_symbol(sym);
888 if (type == E_UNEQUAL)
889 e = expr_alloc_one(E_NOT, e);
894 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
895 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
896 if (sym == &symbol_yes)
897 e = expr_alloc_two(E_AND, e1, e2);
898 if (sym == &symbol_no)
899 e = expr_alloc_two(E_OR, e1, e2);
900 if (type == E_UNEQUAL)
901 e = expr_alloc_one(E_NOT, e);
904 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
905 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
906 if (sym == &symbol_yes)
907 e = expr_alloc_two(E_OR, e1, e2);
908 if (sym == &symbol_no)
909 e = expr_alloc_two(E_AND, e1, e2);
910 if (type == E_UNEQUAL)
911 e = expr_alloc_one(E_NOT, e);
914 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
917 if (type == E_EQUAL) {
918 if (sym == &symbol_yes)
920 if (sym == &symbol_mod)
921 return expr_alloc_symbol(&symbol_no);
922 if (sym == &symbol_no)
923 return expr_alloc_one(E_NOT, expr_copy(e));
925 if (sym == &symbol_yes)
926 return expr_alloc_one(E_NOT, expr_copy(e));
927 if (sym == &symbol_mod)
928 return expr_alloc_symbol(&symbol_yes);
929 if (sym == &symbol_no)
934 return expr_alloc_comp(type, e->left.sym, sym);
943 tristate expr_calc_value(struct expr *e)
946 const char *str1, *str2;
953 sym_calc_value(e->left.sym);
954 return e->left.sym->curr.tri;
956 val1 = expr_calc_value(e->left.expr);
957 val2 = expr_calc_value(e->right.expr);
958 return EXPR_AND(val1, val2);
960 val1 = expr_calc_value(e->left.expr);
961 val2 = expr_calc_value(e->right.expr);
962 return EXPR_OR(val1, val2);
964 val1 = expr_calc_value(e->left.expr);
965 return EXPR_NOT(val1);
967 sym_calc_value(e->left.sym);
968 sym_calc_value(e->right.sym);
969 str1 = sym_get_string_value(e->left.sym);
970 str2 = sym_get_string_value(e->right.sym);
971 return !strcmp(str1, str2) ? yes : no;
973 sym_calc_value(e->left.sym);
974 sym_calc_value(e->right.sym);
975 str1 = sym_get_string_value(e->left.sym);
976 str2 = sym_get_string_value(e->right.sym);
977 return !strcmp(str1, str2) ? no : yes;
979 printf("expr_calc_value: %d?\n", e->type);
984 int expr_compare_type(enum expr_type t1, enum expr_type t2)
1011 printf("[%dgt%d?]", t1, t2);
1016 void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
1019 fn(data, NULL, "y");
1023 if (expr_compare_type(prevtoken, e->type) > 0)
1024 fn(data, NULL, "(");
1027 if (e->left.sym->name)
1028 fn(data, e->left.sym, e->left.sym->name);
1030 fn(data, NULL, "<choice>");
1033 fn(data, NULL, "!");
1034 expr_print(e->left.expr, fn, data, E_NOT);
1037 fn(data, e->left.sym, e->left.sym->name);
1038 fn(data, NULL, "=");
1039 fn(data, e->right.sym, e->right.sym->name);
1042 fn(data, e->left.sym, e->left.sym->name);
1043 fn(data, NULL, "!=");
1044 fn(data, e->right.sym, e->right.sym->name);
1047 expr_print(e->left.expr, fn, data, E_OR);
1048 fn(data, NULL, " || ");
1049 expr_print(e->right.expr, fn, data, E_OR);
1052 expr_print(e->left.expr, fn, data, E_AND);
1053 fn(data, NULL, " && ");
1054 expr_print(e->right.expr, fn, data, E_AND);
1057 fn(data, e->right.sym, e->right.sym->name);
1059 fn(data, NULL, " ^ ");
1060 expr_print(e->left.expr, fn, data, E_CHOICE);
1064 fn(data, NULL, "[");
1065 fn(data, e->left.sym, e->left.sym->name);
1066 fn(data, NULL, " ");
1067 fn(data, e->right.sym, e->right.sym->name);
1068 fn(data, NULL, "]");
1073 sprintf(buf, "<unknown type %d>", e->type);
1074 fn(data, NULL, buf);
1078 if (expr_compare_type(prevtoken, e->type) > 0)
1079 fn(data, NULL, ")");
1082 static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
1084 fwrite(str, strlen(str), 1, data);
1087 void expr_fprint(struct expr *e, FILE *out)
1089 expr_print(e, expr_print_file_helper, out, E_NONE);
1092 static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
1094 str_append((struct gstr*)data, str);
1097 void expr_gstr_print(struct expr *e, struct gstr *gs)
1099 expr_print(e, expr_print_gstr_helper, gs, E_NONE);