#include #include "basic.h" void level2(int*), level3(int*), level4(int*), level5(int*), level6(int*), primitive(int*); void unary(char, int*), arith(char, int*, int*); /* Entry point into parser. */ void get_exp(int *result) { get_token(); if(!*token) { serror(2); return; } level2(result); putback(); /* return last token read to input stream */ } /* Add or subtract two terms. */ void level2(int *result) { register char op; int hold; level3(result); while((op = *token) == '+' || op == '-') { get_token(); level3(&hold); arith(op, result, &hold); } } /* Multiply or divide two factors. */ void level3(int *result) { register char op; int hold; level4(result); while((op = *token) == '*' || op == '/' || op == '%') { get_token(); level4(&hold); arith(op, result, &hold); } } /* Process integer exponent. */ void level4(int *result) { int hold; level5(result); if(*token== '^') { get_token(); level4(&hold); arith('^', result, &hold); } } /* Is a unary + or -. */ void level5(int *result) { register char op; op = 0; if((token_type==DELIMITER) && (*token=='+' || *token=='-')) { op = *token; get_token(); } level6(result); if(op) unary(op, result); } /* Process parenthesized expression. */ void level6(int *result) { if((*token == '(') && (token_type == DELIMITER)) { get_token(); level2(result); if(*token != ')') serror(1); get_token(); } else primitive(result); } /* Find value of number or variable. */ void primitive(int *result) { switch(token_type) { case VARIABLE: *result = *find_var(token); get_token(); return; case NUMBER: *result = atoi(token); get_token(); return; case COMMAND: switch(tok) { case RND: *result = rand(); get_token(); return; } default: serror(0); } } /* Perform the specified arithmetic. */ void arith(char o, int *r, int *h) { register int t, ex; switch(o) { case '-': *r = *r-*h; break; case '+': *r = *r+*h; break; case '*': *r = *r * *h; break; case '/': *r = (*r)/(*h); break; case '%': t = (*r)/(*h); *r = *r-(t*(*h)); break; case '^': ex = *r; if(*h==0) { *r = 1; break; } for(t=*h-1; t>0; --t) *r = (*r) * ex; break; } } /* Reverse the sign. */ void unary(char o, int *r) { if(o=='-') *r = -(*r); }