2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
14 static int expr_eq(struct expr *e1, struct expr *e2);
15 static struct expr *expr_eliminate_yn(struct expr *e);
17 struct expr *expr_alloc_symbol(struct symbol *sym)
19 struct expr *e = xcalloc(1, sizeof(*e));
25 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
27 struct expr *e = xcalloc(1, sizeof(*e));
33 struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
35 struct expr *e = xcalloc(1, sizeof(*e));
42 struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
44 struct expr *e = xcalloc(1, sizeof(*e));
51 struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
55 return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
58 struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
62 return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
65 struct expr *expr_copy(const struct expr *org)
72 e = xmalloc(sizeof(*org));
73 memcpy(e, org, sizeof(*org));
79 e->left.expr = expr_copy(org->left.expr);
87 e->left.sym = org->left.sym;
88 e->right.sym = org->right.sym;
93 e->left.expr = expr_copy(org->left.expr);
94 e->right.expr = expr_copy(org->right.expr);
97 fprintf(stderr, "can't copy type %d\n", e->type);
106 void expr_free(struct expr *e)
115 expr_free(e->left.expr);
126 expr_free(e->left.expr);
127 expr_free(e->right.expr);
130 fprintf(stderr, "how to free type %d?\n", e->type);
136 static int trans_count;
142 * expr_eliminate_eq() helper.
144 * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
145 * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
146 * against all other leaves. Two equal leaves are both replaced with either 'y'
147 * or 'n' as appropriate for 'type', to be eliminated later.
149 static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
151 /* Recurse down to leaves */
153 if (e1->type == type) {
154 __expr_eliminate_eq(type, &e1->left.expr, &e2);
155 __expr_eliminate_eq(type, &e1->right.expr, &e2);
158 if (e2->type == type) {
159 __expr_eliminate_eq(type, &e1, &e2->left.expr);
160 __expr_eliminate_eq(type, &e1, &e2->right.expr);
164 /* e1 and e2 are leaves. Compare them. */
166 if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
167 e1->left.sym == e2->left.sym &&
168 (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
170 if (!expr_eq(e1, e2))
173 /* e1 and e2 are equal leaves. Prepare them for elimination. */
176 expr_free(e1); expr_free(e2);
179 e1 = expr_alloc_symbol(&symbol_no);
180 e2 = expr_alloc_symbol(&symbol_no);
183 e1 = expr_alloc_symbol(&symbol_yes);
184 e2 = expr_alloc_symbol(&symbol_yes);
192 * Rewrites the expressions 'ep1' and 'ep2' to remove operands common to both.
193 * Example reductions:
195 * ep1: A && B -> ep1: y
196 * ep2: A && B && C -> ep2: C
198 * ep1: A || B -> ep1: n
199 * ep2: A || B || C -> ep2: C
201 * ep1: A && (B && FOO) -> ep1: FOO
202 * ep2: (BAR && B) && A -> ep2: BAR
204 * ep1: A && (B || C) -> ep1: y
205 * ep2: (C || B) && A -> ep2: y
207 * Comparisons are done between all operands at the same "level" of && or ||.
208 * For example, in the expression 'e1 && (e2 || e3) && (e4 || e5)', the
209 * following operands will be compared:
211 * - 'e1', 'e2 || e3', and 'e4 || e5', against each other
215 * Parentheses are irrelevant within a single level. 'e1 && (e2 && e3)' and
216 * '(e1 && e2) && e3' are both a single level.
218 * See __expr_eliminate_eq() as well.
220 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
227 __expr_eliminate_eq(e1->type, ep1, ep2);
231 if (e1->type != e2->type) switch (e2->type) {
234 __expr_eliminate_eq(e2->type, ep1, ep2);
238 e1 = expr_eliminate_yn(e1);
239 e2 = expr_eliminate_yn(e2);
246 * Returns true if 'e1' and 'e2' are equal, after minor simplification. Two
247 * &&/|| expressions are considered equal if every operand in one expression
248 * equals some operand in the other (operands do not need to appear in the same
249 * order), recursively.
251 static int expr_eq(struct expr *e1, struct expr *e2)
256 * A NULL expr is taken to be yes, but there's also a different way to
257 * represent yes. expr_is_yes() checks for either representation.
260 return expr_is_yes(e1) && expr_is_yes(e2);
262 if (e1->type != e2->type)
271 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
273 return e1->left.sym == e2->left.sym;
275 return expr_eq(e1->left.expr, e2->left.expr);
280 old_count = trans_count;
281 expr_eliminate_eq(&e1, &e2);
282 res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
283 e1->left.sym == e2->left.sym);
286 trans_count = old_count;
295 expr_fprint(e1, stdout);
297 expr_fprint(e2, stdout);
305 * Recursively performs the following simplifications in-place (as well as the
306 * corresponding simplifications with swapped operands):
313 * Returns the optimized expression.
315 static struct expr *expr_eliminate_yn(struct expr *e)
319 if (e) switch (e->type) {
321 e->left.expr = expr_eliminate_yn(e->left.expr);
322 e->right.expr = expr_eliminate_yn(e->right.expr);
323 if (e->left.expr->type == E_SYMBOL) {
324 if (e->left.expr->left.sym == &symbol_no) {
325 expr_free(e->left.expr);
326 expr_free(e->right.expr);
328 e->left.sym = &symbol_no;
329 e->right.expr = NULL;
331 } else if (e->left.expr->left.sym == &symbol_yes) {
334 *e = *(e->right.expr);
339 if (e->right.expr->type == E_SYMBOL) {
340 if (e->right.expr->left.sym == &symbol_no) {
341 expr_free(e->left.expr);
342 expr_free(e->right.expr);
344 e->left.sym = &symbol_no;
345 e->right.expr = NULL;
347 } else if (e->right.expr->left.sym == &symbol_yes) {
350 *e = *(e->left.expr);
357 e->left.expr = expr_eliminate_yn(e->left.expr);
358 e->right.expr = expr_eliminate_yn(e->right.expr);
359 if (e->left.expr->type == E_SYMBOL) {
360 if (e->left.expr->left.sym == &symbol_no) {
363 *e = *(e->right.expr);
366 } else if (e->left.expr->left.sym == &symbol_yes) {
367 expr_free(e->left.expr);
368 expr_free(e->right.expr);
370 e->left.sym = &symbol_yes;
371 e->right.expr = NULL;
375 if (e->right.expr->type == E_SYMBOL) {
376 if (e->right.expr->left.sym == &symbol_no) {
379 *e = *(e->left.expr);
382 } else if (e->right.expr->left.sym == &symbol_yes) {
383 expr_free(e->left.expr);
384 expr_free(e->right.expr);
386 e->left.sym = &symbol_yes;
387 e->right.expr = NULL;
401 struct expr *expr_trans_bool(struct expr *e)
409 e->left.expr = expr_trans_bool(e->left.expr);
410 e->right.expr = expr_trans_bool(e->right.expr);
414 if (e->left.sym->type == S_TRISTATE) {
415 if (e->right.sym == &symbol_no) {
430 static struct expr *expr_join_or(struct expr *e1, struct expr *e2)
433 struct symbol *sym1, *sym2;
436 return expr_copy(e1);
437 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
439 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
441 if (e1->type == E_NOT) {
443 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
445 sym1 = tmp->left.sym;
448 if (e2->type == E_NOT) {
449 if (e2->left.expr->type != E_SYMBOL)
451 sym2 = e2->left.expr->left.sym;
456 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
458 if (sym1->type == S_TRISTATE) {
459 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
460 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
461 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
462 // (a='y') || (a='m') -> (a!='n')
463 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
465 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
466 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
467 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
468 // (a='y') || (a='n') -> (a!='m')
469 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
471 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
472 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
473 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
474 // (a='m') || (a='n') -> (a!='y')
475 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
478 if (sym1->type == S_BOOLEAN && sym1 == sym2) {
479 if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
480 (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
481 return expr_alloc_symbol(&symbol_yes);
485 printf("optimize (");
486 expr_fprint(e1, stdout);
488 expr_fprint(e2, stdout);
494 static struct expr *expr_join_and(struct expr *e1, struct expr *e2)
497 struct symbol *sym1, *sym2;
500 return expr_copy(e1);
501 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
503 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
505 if (e1->type == E_NOT) {
507 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
509 sym1 = tmp->left.sym;
512 if (e2->type == E_NOT) {
513 if (e2->left.expr->type != E_SYMBOL)
515 sym2 = e2->left.expr->left.sym;
520 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
523 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
524 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
525 // (a) && (a='y') -> (a='y')
526 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
528 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
529 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
530 // (a) && (a!='n') -> (a)
531 return expr_alloc_symbol(sym1);
533 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) ||
534 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod))
535 // (a) && (a!='m') -> (a='y')
536 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
538 if (sym1->type == S_TRISTATE) {
539 if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
540 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
541 sym2 = e1->right.sym;
542 if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
543 return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
544 : expr_alloc_symbol(&symbol_no);
546 if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
547 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
548 sym2 = e2->right.sym;
549 if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
550 return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
551 : expr_alloc_symbol(&symbol_no);
553 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
554 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
555 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
556 // (a!='y') && (a!='n') -> (a='m')
557 return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
559 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
560 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
561 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
562 // (a!='y') && (a!='m') -> (a='n')
563 return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
565 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
566 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
567 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
568 // (a!='m') && (a!='n') -> (a='m')
569 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
571 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
572 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
573 (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
574 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
579 printf("optimize (");
580 expr_fprint(e1, stdout);
582 expr_fprint(e2, stdout);
589 * expr_eliminate_dups() helper.
591 * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
592 * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
593 * against all other leaves to look for simplifications.
595 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
601 /* Recurse down to leaves */
603 if (e1->type == type) {
604 expr_eliminate_dups1(type, &e1->left.expr, &e2);
605 expr_eliminate_dups1(type, &e1->right.expr, &e2);
608 if (e2->type == type) {
609 expr_eliminate_dups1(type, &e1, &e2->left.expr);
610 expr_eliminate_dups1(type, &e1, &e2->right.expr);
614 /* e1 and e2 are leaves. Compare and process them. */
620 case E_OR: case E_AND:
621 expr_eliminate_dups1(e1->type, &e1, &e1);
628 tmp = expr_join_or(e1, e2);
630 expr_free(e1); expr_free(e2);
631 e1 = expr_alloc_symbol(&symbol_no);
637 tmp = expr_join_and(e1, e2);
639 expr_free(e1); expr_free(e2);
640 e1 = expr_alloc_symbol(&symbol_yes);
653 * Rewrites 'e' in-place to remove ("join") duplicate and other redundant
656 * Example simplifications:
658 * A || B || A -> A || B
659 * A && B && A=y -> A=y && B
661 * Returns the deduplicated expression.
663 struct expr *expr_eliminate_dups(struct expr *e)
669 oldcount = trans_count;
673 case E_OR: case E_AND:
674 expr_eliminate_dups1(e->type, &e, &e);
679 /* No simplifications done in this pass. We're done */
681 e = expr_eliminate_yn(e);
683 trans_count = oldcount;
688 * Performs various simplifications involving logical operators and
691 * Allocates and returns a new expression.
693 struct expr *expr_transform(struct expr *e)
710 e->left.expr = expr_transform(e->left.expr);
711 e->right.expr = expr_transform(e->right.expr);
716 if (e->left.sym->type != S_BOOLEAN)
718 if (e->right.sym == &symbol_no) {
720 e->left.expr = expr_alloc_symbol(e->left.sym);
724 if (e->right.sym == &symbol_mod) {
725 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
727 e->left.sym = &symbol_no;
731 if (e->right.sym == &symbol_yes) {
738 if (e->left.sym->type != S_BOOLEAN)
740 if (e->right.sym == &symbol_no) {
745 if (e->right.sym == &symbol_mod) {
746 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
748 e->left.sym = &symbol_yes;
752 if (e->right.sym == &symbol_yes) {
754 e->left.expr = expr_alloc_symbol(e->left.sym);
760 switch (e->left.expr->type) {
763 tmp = e->left.expr->left.expr;
767 e = expr_transform(e);
775 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
783 e->type = e->type == E_LEQ ? E_GTH : E_LTH;
791 e->type = e->type == E_LTH ? E_GEQ : E_LEQ;
794 // !(a || b) -> !a && !b
797 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
799 tmp->right.expr = NULL;
800 e = expr_transform(e);
803 // !(a && b) -> !a || !b
806 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
808 tmp->right.expr = NULL;
809 e = expr_transform(e);
812 if (e->left.expr->left.sym == &symbol_yes) {
818 e->left.sym = &symbol_no;
821 if (e->left.expr->left.sym == &symbol_mod) {
827 e->left.sym = &symbol_mod;
830 if (e->left.expr->left.sym == &symbol_no) {
836 e->left.sym = &symbol_yes;
850 int expr_contains_symbol(struct expr *dep, struct symbol *sym)
858 return expr_contains_symbol(dep->left.expr, sym) ||
859 expr_contains_symbol(dep->right.expr, sym);
861 return dep->left.sym == sym;
868 return dep->left.sym == sym ||
869 dep->right.sym == sym;
871 return expr_contains_symbol(dep->left.expr, sym);
878 bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
885 return expr_depends_symbol(dep->left.expr, sym) ||
886 expr_depends_symbol(dep->right.expr, sym);
888 return dep->left.sym == sym;
890 if (dep->left.sym == sym) {
891 if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
896 if (dep->left.sym == sym) {
897 if (dep->right.sym == &symbol_no)
908 * Inserts explicit comparisons of type 'type' to symbol 'sym' into the
911 * Examples transformations for type == E_UNEQUAL, sym == &symbol_no:
915 * A && B -> !(A=n || B=n)
916 * A || B -> !(A=n && B=n)
917 * A && (B || C) -> !(A=n || (B=n && C=n))
919 * Allocates and returns a new expression.
921 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
923 struct expr *e1, *e2;
926 e = expr_alloc_symbol(sym);
927 if (type == E_UNEQUAL)
928 e = expr_alloc_one(E_NOT, e);
933 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
934 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
935 if (sym == &symbol_yes)
936 e = expr_alloc_two(E_AND, e1, e2);
937 if (sym == &symbol_no)
938 e = expr_alloc_two(E_OR, e1, e2);
939 if (type == E_UNEQUAL)
940 e = expr_alloc_one(E_NOT, e);
943 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
944 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
945 if (sym == &symbol_yes)
946 e = expr_alloc_two(E_OR, e1, e2);
947 if (sym == &symbol_no)
948 e = expr_alloc_two(E_AND, e1, e2);
949 if (type == E_UNEQUAL)
950 e = expr_alloc_one(E_NOT, e);
953 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
960 if (type == E_EQUAL) {
961 if (sym == &symbol_yes)
963 if (sym == &symbol_mod)
964 return expr_alloc_symbol(&symbol_no);
965 if (sym == &symbol_no)
966 return expr_alloc_one(E_NOT, expr_copy(e));
968 if (sym == &symbol_yes)
969 return expr_alloc_one(E_NOT, expr_copy(e));
970 if (sym == &symbol_mod)
971 return expr_alloc_symbol(&symbol_yes);
972 if (sym == &symbol_no)
977 return expr_alloc_comp(type, e->left.sym, sym);
986 enum string_value_kind {
994 unsigned long long u;
998 static enum string_value_kind expr_parse_string(const char *str,
999 enum symbol_type type,
1000 union string_value *val)
1003 enum string_value_kind kind;
1009 val->s = !strcmp(str, "n") ? 0 :
1010 !strcmp(str, "m") ? 1 :
1011 !strcmp(str, "y") ? 2 : -1;
1014 val->s = strtoll(str, &tail, 10);
1018 val->u = strtoull(str, &tail, 16);
1023 val->s = strtoll(str, &tail, 0);
1029 return !errno && !*tail && tail > str && isxdigit(tail[-1])
1033 tristate expr_calc_value(struct expr *e)
1035 tristate val1, val2;
1036 const char *str1, *str2;
1037 enum string_value_kind k1 = k_string, k2 = k_string;
1038 union string_value lval = {}, rval = {};
1046 sym_calc_value(e->left.sym);
1047 return e->left.sym->curr.tri;
1049 val1 = expr_calc_value(e->left.expr);
1050 val2 = expr_calc_value(e->right.expr);
1051 return EXPR_AND(val1, val2);
1053 val1 = expr_calc_value(e->left.expr);
1054 val2 = expr_calc_value(e->right.expr);
1055 return EXPR_OR(val1, val2);
1057 val1 = expr_calc_value(e->left.expr);
1058 return EXPR_NOT(val1);
1067 printf("expr_calc_value: %d?\n", e->type);
1071 sym_calc_value(e->left.sym);
1072 sym_calc_value(e->right.sym);
1073 str1 = sym_get_string_value(e->left.sym);
1074 str2 = sym_get_string_value(e->right.sym);
1076 if (e->left.sym->type != S_STRING || e->right.sym->type != S_STRING) {
1077 k1 = expr_parse_string(str1, e->left.sym->type, &lval);
1078 k2 = expr_parse_string(str2, e->right.sym->type, &rval);
1081 if (k1 == k_string || k2 == k_string)
1082 res = strcmp(str1, str2);
1083 else if (k1 == k_invalid || k2 == k_invalid) {
1084 if (e->type != E_EQUAL && e->type != E_UNEQUAL) {
1085 printf("Cannot compare \"%s\" and \"%s\"\n", str1, str2);
1088 res = strcmp(str1, str2);
1089 } else if (k1 == k_unsigned || k2 == k_unsigned)
1090 res = (lval.u > rval.u) - (lval.u < rval.u);
1091 else /* if (k1 == k_signed && k2 == k_signed) */
1092 res = (lval.s > rval.s) - (lval.s < rval.s);
1096 return res ? no : yes;
1098 return res >= 0 ? yes : no;
1100 return res > 0 ? yes : no;
1102 return res <= 0 ? yes : no;
1104 return res < 0 ? yes : no;
1106 return res ? yes : no;
1108 printf("expr_calc_value: relation %d?\n", e->type);
1113 static int expr_compare_type(enum expr_type t1, enum expr_type t2)
1122 if (t2 == E_EQUAL || t2 == E_UNEQUAL)
1143 printf("[%dgt%d?]", t1, t2);
1147 void expr_print(struct expr *e,
1148 void (*fn)(void *, struct symbol *, const char *),
1149 void *data, int prevtoken)
1152 fn(data, NULL, "y");
1156 if (expr_compare_type(prevtoken, e->type) > 0)
1157 fn(data, NULL, "(");
1160 if (e->left.sym->name)
1161 fn(data, e->left.sym, e->left.sym->name);
1163 fn(data, NULL, "<choice>");
1166 fn(data, NULL, "!");
1167 expr_print(e->left.expr, fn, data, E_NOT);
1170 if (e->left.sym->name)
1171 fn(data, e->left.sym, e->left.sym->name);
1173 fn(data, NULL, "<choice>");
1174 fn(data, NULL, "=");
1175 fn(data, e->right.sym, e->right.sym->name);
1179 if (e->left.sym->name)
1180 fn(data, e->left.sym, e->left.sym->name);
1182 fn(data, NULL, "<choice>");
1183 fn(data, NULL, e->type == E_LEQ ? "<=" : "<");
1184 fn(data, e->right.sym, e->right.sym->name);
1188 if (e->left.sym->name)
1189 fn(data, e->left.sym, e->left.sym->name);
1191 fn(data, NULL, "<choice>");
1192 fn(data, NULL, e->type == E_GEQ ? ">=" : ">");
1193 fn(data, e->right.sym, e->right.sym->name);
1196 if (e->left.sym->name)
1197 fn(data, e->left.sym, e->left.sym->name);
1199 fn(data, NULL, "<choice>");
1200 fn(data, NULL, "!=");
1201 fn(data, e->right.sym, e->right.sym->name);
1204 expr_print(e->left.expr, fn, data, E_OR);
1205 fn(data, NULL, " || ");
1206 expr_print(e->right.expr, fn, data, E_OR);
1209 expr_print(e->left.expr, fn, data, E_AND);
1210 fn(data, NULL, " && ");
1211 expr_print(e->right.expr, fn, data, E_AND);
1214 fn(data, e->right.sym, e->right.sym->name);
1216 fn(data, NULL, " ^ ");
1217 expr_print(e->left.expr, fn, data, E_LIST);
1221 fn(data, NULL, "[");
1222 fn(data, e->left.sym, e->left.sym->name);
1223 fn(data, NULL, " ");
1224 fn(data, e->right.sym, e->right.sym->name);
1225 fn(data, NULL, "]");
1230 sprintf(buf, "<unknown type %d>", e->type);
1231 fn(data, NULL, buf);
1235 if (expr_compare_type(prevtoken, e->type) > 0)
1236 fn(data, NULL, ")");
1239 static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
1241 xfwrite(str, strlen(str), 1, data);
1244 void expr_fprint(struct expr *e, FILE *out)
1246 expr_print(e, expr_print_file_helper, out, E_NONE);
1249 static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
1251 struct gstr *gs = (struct gstr*)data;
1252 const char *sym_str = NULL;
1255 sym_str = sym_get_string_value(sym);
1257 if (gs->max_width) {
1258 unsigned extra_length = strlen(str);
1259 const char *last_cr = strrchr(gs->s, '\n');
1260 unsigned last_line_length;
1263 extra_length += 4 + strlen(sym_str);
1268 last_line_length = strlen(gs->s) - (last_cr - gs->s);
1270 if ((last_line_length + extra_length) > gs->max_width)
1271 str_append(gs, "\\\n");
1274 str_append(gs, str);
1275 if (sym && sym->type != S_UNKNOWN)
1276 str_printf(gs, " [=%s]", sym_str);
1279 void expr_gstr_print(struct expr *e, struct gstr *gs)
1281 expr_print(e, expr_print_gstr_helper, gs, E_NONE);
1285 * Transform the top level "||" tokens into newlines and prepend each
1286 * line with a minus. This makes expressions much easier to read.
1287 * Suitable for reverse dependency expressions.
1289 static void expr_print_revdep(struct expr *e,
1290 void (*fn)(void *, struct symbol *, const char *),
1291 void *data, tristate pr_type, const char **title)
1293 if (e->type == E_OR) {
1294 expr_print_revdep(e->left.expr, fn, data, pr_type, title);
1295 expr_print_revdep(e->right.expr, fn, data, pr_type, title);
1296 } else if (expr_calc_value(e) == pr_type) {
1298 fn(data, NULL, *title);
1302 fn(data, NULL, " - ");
1303 expr_print(e, fn, data, E_NONE);
1304 fn(data, NULL, "\n");
1308 void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
1309 tristate pr_type, const char *title)
1311 expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title);