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 *