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