shithub: mc

Download patch

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)