diff options
author | Ori Bernstein <ori@eigenstate.org> | 2016-01-20 22:02:21 -0800 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2016-01-20 22:26:18 -0800 |
commit | c694d9a9c3f8c78837cf3bcbbe11fb19d04c204d (patch) | |
tree | 0f3c4d88df4e929d9c9fba5ff7646ec3fb056518 | |
parent | d91d1e446ded81fba2452731ed40fec6e9a3be30 (diff) | |
download | mc-c694d9a9c3f8c78837cf3bcbbe11fb19d04c204d.tar.gz |
Put labels into scopes.
-rw-r--r-- | lib/std/slurp.myr | 5 | ||||
-rw-r--r-- | parse/infer.c | 43 | ||||
-rw-r--r-- | parse/parse.h | 3 | ||||
-rw-r--r-- | parse/stab.c | 24 |
4 files changed, 52 insertions, 23 deletions
diff --git a/lib/std/slurp.myr b/lib/std/slurp.myr index 534baf9..576c39e 100644 --- a/lib/std/slurp.myr +++ b/lib/std/slurp.myr @@ -33,10 +33,9 @@ const fslurp = {fd buf = slalloc(bufsz) while true match read(fd, buf[len:]) + | `Ok 0: + -> `Ok buf[:len] | `Ok n: - if n == 0 - -> `Ok buf[:len] - ;; len += n bufsz *= 2 buf = slgrow(buf, bufsz) diff --git a/parse/infer.c b/parse/infer.c index 082315cb..4cbeab1 100644 --- a/parse/infer.c +++ b/parse/infer.c @@ -1400,27 +1400,27 @@ static void inferexpr(Inferstate *st, Node **np, Type *ret, int *sawret) n->expr.isconst = isconst; settype(st, n, t); break; - case Omod: /* @a % @a -> @a */ - case Obor: /* @a | @a -> @a */ + case Omod: /* @a % @a -> @a */ + case Obor: /* @a | @a -> @a */ case Oband: /* @a & @a -> @a */ case Obxor: /* @a ^ @a -> @a */ - case Obsl: /* @a << @a -> @a */ - case Obsr: /* @a >> @a -> @a */ + case Obsl: /* @a << @a -> @a */ + case Obsr: /* @a >> @a -> @a */ case Obnot: /* ~@a -> @a */ - case Opreinc: /* ++@a -> @a */ - case Opredec: /* --@a -> @a */ - case Opostinc: /* @a++ -> @a */ - case Opostdec: /* @a-- -> @a */ - case Oaddeq: /* @a += @a -> @a */ - case Osubeq: /* @a -= @a -> @a */ - case Omuleq: /* @a *= @a -> @a */ - case Odiveq: /* @a /= @a -> @a */ - case Omodeq: /* @a %= @a -> @a */ - case Oboreq: /* @a |= @a -> @a */ - case Obandeq: /* @a &= @a -> @a */ - case Obxoreq: /* @a ^= @a -> @a */ - case Obsleq: /* @a <<= @a -> @a */ - case Obsreq: /* @a >>= @a -> @a */ + case Opreinc: /* ++@a -> @a */ + case Opredec: /* --@a -> @a */ + case Opostinc: /* @a++ -> @a */ + case Opostdec: /* @a-- -> @a */ + case Oaddeq: /* @a += @a -> @a */ + case Osubeq: /* @a -= @a -> @a */ + case Omuleq: /* @a *= @a -> @a */ + case Odiveq: /* @a /= @a -> @a */ + case Omodeq: /* @a %= @a -> @a */ + case Oboreq: /* @a |= @a -> @a */ + case Obandeq: /* @a &= @a -> @a */ + case Obxoreq: /* @a ^= @a -> @a */ + case Obsleq: /* @a <<= @a -> @a */ + case Obsreq: /* @a >>= @a -> @a */ infersub(st, n, ret, sawret, &isconst); t = type(st, args[0]); constrain(st, n, type(st, args[0]), traittab[Tcnum]); @@ -1529,6 +1529,8 @@ static void inferexpr(Inferstate *st, Node **np, Type *ret, int *sawret) settype(st, n, mktype(Zloc, Tyvoid)); break; case Ojmp: /* goto void* -> void */ + if (args[0]->type == Nlit && args[0]->lit.littype == Llbl) + args[0] = getlbl(curstab(), args[0]->loc, args[0]->lit.lblval); infersub(st, n, ret, sawret, &isconst); settype(st, n, mktype(Zloc, Tyvoid)); break; @@ -1860,8 +1862,11 @@ static void infernode(Inferstate *st, Node **np, Type *ret, int *sawret) case Nimpl: specializeimpl(st, n); break; - case Nname: case Nlit: + if (n->lit.littype == Llbl) + putlbl(curstab(), n->lit.lblval, n); + break; + case Nname: case Nuse: break; case Nnone: diff --git a/parse/parse.h b/parse/parse.h index 46b2687..9d9c39a 100644 --- a/parse/parse.h +++ b/parse/parse.h @@ -140,6 +140,7 @@ struct Stab { Htab *ty; /* types */ Htab *tr; /* traits */ Htab *uc; /* union constructors */ + Htab *lbl; /* labels */ Htab *impl; /* trait implementations: really a set of implemented traits. */ }; @@ -494,6 +495,7 @@ void updatetype(Stab *st, Node *n, Type *t); void putdcl(Stab *st, Node *dcl); void forcedcl(Stab *st, Node *dcl); void putucon(Stab *st, Ucon *uc); +void putlbl(Stab *st, char *name, Node *lbl); Stab *getns(Node *file, char *n); Node *getdcl(Stab *st, Node *n); @@ -504,6 +506,7 @@ Type *gettype(Stab *st, Node *n); Node *getimpl(Stab *st, Node *impl); Trait *gettrait(Stab *st, Node *n); Ucon *getucon(Stab *st, Node *n); +Node *getlbl(Stab *st, Srcloc loc, char *name); Stab *curstab(void); void pushstab(Stab *st); diff --git a/parse/stab.c b/parse/stab.c index 5b5512d..9da49dc 100644 --- a/parse/stab.c +++ b/parse/stab.c @@ -109,8 +109,10 @@ Stab *mkstab(int isfunc) st->ty = mkht(nsnamehash, nsnameeq); st->tr = mkht(nsnamehash, nsnameeq); st->uc = mkht(nsnamehash, nsnameeq); - if (isfunc) + if (isfunc) { st->env = mkht(nsnamehash, nsnameeq); + st->lbl = mkht(strhash, streq); + } st->impl = mkht(implhash, impleq); return st; } @@ -178,6 +180,26 @@ Node *getdcl(Stab *st, Node *n) return NULL; } +void putlbl(Stab *st, char *name, Node *lbl) +{ + while (!st->isfunc && st->super) + st = st->super; + if (!st) + fatal(lbl, "label %s defined outside function\n", name); + if (hthas(st->lbl, name)) + fatal(lbl, "duplicate label %s, first defined on line %d\n", name, lbl->loc.line); + htput(st->lbl, name, lbl); +} + +Node *getlbl(Stab *st, Srcloc loc, char *name) +{ + while (!st->isfunc && st->super) + st = st->super; + if (!st || !hthas(st->lbl, name)) + lfatal(loc, "unable to find label %s in function scope\n", name); + return htget(st->lbl, name); +} + Type *gettype_l(Stab *st, Node *n) { Tydefn *t; |