blob: ca5739ab0d9134a170a55ef78a94b42752176873 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define NUMBER '0'
#define MAXOP 100
#define MAXVAL 100
int getop(char[]);
void push(double);
double pop(void);
void clear(void);
double peek(void);
// Naïve implementation of remainder operation
double frem(double f1, double f2) {
return f1 - (f2 * (int)(f1 / f2));
}
/**
* Reverse polish notation calculator
*/
int main(void) {
int type;
double op2;
char s[MAXOP];
while ((type = getop(s)) != EOF) {
switch (type) {
case NUMBER:
push(atof(s));
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
case '-':
op2 = pop();
push(pop() - op2);
break;
case '/':
op2 = pop();
if (op2 != 0.0)
push(pop() / op2);
else
printf("error: zero division attempted!\n");
break;
case '%':
op2 = pop();
if (op2 != 0.0)
push(frem(pop(), op2));
else
printf("error: zero division attempted!\n");
break;
case '~':
clear();
case '\n':
printf("\t%.8g\n", peek());
break;
default:
printf("unknown command %s\n", s);
break;
}
}
return 0;
}
int sp; // Stack position
double val[MAXVAL]; // Value stack
void push(double f) {
if (sp < MAXVAL) {
val[sp++] = f;
} else {
printf("error, stack full\n");
}
}
double pop(void) {
if (sp >= 0) {
return val[--sp];
} else {
printf("error, empty stack\n");
return 0.0;
}
}
double peek(void) {
if (sp >= 0) {
return val[sp-1];
} else {
printf("error, empty stack\n");
return 0.0;
}
}
void clear(void) {
sp = 0;
}
int getch(void);
void ungetch(int);
int getop(char s[]) {
int i,c;
// Skip to teh first non-space or tab character
while ((s[0] = c = getch()) == ' ' || c == '\t');
// Then add a null for some reason?
s[1] = '\0';
// if it's not a part of a number, it's an operation
if (!isdigit(c) && c != '.')
return c;
// Integer part
i = 0;
if (isdigit(c))
while (isdigit(s[++i] = c = getch()));
// fraction part
if (c == '.')
while (isdigit(s[++i] = c = getch()));
s[i] = '\0';
if (c != EOF)
ungetch(c);
return NUMBER;
}
#define BUFSIZE 100
int buf = -2;
int getch(void) {
if (buf != -2) {
int z = buf;
buf = -2;
return z;
}
return getchar();
}
void ungetch(int c) {
if (buf != -2)
printf("ungetch: buffer full\n");
else
buf = c;
}
|