An implementation of post operational calculator. Put a string s into function getop, which in turn gets characters from stdin by a buffered version of getc: getch and ungetch. The operators of this calculator are assumed to be a single non-digit and non-dot character. If getop gets such an operator, it returns its code number. If getop gets an operand (a number), it returns a special code NUMBER, and the string s contains the digits. The operands are stored in a stack of double type. Then the operations are implemented case by case.
Operator Action
+ x y + = x + y
- x y - = x - y
* x y * = x * y
/ x y / = x divided by y
^ x y ^ = x raised to the power of y
e x e = exponential raised to the power of x
l x l = natural logrithm of x
q x q = square root of x
p the constant pi
i x i = x rounded to an integer
r x r = 1 x / = reciprocal of x
s x s = sin(x)
c x c = cos(x)
t x t = tan(x)
j cyclicly downs the stack by one element
k cyclicly ups the stack by one element
w shows the stack from top to bottom
x exchanges the top most two elements in the stack
? shows a brief help message

```#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "stack.h"
#include "getch.h"

#define MAXNUM 100
#define NUMBER '\007'
int getop(char []);

main () {
int type, flag_dup = 1;
double op2;
char s[MAXNUM];

while ((type = getop(s)) != EOF) {
switch (type) {
case NUMBER:
push(atof(s));
break;
case '+':
push(pop() + pop());
break;
case '-':
op2 = pop();
push(pop() - op2);
break;
case '*':
push(pop() * pop());
break;
case '/':
if ((op2 = pop()) != 0)
push(pop() / op2);
break;
case '^':
op2 = pop();
push(pow(pop(), op2));
break;
case 'e':
push(exp(pop()));
break;
case 'l':
push(log(pop()));
break;
case 'q':
push(sqrt(pop()));
break;
case 'p':
push(4 * atan(1.));
break;
case 'i':
push(floor(pop() + 0.5));
break;
case 'r':
push(1. / pop());
break;
case 's':
push(sin(pop()));
break;
case 'c':
push(cos(pop()));
break;
case 't':
push(tan(pop()));
break;
case 'n':
push(-1. * pop());
break;
case '\n':
if (flag_dup == 0)
flag_dup = 1;
else
printf("%.8g\n", dup());
break;
case 'j':
flag_dup = 0;
down();
break;
case 'k':
flag_dup = 0;
up();
break;
case 'w':
flag_dup = 0;
list();
break;
case 'x':
flag_dup = 0;
swaptop();
break;
case '?':
flag_dup = 0;
printf("\tc: cos(x)\n");
printf("\te: exp(x)\n");
printf("\ti: round x to integer\n");
printf("\tl: ln(x)\n");
printf("\tn: -x\n");
printf("\tp: pi\n");
printf("\tq: sqrt(x)\n");
printf("\tr: 1/x\n");
printf("\ts: sin(x)\n");
printf("\tt: tan(x)\n");
printf("\tw: who, list numbers on stack\n");
printf("\tj: downward rotate the stack\n");
printf("\tk: upward rotate the stack\n");
printf("\tx: swap the top two elements on stack\n");
break;
default:
fprintf(stderr, "ERROR: unknown command %s\n", s);
break;
}
}
return 0;
}
```

Created: Nov 26, 1994
Last Revised: Dec 6, 1994