Blob


1 /*
2 * Exercise 4-4. Add commands to print the top element of the stack without
3 * popping, to duplicate it, and to swap the top two elements. Add a command to
4 * clear the stack.
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);
16 double printtop(void);
17 int duplicate(void);
18 int swap(void);
19 void clear(void);
21 /* reverse Polish calculator */
22 int main() {
23 int type;
24 double op2;
25 char s[MAXOP];
27 while ((type = getop(s)) != EOF) {
28 switch (type) {
29 case NUMBER:
30 push(atof(s));
31 break;
32 case '+':
33 push(pop() + pop());
34 break;
35 case '*':
36 push(pop() * pop());
37 break;
38 case '-':
39 op2 = pop();
40 push(pop() - op2);
41 break;
42 case '/':
43 op2 = pop();
44 if (op2 != 0.0)
45 push(pop() / op2);
46 else
47 printf("error: zero divisor\n");
48 break;
49 case '%':
50 op2 = pop();
51 if (op2 != 0.0)
52 push((int) pop() % (int) op2);
53 else
54 printf("error: zero divisor\n");
55 break;
56 case '?':
57 printf("\t%.8g\n", printtop());
58 break;
59 case '#':
60 if (duplicate() == 0)
61 printf("error: can't duplicate\n");
62 break;
63 case '~':
64 if (swap() == 0)
65 printf("error: swap failed, stack needs two numbers\n");
66 break;
67 case '!':
68 clear();
69 break;
70 case '\n':
71 printf("\t%.8g\n", pop());
72 break;
73 default:
74 printf("error: unknown command %s\n", s);
75 break;
76 }
77 }
78 }
80 #define MAXVAL 100 /* maximum depth of val stack */
82 int sp = 0; /* next free stack position */
83 double val[MAXVAL]; /* value stack */
85 /* push: push f onto value stack */
86 void push (double f) {
87 if (sp < MAXVAL)
88 val[sp++] = f;
89 else
90 printf ("error: stack full, can't push %g\n", f);
91 }
93 /* pop: pop and return top value from stack */
94 double pop(void) {
95 if (sp > 0)
96 return val[--sp];
97 else {
98 printf("error: stack empty\n");
99 return 0.0;
103 /* printtop: print the top value of the stack without popping it */
104 double printtop(void) {
105 if (sp > 0)
106 return val[sp-1];
107 else {
108 printf("error: stack empty\n");
109 return 0.0;
113 /* duplicate: duplicate the top value of the stack
114 * return 1 if successful, 0 on failure */
115 int duplicate(void) {
116 if (sp <= 0) {
117 return 0;
118 } else if (sp >= MAXVAL) {
119 return 0;
120 } else {
121 val[sp] = val[sp-1];
122 sp++;
123 return 1;
127 /* swap: swap the top two values of the stack
128 * return 1 if successful, 0 on failure */
129 int swap(void) {
130 if (sp > 1) {
131 int temp = val[sp-1];
132 val[sp-1] = val[sp-2];
133 val[sp-2] = temp;
134 return 1;
136 return 0;
139 /* clear: clear the stack */
140 void clear(void) {
141 sp = 0;
144 #include <ctype.h>
146 int getch(void);
147 void ungetch(int);
149 /* getop: get next operator or numeric operand */
150 int getop(char s[]) {
151 int i, c;
152 while ((s[0] = c = getch()) == ' ' || c == '\t')
154 s[1] = '\0';
155 i = 0;
156 /* negative number or minus */
157 if (c == '-') {
158 s[++i] = c = getch();
159 if (!isdigit(c) && c != '.') {
160 ungetch(c);
161 return '-';
164 if (!isdigit(c) && c != '.')
165 return c; /* not a number */
166 if (isdigit(c)) /* collect integer part */
167 while (isdigit(s[++i] = c = getch()))
169 if (c == '.') /* collect fraction part */
170 while (isdigit(s[++i] = c = getch()))
172 s[i] = '\0';
173 if (c != EOF)
174 ungetch(c);
175 return NUMBER;
178 #define BUFSIZE 100
180 char buf[BUFSIZE]; /* buffer for ungetch */
181 int bufp = 0;
183 /* get a (possibly pushed back) character */
184 int getch(void) {
185 return (bufp > 0) ? buf[--bufp] : getchar();
188 /* push character back on input */
189 void ungetch(int c) {
190 if (bufp >= BUFSIZE)
191 printf("ungetch: too many characters\n");
192 else
193 buf[bufp++] = c;