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