1
1
/*
2
- * Exercise 4-10. An alternate organization uses getline to read an entire input
3
- * line; this makes getch and ungetch unnecessary. Revise the calculator to us
4
- * this approach.
2
+ * Exercise 4-10. An alternative organization uses getline to read an entire
3
+ * input line; this makes getch and ungetch unnecessary. Revise the calculator
4
+ * to use this approach.
5
5
* Faisal Saadatmand
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 */
11
+ #include <string.h> /* for strcmp() */
12
+ #include <math.h> /* for math commands */
13
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 END 0 /* signal EOF */
19
- #define MAXVAL 100 /* maximum depth of val stack */
20
- #define MATCH 0
21
- #define MAXVAR 26 /* max number of variables */
22
- #define TOP val[sp - 1] /* top of the stack element */
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 */
23
22
24
23
/* functions */
25
24
int getop (char []);
26
25
int getLine (char [], int );
27
26
void push (double );
28
27
double pop (void );
29
28
void printTop (void );
30
- void duplicateTop (void );
29
+ void duplicateTop (void );
31
30
void swapTopTwo (void );
32
31
void clearStack (void );
33
- void storeVariable (double [], char );
34
- void fetchVariable (double [], char );
35
- void clearMemory (double [], int );
32
+ int mathfunction (char []);
33
+ void storeVariable (void );
34
+ void fetchVariable (void );
35
+ void clearMemory (void );
36
36
37
37
/* globals */
38
- int sp = 0 ; /* next free stack position */
38
+ int sp ; /* next free stack position */
39
39
double val [MAXVAL ]; /* value stack */
40
+ double mem [MAXVAR ]; /* variables values */
41
+ char buf [BUFSIZE ]; /* buffer from ungetch */
42
+ int bufp ; /* next free position in buf */
43
+ int stackcmd ; /* stack commands flag */
40
44
char variable ; /* current input variable */
41
45
double lastPrint ; /* last printed value */
42
46
@@ -52,44 +56,46 @@ void push(double f)
52
56
/* pop: pop and return top value from stack */
53
57
double pop (void )
54
58
{
55
- if (sp > 0 ) {
59
+ if (sp > 0 )
56
60
return val [-- sp ];
57
- } else {
61
+ else {
58
62
printf ("error: stack empty\n" );
59
63
return 0.0 ;
60
64
}
61
65
}
62
66
63
- /* getop: get next operator or numeric operand */
67
+ /* getop: get next operator or numeric operand - getline version */
64
68
int getop (char s [])
65
69
{
66
70
static int i , len ; /* note static in type */
67
71
static char line [MAXLINE ]; /* note static in type */
68
72
int j ;
69
73
70
- if (i == len ) { /* check if the previous line was read completely */
71
- len = getLine (line , MAXLINE ); /* read the next line */
72
- i = 0 ; /* reset index */
73
- if ( len < 0 ) /* line to read */
74
- return END ;
74
+ if (i == len ) { /* previous was read completely */
75
+ len = getLine (line , MAXLINE );
76
+ if (! len )
77
+ return EOF ;
78
+ i = 0 ; /* reset line index */
75
79
}
76
80
77
81
j = 0 ;
78
82
while (isblank (line [i ])) /* skip blanks */
79
83
++ i ;
80
84
81
- if (line [i ] == '-' && isdigit (line [i + 1 ])) /* negative numbers */
85
+ if (line [i ] == '-' && isdigit (line [i + 1 ])) /* sign */
82
86
s [j ++ ] = line [i ++ ];
83
87
84
- if (!isdigit (line [i ]) && !isalpha (line [i ]) && line [i ] != '.' )
85
- return line [i ++ ]; /* not a number */
86
-
87
88
if (isalpha (line [i ])) { /* math functions and variables */
88
89
while (isalpha (line [i ]))
89
90
s [j ++ ] = line [i ++ ];
90
91
s [j ] = '\0' ;
91
92
return MATH ;
92
- } else if (isdigit (line [i ])) /* collect number */
93
+ }
94
+
95
+ if (!isdigit (line [i ]) && line [i ] != '.' )
96
+ return line [i ++ ]; /* not a number */
97
+
98
+ if (isdigit (line [i ])) /* collect number */
93
99
while (isdigit (line [i ]))
94
100
s [j ++ ] = line [i ++ ];
95
101
@@ -118,23 +124,25 @@ int getLine(char s[], int lim)
118
124
return i ;
119
125
}
120
126
121
- /* printTop: prints the top element in the stack without popping */
127
+ /* printTop: prints the top element in the stack */
122
128
void printTop (void )
123
129
{
124
- if (sp > 0 )
130
+ if (sp > 0 ) {
125
131
printf ("\t%.8g\n" , TOP );
126
- else
127
- printf ( "stack is empty\n" );
132
+ stackcmd = 1 ;
133
+ }
128
134
}
129
135
130
- /* duplicateTop: duplicate the top element in the stack */
131
- void duplicateTop (void )
136
+ /* deleteTop: deletes the top element in the stack */
137
+ void duplicateTop (void )
132
138
{
133
- if (sp > 0 )
139
+ if (sp > 0 ) {
134
140
push (TOP );
141
+ printTop ();
142
+ }
135
143
}
136
144
137
- /* swapTopTwos : swaps top two elements */
145
+ /* swapTopTwo : swaps top two elements */
138
146
void swapTopTwo (void )
139
147
{
140
148
double top1 , top2 ;
@@ -144,54 +152,70 @@ void duplicateTop (void)
144
152
top2 = pop ();
145
153
push (top1 );
146
154
push (top2 );
147
- } else
148
- printf ( "not enough elements\n" );
149
- }
155
+ printTop ();
156
+ }
157
+ }
150
158
151
159
/* clear: clears the entire stack */
152
160
void clearStack (void )
153
161
{
154
162
while (sp > 0 )
155
163
pop ();
164
+ printTop ();
156
165
}
157
166
158
- /* storeVariable: stores the value of a variable (a to z) to the corresponding
159
- * memory location in mem */
160
- void storeVariable (double mem [], char variable )
167
+ /* mathf: call the appropriate math function according to value of s */
168
+ int mathfunction (char s [])
161
169
{
162
- double value ;
170
+ double op2 ;
163
171
164
- if (variable == 'P' ) { /* last printed value variable */
165
- value = lastPrint ; /* fetch last printed value value */
166
- mem [MAXVAR ] = value ; /* last location is reserved for P */
167
- } else {
168
- pop (); /* pop stored value by fetchVariable */
169
- value = pop (); /* variable value - top of the stack */
170
- variable = tolower (variable );
171
- mem [variable - 'a' ] = value ;
172
- push (value );
173
- }
172
+ if (strcmp (s , "sin" ) == 0 )
173
+ push (sin (pop ()));
174
+ else if (strcmp (s , "cos" ) == 0 )
175
+ push (cos (pop ()));
176
+ else if (strcmp (s , "exp" ) == 0 )
177
+ push (exp (pop ()));
178
+ else if (strcmp (s , "sqrt" ) == 0 )
179
+ push (sqrt (pop ()));
180
+ else if (strcmp (s , "pow" ) == 0 ) {
181
+ op2 = pop ();
182
+ push (pow (pop (), op2 ));
183
+ } else
184
+ return 0 ;
185
+ return 1 ;
186
+ }
187
+
188
+ /* storeVariable: stores the value of a variable (a to z) to the corrosponding
189
+ * memory location in mem */
190
+ void storeVariable (void )
191
+ {
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 */
174
196
}
175
197
176
198
/* fetchVariable: fetches variable value from memory and pushes to the top of
177
199
* the stack */
178
- void fetchVariable (double mem [], char variable )
200
+ void fetchVariable (void )
179
201
{
180
- if (variable == 'P' ) /* last printed value variable */
181
- push (mem [ MAXVAR ]); /* last location is reserved for P */
202
+ if (variable == 'R' )
203
+ push (lastPrint );
182
204
else {
183
205
variable = tolower (variable );
184
- push (mem [variable - 'a' ]); /* push value to the top of the stack */
206
+ push (mem [variable - 'a' ]);
185
207
}
186
208
}
187
209
188
210
/* clearMemory: initializes values of mem to 0 */
189
- void clearMemory (double mem [], int size )
211
+ void clearMemory (void )
190
212
{
191
213
int i ;
192
214
193
- for (i = 0 ; i <= size ; ++ i )
215
+ for (i = 0 ; i <= MAXVAR ; ++ i )
194
216
mem [i ] = 0 ;
217
+ printf ("memory cleared\n" );
218
+ stackcmd = 1 ; /* skip pop print */
195
219
}
196
220
197
221
/* reverse Polish Calculator */
@@ -200,9 +224,8 @@ int main(void)
200
224
int type ;
201
225
double op2 ;
202
226
char s [MAXOP ];
203
- static double mem [MAXVAR ]; /* variables values */
204
-
205
- while ((type = getop (s )) != END ) {
227
+
228
+ while ((type = getop (s )) != EOF ) {
206
229
switch (type ) {
207
230
case NUMBER :
208
231
push (atof (s ));
@@ -243,33 +266,21 @@ int main(void)
243
266
case '~' :
244
267
clearStack ();
245
268
break ;
246
- case '$ ' :
247
- storeVariable (mem , variable );
269
+ case '= ' :
270
+ storeVariable ();
248
271
break ;
249
272
case '\n' :
250
- lastPrint = pop ();
251
- printf ("\t%.8g\n" , lastPrint );
252
- storeVariable ( mem , 'P' ); /* store last printed value in P */
273
+ if (! stackcmd )
274
+ printf ("\t%.8g\n" , lastPrint = pop () );
275
+ stackcmd = 0 ;
253
276
break ;
254
277
case MATH :
255
278
if (strlen (s ) == 1 ) {
256
279
variable = s [0 ];
257
- fetchVariable (mem , variable );
258
- } else if (strcmp (s , "sin" ) == MATCH )
259
- push (sin (pop ()));
260
- else if (strcmp (s , "cos" ) == MATCH )
261
- push (cos (pop ()));
262
- else if (strcmp (s , "exp" ) == MATCH )
263
- push (exp (pop ()));
264
- else if (strcmp (s , "sqrt" ) == MATCH )
265
- push (sqrt (pop ()));
266
- else if (strcmp (s , "pow" ) == MATCH ) {
267
- op2 = pop ();
268
- push (pow (pop (), op2 ));
269
- } else if (strcmp (s , "mc" ) == MATCH ) {
270
- clearMemory (mem , MAXVAR );
271
- printf ("memory cleared\n" );
272
- } else
280
+ fetchVariable ();
281
+ } else if (strcmp (s , "mc" ) == 0 )
282
+ clearMemory ();
283
+ else if (!mathfunction (s ))
273
284
printf ("error: unknown command %s\n" , s );
274
285
break ;
275
286
default :
0 commit comments