xref: /rk3399_rockchip-uboot/scripts/kconfig/expr.c (revision 0a9064fb47bb0a239c04b0b63edebfdd3a201fdc)
1*0a9064fbSMasahiro Yamada /*
2*0a9064fbSMasahiro Yamada  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3*0a9064fbSMasahiro Yamada  * Released under the terms of the GNU GPL v2.0.
4*0a9064fbSMasahiro Yamada  */
5*0a9064fbSMasahiro Yamada 
6*0a9064fbSMasahiro Yamada #include <stdio.h>
7*0a9064fbSMasahiro Yamada #include <stdlib.h>
8*0a9064fbSMasahiro Yamada #include <string.h>
9*0a9064fbSMasahiro Yamada 
10*0a9064fbSMasahiro Yamada #include "lkc.h"
11*0a9064fbSMasahiro Yamada 
12*0a9064fbSMasahiro Yamada #define DEBUG_EXPR	0
13*0a9064fbSMasahiro Yamada 
14*0a9064fbSMasahiro Yamada struct expr *expr_alloc_symbol(struct symbol *sym)
15*0a9064fbSMasahiro Yamada {
16*0a9064fbSMasahiro Yamada 	struct expr *e = xcalloc(1, sizeof(*e));
17*0a9064fbSMasahiro Yamada 	e->type = E_SYMBOL;
18*0a9064fbSMasahiro Yamada 	e->left.sym = sym;
19*0a9064fbSMasahiro Yamada 	return e;
20*0a9064fbSMasahiro Yamada }
21*0a9064fbSMasahiro Yamada 
22*0a9064fbSMasahiro Yamada struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
23*0a9064fbSMasahiro Yamada {
24*0a9064fbSMasahiro Yamada 	struct expr *e = xcalloc(1, sizeof(*e));
25*0a9064fbSMasahiro Yamada 	e->type = type;
26*0a9064fbSMasahiro Yamada 	e->left.expr = ce;
27*0a9064fbSMasahiro Yamada 	return e;
28*0a9064fbSMasahiro Yamada }
29*0a9064fbSMasahiro Yamada 
30*0a9064fbSMasahiro Yamada struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
31*0a9064fbSMasahiro Yamada {
32*0a9064fbSMasahiro Yamada 	struct expr *e = xcalloc(1, sizeof(*e));
33*0a9064fbSMasahiro Yamada 	e->type = type;
34*0a9064fbSMasahiro Yamada 	e->left.expr = e1;
35*0a9064fbSMasahiro Yamada 	e->right.expr = e2;
36*0a9064fbSMasahiro Yamada 	return e;
37*0a9064fbSMasahiro Yamada }
38*0a9064fbSMasahiro Yamada 
39*0a9064fbSMasahiro Yamada struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
40*0a9064fbSMasahiro Yamada {
41*0a9064fbSMasahiro Yamada 	struct expr *e = xcalloc(1, sizeof(*e));
42*0a9064fbSMasahiro Yamada 	e->type = type;
43*0a9064fbSMasahiro Yamada 	e->left.sym = s1;
44*0a9064fbSMasahiro Yamada 	e->right.sym = s2;
45*0a9064fbSMasahiro Yamada 	return e;
46*0a9064fbSMasahiro Yamada }
47*0a9064fbSMasahiro Yamada 
48*0a9064fbSMasahiro Yamada struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
49*0a9064fbSMasahiro Yamada {
50*0a9064fbSMasahiro Yamada 	if (!e1)
51*0a9064fbSMasahiro Yamada 		return e2;
52*0a9064fbSMasahiro Yamada 	return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
53*0a9064fbSMasahiro Yamada }
54*0a9064fbSMasahiro Yamada 
55*0a9064fbSMasahiro Yamada struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
56*0a9064fbSMasahiro Yamada {
57*0a9064fbSMasahiro Yamada 	if (!e1)
58*0a9064fbSMasahiro Yamada 		return e2;
59*0a9064fbSMasahiro Yamada 	return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
60*0a9064fbSMasahiro Yamada }
61*0a9064fbSMasahiro Yamada 
62*0a9064fbSMasahiro Yamada struct expr *expr_copy(const struct expr *org)
63*0a9064fbSMasahiro Yamada {
64*0a9064fbSMasahiro Yamada 	struct expr *e;
65*0a9064fbSMasahiro Yamada 
66*0a9064fbSMasahiro Yamada 	if (!org)
67*0a9064fbSMasahiro Yamada 		return NULL;
68*0a9064fbSMasahiro Yamada 
69*0a9064fbSMasahiro Yamada 	e = xmalloc(sizeof(*org));
70*0a9064fbSMasahiro Yamada 	memcpy(e, org, sizeof(*org));
71*0a9064fbSMasahiro Yamada 	switch (org->type) {
72*0a9064fbSMasahiro Yamada 	case E_SYMBOL:
73*0a9064fbSMasahiro Yamada 		e->left = org->left;
74*0a9064fbSMasahiro Yamada 		break;
75*0a9064fbSMasahiro Yamada 	case E_NOT:
76*0a9064fbSMasahiro Yamada 		e->left.expr = expr_copy(org->left.expr);
77*0a9064fbSMasahiro Yamada 		break;
78*0a9064fbSMasahiro Yamada 	case E_EQUAL:
79*0a9064fbSMasahiro Yamada 	case E_UNEQUAL:
80*0a9064fbSMasahiro Yamada 		e->left.sym = org->left.sym;
81*0a9064fbSMasahiro Yamada 		e->right.sym = org->right.sym;
82*0a9064fbSMasahiro Yamada 		break;
83*0a9064fbSMasahiro Yamada 	case E_AND:
84*0a9064fbSMasahiro Yamada 	case E_OR:
85*0a9064fbSMasahiro Yamada 	case E_LIST:
86*0a9064fbSMasahiro Yamada 		e->left.expr = expr_copy(org->left.expr);
87*0a9064fbSMasahiro Yamada 		e->right.expr = expr_copy(org->right.expr);
88*0a9064fbSMasahiro Yamada 		break;
89*0a9064fbSMasahiro Yamada 	default:
90*0a9064fbSMasahiro Yamada 		printf("can't copy type %d\n", e->type);
91*0a9064fbSMasahiro Yamada 		free(e);
92*0a9064fbSMasahiro Yamada 		e = NULL;
93*0a9064fbSMasahiro Yamada 		break;
94*0a9064fbSMasahiro Yamada 	}
95*0a9064fbSMasahiro Yamada 
96*0a9064fbSMasahiro Yamada 	return e;
97*0a9064fbSMasahiro Yamada }
98*0a9064fbSMasahiro Yamada 
99*0a9064fbSMasahiro Yamada void expr_free(struct expr *e)
100*0a9064fbSMasahiro Yamada {
101*0a9064fbSMasahiro Yamada 	if (!e)
102*0a9064fbSMasahiro Yamada 		return;
103*0a9064fbSMasahiro Yamada 
104*0a9064fbSMasahiro Yamada 	switch (e->type) {
105*0a9064fbSMasahiro Yamada 	case E_SYMBOL:
106*0a9064fbSMasahiro Yamada 		break;
107*0a9064fbSMasahiro Yamada 	case E_NOT:
108*0a9064fbSMasahiro Yamada 		expr_free(e->left.expr);
109*0a9064fbSMasahiro Yamada 		return;
110*0a9064fbSMasahiro Yamada 	case E_EQUAL:
111*0a9064fbSMasahiro Yamada 	case E_UNEQUAL:
112*0a9064fbSMasahiro Yamada 		break;
113*0a9064fbSMasahiro Yamada 	case E_OR:
114*0a9064fbSMasahiro Yamada 	case E_AND:
115*0a9064fbSMasahiro Yamada 		expr_free(e->left.expr);
116*0a9064fbSMasahiro Yamada 		expr_free(e->right.expr);
117*0a9064fbSMasahiro Yamada 		break;
118*0a9064fbSMasahiro Yamada 	default:
119*0a9064fbSMasahiro Yamada 		printf("how to free type %d?\n", e->type);
120*0a9064fbSMasahiro Yamada 		break;
121*0a9064fbSMasahiro Yamada 	}
122*0a9064fbSMasahiro Yamada 	free(e);
123*0a9064fbSMasahiro Yamada }
124*0a9064fbSMasahiro Yamada 
125*0a9064fbSMasahiro Yamada static int trans_count;
126*0a9064fbSMasahiro Yamada 
127*0a9064fbSMasahiro Yamada #define e1 (*ep1)
128*0a9064fbSMasahiro Yamada #define e2 (*ep2)
129*0a9064fbSMasahiro Yamada 
130*0a9064fbSMasahiro Yamada static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
131*0a9064fbSMasahiro Yamada {
132*0a9064fbSMasahiro Yamada 	if (e1->type == type) {
133*0a9064fbSMasahiro Yamada 		__expr_eliminate_eq(type, &e1->left.expr, &e2);
134*0a9064fbSMasahiro Yamada 		__expr_eliminate_eq(type, &e1->right.expr, &e2);
135*0a9064fbSMasahiro Yamada 		return;
136*0a9064fbSMasahiro Yamada 	}
137*0a9064fbSMasahiro Yamada 	if (e2->type == type) {
138*0a9064fbSMasahiro Yamada 		__expr_eliminate_eq(type, &e1, &e2->left.expr);
139*0a9064fbSMasahiro Yamada 		__expr_eliminate_eq(type, &e1, &e2->right.expr);
140*0a9064fbSMasahiro Yamada 		return;
141*0a9064fbSMasahiro Yamada 	}
142*0a9064fbSMasahiro Yamada 	if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
143*0a9064fbSMasahiro Yamada 	    e1->left.sym == e2->left.sym &&
144*0a9064fbSMasahiro Yamada 	    (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
145*0a9064fbSMasahiro Yamada 		return;
146*0a9064fbSMasahiro Yamada 	if (!expr_eq(e1, e2))
147*0a9064fbSMasahiro Yamada 		return;
148*0a9064fbSMasahiro Yamada 	trans_count++;
149*0a9064fbSMasahiro Yamada 	expr_free(e1); expr_free(e2);
150*0a9064fbSMasahiro Yamada 	switch (type) {
151*0a9064fbSMasahiro Yamada 	case E_OR:
152*0a9064fbSMasahiro Yamada 		e1 = expr_alloc_symbol(&symbol_no);
153*0a9064fbSMasahiro Yamada 		e2 = expr_alloc_symbol(&symbol_no);
154*0a9064fbSMasahiro Yamada 		break;
155*0a9064fbSMasahiro Yamada 	case E_AND:
156*0a9064fbSMasahiro Yamada 		e1 = expr_alloc_symbol(&symbol_yes);
157*0a9064fbSMasahiro Yamada 		e2 = expr_alloc_symbol(&symbol_yes);
158*0a9064fbSMasahiro Yamada 		break;
159*0a9064fbSMasahiro Yamada 	default:
160*0a9064fbSMasahiro Yamada 		;
161*0a9064fbSMasahiro Yamada 	}
162*0a9064fbSMasahiro Yamada }
163*0a9064fbSMasahiro Yamada 
164*0a9064fbSMasahiro Yamada void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
165*0a9064fbSMasahiro Yamada {
166*0a9064fbSMasahiro Yamada 	if (!e1 || !e2)
167*0a9064fbSMasahiro Yamada 		return;
168*0a9064fbSMasahiro Yamada 	switch (e1->type) {
169*0a9064fbSMasahiro Yamada 	case E_OR:
170*0a9064fbSMasahiro Yamada 	case E_AND:
171*0a9064fbSMasahiro Yamada 		__expr_eliminate_eq(e1->type, ep1, ep2);
172*0a9064fbSMasahiro Yamada 	default:
173*0a9064fbSMasahiro Yamada 		;
174*0a9064fbSMasahiro Yamada 	}
175*0a9064fbSMasahiro Yamada 	if (e1->type != e2->type) switch (e2->type) {
176*0a9064fbSMasahiro Yamada 	case E_OR:
177*0a9064fbSMasahiro Yamada 	case E_AND:
178*0a9064fbSMasahiro Yamada 		__expr_eliminate_eq(e2->type, ep1, ep2);
179*0a9064fbSMasahiro Yamada 	default:
180*0a9064fbSMasahiro Yamada 		;
181*0a9064fbSMasahiro Yamada 	}
182*0a9064fbSMasahiro Yamada 	e1 = expr_eliminate_yn(e1);
183*0a9064fbSMasahiro Yamada 	e2 = expr_eliminate_yn(e2);
184*0a9064fbSMasahiro Yamada }
185*0a9064fbSMasahiro Yamada 
186*0a9064fbSMasahiro Yamada #undef e1
187*0a9064fbSMasahiro Yamada #undef e2
188*0a9064fbSMasahiro Yamada 
189*0a9064fbSMasahiro Yamada int expr_eq(struct expr *e1, struct expr *e2)
190*0a9064fbSMasahiro Yamada {
191*0a9064fbSMasahiro Yamada 	int res, old_count;
192*0a9064fbSMasahiro Yamada 
193*0a9064fbSMasahiro Yamada 	if (e1->type != e2->type)
194*0a9064fbSMasahiro Yamada 		return 0;
195*0a9064fbSMasahiro Yamada 	switch (e1->type) {
196*0a9064fbSMasahiro Yamada 	case E_EQUAL:
197*0a9064fbSMasahiro Yamada 	case E_UNEQUAL:
198*0a9064fbSMasahiro Yamada 		return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
199*0a9064fbSMasahiro Yamada 	case E_SYMBOL:
200*0a9064fbSMasahiro Yamada 		return e1->left.sym == e2->left.sym;
201*0a9064fbSMasahiro Yamada 	case E_NOT:
202*0a9064fbSMasahiro Yamada 		return expr_eq(e1->left.expr, e2->left.expr);
203*0a9064fbSMasahiro Yamada 	case E_AND:
204*0a9064fbSMasahiro Yamada 	case E_OR:
205*0a9064fbSMasahiro Yamada 		e1 = expr_copy(e1);
206*0a9064fbSMasahiro Yamada 		e2 = expr_copy(e2);
207*0a9064fbSMasahiro Yamada 		old_count = trans_count;
208*0a9064fbSMasahiro Yamada 		expr_eliminate_eq(&e1, &e2);
209*0a9064fbSMasahiro Yamada 		res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
210*0a9064fbSMasahiro Yamada 		       e1->left.sym == e2->left.sym);
211*0a9064fbSMasahiro Yamada 		expr_free(e1);
212*0a9064fbSMasahiro Yamada 		expr_free(e2);
213*0a9064fbSMasahiro Yamada 		trans_count = old_count;
214*0a9064fbSMasahiro Yamada 		return res;
215*0a9064fbSMasahiro Yamada 	case E_LIST:
216*0a9064fbSMasahiro Yamada 	case E_RANGE:
217*0a9064fbSMasahiro Yamada 	case E_NONE:
218*0a9064fbSMasahiro Yamada 		/* panic */;
219*0a9064fbSMasahiro Yamada 	}
220*0a9064fbSMasahiro Yamada 
221*0a9064fbSMasahiro Yamada 	if (DEBUG_EXPR) {
222*0a9064fbSMasahiro Yamada 		expr_fprint(e1, stdout);
223*0a9064fbSMasahiro Yamada 		printf(" = ");
224*0a9064fbSMasahiro Yamada 		expr_fprint(e2, stdout);
225*0a9064fbSMasahiro Yamada 		printf(" ?\n");
226*0a9064fbSMasahiro Yamada 	}
227*0a9064fbSMasahiro Yamada 
228*0a9064fbSMasahiro Yamada 	return 0;
229*0a9064fbSMasahiro Yamada }
230*0a9064fbSMasahiro Yamada 
231*0a9064fbSMasahiro Yamada struct expr *expr_eliminate_yn(struct expr *e)
232*0a9064fbSMasahiro Yamada {
233*0a9064fbSMasahiro Yamada 	struct expr *tmp;
234*0a9064fbSMasahiro Yamada 
235*0a9064fbSMasahiro Yamada 	if (e) switch (e->type) {
236*0a9064fbSMasahiro Yamada 	case E_AND:
237*0a9064fbSMasahiro Yamada 		e->left.expr = expr_eliminate_yn(e->left.expr);
238*0a9064fbSMasahiro Yamada 		e->right.expr = expr_eliminate_yn(e->right.expr);
239*0a9064fbSMasahiro Yamada 		if (e->left.expr->type == E_SYMBOL) {
240*0a9064fbSMasahiro Yamada 			if (e->left.expr->left.sym == &symbol_no) {
241*0a9064fbSMasahiro Yamada 				expr_free(e->left.expr);
242*0a9064fbSMasahiro Yamada 				expr_free(e->right.expr);
243*0a9064fbSMasahiro Yamada 				e->type = E_SYMBOL;
244*0a9064fbSMasahiro Yamada 				e->left.sym = &symbol_no;
245*0a9064fbSMasahiro Yamada 				e->right.expr = NULL;
246*0a9064fbSMasahiro Yamada 				return e;
247*0a9064fbSMasahiro Yamada 			} else if (e->left.expr->left.sym == &symbol_yes) {
248*0a9064fbSMasahiro Yamada 				free(e->left.expr);
249*0a9064fbSMasahiro Yamada 				tmp = e->right.expr;
250*0a9064fbSMasahiro Yamada 				*e = *(e->right.expr);
251*0a9064fbSMasahiro Yamada 				free(tmp);
252*0a9064fbSMasahiro Yamada 				return e;
253*0a9064fbSMasahiro Yamada 			}
254*0a9064fbSMasahiro Yamada 		}
255*0a9064fbSMasahiro Yamada 		if (e->right.expr->type == E_SYMBOL) {
256*0a9064fbSMasahiro Yamada 			if (e->right.expr->left.sym == &symbol_no) {
257*0a9064fbSMasahiro Yamada 				expr_free(e->left.expr);
258*0a9064fbSMasahiro Yamada 				expr_free(e->right.expr);
259*0a9064fbSMasahiro Yamada 				e->type = E_SYMBOL;
260*0a9064fbSMasahiro Yamada 				e->left.sym = &symbol_no;
261*0a9064fbSMasahiro Yamada 				e->right.expr = NULL;
262*0a9064fbSMasahiro Yamada 				return e;
263*0a9064fbSMasahiro Yamada 			} else if (e->right.expr->left.sym == &symbol_yes) {
264*0a9064fbSMasahiro Yamada 				free(e->right.expr);
265*0a9064fbSMasahiro Yamada 				tmp = e->left.expr;
266*0a9064fbSMasahiro Yamada 				*e = *(e->left.expr);
267*0a9064fbSMasahiro Yamada 				free(tmp);
268*0a9064fbSMasahiro Yamada 				return e;
269*0a9064fbSMasahiro Yamada 			}
270*0a9064fbSMasahiro Yamada 		}
271*0a9064fbSMasahiro Yamada 		break;
272*0a9064fbSMasahiro Yamada 	case E_OR:
273*0a9064fbSMasahiro Yamada 		e->left.expr = expr_eliminate_yn(e->left.expr);
274*0a9064fbSMasahiro Yamada 		e->right.expr = expr_eliminate_yn(e->right.expr);
275*0a9064fbSMasahiro Yamada 		if (e->left.expr->type == E_SYMBOL) {
276*0a9064fbSMasahiro Yamada 			if (e->left.expr->left.sym == &symbol_no) {
277*0a9064fbSMasahiro Yamada 				free(e->left.expr);
278*0a9064fbSMasahiro Yamada 				tmp = e->right.expr;
279*0a9064fbSMasahiro Yamada 				*e = *(e->right.expr);
280*0a9064fbSMasahiro Yamada 				free(tmp);
281*0a9064fbSMasahiro Yamada 				return e;
282*0a9064fbSMasahiro Yamada 			} else if (e->left.expr->left.sym == &symbol_yes) {
283*0a9064fbSMasahiro Yamada 				expr_free(e->left.expr);
284*0a9064fbSMasahiro Yamada 				expr_free(e->right.expr);
285*0a9064fbSMasahiro Yamada 				e->type = E_SYMBOL;
286*0a9064fbSMasahiro Yamada 				e->left.sym = &symbol_yes;
287*0a9064fbSMasahiro Yamada 				e->right.expr = NULL;
288*0a9064fbSMasahiro Yamada 				return e;
289*0a9064fbSMasahiro Yamada 			}
290*0a9064fbSMasahiro Yamada 		}
291*0a9064fbSMasahiro Yamada 		if (e->right.expr->type == E_SYMBOL) {
292*0a9064fbSMasahiro Yamada 			if (e->right.expr->left.sym == &symbol_no) {
293*0a9064fbSMasahiro Yamada 				free(e->right.expr);
294*0a9064fbSMasahiro Yamada 				tmp = e->left.expr;
295*0a9064fbSMasahiro Yamada 				*e = *(e->left.expr);
296*0a9064fbSMasahiro Yamada 				free(tmp);
297*0a9064fbSMasahiro Yamada 				return e;
298*0a9064fbSMasahiro Yamada 			} else if (e->right.expr->left.sym == &symbol_yes) {
299*0a9064fbSMasahiro Yamada 				expr_free(e->left.expr);
300*0a9064fbSMasahiro Yamada 				expr_free(e->right.expr);
301*0a9064fbSMasahiro Yamada 				e->type = E_SYMBOL;
302*0a9064fbSMasahiro Yamada 				e->left.sym = &symbol_yes;
303*0a9064fbSMasahiro Yamada 				e->right.expr = NULL;
304*0a9064fbSMasahiro Yamada 				return e;
305*0a9064fbSMasahiro Yamada 			}
306*0a9064fbSMasahiro Yamada 		}
307*0a9064fbSMasahiro Yamada 		break;
308*0a9064fbSMasahiro Yamada 	default:
309*0a9064fbSMasahiro Yamada 		;
310*0a9064fbSMasahiro Yamada 	}
311*0a9064fbSMasahiro Yamada 	return e;
312*0a9064fbSMasahiro Yamada }
313*0a9064fbSMasahiro Yamada 
314*0a9064fbSMasahiro Yamada /*
315*0a9064fbSMasahiro Yamada  * bool FOO!=n => FOO
316*0a9064fbSMasahiro Yamada  */
317*0a9064fbSMasahiro Yamada struct expr *expr_trans_bool(struct expr *e)
318*0a9064fbSMasahiro Yamada {
319*0a9064fbSMasahiro Yamada 	if (!e)
320*0a9064fbSMasahiro Yamada 		return NULL;
321*0a9064fbSMasahiro Yamada 	switch (e->type) {
322*0a9064fbSMasahiro Yamada 	case E_AND:
323*0a9064fbSMasahiro Yamada 	case E_OR:
324*0a9064fbSMasahiro Yamada 	case E_NOT:
325*0a9064fbSMasahiro Yamada 		e->left.expr = expr_trans_bool(e->left.expr);
326*0a9064fbSMasahiro Yamada 		e->right.expr = expr_trans_bool(e->right.expr);
327*0a9064fbSMasahiro Yamada 		break;
328*0a9064fbSMasahiro Yamada 	case E_UNEQUAL:
329*0a9064fbSMasahiro Yamada 		// FOO!=n -> FOO
330*0a9064fbSMasahiro Yamada 		if (e->left.sym->type == S_TRISTATE) {
331*0a9064fbSMasahiro Yamada 			if (e->right.sym == &symbol_no) {
332*0a9064fbSMasahiro Yamada 				e->type = E_SYMBOL;
333*0a9064fbSMasahiro Yamada 				e->right.sym = NULL;
334*0a9064fbSMasahiro Yamada 			}
335*0a9064fbSMasahiro Yamada 		}
336*0a9064fbSMasahiro Yamada 		break;
337*0a9064fbSMasahiro Yamada 	default:
338*0a9064fbSMasahiro Yamada 		;
339*0a9064fbSMasahiro Yamada 	}
340*0a9064fbSMasahiro Yamada 	return e;
341*0a9064fbSMasahiro Yamada }
342*0a9064fbSMasahiro Yamada 
343*0a9064fbSMasahiro Yamada /*
344*0a9064fbSMasahiro Yamada  * e1 || e2 -> ?
345*0a9064fbSMasahiro Yamada  */
346*0a9064fbSMasahiro Yamada static struct expr *expr_join_or(struct expr *e1, struct expr *e2)
347*0a9064fbSMasahiro Yamada {
348*0a9064fbSMasahiro Yamada 	struct expr *tmp;
349*0a9064fbSMasahiro Yamada 	struct symbol *sym1, *sym2;
350*0a9064fbSMasahiro Yamada 
351*0a9064fbSMasahiro Yamada 	if (expr_eq(e1, e2))
352*0a9064fbSMasahiro Yamada 		return expr_copy(e1);
353*0a9064fbSMasahiro Yamada 	if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
354*0a9064fbSMasahiro Yamada 		return NULL;
355*0a9064fbSMasahiro Yamada 	if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
356*0a9064fbSMasahiro Yamada 		return NULL;
357*0a9064fbSMasahiro Yamada 	if (e1->type == E_NOT) {
358*0a9064fbSMasahiro Yamada 		tmp = e1->left.expr;
359*0a9064fbSMasahiro Yamada 		if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
360*0a9064fbSMasahiro Yamada 			return NULL;
361*0a9064fbSMasahiro Yamada 		sym1 = tmp->left.sym;
362*0a9064fbSMasahiro Yamada 	} else
363*0a9064fbSMasahiro Yamada 		sym1 = e1->left.sym;
364*0a9064fbSMasahiro Yamada 	if (e2->type == E_NOT) {
365*0a9064fbSMasahiro Yamada 		if (e2->left.expr->type != E_SYMBOL)
366*0a9064fbSMasahiro Yamada 			return NULL;
367*0a9064fbSMasahiro Yamada 		sym2 = e2->left.expr->left.sym;
368*0a9064fbSMasahiro Yamada 	} else
369*0a9064fbSMasahiro Yamada 		sym2 = e2->left.sym;
370*0a9064fbSMasahiro Yamada 	if (sym1 != sym2)
371*0a9064fbSMasahiro Yamada 		return NULL;
372*0a9064fbSMasahiro Yamada 	if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
373*0a9064fbSMasahiro Yamada 		return NULL;
374*0a9064fbSMasahiro Yamada 	if (sym1->type == S_TRISTATE) {
375*0a9064fbSMasahiro Yamada 		if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
376*0a9064fbSMasahiro Yamada 		    ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
377*0a9064fbSMasahiro Yamada 		     (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
378*0a9064fbSMasahiro Yamada 			// (a='y') || (a='m') -> (a!='n')
379*0a9064fbSMasahiro Yamada 			return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
380*0a9064fbSMasahiro Yamada 		}
381*0a9064fbSMasahiro Yamada 		if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
382*0a9064fbSMasahiro Yamada 		    ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
383*0a9064fbSMasahiro Yamada 		     (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
384*0a9064fbSMasahiro Yamada 			// (a='y') || (a='n') -> (a!='m')
385*0a9064fbSMasahiro Yamada 			return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
386*0a9064fbSMasahiro Yamada 		}
387*0a9064fbSMasahiro Yamada 		if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
388*0a9064fbSMasahiro Yamada 		    ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
389*0a9064fbSMasahiro Yamada 		     (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
390*0a9064fbSMasahiro Yamada 			// (a='m') || (a='n') -> (a!='y')
391*0a9064fbSMasahiro Yamada 			return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
392*0a9064fbSMasahiro Yamada 		}
393*0a9064fbSMasahiro Yamada 	}
394*0a9064fbSMasahiro Yamada 	if (sym1->type == S_BOOLEAN && sym1 == sym2) {
395*0a9064fbSMasahiro Yamada 		if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
396*0a9064fbSMasahiro Yamada 		    (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
397*0a9064fbSMasahiro Yamada 			return expr_alloc_symbol(&symbol_yes);
398*0a9064fbSMasahiro Yamada 	}
399*0a9064fbSMasahiro Yamada 
400*0a9064fbSMasahiro Yamada 	if (DEBUG_EXPR) {
401*0a9064fbSMasahiro Yamada 		printf("optimize (");
402*0a9064fbSMasahiro Yamada 		expr_fprint(e1, stdout);
403*0a9064fbSMasahiro Yamada 		printf(") || (");
404*0a9064fbSMasahiro Yamada 		expr_fprint(e2, stdout);
405*0a9064fbSMasahiro Yamada 		printf(")?\n");
406*0a9064fbSMasahiro Yamada 	}
407*0a9064fbSMasahiro Yamada 	return NULL;
408*0a9064fbSMasahiro Yamada }
409*0a9064fbSMasahiro Yamada 
410*0a9064fbSMasahiro Yamada static struct expr *expr_join_and(struct expr *e1, struct expr *e2)
411*0a9064fbSMasahiro Yamada {
412*0a9064fbSMasahiro Yamada 	struct expr *tmp;
413*0a9064fbSMasahiro Yamada 	struct symbol *sym1, *sym2;
414*0a9064fbSMasahiro Yamada 
415*0a9064fbSMasahiro Yamada 	if (expr_eq(e1, e2))
416*0a9064fbSMasahiro Yamada 		return expr_copy(e1);
417*0a9064fbSMasahiro Yamada 	if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
418*0a9064fbSMasahiro Yamada 		return NULL;
419*0a9064fbSMasahiro Yamada 	if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
420*0a9064fbSMasahiro Yamada 		return NULL;
421*0a9064fbSMasahiro Yamada 	if (e1->type == E_NOT) {
422*0a9064fbSMasahiro Yamada 		tmp = e1->left.expr;
423*0a9064fbSMasahiro Yamada 		if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
424*0a9064fbSMasahiro Yamada 			return NULL;
425*0a9064fbSMasahiro Yamada 		sym1 = tmp->left.sym;
426*0a9064fbSMasahiro Yamada 	} else
427*0a9064fbSMasahiro Yamada 		sym1 = e1->left.sym;
428*0a9064fbSMasahiro Yamada 	if (e2->type == E_NOT) {
429*0a9064fbSMasahiro Yamada 		if (e2->left.expr->type != E_SYMBOL)
430*0a9064fbSMasahiro Yamada 			return NULL;
431*0a9064fbSMasahiro Yamada 		sym2 = e2->left.expr->left.sym;
432*0a9064fbSMasahiro Yamada 	} else
433*0a9064fbSMasahiro Yamada 		sym2 = e2->left.sym;
434*0a9064fbSMasahiro Yamada 	if (sym1 != sym2)
435*0a9064fbSMasahiro Yamada 		return NULL;
436*0a9064fbSMasahiro Yamada 	if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
437*0a9064fbSMasahiro Yamada 		return NULL;
438*0a9064fbSMasahiro Yamada 
439*0a9064fbSMasahiro Yamada 	if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
440*0a9064fbSMasahiro Yamada 	    (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
441*0a9064fbSMasahiro Yamada 		// (a) && (a='y') -> (a='y')
442*0a9064fbSMasahiro Yamada 		return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
443*0a9064fbSMasahiro Yamada 
444*0a9064fbSMasahiro Yamada 	if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
445*0a9064fbSMasahiro Yamada 	    (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
446*0a9064fbSMasahiro Yamada 		// (a) && (a!='n') -> (a)
447*0a9064fbSMasahiro Yamada 		return expr_alloc_symbol(sym1);
448*0a9064fbSMasahiro Yamada 
449*0a9064fbSMasahiro Yamada 	if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) ||
450*0a9064fbSMasahiro Yamada 	    (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod))
451*0a9064fbSMasahiro Yamada 		// (a) && (a!='m') -> (a='y')
452*0a9064fbSMasahiro Yamada 		return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
453*0a9064fbSMasahiro Yamada 
454*0a9064fbSMasahiro Yamada 	if (sym1->type == S_TRISTATE) {
455*0a9064fbSMasahiro Yamada 		if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
456*0a9064fbSMasahiro Yamada 			// (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
457*0a9064fbSMasahiro Yamada 			sym2 = e1->right.sym;
458*0a9064fbSMasahiro Yamada 			if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
459*0a9064fbSMasahiro Yamada 				return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
460*0a9064fbSMasahiro Yamada 							     : expr_alloc_symbol(&symbol_no);
461*0a9064fbSMasahiro Yamada 		}
462*0a9064fbSMasahiro Yamada 		if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
463*0a9064fbSMasahiro Yamada 			// (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
464*0a9064fbSMasahiro Yamada 			sym2 = e2->right.sym;
465*0a9064fbSMasahiro Yamada 			if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
466*0a9064fbSMasahiro Yamada 				return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
467*0a9064fbSMasahiro Yamada 							     : expr_alloc_symbol(&symbol_no);
468*0a9064fbSMasahiro Yamada 		}
469*0a9064fbSMasahiro Yamada 		if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
470*0a9064fbSMasahiro Yamada 			   ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
471*0a9064fbSMasahiro Yamada 			    (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
472*0a9064fbSMasahiro Yamada 			// (a!='y') && (a!='n') -> (a='m')
473*0a9064fbSMasahiro Yamada 			return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
474*0a9064fbSMasahiro Yamada 
475*0a9064fbSMasahiro Yamada 		if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
476*0a9064fbSMasahiro Yamada 			   ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
477*0a9064fbSMasahiro Yamada 			    (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
478*0a9064fbSMasahiro Yamada 			// (a!='y') && (a!='m') -> (a='n')
479*0a9064fbSMasahiro Yamada 			return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
480*0a9064fbSMasahiro Yamada 
481*0a9064fbSMasahiro Yamada 		if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
482*0a9064fbSMasahiro Yamada 			   ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
483*0a9064fbSMasahiro Yamada 			    (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
484*0a9064fbSMasahiro Yamada 			// (a!='m') && (a!='n') -> (a='m')
485*0a9064fbSMasahiro Yamada 			return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
486*0a9064fbSMasahiro Yamada 
487*0a9064fbSMasahiro Yamada 		if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
488*0a9064fbSMasahiro Yamada 		    (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
489*0a9064fbSMasahiro Yamada 		    (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
490*0a9064fbSMasahiro Yamada 		    (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
491*0a9064fbSMasahiro Yamada 			return NULL;
492*0a9064fbSMasahiro Yamada 	}
493*0a9064fbSMasahiro Yamada 
494*0a9064fbSMasahiro Yamada 	if (DEBUG_EXPR) {
495*0a9064fbSMasahiro Yamada 		printf("optimize (");
496*0a9064fbSMasahiro Yamada 		expr_fprint(e1, stdout);
497*0a9064fbSMasahiro Yamada 		printf(") && (");
498*0a9064fbSMasahiro Yamada 		expr_fprint(e2, stdout);
499*0a9064fbSMasahiro Yamada 		printf(")?\n");
500*0a9064fbSMasahiro Yamada 	}
501*0a9064fbSMasahiro Yamada 	return NULL;
502*0a9064fbSMasahiro Yamada }
503*0a9064fbSMasahiro Yamada 
504*0a9064fbSMasahiro Yamada static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
505*0a9064fbSMasahiro Yamada {
506*0a9064fbSMasahiro Yamada #define e1 (*ep1)
507*0a9064fbSMasahiro Yamada #define e2 (*ep2)
508*0a9064fbSMasahiro Yamada 	struct expr *tmp;
509*0a9064fbSMasahiro Yamada 
510*0a9064fbSMasahiro Yamada 	if (e1->type == type) {
511*0a9064fbSMasahiro Yamada 		expr_eliminate_dups1(type, &e1->left.expr, &e2);
512*0a9064fbSMasahiro Yamada 		expr_eliminate_dups1(type, &e1->right.expr, &e2);
513*0a9064fbSMasahiro Yamada 		return;
514*0a9064fbSMasahiro Yamada 	}
515*0a9064fbSMasahiro Yamada 	if (e2->type == type) {
516*0a9064fbSMasahiro Yamada 		expr_eliminate_dups1(type, &e1, &e2->left.expr);
517*0a9064fbSMasahiro Yamada 		expr_eliminate_dups1(type, &e1, &e2->right.expr);
518*0a9064fbSMasahiro Yamada 		return;
519*0a9064fbSMasahiro Yamada 	}
520*0a9064fbSMasahiro Yamada 	if (e1 == e2)
521*0a9064fbSMasahiro Yamada 		return;
522*0a9064fbSMasahiro Yamada 
523*0a9064fbSMasahiro Yamada 	switch (e1->type) {
524*0a9064fbSMasahiro Yamada 	case E_OR: case E_AND:
525*0a9064fbSMasahiro Yamada 		expr_eliminate_dups1(e1->type, &e1, &e1);
526*0a9064fbSMasahiro Yamada 	default:
527*0a9064fbSMasahiro Yamada 		;
528*0a9064fbSMasahiro Yamada 	}
529*0a9064fbSMasahiro Yamada 
530*0a9064fbSMasahiro Yamada 	switch (type) {
531*0a9064fbSMasahiro Yamada 	case E_OR:
532*0a9064fbSMasahiro Yamada 		tmp = expr_join_or(e1, e2);
533*0a9064fbSMasahiro Yamada 		if (tmp) {
534*0a9064fbSMasahiro Yamada 			expr_free(e1); expr_free(e2);
535*0a9064fbSMasahiro Yamada 			e1 = expr_alloc_symbol(&symbol_no);
536*0a9064fbSMasahiro Yamada 			e2 = tmp;
537*0a9064fbSMasahiro Yamada 			trans_count++;
538*0a9064fbSMasahiro Yamada 		}
539*0a9064fbSMasahiro Yamada 		break;
540*0a9064fbSMasahiro Yamada 	case E_AND:
541*0a9064fbSMasahiro Yamada 		tmp = expr_join_and(e1, e2);
542*0a9064fbSMasahiro Yamada 		if (tmp) {
543*0a9064fbSMasahiro Yamada 			expr_free(e1); expr_free(e2);
544*0a9064fbSMasahiro Yamada 			e1 = expr_alloc_symbol(&symbol_yes);
545*0a9064fbSMasahiro Yamada 			e2 = tmp;
546*0a9064fbSMasahiro Yamada 			trans_count++;
547*0a9064fbSMasahiro Yamada 		}
548*0a9064fbSMasahiro Yamada 		break;
549*0a9064fbSMasahiro Yamada 	default:
550*0a9064fbSMasahiro Yamada 		;
551*0a9064fbSMasahiro Yamada 	}
552*0a9064fbSMasahiro Yamada #undef e1
553*0a9064fbSMasahiro Yamada #undef e2
554*0a9064fbSMasahiro Yamada }
555*0a9064fbSMasahiro Yamada 
556*0a9064fbSMasahiro Yamada static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2)
557*0a9064fbSMasahiro Yamada {
558*0a9064fbSMasahiro Yamada #define e1 (*ep1)
559*0a9064fbSMasahiro Yamada #define e2 (*ep2)
560*0a9064fbSMasahiro Yamada 	struct expr *tmp, *tmp1, *tmp2;
561*0a9064fbSMasahiro Yamada 
562*0a9064fbSMasahiro Yamada 	if (e1->type == type) {
563*0a9064fbSMasahiro Yamada 		expr_eliminate_dups2(type, &e1->left.expr, &e2);
564*0a9064fbSMasahiro Yamada 		expr_eliminate_dups2(type, &e1->right.expr, &e2);
565*0a9064fbSMasahiro Yamada 		return;
566*0a9064fbSMasahiro Yamada 	}
567*0a9064fbSMasahiro Yamada 	if (e2->type == type) {
568*0a9064fbSMasahiro Yamada 		expr_eliminate_dups2(type, &e1, &e2->left.expr);
569*0a9064fbSMasahiro Yamada 		expr_eliminate_dups2(type, &e1, &e2->right.expr);
570*0a9064fbSMasahiro Yamada 	}
571*0a9064fbSMasahiro Yamada 	if (e1 == e2)
572*0a9064fbSMasahiro Yamada 		return;
573*0a9064fbSMasahiro Yamada 
574*0a9064fbSMasahiro Yamada 	switch (e1->type) {
575*0a9064fbSMasahiro Yamada 	case E_OR:
576*0a9064fbSMasahiro Yamada 		expr_eliminate_dups2(e1->type, &e1, &e1);
577*0a9064fbSMasahiro Yamada 		// (FOO || BAR) && (!FOO && !BAR) -> n
578*0a9064fbSMasahiro Yamada 		tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
579*0a9064fbSMasahiro Yamada 		tmp2 = expr_copy(e2);
580*0a9064fbSMasahiro Yamada 		tmp = expr_extract_eq_and(&tmp1, &tmp2);
581*0a9064fbSMasahiro Yamada 		if (expr_is_yes(tmp1)) {
582*0a9064fbSMasahiro Yamada 			expr_free(e1);
583*0a9064fbSMasahiro Yamada 			e1 = expr_alloc_symbol(&symbol_no);
584*0a9064fbSMasahiro Yamada 			trans_count++;
585*0a9064fbSMasahiro Yamada 		}
586*0a9064fbSMasahiro Yamada 		expr_free(tmp2);
587*0a9064fbSMasahiro Yamada 		expr_free(tmp1);
588*0a9064fbSMasahiro Yamada 		expr_free(tmp);
589*0a9064fbSMasahiro Yamada 		break;
590*0a9064fbSMasahiro Yamada 	case E_AND:
591*0a9064fbSMasahiro Yamada 		expr_eliminate_dups2(e1->type, &e1, &e1);
592*0a9064fbSMasahiro Yamada 		// (FOO && BAR) || (!FOO || !BAR) -> y
593*0a9064fbSMasahiro Yamada 		tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
594*0a9064fbSMasahiro Yamada 		tmp2 = expr_copy(e2);
595*0a9064fbSMasahiro Yamada 		tmp = expr_extract_eq_or(&tmp1, &tmp2);
596*0a9064fbSMasahiro Yamada 		if (expr_is_no(tmp1)) {
597*0a9064fbSMasahiro Yamada 			expr_free(e1);
598*0a9064fbSMasahiro Yamada 			e1 = expr_alloc_symbol(&symbol_yes);
599*0a9064fbSMasahiro Yamada 			trans_count++;
600*0a9064fbSMasahiro Yamada 		}
601*0a9064fbSMasahiro Yamada 		expr_free(tmp2);
602*0a9064fbSMasahiro Yamada 		expr_free(tmp1);
603*0a9064fbSMasahiro Yamada 		expr_free(tmp);
604*0a9064fbSMasahiro Yamada 		break;
605*0a9064fbSMasahiro Yamada 	default:
606*0a9064fbSMasahiro Yamada 		;
607*0a9064fbSMasahiro Yamada 	}
608*0a9064fbSMasahiro Yamada #undef e1
609*0a9064fbSMasahiro Yamada #undef e2
610*0a9064fbSMasahiro Yamada }
611*0a9064fbSMasahiro Yamada 
612*0a9064fbSMasahiro Yamada struct expr *expr_eliminate_dups(struct expr *e)
613*0a9064fbSMasahiro Yamada {
614*0a9064fbSMasahiro Yamada 	int oldcount;
615*0a9064fbSMasahiro Yamada 	if (!e)
616*0a9064fbSMasahiro Yamada 		return e;
617*0a9064fbSMasahiro Yamada 
618*0a9064fbSMasahiro Yamada 	oldcount = trans_count;
619*0a9064fbSMasahiro Yamada 	while (1) {
620*0a9064fbSMasahiro Yamada 		trans_count = 0;
621*0a9064fbSMasahiro Yamada 		switch (e->type) {
622*0a9064fbSMasahiro Yamada 		case E_OR: case E_AND:
623*0a9064fbSMasahiro Yamada 			expr_eliminate_dups1(e->type, &e, &e);
624*0a9064fbSMasahiro Yamada 			expr_eliminate_dups2(e->type, &e, &e);
625*0a9064fbSMasahiro Yamada 		default:
626*0a9064fbSMasahiro Yamada 			;
627*0a9064fbSMasahiro Yamada 		}
628*0a9064fbSMasahiro Yamada 		if (!trans_count)
629*0a9064fbSMasahiro Yamada 			break;
630*0a9064fbSMasahiro Yamada 		e = expr_eliminate_yn(e);
631*0a9064fbSMasahiro Yamada 	}
632*0a9064fbSMasahiro Yamada 	trans_count = oldcount;
633*0a9064fbSMasahiro Yamada 	return e;
634*0a9064fbSMasahiro Yamada }
635*0a9064fbSMasahiro Yamada 
636*0a9064fbSMasahiro Yamada struct expr *expr_transform(struct expr *e)
637*0a9064fbSMasahiro Yamada {
638*0a9064fbSMasahiro Yamada 	struct expr *tmp;
639*0a9064fbSMasahiro Yamada 
640*0a9064fbSMasahiro Yamada 	if (!e)
641*0a9064fbSMasahiro Yamada 		return NULL;
642*0a9064fbSMasahiro Yamada 	switch (e->type) {
643*0a9064fbSMasahiro Yamada 	case E_EQUAL:
644*0a9064fbSMasahiro Yamada 	case E_UNEQUAL:
645*0a9064fbSMasahiro Yamada 	case E_SYMBOL:
646*0a9064fbSMasahiro Yamada 	case E_LIST:
647*0a9064fbSMasahiro Yamada 		break;
648*0a9064fbSMasahiro Yamada 	default:
649*0a9064fbSMasahiro Yamada 		e->left.expr = expr_transform(e->left.expr);
650*0a9064fbSMasahiro Yamada 		e->right.expr = expr_transform(e->right.expr);
651*0a9064fbSMasahiro Yamada 	}
652*0a9064fbSMasahiro Yamada 
653*0a9064fbSMasahiro Yamada 	switch (e->type) {
654*0a9064fbSMasahiro Yamada 	case E_EQUAL:
655*0a9064fbSMasahiro Yamada 		if (e->left.sym->type != S_BOOLEAN)
656*0a9064fbSMasahiro Yamada 			break;
657*0a9064fbSMasahiro Yamada 		if (e->right.sym == &symbol_no) {
658*0a9064fbSMasahiro Yamada 			e->type = E_NOT;
659*0a9064fbSMasahiro Yamada 			e->left.expr = expr_alloc_symbol(e->left.sym);
660*0a9064fbSMasahiro Yamada 			e->right.sym = NULL;
661*0a9064fbSMasahiro Yamada 			break;
662*0a9064fbSMasahiro Yamada 		}
663*0a9064fbSMasahiro Yamada 		if (e->right.sym == &symbol_mod) {
664*0a9064fbSMasahiro Yamada 			printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
665*0a9064fbSMasahiro Yamada 			e->type = E_SYMBOL;
666*0a9064fbSMasahiro Yamada 			e->left.sym = &symbol_no;
667*0a9064fbSMasahiro Yamada 			e->right.sym = NULL;
668*0a9064fbSMasahiro Yamada 			break;
669*0a9064fbSMasahiro Yamada 		}
670*0a9064fbSMasahiro Yamada 		if (e->right.sym == &symbol_yes) {
671*0a9064fbSMasahiro Yamada 			e->type = E_SYMBOL;
672*0a9064fbSMasahiro Yamada 			e->right.sym = NULL;
673*0a9064fbSMasahiro Yamada 			break;
674*0a9064fbSMasahiro Yamada 		}
675*0a9064fbSMasahiro Yamada 		break;
676*0a9064fbSMasahiro Yamada 	case E_UNEQUAL:
677*0a9064fbSMasahiro Yamada 		if (e->left.sym->type != S_BOOLEAN)
678*0a9064fbSMasahiro Yamada 			break;
679*0a9064fbSMasahiro Yamada 		if (e->right.sym == &symbol_no) {
680*0a9064fbSMasahiro Yamada 			e->type = E_SYMBOL;
681*0a9064fbSMasahiro Yamada 			e->right.sym = NULL;
682*0a9064fbSMasahiro Yamada 			break;
683*0a9064fbSMasahiro Yamada 		}
684*0a9064fbSMasahiro Yamada 		if (e->right.sym == &symbol_mod) {
685*0a9064fbSMasahiro Yamada 			printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
686*0a9064fbSMasahiro Yamada 			e->type = E_SYMBOL;
687*0a9064fbSMasahiro Yamada 			e->left.sym = &symbol_yes;
688*0a9064fbSMasahiro Yamada 			e->right.sym = NULL;
689*0a9064fbSMasahiro Yamada 			break;
690*0a9064fbSMasahiro Yamada 		}
691*0a9064fbSMasahiro Yamada 		if (e->right.sym == &symbol_yes) {
692*0a9064fbSMasahiro Yamada 			e->type = E_NOT;
693*0a9064fbSMasahiro Yamada 			e->left.expr = expr_alloc_symbol(e->left.sym);
694*0a9064fbSMasahiro Yamada 			e->right.sym = NULL;
695*0a9064fbSMasahiro Yamada 			break;
696*0a9064fbSMasahiro Yamada 		}
697*0a9064fbSMasahiro Yamada 		break;
698*0a9064fbSMasahiro Yamada 	case E_NOT:
699*0a9064fbSMasahiro Yamada 		switch (e->left.expr->type) {
700*0a9064fbSMasahiro Yamada 		case E_NOT:
701*0a9064fbSMasahiro Yamada 			// !!a -> a
702*0a9064fbSMasahiro Yamada 			tmp = e->left.expr->left.expr;
703*0a9064fbSMasahiro Yamada 			free(e->left.expr);
704*0a9064fbSMasahiro Yamada 			free(e);
705*0a9064fbSMasahiro Yamada 			e = tmp;
706*0a9064fbSMasahiro Yamada 			e = expr_transform(e);
707*0a9064fbSMasahiro Yamada 			break;
708*0a9064fbSMasahiro Yamada 		case E_EQUAL:
709*0a9064fbSMasahiro Yamada 		case E_UNEQUAL:
710*0a9064fbSMasahiro Yamada 			// !a='x' -> a!='x'
711*0a9064fbSMasahiro Yamada 			tmp = e->left.expr;
712*0a9064fbSMasahiro Yamada 			free(e);
713*0a9064fbSMasahiro Yamada 			e = tmp;
714*0a9064fbSMasahiro Yamada 			e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
715*0a9064fbSMasahiro Yamada 			break;
716*0a9064fbSMasahiro Yamada 		case E_OR:
717*0a9064fbSMasahiro Yamada 			// !(a || b) -> !a && !b
718*0a9064fbSMasahiro Yamada 			tmp = e->left.expr;
719*0a9064fbSMasahiro Yamada 			e->type = E_AND;
720*0a9064fbSMasahiro Yamada 			e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
721*0a9064fbSMasahiro Yamada 			tmp->type = E_NOT;
722*0a9064fbSMasahiro Yamada 			tmp->right.expr = NULL;
723*0a9064fbSMasahiro Yamada 			e = expr_transform(e);
724*0a9064fbSMasahiro Yamada 			break;
725*0a9064fbSMasahiro Yamada 		case E_AND:
726*0a9064fbSMasahiro Yamada 			// !(a && b) -> !a || !b
727*0a9064fbSMasahiro Yamada 			tmp = e->left.expr;
728*0a9064fbSMasahiro Yamada 			e->type = E_OR;
729*0a9064fbSMasahiro Yamada 			e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
730*0a9064fbSMasahiro Yamada 			tmp->type = E_NOT;
731*0a9064fbSMasahiro Yamada 			tmp->right.expr = NULL;
732*0a9064fbSMasahiro Yamada 			e = expr_transform(e);
733*0a9064fbSMasahiro Yamada 			break;
734*0a9064fbSMasahiro Yamada 		case E_SYMBOL:
735*0a9064fbSMasahiro Yamada 			if (e->left.expr->left.sym == &symbol_yes) {
736*0a9064fbSMasahiro Yamada 				// !'y' -> 'n'
737*0a9064fbSMasahiro Yamada 				tmp = e->left.expr;
738*0a9064fbSMasahiro Yamada 				free(e);
739*0a9064fbSMasahiro Yamada 				e = tmp;
740*0a9064fbSMasahiro Yamada 				e->type = E_SYMBOL;
741*0a9064fbSMasahiro Yamada 				e->left.sym = &symbol_no;
742*0a9064fbSMasahiro Yamada 				break;
743*0a9064fbSMasahiro Yamada 			}
744*0a9064fbSMasahiro Yamada 			if (e->left.expr->left.sym == &symbol_mod) {
745*0a9064fbSMasahiro Yamada 				// !'m' -> 'm'
746*0a9064fbSMasahiro Yamada 				tmp = e->left.expr;
747*0a9064fbSMasahiro Yamada 				free(e);
748*0a9064fbSMasahiro Yamada 				e = tmp;
749*0a9064fbSMasahiro Yamada 				e->type = E_SYMBOL;
750*0a9064fbSMasahiro Yamada 				e->left.sym = &symbol_mod;
751*0a9064fbSMasahiro Yamada 				break;
752*0a9064fbSMasahiro Yamada 			}
753*0a9064fbSMasahiro Yamada 			if (e->left.expr->left.sym == &symbol_no) {
754*0a9064fbSMasahiro Yamada 				// !'n' -> 'y'
755*0a9064fbSMasahiro Yamada 				tmp = e->left.expr;
756*0a9064fbSMasahiro Yamada 				free(e);
757*0a9064fbSMasahiro Yamada 				e = tmp;
758*0a9064fbSMasahiro Yamada 				e->type = E_SYMBOL;
759*0a9064fbSMasahiro Yamada 				e->left.sym = &symbol_yes;
760*0a9064fbSMasahiro Yamada 				break;
761*0a9064fbSMasahiro Yamada 			}
762*0a9064fbSMasahiro Yamada 			break;
763*0a9064fbSMasahiro Yamada 		default:
764*0a9064fbSMasahiro Yamada 			;
765*0a9064fbSMasahiro Yamada 		}
766*0a9064fbSMasahiro Yamada 		break;
767*0a9064fbSMasahiro Yamada 	default:
768*0a9064fbSMasahiro Yamada 		;
769*0a9064fbSMasahiro Yamada 	}
770*0a9064fbSMasahiro Yamada 	return e;
771*0a9064fbSMasahiro Yamada }
772*0a9064fbSMasahiro Yamada 
773*0a9064fbSMasahiro Yamada int expr_contains_symbol(struct expr *dep, struct symbol *sym)
774*0a9064fbSMasahiro Yamada {
775*0a9064fbSMasahiro Yamada 	if (!dep)
776*0a9064fbSMasahiro Yamada 		return 0;
777*0a9064fbSMasahiro Yamada 
778*0a9064fbSMasahiro Yamada 	switch (dep->type) {
779*0a9064fbSMasahiro Yamada 	case E_AND:
780*0a9064fbSMasahiro Yamada 	case E_OR:
781*0a9064fbSMasahiro Yamada 		return expr_contains_symbol(dep->left.expr, sym) ||
782*0a9064fbSMasahiro Yamada 		       expr_contains_symbol(dep->right.expr, sym);
783*0a9064fbSMasahiro Yamada 	case E_SYMBOL:
784*0a9064fbSMasahiro Yamada 		return dep->left.sym == sym;
785*0a9064fbSMasahiro Yamada 	case E_EQUAL:
786*0a9064fbSMasahiro Yamada 	case E_UNEQUAL:
787*0a9064fbSMasahiro Yamada 		return dep->left.sym == sym ||
788*0a9064fbSMasahiro Yamada 		       dep->right.sym == sym;
789*0a9064fbSMasahiro Yamada 	case E_NOT:
790*0a9064fbSMasahiro Yamada 		return expr_contains_symbol(dep->left.expr, sym);
791*0a9064fbSMasahiro Yamada 	default:
792*0a9064fbSMasahiro Yamada 		;
793*0a9064fbSMasahiro Yamada 	}
794*0a9064fbSMasahiro Yamada 	return 0;
795*0a9064fbSMasahiro Yamada }
796*0a9064fbSMasahiro Yamada 
797*0a9064fbSMasahiro Yamada bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
798*0a9064fbSMasahiro Yamada {
799*0a9064fbSMasahiro Yamada 	if (!dep)
800*0a9064fbSMasahiro Yamada 		return false;
801*0a9064fbSMasahiro Yamada 
802*0a9064fbSMasahiro Yamada 	switch (dep->type) {
803*0a9064fbSMasahiro Yamada 	case E_AND:
804*0a9064fbSMasahiro Yamada 		return expr_depends_symbol(dep->left.expr, sym) ||
805*0a9064fbSMasahiro Yamada 		       expr_depends_symbol(dep->right.expr, sym);
806*0a9064fbSMasahiro Yamada 	case E_SYMBOL:
807*0a9064fbSMasahiro Yamada 		return dep->left.sym == sym;
808*0a9064fbSMasahiro Yamada 	case E_EQUAL:
809*0a9064fbSMasahiro Yamada 		if (dep->left.sym == sym) {
810*0a9064fbSMasahiro Yamada 			if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
811*0a9064fbSMasahiro Yamada 				return true;
812*0a9064fbSMasahiro Yamada 		}
813*0a9064fbSMasahiro Yamada 		break;
814*0a9064fbSMasahiro Yamada 	case E_UNEQUAL:
815*0a9064fbSMasahiro Yamada 		if (dep->left.sym == sym) {
816*0a9064fbSMasahiro Yamada 			if (dep->right.sym == &symbol_no)
817*0a9064fbSMasahiro Yamada 				return true;
818*0a9064fbSMasahiro Yamada 		}
819*0a9064fbSMasahiro Yamada 		break;
820*0a9064fbSMasahiro Yamada 	default:
821*0a9064fbSMasahiro Yamada 		;
822*0a9064fbSMasahiro Yamada 	}
823*0a9064fbSMasahiro Yamada  	return false;
824*0a9064fbSMasahiro Yamada }
825*0a9064fbSMasahiro Yamada 
826*0a9064fbSMasahiro Yamada struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
827*0a9064fbSMasahiro Yamada {
828*0a9064fbSMasahiro Yamada 	struct expr *tmp = NULL;
829*0a9064fbSMasahiro Yamada 	expr_extract_eq(E_AND, &tmp, ep1, ep2);
830*0a9064fbSMasahiro Yamada 	if (tmp) {
831*0a9064fbSMasahiro Yamada 		*ep1 = expr_eliminate_yn(*ep1);
832*0a9064fbSMasahiro Yamada 		*ep2 = expr_eliminate_yn(*ep2);
833*0a9064fbSMasahiro Yamada 	}
834*0a9064fbSMasahiro Yamada 	return tmp;
835*0a9064fbSMasahiro Yamada }
836*0a9064fbSMasahiro Yamada 
837*0a9064fbSMasahiro Yamada struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
838*0a9064fbSMasahiro Yamada {
839*0a9064fbSMasahiro Yamada 	struct expr *tmp = NULL;
840*0a9064fbSMasahiro Yamada 	expr_extract_eq(E_OR, &tmp, ep1, ep2);
841*0a9064fbSMasahiro Yamada 	if (tmp) {
842*0a9064fbSMasahiro Yamada 		*ep1 = expr_eliminate_yn(*ep1);
843*0a9064fbSMasahiro Yamada 		*ep2 = expr_eliminate_yn(*ep2);
844*0a9064fbSMasahiro Yamada 	}
845*0a9064fbSMasahiro Yamada 	return tmp;
846*0a9064fbSMasahiro Yamada }
847*0a9064fbSMasahiro Yamada 
848*0a9064fbSMasahiro Yamada void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
849*0a9064fbSMasahiro Yamada {
850*0a9064fbSMasahiro Yamada #define e1 (*ep1)
851*0a9064fbSMasahiro Yamada #define e2 (*ep2)
852*0a9064fbSMasahiro Yamada 	if (e1->type == type) {
853*0a9064fbSMasahiro Yamada 		expr_extract_eq(type, ep, &e1->left.expr, &e2);
854*0a9064fbSMasahiro Yamada 		expr_extract_eq(type, ep, &e1->right.expr, &e2);
855*0a9064fbSMasahiro Yamada 		return;
856*0a9064fbSMasahiro Yamada 	}
857*0a9064fbSMasahiro Yamada 	if (e2->type == type) {
858*0a9064fbSMasahiro Yamada 		expr_extract_eq(type, ep, ep1, &e2->left.expr);
859*0a9064fbSMasahiro Yamada 		expr_extract_eq(type, ep, ep1, &e2->right.expr);
860*0a9064fbSMasahiro Yamada 		return;
861*0a9064fbSMasahiro Yamada 	}
862*0a9064fbSMasahiro Yamada 	if (expr_eq(e1, e2)) {
863*0a9064fbSMasahiro Yamada 		*ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
864*0a9064fbSMasahiro Yamada 		expr_free(e2);
865*0a9064fbSMasahiro Yamada 		if (type == E_AND) {
866*0a9064fbSMasahiro Yamada 			e1 = expr_alloc_symbol(&symbol_yes);
867*0a9064fbSMasahiro Yamada 			e2 = expr_alloc_symbol(&symbol_yes);
868*0a9064fbSMasahiro Yamada 		} else if (type == E_OR) {
869*0a9064fbSMasahiro Yamada 			e1 = expr_alloc_symbol(&symbol_no);
870*0a9064fbSMasahiro Yamada 			e2 = expr_alloc_symbol(&symbol_no);
871*0a9064fbSMasahiro Yamada 		}
872*0a9064fbSMasahiro Yamada 	}
873*0a9064fbSMasahiro Yamada #undef e1
874*0a9064fbSMasahiro Yamada #undef e2
875*0a9064fbSMasahiro Yamada }
876*0a9064fbSMasahiro Yamada 
877*0a9064fbSMasahiro Yamada struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
878*0a9064fbSMasahiro Yamada {
879*0a9064fbSMasahiro Yamada 	struct expr *e1, *e2;
880*0a9064fbSMasahiro Yamada 
881*0a9064fbSMasahiro Yamada 	if (!e) {
882*0a9064fbSMasahiro Yamada 		e = expr_alloc_symbol(sym);
883*0a9064fbSMasahiro Yamada 		if (type == E_UNEQUAL)
884*0a9064fbSMasahiro Yamada 			e = expr_alloc_one(E_NOT, e);
885*0a9064fbSMasahiro Yamada 		return e;
886*0a9064fbSMasahiro Yamada 	}
887*0a9064fbSMasahiro Yamada 	switch (e->type) {
888*0a9064fbSMasahiro Yamada 	case E_AND:
889*0a9064fbSMasahiro Yamada 		e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
890*0a9064fbSMasahiro Yamada 		e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
891*0a9064fbSMasahiro Yamada 		if (sym == &symbol_yes)
892*0a9064fbSMasahiro Yamada 			e = expr_alloc_two(E_AND, e1, e2);
893*0a9064fbSMasahiro Yamada 		if (sym == &symbol_no)
894*0a9064fbSMasahiro Yamada 			e = expr_alloc_two(E_OR, e1, e2);
895*0a9064fbSMasahiro Yamada 		if (type == E_UNEQUAL)
896*0a9064fbSMasahiro Yamada 			e = expr_alloc_one(E_NOT, e);
897*0a9064fbSMasahiro Yamada 		return e;
898*0a9064fbSMasahiro Yamada 	case E_OR:
899*0a9064fbSMasahiro Yamada 		e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
900*0a9064fbSMasahiro Yamada 		e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
901*0a9064fbSMasahiro Yamada 		if (sym == &symbol_yes)
902*0a9064fbSMasahiro Yamada 			e = expr_alloc_two(E_OR, e1, e2);
903*0a9064fbSMasahiro Yamada 		if (sym == &symbol_no)
904*0a9064fbSMasahiro Yamada 			e = expr_alloc_two(E_AND, e1, e2);
905*0a9064fbSMasahiro Yamada 		if (type == E_UNEQUAL)
906*0a9064fbSMasahiro Yamada 			e = expr_alloc_one(E_NOT, e);
907*0a9064fbSMasahiro Yamada 		return e;
908*0a9064fbSMasahiro Yamada 	case E_NOT:
909*0a9064fbSMasahiro Yamada 		return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
910*0a9064fbSMasahiro Yamada 	case E_UNEQUAL:
911*0a9064fbSMasahiro Yamada 	case E_EQUAL:
912*0a9064fbSMasahiro Yamada 		if (type == E_EQUAL) {
913*0a9064fbSMasahiro Yamada 			if (sym == &symbol_yes)
914*0a9064fbSMasahiro Yamada 				return expr_copy(e);
915*0a9064fbSMasahiro Yamada 			if (sym == &symbol_mod)
916*0a9064fbSMasahiro Yamada 				return expr_alloc_symbol(&symbol_no);
917*0a9064fbSMasahiro Yamada 			if (sym == &symbol_no)
918*0a9064fbSMasahiro Yamada 				return expr_alloc_one(E_NOT, expr_copy(e));
919*0a9064fbSMasahiro Yamada 		} else {
920*0a9064fbSMasahiro Yamada 			if (sym == &symbol_yes)
921*0a9064fbSMasahiro Yamada 				return expr_alloc_one(E_NOT, expr_copy(e));
922*0a9064fbSMasahiro Yamada 			if (sym == &symbol_mod)
923*0a9064fbSMasahiro Yamada 				return expr_alloc_symbol(&symbol_yes);
924*0a9064fbSMasahiro Yamada 			if (sym == &symbol_no)
925*0a9064fbSMasahiro Yamada 				return expr_copy(e);
926*0a9064fbSMasahiro Yamada 		}
927*0a9064fbSMasahiro Yamada 		break;
928*0a9064fbSMasahiro Yamada 	case E_SYMBOL:
929*0a9064fbSMasahiro Yamada 		return expr_alloc_comp(type, e->left.sym, sym);
930*0a9064fbSMasahiro Yamada 	case E_LIST:
931*0a9064fbSMasahiro Yamada 	case E_RANGE:
932*0a9064fbSMasahiro Yamada 	case E_NONE:
933*0a9064fbSMasahiro Yamada 		/* panic */;
934*0a9064fbSMasahiro Yamada 	}
935*0a9064fbSMasahiro Yamada 	return NULL;
936*0a9064fbSMasahiro Yamada }
937*0a9064fbSMasahiro Yamada 
938*0a9064fbSMasahiro Yamada tristate expr_calc_value(struct expr *e)
939*0a9064fbSMasahiro Yamada {
940*0a9064fbSMasahiro Yamada 	tristate val1, val2;
941*0a9064fbSMasahiro Yamada 	const char *str1, *str2;
942*0a9064fbSMasahiro Yamada 
943*0a9064fbSMasahiro Yamada 	if (!e)
944*0a9064fbSMasahiro Yamada 		return yes;
945*0a9064fbSMasahiro Yamada 
946*0a9064fbSMasahiro Yamada 	switch (e->type) {
947*0a9064fbSMasahiro Yamada 	case E_SYMBOL:
948*0a9064fbSMasahiro Yamada 		sym_calc_value(e->left.sym);
949*0a9064fbSMasahiro Yamada 		return e->left.sym->curr.tri;
950*0a9064fbSMasahiro Yamada 	case E_AND:
951*0a9064fbSMasahiro Yamada 		val1 = expr_calc_value(e->left.expr);
952*0a9064fbSMasahiro Yamada 		val2 = expr_calc_value(e->right.expr);
953*0a9064fbSMasahiro Yamada 		return EXPR_AND(val1, val2);
954*0a9064fbSMasahiro Yamada 	case E_OR:
955*0a9064fbSMasahiro Yamada 		val1 = expr_calc_value(e->left.expr);
956*0a9064fbSMasahiro Yamada 		val2 = expr_calc_value(e->right.expr);
957*0a9064fbSMasahiro Yamada 		return EXPR_OR(val1, val2);
958*0a9064fbSMasahiro Yamada 	case E_NOT:
959*0a9064fbSMasahiro Yamada 		val1 = expr_calc_value(e->left.expr);
960*0a9064fbSMasahiro Yamada 		return EXPR_NOT(val1);
961*0a9064fbSMasahiro Yamada 	case E_EQUAL:
962*0a9064fbSMasahiro Yamada 		sym_calc_value(e->left.sym);
963*0a9064fbSMasahiro Yamada 		sym_calc_value(e->right.sym);
964*0a9064fbSMasahiro Yamada 		str1 = sym_get_string_value(e->left.sym);
965*0a9064fbSMasahiro Yamada 		str2 = sym_get_string_value(e->right.sym);
966*0a9064fbSMasahiro Yamada 		return !strcmp(str1, str2) ? yes : no;
967*0a9064fbSMasahiro Yamada 	case E_UNEQUAL:
968*0a9064fbSMasahiro Yamada 		sym_calc_value(e->left.sym);
969*0a9064fbSMasahiro Yamada 		sym_calc_value(e->right.sym);
970*0a9064fbSMasahiro Yamada 		str1 = sym_get_string_value(e->left.sym);
971*0a9064fbSMasahiro Yamada 		str2 = sym_get_string_value(e->right.sym);
972*0a9064fbSMasahiro Yamada 		return !strcmp(str1, str2) ? no : yes;
973*0a9064fbSMasahiro Yamada 	default:
974*0a9064fbSMasahiro Yamada 		printf("expr_calc_value: %d?\n", e->type);
975*0a9064fbSMasahiro Yamada 		return no;
976*0a9064fbSMasahiro Yamada 	}
977*0a9064fbSMasahiro Yamada }
978*0a9064fbSMasahiro Yamada 
979*0a9064fbSMasahiro Yamada int expr_compare_type(enum expr_type t1, enum expr_type t2)
980*0a9064fbSMasahiro Yamada {
981*0a9064fbSMasahiro Yamada #if 0
982*0a9064fbSMasahiro Yamada 	return 1;
983*0a9064fbSMasahiro Yamada #else
984*0a9064fbSMasahiro Yamada 	if (t1 == t2)
985*0a9064fbSMasahiro Yamada 		return 0;
986*0a9064fbSMasahiro Yamada 	switch (t1) {
987*0a9064fbSMasahiro Yamada 	case E_EQUAL:
988*0a9064fbSMasahiro Yamada 	case E_UNEQUAL:
989*0a9064fbSMasahiro Yamada 		if (t2 == E_NOT)
990*0a9064fbSMasahiro Yamada 			return 1;
991*0a9064fbSMasahiro Yamada 	case E_NOT:
992*0a9064fbSMasahiro Yamada 		if (t2 == E_AND)
993*0a9064fbSMasahiro Yamada 			return 1;
994*0a9064fbSMasahiro Yamada 	case E_AND:
995*0a9064fbSMasahiro Yamada 		if (t2 == E_OR)
996*0a9064fbSMasahiro Yamada 			return 1;
997*0a9064fbSMasahiro Yamada 	case E_OR:
998*0a9064fbSMasahiro Yamada 		if (t2 == E_LIST)
999*0a9064fbSMasahiro Yamada 			return 1;
1000*0a9064fbSMasahiro Yamada 	case E_LIST:
1001*0a9064fbSMasahiro Yamada 		if (t2 == 0)
1002*0a9064fbSMasahiro Yamada 			return 1;
1003*0a9064fbSMasahiro Yamada 	default:
1004*0a9064fbSMasahiro Yamada 		return -1;
1005*0a9064fbSMasahiro Yamada 	}
1006*0a9064fbSMasahiro Yamada 	printf("[%dgt%d?]", t1, t2);
1007*0a9064fbSMasahiro Yamada 	return 0;
1008*0a9064fbSMasahiro Yamada #endif
1009*0a9064fbSMasahiro Yamada }
1010*0a9064fbSMasahiro Yamada 
1011*0a9064fbSMasahiro Yamada static inline struct expr *
1012*0a9064fbSMasahiro Yamada expr_get_leftmost_symbol(const struct expr *e)
1013*0a9064fbSMasahiro Yamada {
1014*0a9064fbSMasahiro Yamada 
1015*0a9064fbSMasahiro Yamada 	if (e == NULL)
1016*0a9064fbSMasahiro Yamada 		return NULL;
1017*0a9064fbSMasahiro Yamada 
1018*0a9064fbSMasahiro Yamada 	while (e->type != E_SYMBOL)
1019*0a9064fbSMasahiro Yamada 		e = e->left.expr;
1020*0a9064fbSMasahiro Yamada 
1021*0a9064fbSMasahiro Yamada 	return expr_copy(e);
1022*0a9064fbSMasahiro Yamada }
1023*0a9064fbSMasahiro Yamada 
1024*0a9064fbSMasahiro Yamada /*
1025*0a9064fbSMasahiro Yamada  * Given expression `e1' and `e2', returns the leaf of the longest
1026*0a9064fbSMasahiro Yamada  * sub-expression of `e1' not containing 'e2.
1027*0a9064fbSMasahiro Yamada  */
1028*0a9064fbSMasahiro Yamada struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
1029*0a9064fbSMasahiro Yamada {
1030*0a9064fbSMasahiro Yamada 	struct expr *ret;
1031*0a9064fbSMasahiro Yamada 
1032*0a9064fbSMasahiro Yamada 	switch (e1->type) {
1033*0a9064fbSMasahiro Yamada 	case E_OR:
1034*0a9064fbSMasahiro Yamada 		return expr_alloc_and(
1035*0a9064fbSMasahiro Yamada 		    expr_simplify_unmet_dep(e1->left.expr, e2),
1036*0a9064fbSMasahiro Yamada 		    expr_simplify_unmet_dep(e1->right.expr, e2));
1037*0a9064fbSMasahiro Yamada 	case E_AND: {
1038*0a9064fbSMasahiro Yamada 		struct expr *e;
1039*0a9064fbSMasahiro Yamada 		e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
1040*0a9064fbSMasahiro Yamada 		e = expr_eliminate_dups(e);
1041*0a9064fbSMasahiro Yamada 		ret = (!expr_eq(e, e1)) ? e1 : NULL;
1042*0a9064fbSMasahiro Yamada 		expr_free(e);
1043*0a9064fbSMasahiro Yamada 		break;
1044*0a9064fbSMasahiro Yamada 		}
1045*0a9064fbSMasahiro Yamada 	default:
1046*0a9064fbSMasahiro Yamada 		ret = e1;
1047*0a9064fbSMasahiro Yamada 		break;
1048*0a9064fbSMasahiro Yamada 	}
1049*0a9064fbSMasahiro Yamada 
1050*0a9064fbSMasahiro Yamada 	return expr_get_leftmost_symbol(ret);
1051*0a9064fbSMasahiro Yamada }
1052*0a9064fbSMasahiro Yamada 
1053*0a9064fbSMasahiro Yamada void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
1054*0a9064fbSMasahiro Yamada {
1055*0a9064fbSMasahiro Yamada 	if (!e) {
1056*0a9064fbSMasahiro Yamada 		fn(data, NULL, "y");
1057*0a9064fbSMasahiro Yamada 		return;
1058*0a9064fbSMasahiro Yamada 	}
1059*0a9064fbSMasahiro Yamada 
1060*0a9064fbSMasahiro Yamada 	if (expr_compare_type(prevtoken, e->type) > 0)
1061*0a9064fbSMasahiro Yamada 		fn(data, NULL, "(");
1062*0a9064fbSMasahiro Yamada 	switch (e->type) {
1063*0a9064fbSMasahiro Yamada 	case E_SYMBOL:
1064*0a9064fbSMasahiro Yamada 		if (e->left.sym->name)
1065*0a9064fbSMasahiro Yamada 			fn(data, e->left.sym, e->left.sym->name);
1066*0a9064fbSMasahiro Yamada 		else
1067*0a9064fbSMasahiro Yamada 			fn(data, NULL, "<choice>");
1068*0a9064fbSMasahiro Yamada 		break;
1069*0a9064fbSMasahiro Yamada 	case E_NOT:
1070*0a9064fbSMasahiro Yamada 		fn(data, NULL, "!");
1071*0a9064fbSMasahiro Yamada 		expr_print(e->left.expr, fn, data, E_NOT);
1072*0a9064fbSMasahiro Yamada 		break;
1073*0a9064fbSMasahiro Yamada 	case E_EQUAL:
1074*0a9064fbSMasahiro Yamada 		if (e->left.sym->name)
1075*0a9064fbSMasahiro Yamada 			fn(data, e->left.sym, e->left.sym->name);
1076*0a9064fbSMasahiro Yamada 		else
1077*0a9064fbSMasahiro Yamada 			fn(data, NULL, "<choice>");
1078*0a9064fbSMasahiro Yamada 		fn(data, NULL, "=");
1079*0a9064fbSMasahiro Yamada 		fn(data, e->right.sym, e->right.sym->name);
1080*0a9064fbSMasahiro Yamada 		break;
1081*0a9064fbSMasahiro Yamada 	case E_UNEQUAL:
1082*0a9064fbSMasahiro Yamada 		if (e->left.sym->name)
1083*0a9064fbSMasahiro Yamada 			fn(data, e->left.sym, e->left.sym->name);
1084*0a9064fbSMasahiro Yamada 		else
1085*0a9064fbSMasahiro Yamada 			fn(data, NULL, "<choice>");
1086*0a9064fbSMasahiro Yamada 		fn(data, NULL, "!=");
1087*0a9064fbSMasahiro Yamada 		fn(data, e->right.sym, e->right.sym->name);
1088*0a9064fbSMasahiro Yamada 		break;
1089*0a9064fbSMasahiro Yamada 	case E_OR:
1090*0a9064fbSMasahiro Yamada 		expr_print(e->left.expr, fn, data, E_OR);
1091*0a9064fbSMasahiro Yamada 		fn(data, NULL, " || ");
1092*0a9064fbSMasahiro Yamada 		expr_print(e->right.expr, fn, data, E_OR);
1093*0a9064fbSMasahiro Yamada 		break;
1094*0a9064fbSMasahiro Yamada 	case E_AND:
1095*0a9064fbSMasahiro Yamada 		expr_print(e->left.expr, fn, data, E_AND);
1096*0a9064fbSMasahiro Yamada 		fn(data, NULL, " && ");
1097*0a9064fbSMasahiro Yamada 		expr_print(e->right.expr, fn, data, E_AND);
1098*0a9064fbSMasahiro Yamada 		break;
1099*0a9064fbSMasahiro Yamada 	case E_LIST:
1100*0a9064fbSMasahiro Yamada 		fn(data, e->right.sym, e->right.sym->name);
1101*0a9064fbSMasahiro Yamada 		if (e->left.expr) {
1102*0a9064fbSMasahiro Yamada 			fn(data, NULL, " ^ ");
1103*0a9064fbSMasahiro Yamada 			expr_print(e->left.expr, fn, data, E_LIST);
1104*0a9064fbSMasahiro Yamada 		}
1105*0a9064fbSMasahiro Yamada 		break;
1106*0a9064fbSMasahiro Yamada 	case E_RANGE:
1107*0a9064fbSMasahiro Yamada 		fn(data, NULL, "[");
1108*0a9064fbSMasahiro Yamada 		fn(data, e->left.sym, e->left.sym->name);
1109*0a9064fbSMasahiro Yamada 		fn(data, NULL, " ");
1110*0a9064fbSMasahiro Yamada 		fn(data, e->right.sym, e->right.sym->name);
1111*0a9064fbSMasahiro Yamada 		fn(data, NULL, "]");
1112*0a9064fbSMasahiro Yamada 		break;
1113*0a9064fbSMasahiro Yamada 	default:
1114*0a9064fbSMasahiro Yamada 	  {
1115*0a9064fbSMasahiro Yamada 		char buf[32];
1116*0a9064fbSMasahiro Yamada 		sprintf(buf, "<unknown type %d>", e->type);
1117*0a9064fbSMasahiro Yamada 		fn(data, NULL, buf);
1118*0a9064fbSMasahiro Yamada 		break;
1119*0a9064fbSMasahiro Yamada 	  }
1120*0a9064fbSMasahiro Yamada 	}
1121*0a9064fbSMasahiro Yamada 	if (expr_compare_type(prevtoken, e->type) > 0)
1122*0a9064fbSMasahiro Yamada 		fn(data, NULL, ")");
1123*0a9064fbSMasahiro Yamada }
1124*0a9064fbSMasahiro Yamada 
1125*0a9064fbSMasahiro Yamada static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
1126*0a9064fbSMasahiro Yamada {
1127*0a9064fbSMasahiro Yamada 	xfwrite(str, strlen(str), 1, data);
1128*0a9064fbSMasahiro Yamada }
1129*0a9064fbSMasahiro Yamada 
1130*0a9064fbSMasahiro Yamada void expr_fprint(struct expr *e, FILE *out)
1131*0a9064fbSMasahiro Yamada {
1132*0a9064fbSMasahiro Yamada 	expr_print(e, expr_print_file_helper, out, E_NONE);
1133*0a9064fbSMasahiro Yamada }
1134*0a9064fbSMasahiro Yamada 
1135*0a9064fbSMasahiro Yamada static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
1136*0a9064fbSMasahiro Yamada {
1137*0a9064fbSMasahiro Yamada 	struct gstr *gs = (struct gstr*)data;
1138*0a9064fbSMasahiro Yamada 	const char *sym_str = NULL;
1139*0a9064fbSMasahiro Yamada 
1140*0a9064fbSMasahiro Yamada 	if (sym)
1141*0a9064fbSMasahiro Yamada 		sym_str = sym_get_string_value(sym);
1142*0a9064fbSMasahiro Yamada 
1143*0a9064fbSMasahiro Yamada 	if (gs->max_width) {
1144*0a9064fbSMasahiro Yamada 		unsigned extra_length = strlen(str);
1145*0a9064fbSMasahiro Yamada 		const char *last_cr = strrchr(gs->s, '\n');
1146*0a9064fbSMasahiro Yamada 		unsigned last_line_length;
1147*0a9064fbSMasahiro Yamada 
1148*0a9064fbSMasahiro Yamada 		if (sym_str)
1149*0a9064fbSMasahiro Yamada 			extra_length += 4 + strlen(sym_str);
1150*0a9064fbSMasahiro Yamada 
1151*0a9064fbSMasahiro Yamada 		if (!last_cr)
1152*0a9064fbSMasahiro Yamada 			last_cr = gs->s;
1153*0a9064fbSMasahiro Yamada 
1154*0a9064fbSMasahiro Yamada 		last_line_length = strlen(gs->s) - (last_cr - gs->s);
1155*0a9064fbSMasahiro Yamada 
1156*0a9064fbSMasahiro Yamada 		if ((last_line_length + extra_length) > gs->max_width)
1157*0a9064fbSMasahiro Yamada 			str_append(gs, "\\\n");
1158*0a9064fbSMasahiro Yamada 	}
1159*0a9064fbSMasahiro Yamada 
1160*0a9064fbSMasahiro Yamada 	str_append(gs, str);
1161*0a9064fbSMasahiro Yamada 	if (sym && sym->type != S_UNKNOWN)
1162*0a9064fbSMasahiro Yamada 		str_printf(gs, " [=%s]", sym_str);
1163*0a9064fbSMasahiro Yamada }
1164*0a9064fbSMasahiro Yamada 
1165*0a9064fbSMasahiro Yamada void expr_gstr_print(struct expr *e, struct gstr *gs)
1166*0a9064fbSMasahiro Yamada {
1167*0a9064fbSMasahiro Yamada 	expr_print(e, expr_print_gstr_helper, gs, E_NONE);
1168*0a9064fbSMasahiro Yamada }
1169