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 E_AND(val1
, val2
);
960 val1
= expr_calc_value(e
->left
.expr
);
961 val2
= expr_calc_value(e
->right
.expr
);
962 return E_OR(val1
, val2
);
964 val1
= expr_calc_value(e
->left
.expr
);
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
);