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