summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2016-01-20 22:02:21 -0800
committerOri Bernstein <ori@eigenstate.org>2016-01-20 22:26:18 -0800
commitc694d9a9c3f8c78837cf3bcbbe11fb19d04c204d (patch)
tree0f3c4d88df4e929d9c9fba5ff7646ec3fb056518
parentd91d1e446ded81fba2452731ed40fec6e9a3be30 (diff)
downloadmc-c694d9a9c3f8c78837cf3bcbbe11fb19d04c204d.tar.gz
Put labels into scopes.
-rw-r--r--lib/std/slurp.myr5
-rw-r--r--parse/infer.c43
-rw-r--r--parse/parse.h3
-rw-r--r--parse/stab.c24
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;