ref: 7f04fcc98b500a390d5b89ca766982afa6feb168
parent: 39562e06a87e2068d9dcd788201a2b7a6efdb7b2
author: Ori Bernstein <[email protected]>
date: Wed Oct 21 17:09:47 EDT 2015
Fix decision trees for structs.
--- a/6/simp.c
+++ b/6/simp.c
@@ -655,7 +655,7 @@
}
}
-static void simpmatch(Simp *s, Node *n)
+void simpmatch(Simp *s, Node *n)
{
Node *end, *cur, *next; /* labels */
Node *val, *tmp;
@@ -1218,13 +1218,14 @@
static Node *simpuget(Simp *s, Node *n, Node *dst)
{
- Node *u, *p;
+ Node *u, *p, *l;
if (!dst)
dst = temp(s, n);
- u = n->expr.args[0];
+ u = rval(s, n->expr.args[0], NULL);
p = addk(addr(s, u, exprtype(n)), Wordsz);
- assign(s, dst, load(p));
+ l = assign(s, dst, load(p));
+ append(s, l);
return dst;
}
@@ -1710,9 +1711,10 @@
r = compare(s, n, 0);
break;
case Otupget:
- assert(exprop(args[0]) == Olit);
- i = args[0]->expr.args[0]->lit.intval;
+ assert(exprop(args[1]) == Olit);
+ i = args[1]->expr.args[0]->lit.intval;
r = tupget(s, args[0], i, dst);
+ break;
case Obad:
die("bad operator");
break;
--- a/mbldwrap.sh
+++ b/mbldwrap.sh
@@ -16,9 +16,9 @@
BOOT="./mk/bootstrap/bootstrap+`uname -s`-`uname -m`.sh"
fi
-if [ -z "$@" ]; then
- mbld || ./mbld/mbld || $BOOT
-else
- mbld $@ || ./mbld/mbld $@ || \
+if [ -f mbld/mbld ]; then
+ ./mbld/mbld $@ || mbld $@ || \
(echo "Unable to run mbld $@; have you build successfully"; false)
+else
+ ./mbld/mbld || mbld || $BOOT
fi
--- a/mi/match.c
+++ b/mi/match.c
@@ -143,12 +143,17 @@
static Dtree *addwild(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
{
+ Node *asn;
+
if (t->any)
return t->any;
t->any = mkdtree();
t->any->patexpr = pat;
- if (cap && ncap)
- lappend(cap, ncap, pat);
+ if (cap && ncap) {
+ asn = mkexpr(pat->loc, Oasn, pat, val, NULL);
+ asn->expr.type = exprtype(pat);
+ lappend(cap, ncap, asn);
+ }
return t->any;
}
@@ -248,22 +253,33 @@
static Dtree *addstruct(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
{
- Node *elt, *memb;
- Type *ty;
+ Node *membpat, *membval, *name;
+ char *patname, *membname;
size_t i, j;
+ int found;
+ Type *ty;
if (t->any)
return t->any;
- for (i = 0; i < pat->expr.nargs; i++) {
- elt = pat->expr.args[i];
- for (j = 0; j < t->nval; j++) {
- if (!strcmp(namestr(elt->expr.idx), namestr(t->val[j]->expr.idx))) {
- ty = exprtype(pat->expr.args[i]);
- memb = structmemb(val, elt->expr.idx, ty);
- t = addpat(t, pat->expr.args[i], memb, cap, ncap);
- break;
- }
+ ty = tybase(exprtype(pat));
+ for (i = 0; i < ty->nmemb; i++) {
+ found = 0;
+ name = ty->sdecls[i]->decl.name;
+ membval = structmemb(val, name, decltype(ty->sdecls[i]));
+ for (j = 0; j < pat->expr.nargs; j++) {
+ membpat = pat->expr.args[j];
+ patname = namestr(membpat->expr.idx);
+ membname = namestr(ty->sdecls[i]->decl.name);
+ if (strcmp(patname, membname) != 0)
+ continue;
+ found = 1;
+ t = addpat(t, membpat, membval, cap, ncap);
}
+ if (!found) {
+ membpat = mkexpr(pat->loc, Ogap, NULL);
+ membpat->expr.type = decltype(ty->sdecls[i]);
+ t = addpat(t, membpat, membval, cap, ncap);
+ }
}
return t;
}
@@ -373,29 +389,57 @@
return 1;
}
+Node *addcapture(Dtree *dt, Node *n)
+{
+ Node **blk;
+ size_t nblk, i;
+
+ nblk = 0;
+ blk = NULL;
+
+ /*
+ Disabled until we have all of this code working.
+ for (i = 0; i < dt->ncap; i++)
+ lappend(&blk, &nblk, dt->cap[i]);
+ */
+ for (i = 0; i < n->block.nstmts; i++)
+ lappend(&blk, &nblk, n->block.stmts[i]);
+ lfree(&n->block.stmts, &n->block.nstmts);
+ n->block.stmts = blk;
+ n->block.nstmts = nblk;
+ return n;
+}
+
static Node *genmatch(Srcloc loc, Dtree *dt)
{
- Node *lastcmp, *cmp, *eq, *pat;
+ Node *lastcmp, *cmp, *eq, *pat, *any;
size_t i;
lastcmp = NULL;
cmp = NULL;
pat = NULL;
- if (dt->nsub == 0)
- return dt->act;
+ /* we must have an action if this is a terminal leaf */
+ if (dt->nsub == 0 && !dt->any)
+ return addcapture(dt, dt->act);
for (i = 0; i < dt->nsub; i++) {
eq = mkexpr(loc, Oeq, dt->load[i], dt->val[i], NULL);
cmp = mkifstmt(loc, eq, genmatch(loc, dt->sub[i]), NULL);
if (!pat)
pat = cmp;
- if (lastcmp)
- lastcmp->ifstmt.iffalse = cmp;
- else
+ if (!lastcmp)
lastcmp = cmp;
+ else
+ lastcmp->ifstmt.iffalse = cmp;
lastcmp = cmp;
}
- if (dt->any)
- lastcmp->ifstmt.iffalse = genmatch(loc, dt->any);
+ if (dt->any) {
+ any = genmatch(loc, dt->any);
+ if (lastcmp)
+ lastcmp->ifstmt.iffalse = any;
+ else
+ pat = any;
+ }
+
return pat;
}
@@ -446,6 +490,8 @@
return "struct";
case Ogap:
return "_";
+ case Oasn:
+ return dtnodestr(n->expr.args[0]);
default:
die("Invalid pattern in exhaustivenes check. BUG.");
break;