* Inserts explicit comparisons of type 'type' to symbol 'sym' into the * expression 'e'. * * Examples transformations for type == E_UNEQUAL, sym == &symbol_no: * * A -> A!=n * !A -> A=n * A && B -> !(A=n || B=n) * A || B -> !(A=n && B=n) * A && (B || C) -> !(A=n || (B=n && C=n)) * * Allocates and returns a new expression. */
| 920 | * Allocates and returns a new expression. |
| 921 | */ |
| 922 | struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) |
| 923 | { |
| 924 | struct expr *e1, *e2; |
| 925 | |
| 926 | if (!e) { |
| 927 | e = expr_alloc_symbol(sym); |
| 928 | if (type == E_UNEQUAL) |
| 929 | e = expr_alloc_one(E_NOT, e); |
| 930 | return e; |
| 931 | } |
| 932 | switch (e->type) { |
| 933 | case E_AND: |
| 934 | e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); |
| 935 | e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); |
| 936 | if (sym == &symbol_yes) |
| 937 | e = expr_alloc_two(E_AND, e1, e2); |
| 938 | if (sym == &symbol_no) |
| 939 | e = expr_alloc_two(E_OR, e1, e2); |
| 940 | if (type == E_UNEQUAL) |
| 941 | e = expr_alloc_one(E_NOT, e); |
| 942 | return e; |
| 943 | case E_OR: |
| 944 | e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); |
| 945 | e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); |
| 946 | if (sym == &symbol_yes) |
| 947 | e = expr_alloc_two(E_OR, e1, e2); |
| 948 | if (sym == &symbol_no) |
| 949 | e = expr_alloc_two(E_AND, e1, e2); |
| 950 | if (type == E_UNEQUAL) |
| 951 | e = expr_alloc_one(E_NOT, e); |
| 952 | return e; |
| 953 | case E_NOT: |
| 954 | return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym); |
| 955 | case E_UNEQUAL: |
| 956 | case E_LTH: |
| 957 | case E_LEQ: |
| 958 | case E_GTH: |
| 959 | case E_GEQ: |
| 960 | case E_EQUAL: |
| 961 | if (type == E_EQUAL) { |
| 962 | if (sym == &symbol_yes) |
| 963 | return expr_copy(e); |
| 964 | if (sym == &symbol_mod) |
| 965 | return expr_alloc_symbol(&symbol_no); |
| 966 | if (sym == &symbol_no) |
| 967 | return expr_alloc_one(E_NOT, expr_copy(e)); |
| 968 | } else { |
| 969 | if (sym == &symbol_yes) |
| 970 | return expr_alloc_one(E_NOT, expr_copy(e)); |
| 971 | if (sym == &symbol_mod) |
| 972 | return expr_alloc_symbol(&symbol_yes); |
| 973 | if (sym == &symbol_no) |
| 974 | return expr_copy(e); |
| 975 | } |
| 976 | break; |
| 977 | case E_SYMBOL: |
| 978 | return expr_alloc_comp(type, e->left.sym, sym); |
| 979 | case E_LIST: |
no test coverage detected