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
© Copyright 1994 Wei-Chang Shann

shann@math.ncu.edu.tw