diff options
-rw-r--r-- | 6/simp.c | 37 | ||||
-rw-r--r-- | lib/std/bigint.myr | 6 | ||||
-rw-r--r-- | mi/cfg.c | 5 | ||||
-rw-r--r-- | mi/match.c | 27 | ||||
-rw-r--r-- | mi/mi.h | 2 | ||||
-rwxr-xr-x | mk/bootstrap/bootstrap+Linux-x86_64.sh | 2 | ||||
-rw-r--r-- | test/matchargstr.myr | 3 |
7 files changed, 28 insertions, 54 deletions
@@ -656,37 +656,6 @@ static void matchpattern(Simp *s, Node *pat, Node *val, Type *t, Node *iftrue, N } } -void simpmatch(Simp *s, Node *n) -{ - Node *end, *cur, *next; /* labels */ - Node *val, *tmp; - Node *m; - size_t i; - - gensimpmatch(n); - end = genlbl(n->loc); - val = temp(s, n->matchstmt.val); - tmp = rval(s, n->matchstmt.val, val); - if (val != tmp) - append(s, assign(s, val, tmp)); - for (i = 0; i < n->matchstmt.nmatches; i++) { - m = n->matchstmt.matches[i]; - - /* check pattern */ - cur = genlbl(n->loc); - next = genlbl(n->loc); - matchpattern(s, m->match.pat, val, val->expr.type, cur, next); - - /* do the action if it matches */ - append(s, cur); - simp(s, m->match.block); - jmp(s, end); - append(s, next); - } - append(s, mkexpr(n->loc, Odead, NULL)); - append(s, end); -} - static void simpblk(Simp *s, Node *n) { size_t i; @@ -865,6 +834,7 @@ static Node *lval(Simp *s, Node *n) /* not actually expressible as lvalues in syntax, but we generate them */ case Oudata: r = rval(s, n, NULL); break; case Outag: r = rval(s, n, NULL); break; + case Otupget: r = rval(s, n, NULL); break; default: fatal(n, "%s cannot be an lvalue", opstr[exprop(n)]); break; @@ -1769,7 +1739,10 @@ static Node *simp(Simp *s, Node *n) case Nloopstmt: simploop(s, n); break; case Niterstmt: simpiter(s, n); break; case Nmatchstmt: /*simpmatch(s, n); break;*/ - simp(s, gensimpmatch(n)); + 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 Nexpr: if (islbl(n)) diff --git a/lib/std/bigint.myr b/lib/std/bigint.myr index 6116eca..a3f342a 100644 --- a/lib/std/bigint.myr +++ b/lib/std/bigint.myr @@ -295,10 +295,10 @@ const bigadd = {a, b else match bigcmp(a, b) | `Before: /* a is negative */ - a.sign = b.sign - -> usub(b, a) + a.sign = b.sign + -> usub(b, a) | `After: /* b is negative */ - -> usub(a, b) + -> usub(a, b) | `Equal: die("Impossible. Equal vals with different sign.") ;; @@ -65,11 +65,12 @@ static int addnode(Cfg *cfg, Bb *bb, Node *n) lappend(&cfg->fixjmp, &cfg->nfixjmp, n); lappend(&cfg->fixblk, &cfg->nfixblk, bb); return 1; - break; case Ocall: lappend(&bb->nl, &bb->nnl, n); return isnonretcall(n->expr.args[0]); - break; + case Odead: + lappend(&bb->nl, &bb->nnl, n); + return 1; default: lappend(&bb->nl, &bb->nnl, n); break; @@ -145,7 +145,7 @@ static Node *deadblock() { Node *blk, *dead; - blk = mkblock(Zloc, NULL); + blk = mkblock(Zloc, mkstab(0)); dead = mkexpr(Zloc, Odead, NULL); dead->expr.type = mktype(Zloc, Tyvoid); lappend(&blk->block.stmts, &blk->block.nstmts, dead); @@ -450,7 +450,7 @@ Node *addcapture(Dtree *dt, Node *n) return n; } -static Node *genmatch(Srcloc loc, Dtree *dt) +static Node *genmatch(Srcloc loc, Dtree *dt, Node *lastany) { Node *lastcmp, *cmp, *eq, *pat, *any; size_t i; @@ -459,11 +459,13 @@ static Node *genmatch(Srcloc loc, Dtree *dt) cmp = NULL; pat = NULL; /* we must have an action if this is a terminal leaf */ + if (dt->any && dt->any->act) + lastany = dt->any->act; 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); + cmp = mkifstmt(loc, eq, genmatch(loc, dt->sub[i], lastany), NULL); if (!pat) pat = cmp; if (!lastcmp) @@ -473,21 +475,24 @@ static Node *genmatch(Srcloc loc, Dtree *dt) lastcmp = cmp; } if (dt->any) { - any = genmatch(loc, dt->any); + any = genmatch(loc, dt->any, lastany); if (lastcmp) lastcmp->ifstmt.iffalse = any; else pat = any; + } else if (lastcmp) { + lastcmp->ifstmt.iffalse = lastany; } return pat; } -Node *gensimpmatch(Node *m) +/* val must be a pure, fully evaluated value */ +Node *gensimpmatch(Node *m, Node *val) { - Dtree *t, *leaf; Node **pat, **cap; size_t npat, ncap; + Dtree *t, *leaf; size_t i; Node *n; @@ -497,7 +502,7 @@ Node *gensimpmatch(Node *m) for (i = 0; i < npat; i++) { cap = NULL; ncap = 0; - leaf = addpat(t, pat[i]->match.pat, m->matchstmt.val, &cap, &ncap); + leaf = addpat(t, pat[i]->match.pat, val, &cap, &ncap); /* TODO: NULL is returned by unsupported patterns. */ if (!leaf) return NULL; @@ -509,14 +514,8 @@ 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); + n = genmatch(m->loc, t, deadblock()); assert(n->type == Nifstmt); - if (!n->ifstmt.iftrue) { - n->ifstmt.iftrue = deadblock(); - } - if (!n->ifstmt.iffalse) { - n->ifstmt.iffalse = deadblock(); - } return n; } @@ -48,4 +48,4 @@ void dumpcfg(Cfg *c, FILE *fd); void check(Cfg *cfg); /* pattern matching */ -Node *gensimpmatch(Node *m); +Node *gensimpmatch(Node *m, Node *val); diff --git a/mk/bootstrap/bootstrap+Linux-x86_64.sh b/mk/bootstrap/bootstrap+Linux-x86_64.sh index 7bfe573..7ce53ff 100755 --- a/mk/bootstrap/bootstrap+Linux-x86_64.sh +++ b/mk/bootstrap/bootstrap+Linux-x86_64.sh @@ -27,13 +27,13 @@ echo $pwd/6/6m -I ../sys -I . units.myr ; $pwd/6/6m -I ../sys -I . units.myr echo $pwd/6/6m -I ../sys -I . memops.myr ; $pwd/6/6m -I ../sys -I . memops.myr echo $pwd/6/6m -I ../sys -I . alloc.myr ; $pwd/6/6m -I ../sys -I . alloc.myr echo $pwd/6/6m -I ../sys -I . chartype.myr ; $pwd/6/6m -I ../sys -I . chartype.myr +echo $pwd/6/6m -I ../sys -I . utf.myr ; $pwd/6/6m -I ../sys -I . utf.myr echo $pwd/6/6m -I ../sys -I . cmp.myr ; $pwd/6/6m -I ../sys -I . cmp.myr echo $pwd/6/6m -I ../sys -I . hasprefix.myr ; $pwd/6/6m -I ../sys -I . hasprefix.myr echo $pwd/6/6m -I ../sys -I . slcp.myr ; $pwd/6/6m -I ../sys -I . slcp.myr echo $pwd/6/6m -I ../sys -I . sldup.myr ; $pwd/6/6m -I ../sys -I . sldup.myr echo $pwd/6/6m -I ../sys -I . slfill.myr ; $pwd/6/6m -I ../sys -I . slfill.myr echo $pwd/6/6m -I ../sys -I . slpush.myr ; $pwd/6/6m -I ../sys -I . slpush.myr -echo $pwd/6/6m -I ../sys -I . utf.myr ; $pwd/6/6m -I ../sys -I . utf.myr echo $pwd/6/6m -I ../sys -I . bigint.myr ; $pwd/6/6m -I ../sys -I . bigint.myr echo $pwd/6/6m -I ../sys -I . fltbits.myr ; $pwd/6/6m -I ../sys -I . fltbits.myr echo $pwd/6/6m -I ../sys -I . strbuf.myr ; $pwd/6/6m -I ../sys -I . strbuf.myr diff --git a/test/matchargstr.myr b/test/matchargstr.myr index 0d8cf4e..527082d 100644 --- a/test/matchargstr.myr +++ b/test/matchargstr.myr @@ -14,7 +14,8 @@ const main = { match v | `Int 127: std.fatal("wrong match `Int 127\n") | `Str "foo": std.fatal("Wrong match `Str \"foo\"\n") - | `Str "fsda": std.fatal("Wrong match `Str \"fsda\"\n") + /* make sure we backtrack for the test */ + | `Str "asfd": std.fatal("Wrong match `Str \"fsda\"\n") | `Str "asdf": std.put("Correct `Str \"asdf\"!\n") | `Nil: std.fatal("Wrong match `Str \"fsda\"\n") | _: std.fatal("Impossible failed match\n") |