From b782b3f9b677d2fcfdbf79a30b3fd4e8a0002aec Mon Sep 17 00:00:00 2001 From: Martin Ashby Date: Sat, 11 Feb 2023 17:35:26 +0000 Subject: Exercise 5.10 --- ex5-10.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 ex5-10.c (limited to 'ex5-10.c') diff --git a/ex5-10.c b/ex5-10.c new file mode 100644 index 0000000..c4afccd --- /dev/null +++ b/ex5-10.c @@ -0,0 +1,113 @@ +#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; +} -- cgit v1.2.3-ZIG