#include #include #include #include #define NUMBER '0' #define MAXLINE 1000 #define MAXVAL 100 int getop(char[]); void push(double); double pop(void); void clear(void); double peek(void); // Naïve implementation of remainder operation double frem(double f1, double f2) { return f1 - (f2 * (int)(f1 / f2)); } /** * Reverse polish notation calculator */ int main(int argc, char* argv[]) { if (argc <= 1) { fprintf(stderr, "Usage: rpol EXPR..."); return 1; } argv++; // Skip program name double op2; for (; *argv != NULL; argv++) { char* tok = *argv; int type = getop(tok); switch (type) { case NUMBER: push(atof(tok)); break; case '+': push(pop() + pop()); break; case '*': push(pop() * pop()); break; case '-': op2 = pop(); push(pop() - op2); break; case '/': op2 = pop(); if (op2 != 0.0) push(pop() / op2); else printf("error: zero division attempted!\n"); break; case '%': op2 = pop(); if (op2 != 0.0) push(frem(pop(), op2)); else printf("error: zero division attempted!\n"); break; case '~': clear(); break; default: printf("unknown command %s\n", tok); // Just ignore it? break; } } printf("\t%.8g\n", pop()); return 0; } int sp; // Stack position double val[MAXVAL]; // Value stack void push(double f) { if (sp < MAXVAL) { val[sp++] = f; } else { printf("error, stack full\n"); } } double pop(void) { if (sp >= 0) { return val[--sp]; } else { printf("error, empty stack\n"); return 0.0; } } double peek(void) { if (sp >= 0) { return val[sp-1]; } else { printf("error, empty stack\n"); return 0.0; } } void clear(void) { sp = 0; } int getop(char s[]) { char c = s[0]; if (!isdigit(c) && c != '.') return c; return NUMBER; }