summaryrefslogtreecommitdiff
path: root/parse/stab.c
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-11-17 20:53:32 -0800
committerOri Bernstein <ori@eigenstate.org>2015-11-17 20:53:32 -0800
commit8531896f8d21ba1e727262aaf5cd96043590b480 (patch)
tree7c01441755f56ab66d33c37d3ac41642ddc46c0b /parse/stab.c
parentc20862cda53c711fe476f6c7d0f6631af47a4933 (diff)
downloadmc-8531896f8d21ba1e727262aaf5cd96043590b480.tar.gz
MEGAPATCH: Tabification.
Tabs > spaces. By 4 spaces, to be precise. Let's use them.
Diffstat (limited to 'parse/stab.c')
-rw-r--r--parse/stab.c644
1 files changed, 324 insertions, 320 deletions
diff --git a/parse/stab.c b/parse/stab.c
index 47e06af..f1db002 100644
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -16,15 +16,15 @@
typedef struct Tydefn Tydefn;
typedef struct Traitdefn Traitdefn;
struct Tydefn {
- Srcloc loc;
- Node *name;
- Type *type;
+ Srcloc loc;
+ Node *name;
+ Type *type;
};
struct Traitdefn {
- Srcloc loc;
- Node *name;
- Trait *trait;
+ Srcloc loc;
+ Node *name;
+ Trait *trait;
};
#define Maxstabdepth 128
@@ -34,105 +34,99 @@ int stabstkoff;
/* scope management */
Stab *curstab()
{
- assert(stabstkoff > 0);
- return stabstk[stabstkoff - 1];
+ assert(stabstkoff > 0);
+ return stabstk[stabstkoff - 1];
}
void pushstab(Stab *st)
{
- assert(stabstkoff < Maxstabdepth);
- stabstk[stabstkoff++] = st;
+ assert(stabstkoff < Maxstabdepth);
+ stabstk[stabstkoff++] = st;
}
void popstab(void)
{
- assert(stabstkoff > 0);
- stabstkoff--;
+ assert(stabstkoff > 0);
+ stabstkoff--;
}
/* name hashing: we want namespaced lookups to find the
* name even if we haven't set the namespace up, since
* we can update it after the fact. */
-static ulong nsnamehash(void *n)
-{
- return strhash(namestr(n));
-}
+static ulong nsnamehash(void *n) { return strhash(namestr(n)); }
-static int nsnameeq(void *a, void *b)
-{
- return a == b || !strcmp(namestr(a), namestr(b));
-}
+static int nsnameeq(void *a, void *b) { return a == b || !strcmp(namestr(a), namestr(b)); }
static ulong implhash(void *p)
{
- Node *n;
- ulong h;
+ Node *n;
+ ulong h;
- n = p;
- h = nsnamehash(n->impl.traitname);
- h *= tyhash(n->impl.type);
- return h;
+ n = p;
+ h = nsnamehash(n->impl.traitname);
+ h *= tyhash(n->impl.type);
+ return h;
}
static int impleq(void *pa, void *pb)
{
- Node *a, *b;
+ Node *a, *b;
- a = pa;
- b = pb;
- if (nsnameeq(a->impl.traitname, b->impl.traitname))
- return tyeq(a->impl.type, b->impl.type);
- return 0;
+ a = pa;
+ b = pb;
+ if (nsnameeq(a->impl.traitname, b->impl.traitname))
+ return tyeq(a->impl.type, b->impl.type);
+ return 0;
}
Stab *mkstab(int isfunc)
{
- Stab *st;
-
- st = zalloc(sizeof(Stab));
- st->dcl = mkht(nsnamehash, nsnameeq);
- st->ty = mkht(nsnamehash, nsnameeq);
- st->tr = mkht(nsnamehash, nsnameeq);
- st->uc = mkht(nsnamehash, nsnameeq);
- if (isfunc)
- st->env = mkht(nsnamehash, nsnameeq);
- st->impl = mkht(implhash, impleq);
- return st;
+ Stab *st;
+
+ st = zalloc(sizeof(Stab));
+ st->dcl = mkht(nsnamehash, nsnameeq);
+ st->ty = mkht(nsnamehash, nsnameeq);
+ st->tr = mkht(nsnamehash, nsnameeq);
+ st->uc = mkht(nsnamehash, nsnameeq);
+ if (isfunc)
+ st->env = mkht(nsnamehash, nsnameeq);
+ st->impl = mkht(implhash, impleq);
+ return st;
}
Node *getclosed(Stab *st, Node *n)
{
- while (st && !st->env)
- st = st->super;
- if (st)
- return htget(st->env, n);
- return NULL;
+ while (st && !st->env)
+ st = st->super;
+ if (st)
+ return htget(st->env, n);
+ return NULL;
}
Node **getclosure(Stab *st, size_t *n)
{
- size_t nkeys, i;
- void **keys;
- Node **vals;
-
- while (st && !st->env)
- st = st->super;
-
- if (!st) {
- *n = 0;
- return NULL;
- }
-
- vals = NULL;
- *n = 0;
- keys = htkeys(st->env, &nkeys);
- for (i = 0; i < nkeys; i++)
- lappend(&vals, n, htget(st->env, keys[i]));
- free(keys);
- return vals;
+ size_t nkeys, i;
+ void **keys;
+ Node **vals;
+
+ while (st && !st->env)
+ st = st->super;
+
+ if (!st) {
+ *n = 0;
+ return NULL;
+ }
+
+ vals = NULL;
+ *n = 0;
+ keys = htkeys(st->env, &nkeys);
+ for (i = 0; i < nkeys; i++)
+ lappend(&vals, n, htget(st->env, keys[i]));
+ free(keys);
+ return vals;
}
-/*
+/*
* Searches for declarations from current
* scope, and all enclosing scopes. Does
* not resolve namespaces -- that is the job
@@ -144,312 +138,322 @@ Node **getclosure(Stab *st, size_t *n)
*/
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)
- htput(fn->env, s->decl.name, s);
- return s;
- }
- if (!fn && st->env)
- fn = st;
- st = st->super;
- } while (st);
- return NULL;
+ 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)
+ htput(fn->env, s->decl.name, s);
+ return s;
+ }
+ if (!fn && st->env)
+ fn = st;
+ st = st->super;
+ } while (st);
+ return NULL;
}
Type *gettype_l(Stab *st, Node *n)
{
- Tydefn *t;
+ Tydefn *t;
- if ((t = htget(st->ty, n)))
- return t->type;
- return NULL;
+ if ((t = htget(st->ty, n)))
+ return t->type;
+ return NULL;
}
-
Type *gettype(Stab *st, Node *n)
{
- Tydefn *t;
-
- do {
- if ((t = htget(st->ty, n)))
- return t->type;
- st = st->super;
- } while (st);
- return NULL;
+ Tydefn *t;
+
+ do {
+ if ((t = htget(st->ty, n)))
+ return t->type;
+ st = st->super;
+ } while (st);
+ return NULL;
}
int hastype(Stab *st, Node *n)
{
- do {
- if (hthas(st->ty, n))
- return 1;
- st = st->super;
- } while(st);
- return 0;
+ do {
+ if (hthas(st->ty, n))
+ return 1;
+ st = st->super;
+ } while (st);
+ return 0;
}
Ucon *getucon(Stab *st, Node *n)
{
- Ucon *uc;
-
- do {
- if ((uc = htget(st->uc, n)))
- return uc;
- st = st->super;
- } while (st);
- return NULL;
+ Ucon *uc;
+
+ do {
+ if ((uc = htget(st->uc, n)))
+ return uc;
+ st = st->super;
+ } while (st);
+ return NULL;
}
Trait *gettrait(Stab *st, Node *n)
{
- Traitdefn *c;
-
- do {
- if ((c = htget(st->tr, n)))
- return c->trait;
- st = st->super;
- } while (st);
- return NULL;
+ Traitdefn *c;
+
+ do {
+ if ((c = htget(st->tr, n)))
+ return c->trait;
+ st = st->super;
+ } while (st);
+ return NULL;
}
-Stab *getns(Node *file, char *name)
-{
- return htget(file->file.ns, name);
-}
+Stab *getns(Node *file, char *name) { return htget(file->file.ns, name); }
static int mergedecl(Node *old, Node *new)
{
- Node *e, *g;
-
- if (old->decl.ishidden || new->decl.ishidden) {
- old->decl.ishidden = old->decl.ishidden && new->decl.ishidden;
- return 1;
- }
- if (old->decl.isextern || new->decl.isextern) {
- old->decl.isextern = old->decl.isextern && new->decl.isextern;
- return 1;
- }
- if (old->decl.vis == Visexport && new->decl.vis != Visexport) {
- e = old;
- g = new;
- } else if (new->decl.vis == Visexport && old->decl.vis != Visexport) {
- e = new;
- g = old;
- } else {
- return 0;
- }
- old->decl.vis = Visexport;
-
- if (e->decl.init && g->decl.init)
- fatal(e, "export %s double initialized on %s:%d", declname(e), fname(g->loc), lnum(g->loc));
- if (e->decl.isgeneric != g->decl.isgeneric)
- fatal(e, "export %s declared with different genericness on %s:%d", declname(e), fname(g->loc), lnum(g->loc));
- if (e->decl.isconst != g->decl.isconst)
- fatal(e, "export %s declared with different constness on %s:%d", declname(e), fname(g->loc), lnum(g->loc));
- if (e->decl.isconst != g->decl.isconst)
- fatal(e, "export %s declared with different externness on %s:%d", declname(e), fname(g->loc), lnum(g->loc));
-
- if (new->decl.name->name.ns)
- setns(old->decl.name, new->decl.name->name.ns);
- if (e->decl.type->type == Tyvar)
- e->decl.type = g->decl.type;
- else if (g->decl.type->type == Tyvar)
- g->decl.type = e->decl.type;
-
- if (!e->decl.init)
- e->decl.init = g->decl.init;
- else if (!g->decl.init)
- g->decl.init = e->decl.init;
-
- /* FIXME: check compatible typing */
- old->decl.ishidden = e->decl.ishidden || g->decl.ishidden;
- old->decl.isimport = e->decl.isimport || g->decl.isimport;
- old->decl.isnoret = e->decl.isnoret || g->decl.isnoret;
- old->decl.isexportinit = e->decl.isexportinit || g->decl.isexportinit;
- old->decl.isglobl = e->decl.isglobl || g->decl.isglobl;
- old->decl.ispkglocal = e->decl.ispkglocal || g->decl.ispkglocal;
- old->decl.isextern = e->decl.isextern || g->decl.isextern;
- return 1;
+ Node *e, *g;
+
+ if (old->decl.ishidden || new->decl.ishidden) {
+ old->decl.ishidden = old->decl.ishidden && new->decl.ishidden;
+ return 1;
+ }
+ if (old->decl.isextern || new->decl.isextern) {
+ old->decl.isextern = old->decl.isextern && new->decl.isextern;
+ return 1;
+ }
+ if (old->decl.vis == Visexport && new->decl.vis != Visexport) {
+ e = old;
+ g = new;
+ }
+ else if (new->decl.vis == Visexport && old->decl.vis != Visexport) {
+ e = new;
+ g = old;
+ }
+ else {
+ return 0;
+ }
+ old->decl.vis = Visexport;
+
+ if (e->decl.init && g->decl.init)
+ fatal(e, "export %s double initialized on %s:%d", declname(e), fname(g->loc),
+ lnum(g->loc));
+ if (e->decl.isgeneric != g->decl.isgeneric)
+ fatal(e, "export %s declared with different genericness on %s:%d", declname(e),
+ fname(g->loc), lnum(g->loc));
+ if (e->decl.isconst != g->decl.isconst)
+ fatal(e, "export %s declared with different constness on %s:%d", declname(e),
+ fname(g->loc), lnum(g->loc));
+ if (e->decl.isconst != g->decl.isconst)
+ fatal(e, "export %s declared with different externness on %s:%d", declname(e),
+ fname(g->loc), lnum(g->loc));
+
+ if (new->decl.name->name.ns)
+ setns(old->decl.name, new->decl.name->name.ns);
+ if (e->decl.type->type == Tyvar)
+ e->decl.type = g->decl.type;
+ else if (g->decl.type->type == Tyvar)
+ g->decl.type = e->decl.type;
+
+ if (!e->decl.init)
+ e->decl.init = g->decl.init;
+ else if (!g->decl.init)
+ g->decl.init = e->decl.init;
+
+ /* FIXME: check compatible typing */
+ old->decl.ishidden = e->decl.ishidden || g->decl.ishidden;
+ old->decl.isimport = e->decl.isimport || g->decl.isimport;
+ old->decl.isnoret = e->decl.isnoret || g->decl.isnoret;
+ old->decl.isexportinit = e->decl.isexportinit || g->decl.isexportinit;
+ old->decl.isglobl = e->decl.isglobl || g->decl.isglobl;
+ old->decl.ispkglocal = e->decl.ispkglocal || g->decl.ispkglocal;
+ old->decl.isextern = e->decl.isextern || g->decl.isextern;
+ return 1;
}
-void forcedcl (Stab *st, Node *s) {
- if (st->name)
- setns(s->decl.name, st->name);
- htput(st->dcl, s->decl.name, s);
- assert(htget(st->dcl, s->decl.name) != NULL);
+void forcedcl(Stab *st, Node *s)
+{
+ if (st->name)
+ setns(s->decl.name, st->name);
+ htput(st->dcl, s->decl.name, s);
+ assert(htget(st->dcl, s->decl.name) != NULL);
}
void putdcl(Stab *st, Node *s)
{
- Node *name, *old;
- Stab *ns;
-
- name = s->decl.name;
- if (name->name.ns) {
- ns = getns(file, name->name.ns);
- if (!ns) {
- ns = mkstab(0);
- updatens(ns, name->name.ns);
- }
- st = ns;
- }
- old = htget(st->dcl, s->decl.name);
- if (!old)
- forcedcl(st, s);
- else if (!mergedecl(old, s))
- fatal(old, "%s already declared on %s:%d", namestr(s->decl.name), fname(s->loc), lnum(s->loc));
+ Node *name, *old;
+ Stab *ns;
+
+ name = s->decl.name;
+ if (name->name.ns) {
+ ns = getns(file, name->name.ns);
+ if (!ns) {
+ ns = mkstab(0);
+ updatens(ns, name->name.ns);
+ }
+ st = ns;
+ }
+ old = htget(st->dcl, s->decl.name);
+ if (!old)
+ forcedcl(st, s);
+ else if (!mergedecl(old, s))
+ fatal(old, "%s already declared on %s:%d", namestr(s->decl.name), fname(s->loc),
+ lnum(s->loc));
}
void updatetype(Stab *st, Node *n, Type *t)
{
- Tydefn *td;
+ Tydefn *td;
- td = htget(st->ty, n);
- if (!td)
- die("No type %s to update", namestr(n));
- td->type = t;
+ td = htget(st->ty, n);
+ if (!td)
+ die("No type %s to update", namestr(n));
+ td->type = t;
}
int mergetype(Type *old, Type *new)
{
- if (!new) {
- lfatal(new->loc, "double prototyping of %s", tystr(new));
- } else if (old->vis == Visexport && new->vis != Visexport) {
- if (!old->sub && new->sub) {
- old->sub = new->sub;
- old->nsub = new->nsub;
- return 1;
- }
- } else if (new->vis == Visexport && old->vis != Visexport) {
- if (!new->sub && old->sub) {
- new->sub = old->sub;
- new->nsub = old->nsub;
- return 1;
- }
- }
- return 0;
+ if (!new) {
+ lfatal(new->loc, "double prototyping of %s", tystr(new));
+ }
+ else if (old->vis == Visexport && new->vis != Visexport) {
+ if (!old->sub && new->sub) {
+ old->sub = new->sub;
+ old->nsub = new->nsub;
+ return 1;
+ }
+ }
+ else if (new->vis == Visexport && old->vis != Visexport) {
+ if (!new->sub && old->sub) {
+ new->sub = old->sub;
+ new->nsub = old->nsub;
+ return 1;
+ }
+ }
+ return 0;
}
void puttype(Stab *st, Node *n, Type *t)
{
- Tydefn *td;
- Type *ty;
-
- if (st->name)
- setns(n, st->name);
- if (st->name && t && t->name)
- setns(t->name, st->name);
-
- ty = gettype(st, n);
- if (!ty) {
- if (t && hastype(st, n)) {
- t->vis = Visexport;
- updatetype(st, n, t);
- } else {
- td = xalloc(sizeof(Tydefn));
- td->loc = n->loc;
- td->name = n;
- td->type = t;
- htput(st->ty, td->name, td);
- }
- } else if (!mergetype(ty, t)) {
- fatal(n, "Type %s already declared on %s:%d", tystr(ty), fname(ty->loc), lnum(ty->loc));
- }
+ Tydefn *td;
+ Type *ty;
+
+ if (st->name)
+ setns(n, st->name);
+ if (st->name && t && t->name)
+ setns(t->name, st->name);
+
+ ty = gettype(st, n);
+ if (!ty) {
+ if (t && hastype(st, n)) {
+ t->vis = Visexport;
+ updatetype(st, n, t);
+ }
+ else {
+ td = xalloc(sizeof(Tydefn));
+ td->loc = n->loc;
+ td->name = n;
+ td->type = t;
+ htput(st->ty, td->name, td);
+ }
+ }
+ else if (!mergetype(ty, t)) {
+ fatal(n, "Type %s already declared on %s:%d", tystr(ty), fname(ty->loc),
+ lnum(ty->loc));
+ }
}
void putucon(Stab *st, Ucon *uc)
{
- Ucon *old;
-
+ Ucon *old;
- old = getucon(st, uc->name);
- if (old)
- lfatal(old->loc, "`%s already defined on %s:%d", namestr(uc->name), fname(uc->loc), lnum(uc->loc));
- htput(st->uc, uc->name, uc);
+ old = getucon(st, uc->name);
+ if (old)
+ lfatal(old->loc, "`%s already defined on %s:%d", namestr(uc->name), fname(uc->loc),
+ lnum(uc->loc));
+ htput(st->uc, uc->name, uc);
}
static int mergetrait(Trait *old, Trait *new)
{
- if (old->isproto && !new->isproto)
- *old = *new;
- else if (new->isproto && !old->isproto)
- *new = *old;
- else
- return 0;
- return 1;
+ if (old->isproto && !new->isproto)
+ *old = *new;
+ else if (new->isproto && !old->isproto)
+ *new = *old;
+ else
+ return 0;
+ return 1;
}
void puttrait(Stab *st, Node *n, Trait *c)
{
- Traitdefn *td;
- Trait *t;
- Type *ty;
-
- t = gettrait(st, n);
- if (t && !mergetrait(t, c))
- fatal(n, "Trait %s already defined on %s:%d", namestr(n), fname(t->loc), lnum(t->loc));
- ty = gettype(st, n);
- if (ty)
- fatal(n, "Trait %s defined as a type on %s:%d", namestr(n), fname(ty->loc), lnum(ty->loc));
- td = xalloc(sizeof(Traitdefn));
- td->loc = n->loc;
- td->name = n;
- td->trait = c;
- htput(st->tr, td->name, td);
+ Traitdefn *td;
+ Trait *t;
+ Type *ty;
+
+ t = gettrait(st, n);
+ if (t && !mergetrait(t, c))
+ fatal(n, "Trait %s already defined on %s:%d", namestr(n), fname(t->loc),
+ lnum(t->loc));
+ ty = gettype(st, n);
+ if (ty)
+ fatal(n, "Trait %s defined as a type on %s:%d", namestr(n), fname(ty->loc),
+ lnum(ty->loc));
+ td = xalloc(sizeof(Traitdefn));
+ td->loc = n->loc;
+ td->name = n;
+ td->trait = c;
+ htput(st->tr, td->name, td);
}
static int mergeimpl(Node *old, Node *new)
{
- if (old->impl.isproto && !new->impl.isproto)
- *old = *new;
- else if (new->impl.isproto && !old->impl.isproto)
- *new = *old;
- else
- return 0;
- return 1;
+ if (old->impl.isproto && !new->impl.isproto)
+ *old = *new;
+ else if (new->impl.isproto && !old->impl.isproto)
+ *new = *old;
+ else
+ return 0;
+ return 1;
}
void putimpl(Stab *st, Node *n)
{
- Node *impl;
-
- impl = getimpl(st, n);
- if (impl && !mergeimpl(impl, n))
- fatal(n, "Trait %s already implemented over %s at %s:%d",
- namestr(n->impl.traitname), tystr(n->impl.type),
- fname(n->loc), lnum(n->loc));
- if (st->name)
- setns(n->impl.traitname, st->name);
- htput(st->impl, n, n);
+ Node *impl;
+
+ impl = getimpl(st, n);
+ if (impl && !mergeimpl(impl, n))
+ fatal(n, "Trait %s already implemented over %s at %s:%d",
+ namestr(n->impl.traitname), tystr(n->impl.type), fname(n->loc), lnum(n->loc));
+ if (st->name)
+ setns(n->impl.traitname, st->name);
+ htput(st->impl, n, n);
}
Node *getimpl(Stab *st, Node *n)
{
- Node *imp;
-
- do {
- if ((imp = htget(st->impl, n)))
- return imp;
- st = st->super;
- } while (st);
- return NULL;
+ Node *imp;
+
+ do {
+ if ((imp = htget(st->impl, n)))
+ return imp;
+ st = st->super;
+ } while (st);
+ return NULL;
}
void putns(Node *file, Stab *scope)
{
- Stab *s;
+ Stab *s;
- s = getns(file, scope->name);
- if (s)
- lfatal(Zloc, "Namespace %s already defined", scope->name);
- htput(file->file.ns, scope->name, scope);
+ s = getns(file, scope->name);
+ if (s)
+ lfatal(Zloc, "Namespace %s already defined", scope->name);
+ htput(file->file.ns, scope->name, scope);
}
/*
@@ -459,25 +463,25 @@ void putns(Node *file, Stab *scope)
*/
void updatens(Stab *st, char *name)
{
- void **k;
- size_t i, nk;
- Tydefn *td;
-
- if (st->name)
- die("Stab %s already has namespace; Can't set to %s", st->name, name);
- st->name = strdup(name);
- htput(file->file.ns, st->name, st);
- k = htkeys(st->dcl, &nk);
- for (i = 0; i < nk; i++)
- setns(k[i], name);
- free(k);
- k = htkeys(st->ty, &nk);
- for (i = 0; i < nk; i++)
- setns(k[i], name);
- for (i = 0; i < nk; i++) {
- td = htget(st->ty, k[i]);
- if (td->type && (td->type->type == Tyname || td->type->type == Tygeneric))
- setns(td->type->name, name);
- }
- free(k);
+ void **k;
+ size_t i, nk;
+ Tydefn *td;
+
+ if (st->name)
+ die("Stab %s already has namespace; Can't set to %s", st->name, name);
+ st->name = strdup(name);
+ htput(file->file.ns, st->name, st);
+ k = htkeys(st->dcl, &nk);
+ for (i = 0; i < nk; i++)
+ setns(k[i], name);
+ free(k);
+ k = htkeys(st->ty, &nk);
+ for (i = 0; i < nk; i++)
+ setns(k[i], name);
+ for (i = 0; i < nk; i++) {
+ td = htget(st->ty, k[i]);
+ if (td->type && (td->type->type == Tyname || td->type->type == Tygeneric))
+ setns(td->type->name, name);
+ }
+ free(k);
}