#include #include #include #define MAXOP 100 #define NUMBER '0' #define MAXVAL 100 #define BUFSIZE 100 #define MAXLINE 1000 int getop(char []); int getsop(char [], char []); void push(double); double pop(void); int getch(void); void ungetch(int); int getline(char *, int); int sp = 0; double val[MAXVAL]; int buf[BUFSIZE]; int bufp = 0; double p; float vars[26]; int main(void) { int type; double op2; char s[MAXOP]; char line[MAXLINE] = "\0"; while ((type = getsop(s, line)) != EOF) { switch (type) { case NUMBER: push(atof(s)); break; case '+': push(pop() + pop()); break; case '-': push(pop() - pop()); break; case '*': push(pop() * pop()); break; case '/': op2 = pop(); if (op2 != 0.0) push(pop() / op2); else printf("error: zero divisor\n"); break; case '%': op2 = pop(); if (op2 != 0.0) push(fmod(pop(), op2)); else printf("error zero divisor\n"); break; case 'd': push(p); break; case 'a': pop(); op2 = pop(); push(p); push(op2); break; case 'p': printf("\t%.8g\n", p); break; case 's': push(sin(pop())); break; case 'e': push(exp(pop())); break; case 'w': push(pow(pop(), pop())); break; case 'c': sp = 0; break; case 'r': push(p); break; case '=': if (isalpha((int) (op2 = pop()))) { vars[(int) op2] = pop(); } break; case '\n': printf("\t%.8g\n", pop()); break; default: if (isalpha(type)) { if (vars[type] != 0) { push(vars[type]); } else { push(type); } break; } printf("error: unknown command %s\n", s); printf("type: %d\n", type); break; } } return 0; } void push(double f) { if (sp < MAXVAL) { val[sp++] = f; p = f; } else printf("error: stack full, can't push %g\n", f); } double pop(void) { if (sp > 0) return val[--sp]; else { printf("error: stack empty\n"); return 0.0; } } int getop(char s[]) { int i, c, sign = 1; while ((s[0] = c = getch()) == ' '|| c == '\t'); s[1] = '\0'; if (!isdigit(c) && c != '.' && c != '-') return c; if (c == '-') { if (isdigit(c=getch())) sign = -1; else { ungetch(c); return '-'; } } i = 0; if (sign < 0) s[++i] = c; if (isdigit(c)) while (isdigit(s[++i] = c = getch())); if (c == '.') while (isdigit(s[++i] = c = getch())); s[i] = '\0'; if (c != EOF) ungetch(c); return NUMBER; } int getch(void) { return (bufp > 0) ? buf[--bufp] : getchar(); } void ungetch(int c) { if (bufp >= BUFSIZE) printf("ungetch: too many characters\n"); else buf[bufp++] = c; } void ungets(char s[]) { int i; for (i = 0; s[i] != '\0'; i++) ungetch(s[i]); } int buffer = (int) NULL; int getch1(void) { int c; if (buffer == (int) NULL) return getchar(); else { c = buffer; buffer = (int) NULL; return c; } } void ungetch1(int c) { if (buffer == (int) NULL) buffer = c; else printf("AIEEEE!\n"); } int getsop(char s[], char t[]) { int i, c, sign = 1; static int j; if (t[j] == '\0') { getline(t, MAXLINE); j = 0; } while ((s[0] = c = t[j++]) == ' '|| c == '\t'); s[1] = '\0'; if (!isdigit(c) && c != '.' && c != '-') return c; if (c == '-') { if (isdigit(c=t[j++])) sign = -1; else { j--; return '-'; } } i = 0; if (sign < 0) s[++i] = c; if (isdigit(c)) while (isdigit(s[++i] = c = t[j++])); if (c == '.') while (isdigit(s[++i] = c = t[j++])); s[i] = '\0'; if (c != EOF) j--; return NUMBER; } int getline(char *s, int len) { char c; int i; for (i = 0; i < len-1 && (c = getchar()) != EOF && c != '\n'; i++) s[i] = c; if (c == EOF) s[i++] = c; else if (c == '\n') s[i++] = '\n'; s[i++] = '\0'; return i; } /* getline() */ int shitop(char s[]) { int i, c, sign = 1; int last = 0; if (last == 0) { c = getch(); } else { c = last; last = 0; } while ((s[0] = c) == ' '|| c == '\t'); s[1] = '\0'; if (!isdigit(c) && c != '.' && c != '-') return c; if (c == '-') { if (isdigit(c=getch())) sign = -1; else { last = c; return '-'; } } i = 0; if (sign < 0) s[++i] = c; if (isdigit(c)) while (isdigit(s[++i] = c = getch())); if (c == '.') while (isdigit(s[++i] = c = getch())); s[i] = '\0'; if (c != EOF) last = c; return NUMBER; }