Mercurial > ~dholland > hg > tradcpp > index.cgi
diff 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 |
line wrap: on
line diff
--- a/eval.c Mon Jun 10 22:51:17 2013 -0400 +++ b/eval.c Mon Jun 10 23:22:12 2013 -0400 @@ -32,6 +32,11 @@ #include <limits.h> #include <errno.h> +//#define DEBUG +#ifdef DEBUG +#include <stdio.h> +#endif + #include "utils.h" #include "array.h" #include "mode.h" @@ -154,6 +159,51 @@ DESTROYALL_ARRAY(token, ); +#ifdef DEBUG +static +void +printtokens(void) +{ + unsigned i, num; + struct token *t; + + fprintf(stderr, "tokens:"); + num = tokenarray_num(&tokens); + for (i=0; i<num; i++) { + t = tokenarray_get(&tokens, i); + switch (t->tok) { + case T_EOF: fprintf(stderr, " <eof>"); break; + case T_VAL: fprintf(stderr, " %d", t->val); break; + case T_LPAREN: fprintf(stderr, " ("); break; + case T_RPAREN: fprintf(stderr, " )"); break; + case T_PIPEPIPE: fprintf(stderr, " ||"); break; + case T_AMPAMP: fprintf(stderr, " &&"); break; + case T_EQEQ: fprintf(stderr, " =="); break; + case T_BANGEQ: fprintf(stderr, " !="); break; + case T_LTEQ: fprintf(stderr, " <="); break; + case T_GTEQ: fprintf(stderr, " >="); break; + case T_LTLT: fprintf(stderr, " <<"); break; + case T_GTGT: fprintf(stderr, " >>"); break; + case T_QUES: fprintf(stderr, " ?"); break; + case T_COLON: fprintf(stderr, " :"); break; + case T_PIPE: fprintf(stderr, " |"); break; + case T_CARET: fprintf(stderr, " ^"); break; + case T_AMP: fprintf(stderr, " &"); break; + case T_LT: fprintf(stderr, " <"); break; + case T_GT: fprintf(stderr, " >"); break; + case T_PLUS: fprintf(stderr, " +"); break; + case T_MINUS: fprintf(stderr, " -"); break; + case T_STAR: fprintf(stderr, " *"); break; + case T_SLASH: fprintf(stderr, " /"); break; + case T_PCT: fprintf(stderr, " %%"); break; + case T_BANG: fprintf(stderr, " !"); break; + case T_TILDE: fprintf(stderr, " ~"); break; + } + } + fprintf(stderr, "\n"); +} +#endif + static bool isuop(enum tokens tok) @@ -211,6 +261,7 @@ getprec(enum tokens tok) { switch (tok) { + case T_BANG: case T_TILDE: return -1; case T_STAR: case T_SLASH: case T_PCT: return 0; case T_PLUS: case T_MINUS: return 1; case T_LTLT: case T_GTGT: return 2; @@ -230,7 +281,7 @@ bool looser(enum tokens t1, enum tokens t2) { - return getprec(t1) > getprec(t2); + return getprec(t1) >= getprec(t2); } static @@ -381,6 +432,9 @@ struct token *t1, *t2, *t3, *t4, *t5, *t6; while (1) { +#ifdef DEBUG + printtokens(); +#endif num = tokenarray_num(&tokens); t1 = (num >= 1) ? tokenarray_get(&tokens, num-1) : NULL; t2 = (num >= 2) ? tokenarray_get(&tokens, num-2) : NULL; @@ -411,7 +465,7 @@ continue; } if (num >= 2 && - (num == 2 || isop(t3->tok) || t3->tok == T_RPAREN) && + (num == 2 || isop(t3->tok) || t3->tok == T_LPAREN) && t2->tok != T_LPAREN && t2->tok != T_VAL && t1->tok == T_VAL) { complain(&t2->place, "Invalid unary operator"); @@ -427,8 +481,7 @@ if (num >= 4 && t4->tok == T_VAL && isbop(t3->tok) && - t2->tok == T_VAL && - (isbop(t1->tok) || !isop(t1->tok))) { + t2->tok == T_VAL) { /* binary operator */ if (looser(t1->tok, t3->tok)) { t4->val = eval_bop(&t3->place, @@ -680,6 +733,10 @@ unsigned num; bool result; +#ifdef DEBUG + fprintf(stderr, "eval: %s\n", expr); +#endif + tokenarray_init(&tokens); tokenize(p, expr);