shithub: mc

Download patch

ref: 6ceec6218bd3d7040758c09233c07d2afcdb2cbe
parent: afbbc54292c6e52787461058786c80009723a24c
author: Ori Bernstein <[email protected]>
date: Fri Jun 29 11:38:09 EDT 2012

Compile matches on literal values.

--- a/8/simp.c
+++ b/8/simp.c
@@ -358,6 +358,33 @@
     simp(s, lend);              /* exit */
 }
 
+static void simpmatch(Simp *s, Node *n)
+{
+    Node *end, *cur, *next; /* labels */
+    Node *val, *cond; /* intermediates */
+    Node *m;
+    size_t i;
+
+    end = genlbl();
+    val = rval(s, n->matchstmt.val); /* FIXME: don't recompute, even if pure */
+    for (i = 0; i < n->matchstmt.nmatches; i++) {
+        m = n->matchstmt.matches[i];
+
+        if (exprop(m->match.pat) != Olit)
+            die("Unsupported non-lit pat");
+        cond = mkexpr(m->line, Oeq, val, m->match.pat, NULL);
+
+        cur = genlbl();
+        next = genlbl();
+        cjmp(s, cond, cur, next);
+        append(s, cur);
+        simp(s, m->match.block);
+        jmp(s, end);
+        append(s, next);
+    }
+    append(s, end);
+}
+
 static void simpblk(Simp *s, Node *n)
 {
     size_t i;
@@ -801,15 +828,12 @@
         return NULL;
     r = NULL;
     switch (n->type) {
-        case Nblock:
-            simpblk(s, n);
-            break;
-        case Nifstmt:
-            simpif(s, n);
-            break;
-        case Nloopstmt:
-            simploop(s, n);
-            break;
+        case Nlit:       r = n;                 break;
+        case Nlbl:       append(s, n);          break;
+        case Nblock:     simpblk(s, n);         break;
+        case Nifstmt:    simpif(s, n);          break;
+        case Nloopstmt:  simploop(s, n);        break;
+        case Nmatchstmt: simpmatch(s, n);       break;
         case Nexpr:
             r = rval(s, n);
             if (r)
@@ -819,9 +843,7 @@
                 append(s, s->incqueue[i]);
             lfree(&s->incqueue, &s->nqueue);
             break;
-        case Nlit:
-            r = n;
-            break;
+
         case Ndecl:
             declarelocal(s, n);
             if (n->decl.init) {
@@ -832,9 +854,6 @@
                 t->expr.did = n->decl.did;
                 simp(s, u);
             }
-            break;
-        case Nlbl:
-            append(s, n);
             break;
         default:
             die("Bad node passsed to simp()");
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -577,7 +577,7 @@
         | Tendln {$$ = NULL;}
         ;
 
-pat     : literal {$$ = $1;}
+pat     : literal {$$ = mkexpr($1->line, Olit, $1, NULL);}
         ;
 
 block   : blockbody Tendblk