diff options
author | Ori Bernstein <ori@eigenstate.org> | 2015-10-21 23:11:41 -0700 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2015-11-06 00:38:56 -0800 |
commit | 26e54d3c7cbaab5efa5e63a32b87b49328fd5f6b (patch) | |
tree | 9059ca3618cafeda101f73a402a32763b4b75127 /mi | |
parent | 7f04fcc98b500a390d5b89ca766982afa6feb168 (diff) | |
download | mc-26e54d3c7cbaab5efa5e63a32b87b49328fd5f6b.tar.gz |
Pass the basic tests. we still fail complex ones.
Diffstat (limited to 'mi')
-rw-r--r-- | mi/match.c | 75 |
1 files changed, 61 insertions, 14 deletions
@@ -141,6 +141,17 @@ static Node *uvalue(Node *n, Type *ty) return elt; } +static Node *deadblock() +{ + Node *blk, *dead; + + blk = mkblock(Zloc, NULL); + dead = mkexpr(Zloc, Odead, NULL); + dead->expr.type = mktype(Zloc, Tyvoid); + lappend(&blk->block.stmts, &blk->block.nstmts, dead); + return blk; +} + static Dtree *addwild(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap) { Node *asn; @@ -203,23 +214,55 @@ static Dtree *addunion(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap return sub; } +static Dtree *addstr(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap) +{ + Node *p, *v, *lit; + size_t i, n; + Type *ty; + char *s; + + lit = pat->expr.args[0]; + n = lit->lit.strval.len; + s = lit->lit.strval.buf; + + ty = mktype(pat->loc, Tyuint64); + p = mkintlit(lit->loc, n); + v = structmemb(val, mkname(pat->loc, "len"), ty); + p->expr.type = ty; + + t = addpat(t, p, v, cap, ncap); + + ty = mktype(pat->loc, Tybyte); + for (i = 0; i < n; i++) { + p = mkintlit(lit->loc, s[i]); + p->expr.type = ty; + v = arrayelt(val, i); + t = addpat(t, p, v, cap, ncap); + } + return t; +} + static Dtree *addlit(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap) { Dtree *sub; size_t i; - if (t->any) - return t->any; - for (i = 0; i < t->nval; i++) { - if (liteq(t->val[i]->expr.args[0], pat->expr.args[0])) - return t->sub[i]; - } + if (pat->expr.args[0]->lit.littype == Lstr) { + sub = addstr(t, pat, val, cap, ncap); + } else { + if (t->any) + return t->any; + for (i = 0; i < t->nval; i++) { + if (liteq(t->val[i]->expr.args[0], pat->expr.args[0])) + return t->sub[i]; + } - sub = mkdtree(); - sub->patexpr = pat; - lappend(&t->val, &t->nval, pat); - lappend(&t->load, &t->nload, val); - lappend(&t->sub, &t->nsub, sub); + sub = mkdtree(); + sub->patexpr = pat; + lappend(&t->val, &t->nval, pat); + lappend(&t->load, &t->nload, val); + lappend(&t->sub, &t->nsub, sub); + } return sub; } @@ -397,11 +440,8 @@ Node *addcapture(Dtree *dt, Node *n) 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); @@ -470,6 +510,13 @@ Node *gensimpmatch(Node *m) if (!exhaustivematch(m, t, exprtype(m->matchstmt.val))) fatal(m, "nonexhaustive pattern set in match statement"); n = genmatch(m->loc, t); + assert(n->type == Nifstmt); + if (!n->ifstmt.iftrue) { + n->ifstmt.iftrue = deadblock(); + } + if (!n->ifstmt.iffalse) { + n->ifstmt.iffalse = deadblock(); + } return n; } |