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