#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(void) { double op2; char* line = NULL; size_t line_len = 0; while (getline(&line, &line_len, stdin) != -1) { char* tok = strtok(line, " "); do { 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; } } while ((tok = strtok(NULL, " ")) != NULL); printf("\t%.8g\n", pop()); } free(line); // or, don't bother since we exit the program next... 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; }