* e1 || e2 -> ? */
| 429 | * e1 || e2 -> ? |
| 430 | */ |
| 431 | static struct expr *expr_join_or(struct expr *e1, struct expr *e2) |
| 432 | { |
| 433 | struct expr *tmp; |
| 434 | struct symbol *sym1, *sym2; |
| 435 | |
| 436 | if (expr_eq(e1, e2)) |
| 437 | return expr_copy(e1); |
| 438 | if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) |
| 439 | return NULL; |
| 440 | if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) |
| 441 | return NULL; |
| 442 | if (e1->type == E_NOT) { |
| 443 | tmp = e1->left.expr; |
| 444 | if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) |
| 445 | return NULL; |
| 446 | sym1 = tmp->left.sym; |
| 447 | } else |
| 448 | sym1 = e1->left.sym; |
| 449 | if (e2->type == E_NOT) { |
| 450 | if (e2->left.expr->type != E_SYMBOL) |
| 451 | return NULL; |
| 452 | sym2 = e2->left.expr->left.sym; |
| 453 | } else |
| 454 | sym2 = e2->left.sym; |
| 455 | if (sym1 != sym2) |
| 456 | return NULL; |
| 457 | if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) |
| 458 | return NULL; |
| 459 | if (sym1->type == S_TRISTATE) { |
| 460 | if (e1->type == E_EQUAL && e2->type == E_EQUAL && |
| 461 | ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || |
| 462 | (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) { |
| 463 | // (a='y') || (a='m') -> (a!='n') |
| 464 | return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no); |
| 465 | } |
| 466 | if (e1->type == E_EQUAL && e2->type == E_EQUAL && |
| 467 | ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || |
| 468 | (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) { |
| 469 | // (a='y') || (a='n') -> (a!='m') |
| 470 | return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod); |
| 471 | } |
| 472 | if (e1->type == E_EQUAL && e2->type == E_EQUAL && |
| 473 | ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || |
| 474 | (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) { |
| 475 | // (a='m') || (a='n') -> (a!='y') |
| 476 | return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes); |
| 477 | } |
| 478 | } |
| 479 | if (sym1->type == S_BOOLEAN && sym1 == sym2) { |
| 480 | if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) || |
| 481 | (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL)) |
| 482 | return expr_alloc_symbol(&symbol_yes); |
| 483 | } |
| 484 | |
| 485 | if (DEBUG_EXPR) { |
| 486 | printf("optimize ("); |
| 487 | expr_fprint(e1, stdout); |
| 488 | printf(") || ("); |
no test coverage detected