Blob


1 /*
2 * Exercise 4-5. Add access to library functions like sin, exp, and pow. See
3 * <math.h> in Appendix B, Section 4.
4 */
6 #include <stdio.h>
7 #include <stdlib.h> /* for atof() */
8 #include <math.h>
9 #include <string.h>
11 #define MAXOP 100 /* max size of operand or operator */
12 #define NUMBER '0' /* signal that a number was found */
13 #define IDENTIFIER '1' /* signal that an identifier was found */
15 int getop(char []);
16 void push(double);
17 double pop(void);
18 double printtop(void);
19 int duplicate(void);
20 int swap(void);
21 void clear(void);
23 /* reverse Polish calculator */
24 int main() {
25 int type;
26 double op2;
27 char s[MAXOP];
28 while ((type = getop(s)) != EOF) {
29 switch (type) {
30 case NUMBER:
31 push(atof(s));
32 break;
33 case IDENTIFIER:
34 if (strcmp(s, "sin") == 0)
35 push(sin(pop()));
36 else if (strcmp(s, "cos") == 0)
37 push(cos(pop()));
38 else if (strcmp(s, "exp") == 0)
39 push(exp(pop()));
40 break;
41 case '+':
42 push(pop() + pop());
43 break;
44 case '*':
45 push(pop() * pop());
46 break;
47 case '-':
48 op2 = pop();
49 push(pop() - op2);
50 break;
51 case '/':
52 op2 = pop();
53 if (op2 != 0.0)
54 push(pop() / op2);
55 else
56 printf("error: zero divisor\n");
57 break;
58 case '%':
59 op2 = pop();
60 if (op2 != 0.0)
61 push((int) pop() % (int) op2);
62 else
63 printf("error: zero divisor\n");
64 break;
65 case '?':
66 printf("\t%.8g\n", printtop());
67 break;
68 case '#':
69 if (duplicate() == 0)
70 printf("error: can't duplicate\n");
71 break;
72 case '~':
73 if (swap() == 0)
74 printf("error: swap failed, stack needs two numbers\n");
75 break;
76 case '!':
77 clear();
78 break;
79 case '\n':
80 printf("\t%.8g\n", pop());
81 break;
82 default:
83 printf("error: unknown command %s\n", s);
84 break;
85 }
86 }
87 }
89 #define MAXVAL 100 /* maximum depth of val stack */
91 int sp = 0; /* next free stack position */
92 double val[MAXVAL]; /* value stack */
94 /* push: push f onto value stack */
95 void push (double f) {
96 if (sp < MAXVAL)
97 val[sp++] = f;
98 else
99 printf ("error: stack full, can't push %g\n", f);
102 /* pop: pop and return top value from stack */
103 double pop(void) {
104 if (sp > 0)
105 return val[--sp];
106 else {
107 printf("error: stack empty\n");
108 return 0.0;
112 /* printtop: print the top value of the stack without popping it */
113 double printtop(void) {
114 if (sp > 0)
115 return val[sp-1];
116 else {
117 printf("error: stack empty\n");
118 return 0.0;
122 /* duplicate: duplicate the top value of the stack
123 * return 1 if successful, 0 on failure */
124 int duplicate(void) {
125 if (sp <= 0) {
126 return 0;
127 } else if (sp >= MAXVAL) {
128 return 0;
129 } else {
130 val[sp] = val[sp-1];
131 sp++;
132 return 1;
136 /* swap: swap the top two values of the stack
137 * return 1 if successful, 0 on failure */
138 int swap(void) {
139 if (sp > 1) {
140 int temp = val[sp-1];
141 val[sp-1] = val[sp-2];
142 val[sp-2] = temp;
143 return 1;
145 return 0;
148 /* clear: clear the stack */
149 void clear(void) {
150 sp = 0;
153 #include <ctype.h>
155 int getch(void);
156 void ungetch(int);
158 /* getop: get next operator or numeric operand */
159 int getop(char s[]) {
160 int i, c;
161 while ((s[0] = c = getch()) == ' ' || c == '\t')
163 s[1] = '\0';
164 i = 0;
165 if (isalpha(c)) {
166 while (isalpha(s[++i] = c = getch()))
168 s[i] = '\0';
169 if (c != EOF)
170 ungetch(c);
171 return IDENTIFIER;
173 /* negative number or minus */
174 if (c == '-') {
175 s[++i] = c = getch();
176 if (!isdigit(c) && c != '.') {
177 ungetch(c);
178 return '-';
181 if (!isdigit(c) && c != '.')
182 return c; /* not a number */
183 if (isdigit(c)) /* collect integer part */
184 while (isdigit(s[++i] = c = getch()))
186 if (c == '.') /* collect fraction part */
187 while (isdigit(s[++i] = c = getch()))
189 s[i] = '\0';
190 if (c != EOF)
191 ungetch(c);
192 return NUMBER;
195 #define BUFSIZE 100
197 char buf[BUFSIZE]; /* buffer for ungetch */
198 int bufp = 0;
200 /* get a (possibly pushed back) character */
201 int getch(void) {
202 return (bufp > 0) ? buf[--bufp] : getchar();
205 /* push character back on input */
206 void ungetch(int c) {
207 if (bufp >= BUFSIZE)
208 printf("ungetch: too many characters\n");
209 else
210 buf[bufp++] = c;
213 /*
214 void printstack(void);
215 printstack();
216 void printstack(void) {
217 for (int i = 0; i < sp; i++)
218 printf("%g ", val[i]);
219 printf("\n");
221 */