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