/* Very Simple Calculator $Id: s-calc.c,v 1.1 1996/09/22 04:43:09 kono Exp kono $ */ #include < stdio.h> char *ptr,*last_ptr; int value,lvalue; int last_token; int variable[48]; void error(char *); int expr(); int aexpr(); int mexpr(); int term(); int token(); int token() { int c,d; last_ptr = ptr; /* for error position */ c= *ptr; if(!c) { last_token = EOF; return last_token; } ptr++; if (c< =' ') { /* comment */ while(*ptr++); ptr--; last_token = EOF; last_ptr = ptr; return last_token; } if('0'< =c && c< ='9') { /* Decimal */ d = c-'0'; while(c= *ptr++) { if('0'< =c && c< ='9') { d = d*10 + (c - '0'); } else { break; } } c && ptr--; value = d; last_token = '0'; return last_token; } else if ('a'< =c && c< ='z') { /* variable */ value = c-'a'; /* return variable reference */ last_token = 'v'; return last_token; } else { last_token = c; return last_token; return c; } } int expr() { int d,assign; d = aexpr(); assign = lvalue; switch(last_token) { case '> ': d = (d > aexpr()); return d; case '=': if(assign> =0) { d = expr(); variable[assign] = d; return d; } else { error("Bad assignment"); return 0; } case ')': return d; case EOF: return d; default: error("Bad expression"); return d; } } int aexpr() { int d; d = mexpr(); switch(last_token) { case '-': d -= aexpr(); return d; case '+': d += aexpr(); return d; default: return d; } } int mexpr() { int d; d = term(); switch(last_token) { case '*': d *= mexpr(); return d; case '/': d /= mexpr(); return d; default: return d; } } int term() { int d; lvalue= -1; token(); if(last_token==EOF) { error("Term expected"); } switch(last_token) { case '0': d = value; token(); return d; case 'v': d = lvalue = value; token(); return variable[d]; case '(': d = expr(); if(last_token != ')') { error("Unbalanced parenthsis"); } token(); return d; default: token(); error("Unknown term"); return 0; } } int main() { int d; char buf[BUFSIZ]; while (fgets(buf,BUFSIZ,stdin)) { ptr = buf; d = expr(); printf("%s = 0x%08x = %d\n",buf,d,d); fflush(stdout); } return 0; } void error(s) char *s; { fprintf(stderr,"%s on %s\n",s,last_ptr); } /* end */