Mercurial > ~dholland > hg > tradcpp > index.cgi
comparison eval.c @ 92:b127a69061b2
fix some bugs.
add compile-time option for debug output
author | David A. Holland |
---|---|
date | Mon, 10 Jun 2013 23:22:12 -0400 |
parents | bd1b7a09da89 |
children | 408331be8792 |
comparison
equal
deleted
inserted
replaced
91:bd1b7a09da89 | 92:b127a69061b2 |
---|---|
30 #include <stdlib.h> | 30 #include <stdlib.h> |
31 #include <string.h> | 31 #include <string.h> |
32 #include <limits.h> | 32 #include <limits.h> |
33 #include <errno.h> | 33 #include <errno.h> |
34 | 34 |
35 //#define DEBUG | |
36 #ifdef DEBUG | |
37 #include <stdio.h> | |
38 #endif | |
39 | |
35 #include "utils.h" | 40 #include "utils.h" |
36 #include "array.h" | 41 #include "array.h" |
37 #include "mode.h" | 42 #include "mode.h" |
38 #include "place.h" | 43 #include "place.h" |
39 #include "eval.h" | 44 #include "eval.h" |
152 dofree(t, sizeof(*t)); | 157 dofree(t, sizeof(*t)); |
153 } | 158 } |
154 | 159 |
155 DESTROYALL_ARRAY(token, ); | 160 DESTROYALL_ARRAY(token, ); |
156 | 161 |
162 #ifdef DEBUG | |
163 static | |
164 void | |
165 printtokens(void) | |
166 { | |
167 unsigned i, num; | |
168 struct token *t; | |
169 | |
170 fprintf(stderr, "tokens:"); | |
171 num = tokenarray_num(&tokens); | |
172 for (i=0; i<num; i++) { | |
173 t = tokenarray_get(&tokens, i); | |
174 switch (t->tok) { | |
175 case T_EOF: fprintf(stderr, " <eof>"); break; | |
176 case T_VAL: fprintf(stderr, " %d", t->val); break; | |
177 case T_LPAREN: fprintf(stderr, " ("); break; | |
178 case T_RPAREN: fprintf(stderr, " )"); break; | |
179 case T_PIPEPIPE: fprintf(stderr, " ||"); break; | |
180 case T_AMPAMP: fprintf(stderr, " &&"); break; | |
181 case T_EQEQ: fprintf(stderr, " =="); break; | |
182 case T_BANGEQ: fprintf(stderr, " !="); break; | |
183 case T_LTEQ: fprintf(stderr, " <="); break; | |
184 case T_GTEQ: fprintf(stderr, " >="); break; | |
185 case T_LTLT: fprintf(stderr, " <<"); break; | |
186 case T_GTGT: fprintf(stderr, " >>"); break; | |
187 case T_QUES: fprintf(stderr, " ?"); break; | |
188 case T_COLON: fprintf(stderr, " :"); break; | |
189 case T_PIPE: fprintf(stderr, " |"); break; | |
190 case T_CARET: fprintf(stderr, " ^"); break; | |
191 case T_AMP: fprintf(stderr, " &"); break; | |
192 case T_LT: fprintf(stderr, " <"); break; | |
193 case T_GT: fprintf(stderr, " >"); break; | |
194 case T_PLUS: fprintf(stderr, " +"); break; | |
195 case T_MINUS: fprintf(stderr, " -"); break; | |
196 case T_STAR: fprintf(stderr, " *"); break; | |
197 case T_SLASH: fprintf(stderr, " /"); break; | |
198 case T_PCT: fprintf(stderr, " %%"); break; | |
199 case T_BANG: fprintf(stderr, " !"); break; | |
200 case T_TILDE: fprintf(stderr, " ~"); break; | |
201 } | |
202 } | |
203 fprintf(stderr, "\n"); | |
204 } | |
205 #endif | |
206 | |
157 static | 207 static |
158 bool | 208 bool |
159 isuop(enum tokens tok) | 209 isuop(enum tokens tok) |
160 { | 210 { |
161 switch (tok) { | 211 switch (tok) { |
209 static | 259 static |
210 int | 260 int |
211 getprec(enum tokens tok) | 261 getprec(enum tokens tok) |
212 { | 262 { |
213 switch (tok) { | 263 switch (tok) { |
264 case T_BANG: case T_TILDE: return -1; | |
214 case T_STAR: case T_SLASH: case T_PCT: return 0; | 265 case T_STAR: case T_SLASH: case T_PCT: return 0; |
215 case T_PLUS: case T_MINUS: return 1; | 266 case T_PLUS: case T_MINUS: return 1; |
216 case T_LTLT: case T_GTGT: return 2; | 267 case T_LTLT: case T_GTGT: return 2; |
217 case T_LT: case T_LTEQ: case T_GT: case T_GTEQ: return 3; | 268 case T_LT: case T_LTEQ: case T_GT: case T_GTEQ: return 3; |
218 case T_EQEQ: case T_BANGEQ: return 4; | 269 case T_EQEQ: case T_BANGEQ: return 4; |
228 | 279 |
229 static | 280 static |
230 bool | 281 bool |
231 looser(enum tokens t1, enum tokens t2) | 282 looser(enum tokens t1, enum tokens t2) |
232 { | 283 { |
233 return getprec(t1) > getprec(t2); | 284 return getprec(t1) >= getprec(t2); |
234 } | 285 } |
235 | 286 |
236 static | 287 static |
237 int | 288 int |
238 eval_uop(enum tokens op, int val) | 289 eval_uop(enum tokens op, int val) |
379 { | 430 { |
380 unsigned num; | 431 unsigned num; |
381 struct token *t1, *t2, *t3, *t4, *t5, *t6; | 432 struct token *t1, *t2, *t3, *t4, *t5, *t6; |
382 | 433 |
383 while (1) { | 434 while (1) { |
435 #ifdef DEBUG | |
436 printtokens(); | |
437 #endif | |
384 num = tokenarray_num(&tokens); | 438 num = tokenarray_num(&tokens); |
385 t1 = (num >= 1) ? tokenarray_get(&tokens, num-1) : NULL; | 439 t1 = (num >= 1) ? tokenarray_get(&tokens, num-1) : NULL; |
386 t2 = (num >= 2) ? tokenarray_get(&tokens, num-2) : NULL; | 440 t2 = (num >= 2) ? tokenarray_get(&tokens, num-2) : NULL; |
387 t3 = (num >= 3) ? tokenarray_get(&tokens, num-3) : NULL; | 441 t3 = (num >= 3) ? tokenarray_get(&tokens, num-3) : NULL; |
388 | 442 |
409 token_destroy(t2); | 463 token_destroy(t2); |
410 tokenarray_remove(&tokens, num-2); | 464 tokenarray_remove(&tokens, num-2); |
411 continue; | 465 continue; |
412 } | 466 } |
413 if (num >= 2 && | 467 if (num >= 2 && |
414 (num == 2 || isop(t3->tok) || t3->tok == T_RPAREN) && | 468 (num == 2 || isop(t3->tok) || t3->tok == T_LPAREN) && |
415 t2->tok != T_LPAREN && t2->tok != T_VAL && | 469 t2->tok != T_LPAREN && t2->tok != T_VAL && |
416 t1->tok == T_VAL) { | 470 t1->tok == T_VAL) { |
417 complain(&t2->place, "Invalid unary operator"); | 471 complain(&t2->place, "Invalid unary operator"); |
418 complain_fail(); | 472 complain_fail(); |
419 token_destroy(t2); | 473 token_destroy(t2); |
425 t4 = (num >= 4) ? tokenarray_get(&tokens, num-4) : NULL; | 479 t4 = (num >= 4) ? tokenarray_get(&tokens, num-4) : NULL; |
426 | 480 |
427 if (num >= 4 && | 481 if (num >= 4 && |
428 t4->tok == T_VAL && | 482 t4->tok == T_VAL && |
429 isbop(t3->tok) && | 483 isbop(t3->tok) && |
430 t2->tok == T_VAL && | 484 t2->tok == T_VAL) { |
431 (isbop(t1->tok) || !isop(t1->tok))) { | |
432 /* binary operator */ | 485 /* binary operator */ |
433 if (looser(t1->tok, t3->tok)) { | 486 if (looser(t1->tok, t3->tok)) { |
434 t4->val = eval_bop(&t3->place, | 487 t4->val = eval_bop(&t3->place, |
435 t4->val, t3->tok, t2->val); | 488 t4->val, t3->tok, t2->val); |
436 token_destroy(t2); | 489 token_destroy(t2); |
678 { | 731 { |
679 struct token *t1, *t2; | 732 struct token *t1, *t2; |
680 unsigned num; | 733 unsigned num; |
681 bool result; | 734 bool result; |
682 | 735 |
736 #ifdef DEBUG | |
737 fprintf(stderr, "eval: %s\n", expr); | |
738 #endif | |
739 | |
683 tokenarray_init(&tokens); | 740 tokenarray_init(&tokens); |
684 tokenize(p, expr); | 741 tokenize(p, expr); |
685 | 742 |
686 result = false; | 743 result = false; |
687 num = tokenarray_num(&tokens); | 744 num = tokenarray_num(&tokens); |