| 493 | } |
| 494 | |
| 495 | static struct expr *expr_join_and(struct expr *e1, struct expr *e2) |
| 496 | { |
| 497 | struct expr *tmp; |
| 498 | struct symbol *sym1, *sym2; |
| 499 | |
| 500 | if (expr_eq(e1, e2)) |
| 501 | return expr_copy(e1); |
| 502 | if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) |
| 503 | return NULL; |
| 504 | if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) |
| 505 | return NULL; |
| 506 | if (e1->type == E_NOT) { |
| 507 | tmp = e1->left.expr; |
| 508 | if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) |
| 509 | return NULL; |
| 510 | sym1 = tmp->left.sym; |
| 511 | } else |
| 512 | sym1 = e1->left.sym; |
| 513 | if (e2->type == E_NOT) { |
| 514 | if (e2->left.expr->type != E_SYMBOL) |
| 515 | return NULL; |
| 516 | sym2 = e2->left.expr->left.sym; |
| 517 | } else |
| 518 | sym2 = e2->left.sym; |
| 519 | if (sym1 != sym2) |
| 520 | return NULL; |
| 521 | if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) |
| 522 | return NULL; |
| 523 | |
| 524 | if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) || |
| 525 | (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes)) |
| 526 | // (a) && (a='y') -> (a='y') |
| 527 | return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); |
| 528 | |
| 529 | if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) || |
| 530 | (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no)) |
| 531 | // (a) && (a!='n') -> (a) |
| 532 | return expr_alloc_symbol(sym1); |
| 533 | |
| 534 | if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) || |
| 535 | (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod)) |
| 536 | // (a) && (a!='m') -> (a='y') |
| 537 | return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); |
| 538 | |
| 539 | if (sym1->type == S_TRISTATE) { |
| 540 | if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) { |
| 541 | // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' |
| 542 | sym2 = e1->right.sym; |
| 543 | if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) |
| 544 | return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) |
| 545 | : expr_alloc_symbol(&symbol_no); |
| 546 | } |
| 547 | if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) { |
| 548 | // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' |
| 549 | sym2 = e2->right.sym; |
| 550 | if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) |
| 551 | return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) |
| 552 | : expr_alloc_symbol(&symbol_no); |
no test coverage detected