2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
14 struct expr
*expr_alloc_symbol(struct symbol
*sym
)
16 struct expr
*e
= calloc(1, sizeof(*e
));
22 struct expr
*expr_alloc_one(enum expr_type type
, struct expr
*ce
)
24 struct expr
*e
= calloc(1, sizeof(*e
));
30 struct expr
*expr_alloc_two(enum expr_type type
, struct expr
*e1
, struct expr
*e2
)
32 struct expr
*e
= calloc(1, sizeof(*e
));
39 struct expr
*expr_alloc_comp(enum expr_type type
, struct symbol
*s1
, struct symbol
*s2
)
41 struct expr
*e
= calloc(1, sizeof(*e
));
48 struct expr
*expr_alloc_and(struct expr
*e1
, struct expr
*e2
)
52 return e2
? expr_alloc_two(E_AND
, e1
, e2
) : e1
;
55 struct expr
*expr_alloc_or(struct expr
*e1
, struct expr
*e2
)
59 return e2
? expr_alloc_two(E_OR
, e1
, e2
) : e1
;
62 struct expr
*expr_copy(const struct expr
*org
)
69 e
= malloc(sizeof(*org
));
70 memcpy(e
, org
, sizeof(*org
));
76 e
->left
.expr
= expr_copy(org
->left
.expr
);
80 e
->left
.sym
= org
->left
.sym
;
81 e
->right
.sym
= org
->right
.sym
;
86 e
->left
.expr
= expr_copy(org
->left
.expr
);
87 e
->right
.expr
= expr_copy(org
->right
.expr
);
90 printf("can't copy type %d\n", e
->type
);
99 void expr_free(struct expr
*e
)
108 expr_free(e
->left
.expr
);
115 expr_free(e
->left
.expr
);
116 expr_free(e
->right
.expr
);
119 printf("how to free type %d?\n", e
->type
);
125 static int trans_count
;
130 static void __expr_eliminate_eq(enum expr_type type
, struct expr
**ep1
, struct expr
**ep2
)
132 if (e1
->type
== type
) {
133 __expr_eliminate_eq(type
, &e1
->left
.expr
, &e2
);
134 __expr_eliminate_eq(type
, &e1
->right
.expr
, &e2
);
137 if (e2
->type
== type
) {
138 __expr_eliminate_eq(type
, &e1
, &e2
->left
.expr
);
139 __expr_eliminate_eq(type
, &e1
, &e2
->right
.expr
);
142 if (e1
->type
== E_SYMBOL
&& e2
->type
== E_SYMBOL
&&
143 e1
->left
.sym
== e2
->left
.sym
&&
144 (e1
->left
.sym
== &symbol_yes
|| e1
->left
.sym
== &symbol_no
))
146 if (!expr_eq(e1
, e2
))
149 expr_free(e1
); expr_free(e2
);
152 e1
= expr_alloc_symbol(&symbol_no
);
153 e2
= expr_alloc_symbol(&symbol_no
);
156 e1
= expr_alloc_symbol(&symbol_yes
);
157 e2
= expr_alloc_symbol(&symbol_yes
);
164 void expr_eliminate_eq(struct expr
**ep1
, struct expr
**ep2
)
171 __expr_eliminate_eq(e1
->type
, ep1
, ep2
);
175 if (e1
->type
!= e2
->type
) switch (e2
->type
) {
178 __expr_eliminate_eq(e2
->type
, ep1
, ep2
);
182 e1
= expr_eliminate_yn(e1
);
183 e2
= expr_eliminate_yn(e2
);
189 int expr_eq(struct expr
*e1
, struct expr
*e2
)
193 if (e1
->type
!= e2
->type
)
198 return e1
->left
.sym
== e2
->left
.sym
&& e1
->right
.sym
== e2
->right
.sym
;
200 return e1
->left
.sym
== e2
->left
.sym
;
202 return expr_eq(e1
->left
.expr
, e2
->left
.expr
);
207 old_count
= trans_count
;
208 expr_eliminate_eq(&e1
, &e2
);
209 res
= (e1
->type
== E_SYMBOL
&& e2
->type
== E_SYMBOL
&&
210 e1
->left
.sym
== e2
->left
.sym
);
213 trans_count
= old_count
;
222 expr_fprint(e1
, stdout
);
224 expr_fprint(e2
, stdout
);
231 struct expr
*expr_eliminate_yn(struct expr
*e
)
235 if (e
) switch (e
->type
) {
237 e
->left
.expr
= expr_eliminate_yn(e
->left
.expr
);
238 e
->right
.expr
= expr_eliminate_yn(e
->right
.expr
);
239 if (e
->left
.expr
->type
== E_SYMBOL
) {
240 if (e
->left
.expr
->left
.sym
== &symbol_no
) {
241 expr_free(e
->left
.expr
);
242 expr_free(e
->right
.expr
);
244 e
->left
.sym
= &symbol_no
;
245 e
->right
.expr
= NULL
;
247 } else if (e
->left
.expr
->left
.sym
== &symbol_yes
) {
250 *e
= *(e
->right
.expr
);
255 if (e
->right
.expr
->type
== E_SYMBOL
) {
256 if (e
->right
.expr
->left
.sym
== &symbol_no
) {
257 expr_free(e
->left
.expr
);
258 expr_free(e
->right
.expr
);
260 e
->left
.sym
= &symbol_no
;
261 e
->right
.expr
= NULL
;
263 } else if (e
->right
.expr
->left
.sym
== &symbol_yes
) {
266 *e
= *(e
->left
.expr
);
273 e
->left
.expr
= expr_eliminate_yn(e
->left
.expr
);
274 e
->right
.expr
= expr_eliminate_yn(e
->right
.expr
);
275 if (e
->left
.expr
->type
== E_SYMBOL
) {
276 if (e
->left
.expr
->left
.sym
== &symbol_no
) {
279 *e
= *(e
->right
.expr
);
282 } else if (e
->left
.expr
->left
.sym
== &symbol_yes
) {
283 expr_free(e
->left
.expr
);
284 expr_free(e
->right
.expr
);
286 e
->left
.sym
= &symbol_yes
;
287 e
->right
.expr
= NULL
;
291 if (e
->right
.expr
->type
== E_SYMBOL
) {
292 if (e
->right
.expr
->left
.sym
== &symbol_no
) {
295 *e
= *(e
->left
.expr
);
298 } else if (e
->right
.expr
->left
.sym
== &symbol_yes
) {
299 expr_free(e
->left
.expr
);
300 expr_free(e
->right
.expr
);
302 e
->left
.sym
= &symbol_yes
;
303 e
->right
.expr
= NULL
;
317 struct expr
*expr_trans_bool(struct expr
*e
)
325 e
->left
.expr
= expr_trans_bool(e
->left
.expr
);
326 e
->right
.expr
= expr_trans_bool(e
->right
.expr
);
330 if (e
->left
.sym
->type
== S_TRISTATE
) {
331 if (e
->right
.sym
== &symbol_no
) {
346 static struct expr
*expr_join_or(struct expr
*e1
, struct expr
*e2
)
349 struct symbol
*sym1
, *sym2
;
352 return expr_copy(e1
);
353 if (e1
->type
!= E_EQUAL
&& e1
->type
!= E_UNEQUAL
&& e1
->type
!= E_SYMBOL
&& e1
->type
!= E_NOT
)
355 if (e2
->type
!= E_EQUAL
&& e2
->type
!= E_UNEQUAL
&& e2
->type
!= E_SYMBOL
&& e2
->type
!= E_NOT
)
357 if (e1
->type
== E_NOT
) {
359 if (tmp
->type
!= E_EQUAL
&& tmp
->type
!= E_UNEQUAL
&& tmp
->type
!= E_SYMBOL
)
361 sym1
= tmp
->left
.sym
;
364 if (e2
->type
== E_NOT
) {
365 if (e2
->left
.expr
->type
!= E_SYMBOL
)
367 sym2
= e2
->left
.expr
->left
.sym
;
372 if (sym1
->type
!= S_BOOLEAN
&& sym1
->type
!= S_TRISTATE
)
374 if (sym1
->type
== S_TRISTATE
) {
375 if (e1
->type
== E_EQUAL
&& e2
->type
== E_EQUAL
&&
376 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_mod
) ||
377 (e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_yes
))) {
378 // (a='y') || (a='m') -> (a!='n')
379 return expr_alloc_comp(E_UNEQUAL
, sym1
, &symbol_no
);
381 if (e1
->type
== E_EQUAL
&& e2
->type
== E_EQUAL
&&
382 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_no
) ||
383 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_yes
))) {
384 // (a='y') || (a='n') -> (a!='m')
385 return expr_alloc_comp(E_UNEQUAL
, sym1
, &symbol_mod
);
387 if (e1
->type
== E_EQUAL
&& e2
->type
== E_EQUAL
&&
388 ((e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_no
) ||
389 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_mod
))) {
390 // (a='m') || (a='n') -> (a!='y')
391 return expr_alloc_comp(E_UNEQUAL
, sym1
, &symbol_yes
);
394 if (sym1
->type
== S_BOOLEAN
&& sym1
== sym2
) {
395 if ((e1
->type
== E_NOT
&& e1
->left
.expr
->type
== E_SYMBOL
&& e2
->type
== E_SYMBOL
) ||
396 (e2
->type
== E_NOT
&& e2
->left
.expr
->type
== E_SYMBOL
&& e1
->type
== E_SYMBOL
))
397 return expr_alloc_symbol(&symbol_yes
);
401 printf("optimize (");
402 expr_fprint(e1
, stdout
);
404 expr_fprint(e2
, stdout
);
410 static struct expr
*expr_join_and(struct expr
*e1
, struct expr
*e2
)
413 struct symbol
*sym1
, *sym2
;
416 return expr_copy(e1
);
417 if (e1
->type
!= E_EQUAL
&& e1
->type
!= E_UNEQUAL
&& e1
->type
!= E_SYMBOL
&& e1
->type
!= E_NOT
)
419 if (e2
->type
!= E_EQUAL
&& e2
->type
!= E_UNEQUAL
&& e2
->type
!= E_SYMBOL
&& e2
->type
!= E_NOT
)
421 if (e1
->type
== E_NOT
) {
423 if (tmp
->type
!= E_EQUAL
&& tmp
->type
!= E_UNEQUAL
&& tmp
->type
!= E_SYMBOL
)
425 sym1
= tmp
->left
.sym
;
428 if (e2
->type
== E_NOT
) {
429 if (e2
->left
.expr
->type
!= E_SYMBOL
)
431 sym2
= e2
->left
.expr
->left
.sym
;
436 if (sym1
->type
!= S_BOOLEAN
&& sym1
->type
!= S_TRISTATE
)
439 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_EQUAL
&& e2
->right
.sym
== &symbol_yes
) ||
440 (e2
->type
== E_SYMBOL
&& e1
->type
== E_EQUAL
&& e1
->right
.sym
== &symbol_yes
))
441 // (a) && (a='y') -> (a='y')
442 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_yes
);
444 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_UNEQUAL
&& e2
->right
.sym
== &symbol_no
) ||
445 (e2
->type
== E_SYMBOL
&& e1
->type
== E_UNEQUAL
&& e1
->right
.sym
== &symbol_no
))
446 // (a) && (a!='n') -> (a)
447 return expr_alloc_symbol(sym1
);
449 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_UNEQUAL
&& e2
->right
.sym
== &symbol_mod
) ||
450 (e2
->type
== E_SYMBOL
&& e1
->type
== E_UNEQUAL
&& e1
->right
.sym
== &symbol_mod
))
451 // (a) && (a!='m') -> (a='y')
452 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_yes
);
454 if (sym1
->type
== S_TRISTATE
) {
455 if (e1
->type
== E_EQUAL
&& e2
->type
== E_UNEQUAL
) {
456 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
457 sym2
= e1
->right
.sym
;
458 if ((e2
->right
.sym
->flags
& SYMBOL_CONST
) && (sym2
->flags
& SYMBOL_CONST
))
459 return sym2
!= e2
->right
.sym
? expr_alloc_comp(E_EQUAL
, sym1
, sym2
)
460 : expr_alloc_symbol(&symbol_no
);
462 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_EQUAL
) {
463 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
464 sym2
= e2
->right
.sym
;
465 if ((e1
->right
.sym
->flags
& SYMBOL_CONST
) && (sym2
->flags
& SYMBOL_CONST
))
466 return sym2
!= e1
->right
.sym
? expr_alloc_comp(E_EQUAL
, sym1
, sym2
)
467 : expr_alloc_symbol(&symbol_no
);
469 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_UNEQUAL
&&
470 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_no
) ||
471 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_yes
)))
472 // (a!='y') && (a!='n') -> (a='m')
473 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_mod
);
475 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_UNEQUAL
&&
476 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_mod
) ||
477 (e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_yes
)))
478 // (a!='y') && (a!='m') -> (a='n')
479 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_no
);
481 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_UNEQUAL
&&
482 ((e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_no
) ||
483 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_mod
)))
484 // (a!='m') && (a!='n') -> (a='m')
485 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_yes
);
487 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_EQUAL
&& e2
->right
.sym
== &symbol_mod
) ||
488 (e2
->type
== E_SYMBOL
&& e1
->type
== E_EQUAL
&& e1
->right
.sym
== &symbol_mod
) ||
489 (e1
->type
== E_SYMBOL
&& e2
->type
== E_UNEQUAL
&& e2
->right
.sym
== &symbol_yes
) ||
490 (e2
->type
== E_SYMBOL
&& e1
->type
== E_UNEQUAL
&& e1
->right
.sym
== &symbol_yes
))
495 printf("optimize (");
496 expr_fprint(e1
, stdout
);
498 expr_fprint(e2
, stdout
);
504 static void expr_eliminate_dups1(enum expr_type type
, struct expr
**ep1
, struct expr
**ep2
)
510 if (e1
->type
== type
) {
511 expr_eliminate_dups1(type
, &e1
->left
.expr
, &e2
);
512 expr_eliminate_dups1(type
, &e1
->right
.expr
, &e2
);
515 if (e2
->type
== type
) {
516 expr_eliminate_dups1(type
, &e1
, &e2
->left
.expr
);
517 expr_eliminate_dups1(type
, &e1
, &e2
->right
.expr
);
524 case E_OR
: case E_AND
:
525 expr_eliminate_dups1(e1
->type
, &e1
, &e1
);
532 tmp
= expr_join_or(e1
, e2
);
534 expr_free(e1
); expr_free(e2
);
535 e1
= expr_alloc_symbol(&symbol_no
);
541 tmp
= expr_join_and(e1
, e2
);
543 expr_free(e1
); expr_free(e2
);
544 e1
= expr_alloc_symbol(&symbol_yes
);
556 static void expr_eliminate_dups2(enum expr_type type
, struct expr
**ep1
, struct expr
**ep2
)
560 struct expr
*tmp
, *tmp1
, *tmp2
;
562 if (e1
->type
== type
) {
563 expr_eliminate_dups2(type
, &e1
->left
.expr
, &e2
);
564 expr_eliminate_dups2(type
, &e1
->right
.expr
, &e2
);
567 if (e2
->type
== type
) {
568 expr_eliminate_dups2(type
, &e1
, &e2
->left
.expr
);
569 expr_eliminate_dups2(type
, &e1
, &e2
->right
.expr
);
576 expr_eliminate_dups2(e1
->type
, &e1
, &e1
);
577 // (FOO || BAR) && (!FOO && !BAR) -> n
578 tmp1
= expr_transform(expr_alloc_one(E_NOT
, expr_copy(e1
)));
579 tmp2
= expr_copy(e2
);
580 tmp
= expr_extract_eq_and(&tmp1
, &tmp2
);
581 if (expr_is_yes(tmp1
)) {
583 e1
= expr_alloc_symbol(&symbol_no
);
591 expr_eliminate_dups2(e1
->type
, &e1
, &e1
);
592 // (FOO && BAR) || (!FOO || !BAR) -> y
593 tmp1
= expr_transform(expr_alloc_one(E_NOT
, expr_copy(e1
)));
594 tmp2
= expr_copy(e2
);
595 tmp
= expr_extract_eq_or(&tmp1
, &tmp2
);
596 if (expr_is_no(tmp1
)) {
598 e1
= expr_alloc_symbol(&symbol_yes
);
612 struct expr
*expr_eliminate_dups(struct expr
*e
)
618 oldcount
= trans_count
;
622 case E_OR
: case E_AND
:
623 expr_eliminate_dups1(e
->type
, &e
, &e
);
624 expr_eliminate_dups2(e
->type
, &e
, &e
);
630 e
= expr_eliminate_yn(e
);
632 trans_count
= oldcount
;
636 struct expr
*expr_transform(struct expr
*e
)
649 e
->left
.expr
= expr_transform(e
->left
.expr
);
650 e
->right
.expr
= expr_transform(e
->right
.expr
);
655 if (e
->left
.sym
->type
!= S_BOOLEAN
)
657 if (e
->right
.sym
== &symbol_no
) {
659 e
->left
.expr
= expr_alloc_symbol(e
->left
.sym
);
663 if (e
->right
.sym
== &symbol_mod
) {
664 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e
->left
.sym
->name
);
666 e
->left
.sym
= &symbol_no
;
670 if (e
->right
.sym
== &symbol_yes
) {
677 if (e
->left
.sym
->type
!= S_BOOLEAN
)
679 if (e
->right
.sym
== &symbol_no
) {
684 if (e
->right
.sym
== &symbol_mod
) {
685 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e
->left
.sym
->name
);
687 e
->left
.sym
= &symbol_yes
;
691 if (e
->right
.sym
== &symbol_yes
) {
693 e
->left
.expr
= expr_alloc_symbol(e
->left
.sym
);
699 switch (e
->left
.expr
->type
) {
702 tmp
= e
->left
.expr
->left
.expr
;
706 e
= expr_transform(e
);
714 e
->type
= e
->type
== E_EQUAL
? E_UNEQUAL
: E_EQUAL
;
717 // !(a || b) -> !a && !b
720 e
->right
.expr
= expr_alloc_one(E_NOT
, tmp
->right
.expr
);
722 tmp
->right
.expr
= NULL
;
723 e
= expr_transform(e
);
726 // !(a && b) -> !a || !b
729 e
->right
.expr
= expr_alloc_one(E_NOT
, tmp
->right
.expr
);
731 tmp
->right
.expr
= NULL
;
732 e
= expr_transform(e
);
735 if (e
->left
.expr
->left
.sym
== &symbol_yes
) {
741 e
->left
.sym
= &symbol_no
;
744 if (e
->left
.expr
->left
.sym
== &symbol_mod
) {
750 e
->left
.sym
= &symbol_mod
;
753 if (e
->left
.expr
->left
.sym
== &symbol_no
) {
759 e
->left
.sym
= &symbol_yes
;
773 int expr_contains_symbol(struct expr
*dep
, struct symbol
*sym
)
781 return expr_contains_symbol(dep
->left
.expr
, sym
) ||
782 expr_contains_symbol(dep
->right
.expr
, sym
);
784 return dep
->left
.sym
== sym
;
787 return dep
->left
.sym
== sym
||
788 dep
->right
.sym
== sym
;
790 return expr_contains_symbol(dep
->left
.expr
, sym
);
797 bool expr_depends_symbol(struct expr
*dep
, struct symbol
*sym
)
804 return expr_depends_symbol(dep
->left
.expr
, sym
) ||
805 expr_depends_symbol(dep
->right
.expr
, sym
);
807 return dep
->left
.sym
== sym
;
809 if (dep
->left
.sym
== sym
) {
810 if (dep
->right
.sym
== &symbol_yes
|| dep
->right
.sym
== &symbol_mod
)
815 if (dep
->left
.sym
== sym
) {
816 if (dep
->right
.sym
== &symbol_no
)
826 struct expr
*expr_extract_eq_and(struct expr
**ep1
, struct expr
**ep2
)
828 struct expr
*tmp
= NULL
;
829 expr_extract_eq(E_AND
, &tmp
, ep1
, ep2
);
831 *ep1
= expr_eliminate_yn(*ep1
);
832 *ep2
= expr_eliminate_yn(*ep2
);
837 struct expr
*expr_extract_eq_or(struct expr
**ep1
, struct expr
**ep2
)
839 struct expr
*tmp
= NULL
;
840 expr_extract_eq(E_OR
, &tmp
, ep1
, ep2
);
842 *ep1
= expr_eliminate_yn(*ep1
);
843 *ep2
= expr_eliminate_yn(*ep2
);
848 void expr_extract_eq(enum expr_type type
, struct expr
**ep
, struct expr
**ep1
, struct expr
**ep2
)
852 if (e1
->type
== type
) {
853 expr_extract_eq(type
, ep
, &e1
->left
.expr
, &e2
);
854 expr_extract_eq(type
, ep
, &e1
->right
.expr
, &e2
);
857 if (e2
->type
== type
) {
858 expr_extract_eq(type
, ep
, ep1
, &e2
->left
.expr
);
859 expr_extract_eq(type
, ep
, ep1
, &e2
->right
.expr
);
862 if (expr_eq(e1
, e2
)) {
863 *ep
= *ep
? expr_alloc_two(type
, *ep
, e1
) : e1
;
866 e1
= expr_alloc_symbol(&symbol_yes
);
867 e2
= expr_alloc_symbol(&symbol_yes
);
868 } else if (type
== E_OR
) {
869 e1
= expr_alloc_symbol(&symbol_no
);
870 e2
= expr_alloc_symbol(&symbol_no
);
877 struct expr
*expr_trans_compare(struct expr
*e
, enum expr_type type
, struct symbol
*sym
)
879 struct expr
*e1
, *e2
;
882 e
= expr_alloc_symbol(sym
);
883 if (type
== E_UNEQUAL
)
884 e
= expr_alloc_one(E_NOT
, e
);
889 e1
= expr_trans_compare(e
->left
.expr
, E_EQUAL
, sym
);
890 e2
= expr_trans_compare(e
->right
.expr
, E_EQUAL
, sym
);
891 if (sym
== &symbol_yes
)
892 e
= expr_alloc_two(E_AND
, e1
, e2
);
893 if (sym
== &symbol_no
)
894 e
= expr_alloc_two(E_OR
, e1
, e2
);
895 if (type
== E_UNEQUAL
)
896 e
= expr_alloc_one(E_NOT
, e
);
899 e1
= expr_trans_compare(e
->left
.expr
, E_EQUAL
, sym
);
900 e2
= expr_trans_compare(e
->right
.expr
, E_EQUAL
, sym
);
901 if (sym
== &symbol_yes
)
902 e
= expr_alloc_two(E_OR
, e1
, e2
);
903 if (sym
== &symbol_no
)
904 e
= expr_alloc_two(E_AND
, e1
, e2
);
905 if (type
== E_UNEQUAL
)
906 e
= expr_alloc_one(E_NOT
, e
);
909 return expr_trans_compare(e
->left
.expr
, type
== E_EQUAL
? E_UNEQUAL
: E_EQUAL
, sym
);
912 if (type
== E_EQUAL
) {
913 if (sym
== &symbol_yes
)
915 if (sym
== &symbol_mod
)
916 return expr_alloc_symbol(&symbol_no
);
917 if (sym
== &symbol_no
)
918 return expr_alloc_one(E_NOT
, expr_copy(e
));
920 if (sym
== &symbol_yes
)
921 return expr_alloc_one(E_NOT
, expr_copy(e
));
922 if (sym
== &symbol_mod
)
923 return expr_alloc_symbol(&symbol_yes
);
924 if (sym
== &symbol_no
)
929 return expr_alloc_comp(type
, e
->left
.sym
, sym
);
938 tristate
expr_calc_value(struct expr
*e
)
941 const char *str1
, *str2
;
948 sym_calc_value(e
->left
.sym
);
949 return e
->left
.sym
->curr
.tri
;
951 val1
= expr_calc_value(e
->left
.expr
);
952 val2
= expr_calc_value(e
->right
.expr
);
953 return EXPR_AND(val1
, val2
);
955 val1
= expr_calc_value(e
->left
.expr
);
956 val2
= expr_calc_value(e
->right
.expr
);
957 return EXPR_OR(val1
, val2
);
959 val1
= expr_calc_value(e
->left
.expr
);
960 return EXPR_NOT(val1
);
962 sym_calc_value(e
->left
.sym
);
963 sym_calc_value(e
->right
.sym
);
964 str1
= sym_get_string_value(e
->left
.sym
);
965 str2
= sym_get_string_value(e
->right
.sym
);
966 return !strcmp(str1
, str2
) ? yes
: no
;
968 sym_calc_value(e
->left
.sym
);
969 sym_calc_value(e
->right
.sym
);
970 str1
= sym_get_string_value(e
->left
.sym
);
971 str2
= sym_get_string_value(e
->right
.sym
);
972 return !strcmp(str1
, str2
) ? no
: yes
;
974 printf("expr_calc_value: %d?\n", e
->type
);
979 int expr_compare_type(enum expr_type t1
, enum expr_type t2
)
1006 printf("[%dgt%d?]", t1
, t2
);
1011 static inline struct expr
*
1012 expr_get_leftmost_symbol(const struct expr
*e
)
1018 while (e
->type
!= E_SYMBOL
)
1021 return expr_copy(e
);
1025 * Given expression `e1' and `e2', returns the leaf of the longest
1026 * sub-expression of `e1' not containing 'e2.
1028 struct expr
*expr_simplify_unmet_dep(struct expr
*e1
, struct expr
*e2
)
1034 return expr_alloc_and(
1035 expr_simplify_unmet_dep(e1
->left
.expr
, e2
),
1036 expr_simplify_unmet_dep(e1
->right
.expr
, e2
));
1039 e
= expr_alloc_and(expr_copy(e1
), expr_copy(e2
));
1040 e
= expr_eliminate_dups(e
);
1041 ret
= (!expr_eq(e
, e1
)) ? e1
: NULL
;
1050 return expr_get_leftmost_symbol(ret
);
1053 void expr_print(struct expr
*e
, void (*fn
)(void *, struct symbol
*, const char *), void *data
, int prevtoken
)
1056 fn(data
, NULL
, "y");
1060 if (expr_compare_type(prevtoken
, e
->type
) > 0)
1061 fn(data
, NULL
, "(");
1064 if (e
->left
.sym
->name
)
1065 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1067 fn(data
, NULL
, "<choice>");
1070 fn(data
, NULL
, "!");
1071 expr_print(e
->left
.expr
, fn
, data
, E_NOT
);
1074 if (e
->left
.sym
->name
)
1075 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1077 fn(data
, NULL
, "<choice>");
1078 fn(data
, NULL
, "=");
1079 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1082 if (e
->left
.sym
->name
)
1083 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1085 fn(data
, NULL
, "<choice>");
1086 fn(data
, NULL
, "!=");
1087 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1090 expr_print(e
->left
.expr
, fn
, data
, E_OR
);
1091 fn(data
, NULL
, " || ");
1092 expr_print(e
->right
.expr
, fn
, data
, E_OR
);
1095 expr_print(e
->left
.expr
, fn
, data
, E_AND
);
1096 fn(data
, NULL
, " && ");
1097 expr_print(e
->right
.expr
, fn
, data
, E_AND
);
1100 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1102 fn(data
, NULL
, " ^ ");
1103 expr_print(e
->left
.expr
, fn
, data
, E_LIST
);
1107 fn(data
, NULL
, "[");
1108 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1109 fn(data
, NULL
, " ");
1110 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1111 fn(data
, NULL
, "]");
1116 sprintf(buf
, "<unknown type %d>", e
->type
);
1117 fn(data
, NULL
, buf
);
1121 if (expr_compare_type(prevtoken
, e
->type
) > 0)
1122 fn(data
, NULL
, ")");
1125 static void expr_print_file_helper(void *data
, struct symbol
*sym
, const char *str
)
1127 xfwrite(str
, strlen(str
), 1, data
);
1130 void expr_fprint(struct expr
*e
, FILE *out
)
1132 expr_print(e
, expr_print_file_helper
, out
, E_NONE
);
1135 static void expr_print_gstr_helper(void *data
, struct symbol
*sym
, const char *str
)
1137 struct gstr
*gs
= (struct gstr
*)data
;
1138 const char *sym_str
= NULL
;
1141 sym_str
= sym_get_string_value(sym
);
1143 if (gs
->max_width
) {
1144 unsigned extra_length
= strlen(str
);
1145 const char *last_cr
= strrchr(gs
->s
, '\n');
1146 unsigned last_line_length
;
1149 extra_length
+= 4 + strlen(sym_str
);
1154 last_line_length
= strlen(gs
->s
) - (last_cr
- gs
->s
);
1156 if ((last_line_length
+ extra_length
) > gs
->max_width
)
1157 str_append(gs
, "\\\n");
1160 str_append(gs
, str
);
1161 if (sym
&& sym
->type
!= S_UNKNOWN
)
1162 str_printf(gs
, " [=%s]", sym_str
);
1165 void expr_gstr_print(struct expr
*e
, struct gstr
*gs
)
1167 expr_print(e
, expr_print_gstr_helper
, gs
, E_NONE
);