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