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);