shithub: mc

Download patch

ref: c5245eaa80064b77186fa286f8e5e8bca73309ab
parent: 0087d35b4f6393aa46c5ac757f77c5087f2add19
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Jul 26 21:11:33 EDT 2017

std.change std.name std.lookup std.rules.

	std.no std.on std.every std.name std.you std.use.

	The rules for an un-namespaced name now are as follows:

		1) Attempt to look up a name in the current file.
		2) Check all namespaces for a unique name. If the
		   name is not globally unique, give an error.

--- a/mk/c.mk
+++ b/mk/c.mk
@@ -9,7 +9,7 @@
 _LIBPATHS=$(addprefix -l, $(patsubst lib%.a,%,$(notdir $(DEPS)))) $(_PCLIBS)
 
 # yeah, I should probably remove -Werror, but it's nice for developing alone.
-CFLAGS += -Wall -Werror -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-char-subscripts -g -O3
+CFLAGS += -Wall -Werror -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-char-subscripts -g -O0
 CFLAGS += -MMD -MP -MF .deps/$(subst /,-,$*).d
 
 LIB ?= $(INSTLIB)
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1355,7 +1355,7 @@
 		ns = curstab();
 		if (args[0]->name.ns)
 			ns = getns(file, args[0]->name.ns);
-		s = getdcl(ns, args[0]);
+		s = getnsdcl(ns, args[0]);
 		if (s && !s->decl.ishidden) {
 			if (s->decl.isgeneric)
 				t = tysubst(s->decl.type, s->decl.type);
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -90,13 +90,14 @@
 	char *name;
 	char isfunc;
 
-	/* Contents of stab.
-	 * types and values are in separate namespaces. */
-	Htab *dcl;
-	Htab *env;	/* the syms we close over, if we're a function */
+	/* symbols */
+	Htab *dcl;	/* decls */
 	Htab *ty;	/* types */
 	Htab *tr;	/* traits */
 	Htab *uc;	/* union constructors */
+
+	/* not quite symbols */
+	Htab *env;	/* the syms closed over, if this is a function stab */
 	Htab *lbl;	/* labels */
 	Htab *impl;	/* trait implementations: really a set of implemented traits. */
 };
@@ -396,15 +397,16 @@
 void putucon(Stab *st, Ucon *uc);
 void putlbl(Stab *st, char *name, Node *lbl);
 
-Stab *getns(Node *file, char *n);
+void *getnsdcl(Stab *st, Node *n);
 Node *getdcl(Stab *st, Node *n);
-Node *getclosed(Stab *st, Node *n);
-Node **getclosure(Stab *st, size_t *n);
-Type *gettype_l(Stab *st, Node *n);
 Type *gettype(Stab *st, Node *n);
-Node *getimpl(Stab *st, Node *impl);
 Trait *gettrait(Stab *st, Node *n);
 Ucon *getucon(Stab *st, Node *n);
+
+Stab *getns(Node *file, char *n);
+Node *getclosed(Stab *st, Node *n);
+Node **getclosure(Stab *st, size_t *n);
+Node *getimpl(Stab *st, Node *impl);
 Node *getlbl(Stab *st, Srcloc loc, char *name);
 
 Stab *curstab(void);
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -16,6 +16,7 @@
 /* Allows us to look up types/traits by name nodes */
 typedef struct Tydefn Tydefn;
 typedef struct Traitdefn Traitdefn;
+
 struct Tydefn {
 	Srcloc loc;
 	Node *name;
@@ -213,28 +214,7 @@
  * not in the current scope, it is recorded
  * in the scope's closure.
  */
-Node *
-getdcl(Stab *st, Node *n)
-{
-	Node *s;
-	Stab *fn;
 
-	fn = NULL;
-	do {
-		s = htget(st->dcl, n);
-		if (s) {
-			/* record that this is in the closure of this scope */
-			if (fn && !s->decl.isglobl && !s->decl.isgeneric)
-				htput(fn->env, s->decl.name, s);
-			return s;
-		}
-		if (!fn && st->env)
-			fn = st;
-		st = st->super;
-	} while (st);
-	return NULL;
-}
-
 void
 putlbl(Stab *st, char *name, Node *lbl)
 {
@@ -254,18 +234,50 @@
 	return htget(st->lbl, name);
 }
 
-Type *
-gettype_l(Stab *st, Node *n)
+int
+hastype(Stab *st, Node *n)
 {
-	Tydefn *t;
+	do {
+		if (hthas(st->ty, n))
+			return 1;
+		st = st->super;
+	} while (st);
+	return 0;
+}
 
-	if ((t = htget(st->ty, n)))
-		return t->type;
-	return NULL;
+/* because of function casting rules, it's cleaner to do this as a macro */
+static void*
+getunique(void *(*fn)(Stab *, Node*), char *name, Stab *st, Node *n)
+{
+	size_t i, nk;
+	void *p, *sym;
+	char *foundns;
+	void **k; 
+	Stab *s;
+
+	p = fn(st, n);
+	/* file can be null early on, when initializing the type tables */
+	if (p || n->name.ns || !file)
+		return p;
+
+	/* if a name is globally unique, we can refer to it without a namespace */
+	sym = NULL;
+	k = htkeys(file->file.ns, &nk);
+	for (i = 0; i < nk; i++) {
+		s = htget(file->file.ns, k[i]);
+		p = fn(s, n);
+		if (p) {
+			if (sym)
+				fatal(n, "ambiguous %s %s, defined in %s and %s\n", name, namestr(n), k[i], foundns);
+			foundns = k[i];
+			sym = p;
+		}
+	}
+	return sym;
 }
 
-Type *
-gettype(Stab *st, Node *n)
+static void*
+getnstype(Stab *st, Node *n)
 {
 	Tydefn *t;
 
@@ -277,20 +289,44 @@
 	return NULL;
 }
 
-int
-hastype(Stab *st, Node *n)
+Type*
+gettype(Stab *st, Node *n)
 {
+	return getunique(getnstype, "type", st, n);
+}
+
+void*
+getnsdcl(Stab *st, Node *n)
+{
+	Node *s;
+	Stab *fn;
+
+	fn = NULL;
 	do {
-		if (hthas(st->ty, n))
-			return 1;
+		s = htget(st->dcl, n);
+		if (s) {
+			/* record that this is in the closure of this scope */
+			if (fn && !s->decl.isglobl && !s->decl.isgeneric)
+				htput(fn->env, s->decl.name, s);
+			return s;
+		}
+		if (!fn && st->env)
+			fn = st;
 		st = st->super;
 	} while (st);
-	return 0;
+	return NULL;
 }
 
-Ucon *
-getucon(Stab *st, Node *n)
+
+Node*
+getdcl(Stab *st, Node *n)
 {
+	return getunique(getnsdcl, "decl", st, n);
+}
+
+static void*
+getnsucon(Stab *st, Node *n)
+{
 	Ucon *uc;
 
 	do {
@@ -301,9 +337,15 @@
 	return NULL;
 }
 
-Trait *
-gettrait(Stab *st, Node *n)
+Ucon*
+getucon(Stab *st, Node *n)
 {
+	return getunique(getnsucon, "union constructor", st, n);
+}
+
+static void*
+getnstrait(Stab *st, Node *n)
+{
 	Traitdefn *c;
 
 	if (n->name.ns)
@@ -314,6 +356,12 @@
 		st = st->super;
 	} while (st);
 	return NULL;
+}
+
+Trait*
+gettrait(Stab *st, Node *n)
+{
+	return getunique(getnstrait, "trait", st, n);
 }
 
 Stab *