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
);
16 static struct expr
*expr_extract_eq_and(struct expr
**ep1
, struct expr
**ep2
);
17 static struct expr
*expr_extract_eq_or(struct expr
**ep1
, struct expr
**ep2
);
18 static void expr_extract_eq(enum expr_type type
, struct expr
**ep
, struct expr
**ep1
, struct expr
**ep2
);
20 struct expr
*expr_alloc_symbol(struct symbol
*sym
)
22 struct expr
*e
= xcalloc(1, sizeof(*e
));
28 struct expr
*expr_alloc_one(enum expr_type type
, struct expr
*ce
)
30 struct expr
*e
= xcalloc(1, sizeof(*e
));
36 struct expr
*expr_alloc_two(enum expr_type type
, struct expr
*e1
, struct expr
*e2
)
38 struct expr
*e
= xcalloc(1, sizeof(*e
));
45 struct expr
*expr_alloc_comp(enum expr_type type
, struct symbol
*s1
, struct symbol
*s2
)
47 struct expr
*e
= xcalloc(1, sizeof(*e
));
54 struct expr
*expr_alloc_and(struct expr
*e1
, struct expr
*e2
)
58 return e2
? expr_alloc_two(E_AND
, e1
, e2
) : e1
;
61 struct expr
*expr_alloc_or(struct expr
*e1
, struct expr
*e2
)
65 return e2
? expr_alloc_two(E_OR
, e1
, e2
) : e1
;
68 struct expr
*expr_copy(const struct expr
*org
)
75 e
= xmalloc(sizeof(*org
));
76 memcpy(e
, org
, sizeof(*org
));
82 e
->left
.expr
= expr_copy(org
->left
.expr
);
86 e
->left
.sym
= org
->left
.sym
;
87 e
->right
.sym
= org
->right
.sym
;
92 e
->left
.expr
= expr_copy(org
->left
.expr
);
93 e
->right
.expr
= expr_copy(org
->right
.expr
);
96 printf("can't copy type %d\n", e
->type
);
105 void expr_free(struct expr
*e
)
114 expr_free(e
->left
.expr
);
121 expr_free(e
->left
.expr
);
122 expr_free(e
->right
.expr
);
125 printf("how to free type %d?\n", e
->type
);
131 static int trans_count
;
136 static void __expr_eliminate_eq(enum expr_type type
, struct expr
**ep1
, struct expr
**ep2
)
138 if (e1
->type
== type
) {
139 __expr_eliminate_eq(type
, &e1
->left
.expr
, &e2
);
140 __expr_eliminate_eq(type
, &e1
->right
.expr
, &e2
);
143 if (e2
->type
== type
) {
144 __expr_eliminate_eq(type
, &e1
, &e2
->left
.expr
);
145 __expr_eliminate_eq(type
, &e1
, &e2
->right
.expr
);
148 if (e1
->type
== E_SYMBOL
&& e2
->type
== E_SYMBOL
&&
149 e1
->left
.sym
== e2
->left
.sym
&&
150 (e1
->left
.sym
== &symbol_yes
|| e1
->left
.sym
== &symbol_no
))
152 if (!expr_eq(e1
, e2
))
155 expr_free(e1
); expr_free(e2
);
158 e1
= expr_alloc_symbol(&symbol_no
);
159 e2
= expr_alloc_symbol(&symbol_no
);
162 e1
= expr_alloc_symbol(&symbol_yes
);
163 e2
= expr_alloc_symbol(&symbol_yes
);
170 void expr_eliminate_eq(struct expr
**ep1
, struct expr
**ep2
)
177 __expr_eliminate_eq(e1
->type
, ep1
, ep2
);
181 if (e1
->type
!= e2
->type
) switch (e2
->type
) {
184 __expr_eliminate_eq(e2
->type
, ep1
, ep2
);
188 e1
= expr_eliminate_yn(e1
);
189 e2
= expr_eliminate_yn(e2
);
195 static int expr_eq(struct expr
*e1
, struct expr
*e2
)
199 if (e1
->type
!= e2
->type
)
204 return e1
->left
.sym
== e2
->left
.sym
&& e1
->right
.sym
== e2
->right
.sym
;
206 return e1
->left
.sym
== e2
->left
.sym
;
208 return expr_eq(e1
->left
.expr
, e2
->left
.expr
);
213 old_count
= trans_count
;
214 expr_eliminate_eq(&e1
, &e2
);
215 res
= (e1
->type
== E_SYMBOL
&& e2
->type
== E_SYMBOL
&&
216 e1
->left
.sym
== e2
->left
.sym
);
219 trans_count
= old_count
;
228 expr_fprint(e1
, stdout
);
230 expr_fprint(e2
, stdout
);
237 static struct expr
*expr_eliminate_yn(struct expr
*e
)
241 if (e
) switch (e
->type
) {
243 e
->left
.expr
= expr_eliminate_yn(e
->left
.expr
);
244 e
->right
.expr
= expr_eliminate_yn(e
->right
.expr
);
245 if (e
->left
.expr
->type
== E_SYMBOL
) {
246 if (e
->left
.expr
->left
.sym
== &symbol_no
) {
247 expr_free(e
->left
.expr
);
248 expr_free(e
->right
.expr
);
250 e
->left
.sym
= &symbol_no
;
251 e
->right
.expr
= NULL
;
253 } else if (e
->left
.expr
->left
.sym
== &symbol_yes
) {
256 *e
= *(e
->right
.expr
);
261 if (e
->right
.expr
->type
== E_SYMBOL
) {
262 if (e
->right
.expr
->left
.sym
== &symbol_no
) {
263 expr_free(e
->left
.expr
);
264 expr_free(e
->right
.expr
);
266 e
->left
.sym
= &symbol_no
;
267 e
->right
.expr
= NULL
;
269 } else if (e
->right
.expr
->left
.sym
== &symbol_yes
) {
272 *e
= *(e
->left
.expr
);
279 e
->left
.expr
= expr_eliminate_yn(e
->left
.expr
);
280 e
->right
.expr
= expr_eliminate_yn(e
->right
.expr
);
281 if (e
->left
.expr
->type
== E_SYMBOL
) {
282 if (e
->left
.expr
->left
.sym
== &symbol_no
) {
285 *e
= *(e
->right
.expr
);
288 } else if (e
->left
.expr
->left
.sym
== &symbol_yes
) {
289 expr_free(e
->left
.expr
);
290 expr_free(e
->right
.expr
);
292 e
->left
.sym
= &symbol_yes
;
293 e
->right
.expr
= NULL
;
297 if (e
->right
.expr
->type
== E_SYMBOL
) {
298 if (e
->right
.expr
->left
.sym
== &symbol_no
) {
301 *e
= *(e
->left
.expr
);
304 } else if (e
->right
.expr
->left
.sym
== &symbol_yes
) {
305 expr_free(e
->left
.expr
);
306 expr_free(e
->right
.expr
);
308 e
->left
.sym
= &symbol_yes
;
309 e
->right
.expr
= NULL
;
323 struct expr
*expr_trans_bool(struct expr
*e
)
331 e
->left
.expr
= expr_trans_bool(e
->left
.expr
);
332 e
->right
.expr
= expr_trans_bool(e
->right
.expr
);
336 if (e
->left
.sym
->type
== S_TRISTATE
) {
337 if (e
->right
.sym
== &symbol_no
) {
352 static struct expr
*expr_join_or(struct expr
*e1
, struct expr
*e2
)
355 struct symbol
*sym1
, *sym2
;
358 return expr_copy(e1
);
359 if (e1
->type
!= E_EQUAL
&& e1
->type
!= E_UNEQUAL
&& e1
->type
!= E_SYMBOL
&& e1
->type
!= E_NOT
)
361 if (e2
->type
!= E_EQUAL
&& e2
->type
!= E_UNEQUAL
&& e2
->type
!= E_SYMBOL
&& e2
->type
!= E_NOT
)
363 if (e1
->type
== E_NOT
) {
365 if (tmp
->type
!= E_EQUAL
&& tmp
->type
!= E_UNEQUAL
&& tmp
->type
!= E_SYMBOL
)
367 sym1
= tmp
->left
.sym
;
370 if (e2
->type
== E_NOT
) {
371 if (e2
->left
.expr
->type
!= E_SYMBOL
)
373 sym2
= e2
->left
.expr
->left
.sym
;
378 if (sym1
->type
!= S_BOOLEAN
&& sym1
->type
!= S_TRISTATE
)
380 if (sym1
->type
== S_TRISTATE
) {
381 if (e1
->type
== E_EQUAL
&& e2
->type
== E_EQUAL
&&
382 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_mod
) ||
383 (e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_yes
))) {
384 // (a='y') || (a='m') -> (a!='n')
385 return expr_alloc_comp(E_UNEQUAL
, sym1
, &symbol_no
);
387 if (e1
->type
== E_EQUAL
&& e2
->type
== E_EQUAL
&&
388 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_no
) ||
389 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_yes
))) {
390 // (a='y') || (a='n') -> (a!='m')
391 return expr_alloc_comp(E_UNEQUAL
, sym1
, &symbol_mod
);
393 if (e1
->type
== E_EQUAL
&& e2
->type
== E_EQUAL
&&
394 ((e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_no
) ||
395 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_mod
))) {
396 // (a='m') || (a='n') -> (a!='y')
397 return expr_alloc_comp(E_UNEQUAL
, sym1
, &symbol_yes
);
400 if (sym1
->type
== S_BOOLEAN
&& sym1
== sym2
) {
401 if ((e1
->type
== E_NOT
&& e1
->left
.expr
->type
== E_SYMBOL
&& e2
->type
== E_SYMBOL
) ||
402 (e2
->type
== E_NOT
&& e2
->left
.expr
->type
== E_SYMBOL
&& e1
->type
== E_SYMBOL
))
403 return expr_alloc_symbol(&symbol_yes
);
407 printf("optimize (");
408 expr_fprint(e1
, stdout
);
410 expr_fprint(e2
, stdout
);
416 static struct expr
*expr_join_and(struct expr
*e1
, struct expr
*e2
)
419 struct symbol
*sym1
, *sym2
;
422 return expr_copy(e1
);
423 if (e1
->type
!= E_EQUAL
&& e1
->type
!= E_UNEQUAL
&& e1
->type
!= E_SYMBOL
&& e1
->type
!= E_NOT
)
425 if (e2
->type
!= E_EQUAL
&& e2
->type
!= E_UNEQUAL
&& e2
->type
!= E_SYMBOL
&& e2
->type
!= E_NOT
)
427 if (e1
->type
== E_NOT
) {
429 if (tmp
->type
!= E_EQUAL
&& tmp
->type
!= E_UNEQUAL
&& tmp
->type
!= E_SYMBOL
)
431 sym1
= tmp
->left
.sym
;
434 if (e2
->type
== E_NOT
) {
435 if (e2
->left
.expr
->type
!= E_SYMBOL
)
437 sym2
= e2
->left
.expr
->left
.sym
;
442 if (sym1
->type
!= S_BOOLEAN
&& sym1
->type
!= S_TRISTATE
)
445 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_EQUAL
&& e2
->right
.sym
== &symbol_yes
) ||
446 (e2
->type
== E_SYMBOL
&& e1
->type
== E_EQUAL
&& e1
->right
.sym
== &symbol_yes
))
447 // (a) && (a='y') -> (a='y')
448 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_yes
);
450 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_UNEQUAL
&& e2
->right
.sym
== &symbol_no
) ||
451 (e2
->type
== E_SYMBOL
&& e1
->type
== E_UNEQUAL
&& e1
->right
.sym
== &symbol_no
))
452 // (a) && (a!='n') -> (a)
453 return expr_alloc_symbol(sym1
);
455 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_UNEQUAL
&& e2
->right
.sym
== &symbol_mod
) ||
456 (e2
->type
== E_SYMBOL
&& e1
->type
== E_UNEQUAL
&& e1
->right
.sym
== &symbol_mod
))
457 // (a) && (a!='m') -> (a='y')
458 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_yes
);
460 if (sym1
->type
== S_TRISTATE
) {
461 if (e1
->type
== E_EQUAL
&& e2
->type
== E_UNEQUAL
) {
462 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
463 sym2
= e1
->right
.sym
;
464 if ((e2
->right
.sym
->flags
& SYMBOL_CONST
) && (sym2
->flags
& SYMBOL_CONST
))
465 return sym2
!= e2
->right
.sym
? expr_alloc_comp(E_EQUAL
, sym1
, sym2
)
466 : expr_alloc_symbol(&symbol_no
);
468 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_EQUAL
) {
469 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
470 sym2
= e2
->right
.sym
;
471 if ((e1
->right
.sym
->flags
& SYMBOL_CONST
) && (sym2
->flags
& SYMBOL_CONST
))
472 return sym2
!= e1
->right
.sym
? expr_alloc_comp(E_EQUAL
, sym1
, sym2
)
473 : expr_alloc_symbol(&symbol_no
);
475 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_UNEQUAL
&&
476 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_no
) ||
477 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_yes
)))
478 // (a!='y') && (a!='n') -> (a='m')
479 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_mod
);
481 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_UNEQUAL
&&
482 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_mod
) ||
483 (e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_yes
)))
484 // (a!='y') && (a!='m') -> (a='n')
485 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_no
);
487 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_UNEQUAL
&&
488 ((e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_no
) ||
489 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_mod
)))
490 // (a!='m') && (a!='n') -> (a='m')
491 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_yes
);
493 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_EQUAL
&& e2
->right
.sym
== &symbol_mod
) ||
494 (e2
->type
== E_SYMBOL
&& e1
->type
== E_EQUAL
&& e1
->right
.sym
== &symbol_mod
) ||
495 (e1
->type
== E_SYMBOL
&& e2
->type
== E_UNEQUAL
&& e2
->right
.sym
== &symbol_yes
) ||
496 (e2
->type
== E_SYMBOL
&& e1
->type
== E_UNEQUAL
&& e1
->right
.sym
== &symbol_yes
))
501 printf("optimize (");
502 expr_fprint(e1
, stdout
);
504 expr_fprint(e2
, stdout
);
510 static void expr_eliminate_dups1(enum expr_type type
, struct expr
**ep1
, struct expr
**ep2
)
516 if (e1
->type
== type
) {
517 expr_eliminate_dups1(type
, &e1
->left
.expr
, &e2
);
518 expr_eliminate_dups1(type
, &e1
->right
.expr
, &e2
);
521 if (e2
->type
== type
) {
522 expr_eliminate_dups1(type
, &e1
, &e2
->left
.expr
);
523 expr_eliminate_dups1(type
, &e1
, &e2
->right
.expr
);
530 case E_OR
: case E_AND
:
531 expr_eliminate_dups1(e1
->type
, &e1
, &e1
);
538 tmp
= expr_join_or(e1
, e2
);
540 expr_free(e1
); expr_free(e2
);
541 e1
= expr_alloc_symbol(&symbol_no
);
547 tmp
= expr_join_and(e1
, e2
);
549 expr_free(e1
); expr_free(e2
);
550 e1
= expr_alloc_symbol(&symbol_yes
);
562 static void expr_eliminate_dups2(enum expr_type type
, struct expr
**ep1
, struct expr
**ep2
)
566 struct expr
*tmp
, *tmp1
, *tmp2
;
568 if (e1
->type
== type
) {
569 expr_eliminate_dups2(type
, &e1
->left
.expr
, &e2
);
570 expr_eliminate_dups2(type
, &e1
->right
.expr
, &e2
);
573 if (e2
->type
== type
) {
574 expr_eliminate_dups2(type
, &e1
, &e2
->left
.expr
);
575 expr_eliminate_dups2(type
, &e1
, &e2
->right
.expr
);
582 expr_eliminate_dups2(e1
->type
, &e1
, &e1
);
583 // (FOO || BAR) && (!FOO && !BAR) -> n
584 tmp1
= expr_transform(expr_alloc_one(E_NOT
, expr_copy(e1
)));
585 tmp2
= expr_copy(e2
);
586 tmp
= expr_extract_eq_and(&tmp1
, &tmp2
);
587 if (expr_is_yes(tmp1
)) {
589 e1
= expr_alloc_symbol(&symbol_no
);
597 expr_eliminate_dups2(e1
->type
, &e1
, &e1
);
598 // (FOO && BAR) || (!FOO || !BAR) -> y
599 tmp1
= expr_transform(expr_alloc_one(E_NOT
, expr_copy(e1
)));
600 tmp2
= expr_copy(e2
);
601 tmp
= expr_extract_eq_or(&tmp1
, &tmp2
);
602 if (expr_is_no(tmp1
)) {
604 e1
= expr_alloc_symbol(&symbol_yes
);
618 struct expr
*expr_eliminate_dups(struct expr
*e
)
624 oldcount
= trans_count
;
628 case E_OR
: case E_AND
:
629 expr_eliminate_dups1(e
->type
, &e
, &e
);
630 expr_eliminate_dups2(e
->type
, &e
, &e
);
636 e
= expr_eliminate_yn(e
);
638 trans_count
= oldcount
;
642 struct expr
*expr_transform(struct expr
*e
)
655 e
->left
.expr
= expr_transform(e
->left
.expr
);
656 e
->right
.expr
= expr_transform(e
->right
.expr
);
661 if (e
->left
.sym
->type
!= S_BOOLEAN
)
663 if (e
->right
.sym
== &symbol_no
) {
665 e
->left
.expr
= expr_alloc_symbol(e
->left
.sym
);
669 if (e
->right
.sym
== &symbol_mod
) {
670 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e
->left
.sym
->name
);
672 e
->left
.sym
= &symbol_no
;
676 if (e
->right
.sym
== &symbol_yes
) {
683 if (e
->left
.sym
->type
!= S_BOOLEAN
)
685 if (e
->right
.sym
== &symbol_no
) {
690 if (e
->right
.sym
== &symbol_mod
) {
691 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e
->left
.sym
->name
);
693 e
->left
.sym
= &symbol_yes
;
697 if (e
->right
.sym
== &symbol_yes
) {
699 e
->left
.expr
= expr_alloc_symbol(e
->left
.sym
);
705 switch (e
->left
.expr
->type
) {
708 tmp
= e
->left
.expr
->left
.expr
;
712 e
= expr_transform(e
);
720 e
->type
= e
->type
== E_EQUAL
? E_UNEQUAL
: E_EQUAL
;
723 // !(a || b) -> !a && !b
726 e
->right
.expr
= expr_alloc_one(E_NOT
, tmp
->right
.expr
);
728 tmp
->right
.expr
= NULL
;
729 e
= expr_transform(e
);
732 // !(a && b) -> !a || !b
735 e
->right
.expr
= expr_alloc_one(E_NOT
, tmp
->right
.expr
);
737 tmp
->right
.expr
= NULL
;
738 e
= expr_transform(e
);
741 if (e
->left
.expr
->left
.sym
== &symbol_yes
) {
747 e
->left
.sym
= &symbol_no
;
750 if (e
->left
.expr
->left
.sym
== &symbol_mod
) {
756 e
->left
.sym
= &symbol_mod
;
759 if (e
->left
.expr
->left
.sym
== &symbol_no
) {
765 e
->left
.sym
= &symbol_yes
;
779 int expr_contains_symbol(struct expr
*dep
, struct symbol
*sym
)
787 return expr_contains_symbol(dep
->left
.expr
, sym
) ||
788 expr_contains_symbol(dep
->right
.expr
, sym
);
790 return dep
->left
.sym
== sym
;
793 return dep
->left
.sym
== sym
||
794 dep
->right
.sym
== sym
;
796 return expr_contains_symbol(dep
->left
.expr
, sym
);
803 bool expr_depends_symbol(struct expr
*dep
, struct symbol
*sym
)
810 return expr_depends_symbol(dep
->left
.expr
, sym
) ||
811 expr_depends_symbol(dep
->right
.expr
, sym
);
813 return dep
->left
.sym
== sym
;
815 if (dep
->left
.sym
== sym
) {
816 if (dep
->right
.sym
== &symbol_yes
|| dep
->right
.sym
== &symbol_mod
)
821 if (dep
->left
.sym
== sym
) {
822 if (dep
->right
.sym
== &symbol_no
)
832 static struct expr
*expr_extract_eq_and(struct expr
**ep1
, struct expr
**ep2
)
834 struct expr
*tmp
= NULL
;
835 expr_extract_eq(E_AND
, &tmp
, ep1
, ep2
);
837 *ep1
= expr_eliminate_yn(*ep1
);
838 *ep2
= expr_eliminate_yn(*ep2
);
843 static struct expr
*expr_extract_eq_or(struct expr
**ep1
, struct expr
**ep2
)
845 struct expr
*tmp
= NULL
;
846 expr_extract_eq(E_OR
, &tmp
, ep1
, ep2
);
848 *ep1
= expr_eliminate_yn(*ep1
);
849 *ep2
= expr_eliminate_yn(*ep2
);
854 static void expr_extract_eq(enum expr_type type
, struct expr
**ep
, struct expr
**ep1
, struct expr
**ep2
)
858 if (e1
->type
== type
) {
859 expr_extract_eq(type
, ep
, &e1
->left
.expr
, &e2
);
860 expr_extract_eq(type
, ep
, &e1
->right
.expr
, &e2
);
863 if (e2
->type
== type
) {
864 expr_extract_eq(type
, ep
, ep1
, &e2
->left
.expr
);
865 expr_extract_eq(type
, ep
, ep1
, &e2
->right
.expr
);
868 if (expr_eq(e1
, e2
)) {
869 *ep
= *ep
? expr_alloc_two(type
, *ep
, e1
) : e1
;
872 e1
= expr_alloc_symbol(&symbol_yes
);
873 e2
= expr_alloc_symbol(&symbol_yes
);
874 } else if (type
== E_OR
) {
875 e1
= expr_alloc_symbol(&symbol_no
);
876 e2
= expr_alloc_symbol(&symbol_no
);
883 struct expr
*expr_trans_compare(struct expr
*e
, enum expr_type type
, struct symbol
*sym
)
885 struct expr
*e1
, *e2
;
888 e
= expr_alloc_symbol(sym
);
889 if (type
== E_UNEQUAL
)
890 e
= expr_alloc_one(E_NOT
, e
);
895 e1
= expr_trans_compare(e
->left
.expr
, E_EQUAL
, sym
);
896 e2
= expr_trans_compare(e
->right
.expr
, E_EQUAL
, sym
);
897 if (sym
== &symbol_yes
)
898 e
= expr_alloc_two(E_AND
, e1
, e2
);
899 if (sym
== &symbol_no
)
900 e
= expr_alloc_two(E_OR
, e1
, e2
);
901 if (type
== E_UNEQUAL
)
902 e
= expr_alloc_one(E_NOT
, e
);
905 e1
= expr_trans_compare(e
->left
.expr
, E_EQUAL
, sym
);
906 e2
= expr_trans_compare(e
->right
.expr
, E_EQUAL
, sym
);
907 if (sym
== &symbol_yes
)
908 e
= expr_alloc_two(E_OR
, e1
, e2
);
909 if (sym
== &symbol_no
)
910 e
= expr_alloc_two(E_AND
, e1
, e2
);
911 if (type
== E_UNEQUAL
)
912 e
= expr_alloc_one(E_NOT
, e
);
915 return expr_trans_compare(e
->left
.expr
, type
== E_EQUAL
? E_UNEQUAL
: E_EQUAL
, sym
);
918 if (type
== E_EQUAL
) {
919 if (sym
== &symbol_yes
)
921 if (sym
== &symbol_mod
)
922 return expr_alloc_symbol(&symbol_no
);
923 if (sym
== &symbol_no
)
924 return expr_alloc_one(E_NOT
, expr_copy(e
));
926 if (sym
== &symbol_yes
)
927 return expr_alloc_one(E_NOT
, expr_copy(e
));
928 if (sym
== &symbol_mod
)
929 return expr_alloc_symbol(&symbol_yes
);
930 if (sym
== &symbol_no
)
935 return expr_alloc_comp(type
, e
->left
.sym
, sym
);
944 tristate
expr_calc_value(struct expr
*e
)
947 const char *str1
, *str2
;
954 sym_calc_value(e
->left
.sym
);
955 return e
->left
.sym
->curr
.tri
;
957 val1
= expr_calc_value(e
->left
.expr
);
958 val2
= expr_calc_value(e
->right
.expr
);
959 return EXPR_AND(val1
, val2
);
961 val1
= expr_calc_value(e
->left
.expr
);
962 val2
= expr_calc_value(e
->right
.expr
);
963 return EXPR_OR(val1
, val2
);
965 val1
= expr_calc_value(e
->left
.expr
);
966 return EXPR_NOT(val1
);
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
) ? yes
: no
;
974 sym_calc_value(e
->left
.sym
);
975 sym_calc_value(e
->right
.sym
);
976 str1
= sym_get_string_value(e
->left
.sym
);
977 str2
= sym_get_string_value(e
->right
.sym
);
978 return !strcmp(str1
, str2
) ? no
: yes
;
980 printf("expr_calc_value: %d?\n", e
->type
);
985 static int expr_compare_type(enum expr_type t1
, enum expr_type t2
)
1009 printf("[%dgt%d?]", t1
, t2
);
1013 static inline struct expr
*
1014 expr_get_leftmost_symbol(const struct expr
*e
)
1020 while (e
->type
!= E_SYMBOL
)
1023 return expr_copy(e
);
1027 * Given expression `e1' and `e2', returns the leaf of the longest
1028 * sub-expression of `e1' not containing 'e2.
1030 struct expr
*expr_simplify_unmet_dep(struct expr
*e1
, struct expr
*e2
)
1036 return expr_alloc_and(
1037 expr_simplify_unmet_dep(e1
->left
.expr
, e2
),
1038 expr_simplify_unmet_dep(e1
->right
.expr
, e2
));
1041 e
= expr_alloc_and(expr_copy(e1
), expr_copy(e2
));
1042 e
= expr_eliminate_dups(e
);
1043 ret
= (!expr_eq(e
, e1
)) ? e1
: NULL
;
1052 return expr_get_leftmost_symbol(ret
);
1055 void expr_print(struct expr
*e
, void (*fn
)(void *, struct symbol
*, const char *), void *data
, int prevtoken
)
1058 fn(data
, NULL
, "y");
1062 if (expr_compare_type(prevtoken
, e
->type
) > 0)
1063 fn(data
, NULL
, "(");
1066 if (e
->left
.sym
->name
)
1067 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1069 fn(data
, NULL
, "<choice>");
1072 fn(data
, NULL
, "!");
1073 expr_print(e
->left
.expr
, fn
, data
, E_NOT
);
1076 if (e
->left
.sym
->name
)
1077 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1079 fn(data
, NULL
, "<choice>");
1080 fn(data
, NULL
, "=");
1081 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1084 if (e
->left
.sym
->name
)
1085 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1087 fn(data
, NULL
, "<choice>");
1088 fn(data
, NULL
, "!=");
1089 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1092 expr_print(e
->left
.expr
, fn
, data
, E_OR
);
1093 fn(data
, NULL
, " || ");
1094 expr_print(e
->right
.expr
, fn
, data
, E_OR
);
1097 expr_print(e
->left
.expr
, fn
, data
, E_AND
);
1098 fn(data
, NULL
, " && ");
1099 expr_print(e
->right
.expr
, fn
, data
, E_AND
);
1102 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1104 fn(data
, NULL
, " ^ ");
1105 expr_print(e
->left
.expr
, fn
, data
, E_LIST
);
1109 fn(data
, NULL
, "[");
1110 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1111 fn(data
, NULL
, " ");
1112 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1113 fn(data
, NULL
, "]");
1118 sprintf(buf
, "<unknown type %d>", e
->type
);
1119 fn(data
, NULL
, buf
);
1123 if (expr_compare_type(prevtoken
, e
->type
) > 0)
1124 fn(data
, NULL
, ")");
1127 static void expr_print_file_helper(void *data
, struct symbol
*sym
, const char *str
)
1129 xfwrite(str
, strlen(str
), 1, data
);
1132 void expr_fprint(struct expr
*e
, FILE *out
)
1134 expr_print(e
, expr_print_file_helper
, out
, E_NONE
);
1137 static void expr_print_gstr_helper(void *data
, struct symbol
*sym
, const char *str
)
1139 struct gstr
*gs
= (struct gstr
*)data
;
1140 const char *sym_str
= NULL
;
1143 sym_str
= sym_get_string_value(sym
);
1145 if (gs
->max_width
) {
1146 unsigned extra_length
= strlen(str
);
1147 const char *last_cr
= strrchr(gs
->s
, '\n');
1148 unsigned last_line_length
;
1151 extra_length
+= 4 + strlen(sym_str
);
1156 last_line_length
= strlen(gs
->s
) - (last_cr
- gs
->s
);
1158 if ((last_line_length
+ extra_length
) > gs
->max_width
)
1159 str_append(gs
, "\\\n");
1162 str_append(gs
, str
);
1163 if (sym
&& sym
->type
!= S_UNKNOWN
)
1164 str_printf(gs
, " [=%s]", sym_str
);
1167 void expr_gstr_print(struct expr
*e
, struct gstr
*gs
)
1169 expr_print(e
, expr_print_gstr_helper
, gs
, E_NONE
);