summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--6/asm.h2
-rw-r--r--6/gen.c12
-rw-r--r--6/locs.c8
-rw-r--r--6/simp.c42
-rw-r--r--mi/match.c8
-rw-r--r--mi/mi.h2
-rw-r--r--parse/node.c33
-rw-r--r--parse/parse.h2
8 files changed, 67 insertions, 42 deletions
diff --git a/6/asm.h b/6/asm.h
index dde50a6..ceb720a 100644
--- a/6/asm.h
+++ b/6/asm.h
@@ -269,10 +269,8 @@ extern size_t maxregid;
extern Loc **locmap; /* mapping from reg id => Loc * */
char *genlocallblstr(char *buf, size_t sz);
-char *genlblstr(char *buf, size_t sz);
Type *codetype(Type *ft);
Type *closuretype(Type *ft);
-Node *genlbl(Srcloc loc);
Loc *loclbl(Node *lbl);
Loc *locstrlbl(char *lbl);
Loc *locreg(Mode m);
diff --git a/6/gen.c b/6/gen.c
index a17d6f7..5290e6d 100644
--- a/6/gen.c
+++ b/6/gen.c
@@ -75,20 +75,12 @@ static int islocal(Node *dcl)
return 1;
}
-static int nextlbl;
char *genlocallblstr(char *buf, size_t sz)
{
if (asmsyntax == Plan9)
- bprintf(buf, 128, ".L%d<>", nextlbl++);
+ return genlblstr(buf, 128, "<>");
else
- bprintf(buf, 128, ".L%d", nextlbl++);
- return buf;
-}
-
-char *genlblstr(char *buf, size_t sz)
-{
- bprintf(buf, 128, ".L%d", nextlbl++);
- return buf;
+ return genlblstr(buf, 128, "");
}
int isconstfn(Node *n)
diff --git a/6/locs.c b/6/locs.c
index efb938d..ba5dbd0 100644
--- a/6/locs.c
+++ b/6/locs.c
@@ -31,14 +31,6 @@ int isfloatmode(Mode m)
return m == ModeF || m == ModeD;
}
-Node *genlbl(Srcloc loc)
-{
- char buf[128];
-
- genlblstr(buf, 128);
- return mklbl(loc, buf);
-}
-
Loc *locstrlbl(char *lbl)
{
Loc *l;
diff --git a/6/simp.c b/6/simp.c
index 3f4daf6..f206bca 100644
--- a/6/simp.c
+++ b/6/simp.c
@@ -285,7 +285,7 @@ static Node *word(Srcloc loc, uint v)
return n;
}
-static Node *gentemp(Simp *simp, Srcloc loc, Type *ty, Node **dcl)
+static Node *gentemp(Srcloc loc, Type *ty, Node **dcl)
{
char buf[128];
static int nexttmp;
@@ -307,7 +307,7 @@ static Node *temp(Simp *simp, Node *e)
Node *t, *dcl;
assert(e->type == Nexpr);
- t = gentemp(simp, e->loc, e->expr.type, &dcl);
+ t = gentemp(e->loc, e->expr.type, &dcl);
if (stacknode(e))
declarelocal(simp, dcl);
return t;
@@ -479,7 +479,7 @@ static void simpiter(Simp *s, Node *n)
zero->expr.type = tyintptr;
seq = rval(s, n->iterstmt.seq, NULL);
- idx = gentemp(s, n->loc, tyintptr, &dcl);
+ idx = gentemp(n->loc, tyintptr, &dcl);
declarelocal(s, dcl);
/* setup */
@@ -671,7 +671,7 @@ static Node *geninitdecl(Node *init, Type *ty, Node **dcl)
Node *n, *d, *r;
char lbl[128];
- n = mkname(init->loc, genlblstr(lbl, 128));
+ n = mkname(init->loc, genlblstr(lbl, 128, ""));
d = mkdecl(init->loc, n, ty);
r = mkexpr(init->loc, Ovar, n, NULL);
@@ -1040,7 +1040,7 @@ static Node *tupget(Simp *s, Node *tup, size_t idx, Node *dst)
}
if (!dst) {
- dst = gentemp(s, tup->loc, ty->sub[idx], &dcl);
+ dst = gentemp(tup->loc, ty->sub[idx], &dcl);
if (isstacktype(ty->sub[idx]))
declarelocal(s, dcl);
}
@@ -1341,7 +1341,7 @@ static Node *capture(Simp *s, Node *n, Node *dst)
fn = n->expr.args[0];
fn = fn->lit.fnval;
if (!dst) {
- dst = gentemp(s, n->loc, closuretype(exprtype(f)), &dcl);
+ dst = gentemp(n->loc, closuretype(exprtype(f)), &dcl);
forcelocal(s, dcl);
}
fp = addr(s, dst, exprtype(dst));
@@ -1361,7 +1361,7 @@ static Node *capture(Simp *s, Node *n, Node *dst)
for (i = 0; i < nenv; i++)
lappend(&envt, &nenvt, decltype(env[i]));
- t = gentemp(s, n->loc, mktytuple(n->loc, envt, nenvt), &dcl);
+ t = gentemp(n->loc, mktytuple(n->loc, envt, nenvt), &dcl);
forcelocal(s, dcl);
e = addr(s, t, exprtype(t));
@@ -1725,6 +1725,23 @@ static int islbl(Node *n)
return l->type == Nlit && l->lit.littype == Llbl;
}
+static void simpmatch(Simp *s, Node *n)
+{
+ Node *val, *tmp;
+ Node **match;
+ size_t i, nmatch;
+
+ tmp = temp(s, n->matchstmt.val);
+ val = rval(s, n->matchstmt.val, tmp);
+ append(s, assign(s, tmp, val));
+
+ match = NULL;
+ nmatch = 0;
+ gensimpmatch(n, tmp, &match, &nmatch);
+ for (i = 0; i < nmatch; i++)
+ simp(s, match[i]);
+}
+
static Node *simp(Simp *s, Node *n)
{
Node *r, *t, *u;
@@ -1738,12 +1755,7 @@ static Node *simp(Simp *s, Node *n)
case Nifstmt: simpif(s, n, NULL); break;
case Nloopstmt: simploop(s, n); break;
case Niterstmt: simpiter(s, n); break;
- case Nmatchstmt: /*simpmatch(s, n); break;*/
- t = temp(s, n->matchstmt.val);
- u = rval(s, n->matchstmt.val, t);
- append(s, assign(s, t, u));
- simp(s, gensimpmatch(n, t));
- break;
+ case Nmatchstmt: simpmatch(s, n); break;
case Nexpr:
if (islbl(n))
append(s, n);
@@ -1797,11 +1809,11 @@ static void flatten(Simp *s, Node *f)
ty = f->func.type->sub[0];
if (isstacktype(ty)) {
s->isbigret = 1;
- s->ret = gentemp(s, f->loc, mktyptr(f->loc, ty), &dcl);
+ s->ret = gentemp(f->loc, mktyptr(f->loc, ty), &dcl);
declarearg(s, dcl);
} else if (ty->type != Tyvoid) {
s->isbigret = 0;
- s->ret = gentemp(s, f->loc, ty, &dcl);
+ s->ret = gentemp(f->loc, ty, &dcl);
}
for (i = 0; i < f->func.nargs; i++) {
diff --git a/mi/match.c b/mi/match.c
index 6fda431..a2bb271 100644
--- a/mi/match.c
+++ b/mi/match.c
@@ -490,7 +490,7 @@ static Node *genmatch(Srcloc loc, Dtree *dt, Node *lastany)
}
/* val must be a pure, fully evaluated value */
-Node *gensimpmatch(Node *m, Node *val)
+void gensimpmatch(Node *m, Node *val, Node ***out, size_t *nout)
{
Node **pat, **cap;
size_t npat, ncap;
@@ -505,9 +505,6 @@ Node *gensimpmatch(Node *m, Node *val)
cap = NULL;
ncap = 0;
leaf = addpat(t, pat[i]->match.pat, val, &cap, &ncap);
- /* TODO: NULL is returned by unsupported patterns. */
- if (!leaf)
- return NULL;
if (leaf->act)
fatal(pat[i], "pattern matched by earlier case on line %d", leaf->act->loc.line);
leaf->act = pat[i]->match.block;
@@ -517,8 +514,7 @@ Node *gensimpmatch(Node *m, Node *val)
if (!exhaustivematch(m, t, exprtype(m->matchstmt.val)))
fatal(m, "nonexhaustive pattern set in match statement");
n = genmatch(m->loc, t, deadblock());
- assert(n->type == Nifstmt);
- return n;
+ lappend(out, nout, n);
}
char *dtnodestr(Node *n)
diff --git a/mi/mi.h b/mi/mi.h
index 8b92a9d..a29619a 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -48,4 +48,4 @@ void dumpcfg(Cfg *c, FILE *fd);
void check(Cfg *cfg);
/* pattern matching */
-Node *gensimpmatch(Node *m, Node *val);
+void gensimpmatch(Node *m, Node *val, Node ***out, size_t *nout);
diff --git a/parse/node.c b/parse/node.c
index c3522cb..eb613ff 100644
--- a/parse/node.c
+++ b/parse/node.c
@@ -245,6 +245,22 @@ Node *mklbl(Srcloc loc, char *lbl)
return mkexpr(loc, Olit, n, NULL);
}
+char *genlblstr(char *buf, size_t sz, char *suffix)
+{
+ static int nextlbl;
+ bprintf(buf, 128, ".L%d%s", nextlbl++, suffix);
+ return buf;
+}
+
+Node *genlbl(Srcloc loc)
+{
+ char buf[128];
+
+ genlblstr(buf, 128, "");
+ return mklbl(loc, buf);
+}
+
+
Node *mkstr(Srcloc loc, Str val)
{
Node *n;
@@ -330,6 +346,23 @@ Node *mkdecl(Srcloc loc, Node *name, Type *ty)
return n;
}
+Node *gentemp(Srcloc loc, Type *ty, Node **dcl)
+{
+ char buf[128];
+ static int nexttmp;
+ Node *t, *r, *n;
+
+ bprintf(buf, 128, ".t%d", nexttmp++);
+ n = mkname(loc, buf);
+ t = mkdecl(loc, n, ty);
+ r = mkexpr(loc, Ovar, n, NULL);
+ r->expr.type = t->decl.type;
+ r->expr.did = t->decl.did;
+ if (dcl)
+ *dcl = t;
+ return r;
+}
+
Ucon *mkucon(Srcloc loc, Node *name, Type *ut, Type *et)
{
Ucon *uc;
diff --git a/parse/parse.h b/parse/parse.h
index 1d8086e..859641c 100644
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -569,6 +569,8 @@ Node *mkname(Srcloc l, char *name);
Node *mknsname(Srcloc l, char *ns, char *name);
Node *mkdecl(Srcloc l, Node *name, Type *ty);
Node *mklbl(Srcloc l, char *lbl);
+Node *genlbl(Srcloc loc);
+char *genlblstr(char *buf, size_t sz, char *suffix);
Node *mkslice(Srcloc l, Node *base, Node *off);
Ucon *mkucon(Srcloc l, Node *name, Type *ut, Type *uet);