Improved version, originally named "ev2.c"
authorshort <>
Mon, 9 Jul 2001 23:04:21 +0000 (23:04 +0000)
committershort <>
Mon, 9 Jul 2001 23:04:21 +0000 (23:04 +0000)
src/ev.c

index f8f8d95..0ce6142 100644 (file)
--- a/src/ev.c
+++ b/src/ev.c
@@ -3,7 +3,11 @@
 #include <ctype.h>
 #include <assert.h>
 
-#define BUFSIZE 100
+#define NDEBUG
+
+#define BUFSIZE 1024
+
+#define bail(arg...) do { fprintf(stderr, ##arg); exit(EXIT_FAILURE); } while (0)
 
 char *arg;
 
@@ -11,6 +15,23 @@ int istack[BUFSIZE];
 char opstack[BUFSIZE];
 int istackp,opstackp;
 
+#ifdef NDEBUG
+#define dump(x)
+#else
+static void dump(char *pref)
+{
+int i;
+       fprintf(stderr,"%s: i[",pref);
+       for (i=0;i<istackp;i++) {
+               if (i) fputc(',',stderr);
+               fprintf(stderr,"%d",istack[i]);
+               }
+       fprintf(stderr,"],op=[");
+       for (i=0;i<opstackp;i++) fputc(opstack[i],stderr);
+       fprintf(stderr,"]\n");
+}
+#endif
+
 static char lex(int *ip)
 {
 char c;
@@ -27,8 +48,7 @@ long l;
                        *ip=l;
                        return 'n';
                default:
-                       fprintf(stderr,"Invalid characted in string: %s\n",arg);
-                       exit(EXIT_FAILURE);
+                       bail("Invalid characted in string: %s\n",arg);
                }
 }
 
@@ -46,21 +66,18 @@ static int oppri(char op)
 
 static void evalit(void)
 {
-       assert(opstackp);
-       if (istackp<2) {
-               fprintf(stderr,"2 arguments for operator required!\n");
-               exit(EXIT_FAILURE);
-               }
+       dump("evalit()");
+       assert(opstackp); opstackp--;
+       if (istackp<2) 
+               if (opstack[opstackp]!='(') bail("2 arguments for operator '%c' required!\n",opstack[opstackp]);
+               else bail("Stray '('!\n");
        istackp--;
-       switch (opstack[--opstackp]) {
+       switch (opstack[opstackp]) {
                case '+': istack[istackp-1]+=istack[istackp]; break;
                case '-': istack[istackp-1]-=istack[istackp]; break;
                case '*': istack[istackp-1]*=istack[istackp]; break;
                case '/': 
-                       if (!istack[istackp]) {
-                               fprintf(stderr,"Division of %d by zero not supported!\n",istack[istackp-1]);
-                               exit(EXIT_FAILURE);
-                               }
+                       if (!istack[istackp]) bail("Division of %d by zero not supported!\n",istack[istackp-1]);
                        istack[istackp-1]/=istack[istackp];
                        break;
                }
@@ -73,46 +90,36 @@ int mypri=oppri(op);
                evalit();
        if (!op) return;
        if (op==')') {
-               if (!opstackp || opstack[opstackp-1]!='(') {
-                       fprintf(stderr,"Not enough content for brackets-inside space!\n");
-                       exit(EXIT_FAILURE);
-                       }
+               if (!opstackp || opstack[opstackp-1]!='(')
+                       bail("Not enough content for brackets-inside space!\n");
                opstackp--;
                return;
                }
-       assert(opstackp<BUFSIZE);
+       if (opstackp>=BUFSIZE) bail("Too many operators (%d is max)!\n",BUFSIZE);
        opstack[opstackp++]=op;
 }
 
 static void process(void)
 {
-char lastop=0,op;
+char lastop,op;
 int curi;
 
        istackp=opstackp=0;
-       for (;;) switch ((op=lex(&curi))) {
+       for (lastop=0;;lastop=op) switch (op=lex(&curi)) {
                case 'n':
-                       if (lastop=='n') {
-                               fprintf(stderr,"Two successive numbers not permitted!\n");
-                               exit(EXIT_FAILURE);
-                               }
-                       assert(istackp<BUFSIZE);
+                       if (lastop=='n') bail("Two successive numbers not permitted!\n");
+                       if (istackp>=BUFSIZE) bail("Too many operators (%d is max)!\n",BUFSIZE);
                        istack[istackp++]=curi;
                        break;
                case '(':
-                       if (lastop=='n') {
-                               fprintf(stderr,"Open-bracket not permitted after number!\n");
-                               exit(EXIT_FAILURE);
-                               }
+                       if (lastop=='n') bail("Open-bracket not permitted after number!\n");
                        pushop(op);
                        break;
                case '+': case '-': case '*': case '/': case ')': pushop(op); break;
                case 0:
                        pushop(op);
-                       if (istackp!=1||opstackp) {
-                               fprintf(stderr,"Machine not in sane state on the end of expression, ints=%d,ops=%d!\n",istackp,opstackp);
-                               exit(EXIT_FAILURE);
-                               }
+                       if (istackp!=1||opstackp)
+                               bail("Machine not in sane state on the end of expression, ints=%d,ops=%d!\n",istackp,opstackp);
                        printf("%d\n",istack[0]);
                        return;
                default: assert(0);