ref: c694d9a9c3f8c78837cf3bcbbe11fb19d04c204d
parent: d91d1e446ded81fba2452731ed40fec6e9a3be30
author: Ori Bernstein <[email protected]>
date: Wed Jan 20 17:02:21 EST 2016
Put labels into scopes.
--- a/lib/std/slurp.myr
+++ b/lib/std/slurp.myr
@@ -33,10 +33,9 @@
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)
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1400,27 +1400,27 @@
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 @@
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 @@
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:
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -140,6 +140,7 @@
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 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 @@
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);
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -109,8 +109,10 @@
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;
}
@@ -176,6 +178,26 @@
st = st->super;
} while (st);
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)