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