/* evalf2.c (yukino.c) - Don Yang (uguu.org) Preprocess step 2: evaluate constants. 11/05/99 */ #include #include #include #define isdigit0(x) (((x) >= '0' && (x) <= '9') || (x) == '.') char *label[19] = { "-", "+", "%", "/", "*", "-", "exp", "ln", "log", "atan", "acos", "asin", "tan", "cos", "sin", "^", "(", "e", "PI"}; char expression[2048 + 1]; int expindex, lasttoken, lastop, nestlevel; double operand[2048], lit; int operator[2048]; int left[2048], right[2048], parent[2048]; int newnode, cursor; int i; double evaluate(int node) { switch( operator[node] ) { case 294: return atan2(0, -1); case 278: return exp(1); case 262: return evaluate(right[node]); case 245: return pow(evaluate(left[node]), evaluate(right[node])); case 228: return sin(evaluate(right[node])); case 212: return cos(evaluate(right[node])); case 196: return tan(evaluate(right[node])); case 180: return asin(evaluate(right[node])); case 164: return acos(evaluate(right[node])); case 148: return atan(evaluate(right[node])); case 132: return log10(evaluate(right[node])); case 116: return log(evaluate(right[node])); case 100: return exp(evaluate(right[node])); case 83: return -evaluate(right[node]); case 66: return evaluate(left[node]) * evaluate(right[node]); case 50: return evaluate(left[node]) / evaluate(right[node]); case 34: return fmod(evaluate(left[node]), evaluate(right[node])); case 17: return evaluate(left[node]) + evaluate(right[node]); case 1: return evaluate(left[node]) - evaluate(right[node]); default: return operand[node]; } } void insertbop(int op) { printf("%s ", label[op >> 4]); for(; operator[parent[cursor]] != 262 && (operator[parent[cursor]] & 7) >= (op & 7); cursor = parent[cursor]); operator[newnode] = op; left[newnode] = cursor; parent[newnode] = parent[cursor]; parent[cursor] = newnode; right[parent[newnode]] = newnode; cursor = newnode; newnode++; lasttoken = 0; lastop = 0; } void insertuop(int op) { if( lasttoken == 1 ) insertbop(66); if( op == 310 ) { printf("%lG ", lit); lasttoken = 1; } else if( op == 294 || op == 278 ) { printf("%s ", label[op >> 4]); lasttoken = 1; } else { if( op == 262 ) { nestlevel++; if( lastop ) putchar(8); } printf("%s", label[op >> 4]); lasttoken = 0; } lastop = 0; if( op >= 100 && op <= 228 ) { putchar(32); lastop = 1; } operator[newnode] = op; operand[newnode] = lit; parent[newnode] = cursor; right[cursor] = newnode; cursor = newnode; newnode++; } int main(int argc, char *argv[]) { if( argc == 1 ) { puts("?"); return 0; } expindex = 0; strcpy(expression, argv[1]); for(i = 2; i < argc; i++) strcat(expression, argv[i]); strlwr(expression); operator[cursor = 0] = 262; newnode = 1; for(expindex = lasttoken = nestlevel = 0; expression[expindex];) { if( isdigit0(expression[expindex]) ) { sscanf(expression + expindex, "%lf", &lit); insertuop(310); for(; isdigit0(expression[expindex]); expindex++); if( expression[expindex] == 101 ) { if( expression[expindex + 1] == 43 || expression[expindex + 1] == 45 ) expindex++; for(expindex++; expression[expindex] >= 48 && expression[expindex] <= 57; expindex++); } } else if( expression[expindex] > 97 && expression[expindex] <= 116 ) { if( !memcmp(expression + expindex, label[14], 3) ) insertuop(228); else if( !memcmp(expression + expindex, label[13], 3) ) insertuop(212); else if( !memcmp(expression + expindex, label[12], 3) ) insertuop(196); else if( !memcmp(expression + expindex, label[6], 3) ) insertuop(100); else if( !memcmp(expression + expindex, label[8], 3) ) insertuop(132); else { if( !memcmp(expression + expindex, "pi", 2) ) insertuop(294); else if( !memcmp(expression + expindex, "ln", 2) ) insertuop(116); else { if( expression[expindex] == 101 ) insertuop(278); expindex--; } expindex--; } expindex += 3; } else if( expression[expindex] == 97 ) { if( !memcmp(expression + expindex + 1, label[14], 3) ) insertuop(180); else if( !memcmp(expression + expindex + 1, label[13], 3) ) insertuop(164); else if( !memcmp(expression + expindex + 1, label[12], 3) ) insertuop(148); else expindex -= 3; expindex += 4; } else { i = expression[expindex++]; if( lasttoken == 1 ) { if( i == 40 ) { insertuop(262); } else if( i == 41 && nestlevel ) { printf("\b) "); for(cursor = parent[cursor]; operator[cursor] != 262; cursor = parent[cursor]); nestlevel--; } else { if( i == 42 ) insertbop(66); else if( i == 47 ) insertbop(50); else if( i == 37 ) insertbop(34); else if( i == 43 ) insertbop(17); else if( i == 45 ) insertbop(1); else if( i == 94 ) insertbop(245); } } else { if( i == 40 ) insertuop(262); else if( i == 45 ) insertuop(83); } } } if( lasttoken == 0 ) { lit = 0; insertuop(310); } for(i = !putchar(8); i < nestlevel; i++) putchar(41); putchar(10); printf("\n= %.16lG\n", evaluate(0)); return 0; }