6
6
*/
7
7
8
8
#include <stdio.h>
9
- #include <stdlib.h> /* for atof() */
9
+ #include <stdlib.h> /* for atof() */
10
10
#include <ctype.h>
11
- #include <string.h> /* for strcmp() */
12
- #include <math.h> /* for math commands */
13
-
14
- #define MAXLINE 1000
15
- #define MAXOP 100 /* max size of operand or operator */
16
- #define NUMBER '0' /* signal that a number was found */
17
- #define MATH '1' /* signal that an operation was found */
18
- #define MAXVAL 100 /* maximum depth of val stack */
19
- #define BUFSIZE 100
20
- #define MAXVAR 26
21
- #define TOP val[sp - 1] /* top element in stack */
11
+ #include <string.h> /* for strcmp() */
12
+ #include <math.h> /* for math commands */
13
+
14
+ #define MAXLINE 1000
15
+ #define MAXOP 100 /* max size of operand or operator */
16
+ #define NUMBER '0' /* signal that a number was found */
17
+ #define NAME '1' /* signal that a string command was found */
18
+ #define MAXVAL 100 /* maximum depth of val stack */
19
+ #define BUFSIZE 100
20
+ #define MAXVAR 26
21
+ #define TOP val[sp - 1] /* top element in stack */
22
22
23
23
/* functions */
24
24
int getop (char []);
25
25
int getLine (char [], int );
26
26
void push (double );
27
27
double pop (void );
28
- void printTop (void );
28
+ void printTOP (void );
29
29
void duplicateTop (void );
30
30
void swapTopTwo (void );
31
31
void clearStack (void );
32
32
int mathfunction (char []);
33
33
void storeVariable (void );
34
- void fetchVariable (void );
34
+ void fetchVariable (int var );
35
35
void clearMemory (void );
36
36
37
37
/* globals */
@@ -40,9 +40,9 @@ double val[MAXVAL]; /* value stack */
40
40
double mem [MAXVAR ]; /* variables values */
41
41
char buf [BUFSIZE ]; /* buffer from ungetch */
42
42
int bufp ; /* next free position in buf */
43
- int stackcmd ; /* stack commands flag */
44
- char variable ; /* current input variable */
45
- double lastPrint ; /* last printed value */
43
+ int peak ; /* flag: peak at top of the stack */
44
+ int variable ; /* current input variable */
45
+ double printed ; /* last printed value */
46
46
47
47
/* push: push f onto value stack */
48
48
void push (double f )
@@ -71,7 +71,7 @@ int getop(char s[])
71
71
static char line [MAXLINE ]; /* note static in type */
72
72
int j ;
73
73
74
- if (i == len ) { /* previous was read completely */
74
+ if (i == len ) { /* previous line read completely */
75
75
len = getLine (line , MAXLINE );
76
76
if (!len )
77
77
return EOF ;
@@ -89,7 +89,7 @@ int getop(char s[])
89
89
while (isalpha (line [i ]))
90
90
s [j ++ ] = line [i ++ ];
91
91
s [j ] = '\0' ;
92
- return MATH ;
92
+ return ( strlen ( s ) == 1 ) ? s [ 0 ] : NAME ;
93
93
}
94
94
95
95
if (!isdigit (line [i ]) && line [i ] != '.' )
@@ -124,98 +124,96 @@ int getLine(char s[], int lim)
124
124
return i ;
125
125
}
126
126
127
- /* printTop: prints the top element in the stack */
128
- void printTop (void )
127
+ /* printTOP: print top of the stack without pop */
128
+ void printTOP (void )
129
129
{
130
- if (sp > 0 ) {
131
- printf ("\t%.8g\n" , TOP );
132
- stackcmd = 1 ;
133
- }
130
+ if (sp < 1 )
131
+ printf ("stack empty\n" );
132
+ printf ("\t%.8g\n" , TOP );
134
133
}
135
134
136
- /* deleteTop: deletes the top element in the stack */
135
+ /* duplicateTop: duplicate the top element in the stack */
137
136
void duplicateTop (void )
138
137
{
139
- if (sp > 0 ) {
140
- push (TOP );
141
- printTop ();
142
- }
138
+ double top ;
139
+
140
+ if (sp < 1 )
141
+ return ;
142
+ push (top = pop ());
143
+ push (top );
143
144
}
144
145
145
146
/* swapTopTwo: swaps top two elements */
146
147
void swapTopTwo (void )
147
148
{
148
149
double top1 , top2 ;
149
150
150
- if (sp > 1 ) {
151
- top1 = pop ();
152
- top2 = pop ();
153
- push (top1 );
154
- push (top2 );
155
- printTop ();
151
+ if (sp < 2 ) {
152
+ if (sp == 1 )
153
+ printf ("error: 1 element in stack\n" );
154
+ return ;
156
155
}
156
+ top1 = pop ();
157
+ top2 = pop ();
158
+ push (top1 );
159
+ push (top2 );
157
160
}
158
161
159
162
/* clear: clears the entire stack */
160
163
void clearStack (void )
161
164
{
162
- while (sp > 0 )
165
+ while (sp > 1 )
163
166
pop ();
164
- printTop ();
165
167
}
166
168
167
- /* mathf: call the appropriate math function according to value of s */
169
+ /* mathfunction: call the appropriate math function according to value of s,
170
+ * return 1 on success 0 on failure. */
168
171
int mathfunction (char s [])
169
172
{
170
173
double op2 ;
171
174
172
- if (strcmp (s , "sin" ) == 0 )
175
+ if (! strcmp (s , "sin" ))
173
176
push (sin (pop ()));
174
- else if (strcmp (s , "cos" ) == 0 )
177
+ else if (! strcmp (s , "cos" ))
175
178
push (cos (pop ()));
176
- else if (strcmp (s , "exp" ) == 0 )
179
+ else if (! strcmp (s , "exp" ))
177
180
push (exp (pop ()));
178
- else if (strcmp (s , "sqrt" ) == 0 )
181
+ else if (! strcmp (s , "sqrt" ))
179
182
push (sqrt (pop ()));
180
- else if (strcmp (s , "pow" ) == 0 ) {
183
+ else if (! strcmp (s , "pow" )) {
181
184
op2 = pop ();
182
185
push (pow (pop (), op2 ));
183
186
} else
184
187
return 0 ;
185
188
return 1 ;
186
189
}
187
190
188
- /* storeVariable: stores the value of a variable (a to z) to the corrosponding
189
- * memory location in mem */
191
+ /* storeVariable: store variable value (a to z) to the corresponding
192
+ * location in mem and push back to top of stack */
190
193
void storeVariable (void )
191
194
{
192
- pop (); /* pop stored value by fetchVariable */
193
- variable = tolower (variable );
194
- mem [variable - 'a' ] = pop (); /* variable value - top of the stack */
195
- stackcmd = 1 ; /* skip pop print */
195
+ // if (isalpha(variable) && islower(variable)) {
196
+ if (variable >= 'a' && variable <= 'z' ) {
197
+ pop ();
198
+ push (mem [variable - 'a' ] = pop ());
199
+ } else
200
+ printf ("error: no variable name\n" );
196
201
}
197
202
198
- /* fetchVariable: fetches variable value from memory and pushes to the top of
199
- * the stack */
200
- void fetchVariable (void )
203
+ /* fetchVariable: fetch var value from mem and push on to value stack */
204
+ void fetchVariable (int var )
201
205
{
202
- if (variable == 'R' )
203
- push (lastPrint );
204
- else {
205
- variable = tolower (variable );
206
- push (mem [variable - 'a' ]);
207
- }
206
+ push (mem [var - 'a' ]);
208
207
}
209
208
210
- /* clearMemory: initializes values of mem to 0 */
209
+ /* clearMemory: set values of mem to 0 */
211
210
void clearMemory (void )
212
211
{
213
212
int i ;
214
213
215
214
for (i = 0 ; i <= MAXVAR ; ++ i )
216
215
mem [i ] = 0 ;
217
216
printf ("memory cleared\n" );
218
- stackcmd = 1 ; /* skip pop print */
219
217
}
220
218
221
219
/* reverse Polish Calculator */
@@ -224,12 +222,21 @@ int main(void)
224
222
int type ;
225
223
double op2 ;
226
224
char s [MAXOP ];
227
-
225
+
228
226
while ((type = getop (s )) != EOF ) {
229
227
switch (type ) {
230
228
case NUMBER :
231
229
push (atof (s ));
232
230
break ;
231
+ case NAME :
232
+ if (!strcmp (s , "lp" )) {
233
+ push (printed );
234
+ } else if (!strcmp (s , "mc" )) {
235
+ clearMemory ();
236
+ peak = 1 ;
237
+ } else if (!mathfunction (s ))
238
+ printf ("error: unknown command %s\n" , s );
239
+ break ;
233
240
case '+' :
234
241
push (pop () + pop ());
235
242
break ;
@@ -255,7 +262,7 @@ int main(void)
255
262
printf ("error: zero divisor\n" );
256
263
break ;
257
264
case '!' :
258
- printTop () ;
265
+ peak = 1 ;
259
266
break ;
260
267
case '#' :
261
268
duplicateTop ();
@@ -270,23 +277,20 @@ int main(void)
270
277
storeVariable ();
271
278
break ;
272
279
case '\n' :
273
- if (!stackcmd )
274
- printf ("\t%.8g\n" , lastPrint = pop ());
275
- stackcmd = 0 ;
276
- break ;
277
- case MATH :
278
- if (strlen (s ) == 1 ) {
279
- variable = s [0 ];
280
- fetchVariable ();
281
- } else if (strcmp (s , "mc" ) == 0 )
282
- clearMemory ();
283
- else if (!mathfunction (s ))
284
- printf ("error: unknown command %s\n" , s );
280
+ if (peak ) {
281
+ printTOP ();
282
+ peak = 0 ;
283
+ } else
284
+ printf ("\t%.8g\n" , printed = pop ());
285
285
break ;
286
286
default :
287
- printf ("error: unknown command %s\n" , s );
287
+ if (islower (type ))
288
+ fetchVariable (type );
289
+ else
290
+ printf ("error: unknown command %s\n" , s );
288
291
break ;
289
292
}
293
+ variable = type ; /* remember variable */
290
294
}
291
295
return 0 ;
292
296
}
0 commit comments