Blob


1 /*
2 * Exercise 4-3. Given the basic framework, it's straightforward to extend the
3 * calculator. Add the modulus (%) operator and provisions for negative
4 * numbers.
5 */
7 #include <stdio.h>
8 #include <stdlib.h> /* for atof() */
10 #define MAXOP 100 /* max size of operand or operator */
11 #define NUMBER '0' /* signal that a number was found */
13 int getop(char []);
14 void push(double);
15 double pop(void);
17 /* reverse Polish calculator */
18 int main() {
19 int type;
20 double op2;
21 char s[MAXOP];
23 while ((type = getop(s)) != EOF) {
24 switch (type) {
25 case NUMBER:
26 push(atof(s));
27 break;
28 case '+':
29 push(pop() + pop());
30 break;
31 case '*':
32 push(pop() * pop());
33 break;
34 case '-':
35 op2 = pop();
36 push(pop() - op2);
37 break;
38 case '/':
39 op2 = pop();
40 if (op2 != 0.0)
41 push(pop() / op2);
42 else
43 printf("error: zero divisor\n");
44 break;
45 case '%':
46 op2 = pop();
47 if (op2 != 0.0)
48 push((int) pop() % (int) op2);
49 else
50 printf("error: zero divisor\n");
51 break;
52 case '\n':
53 printf("\t%.8g\n", pop());
54 break;
55 default:
56 printf("error: unknown command %s\n", s);
57 break;
58 }
59 }
60 }
62 #define MAXVAL 100 /* maximum depth of val stack */
64 int sp = 0; /* next free stack position */
65 double val[MAXVAL]; /* value stack */
67 /* push: push f onto value stack */
68 void push (double f) {
69 if (sp < MAXVAL)
70 val[sp++] = f;
71 else
72 printf ("error: stack full, can't push %g\n", f);
73 }
75 /* pop: pop and return top value from stack */
76 double pop(void) {
77 if (sp > 0)
78 return val[--sp];
79 else {
80 printf("error: stack empty\n");
81 return 0.0;
82 }
83 }
85 #include <ctype.h>
87 int getch(void);
88 void ungetch(int);
90 /* getop: get next operator or numeric operand */
91 int getop(char s[]) {
92 int i, c;
93 while ((s[0] = c = getch()) == ' ' || c == '\t')
94 ;
95 s[1] = '\0';
96 i = 0;
97 /* negative number or minus */
98 if (c == '-') {
99 s[++i] = c = getch();
100 if (!isdigit(c) && c != '.') {
101 ungetch(c);
102 return '-';
105 if (!isdigit(c) && c != '.')
106 return c; /* not a number */
107 if (isdigit(c)) /* collect integer part */
108 while (isdigit(s[++i] = c = getch()))
110 if (c == '.') /* collect fraction part */
111 while (isdigit(s[++i] = c = getch()))
113 s[i] = '\0';
114 if (c != EOF)
115 ungetch(c);
116 return NUMBER;
119 #define BUFSIZE 100
121 char buf[BUFSIZE]; /* buffer for ungetch */
122 int bufp = 0;
124 /* get a (possibly pushed back) character */
125 int getch(void) {
126 return (bufp > 0) ? buf[--bufp] : getchar();
129 /* push character back on input */
130 void ungetch(int c) {
131 if (bufp >= BUFSIZE)
132 printf("ungetch: too many characters\n");
133 else
134 buf[bufp++] = c;