2
2
* Exercise 4-6. Add commands for handling variables. (it's easy to provide
3
3
* twenty-six variables with single-letter names). Add a variable for most
4
4
* recently printed value.
5
+ * Issues:
6
+ * 1. Variables are initialized to zero by default. Therefore, if a user
7
+ * calls an unset variable, it will return a value 0. For example, the
8
+ * result of "2 x$ *" is 0, if x is unset.
9
+ * 2. If a variable is entered without the fetch operator "$", it will be
10
+ * ignored. For example, "2 x *" is be evaluated as "2 *".
11
+ * 3. If the call operator is used on an invalid variable, it will be ignored.
12
+ * 4. Ambiguity, 4 x = and x 4 = will assign 4 to x. This makes 4 x 5 y = will
13
+ * ambiguous becasue it assigns 5 to x and y.
5
14
* Faisal Saadatmand
6
15
*/
7
16
11
20
#include <string.h> /* for strcmp() */
12
21
#include <math.h> /* for math commands */
13
22
14
- #define MAXOP 100 /* max size of operand or operator */
15
- #define NUMBER '0' /* signal that a number was found */
16
- #define MATH '1' /* signal that an operation was found */
17
- #define MAXVAL 100 /* maximum depth of val stack */
18
- #define BUFSIZE 100
19
- #define MAXVAR 26
20
- #define TOP val[sp - 1] /* top element in stack */
23
+ #define MAXOP 100 /* max size of operand or operator */
24
+ #define NUMBER '0' /* signal that a number was found */
25
+ #define COMMAND '1' /* signal that a string command was found */
26
+ #define VARIABLE '2' /* signal that variable was found */
27
+ #define MAXVAL 100 /* maximum depth of val stack */
28
+ #define BUFSIZE 100
29
+ #define MAXVAR 26
30
+ #define TOP val[sp - 1] /* top element in stack */
21
31
22
32
/* functions */
23
33
int getop (char []);
24
34
void push (double );
25
35
double pop (void );
26
36
int getch (void );
27
37
void ungetch (int );
28
- void printTop (void );
38
+ void printTOP (void );
29
39
void duplicateTop (void );
30
40
void swapTopTwo (void );
31
41
void clearStack (void );
32
42
int mathfunction (char []);
33
- void storeVariable ( void );
34
- void fetchVariable ( void );
43
+ void storeValue ( char );
44
+ void fetchValue ( char );
35
45
void clearMemory (void );
36
46
37
47
/* globals */
@@ -40,9 +50,9 @@ double val[MAXVAL]; /* value stack */
40
50
double mem [MAXVAR ]; /* variables values */
41
51
char buf [BUFSIZE ]; /* buffer from ungetch */
42
52
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 */
53
+ int peak ; /* flag: peak at top of the stack */
54
+ int variable ; /* current input variable */
55
+ double printed ; /* last printed value */
46
56
47
57
/* push: push f onto value stack */
48
58
void push (double f )
@@ -74,27 +84,27 @@ int getop(char s[])
74
84
s [1 ] = '\0' ;
75
85
76
86
i = 0 ;
77
- if (c == '-' ) /* check sign */
87
+ if (c == '-' ) /* check sign */
78
88
if (!isdigit (s [++ i ] = c = getch ())) {
79
89
ungetch (c );
80
- c = s [0 ]; /* not a sign */
90
+ c = s [0 ]; /* not a sign */
81
91
}
82
92
83
- if (isalpha (c )) { /* math functions */
93
+ if (isalpha (c )) { /* string command */
84
94
while (isalpha (s [++ i ] = c = getch ()))
85
95
;
86
96
s [i ] = '\0' ;
87
97
ungetch (c );
88
- return MATH ;
98
+ return ( strlen ( s ) == 1 ) ? VARIABLE : COMMAND ;
89
99
}
90
100
91
101
if (!isdigit (c ) && c != '.' )
92
- return c ; /* not a number */
102
+ return c ; /* not a number */
93
103
94
104
if (isdigit (c ))
95
105
while (isdigit (s [++ i ] = c = getch ()))
96
106
;
97
- if ( c == '.' ) /* collect fraction part */
107
+ if ( c == '.' ) /* collect fraction part */
98
108
while (isdigit (s [++ i ] = c = getch ()))
99
109
;
100
110
s [i ] = '\0' ;
@@ -119,98 +129,91 @@ void ungetch(int c)
119
129
buf [bufp ++ ] = c ;
120
130
}
121
131
122
- /* printTop: prints the top element in the stack */
123
- void printTop ( void )
132
+ /* printTOP: print top of the stack without pop */
133
+ void printTOP ( )
124
134
{
125
- if (sp > 0 ) {
126
- printf ("\t%.8g\n" , TOP );
127
- stackcmd = 1 ;
128
- }
135
+ if (sp < 1 )
136
+ printf ("stack empty\n" );
137
+ printf ("\t%.8g\n" , TOP );
129
138
}
130
139
131
- /* deleteTop: deletes the top element in the stack */
140
+ /* duplicateTop: duplicate the top element in the stack */
132
141
void duplicateTop (void )
133
142
{
134
- if (sp > 0 ) {
135
- push (TOP );
136
- printTop ();
137
- }
143
+ double top ;
144
+
145
+ if (sp < 1 )
146
+ return ;
147
+ push (top = pop ());
148
+ push (top );
138
149
}
139
150
140
151
/* swapTopTwo: swaps top two elements */
141
152
void swapTopTwo (void )
142
153
{
143
154
double top1 , top2 ;
144
155
145
- if (sp > 1 ) {
146
- top1 = pop ();
147
- top2 = pop ();
148
- push (top1 );
149
- push (top2 );
150
- printTop ();
156
+ if (sp < 2 ) {
157
+ if (sp == 1 )
158
+ printf ("error: 1 element in stack\n" );
159
+ return ;
151
160
}
161
+ top1 = pop ();
162
+ top2 = pop ();
163
+ push (top1 );
164
+ push (top2 );
152
165
}
153
166
154
167
/* clear: clears the entire stack */
155
168
void clearStack (void )
156
169
{
157
- while (sp > 0 )
170
+ while (sp > 1 )
158
171
pop ();
159
- printTop ();
160
172
}
161
173
162
- /* mathf: call the appropriate math function according to value of s */
174
+ /* mathfunction: call the appropriate math function according to value of s,
175
+ * return 1 on success 0 on failure. */
163
176
int mathfunction (char s [])
164
177
{
165
178
double op2 ;
166
179
167
- if (strcmp (s , "sin" ) == 0 )
180
+ if (! strcmp (s , "sin" ))
168
181
push (sin (pop ()));
169
- else if (strcmp (s , "cos" ) == 0 )
182
+ else if (! strcmp (s , "cos" ))
170
183
push (cos (pop ()));
171
- else if (strcmp (s , "exp" ) == 0 )
184
+ else if (! strcmp (s , "exp" ))
172
185
push (exp (pop ()));
173
- else if (strcmp (s , "sqrt" ) == 0 )
186
+ else if (! strcmp (s , "sqrt" ))
174
187
push (sqrt (pop ()));
175
- else if (strcmp (s , "pow" ) == 0 ) {
188
+ else if (! strcmp (s , "pow" )) {
176
189
op2 = pop ();
177
190
push (pow (pop (), op2 ));
178
191
} else
179
192
return 0 ;
180
193
return 1 ;
181
194
}
182
195
183
- /* storeVariable: stores the value of a variable (a to z) to the corrosponding
184
- * memory location in mem */
185
- void storeVariable ( void )
196
+ /* storeValue: store value of a var (a to z) to the corresponding
197
+ * location in mem and push back to top of stack */
198
+ void storeValue ( char var )
186
199
{
187
- pop (); /* pop stored value by fetchVariable */
188
- variable = tolower (variable );
189
- mem [variable - 'a' ] = pop (); /* variable value - top of the stack */
190
- stackcmd = 1 ; /* skip pop print */
200
+ push (mem [var - 'a' ] = pop ());
191
201
}
192
202
193
- /* fetchVariable: fetches variable value from memory and pushes to the top of
194
- * the stack */
195
- void fetchVariable (void )
203
+ /* fetchValue: fetch value var from mem and push on to value stack */
204
+ void fetchValue (char var )
196
205
{
197
- if (variable == 'R' )
198
- push (lastPrint );
199
- else {
200
- variable = tolower (variable );
201
- push (mem [variable - 'a' ]);
202
- }
206
+ push (mem [var - 'a' ]);
203
207
}
204
208
205
- /* clearMemory: initializes values of mem to 0 */
209
+ /* clearMemory: set values of mem to 0 */
206
210
void clearMemory (void )
207
211
{
208
212
int i ;
209
213
210
214
for (i = 0 ; i <= MAXVAR ; ++ i )
211
215
mem [i ] = 0 ;
212
216
printf ("memory cleared\n" );
213
- stackcmd = 1 ; /* skip pop print */
214
217
}
215
218
216
219
/* reverse Polish Calculator */
@@ -250,7 +253,7 @@ int main(void)
250
253
printf ("error: zero divisor\n" );
251
254
break ;
252
255
case '!' :
253
- printTop () ;
256
+ peak = 1 ;
254
257
break ;
255
258
case '#' :
256
259
duplicateTop ();
@@ -262,22 +265,43 @@ int main(void)
262
265
clearStack ();
263
266
break ;
264
267
case '=' :
265
- storeVariable ();
268
+ if (isalpha (variable )) /* check if variable is valid */
269
+ storeValue (variable );
270
+ variable = 0 ;
271
+ break ;
272
+ case '$' :
273
+ if (isalpha (variable )) /* check if variable is valid */
274
+ fetchValue (variable );
275
+ variable = 0 ;
266
276
break ;
267
277
case '\n' :
268
- if (!stackcmd )
269
- printf ("\t%.8g\n" , lastPrint = pop ());
270
- stackcmd = 0 ;
278
+ if (peak ) {
279
+ printTOP ();
280
+ peak = 0 ;
281
+ } else
282
+ printf ("\t%.8g\n" , printed = pop ());
283
+
284
+ if (variable ) {
285
+ printf ("usage: %c$\n" , variable );
286
+ variable = 0 ;
287
+ }
271
288
break ;
272
- case MATH :
273
- if (strlen (s ) == 1 ) {
274
- variable = s [0 ];
275
- fetchVariable ();
276
- } else if (strcmp (s , "mc" ) == 0 )
277
- clearMemory ();
278
- else if (!mathfunction (s ))
279
- printf ("error: unknown command %s\n" , s );
289
+ case VARIABLE :
290
+ variable = tolower (s [0 ]);
280
291
break ;
292
+ case COMMAND :
293
+ if (!strcmp (s , "lp" )) {
294
+ push (printed );
295
+ break ;
296
+ }
297
+ if (!strcmp (s , "mc" )) {
298
+ clearMemory ();
299
+ peak = 1 ;
300
+ break ;
301
+ }
302
+ if (mathfunction (s ))
303
+ break ;
304
+ /* fall through */
281
305
default :
282
306
printf ("error: unknown command %s\n" , s );
283
307
break ;
0 commit comments