/* eval3.c (comment9.c) - Don Yang (uguu.org) Preprocess step 3: evaluate constants 10/21/99 */ #include long operand[1024], lit; char expression[1025], *errtext = "\nbaka."; int expindex, lasttoken, nestlevel, operator[1024], left[1024], right[1024], parent[1024], newnode, cursor, i; long evaluate(int node) { long tmp; switch( operator[node] ) { case 183: return evaluate(right[node]); case 166: return -evaluate(right[node]); case 150: return ~evaluate(right[node]); case 133: return evaluate(left[node]) * evaluate(right[node]); case 117: if( (tmp = evaluate(right[node])) == 0 ) return puts(errtext); return evaluate(left[node]) / tmp; case 101: if( (tmp = evaluate(right[node])) == 0 ) return puts(errtext); return evaluate(left[node]) % tmp; case 84: return evaluate(left[node]) + evaluate(right[node]); case 68: return evaluate(left[node]) - evaluate(right[node]); case 51: return evaluate(left[node]) & evaluate(right[node]); case 34: return evaluate(left[node]) ^ evaluate(right[node]); case 17: return evaluate(left[node]) | evaluate(right[node]); default: return operand[node]; } } void insertbop(int op) { for(printf("%c ", i); operator[parent[cursor]] - 183 && (operator[parent[cursor]] & 7) >= (op & 7); cursor = parent[cursor]); operator[newnode] = op; parent[newnode] = parent[left[newnode] = cursor]; right[parent[parent[cursor] = newnode]] = newnode; cursor = newnode++; lasttoken = 0; } void insertuop(int op) { if( op == 199 ) { printf("%ld ", lit); lasttoken = 1; } else { putchar(i); lasttoken = 0; if( op == 183 ) nestlevel++; } operator[newnode] = op; operand[newnode] = lit; right[parent[newnode] = cursor] = newnode; cursor = newnode++; } int main(int argc, char *argv[]) { if( argc == 1 ) return puts(errtext); expindex = 0; for(cursor = newnode = 1; cursor < argc; cursor++) for(i = 0; argv[cursor][i];) expression[expindex++] = argv[cursor][i++]; for(operator[expindex = lasttoken = nestlevel = cursor = expression[expindex] = 0] = 183; expression[expindex];) if( expression[expindex] >= '0' && expression[expindex] <= '9' ) { if( expression[expindex + 1] == 'x' ) sscanf(expression + (expindex += 2), "%lx", &lit); else sscanf(expression + expindex, "%ld", &lit); if( lasttoken ) { i = '*'; insertbop(133); } for(insertuop(199); (expression[expindex] >= '0' && expression[expindex] <= '9') || (expression[expindex] >= 'a' && expression[expindex] <= 'f'); expindex++); } else { i = expression[expindex++]; if( lasttoken ) { if( i == '(' ) { i = '*'; insertbop(133); i = '('; insertuop(183); } else if( i == ')' && nestlevel ) { printf("\b) "); for(cursor = parent[cursor]; operator[cursor] - 183; cursor = parent[cursor]); nestlevel--; } else { if( i == '*' ) insertbop(133); else if( i == '/' ) insertbop(117); else if( i == '%' ) insertbop(101); else if( i == '+' ) insertbop(84); else if( i == '-' ) insertbop(68); else if( i == '&' ) insertbop(51); else if( i == '^' ) insertbop(34); else if( i == '|' ) insertbop(17); } } else { if( i == '(' ) insertuop(183); else if( i == '-' ) insertuop(166); else if( i == '~' ) insertuop(150); } } if( !lasttoken ) { lit = 0; insertuop(199); } for(i = !putchar('\b'); i++ < nestlevel; putchar(')')); lit = evaluate(0); return printf("\n= %ld (0x%lx)\n", lit, lit); }