15257cf54a5810105bc4a75703a06740d756d8e8landley/* 25257cf54a5810105bc4a75703a06740d756d8e8landley * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 35257cf54a5810105bc4a75703a06740d756d8e8landley * Released under the terms of the GNU GPL v2.0. 45257cf54a5810105bc4a75703a06740d756d8e8landley */ 55257cf54a5810105bc4a75703a06740d756d8e8landley 65257cf54a5810105bc4a75703a06740d756d8e8landley#include <stdio.h> 75257cf54a5810105bc4a75703a06740d756d8e8landley#include <stdlib.h> 85257cf54a5810105bc4a75703a06740d756d8e8landley#include <string.h> 95257cf54a5810105bc4a75703a06740d756d8e8landley 105257cf54a5810105bc4a75703a06740d756d8e8landley#define LKC_DIRECT_LINK 115257cf54a5810105bc4a75703a06740d756d8e8landley#include "lkc.h" 125257cf54a5810105bc4a75703a06740d756d8e8landley 135257cf54a5810105bc4a75703a06740d756d8e8landley#define DEBUG_EXPR 0 145257cf54a5810105bc4a75703a06740d756d8e8landley 155257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_alloc_symbol(struct symbol *sym) 165257cf54a5810105bc4a75703a06740d756d8e8landley{ 175257cf54a5810105bc4a75703a06740d756d8e8landley struct expr *e = malloc(sizeof(*e)); 185257cf54a5810105bc4a75703a06740d756d8e8landley memset(e, 0, sizeof(*e)); 195257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_SYMBOL; 205257cf54a5810105bc4a75703a06740d756d8e8landley e->left.sym = sym; 215257cf54a5810105bc4a75703a06740d756d8e8landley return e; 225257cf54a5810105bc4a75703a06740d756d8e8landley} 235257cf54a5810105bc4a75703a06740d756d8e8landley 245257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_alloc_one(enum expr_type type, struct expr *ce) 255257cf54a5810105bc4a75703a06740d756d8e8landley{ 265257cf54a5810105bc4a75703a06740d756d8e8landley struct expr *e = malloc(sizeof(*e)); 275257cf54a5810105bc4a75703a06740d756d8e8landley memset(e, 0, sizeof(*e)); 285257cf54a5810105bc4a75703a06740d756d8e8landley e->type = type; 295257cf54a5810105bc4a75703a06740d756d8e8landley e->left.expr = ce; 305257cf54a5810105bc4a75703a06740d756d8e8landley return e; 315257cf54a5810105bc4a75703a06740d756d8e8landley} 325257cf54a5810105bc4a75703a06740d756d8e8landley 335257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2) 345257cf54a5810105bc4a75703a06740d756d8e8landley{ 355257cf54a5810105bc4a75703a06740d756d8e8landley struct expr *e = malloc(sizeof(*e)); 365257cf54a5810105bc4a75703a06740d756d8e8landley memset(e, 0, sizeof(*e)); 375257cf54a5810105bc4a75703a06740d756d8e8landley e->type = type; 385257cf54a5810105bc4a75703a06740d756d8e8landley e->left.expr = e1; 395257cf54a5810105bc4a75703a06740d756d8e8landley e->right.expr = e2; 405257cf54a5810105bc4a75703a06740d756d8e8landley return e; 415257cf54a5810105bc4a75703a06740d756d8e8landley} 425257cf54a5810105bc4a75703a06740d756d8e8landley 435257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2) 445257cf54a5810105bc4a75703a06740d756d8e8landley{ 455257cf54a5810105bc4a75703a06740d756d8e8landley struct expr *e = malloc(sizeof(*e)); 465257cf54a5810105bc4a75703a06740d756d8e8landley memset(e, 0, sizeof(*e)); 475257cf54a5810105bc4a75703a06740d756d8e8landley e->type = type; 485257cf54a5810105bc4a75703a06740d756d8e8landley e->left.sym = s1; 495257cf54a5810105bc4a75703a06740d756d8e8landley e->right.sym = s2; 505257cf54a5810105bc4a75703a06740d756d8e8landley return e; 515257cf54a5810105bc4a75703a06740d756d8e8landley} 525257cf54a5810105bc4a75703a06740d756d8e8landley 535257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_alloc_and(struct expr *e1, struct expr *e2) 545257cf54a5810105bc4a75703a06740d756d8e8landley{ 555257cf54a5810105bc4a75703a06740d756d8e8landley if (!e1) 565257cf54a5810105bc4a75703a06740d756d8e8landley return e2; 575257cf54a5810105bc4a75703a06740d756d8e8landley return e2 ? expr_alloc_two(E_AND, e1, e2) : e1; 585257cf54a5810105bc4a75703a06740d756d8e8landley} 595257cf54a5810105bc4a75703a06740d756d8e8landley 605257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_alloc_or(struct expr *e1, struct expr *e2) 615257cf54a5810105bc4a75703a06740d756d8e8landley{ 625257cf54a5810105bc4a75703a06740d756d8e8landley if (!e1) 635257cf54a5810105bc4a75703a06740d756d8e8landley return e2; 645257cf54a5810105bc4a75703a06740d756d8e8landley return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; 655257cf54a5810105bc4a75703a06740d756d8e8landley} 665257cf54a5810105bc4a75703a06740d756d8e8landley 675257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_copy(struct expr *org) 685257cf54a5810105bc4a75703a06740d756d8e8landley{ 695257cf54a5810105bc4a75703a06740d756d8e8landley struct expr *e; 705257cf54a5810105bc4a75703a06740d756d8e8landley 715257cf54a5810105bc4a75703a06740d756d8e8landley if (!org) 725257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 735257cf54a5810105bc4a75703a06740d756d8e8landley 745257cf54a5810105bc4a75703a06740d756d8e8landley e = malloc(sizeof(*org)); 755257cf54a5810105bc4a75703a06740d756d8e8landley memcpy(e, org, sizeof(*org)); 765257cf54a5810105bc4a75703a06740d756d8e8landley switch (org->type) { 775257cf54a5810105bc4a75703a06740d756d8e8landley case E_SYMBOL: 785257cf54a5810105bc4a75703a06740d756d8e8landley e->left = org->left; 795257cf54a5810105bc4a75703a06740d756d8e8landley break; 805257cf54a5810105bc4a75703a06740d756d8e8landley case E_NOT: 815257cf54a5810105bc4a75703a06740d756d8e8landley e->left.expr = expr_copy(org->left.expr); 825257cf54a5810105bc4a75703a06740d756d8e8landley break; 835257cf54a5810105bc4a75703a06740d756d8e8landley case E_EQUAL: 845257cf54a5810105bc4a75703a06740d756d8e8landley case E_UNEQUAL: 855257cf54a5810105bc4a75703a06740d756d8e8landley e->left.sym = org->left.sym; 865257cf54a5810105bc4a75703a06740d756d8e8landley e->right.sym = org->right.sym; 875257cf54a5810105bc4a75703a06740d756d8e8landley break; 885257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 895257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 905257cf54a5810105bc4a75703a06740d756d8e8landley case E_CHOICE: 915257cf54a5810105bc4a75703a06740d756d8e8landley e->left.expr = expr_copy(org->left.expr); 925257cf54a5810105bc4a75703a06740d756d8e8landley e->right.expr = expr_copy(org->right.expr); 935257cf54a5810105bc4a75703a06740d756d8e8landley break; 945257cf54a5810105bc4a75703a06740d756d8e8landley default: 955257cf54a5810105bc4a75703a06740d756d8e8landley printf("can't copy type %d\n", e->type); 965257cf54a5810105bc4a75703a06740d756d8e8landley free(e); 975257cf54a5810105bc4a75703a06740d756d8e8landley e = NULL; 985257cf54a5810105bc4a75703a06740d756d8e8landley break; 995257cf54a5810105bc4a75703a06740d756d8e8landley } 1005257cf54a5810105bc4a75703a06740d756d8e8landley 1015257cf54a5810105bc4a75703a06740d756d8e8landley return e; 1025257cf54a5810105bc4a75703a06740d756d8e8landley} 1035257cf54a5810105bc4a75703a06740d756d8e8landley 1045257cf54a5810105bc4a75703a06740d756d8e8landleyvoid expr_free(struct expr *e) 1055257cf54a5810105bc4a75703a06740d756d8e8landley{ 1065257cf54a5810105bc4a75703a06740d756d8e8landley if (!e) 1075257cf54a5810105bc4a75703a06740d756d8e8landley return; 1085257cf54a5810105bc4a75703a06740d756d8e8landley 1095257cf54a5810105bc4a75703a06740d756d8e8landley switch (e->type) { 1105257cf54a5810105bc4a75703a06740d756d8e8landley case E_SYMBOL: 1115257cf54a5810105bc4a75703a06740d756d8e8landley break; 1125257cf54a5810105bc4a75703a06740d756d8e8landley case E_NOT: 1135257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e->left.expr); 1145257cf54a5810105bc4a75703a06740d756d8e8landley return; 1155257cf54a5810105bc4a75703a06740d756d8e8landley case E_EQUAL: 1165257cf54a5810105bc4a75703a06740d756d8e8landley case E_UNEQUAL: 1175257cf54a5810105bc4a75703a06740d756d8e8landley break; 1185257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 1195257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 1205257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e->left.expr); 1215257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e->right.expr); 1225257cf54a5810105bc4a75703a06740d756d8e8landley break; 1235257cf54a5810105bc4a75703a06740d756d8e8landley default: 1245257cf54a5810105bc4a75703a06740d756d8e8landley printf("how to free type %d?\n", e->type); 1255257cf54a5810105bc4a75703a06740d756d8e8landley break; 1265257cf54a5810105bc4a75703a06740d756d8e8landley } 1275257cf54a5810105bc4a75703a06740d756d8e8landley free(e); 1285257cf54a5810105bc4a75703a06740d756d8e8landley} 1295257cf54a5810105bc4a75703a06740d756d8e8landley 1305257cf54a5810105bc4a75703a06740d756d8e8landleystatic int trans_count; 1315257cf54a5810105bc4a75703a06740d756d8e8landley 1325257cf54a5810105bc4a75703a06740d756d8e8landley#define e1 (*ep1) 1335257cf54a5810105bc4a75703a06740d756d8e8landley#define e2 (*ep2) 1345257cf54a5810105bc4a75703a06740d756d8e8landley 1355257cf54a5810105bc4a75703a06740d756d8e8landleystatic void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2) 1365257cf54a5810105bc4a75703a06740d756d8e8landley{ 1375257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == type) { 1385257cf54a5810105bc4a75703a06740d756d8e8landley __expr_eliminate_eq(type, &e1->left.expr, &e2); 1395257cf54a5810105bc4a75703a06740d756d8e8landley __expr_eliminate_eq(type, &e1->right.expr, &e2); 1405257cf54a5810105bc4a75703a06740d756d8e8landley return; 1415257cf54a5810105bc4a75703a06740d756d8e8landley } 1425257cf54a5810105bc4a75703a06740d756d8e8landley if (e2->type == type) { 1435257cf54a5810105bc4a75703a06740d756d8e8landley __expr_eliminate_eq(type, &e1, &e2->left.expr); 1445257cf54a5810105bc4a75703a06740d756d8e8landley __expr_eliminate_eq(type, &e1, &e2->right.expr); 1455257cf54a5810105bc4a75703a06740d756d8e8landley return; 1465257cf54a5810105bc4a75703a06740d756d8e8landley } 1475257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && 1485257cf54a5810105bc4a75703a06740d756d8e8landley e1->left.sym == e2->left.sym && 1495257cf54a5810105bc4a75703a06740d756d8e8landley (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no)) 1505257cf54a5810105bc4a75703a06740d756d8e8landley return; 1515257cf54a5810105bc4a75703a06740d756d8e8landley if (!expr_eq(e1, e2)) 1525257cf54a5810105bc4a75703a06740d756d8e8landley return; 1535257cf54a5810105bc4a75703a06740d756d8e8landley trans_count++; 1545257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e1); expr_free(e2); 1555257cf54a5810105bc4a75703a06740d756d8e8landley switch (type) { 1565257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 1575257cf54a5810105bc4a75703a06740d756d8e8landley e1 = expr_alloc_symbol(&symbol_no); 1585257cf54a5810105bc4a75703a06740d756d8e8landley e2 = expr_alloc_symbol(&symbol_no); 1595257cf54a5810105bc4a75703a06740d756d8e8landley break; 1605257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 1615257cf54a5810105bc4a75703a06740d756d8e8landley e1 = expr_alloc_symbol(&symbol_yes); 1625257cf54a5810105bc4a75703a06740d756d8e8landley e2 = expr_alloc_symbol(&symbol_yes); 1635257cf54a5810105bc4a75703a06740d756d8e8landley break; 1645257cf54a5810105bc4a75703a06740d756d8e8landley default: 1655257cf54a5810105bc4a75703a06740d756d8e8landley ; 1665257cf54a5810105bc4a75703a06740d756d8e8landley } 1675257cf54a5810105bc4a75703a06740d756d8e8landley} 1685257cf54a5810105bc4a75703a06740d756d8e8landley 1695257cf54a5810105bc4a75703a06740d756d8e8landleyvoid expr_eliminate_eq(struct expr **ep1, struct expr **ep2) 1705257cf54a5810105bc4a75703a06740d756d8e8landley{ 1715257cf54a5810105bc4a75703a06740d756d8e8landley if (!e1 || !e2) 1725257cf54a5810105bc4a75703a06740d756d8e8landley return; 1735257cf54a5810105bc4a75703a06740d756d8e8landley switch (e1->type) { 1745257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 1755257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 1765257cf54a5810105bc4a75703a06740d756d8e8landley __expr_eliminate_eq(e1->type, ep1, ep2); 1775257cf54a5810105bc4a75703a06740d756d8e8landley default: 1785257cf54a5810105bc4a75703a06740d756d8e8landley ; 1795257cf54a5810105bc4a75703a06740d756d8e8landley } 1805257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type != e2->type) switch (e2->type) { 1815257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 1825257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 1835257cf54a5810105bc4a75703a06740d756d8e8landley __expr_eliminate_eq(e2->type, ep1, ep2); 1845257cf54a5810105bc4a75703a06740d756d8e8landley default: 1855257cf54a5810105bc4a75703a06740d756d8e8landley ; 1865257cf54a5810105bc4a75703a06740d756d8e8landley } 1875257cf54a5810105bc4a75703a06740d756d8e8landley e1 = expr_eliminate_yn(e1); 1885257cf54a5810105bc4a75703a06740d756d8e8landley e2 = expr_eliminate_yn(e2); 1895257cf54a5810105bc4a75703a06740d756d8e8landley} 1905257cf54a5810105bc4a75703a06740d756d8e8landley 1915257cf54a5810105bc4a75703a06740d756d8e8landley#undef e1 1925257cf54a5810105bc4a75703a06740d756d8e8landley#undef e2 1935257cf54a5810105bc4a75703a06740d756d8e8landley 1945257cf54a5810105bc4a75703a06740d756d8e8landleyint expr_eq(struct expr *e1, struct expr *e2) 1955257cf54a5810105bc4a75703a06740d756d8e8landley{ 1965257cf54a5810105bc4a75703a06740d756d8e8landley int res, old_count; 1975257cf54a5810105bc4a75703a06740d756d8e8landley 1985257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type != e2->type) 1995257cf54a5810105bc4a75703a06740d756d8e8landley return 0; 2005257cf54a5810105bc4a75703a06740d756d8e8landley switch (e1->type) { 2015257cf54a5810105bc4a75703a06740d756d8e8landley case E_EQUAL: 2025257cf54a5810105bc4a75703a06740d756d8e8landley case E_UNEQUAL: 2035257cf54a5810105bc4a75703a06740d756d8e8landley return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym; 2045257cf54a5810105bc4a75703a06740d756d8e8landley case E_SYMBOL: 2055257cf54a5810105bc4a75703a06740d756d8e8landley return e1->left.sym == e2->left.sym; 2065257cf54a5810105bc4a75703a06740d756d8e8landley case E_NOT: 2075257cf54a5810105bc4a75703a06740d756d8e8landley return expr_eq(e1->left.expr, e2->left.expr); 2085257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 2095257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 2105257cf54a5810105bc4a75703a06740d756d8e8landley e1 = expr_copy(e1); 2115257cf54a5810105bc4a75703a06740d756d8e8landley e2 = expr_copy(e2); 2125257cf54a5810105bc4a75703a06740d756d8e8landley old_count = trans_count; 2135257cf54a5810105bc4a75703a06740d756d8e8landley expr_eliminate_eq(&e1, &e2); 2145257cf54a5810105bc4a75703a06740d756d8e8landley res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL && 2155257cf54a5810105bc4a75703a06740d756d8e8landley e1->left.sym == e2->left.sym); 2165257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e1); 2175257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e2); 2185257cf54a5810105bc4a75703a06740d756d8e8landley trans_count = old_count; 2195257cf54a5810105bc4a75703a06740d756d8e8landley return res; 2205257cf54a5810105bc4a75703a06740d756d8e8landley case E_CHOICE: 2215257cf54a5810105bc4a75703a06740d756d8e8landley case E_RANGE: 2225257cf54a5810105bc4a75703a06740d756d8e8landley case E_NONE: 2235257cf54a5810105bc4a75703a06740d756d8e8landley /* panic */; 2245257cf54a5810105bc4a75703a06740d756d8e8landley } 2255257cf54a5810105bc4a75703a06740d756d8e8landley 2265257cf54a5810105bc4a75703a06740d756d8e8landley if (DEBUG_EXPR) { 2275257cf54a5810105bc4a75703a06740d756d8e8landley expr_fprint(e1, stdout); 2285257cf54a5810105bc4a75703a06740d756d8e8landley printf(" = "); 2295257cf54a5810105bc4a75703a06740d756d8e8landley expr_fprint(e2, stdout); 2305257cf54a5810105bc4a75703a06740d756d8e8landley printf(" ?\n"); 2315257cf54a5810105bc4a75703a06740d756d8e8landley } 2325257cf54a5810105bc4a75703a06740d756d8e8landley 2335257cf54a5810105bc4a75703a06740d756d8e8landley return 0; 2345257cf54a5810105bc4a75703a06740d756d8e8landley} 2355257cf54a5810105bc4a75703a06740d756d8e8landley 2365257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_eliminate_yn(struct expr *e) 2375257cf54a5810105bc4a75703a06740d756d8e8landley{ 2385257cf54a5810105bc4a75703a06740d756d8e8landley struct expr *tmp; 2395257cf54a5810105bc4a75703a06740d756d8e8landley 2405257cf54a5810105bc4a75703a06740d756d8e8landley if (e) switch (e->type) { 2415257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 2425257cf54a5810105bc4a75703a06740d756d8e8landley e->left.expr = expr_eliminate_yn(e->left.expr); 2435257cf54a5810105bc4a75703a06740d756d8e8landley e->right.expr = expr_eliminate_yn(e->right.expr); 2445257cf54a5810105bc4a75703a06740d756d8e8landley if (e->left.expr->type == E_SYMBOL) { 2455257cf54a5810105bc4a75703a06740d756d8e8landley if (e->left.expr->left.sym == &symbol_no) { 2465257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e->left.expr); 2475257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e->right.expr); 2485257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_SYMBOL; 2495257cf54a5810105bc4a75703a06740d756d8e8landley e->left.sym = &symbol_no; 2505257cf54a5810105bc4a75703a06740d756d8e8landley e->right.expr = NULL; 2515257cf54a5810105bc4a75703a06740d756d8e8landley return e; 2525257cf54a5810105bc4a75703a06740d756d8e8landley } else if (e->left.expr->left.sym == &symbol_yes) { 2535257cf54a5810105bc4a75703a06740d756d8e8landley free(e->left.expr); 2545257cf54a5810105bc4a75703a06740d756d8e8landley tmp = e->right.expr; 2555257cf54a5810105bc4a75703a06740d756d8e8landley *e = *(e->right.expr); 2565257cf54a5810105bc4a75703a06740d756d8e8landley free(tmp); 2575257cf54a5810105bc4a75703a06740d756d8e8landley return e; 2585257cf54a5810105bc4a75703a06740d756d8e8landley } 2595257cf54a5810105bc4a75703a06740d756d8e8landley } 2605257cf54a5810105bc4a75703a06740d756d8e8landley if (e->right.expr->type == E_SYMBOL) { 2615257cf54a5810105bc4a75703a06740d756d8e8landley if (e->right.expr->left.sym == &symbol_no) { 2625257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e->left.expr); 2635257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e->right.expr); 2645257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_SYMBOL; 2655257cf54a5810105bc4a75703a06740d756d8e8landley e->left.sym = &symbol_no; 2665257cf54a5810105bc4a75703a06740d756d8e8landley e->right.expr = NULL; 2675257cf54a5810105bc4a75703a06740d756d8e8landley return e; 2685257cf54a5810105bc4a75703a06740d756d8e8landley } else if (e->right.expr->left.sym == &symbol_yes) { 2695257cf54a5810105bc4a75703a06740d756d8e8landley free(e->right.expr); 2705257cf54a5810105bc4a75703a06740d756d8e8landley tmp = e->left.expr; 2715257cf54a5810105bc4a75703a06740d756d8e8landley *e = *(e->left.expr); 2725257cf54a5810105bc4a75703a06740d756d8e8landley free(tmp); 2735257cf54a5810105bc4a75703a06740d756d8e8landley return e; 2745257cf54a5810105bc4a75703a06740d756d8e8landley } 2755257cf54a5810105bc4a75703a06740d756d8e8landley } 2765257cf54a5810105bc4a75703a06740d756d8e8landley break; 2775257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 2785257cf54a5810105bc4a75703a06740d756d8e8landley e->left.expr = expr_eliminate_yn(e->left.expr); 2795257cf54a5810105bc4a75703a06740d756d8e8landley e->right.expr = expr_eliminate_yn(e->right.expr); 2805257cf54a5810105bc4a75703a06740d756d8e8landley if (e->left.expr->type == E_SYMBOL) { 2815257cf54a5810105bc4a75703a06740d756d8e8landley if (e->left.expr->left.sym == &symbol_no) { 2825257cf54a5810105bc4a75703a06740d756d8e8landley free(e->left.expr); 2835257cf54a5810105bc4a75703a06740d756d8e8landley tmp = e->right.expr; 2845257cf54a5810105bc4a75703a06740d756d8e8landley *e = *(e->right.expr); 2855257cf54a5810105bc4a75703a06740d756d8e8landley free(tmp); 2865257cf54a5810105bc4a75703a06740d756d8e8landley return e; 2875257cf54a5810105bc4a75703a06740d756d8e8landley } else if (e->left.expr->left.sym == &symbol_yes) { 2885257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e->left.expr); 2895257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e->right.expr); 2905257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_SYMBOL; 2915257cf54a5810105bc4a75703a06740d756d8e8landley e->left.sym = &symbol_yes; 2925257cf54a5810105bc4a75703a06740d756d8e8landley e->right.expr = NULL; 2935257cf54a5810105bc4a75703a06740d756d8e8landley return e; 2945257cf54a5810105bc4a75703a06740d756d8e8landley } 2955257cf54a5810105bc4a75703a06740d756d8e8landley } 2965257cf54a5810105bc4a75703a06740d756d8e8landley if (e->right.expr->type == E_SYMBOL) { 2975257cf54a5810105bc4a75703a06740d756d8e8landley if (e->right.expr->left.sym == &symbol_no) { 2985257cf54a5810105bc4a75703a06740d756d8e8landley free(e->right.expr); 2995257cf54a5810105bc4a75703a06740d756d8e8landley tmp = e->left.expr; 3005257cf54a5810105bc4a75703a06740d756d8e8landley *e = *(e->left.expr); 3015257cf54a5810105bc4a75703a06740d756d8e8landley free(tmp); 3025257cf54a5810105bc4a75703a06740d756d8e8landley return e; 3035257cf54a5810105bc4a75703a06740d756d8e8landley } else if (e->right.expr->left.sym == &symbol_yes) { 3045257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e->left.expr); 3055257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e->right.expr); 3065257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_SYMBOL; 3075257cf54a5810105bc4a75703a06740d756d8e8landley e->left.sym = &symbol_yes; 3085257cf54a5810105bc4a75703a06740d756d8e8landley e->right.expr = NULL; 3095257cf54a5810105bc4a75703a06740d756d8e8landley return e; 3105257cf54a5810105bc4a75703a06740d756d8e8landley } 3115257cf54a5810105bc4a75703a06740d756d8e8landley } 3125257cf54a5810105bc4a75703a06740d756d8e8landley break; 3135257cf54a5810105bc4a75703a06740d756d8e8landley default: 3145257cf54a5810105bc4a75703a06740d756d8e8landley ; 3155257cf54a5810105bc4a75703a06740d756d8e8landley } 3165257cf54a5810105bc4a75703a06740d756d8e8landley return e; 3175257cf54a5810105bc4a75703a06740d756d8e8landley} 3185257cf54a5810105bc4a75703a06740d756d8e8landley 3195257cf54a5810105bc4a75703a06740d756d8e8landley/* 3205257cf54a5810105bc4a75703a06740d756d8e8landley * bool FOO!=n => FOO 3215257cf54a5810105bc4a75703a06740d756d8e8landley */ 3225257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_trans_bool(struct expr *e) 3235257cf54a5810105bc4a75703a06740d756d8e8landley{ 3245257cf54a5810105bc4a75703a06740d756d8e8landley if (!e) 3255257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 3265257cf54a5810105bc4a75703a06740d756d8e8landley switch (e->type) { 3275257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 3285257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 3295257cf54a5810105bc4a75703a06740d756d8e8landley case E_NOT: 3305257cf54a5810105bc4a75703a06740d756d8e8landley e->left.expr = expr_trans_bool(e->left.expr); 3315257cf54a5810105bc4a75703a06740d756d8e8landley e->right.expr = expr_trans_bool(e->right.expr); 3325257cf54a5810105bc4a75703a06740d756d8e8landley break; 3335257cf54a5810105bc4a75703a06740d756d8e8landley case E_UNEQUAL: 3345257cf54a5810105bc4a75703a06740d756d8e8landley // FOO!=n -> FOO 3355257cf54a5810105bc4a75703a06740d756d8e8landley if (e->left.sym->type == S_TRISTATE) { 3365257cf54a5810105bc4a75703a06740d756d8e8landley if (e->right.sym == &symbol_no) { 3375257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_SYMBOL; 3385257cf54a5810105bc4a75703a06740d756d8e8landley e->right.sym = NULL; 3395257cf54a5810105bc4a75703a06740d756d8e8landley } 3405257cf54a5810105bc4a75703a06740d756d8e8landley } 3415257cf54a5810105bc4a75703a06740d756d8e8landley break; 3425257cf54a5810105bc4a75703a06740d756d8e8landley default: 3435257cf54a5810105bc4a75703a06740d756d8e8landley ; 3445257cf54a5810105bc4a75703a06740d756d8e8landley } 3455257cf54a5810105bc4a75703a06740d756d8e8landley return e; 3465257cf54a5810105bc4a75703a06740d756d8e8landley} 3475257cf54a5810105bc4a75703a06740d756d8e8landley 3485257cf54a5810105bc4a75703a06740d756d8e8landley/* 3495257cf54a5810105bc4a75703a06740d756d8e8landley * e1 || e2 -> ? 3505257cf54a5810105bc4a75703a06740d756d8e8landley */ 3515257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_join_or(struct expr *e1, struct expr *e2) 3525257cf54a5810105bc4a75703a06740d756d8e8landley{ 3535257cf54a5810105bc4a75703a06740d756d8e8landley struct expr *tmp; 3545257cf54a5810105bc4a75703a06740d756d8e8landley struct symbol *sym1, *sym2; 3555257cf54a5810105bc4a75703a06740d756d8e8landley 3565257cf54a5810105bc4a75703a06740d756d8e8landley if (expr_eq(e1, e2)) 3575257cf54a5810105bc4a75703a06740d756d8e8landley return expr_copy(e1); 3585257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) 3595257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 3605257cf54a5810105bc4a75703a06740d756d8e8landley if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) 3615257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 3625257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == E_NOT) { 3635257cf54a5810105bc4a75703a06740d756d8e8landley tmp = e1->left.expr; 3645257cf54a5810105bc4a75703a06740d756d8e8landley if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) 3655257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 3665257cf54a5810105bc4a75703a06740d756d8e8landley sym1 = tmp->left.sym; 3675257cf54a5810105bc4a75703a06740d756d8e8landley } else 3685257cf54a5810105bc4a75703a06740d756d8e8landley sym1 = e1->left.sym; 3695257cf54a5810105bc4a75703a06740d756d8e8landley if (e2->type == E_NOT) { 3705257cf54a5810105bc4a75703a06740d756d8e8landley if (e2->left.expr->type != E_SYMBOL) 3715257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 3725257cf54a5810105bc4a75703a06740d756d8e8landley sym2 = e2->left.expr->left.sym; 3735257cf54a5810105bc4a75703a06740d756d8e8landley } else 3745257cf54a5810105bc4a75703a06740d756d8e8landley sym2 = e2->left.sym; 3755257cf54a5810105bc4a75703a06740d756d8e8landley if (sym1 != sym2) 3765257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 3775257cf54a5810105bc4a75703a06740d756d8e8landley if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) 3785257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 3795257cf54a5810105bc4a75703a06740d756d8e8landley if (sym1->type == S_TRISTATE) { 3805257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == E_EQUAL && e2->type == E_EQUAL && 3815257cf54a5810105bc4a75703a06740d756d8e8landley ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || 3825257cf54a5810105bc4a75703a06740d756d8e8landley (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) { 3835257cf54a5810105bc4a75703a06740d756d8e8landley // (a='y') || (a='m') -> (a!='n') 3845257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no); 3855257cf54a5810105bc4a75703a06740d756d8e8landley } 3865257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == E_EQUAL && e2->type == E_EQUAL && 3875257cf54a5810105bc4a75703a06740d756d8e8landley ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || 3885257cf54a5810105bc4a75703a06740d756d8e8landley (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) { 3895257cf54a5810105bc4a75703a06740d756d8e8landley // (a='y') || (a='n') -> (a!='m') 3905257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod); 3915257cf54a5810105bc4a75703a06740d756d8e8landley } 3925257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == E_EQUAL && e2->type == E_EQUAL && 3935257cf54a5810105bc4a75703a06740d756d8e8landley ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || 3945257cf54a5810105bc4a75703a06740d756d8e8landley (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) { 3955257cf54a5810105bc4a75703a06740d756d8e8landley // (a='m') || (a='n') -> (a!='y') 3965257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes); 3975257cf54a5810105bc4a75703a06740d756d8e8landley } 3985257cf54a5810105bc4a75703a06740d756d8e8landley } 3995257cf54a5810105bc4a75703a06740d756d8e8landley if (sym1->type == S_BOOLEAN && sym1 == sym2) { 4005257cf54a5810105bc4a75703a06740d756d8e8landley if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) || 4015257cf54a5810105bc4a75703a06740d756d8e8landley (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL)) 4025257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_symbol(&symbol_yes); 4035257cf54a5810105bc4a75703a06740d756d8e8landley } 4045257cf54a5810105bc4a75703a06740d756d8e8landley 4055257cf54a5810105bc4a75703a06740d756d8e8landley if (DEBUG_EXPR) { 4065257cf54a5810105bc4a75703a06740d756d8e8landley printf("optimize ("); 4075257cf54a5810105bc4a75703a06740d756d8e8landley expr_fprint(e1, stdout); 4085257cf54a5810105bc4a75703a06740d756d8e8landley printf(") || ("); 4095257cf54a5810105bc4a75703a06740d756d8e8landley expr_fprint(e2, stdout); 4105257cf54a5810105bc4a75703a06740d756d8e8landley printf(")?\n"); 4115257cf54a5810105bc4a75703a06740d756d8e8landley } 4125257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 4135257cf54a5810105bc4a75703a06740d756d8e8landley} 4145257cf54a5810105bc4a75703a06740d756d8e8landley 4155257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_join_and(struct expr *e1, struct expr *e2) 4165257cf54a5810105bc4a75703a06740d756d8e8landley{ 4175257cf54a5810105bc4a75703a06740d756d8e8landley struct expr *tmp; 4185257cf54a5810105bc4a75703a06740d756d8e8landley struct symbol *sym1, *sym2; 4195257cf54a5810105bc4a75703a06740d756d8e8landley 4205257cf54a5810105bc4a75703a06740d756d8e8landley if (expr_eq(e1, e2)) 4215257cf54a5810105bc4a75703a06740d756d8e8landley return expr_copy(e1); 4225257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) 4235257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 4245257cf54a5810105bc4a75703a06740d756d8e8landley if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) 4255257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 4265257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == E_NOT) { 4275257cf54a5810105bc4a75703a06740d756d8e8landley tmp = e1->left.expr; 4285257cf54a5810105bc4a75703a06740d756d8e8landley if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) 4295257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 4305257cf54a5810105bc4a75703a06740d756d8e8landley sym1 = tmp->left.sym; 4315257cf54a5810105bc4a75703a06740d756d8e8landley } else 4325257cf54a5810105bc4a75703a06740d756d8e8landley sym1 = e1->left.sym; 4335257cf54a5810105bc4a75703a06740d756d8e8landley if (e2->type == E_NOT) { 4345257cf54a5810105bc4a75703a06740d756d8e8landley if (e2->left.expr->type != E_SYMBOL) 4355257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 4365257cf54a5810105bc4a75703a06740d756d8e8landley sym2 = e2->left.expr->left.sym; 4375257cf54a5810105bc4a75703a06740d756d8e8landley } else 4385257cf54a5810105bc4a75703a06740d756d8e8landley sym2 = e2->left.sym; 4395257cf54a5810105bc4a75703a06740d756d8e8landley if (sym1 != sym2) 4405257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 4415257cf54a5810105bc4a75703a06740d756d8e8landley if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) 4425257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 4435257cf54a5810105bc4a75703a06740d756d8e8landley 4445257cf54a5810105bc4a75703a06740d756d8e8landley if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) || 4455257cf54a5810105bc4a75703a06740d756d8e8landley (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes)) 4465257cf54a5810105bc4a75703a06740d756d8e8landley // (a) && (a='y') -> (a='y') 4475257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); 4485257cf54a5810105bc4a75703a06740d756d8e8landley 4495257cf54a5810105bc4a75703a06740d756d8e8landley if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) || 4505257cf54a5810105bc4a75703a06740d756d8e8landley (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no)) 4515257cf54a5810105bc4a75703a06740d756d8e8landley // (a) && (a!='n') -> (a) 4525257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_symbol(sym1); 4535257cf54a5810105bc4a75703a06740d756d8e8landley 4545257cf54a5810105bc4a75703a06740d756d8e8landley if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) || 4555257cf54a5810105bc4a75703a06740d756d8e8landley (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod)) 4565257cf54a5810105bc4a75703a06740d756d8e8landley // (a) && (a!='m') -> (a='y') 4575257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); 4585257cf54a5810105bc4a75703a06740d756d8e8landley 4595257cf54a5810105bc4a75703a06740d756d8e8landley if (sym1->type == S_TRISTATE) { 4605257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) { 4615257cf54a5810105bc4a75703a06740d756d8e8landley // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' 4625257cf54a5810105bc4a75703a06740d756d8e8landley sym2 = e1->right.sym; 4635257cf54a5810105bc4a75703a06740d756d8e8landley if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) 4645257cf54a5810105bc4a75703a06740d756d8e8landley return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) 4655257cf54a5810105bc4a75703a06740d756d8e8landley : expr_alloc_symbol(&symbol_no); 4665257cf54a5810105bc4a75703a06740d756d8e8landley } 4675257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) { 4685257cf54a5810105bc4a75703a06740d756d8e8landley // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' 4695257cf54a5810105bc4a75703a06740d756d8e8landley sym2 = e2->right.sym; 4705257cf54a5810105bc4a75703a06740d756d8e8landley if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) 4715257cf54a5810105bc4a75703a06740d756d8e8landley return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) 4725257cf54a5810105bc4a75703a06740d756d8e8landley : expr_alloc_symbol(&symbol_no); 4735257cf54a5810105bc4a75703a06740d756d8e8landley } 4745257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 4755257cf54a5810105bc4a75703a06740d756d8e8landley ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || 4765257cf54a5810105bc4a75703a06740d756d8e8landley (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) 4775257cf54a5810105bc4a75703a06740d756d8e8landley // (a!='y') && (a!='n') -> (a='m') 4785257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod); 4795257cf54a5810105bc4a75703a06740d756d8e8landley 4805257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 4815257cf54a5810105bc4a75703a06740d756d8e8landley ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || 4825257cf54a5810105bc4a75703a06740d756d8e8landley (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) 4835257cf54a5810105bc4a75703a06740d756d8e8landley // (a!='y') && (a!='m') -> (a='n') 4845257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_comp(E_EQUAL, sym1, &symbol_no); 4855257cf54a5810105bc4a75703a06740d756d8e8landley 4865257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 4875257cf54a5810105bc4a75703a06740d756d8e8landley ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || 4885257cf54a5810105bc4a75703a06740d756d8e8landley (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) 4895257cf54a5810105bc4a75703a06740d756d8e8landley // (a!='m') && (a!='n') -> (a='m') 4905257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); 4915257cf54a5810105bc4a75703a06740d756d8e8landley 4925257cf54a5810105bc4a75703a06740d756d8e8landley if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) || 4935257cf54a5810105bc4a75703a06740d756d8e8landley (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) || 4945257cf54a5810105bc4a75703a06740d756d8e8landley (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) || 4955257cf54a5810105bc4a75703a06740d756d8e8landley (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes)) 4965257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 4975257cf54a5810105bc4a75703a06740d756d8e8landley } 4985257cf54a5810105bc4a75703a06740d756d8e8landley 4995257cf54a5810105bc4a75703a06740d756d8e8landley if (DEBUG_EXPR) { 5005257cf54a5810105bc4a75703a06740d756d8e8landley printf("optimize ("); 5015257cf54a5810105bc4a75703a06740d756d8e8landley expr_fprint(e1, stdout); 5025257cf54a5810105bc4a75703a06740d756d8e8landley printf(") && ("); 5035257cf54a5810105bc4a75703a06740d756d8e8landley expr_fprint(e2, stdout); 5045257cf54a5810105bc4a75703a06740d756d8e8landley printf(")?\n"); 5055257cf54a5810105bc4a75703a06740d756d8e8landley } 5065257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 5075257cf54a5810105bc4a75703a06740d756d8e8landley} 5085257cf54a5810105bc4a75703a06740d756d8e8landley 5095257cf54a5810105bc4a75703a06740d756d8e8landleystatic void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2) 5105257cf54a5810105bc4a75703a06740d756d8e8landley{ 5115257cf54a5810105bc4a75703a06740d756d8e8landley#define e1 (*ep1) 5125257cf54a5810105bc4a75703a06740d756d8e8landley#define e2 (*ep2) 5135257cf54a5810105bc4a75703a06740d756d8e8landley struct expr *tmp; 5145257cf54a5810105bc4a75703a06740d756d8e8landley 5155257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == type) { 5165257cf54a5810105bc4a75703a06740d756d8e8landley expr_eliminate_dups1(type, &e1->left.expr, &e2); 5175257cf54a5810105bc4a75703a06740d756d8e8landley expr_eliminate_dups1(type, &e1->right.expr, &e2); 5185257cf54a5810105bc4a75703a06740d756d8e8landley return; 5195257cf54a5810105bc4a75703a06740d756d8e8landley } 5205257cf54a5810105bc4a75703a06740d756d8e8landley if (e2->type == type) { 5215257cf54a5810105bc4a75703a06740d756d8e8landley expr_eliminate_dups1(type, &e1, &e2->left.expr); 5225257cf54a5810105bc4a75703a06740d756d8e8landley expr_eliminate_dups1(type, &e1, &e2->right.expr); 5235257cf54a5810105bc4a75703a06740d756d8e8landley return; 5245257cf54a5810105bc4a75703a06740d756d8e8landley } 5255257cf54a5810105bc4a75703a06740d756d8e8landley if (e1 == e2) 5265257cf54a5810105bc4a75703a06740d756d8e8landley return; 5275257cf54a5810105bc4a75703a06740d756d8e8landley 5285257cf54a5810105bc4a75703a06740d756d8e8landley switch (e1->type) { 5295257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: case E_AND: 5305257cf54a5810105bc4a75703a06740d756d8e8landley expr_eliminate_dups1(e1->type, &e1, &e1); 5315257cf54a5810105bc4a75703a06740d756d8e8landley default: 5325257cf54a5810105bc4a75703a06740d756d8e8landley ; 5335257cf54a5810105bc4a75703a06740d756d8e8landley } 5345257cf54a5810105bc4a75703a06740d756d8e8landley 5355257cf54a5810105bc4a75703a06740d756d8e8landley switch (type) { 5365257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 5375257cf54a5810105bc4a75703a06740d756d8e8landley tmp = expr_join_or(e1, e2); 5385257cf54a5810105bc4a75703a06740d756d8e8landley if (tmp) { 5395257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e1); expr_free(e2); 5405257cf54a5810105bc4a75703a06740d756d8e8landley e1 = expr_alloc_symbol(&symbol_no); 5415257cf54a5810105bc4a75703a06740d756d8e8landley e2 = tmp; 5425257cf54a5810105bc4a75703a06740d756d8e8landley trans_count++; 5435257cf54a5810105bc4a75703a06740d756d8e8landley } 5445257cf54a5810105bc4a75703a06740d756d8e8landley break; 5455257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 5465257cf54a5810105bc4a75703a06740d756d8e8landley tmp = expr_join_and(e1, e2); 5475257cf54a5810105bc4a75703a06740d756d8e8landley if (tmp) { 5485257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e1); expr_free(e2); 5495257cf54a5810105bc4a75703a06740d756d8e8landley e1 = expr_alloc_symbol(&symbol_yes); 5505257cf54a5810105bc4a75703a06740d756d8e8landley e2 = tmp; 5515257cf54a5810105bc4a75703a06740d756d8e8landley trans_count++; 5525257cf54a5810105bc4a75703a06740d756d8e8landley } 5535257cf54a5810105bc4a75703a06740d756d8e8landley break; 5545257cf54a5810105bc4a75703a06740d756d8e8landley default: 5555257cf54a5810105bc4a75703a06740d756d8e8landley ; 5565257cf54a5810105bc4a75703a06740d756d8e8landley } 5575257cf54a5810105bc4a75703a06740d756d8e8landley#undef e1 5585257cf54a5810105bc4a75703a06740d756d8e8landley#undef e2 5595257cf54a5810105bc4a75703a06740d756d8e8landley} 5605257cf54a5810105bc4a75703a06740d756d8e8landley 5615257cf54a5810105bc4a75703a06740d756d8e8landleystatic void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2) 5625257cf54a5810105bc4a75703a06740d756d8e8landley{ 5635257cf54a5810105bc4a75703a06740d756d8e8landley#define e1 (*ep1) 5645257cf54a5810105bc4a75703a06740d756d8e8landley#define e2 (*ep2) 5655257cf54a5810105bc4a75703a06740d756d8e8landley struct expr *tmp, *tmp1, *tmp2; 5665257cf54a5810105bc4a75703a06740d756d8e8landley 5675257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == type) { 5685257cf54a5810105bc4a75703a06740d756d8e8landley expr_eliminate_dups2(type, &e1->left.expr, &e2); 5695257cf54a5810105bc4a75703a06740d756d8e8landley expr_eliminate_dups2(type, &e1->right.expr, &e2); 5705257cf54a5810105bc4a75703a06740d756d8e8landley return; 5715257cf54a5810105bc4a75703a06740d756d8e8landley } 5725257cf54a5810105bc4a75703a06740d756d8e8landley if (e2->type == type) { 5735257cf54a5810105bc4a75703a06740d756d8e8landley expr_eliminate_dups2(type, &e1, &e2->left.expr); 5745257cf54a5810105bc4a75703a06740d756d8e8landley expr_eliminate_dups2(type, &e1, &e2->right.expr); 5755257cf54a5810105bc4a75703a06740d756d8e8landley } 5765257cf54a5810105bc4a75703a06740d756d8e8landley if (e1 == e2) 5775257cf54a5810105bc4a75703a06740d756d8e8landley return; 5785257cf54a5810105bc4a75703a06740d756d8e8landley 5795257cf54a5810105bc4a75703a06740d756d8e8landley switch (e1->type) { 5805257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 5815257cf54a5810105bc4a75703a06740d756d8e8landley expr_eliminate_dups2(e1->type, &e1, &e1); 5825257cf54a5810105bc4a75703a06740d756d8e8landley // (FOO || BAR) && (!FOO && !BAR) -> n 5835257cf54a5810105bc4a75703a06740d756d8e8landley tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); 5845257cf54a5810105bc4a75703a06740d756d8e8landley tmp2 = expr_copy(e2); 5855257cf54a5810105bc4a75703a06740d756d8e8landley tmp = expr_extract_eq_and(&tmp1, &tmp2); 5865257cf54a5810105bc4a75703a06740d756d8e8landley if (expr_is_yes(tmp1)) { 5875257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e1); 5885257cf54a5810105bc4a75703a06740d756d8e8landley e1 = expr_alloc_symbol(&symbol_no); 5895257cf54a5810105bc4a75703a06740d756d8e8landley trans_count++; 5905257cf54a5810105bc4a75703a06740d756d8e8landley } 5915257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(tmp2); 5925257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(tmp1); 5935257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(tmp); 5945257cf54a5810105bc4a75703a06740d756d8e8landley break; 5955257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 5965257cf54a5810105bc4a75703a06740d756d8e8landley expr_eliminate_dups2(e1->type, &e1, &e1); 5975257cf54a5810105bc4a75703a06740d756d8e8landley // (FOO && BAR) || (!FOO || !BAR) -> y 5985257cf54a5810105bc4a75703a06740d756d8e8landley tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); 5995257cf54a5810105bc4a75703a06740d756d8e8landley tmp2 = expr_copy(e2); 6005257cf54a5810105bc4a75703a06740d756d8e8landley tmp = expr_extract_eq_or(&tmp1, &tmp2); 6015257cf54a5810105bc4a75703a06740d756d8e8landley if (expr_is_no(tmp1)) { 6025257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e1); 6035257cf54a5810105bc4a75703a06740d756d8e8landley e1 = expr_alloc_symbol(&symbol_yes); 6045257cf54a5810105bc4a75703a06740d756d8e8landley trans_count++; 6055257cf54a5810105bc4a75703a06740d756d8e8landley } 6065257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(tmp2); 6075257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(tmp1); 6085257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(tmp); 6095257cf54a5810105bc4a75703a06740d756d8e8landley break; 6105257cf54a5810105bc4a75703a06740d756d8e8landley default: 6115257cf54a5810105bc4a75703a06740d756d8e8landley ; 6125257cf54a5810105bc4a75703a06740d756d8e8landley } 6135257cf54a5810105bc4a75703a06740d756d8e8landley#undef e1 6145257cf54a5810105bc4a75703a06740d756d8e8landley#undef e2 6155257cf54a5810105bc4a75703a06740d756d8e8landley} 6165257cf54a5810105bc4a75703a06740d756d8e8landley 6175257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_eliminate_dups(struct expr *e) 6185257cf54a5810105bc4a75703a06740d756d8e8landley{ 6195257cf54a5810105bc4a75703a06740d756d8e8landley int oldcount; 6205257cf54a5810105bc4a75703a06740d756d8e8landley if (!e) 6215257cf54a5810105bc4a75703a06740d756d8e8landley return e; 6225257cf54a5810105bc4a75703a06740d756d8e8landley 6235257cf54a5810105bc4a75703a06740d756d8e8landley oldcount = trans_count; 6245257cf54a5810105bc4a75703a06740d756d8e8landley while (1) { 6255257cf54a5810105bc4a75703a06740d756d8e8landley trans_count = 0; 6265257cf54a5810105bc4a75703a06740d756d8e8landley switch (e->type) { 6275257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: case E_AND: 6285257cf54a5810105bc4a75703a06740d756d8e8landley expr_eliminate_dups1(e->type, &e, &e); 6295257cf54a5810105bc4a75703a06740d756d8e8landley expr_eliminate_dups2(e->type, &e, &e); 6305257cf54a5810105bc4a75703a06740d756d8e8landley default: 6315257cf54a5810105bc4a75703a06740d756d8e8landley ; 6325257cf54a5810105bc4a75703a06740d756d8e8landley } 6335257cf54a5810105bc4a75703a06740d756d8e8landley if (!trans_count) 6345257cf54a5810105bc4a75703a06740d756d8e8landley break; 6355257cf54a5810105bc4a75703a06740d756d8e8landley e = expr_eliminate_yn(e); 6365257cf54a5810105bc4a75703a06740d756d8e8landley } 6375257cf54a5810105bc4a75703a06740d756d8e8landley trans_count = oldcount; 6385257cf54a5810105bc4a75703a06740d756d8e8landley return e; 6395257cf54a5810105bc4a75703a06740d756d8e8landley} 6405257cf54a5810105bc4a75703a06740d756d8e8landley 6415257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_transform(struct expr *e) 6425257cf54a5810105bc4a75703a06740d756d8e8landley{ 6435257cf54a5810105bc4a75703a06740d756d8e8landley struct expr *tmp; 6445257cf54a5810105bc4a75703a06740d756d8e8landley 6455257cf54a5810105bc4a75703a06740d756d8e8landley if (!e) 6465257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 6475257cf54a5810105bc4a75703a06740d756d8e8landley switch (e->type) { 6485257cf54a5810105bc4a75703a06740d756d8e8landley case E_EQUAL: 6495257cf54a5810105bc4a75703a06740d756d8e8landley case E_UNEQUAL: 6505257cf54a5810105bc4a75703a06740d756d8e8landley case E_SYMBOL: 6515257cf54a5810105bc4a75703a06740d756d8e8landley case E_CHOICE: 6525257cf54a5810105bc4a75703a06740d756d8e8landley break; 6535257cf54a5810105bc4a75703a06740d756d8e8landley default: 6545257cf54a5810105bc4a75703a06740d756d8e8landley e->left.expr = expr_transform(e->left.expr); 6555257cf54a5810105bc4a75703a06740d756d8e8landley e->right.expr = expr_transform(e->right.expr); 6565257cf54a5810105bc4a75703a06740d756d8e8landley } 6575257cf54a5810105bc4a75703a06740d756d8e8landley 6585257cf54a5810105bc4a75703a06740d756d8e8landley switch (e->type) { 6595257cf54a5810105bc4a75703a06740d756d8e8landley case E_EQUAL: 6605257cf54a5810105bc4a75703a06740d756d8e8landley if (e->left.sym->type != S_BOOLEAN) 6615257cf54a5810105bc4a75703a06740d756d8e8landley break; 6625257cf54a5810105bc4a75703a06740d756d8e8landley if (e->right.sym == &symbol_no) { 6635257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_NOT; 6645257cf54a5810105bc4a75703a06740d756d8e8landley e->left.expr = expr_alloc_symbol(e->left.sym); 6655257cf54a5810105bc4a75703a06740d756d8e8landley e->right.sym = NULL; 6665257cf54a5810105bc4a75703a06740d756d8e8landley break; 6675257cf54a5810105bc4a75703a06740d756d8e8landley } 6685257cf54a5810105bc4a75703a06740d756d8e8landley if (e->right.sym == &symbol_mod) { 6695257cf54a5810105bc4a75703a06740d756d8e8landley printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name); 6705257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_SYMBOL; 6715257cf54a5810105bc4a75703a06740d756d8e8landley e->left.sym = &symbol_no; 6725257cf54a5810105bc4a75703a06740d756d8e8landley e->right.sym = NULL; 6735257cf54a5810105bc4a75703a06740d756d8e8landley break; 6745257cf54a5810105bc4a75703a06740d756d8e8landley } 6755257cf54a5810105bc4a75703a06740d756d8e8landley if (e->right.sym == &symbol_yes) { 6765257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_SYMBOL; 6775257cf54a5810105bc4a75703a06740d756d8e8landley e->right.sym = NULL; 6785257cf54a5810105bc4a75703a06740d756d8e8landley break; 6795257cf54a5810105bc4a75703a06740d756d8e8landley } 6805257cf54a5810105bc4a75703a06740d756d8e8landley break; 6815257cf54a5810105bc4a75703a06740d756d8e8landley case E_UNEQUAL: 6825257cf54a5810105bc4a75703a06740d756d8e8landley if (e->left.sym->type != S_BOOLEAN) 6835257cf54a5810105bc4a75703a06740d756d8e8landley break; 6845257cf54a5810105bc4a75703a06740d756d8e8landley if (e->right.sym == &symbol_no) { 6855257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_SYMBOL; 6865257cf54a5810105bc4a75703a06740d756d8e8landley e->right.sym = NULL; 6875257cf54a5810105bc4a75703a06740d756d8e8landley break; 6885257cf54a5810105bc4a75703a06740d756d8e8landley } 6895257cf54a5810105bc4a75703a06740d756d8e8landley if (e->right.sym == &symbol_mod) { 6905257cf54a5810105bc4a75703a06740d756d8e8landley printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name); 6915257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_SYMBOL; 6925257cf54a5810105bc4a75703a06740d756d8e8landley e->left.sym = &symbol_yes; 6935257cf54a5810105bc4a75703a06740d756d8e8landley e->right.sym = NULL; 6945257cf54a5810105bc4a75703a06740d756d8e8landley break; 6955257cf54a5810105bc4a75703a06740d756d8e8landley } 6965257cf54a5810105bc4a75703a06740d756d8e8landley if (e->right.sym == &symbol_yes) { 6975257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_NOT; 6985257cf54a5810105bc4a75703a06740d756d8e8landley e->left.expr = expr_alloc_symbol(e->left.sym); 6995257cf54a5810105bc4a75703a06740d756d8e8landley e->right.sym = NULL; 7005257cf54a5810105bc4a75703a06740d756d8e8landley break; 7015257cf54a5810105bc4a75703a06740d756d8e8landley } 7025257cf54a5810105bc4a75703a06740d756d8e8landley break; 7035257cf54a5810105bc4a75703a06740d756d8e8landley case E_NOT: 7045257cf54a5810105bc4a75703a06740d756d8e8landley switch (e->left.expr->type) { 7055257cf54a5810105bc4a75703a06740d756d8e8landley case E_NOT: 7065257cf54a5810105bc4a75703a06740d756d8e8landley // !!a -> a 7075257cf54a5810105bc4a75703a06740d756d8e8landley tmp = e->left.expr->left.expr; 7085257cf54a5810105bc4a75703a06740d756d8e8landley free(e->left.expr); 7095257cf54a5810105bc4a75703a06740d756d8e8landley free(e); 7105257cf54a5810105bc4a75703a06740d756d8e8landley e = tmp; 7115257cf54a5810105bc4a75703a06740d756d8e8landley e = expr_transform(e); 7125257cf54a5810105bc4a75703a06740d756d8e8landley break; 7135257cf54a5810105bc4a75703a06740d756d8e8landley case E_EQUAL: 7145257cf54a5810105bc4a75703a06740d756d8e8landley case E_UNEQUAL: 7155257cf54a5810105bc4a75703a06740d756d8e8landley // !a='x' -> a!='x' 7165257cf54a5810105bc4a75703a06740d756d8e8landley tmp = e->left.expr; 7175257cf54a5810105bc4a75703a06740d756d8e8landley free(e); 7185257cf54a5810105bc4a75703a06740d756d8e8landley e = tmp; 7195257cf54a5810105bc4a75703a06740d756d8e8landley e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; 7205257cf54a5810105bc4a75703a06740d756d8e8landley break; 7215257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 7225257cf54a5810105bc4a75703a06740d756d8e8landley // !(a || b) -> !a && !b 7235257cf54a5810105bc4a75703a06740d756d8e8landley tmp = e->left.expr; 7245257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_AND; 7255257cf54a5810105bc4a75703a06740d756d8e8landley e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); 7265257cf54a5810105bc4a75703a06740d756d8e8landley tmp->type = E_NOT; 7275257cf54a5810105bc4a75703a06740d756d8e8landley tmp->right.expr = NULL; 7285257cf54a5810105bc4a75703a06740d756d8e8landley e = expr_transform(e); 7295257cf54a5810105bc4a75703a06740d756d8e8landley break; 7305257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 7315257cf54a5810105bc4a75703a06740d756d8e8landley // !(a && b) -> !a || !b 7325257cf54a5810105bc4a75703a06740d756d8e8landley tmp = e->left.expr; 7335257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_OR; 7345257cf54a5810105bc4a75703a06740d756d8e8landley e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); 7355257cf54a5810105bc4a75703a06740d756d8e8landley tmp->type = E_NOT; 7365257cf54a5810105bc4a75703a06740d756d8e8landley tmp->right.expr = NULL; 7375257cf54a5810105bc4a75703a06740d756d8e8landley e = expr_transform(e); 7385257cf54a5810105bc4a75703a06740d756d8e8landley break; 7395257cf54a5810105bc4a75703a06740d756d8e8landley case E_SYMBOL: 7405257cf54a5810105bc4a75703a06740d756d8e8landley if (e->left.expr->left.sym == &symbol_yes) { 7415257cf54a5810105bc4a75703a06740d756d8e8landley // !'y' -> 'n' 7425257cf54a5810105bc4a75703a06740d756d8e8landley tmp = e->left.expr; 7435257cf54a5810105bc4a75703a06740d756d8e8landley free(e); 7445257cf54a5810105bc4a75703a06740d756d8e8landley e = tmp; 7455257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_SYMBOL; 7465257cf54a5810105bc4a75703a06740d756d8e8landley e->left.sym = &symbol_no; 7475257cf54a5810105bc4a75703a06740d756d8e8landley break; 7485257cf54a5810105bc4a75703a06740d756d8e8landley } 7495257cf54a5810105bc4a75703a06740d756d8e8landley if (e->left.expr->left.sym == &symbol_mod) { 7505257cf54a5810105bc4a75703a06740d756d8e8landley // !'m' -> 'm' 7515257cf54a5810105bc4a75703a06740d756d8e8landley tmp = e->left.expr; 7525257cf54a5810105bc4a75703a06740d756d8e8landley free(e); 7535257cf54a5810105bc4a75703a06740d756d8e8landley e = tmp; 7545257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_SYMBOL; 7555257cf54a5810105bc4a75703a06740d756d8e8landley e->left.sym = &symbol_mod; 7565257cf54a5810105bc4a75703a06740d756d8e8landley break; 7575257cf54a5810105bc4a75703a06740d756d8e8landley } 7585257cf54a5810105bc4a75703a06740d756d8e8landley if (e->left.expr->left.sym == &symbol_no) { 7595257cf54a5810105bc4a75703a06740d756d8e8landley // !'n' -> 'y' 7605257cf54a5810105bc4a75703a06740d756d8e8landley tmp = e->left.expr; 7615257cf54a5810105bc4a75703a06740d756d8e8landley free(e); 7625257cf54a5810105bc4a75703a06740d756d8e8landley e = tmp; 7635257cf54a5810105bc4a75703a06740d756d8e8landley e->type = E_SYMBOL; 7645257cf54a5810105bc4a75703a06740d756d8e8landley e->left.sym = &symbol_yes; 7655257cf54a5810105bc4a75703a06740d756d8e8landley break; 7665257cf54a5810105bc4a75703a06740d756d8e8landley } 7675257cf54a5810105bc4a75703a06740d756d8e8landley break; 7685257cf54a5810105bc4a75703a06740d756d8e8landley default: 7695257cf54a5810105bc4a75703a06740d756d8e8landley ; 7705257cf54a5810105bc4a75703a06740d756d8e8landley } 7715257cf54a5810105bc4a75703a06740d756d8e8landley break; 7725257cf54a5810105bc4a75703a06740d756d8e8landley default: 7735257cf54a5810105bc4a75703a06740d756d8e8landley ; 7745257cf54a5810105bc4a75703a06740d756d8e8landley } 7755257cf54a5810105bc4a75703a06740d756d8e8landley return e; 7765257cf54a5810105bc4a75703a06740d756d8e8landley} 7775257cf54a5810105bc4a75703a06740d756d8e8landley 7785257cf54a5810105bc4a75703a06740d756d8e8landleyint expr_contains_symbol(struct expr *dep, struct symbol *sym) 7795257cf54a5810105bc4a75703a06740d756d8e8landley{ 7805257cf54a5810105bc4a75703a06740d756d8e8landley if (!dep) 7815257cf54a5810105bc4a75703a06740d756d8e8landley return 0; 7825257cf54a5810105bc4a75703a06740d756d8e8landley 7835257cf54a5810105bc4a75703a06740d756d8e8landley switch (dep->type) { 7845257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 7855257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 7865257cf54a5810105bc4a75703a06740d756d8e8landley return expr_contains_symbol(dep->left.expr, sym) || 7875257cf54a5810105bc4a75703a06740d756d8e8landley expr_contains_symbol(dep->right.expr, sym); 7885257cf54a5810105bc4a75703a06740d756d8e8landley case E_SYMBOL: 7895257cf54a5810105bc4a75703a06740d756d8e8landley return dep->left.sym == sym; 7905257cf54a5810105bc4a75703a06740d756d8e8landley case E_EQUAL: 7915257cf54a5810105bc4a75703a06740d756d8e8landley case E_UNEQUAL: 7925257cf54a5810105bc4a75703a06740d756d8e8landley return dep->left.sym == sym || 7935257cf54a5810105bc4a75703a06740d756d8e8landley dep->right.sym == sym; 7945257cf54a5810105bc4a75703a06740d756d8e8landley case E_NOT: 7955257cf54a5810105bc4a75703a06740d756d8e8landley return expr_contains_symbol(dep->left.expr, sym); 7965257cf54a5810105bc4a75703a06740d756d8e8landley default: 7975257cf54a5810105bc4a75703a06740d756d8e8landley ; 7985257cf54a5810105bc4a75703a06740d756d8e8landley } 7995257cf54a5810105bc4a75703a06740d756d8e8landley return 0; 8005257cf54a5810105bc4a75703a06740d756d8e8landley} 8015257cf54a5810105bc4a75703a06740d756d8e8landley 8025257cf54a5810105bc4a75703a06740d756d8e8landleybool expr_depends_symbol(struct expr *dep, struct symbol *sym) 8035257cf54a5810105bc4a75703a06740d756d8e8landley{ 8045257cf54a5810105bc4a75703a06740d756d8e8landley if (!dep) 8055257cf54a5810105bc4a75703a06740d756d8e8landley return false; 8065257cf54a5810105bc4a75703a06740d756d8e8landley 8075257cf54a5810105bc4a75703a06740d756d8e8landley switch (dep->type) { 8085257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 8095257cf54a5810105bc4a75703a06740d756d8e8landley return expr_depends_symbol(dep->left.expr, sym) || 8105257cf54a5810105bc4a75703a06740d756d8e8landley expr_depends_symbol(dep->right.expr, sym); 8115257cf54a5810105bc4a75703a06740d756d8e8landley case E_SYMBOL: 8125257cf54a5810105bc4a75703a06740d756d8e8landley return dep->left.sym == sym; 8135257cf54a5810105bc4a75703a06740d756d8e8landley case E_EQUAL: 8145257cf54a5810105bc4a75703a06740d756d8e8landley if (dep->left.sym == sym) { 8155257cf54a5810105bc4a75703a06740d756d8e8landley if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod) 8165257cf54a5810105bc4a75703a06740d756d8e8landley return true; 8175257cf54a5810105bc4a75703a06740d756d8e8landley } 8185257cf54a5810105bc4a75703a06740d756d8e8landley break; 8195257cf54a5810105bc4a75703a06740d756d8e8landley case E_UNEQUAL: 8205257cf54a5810105bc4a75703a06740d756d8e8landley if (dep->left.sym == sym) { 8215257cf54a5810105bc4a75703a06740d756d8e8landley if (dep->right.sym == &symbol_no) 8225257cf54a5810105bc4a75703a06740d756d8e8landley return true; 8235257cf54a5810105bc4a75703a06740d756d8e8landley } 8245257cf54a5810105bc4a75703a06740d756d8e8landley break; 8255257cf54a5810105bc4a75703a06740d756d8e8landley default: 8265257cf54a5810105bc4a75703a06740d756d8e8landley ; 8275257cf54a5810105bc4a75703a06740d756d8e8landley } 8285257cf54a5810105bc4a75703a06740d756d8e8landley return false; 8295257cf54a5810105bc4a75703a06740d756d8e8landley} 8305257cf54a5810105bc4a75703a06740d756d8e8landley 8315257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2) 8325257cf54a5810105bc4a75703a06740d756d8e8landley{ 8335257cf54a5810105bc4a75703a06740d756d8e8landley struct expr *tmp = NULL; 8345257cf54a5810105bc4a75703a06740d756d8e8landley expr_extract_eq(E_AND, &tmp, ep1, ep2); 8355257cf54a5810105bc4a75703a06740d756d8e8landley if (tmp) { 8365257cf54a5810105bc4a75703a06740d756d8e8landley *ep1 = expr_eliminate_yn(*ep1); 8375257cf54a5810105bc4a75703a06740d756d8e8landley *ep2 = expr_eliminate_yn(*ep2); 8385257cf54a5810105bc4a75703a06740d756d8e8landley } 8395257cf54a5810105bc4a75703a06740d756d8e8landley return tmp; 8405257cf54a5810105bc4a75703a06740d756d8e8landley} 8415257cf54a5810105bc4a75703a06740d756d8e8landley 8425257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2) 8435257cf54a5810105bc4a75703a06740d756d8e8landley{ 8445257cf54a5810105bc4a75703a06740d756d8e8landley struct expr *tmp = NULL; 8455257cf54a5810105bc4a75703a06740d756d8e8landley expr_extract_eq(E_OR, &tmp, ep1, ep2); 8465257cf54a5810105bc4a75703a06740d756d8e8landley if (tmp) { 8475257cf54a5810105bc4a75703a06740d756d8e8landley *ep1 = expr_eliminate_yn(*ep1); 8485257cf54a5810105bc4a75703a06740d756d8e8landley *ep2 = expr_eliminate_yn(*ep2); 8495257cf54a5810105bc4a75703a06740d756d8e8landley } 8505257cf54a5810105bc4a75703a06740d756d8e8landley return tmp; 8515257cf54a5810105bc4a75703a06740d756d8e8landley} 8525257cf54a5810105bc4a75703a06740d756d8e8landley 8535257cf54a5810105bc4a75703a06740d756d8e8landleyvoid expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2) 8545257cf54a5810105bc4a75703a06740d756d8e8landley{ 8555257cf54a5810105bc4a75703a06740d756d8e8landley#define e1 (*ep1) 8565257cf54a5810105bc4a75703a06740d756d8e8landley#define e2 (*ep2) 8575257cf54a5810105bc4a75703a06740d756d8e8landley if (e1->type == type) { 8585257cf54a5810105bc4a75703a06740d756d8e8landley expr_extract_eq(type, ep, &e1->left.expr, &e2); 8595257cf54a5810105bc4a75703a06740d756d8e8landley expr_extract_eq(type, ep, &e1->right.expr, &e2); 8605257cf54a5810105bc4a75703a06740d756d8e8landley return; 8615257cf54a5810105bc4a75703a06740d756d8e8landley } 8625257cf54a5810105bc4a75703a06740d756d8e8landley if (e2->type == type) { 8635257cf54a5810105bc4a75703a06740d756d8e8landley expr_extract_eq(type, ep, ep1, &e2->left.expr); 8645257cf54a5810105bc4a75703a06740d756d8e8landley expr_extract_eq(type, ep, ep1, &e2->right.expr); 8655257cf54a5810105bc4a75703a06740d756d8e8landley return; 8665257cf54a5810105bc4a75703a06740d756d8e8landley } 8675257cf54a5810105bc4a75703a06740d756d8e8landley if (expr_eq(e1, e2)) { 8685257cf54a5810105bc4a75703a06740d756d8e8landley *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1; 8695257cf54a5810105bc4a75703a06740d756d8e8landley expr_free(e2); 8705257cf54a5810105bc4a75703a06740d756d8e8landley if (type == E_AND) { 8715257cf54a5810105bc4a75703a06740d756d8e8landley e1 = expr_alloc_symbol(&symbol_yes); 8725257cf54a5810105bc4a75703a06740d756d8e8landley e2 = expr_alloc_symbol(&symbol_yes); 8735257cf54a5810105bc4a75703a06740d756d8e8landley } else if (type == E_OR) { 8745257cf54a5810105bc4a75703a06740d756d8e8landley e1 = expr_alloc_symbol(&symbol_no); 8755257cf54a5810105bc4a75703a06740d756d8e8landley e2 = expr_alloc_symbol(&symbol_no); 8765257cf54a5810105bc4a75703a06740d756d8e8landley } 8775257cf54a5810105bc4a75703a06740d756d8e8landley } 8785257cf54a5810105bc4a75703a06740d756d8e8landley#undef e1 8795257cf54a5810105bc4a75703a06740d756d8e8landley#undef e2 8805257cf54a5810105bc4a75703a06740d756d8e8landley} 8815257cf54a5810105bc4a75703a06740d756d8e8landley 8825257cf54a5810105bc4a75703a06740d756d8e8landleystruct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) 8835257cf54a5810105bc4a75703a06740d756d8e8landley{ 8845257cf54a5810105bc4a75703a06740d756d8e8landley struct expr *e1, *e2; 8855257cf54a5810105bc4a75703a06740d756d8e8landley 8865257cf54a5810105bc4a75703a06740d756d8e8landley if (!e) { 8875257cf54a5810105bc4a75703a06740d756d8e8landley e = expr_alloc_symbol(sym); 8885257cf54a5810105bc4a75703a06740d756d8e8landley if (type == E_UNEQUAL) 8895257cf54a5810105bc4a75703a06740d756d8e8landley e = expr_alloc_one(E_NOT, e); 8905257cf54a5810105bc4a75703a06740d756d8e8landley return e; 8915257cf54a5810105bc4a75703a06740d756d8e8landley } 8925257cf54a5810105bc4a75703a06740d756d8e8landley switch (e->type) { 8935257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 8945257cf54a5810105bc4a75703a06740d756d8e8landley e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); 8955257cf54a5810105bc4a75703a06740d756d8e8landley e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); 8965257cf54a5810105bc4a75703a06740d756d8e8landley if (sym == &symbol_yes) 8975257cf54a5810105bc4a75703a06740d756d8e8landley e = expr_alloc_two(E_AND, e1, e2); 8985257cf54a5810105bc4a75703a06740d756d8e8landley if (sym == &symbol_no) 8995257cf54a5810105bc4a75703a06740d756d8e8landley e = expr_alloc_two(E_OR, e1, e2); 9005257cf54a5810105bc4a75703a06740d756d8e8landley if (type == E_UNEQUAL) 9015257cf54a5810105bc4a75703a06740d756d8e8landley e = expr_alloc_one(E_NOT, e); 9025257cf54a5810105bc4a75703a06740d756d8e8landley return e; 9035257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 9045257cf54a5810105bc4a75703a06740d756d8e8landley e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); 9055257cf54a5810105bc4a75703a06740d756d8e8landley e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); 9065257cf54a5810105bc4a75703a06740d756d8e8landley if (sym == &symbol_yes) 9075257cf54a5810105bc4a75703a06740d756d8e8landley e = expr_alloc_two(E_OR, e1, e2); 9085257cf54a5810105bc4a75703a06740d756d8e8landley if (sym == &symbol_no) 9095257cf54a5810105bc4a75703a06740d756d8e8landley e = expr_alloc_two(E_AND, e1, e2); 9105257cf54a5810105bc4a75703a06740d756d8e8landley if (type == E_UNEQUAL) 9115257cf54a5810105bc4a75703a06740d756d8e8landley e = expr_alloc_one(E_NOT, e); 9125257cf54a5810105bc4a75703a06740d756d8e8landley return e; 9135257cf54a5810105bc4a75703a06740d756d8e8landley case E_NOT: 9145257cf54a5810105bc4a75703a06740d756d8e8landley return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym); 9155257cf54a5810105bc4a75703a06740d756d8e8landley case E_UNEQUAL: 9165257cf54a5810105bc4a75703a06740d756d8e8landley case E_EQUAL: 9175257cf54a5810105bc4a75703a06740d756d8e8landley if (type == E_EQUAL) { 9185257cf54a5810105bc4a75703a06740d756d8e8landley if (sym == &symbol_yes) 9195257cf54a5810105bc4a75703a06740d756d8e8landley return expr_copy(e); 9205257cf54a5810105bc4a75703a06740d756d8e8landley if (sym == &symbol_mod) 9215257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_symbol(&symbol_no); 9225257cf54a5810105bc4a75703a06740d756d8e8landley if (sym == &symbol_no) 9235257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_one(E_NOT, expr_copy(e)); 9245257cf54a5810105bc4a75703a06740d756d8e8landley } else { 9255257cf54a5810105bc4a75703a06740d756d8e8landley if (sym == &symbol_yes) 9265257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_one(E_NOT, expr_copy(e)); 9275257cf54a5810105bc4a75703a06740d756d8e8landley if (sym == &symbol_mod) 9285257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_symbol(&symbol_yes); 9295257cf54a5810105bc4a75703a06740d756d8e8landley if (sym == &symbol_no) 9305257cf54a5810105bc4a75703a06740d756d8e8landley return expr_copy(e); 9315257cf54a5810105bc4a75703a06740d756d8e8landley } 9325257cf54a5810105bc4a75703a06740d756d8e8landley break; 9335257cf54a5810105bc4a75703a06740d756d8e8landley case E_SYMBOL: 9345257cf54a5810105bc4a75703a06740d756d8e8landley return expr_alloc_comp(type, e->left.sym, sym); 9355257cf54a5810105bc4a75703a06740d756d8e8landley case E_CHOICE: 9365257cf54a5810105bc4a75703a06740d756d8e8landley case E_RANGE: 9375257cf54a5810105bc4a75703a06740d756d8e8landley case E_NONE: 9385257cf54a5810105bc4a75703a06740d756d8e8landley /* panic */; 9395257cf54a5810105bc4a75703a06740d756d8e8landley } 9405257cf54a5810105bc4a75703a06740d756d8e8landley return NULL; 9415257cf54a5810105bc4a75703a06740d756d8e8landley} 9425257cf54a5810105bc4a75703a06740d756d8e8landley 9435257cf54a5810105bc4a75703a06740d756d8e8landleytristate expr_calc_value(struct expr *e) 9445257cf54a5810105bc4a75703a06740d756d8e8landley{ 9455257cf54a5810105bc4a75703a06740d756d8e8landley tristate val1, val2; 9465257cf54a5810105bc4a75703a06740d756d8e8landley const char *str1, *str2; 9475257cf54a5810105bc4a75703a06740d756d8e8landley 9485257cf54a5810105bc4a75703a06740d756d8e8landley if (!e) 9495257cf54a5810105bc4a75703a06740d756d8e8landley return yes; 9505257cf54a5810105bc4a75703a06740d756d8e8landley 9515257cf54a5810105bc4a75703a06740d756d8e8landley switch (e->type) { 9525257cf54a5810105bc4a75703a06740d756d8e8landley case E_SYMBOL: 9535257cf54a5810105bc4a75703a06740d756d8e8landley sym_calc_value(e->left.sym); 9545257cf54a5810105bc4a75703a06740d756d8e8landley return e->left.sym->curr.tri; 9555257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 9565257cf54a5810105bc4a75703a06740d756d8e8landley val1 = expr_calc_value(e->left.expr); 9575257cf54a5810105bc4a75703a06740d756d8e8landley val2 = expr_calc_value(e->right.expr); 9585257cf54a5810105bc4a75703a06740d756d8e8landley return E_AND(val1, val2); 9595257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 9605257cf54a5810105bc4a75703a06740d756d8e8landley val1 = expr_calc_value(e->left.expr); 9615257cf54a5810105bc4a75703a06740d756d8e8landley val2 = expr_calc_value(e->right.expr); 9625257cf54a5810105bc4a75703a06740d756d8e8landley return E_OR(val1, val2); 9635257cf54a5810105bc4a75703a06740d756d8e8landley case E_NOT: 9645257cf54a5810105bc4a75703a06740d756d8e8landley val1 = expr_calc_value(e->left.expr); 9655257cf54a5810105bc4a75703a06740d756d8e8landley return E_NOT(val1); 9665257cf54a5810105bc4a75703a06740d756d8e8landley case E_EQUAL: 9675257cf54a5810105bc4a75703a06740d756d8e8landley sym_calc_value(e->left.sym); 9685257cf54a5810105bc4a75703a06740d756d8e8landley sym_calc_value(e->right.sym); 9695257cf54a5810105bc4a75703a06740d756d8e8landley str1 = sym_get_string_value(e->left.sym); 9705257cf54a5810105bc4a75703a06740d756d8e8landley str2 = sym_get_string_value(e->right.sym); 9715257cf54a5810105bc4a75703a06740d756d8e8landley return !strcmp(str1, str2) ? yes : no; 9725257cf54a5810105bc4a75703a06740d756d8e8landley case E_UNEQUAL: 9735257cf54a5810105bc4a75703a06740d756d8e8landley sym_calc_value(e->left.sym); 9745257cf54a5810105bc4a75703a06740d756d8e8landley sym_calc_value(e->right.sym); 9755257cf54a5810105bc4a75703a06740d756d8e8landley str1 = sym_get_string_value(e->left.sym); 9765257cf54a5810105bc4a75703a06740d756d8e8landley str2 = sym_get_string_value(e->right.sym); 9775257cf54a5810105bc4a75703a06740d756d8e8landley return !strcmp(str1, str2) ? no : yes; 9785257cf54a5810105bc4a75703a06740d756d8e8landley default: 9795257cf54a5810105bc4a75703a06740d756d8e8landley printf("expr_calc_value: %d?\n", e->type); 9805257cf54a5810105bc4a75703a06740d756d8e8landley return no; 9815257cf54a5810105bc4a75703a06740d756d8e8landley } 9825257cf54a5810105bc4a75703a06740d756d8e8landley} 9835257cf54a5810105bc4a75703a06740d756d8e8landley 9845257cf54a5810105bc4a75703a06740d756d8e8landleyint expr_compare_type(enum expr_type t1, enum expr_type t2) 9855257cf54a5810105bc4a75703a06740d756d8e8landley{ 9865257cf54a5810105bc4a75703a06740d756d8e8landley#if 0 9875257cf54a5810105bc4a75703a06740d756d8e8landley return 1; 9885257cf54a5810105bc4a75703a06740d756d8e8landley#else 9895257cf54a5810105bc4a75703a06740d756d8e8landley if (t1 == t2) 9905257cf54a5810105bc4a75703a06740d756d8e8landley return 0; 9915257cf54a5810105bc4a75703a06740d756d8e8landley switch (t1) { 9925257cf54a5810105bc4a75703a06740d756d8e8landley case E_EQUAL: 9935257cf54a5810105bc4a75703a06740d756d8e8landley case E_UNEQUAL: 9945257cf54a5810105bc4a75703a06740d756d8e8landley if (t2 == E_NOT) 9955257cf54a5810105bc4a75703a06740d756d8e8landley return 1; 9965257cf54a5810105bc4a75703a06740d756d8e8landley case E_NOT: 9975257cf54a5810105bc4a75703a06740d756d8e8landley if (t2 == E_AND) 9985257cf54a5810105bc4a75703a06740d756d8e8landley return 1; 9995257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 10005257cf54a5810105bc4a75703a06740d756d8e8landley if (t2 == E_OR) 10015257cf54a5810105bc4a75703a06740d756d8e8landley return 1; 10025257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 10035257cf54a5810105bc4a75703a06740d756d8e8landley if (t2 == E_CHOICE) 10045257cf54a5810105bc4a75703a06740d756d8e8landley return 1; 10055257cf54a5810105bc4a75703a06740d756d8e8landley case E_CHOICE: 10065257cf54a5810105bc4a75703a06740d756d8e8landley if (t2 == 0) 10075257cf54a5810105bc4a75703a06740d756d8e8landley return 1; 10085257cf54a5810105bc4a75703a06740d756d8e8landley default: 10095257cf54a5810105bc4a75703a06740d756d8e8landley return -1; 10105257cf54a5810105bc4a75703a06740d756d8e8landley } 10115257cf54a5810105bc4a75703a06740d756d8e8landley printf("[%dgt%d?]", t1, t2); 10125257cf54a5810105bc4a75703a06740d756d8e8landley return 0; 10135257cf54a5810105bc4a75703a06740d756d8e8landley#endif 10145257cf54a5810105bc4a75703a06740d756d8e8landley} 10155257cf54a5810105bc4a75703a06740d756d8e8landley 10165257cf54a5810105bc4a75703a06740d756d8e8landleyvoid expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken) 10175257cf54a5810105bc4a75703a06740d756d8e8landley{ 10185257cf54a5810105bc4a75703a06740d756d8e8landley if (!e) { 10195257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, NULL, "y"); 10205257cf54a5810105bc4a75703a06740d756d8e8landley return; 10215257cf54a5810105bc4a75703a06740d756d8e8landley } 10225257cf54a5810105bc4a75703a06740d756d8e8landley 10235257cf54a5810105bc4a75703a06740d756d8e8landley if (expr_compare_type(prevtoken, e->type) > 0) 10245257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, NULL, "("); 10255257cf54a5810105bc4a75703a06740d756d8e8landley switch (e->type) { 10265257cf54a5810105bc4a75703a06740d756d8e8landley case E_SYMBOL: 10275257cf54a5810105bc4a75703a06740d756d8e8landley if (e->left.sym->name) 10285257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, e->left.sym, e->left.sym->name); 10295257cf54a5810105bc4a75703a06740d756d8e8landley else 10305257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, NULL, "<choice>"); 10315257cf54a5810105bc4a75703a06740d756d8e8landley break; 10325257cf54a5810105bc4a75703a06740d756d8e8landley case E_NOT: 10335257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, NULL, "!"); 10345257cf54a5810105bc4a75703a06740d756d8e8landley expr_print(e->left.expr, fn, data, E_NOT); 10355257cf54a5810105bc4a75703a06740d756d8e8landley break; 10365257cf54a5810105bc4a75703a06740d756d8e8landley case E_EQUAL: 10375257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, e->left.sym, e->left.sym->name); 10385257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, NULL, "="); 10395257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, e->right.sym, e->right.sym->name); 10405257cf54a5810105bc4a75703a06740d756d8e8landley break; 10415257cf54a5810105bc4a75703a06740d756d8e8landley case E_UNEQUAL: 10425257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, e->left.sym, e->left.sym->name); 10435257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, NULL, "!="); 10445257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, e->right.sym, e->right.sym->name); 10455257cf54a5810105bc4a75703a06740d756d8e8landley break; 10465257cf54a5810105bc4a75703a06740d756d8e8landley case E_OR: 10475257cf54a5810105bc4a75703a06740d756d8e8landley expr_print(e->left.expr, fn, data, E_OR); 10485257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, NULL, " || "); 10495257cf54a5810105bc4a75703a06740d756d8e8landley expr_print(e->right.expr, fn, data, E_OR); 10505257cf54a5810105bc4a75703a06740d756d8e8landley break; 10515257cf54a5810105bc4a75703a06740d756d8e8landley case E_AND: 10525257cf54a5810105bc4a75703a06740d756d8e8landley expr_print(e->left.expr, fn, data, E_AND); 10535257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, NULL, " && "); 10545257cf54a5810105bc4a75703a06740d756d8e8landley expr_print(e->right.expr, fn, data, E_AND); 10555257cf54a5810105bc4a75703a06740d756d8e8landley break; 10565257cf54a5810105bc4a75703a06740d756d8e8landley case E_CHOICE: 10575257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, e->right.sym, e->right.sym->name); 10585257cf54a5810105bc4a75703a06740d756d8e8landley if (e->left.expr) { 10595257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, NULL, " ^ "); 10605257cf54a5810105bc4a75703a06740d756d8e8landley expr_print(e->left.expr, fn, data, E_CHOICE); 10615257cf54a5810105bc4a75703a06740d756d8e8landley } 10625257cf54a5810105bc4a75703a06740d756d8e8landley break; 10635257cf54a5810105bc4a75703a06740d756d8e8landley case E_RANGE: 10645257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, NULL, "["); 10655257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, e->left.sym, e->left.sym->name); 10665257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, NULL, " "); 10675257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, e->right.sym, e->right.sym->name); 10685257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, NULL, "]"); 10695257cf54a5810105bc4a75703a06740d756d8e8landley break; 10705257cf54a5810105bc4a75703a06740d756d8e8landley default: 10715257cf54a5810105bc4a75703a06740d756d8e8landley { 10725257cf54a5810105bc4a75703a06740d756d8e8landley char buf[32]; 10735257cf54a5810105bc4a75703a06740d756d8e8landley sprintf(buf, "<unknown type %d>", e->type); 10745257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, NULL, buf); 10755257cf54a5810105bc4a75703a06740d756d8e8landley break; 10765257cf54a5810105bc4a75703a06740d756d8e8landley } 10775257cf54a5810105bc4a75703a06740d756d8e8landley } 10785257cf54a5810105bc4a75703a06740d756d8e8landley if (expr_compare_type(prevtoken, e->type) > 0) 10795257cf54a5810105bc4a75703a06740d756d8e8landley fn(data, NULL, ")"); 10805257cf54a5810105bc4a75703a06740d756d8e8landley} 10815257cf54a5810105bc4a75703a06740d756d8e8landley 10825257cf54a5810105bc4a75703a06740d756d8e8landleystatic void expr_print_file_helper(void *data, struct symbol *sym, const char *str) 10835257cf54a5810105bc4a75703a06740d756d8e8landley{ 10845257cf54a5810105bc4a75703a06740d756d8e8landley fwrite(str, strlen(str), 1, data); 10855257cf54a5810105bc4a75703a06740d756d8e8landley} 10865257cf54a5810105bc4a75703a06740d756d8e8landley 10875257cf54a5810105bc4a75703a06740d756d8e8landleyvoid expr_fprint(struct expr *e, FILE *out) 10885257cf54a5810105bc4a75703a06740d756d8e8landley{ 10895257cf54a5810105bc4a75703a06740d756d8e8landley expr_print(e, expr_print_file_helper, out, E_NONE); 10905257cf54a5810105bc4a75703a06740d756d8e8landley} 10915257cf54a5810105bc4a75703a06740d756d8e8landley 10925257cf54a5810105bc4a75703a06740d756d8e8landleystatic void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) 10935257cf54a5810105bc4a75703a06740d756d8e8landley{ 10945257cf54a5810105bc4a75703a06740d756d8e8landley str_append((struct gstr*)data, str); 10955257cf54a5810105bc4a75703a06740d756d8e8landley} 10965257cf54a5810105bc4a75703a06740d756d8e8landley 10975257cf54a5810105bc4a75703a06740d756d8e8landleyvoid expr_gstr_print(struct expr *e, struct gstr *gs) 10985257cf54a5810105bc4a75703a06740d756d8e8landley{ 10995257cf54a5810105bc4a75703a06740d756d8e8landley expr_print(e, expr_print_gstr_helper, gs, E_NONE); 11005257cf54a5810105bc4a75703a06740d756d8e8landley} 1101