summaryrefslogtreecommitdiff
path: root/parse/use.c
diff options
context:
space:
mode:
Diffstat (limited to 'parse/use.c')
-rw-r--r--parse/use.c1826
1 files changed, 908 insertions, 918 deletions
diff --git a/parse/use.c b/parse/use.c
index a5cbe46..88ac64a 100644
--- a/parse/use.c
+++ b/parse/use.c
@@ -22,35 +22,34 @@ static void pickle(FILE *fd, Node *n);
static Node *unpickle(FILE *fd);
/* type fixup list */
-static Htab *tydedup; /* map from name -> type, contains all Tynames loaded ever */
-static Htab *tidmap; /* map from tid -> type */
-static Htab *trmap; /* map from trait id -> trait */
-static Htab *initmap; /* map from init name -> int */
+static Htab *tydedup; /* map from name -> type, contains all Tynames loaded ever */
+static Htab *tidmap; /* map from tid -> type */
+static Htab *trmap; /* map from trait id -> trait */
+static Htab *initmap; /* map from init name -> int */
#define Builtinmask (1 << 30)
-static Type ***typefixdest; /* list of types we need to replace */
-static size_t ntypefixdest; /* size of replacement list */
-static intptr_t *typefixid; /* list of types we need to replace */
-static size_t ntypefixid; /* size of replacement list */
-
-static Trait ***traitfixdest; /* list of traits we need to replace */
-static size_t ntraitfixdest; /* size of replacement list */
-static Type **traitfixtype; /* list of types we need to set the trait on */
-static size_t ntraitfixtype; /* size of replacement list */
-static intptr_t *traitfixid; /* list of traits we need to replace */
-static size_t ntraitfixid; /* size of replacement list */
-
+static Type ***typefixdest; /* list of types we need to replace */
+static size_t ntypefixdest; /* size of replacement list */
+static intptr_t *typefixid; /* list of types we need to replace */
+static size_t ntypefixid; /* size of replacement list */
+
+static Trait ***traitfixdest; /* list of traits we need to replace */
+static size_t ntraitfixdest; /* size of replacement list */
+static Type **traitfixtype; /* list of types we need to set the trait on */
+static size_t ntraitfixtype; /* size of replacement list */
+static intptr_t *traitfixid; /* list of traits we need to replace */
+static size_t ntraitfixid; /* size of replacement list */
void addextlibs(Node *file, char **libs, size_t nlibs)
{
- size_t i, j;
-
- for (i = 0; i < nlibs; i++) {
- for (j = 0; j < file->file.nextlibs; j++)
- if (!strcmp(file->file.extlibs[j], libs[i]))
- continue;
- lappend(&file->file.extlibs, &file->file.nextlibs, libs[i]);
- }
+ size_t i, j;
+
+ for (i = 0; i < nlibs; i++) {
+ for (j = 0; j < file->file.nextlibs; j++)
+ if (!strcmp(file->file.extlibs[j], libs[i]))
+ continue;
+ lappend(&file->file.extlibs, &file->file.nextlibs, libs[i]);
+ }
}
/* Outputs a symbol table to file in a way that can be
@@ -58,89 +57,88 @@ void addextlibs(Node *file, char **libs, size_t nlibs)
* and sub-namespaces. Captured variables are ommitted. */
static void wrstab(FILE *fd, Stab *val)
{
- size_t n, i;
- void **keys;
-
- wrstr(fd, val->name);
-
- /* write decls */
- keys = htkeys(val->dcl, &n);
- wrint(fd, n);
- for (i = 0; i < n; i++)
- wrsym(fd, getdcl(val, keys[i]));
- free(keys);
-
- /* write types */
- keys = htkeys(val->ty, &n);
- wrint(fd, n);
- for (i = 0; i < n; i++) {
- pickle(fd, keys[i]); /* name */
- wrtype(fd, gettype(val, keys[i])); /* type */
- }
- free(keys);
-
+ size_t n, i;
+ void **keys;
+
+ wrstr(fd, val->name);
+
+ /* write decls */
+ keys = htkeys(val->dcl, &n);
+ wrint(fd, n);
+ for (i = 0; i < n; i++)
+ wrsym(fd, getdcl(val, keys[i]));
+ free(keys);
+
+ /* write types */
+ keys = htkeys(val->ty, &n);
+ wrint(fd, n);
+ for (i = 0; i < n; i++) {
+ pickle(fd, keys[i]); /* name */
+ wrtype(fd, gettype(val, keys[i])); /* type */
+ }
+ free(keys);
}
/* Reads a symbol table from file. The converse
* of wrstab. */
static Stab *rdstab(FILE *fd, int isfunc)
{
- Stab *st;
- Type *ty;
- Node *nm;
- int n;
- int i;
-
- /* read dcls */
- st = mkstab(isfunc);
- st->name = rdstr(fd);
- n = rdint(fd);
- for (i = 0; i < n; i++)
- putdcl(st, rdsym(fd, NULL));
-
- /* read types */
- n = rdint(fd);
- for (i = 0; i < n; i++) {
- nm = unpickle(fd);
- rdtype(fd, &ty);
- puttype(st, nm, ty);
- }
- return st;
+ Stab *st;
+ Type *ty;
+ Node *nm;
+ int n;
+ int i;
+
+ /* read dcls */
+ st = mkstab(isfunc);
+ st->name = rdstr(fd);
+ n = rdint(fd);
+ for (i = 0; i < n; i++)
+ putdcl(st, rdsym(fd, NULL));
+
+ /* read types */
+ n = rdint(fd);
+ for (i = 0; i < n; i++) {
+ nm = unpickle(fd);
+ rdtype(fd, &ty);
+ puttype(st, nm, ty);
+ }
+ return st;
}
static void wrucon(FILE *fd, Ucon *uc)
{
- wrint(fd, uc->loc.line);
- wrint(fd, uc->id);
- wrbool(fd, uc->synth);
- pickle(fd, uc->name);
- wrbool(fd, uc->etype != NULL);
- if (uc->etype)
- wrtype(fd, uc->etype);
+ wrint(fd, uc->loc.line);
+ wrint(fd, uc->id);
+ wrbool(fd, uc->synth);
+ pickle(fd, uc->name);
+ wrbool(fd, uc->etype != NULL);
+ if (uc->etype)
+ wrtype(fd, uc->etype);
}
static Ucon *rducon(FILE *fd, Type *ut)
{
- Type *et;
- Node *name;
- Ucon *uc;
- size_t id;
- int line;
- int synth;
-
- et = NULL;
- line = rdint(fd);
- id = rdint(fd);
- synth = rdbool(fd);
- name = unpickle(fd);
- uc = mkucon(Zloc, name, ut, et);
- uc->loc.line = line;
- uc->loc.file = file->file.nfiles - 1;
- if (rdbool(fd))
- rdtype(fd, &uc->etype);
- uc->id = id;
- uc->synth = synth;
- return uc;
+ Type *et;
+ Node *name;
+ Ucon *uc;
+ size_t id;
+ int line;
+ int synth;
+
+ et = NULL;
+ line = rdint(fd);
+ id = rdint(fd);
+ synth = rdbool(fd);
+ name = unpickle(fd);
+ uc = mkucon(Zloc, name, ut, et);
+ uc->loc.line = line;
+ uc->loc.file = file->file.nfiles - 1;
+ if (rdbool(fd))
+ rdtype(fd, &uc->etype);
+ uc->id = id;
+ uc->synth = synth;
+ return uc;
}
/* Writes the name and type of a variable,
@@ -149,52 +147,52 @@ static Ucon *rducon(FILE *fd, Type *ut)
* the only cross-file inline is generics) */
static void wrsym(FILE *fd, Node *val)
{
- /* sym */
- wrint(fd, val->loc.line);
- pickle(fd, val->decl.name);
- wrtype(fd, val->decl.type);
-
- /* symflags */
- wrint(fd, val->decl.vis);
- wrbool(fd, val->decl.isconst);
- wrbool(fd, val->decl.isgeneric);
- wrbool(fd, val->decl.isextern);
- wrbool(fd, val->decl.ispkglocal);
- wrbool(fd, val->decl.isnoret);
- wrbool(fd, val->decl.isexportinit);
- wrbool(fd, val->decl.isinit);
- if (val->decl.isexportinit) {
- pickle(fd, val->decl.init);
- }
+ /* sym */
+ wrint(fd, val->loc.line);
+ pickle(fd, val->decl.name);
+ wrtype(fd, val->decl.type);
+
+ /* symflags */
+ wrint(fd, val->decl.vis);
+ wrbool(fd, val->decl.isconst);
+ wrbool(fd, val->decl.isgeneric);
+ wrbool(fd, val->decl.isextern);
+ wrbool(fd, val->decl.ispkglocal);
+ wrbool(fd, val->decl.isnoret);
+ wrbool(fd, val->decl.isexportinit);
+ wrbool(fd, val->decl.isinit);
+ if (val->decl.isexportinit) {
+ pickle(fd, val->decl.init);
+ }
}
static Node *rdsym(FILE *fd, Trait *ctx)
{
- int line;
- Node *name;
- Node *n;
-
- line = rdint(fd);
- name = unpickle(fd);
- n = mkdecl(Zloc, name, NULL);
- n->loc.line = line;
- n->loc.file = file->file.nfiles - 1;
- rdtype(fd, &n->decl.type);
-
- if (rdint(fd) == Vishidden)
- n->decl.ishidden = 1;
- n->decl.trait = ctx;
- n->decl.isconst = rdbool(fd);
- n->decl.isgeneric = rdbool(fd);
- n->decl.isextern = rdbool(fd);
- n->decl.ispkglocal = rdbool(fd);
- n->decl.isnoret = rdbool(fd);
- n->decl.isimport = 1;
- n->decl.isexportinit = rdbool(fd);
- n->decl.isinit = rdbool(fd);
- if (n->decl.isexportinit)
- n->decl.init = unpickle(fd);
- return n;
+ int line;
+ Node *name;
+ Node *n;
+
+ line = rdint(fd);
+ name = unpickle(fd);
+ n = mkdecl(Zloc, name, NULL);
+ n->loc.line = line;
+ n->loc.file = file->file.nfiles - 1;
+ rdtype(fd, &n->decl.type);
+
+ if (rdint(fd) == Vishidden)
+ n->decl.ishidden = 1;
+ n->decl.trait = ctx;
+ n->decl.isconst = rdbool(fd);
+ n->decl.isgeneric = rdbool(fd);
+ n->decl.isextern = rdbool(fd);
+ n->decl.ispkglocal = rdbool(fd);
+ n->decl.isnoret = rdbool(fd);
+ n->decl.isimport = 1;
+ n->decl.isexportinit = rdbool(fd);
+ n->decl.isinit = rdbool(fd);
+ if (n->decl.isexportinit)
+ n->decl.init = unpickle(fd);
+ return n;
}
/* Writes types to a file. Errors on
@@ -202,134 +200,129 @@ static Node *rdsym(FILE *fd, Trait *ctx)
* will not be meaningful in another file*/
static void typickle(FILE *fd, Type *ty)
{
- size_t i;
-
- if (!ty) {
- die("trying to pickle null type\n");
- return;
- }
- wrbyte(fd, ty->type);
- wrbyte(fd, ty->vis);
- /* tid is generated; don't write */
- /* FIXME: since we only support hardcoded traits, we just write
- * out the set of them. we should write out the trait list as
- * well */
- if (!ty->traits) {
- wrint(fd, 0);
- } else {
- wrint(fd, bscount(ty->traits));
- for (i = 0; bsiter(ty->traits, &i); i++) {
- if (i < Ntraits)
- wrint(fd, i | Builtinmask);
- else
- wrint(fd, i);
- }
- }
- wrint(fd, ty->nsub);
- switch (ty->type) {
- case Tyunres:
- pickle(fd, ty->name);
- break;
- case Typaram:
- wrstr(fd, ty->pname);
- break;
- case Tystruct:
- wrint(fd, ty->nmemb);
- for (i = 0; i < ty->nmemb; i++)
- pickle(fd, ty->sdecls[i]);
- break;
- case Tyunion:
- wrint(fd, ty->nmemb);
- for (i = 0; i < ty->nmemb; i++)
- wrucon(fd, ty->udecls[i]);
- break;
- case Tyarray:
- wrtype(fd, ty->sub[0]);
- pickle(fd, ty->asize);
- break;
- case Tyslice:
- wrtype(fd, ty->sub[0]);
- break;
- case Tyvar:
- die("Attempting to pickle %s. This will not work.\n", tystr(ty));
- break;
- case Tyname:
- pickle(fd, ty->name);
- wrbool(fd, ty->issynth);
- wrint(fd, ty->narg);
- for (i = 0; i < ty->narg; i++)
- wrtype(fd, ty->arg[i]);
- wrtype(fd, ty->sub[0]);
- break;
- case Tygeneric:
- pickle(fd, ty->name);
- wrbool(fd, ty->issynth);
- wrint(fd, ty->ngparam);
- for (i = 0; i < ty->ngparam; i++)
- wrtype(fd, ty->gparam[i]);
- wrtype(fd, ty->sub[0]);
- break;
- default:
- for (i = 0; i < ty->nsub; i++)
- wrtype(fd, ty->sub[i]);
- break;
- }
+ size_t i;
+
+ if (!ty) {
+ die("trying to pickle null type\n");
+ return;
+ }
+ wrbyte(fd, ty->type);
+ wrbyte(fd, ty->vis);
+ /* tid is generated; don't write */
+ /* FIXME: since we only support hardcoded traits, we just write
+ * out the set of them. we should write out the trait list as
+ * well */
+ if (!ty->traits) {
+ wrint(fd, 0);
+ }
+ else {
+ wrint(fd, bscount(ty->traits));
+ for (i = 0; bsiter(ty->traits, &i); i++) {
+ if (i < Ntraits)
+ wrint(fd, i | Builtinmask);
+ else
+ wrint(fd, i);
+ }
+ }
+ wrint(fd, ty->nsub);
+ switch (ty->type) {
+ case Tyunres: pickle(fd, ty->name); break;
+ case Typaram: wrstr(fd, ty->pname); break;
+ case Tystruct:
+ wrint(fd, ty->nmemb);
+ for (i = 0; i < ty->nmemb; i++)
+ pickle(fd, ty->sdecls[i]);
+ break;
+ case Tyunion:
+ wrint(fd, ty->nmemb);
+ for (i = 0; i < ty->nmemb; i++)
+ wrucon(fd, ty->udecls[i]);
+ break;
+ case Tyarray:
+ wrtype(fd, ty->sub[0]);
+ pickle(fd, ty->asize);
+ break;
+ case Tyslice: wrtype(fd, ty->sub[0]); break;
+ case Tyvar: die("Attempting to pickle %s. This will not work.\n", tystr(ty)); break;
+ case Tyname:
+ pickle(fd, ty->name);
+ wrbool(fd, ty->issynth);
+ wrint(fd, ty->narg);
+ for (i = 0; i < ty->narg; i++)
+ wrtype(fd, ty->arg[i]);
+ wrtype(fd, ty->sub[0]);
+ break;
+ case Tygeneric:
+ pickle(fd, ty->name);
+ wrbool(fd, ty->issynth);
+ wrint(fd, ty->ngparam);
+ for (i = 0; i < ty->ngparam; i++)
+ wrtype(fd, ty->gparam[i]);
+ wrtype(fd, ty->sub[0]);
+ break;
+ default:
+ for (i = 0; i < ty->nsub; i++)
+ wrtype(fd, ty->sub[i]);
+ break;
+ }
}
static void traitpickle(FILE *fd, Trait *tr)
{
- size_t i;
-
- wrint(fd, tr->uid);
- wrbool(fd, tr->ishidden);
- pickle(fd, tr->name);
- typickle(fd, tr->param);
- wrint(fd, tr->nmemb);
- for (i = 0; i < tr->nmemb; i++)
- wrsym(fd, tr->memb[i]);
- wrint(fd, tr->nfuncs);
- for (i = 0; i < tr->nfuncs; i++)
- wrsym(fd, tr->funcs[i]);
+ size_t i;
+
+ wrint(fd, tr->uid);
+ wrbool(fd, tr->ishidden);
+ pickle(fd, tr->name);
+ typickle(fd, tr->param);
+ wrint(fd, tr->nmemb);
+ for (i = 0; i < tr->nmemb; i++)
+ wrsym(fd, tr->memb[i]);
+ wrint(fd, tr->nfuncs);
+ for (i = 0; i < tr->nfuncs; i++)
+ wrsym(fd, tr->funcs[i]);
}
static void wrtype(FILE *fd, Type *ty)
{
- if (ty->tid >= Builtinmask)
- die("Type id %d for %s too big", ty->tid, tystr(ty));
- if (ty->vis == Visbuiltin)
- wrint(fd, ty->type | Builtinmask);
- else
- wrint(fd, ty->tid);
+ if (ty->tid >= Builtinmask)
+ die("Type id %d for %s too big", ty->tid, tystr(ty));
+ if (ty->vis == Visbuiltin)
+ wrint(fd, ty->type | Builtinmask);
+ else
+ wrint(fd, ty->tid);
}
static void rdtype(FILE *fd, Type **dest)
{
- uintptr_t tid;
-
- tid = rdint(fd);
- if (tid & Builtinmask) {
- *dest = mktype(Zloc, tid & ~Builtinmask);
- } else {
- lappend(&typefixdest, &ntypefixdest, dest);
- lappend(&typefixid, &ntypefixid, itop(tid));
- }
+ uintptr_t tid;
+
+ tid = rdint(fd);
+ if (tid & Builtinmask) {
+ *dest = mktype(Zloc, tid & ~Builtinmask);
+ }
+ else {
+ lappend(&typefixdest, &ntypefixdest, dest);
+ lappend(&typefixid, &ntypefixid, itop(tid));
+ }
}
static void rdtrait(FILE *fd, Trait **dest, Type *ty)
{
- uintptr_t tid;
-
- tid = rdint(fd);
- if (tid & Builtinmask) {
- if (dest)
- *dest = traittab[tid & ~Builtinmask];
- if (ty)
- settrait(ty, traittab[tid & ~Builtinmask]);
- } else {
- lappend(&traitfixdest, &ntraitfixdest, dest);
- lappend(&traitfixtype, &ntraitfixtype, ty);
- lappend(&traitfixid, &ntraitfixid, itop(tid));
- }
+ uintptr_t tid;
+
+ tid = rdint(fd);
+ if (tid & Builtinmask) {
+ if (dest)
+ *dest = traittab[tid & ~Builtinmask];
+ if (ty)
+ settrait(ty, traittab[tid & ~Builtinmask]);
+ }
+ else {
+ lappend(&traitfixdest, &ntraitfixdest, dest);
+ lappend(&traitfixtype, &ntraitfixtype, ty);
+ lappend(&traitfixid, &ntraitfixid, itop(tid));
+ }
}
/* Writes types to a file. Errors on
@@ -337,94 +330,90 @@ static void rdtrait(FILE *fd, Trait **dest, Type *ty)
* will not be meaningful in another file */
static Type *tyunpickle(FILE *fd)
{
- size_t i, n;
- Type *ty;
- Ty t;
-
- t = rdbyte(fd);
- ty = mktype(Zloc, t);
- ty->isimport = 1;
- if (rdbyte(fd) == Vishidden)
- ty->ishidden = 1;
- /* tid is generated; don't write */
- n = rdint(fd);
- for (i = 0; i < n; i++)
- rdtrait(fd, NULL, ty);
- ty->nsub = rdint(fd);
- if (ty->nsub > 0)
- ty->sub = zalloc(ty->nsub * sizeof(Type*));
- switch (ty->type) {
- case Tyunres:
- ty->name = unpickle(fd);
- break;
- case Typaram:
- ty->pname = rdstr(fd);
- break;
- case Tystruct:
- ty->nmemb = rdint(fd);
- ty->sdecls = zalloc(ty->nmemb * sizeof(Node*));
- for (i = 0; i < ty->nmemb; i++)
- ty->sdecls[i] = unpickle(fd);
- break;
- case Tyunion:
- ty->nmemb = rdint(fd);
- ty->udecls = zalloc(ty->nmemb * sizeof(Node*));
- for (i = 0; i < ty->nmemb; i++)
- ty->udecls[i] = rducon(fd, ty);
- break;
- case Tyarray:
- rdtype(fd, &ty->sub[0]);
- ty->asize = unpickle(fd);
- break;
- case Tyslice:
- rdtype(fd, &ty->sub[0]);
- break;
- case Tyname:
- ty->name = unpickle(fd);
- ty->issynth = rdbool(fd);
- ty->narg = rdint(fd);
- ty->arg = zalloc(ty->narg * sizeof(Type *));
- for (i = 0; i < ty->narg; i++)
- rdtype(fd, &ty->arg[i]);
- rdtype(fd, &ty->sub[0]);
- break;
- case Tygeneric:
- ty->name = unpickle(fd);
- ty->issynth = rdbool(fd);
- ty->ngparam = rdint(fd);
- ty->gparam = zalloc(ty->ngparam * sizeof(Type *));
- for (i = 0; i < ty->ngparam; i++)
- rdtype(fd, &ty->gparam[i]);
- rdtype(fd, &ty->sub[0]);
- break;
- default:
- for (i = 0; i < ty->nsub; i++)
- rdtype(fd, &ty->sub[i]);
- break;
- }
- return ty;
+ size_t i, n;
+ Type *ty;
+ Ty t;
+
+ t = rdbyte(fd);
+ ty = mktype(Zloc, t);
+ ty->isimport = 1;
+ if (rdbyte(fd) == Vishidden)
+ ty->ishidden = 1;
+ /* tid is generated; don't write */
+ n = rdint(fd);
+ for (i = 0; i < n; i++)
+ rdtrait(fd, NULL, ty);
+ ty->nsub = rdint(fd);
+ if (ty->nsub > 0)
+ ty->sub = zalloc(ty->nsub * sizeof(Type *));
+ switch (ty->type) {
+ case Tyunres: ty->name = unpickle(fd); break;
+ case Typaram: ty->pname = rdstr(fd); break;
+ case Tystruct:
+ ty->nmemb = rdint(fd);
+ ty->sdecls = zalloc(ty->nmemb * sizeof(Node *));
+ for (i = 0; i < ty->nmemb; i++)
+ ty->sdecls[i] = unpickle(fd);
+ break;
+ case Tyunion:
+ ty->nmemb = rdint(fd);
+ ty->udecls = zalloc(ty->nmemb * sizeof(Node *));
+ for (i = 0; i < ty->nmemb; i++)
+ ty->udecls[i] = rducon(fd, ty);
+ break;
+ case Tyarray:
+ rdtype(fd, &ty->sub[0]);
+ ty->asize = unpickle(fd);
+ break;
+ case Tyslice:
+ rdtype(fd, &ty->sub[0]);
+ break;
+ case Tyname:
+ ty->name = unpickle(fd);
+ ty->issynth = rdbool(fd);
+ ty->narg = rdint(fd);
+ ty->arg = zalloc(ty->narg * sizeof(Type *));
+ for (i = 0; i < ty->narg; i++)
+ rdtype(fd, &ty->arg[i]);
+ rdtype(fd, &ty->sub[0]);
+ break;
+ case Tygeneric:
+ ty->name = unpickle(fd);
+ ty->issynth = rdbool(fd);
+ ty->ngparam = rdint(fd);
+ ty->gparam = zalloc(ty->ngparam * sizeof(Type *));
+ for (i = 0; i < ty->ngparam; i++)
+ rdtype(fd, &ty->gparam[i]);
+ rdtype(fd, &ty->sub[0]);
+ break;
+ default:
+ for (i = 0; i < ty->nsub; i++)
+ rdtype(fd, &ty->sub[i]);
+ break;
+ }
+ return ty;
}
Trait *traitunpickle(FILE *fd)
{
- Trait *tr;
- size_t i, n;
- intptr_t uid;
-
- /* create an empty trait */
- tr = mktrait(Zloc, NULL, NULL, NULL, 0, NULL, 0, 0);
- uid = rdint(fd);
- tr->ishidden = rdbool(fd);
- tr->name = unpickle(fd);
- tr->param = tyunpickle(fd);
- n = rdint(fd);
- for (i = 0; i < n; i++)
- lappend(&tr->memb, &tr->nmemb, rdsym(fd, tr));
- n = rdint(fd);
- for (i = 0; i < n; i++)
- lappend(&tr->funcs, &tr->nfuncs, rdsym(fd, tr));
- htput(trmap, itop(uid), tr);
- return tr;
+ Trait *tr;
+ size_t i, n;
+ intptr_t uid;
+
+ /* create an empty trait */
+ tr = mktrait(Zloc, NULL, NULL, NULL, 0, NULL, 0, 0);
+ uid = rdint(fd);
+ tr->ishidden = rdbool(fd);
+ tr->name = unpickle(fd);
+ tr->param = tyunpickle(fd);
+ n = rdint(fd);
+ for (i = 0; i < n; i++)
+ lappend(&tr->memb, &tr->nmemb, rdsym(fd, tr));
+ n = rdint(fd);
+ for (i = 0; i < n; i++)
+ lappend(&tr->funcs, &tr->nfuncs, rdsym(fd, tr));
+ htput(trmap, itop(uid), tr);
+ return tr;
}
/* Pickles a node to a file. The format
@@ -435,127 +424,125 @@ Trait *traitunpickle(FILE *fd)
* crash the compiler */
static void pickle(FILE *fd, Node *n)
{
- size_t i;
-
- if (!n) {
- wrbyte(fd, Nnone);
- return;
- }
- wrbyte(fd, n->type);
- wrint(fd, n->loc.line);
- switch (n->type) {
- case Nfile:
- wrstr(fd, n->file.files[0]);
- wrint(fd, n->file.nuses);
- for (i = 0; i < n->file.nuses; i++)
- pickle(fd, n->file.uses[i]);
- wrint(fd, n->file.nstmts);
- for (i = 0; i < n->file.nstmts; i++)
- pickle(fd, n->file.stmts[i]);
- wrstab(fd, n->file.globls);
- break;
-
- case Nexpr:
- wrbyte(fd, n->expr.op);
- wrtype(fd, n->expr.type);
- wrbool(fd, n->expr.isconst);
- pickle(fd, n->expr.idx);
- wrint(fd, n->expr.nargs);
- for (i = 0; i < n->expr.nargs; i++)
- pickle(fd, n->expr.args[i]);
- break;
- case Nname:
- wrbool(fd, n->name.ns != NULL);
- if (n->name.ns) {
- wrstr(fd, n->name.ns);
- }
- wrstr(fd, n->name.name);
- break;
- case Nuse:
- wrbool(fd, n->use.islocal);
- wrstr(fd, n->use.name);
- break;
- case Nlit:
- wrbyte(fd, n->lit.littype);
- wrtype(fd, n->lit.type);
- wrint(fd, n->lit.nelt);
- switch (n->lit.littype) {
- case Lchr: wrint(fd, n->lit.chrval); break;
- case Lint: wrint(fd, n->lit.intval); break;
- case Lflt: wrflt(fd, n->lit.fltval); break;
- case Lstr: wrlenstr(fd, n->lit.strval); break;
- case Llbl: wrstr(fd, n->lit.lblval); break;
- case Lbool: wrbool(fd, n->lit.boolval); break;
- case Lfunc: pickle(fd, n->lit.fnval); break;
- }
- break;
- case Nloopstmt:
- pickle(fd, n->loopstmt.init);
- pickle(fd, n->loopstmt.cond);
- pickle(fd, n->loopstmt.step);
- pickle(fd, n->loopstmt.body);
- break;
- case Niterstmt:
- pickle(fd, n->iterstmt.elt);
- pickle(fd, n->iterstmt.seq);
- pickle(fd, n->iterstmt.body);
- break;
- case Nmatchstmt:
- pickle(fd, n->matchstmt.val);
- wrint(fd, n->matchstmt.nmatches);
- for (i = 0; i < n->matchstmt.nmatches; i++)
- pickle(fd, n->matchstmt.matches[i]);
- break;
- case Nmatch:
- pickle(fd, n->match.pat);
- pickle(fd, n->match.block);
- break;
- case Nifstmt:
- pickle(fd, n->ifstmt.cond);
- pickle(fd, n->ifstmt.iftrue);
- pickle(fd, n->ifstmt.iffalse);
- break;
- case Nblock:
- wrstab(fd, n->block.scope);
- wrint(fd, n->block.nstmts);
- for (i = 0; i < n->block.nstmts; i++)
- pickle(fd, n->block.stmts[i]);
- break;
- case Ndecl:
- /* sym */
- pickle(fd, n->decl.name);
- wrtype(fd, n->decl.type);
-
- /* symflags */
- wrbool(fd, n->decl.isconst);
- wrbool(fd, n->decl.isgeneric);
- wrbool(fd, n->decl.isextern);
- wrbool(fd, n->decl.isnoret);
- wrbool(fd, n->decl.ispkglocal);
-
- /* init */
- pickle(fd, n->decl.init);
- break;
- case Nfunc:
- wrtype(fd, n->func.type);
- wrstab(fd, n->func.scope);
- wrint(fd, n->func.nargs);
- for (i = 0; i < n->func.nargs; i++)
- pickle(fd, n->func.args[i]);
- pickle(fd, n->func.body);
- break;
- case Nimpl:
- pickle(fd, n->impl.traitname);
- wrint(fd, n->impl.trait->uid);
- wrtype(fd, n->impl.type);
- wrint(fd, n->impl.ndecls);
- for (i = 0; i < n->impl.ndecls; i++)
- wrsym(fd, n->impl.decls[i]);
- break;
- case Nnone:
- die("Nnone should not be seen as node type!");
- break;
- }
+ size_t i;
+
+ if (!n) {
+ wrbyte(fd, Nnone);
+ return;
+ }
+ wrbyte(fd, n->type);
+ wrint(fd, n->loc.line);
+ switch (n->type) {
+ case Nfile:
+ wrstr(fd, n->file.files[0]);
+ wrint(fd, n->file.nuses);
+ for (i = 0; i < n->file.nuses; i++)
+ pickle(fd, n->file.uses[i]);
+ wrint(fd, n->file.nstmts);
+ for (i = 0; i < n->file.nstmts; i++)
+ pickle(fd, n->file.stmts[i]);
+ wrstab(fd, n->file.globls);
+ break;
+
+ case Nexpr:
+ wrbyte(fd, n->expr.op);
+ wrtype(fd, n->expr.type);
+ wrbool(fd, n->expr.isconst);
+ pickle(fd, n->expr.idx);
+ wrint(fd, n->expr.nargs);
+ for (i = 0; i < n->expr.nargs; i++)
+ pickle(fd, n->expr.args[i]);
+ break;
+ case Nname:
+ wrbool(fd, n->name.ns != NULL);
+ if (n->name.ns) {
+ wrstr(fd, n->name.ns);
+ }
+ wrstr(fd, n->name.name);
+ break;
+ case Nuse:
+ wrbool(fd, n->use.islocal);
+ wrstr(fd, n->use.name);
+ break;
+ case Nlit:
+ wrbyte(fd, n->lit.littype);
+ wrtype(fd, n->lit.type);
+ wrint(fd, n->lit.nelt);
+ switch (n->lit.littype) {
+ case Lchr: wrint(fd, n->lit.chrval); break;
+ case Lint: wrint(fd, n->lit.intval); break;
+ case Lflt: wrflt(fd, n->lit.fltval); break;
+ case Lstr: wrlenstr(fd, n->lit.strval); break;
+ case Llbl: wrstr(fd, n->lit.lblval); break;
+ case Lbool: wrbool(fd, n->lit.boolval); break;
+ case Lfunc: pickle(fd, n->lit.fnval); break;
+ }
+ break;
+ case Nloopstmt:
+ pickle(fd, n->loopstmt.init);
+ pickle(fd, n->loopstmt.cond);
+ pickle(fd, n->loopstmt.step);
+ pickle(fd, n->loopstmt.body);
+ break;
+ case Niterstmt:
+ pickle(fd, n->iterstmt.elt);
+ pickle(fd, n->iterstmt.seq);
+ pickle(fd, n->iterstmt.body);
+ break;
+ case Nmatchstmt:
+ pickle(fd, n->matchstmt.val);
+ wrint(fd, n->matchstmt.nmatches);
+ for (i = 0; i < n->matchstmt.nmatches; i++)
+ pickle(fd, n->matchstmt.matches[i]);
+ break;
+ case Nmatch:
+ pickle(fd, n->match.pat);
+ pickle(fd, n->match.block);
+ break;
+ case Nifstmt:
+ pickle(fd, n->ifstmt.cond);
+ pickle(fd, n->ifstmt.iftrue);
+ pickle(fd, n->ifstmt.iffalse);
+ break;
+ case Nblock:
+ wrstab(fd, n->block.scope);
+ wrint(fd, n->block.nstmts);
+ for (i = 0; i < n->block.nstmts; i++)
+ pickle(fd, n->block.stmts[i]);
+ break;
+ case Ndecl:
+ /* sym */
+ pickle(fd, n->decl.name);
+ wrtype(fd, n->decl.type);
+
+ /* symflags */
+ wrbool(fd, n->decl.isconst);
+ wrbool(fd, n->decl.isgeneric);
+ wrbool(fd, n->decl.isextern);
+ wrbool(fd, n->decl.isnoret);
+ wrbool(fd, n->decl.ispkglocal);
+
+ /* init */
+ pickle(fd, n->decl.init);
+ break;
+ case Nfunc:
+ wrtype(fd, n->func.type);
+ wrstab(fd, n->func.scope);
+ wrint(fd, n->func.nargs);
+ for (i = 0; i < n->func.nargs; i++)
+ pickle(fd, n->func.args[i]);
+ pickle(fd, n->func.body);
+ break;
+ case Nimpl:
+ pickle(fd, n->impl.traitname);
+ wrint(fd, n->impl.trait->uid);
+ wrtype(fd, n->impl.type);
+ wrint(fd, n->impl.ndecls);
+ for (i = 0; i < n->impl.ndecls; i++)
+ wrsym(fd, n->impl.decls[i]);
+ break;
+ case Nnone: die("Nnone should not be seen as node type!"); break;
+ }
}
/* Unpickles a node from a file. Minimal checking
@@ -563,243 +550,243 @@ static void pickle(FILE *fd, Node *n)
* sane arities, a bad file can crash the compiler */
static Node *unpickle(FILE *fd)
{
- size_t i;
- Ntype type;
- Node *n;
-
- type = rdbyte(fd);
- if (type == Nnone)
- return NULL;
- n = mknode(Zloc, type);
- n->loc.line = rdint(fd);
- n->loc.file = file->file.nfiles - 1;
- switch (n->type) {
- case Nfile:
- lappend(&n->file.files, &n->file.nfiles, rdstr(fd));
- n->file.nuses = rdint(fd);
- n->file.uses = zalloc(sizeof(Node*)*n->file.nuses);
- for (i = 0; i < n->file.nuses; i++)
- n->file.uses[i] = unpickle(fd);
- n->file.nstmts = rdint(fd);
- n->file.stmts = zalloc(sizeof(Node*)*n->file.nstmts);
- for (i = 0; i < n->file.nstmts; i++)
- n->file.stmts[i] = unpickle(fd);
- n->file.globls = rdstab(fd, 0);
- break;
-
- case Nexpr:
- n->expr.op = rdbyte(fd);
- rdtype(fd, &n->expr.type);
- n->expr.isconst = rdbool(fd);
- n->expr.idx = unpickle(fd);
- n->expr.nargs = rdint(fd);
- n->expr.args = zalloc(sizeof(Node *)*n->expr.nargs);
- for (i = 0; i < n->expr.nargs; i++)
- n->expr.args[i] = unpickle(fd);
- break;
- case Nname:
- if (rdbool(fd))
- n->name.ns = rdstr(fd);
- n->name.name = rdstr(fd);
- break;
- case Nuse:
- n->use.islocal = rdbool(fd);
- n->use.name = rdstr(fd);
- break;
- case Nlit:
- n->lit.littype = rdbyte(fd);
- rdtype(fd, &n->lit.type);
- n->lit.nelt = rdint(fd);
- switch (n->lit.littype) {
- case Lchr: n->lit.chrval = rdint(fd); break;
- case Lint: n->lit.intval = rdint(fd); break;
- case Lflt: n->lit.fltval = rdflt(fd); break;
- case Lstr: rdlenstr(fd, &n->lit.strval); break;
- case Llbl: n->lit.lblval = rdstr(fd); break;
- case Lbool: n->lit.boolval = rdbool(fd); break;
- case Lfunc: n->lit.fnval = unpickle(fd); break;
- }
- break;
- case Nloopstmt:
- n->loopstmt.init = unpickle(fd);
- n->loopstmt.cond = unpickle(fd);
- n->loopstmt.step = unpickle(fd);
- n->loopstmt.body = unpickle(fd);
- break;
- case Niterstmt:
- n->iterstmt.elt = unpickle(fd);
- n->iterstmt.seq = unpickle(fd);
- n->iterstmt.body = unpickle(fd);
- break;
- case Nmatchstmt:
- n->matchstmt.val = unpickle(fd);
- n->matchstmt.nmatches = rdint(fd);
- n->matchstmt.matches = zalloc(sizeof(Node *)*n->matchstmt.nmatches);
- for (i = 0; i < n->matchstmt.nmatches; i++)
- n->matchstmt.matches[i] = unpickle(fd);
- break;
- case Nmatch:
- n->match.pat = unpickle(fd);
- n->match.block = unpickle(fd);
- break;
- case Nifstmt:
- n->ifstmt.cond = unpickle(fd);
- n->ifstmt.iftrue = unpickle(fd);
- n->ifstmt.iffalse = unpickle(fd);
- break;
- case Nblock:
- n->block.scope = rdstab(fd, 0);
- n->block.nstmts = rdint(fd);
- n->block.stmts = zalloc(sizeof(Node *)*n->block.nstmts);
- n->block.scope->super = curstab();
- pushstab(n->func.scope->super);
- for (i = 0; i < n->block.nstmts; i++)
- n->block.stmts[i] = unpickle(fd);
- popstab();
- break;
- case Ndecl:
- n->decl.did = ndecls; /* unique within file */
- /* sym */
- n->decl.name = unpickle(fd);
- rdtype(fd, &n->decl.type);
-
- /* symflags */
- n->decl.isconst = rdbool(fd);
- n->decl.isgeneric = rdbool(fd);
- n->decl.isextern = rdbool(fd);
- n->decl.isnoret = rdbool(fd);
- n->decl.ispkglocal = rdbool(fd);
-
- /* init */
- n->decl.init = unpickle(fd);
- lappend(&decls, &ndecls, n);
- break;
- case Nfunc:
- rdtype(fd, &n->func.type);
- n->func.scope = rdstab(fd, 1);
- n->func.nargs = rdint(fd);
- n->func.args = zalloc(sizeof(Node *)*n->func.nargs);
- n->func.scope->super = curstab();
- pushstab(n->func.scope->super);
- for (i = 0; i < n->func.nargs; i++)
- n->func.args[i] = unpickle(fd);
- n->func.body = unpickle(fd);
- popstab();
- break;
- case Nimpl:
- n->impl.traitname = unpickle(fd);
- i = rdint(fd);
- rdtrait(fd, &n->impl.trait, NULL);
- rdtype(fd, &n->impl.type);
- n->impl.ndecls = rdint(fd);
- n->impl.decls = zalloc(sizeof(Node *)*n->impl.ndecls);
- for (i = 0; i < n->impl.ndecls; i++)
- n->impl.decls[i] = rdsym(fd, n->impl.trait);
- break;
- case Nnone:
- die("Nnone should not be seen as node type!");
- break;
- }
- return n;
+ size_t i;
+ Ntype type;
+ Node *n;
+
+ type = rdbyte(fd);
+ if (type == Nnone)
+ return NULL;
+ n = mknode(Zloc, type);
+ n->loc.line = rdint(fd);
+ n->loc.file = file->file.nfiles - 1;
+ switch (n->type) {
+ case Nfile:
+ lappend(&n->file.files, &n->file.nfiles, rdstr(fd));
+ n->file.nuses = rdint(fd);
+ n->file.uses = zalloc(sizeof(Node *) * n->file.nuses);
+ for (i = 0; i < n->file.nuses; i++)
+ n->file.uses[i] = unpickle(fd);
+ n->file.nstmts = rdint(fd);
+ n->file.stmts = zalloc(sizeof(Node *) * n->file.nstmts);
+ for (i = 0; i < n->file.nstmts; i++)
+ n->file.stmts[i] = unpickle(fd);
+ n->file.globls = rdstab(fd, 0);
+ break;
+
+ case Nexpr:
+ n->expr.op = rdbyte(fd);
+ rdtype(fd, &n->expr.type);
+ n->expr.isconst = rdbool(fd);
+ n->expr.idx = unpickle(fd);
+ n->expr.nargs = rdint(fd);
+ n->expr.args = zalloc(sizeof(Node *) * n->expr.nargs);
+ for (i = 0; i < n->expr.nargs; i++)
+ n->expr.args[i] = unpickle(fd);
+ break;
+ case Nname:
+ if (rdbool(fd))
+ n->name.ns = rdstr(fd);
+ n->name.name = rdstr(fd);
+ break;
+ case Nuse:
+ n->use.islocal = rdbool(fd);
+ n->use.name = rdstr(fd);
+ break;
+ case Nlit:
+ n->lit.littype = rdbyte(fd);
+ rdtype(fd, &n->lit.type);
+ n->lit.nelt = rdint(fd);
+ switch (n->lit.littype) {
+ case Lchr: n->lit.chrval = rdint(fd); break;
+ case Lint: n->lit.intval = rdint(fd); break;
+ case Lflt: n->lit.fltval = rdflt(fd); break;
+ case Lstr: rdlenstr(fd, &n->lit.strval); break;
+ case Llbl: n->lit.lblval = rdstr(fd); break;
+ case Lbool: n->lit.boolval = rdbool(fd); break;
+ case Lfunc: n->lit.fnval = unpickle(fd); break;
+ }
+ break;
+ case Nloopstmt:
+ n->loopstmt.init = unpickle(fd);
+ n->loopstmt.cond = unpickle(fd);
+ n->loopstmt.step = unpickle(fd);
+ n->loopstmt.body = unpickle(fd);
+ break;
+ case Niterstmt:
+ n->iterstmt.elt = unpickle(fd);
+ n->iterstmt.seq = unpickle(fd);
+ n->iterstmt.body = unpickle(fd);
+ break;
+ case Nmatchstmt:
+ n->matchstmt.val = unpickle(fd);
+ n->matchstmt.nmatches = rdint(fd);
+ n->matchstmt.matches = zalloc(sizeof(Node *) * n->matchstmt.nmatches);
+ for (i = 0; i < n->matchstmt.nmatches; i++)
+ n->matchstmt.matches[i] = unpickle(fd);
+ break;
+ case Nmatch:
+ n->match.pat = unpickle(fd);
+ n->match.block = unpickle(fd);
+ break;
+ case Nifstmt:
+ n->ifstmt.cond = unpickle(fd);
+ n->ifstmt.iftrue = unpickle(fd);
+ n->ifstmt.iffalse = unpickle(fd);
+ break;
+ case Nblock:
+ n->block.scope = rdstab(fd, 0);
+ n->block.nstmts = rdint(fd);
+ n->block.stmts = zalloc(sizeof(Node *) * n->block.nstmts);
+ n->block.scope->super = curstab();
+ pushstab(n->func.scope->super);
+ for (i = 0; i < n->block.nstmts; i++)
+ n->block.stmts[i] = unpickle(fd);
+ popstab();
+ break;
+ case Ndecl:
+ n->decl.did = ndecls; /* unique within file */
+ /* sym */
+ n->decl.name = unpickle(fd);
+ rdtype(fd, &n->decl.type);
+
+ /* symflags */
+ n->decl.isconst = rdbool(fd);
+ n->decl.isgeneric = rdbool(fd);
+ n->decl.isextern = rdbool(fd);
+ n->decl.isnoret = rdbool(fd);
+ n->decl.ispkglocal = rdbool(fd);
+
+ /* init */
+ n->decl.init = unpickle(fd);
+ lappend(&decls, &ndecls, n);
+ break;
+ case Nfunc:
+ rdtype(fd, &n->func.type);
+ n->func.scope = rdstab(fd, 1);
+ n->func.nargs = rdint(fd);
+ n->func.args = zalloc(sizeof(Node *) * n->func.nargs);
+ n->func.scope->super = curstab();
+ pushstab(n->func.scope->super);
+ for (i = 0; i < n->func.nargs; i++)
+ n->func.args[i] = unpickle(fd);
+ n->func.body = unpickle(fd);
+ popstab();
+ break;
+ case Nimpl:
+ n->impl.traitname = unpickle(fd);
+ i = rdint(fd);
+ rdtrait(fd, &n->impl.trait, NULL);
+ rdtype(fd, &n->impl.type);
+ n->impl.ndecls = rdint(fd);
+ n->impl.decls = zalloc(sizeof(Node *) * n->impl.ndecls);
+ for (i = 0; i < n->impl.ndecls; i++)
+ n->impl.decls[i] = rdsym(fd, n->impl.trait);
+ break;
+ case Nnone:
+ die("Nnone should not be seen as node type!");
+ break;
+ }
+ return n;
}
static Stab *findstab(Stab *st, char *pkg)
{
- Stab *s;
-
- if (!pkg) {
- if (!st->name)
- return st;
- else
- return NULL;
- }
-
- s = getns(file, pkg);
- if (!s) {
- s = mkstab(0);
- s->name = strdup(pkg);
- putns(file, s);
- }
- return s;
+ Stab *s;
+
+ if (!pkg) {
+ if (!st->name)
+ return st;
+ else
+ return NULL;
+ }
+
+ s = getns(file, pkg);
+ if (!s) {
+ s = mkstab(0);
+ s->name = strdup(pkg);
+ putns(file, s);
+ }
+ return s;
}
static int isspecialization(Type *t1, Type *t2)
{
- if ((t1->type != Tygeneric || t2->type != Tyname) &&
- (t1->type != Tyname || t2->type != Tygeneric) &&
- (t1->type != Tyname || t2->type != Tyname))
- return 0;
- /* FIXME: this should be done better */
- return nameeq(t1->name, t2->name);
+ if ((t1->type != Tygeneric || t2->type != Tyname) &&
+ (t1->type != Tyname || t2->type != Tygeneric) &&
+ (t1->type != Tyname || t2->type != Tyname))
+ return 0;
+ /* FIXME: this should be done better */
+ return nameeq(t1->name, t2->name);
}
static void fixtypemappings(Stab *st)
{
- size_t i;
- Type *t, *old;
-
-
- /*
- * merge duplicate definitions.
- * This allows us to compare named types by id, instead
- * of doing a deep walk through the type. This ability is
- * depended on when we do type inference.
- */
- for (i = 0; i < ntypefixdest; i++) {
- t = htget(tidmap, itop(typefixid[i]));
- if (!t)
- die("Unable to find type for id %zd\n", typefixid[i]);
- *typefixdest[i] = t;
- }
- for (i = 0; i < ntypefixdest; i++) {
- old = *typefixdest[i];
- if (old->type == Tyname || old->type == Tygeneric) {
- t = htget(tydedup, old);
- if (!t) {
- t = old;
- htput(tydedup, old, old);
- }
- *typefixdest[i] = t;
- }
- }
-
- /* check for duplicate type definitions */
- for (i = 0; i < ntypefixdest; i++) {
- t = htget(tidmap, itop(typefixid[i]));
- if ((t->type != Tyname && t->type != Tygeneric) || t->issynth)
- continue;
- old = htget(tydedup, t);
- if (old && !tyeq(t, old) && !isspecialization(t, old))
- lfatal(t->loc, "Duplicate definition of type %s on %s:%d", tystr(old), file->file.files[old->loc.file], old->loc.line);
- }
- for (i = 0; i < ntypefixdest; i++)
- lfree(&typefixdest, &ntypefixdest);
- lfree(&typefixid, &ntypefixid);
+ size_t i;
+ Type *t, *old;
+
+ /*
+ * merge duplicate definitions.
+ * This allows us to compare named types by id, instead
+ * of doing a deep walk through the type. This ability is
+ * depended on when we do type inference.
+ */
+ for (i = 0; i < ntypefixdest; i++) {
+ t = htget(tidmap, itop(typefixid[i]));
+ if (!t)
+ die("Unable to find type for id %zd\n", typefixid[i]);
+ *typefixdest[i] = t;
+ }
+ for (i = 0; i < ntypefixdest; i++) {
+ old = *typefixdest[i];
+ if (old->type == Tyname || old->type == Tygeneric) {
+ t = htget(tydedup, old);
+ if (!t) {
+ t = old;
+ htput(tydedup, old, old);
+ }
+ *typefixdest[i] = t;
+ }
+ }
+
+ /* check for duplicate type definitions */
+ for (i = 0; i < ntypefixdest; i++) {
+ t = htget(tidmap, itop(typefixid[i]));
+ if ((t->type != Tyname && t->type != Tygeneric) || t->issynth)
+ continue;
+ old = htget(tydedup, t);
+ if (old && !tyeq(t, old) && !isspecialization(t, old))
+ lfatal(t->loc, "Duplicate definition of type %s on %s:%d", tystr(old),
+ file->file.files[old->loc.file], old->loc.line);
+ }
+ for (i = 0; i < ntypefixdest; i++)
+ lfree(&typefixdest, &ntypefixdest);
+ lfree(&typefixid, &ntypefixid);
}
static void fixtraitmappings(Stab *st)
{
- size_t i;
- Trait *t;
-
- /*
- * merge duplicate definitions.
- * This allows us to compare named types by id, instead
- * of doing a deep walk through the type. This ability is
- * depended on when we do type inference.
- */
- for (i = 0; i < ntraitfixdest; i++) {
- t = htget(trmap, itop(traitfixid[i]));
- if (!t)
- die("Unable to find trait for id %zd\n", traitfixid[i]);
- if (traitfixdest[i])
- *traitfixdest[i] = t;
- if (traitfixtype[i])
- settrait(traitfixtype[i], t);
- }
-
- lfree(&traitfixdest, &ntraitfixdest);
- lfree(&traitfixid, &ntraitfixid);
+ size_t i;
+ Trait *t;
+
+ /*
+ * merge duplicate definitions.
+ * This allows us to compare named types by id, instead
+ * of doing a deep walk through the type. This ability is
+ * depended on when we do type inference.
+ */
+ for (i = 0; i < ntraitfixdest; i++) {
+ t = htget(trmap, itop(traitfixid[i]));
+ if (!t)
+ die("Unable to find trait for id %zd\n", traitfixid[i]);
+ if (traitfixdest[i])
+ *traitfixdest[i] = t;
+ if (traitfixtype[i])
+ settrait(traitfixtype[i], t);
+ }
+
+ lfree(&traitfixdest, &ntraitfixdest);
+ lfree(&traitfixid, &ntraitfixid);
}
/* Usefile format:
@@ -812,169 +799,172 @@ static void fixtraitmappings(Stab *st)
*/
int loaduse(char *path, FILE *f, Stab *st, Vis vis)
{
- intptr_t tid;
- size_t i;
- int v;
- char *pkg;
- Node *dcl, *impl, *init;
- Stab *s;
- Type *ty;
- Trait *tr;
- char *lib;
- int c;
-
- pushstab(file->file.globls);
- if (!tydedup)
- tydedup = mkht(tyhash, tyeq);
- if (fgetc(f) != 'U')
- return 0;
- v = rdint(f);
- if (v != Abiversion) {
- fprintf(stderr, "%s: abi version %d, expected %d\n", path, v, Abiversion);
- return 0;
- }
- pkg = rdstr(f);
- /* if the package names match up, or the usefile has no declared
- * package, then we simply add to the current stab. Otherwise,
- * we add a new stab under the current one */
- if (st->name) {
- if (pkg && !strcmp(pkg, st->name)) {
- s = st;
- } else {
- s = findstab(st, pkg);
- }
- } else {
- if (pkg) {
- s = findstab(st, pkg);
- } else {
- s = st;
- }
- }
- if (!streq(st->name, pkg))
- vis = Visintern;
- if (!s) {
- printf("could not find matching package for merge: %s in %s\n", st->name, path);
- exit(1);
- }
- tidmap = mkht(ptrhash, ptreq);
- trmap = mkht(ptrhash, ptreq);
- if (!initmap)
- initmap = mkht(namehash, nameeq);
- /* builtin traits */
- for (i = 0; i < Ntraits; i++)
- htput(trmap, itop(i), traittab[i]);
- while ((c = fgetc(f)) != EOF) {
- switch(c) {
- case 'L':
- lib = rdstr(f);
- for (i = 0; i < file->file.nlibdeps; i++)
- if (!strcmp(file->file.libdeps[i], lib))
- /* break out of both loop and switch */
- goto foundlib;
- lappend(&file->file.libdeps, &file->file.nlibdeps, lib);
+ intptr_t tid;
+ size_t i;
+ int v;
+ char *pkg;
+ Node *dcl, *impl, *init;
+ Stab *s;
+ Type *ty;
+ Trait *tr;
+ char *lib;
+ int c;
+
+ pushstab(file->file.globls);
+ if (!tydedup)
+ tydedup = mkht(tyhash, tyeq);
+ if (fgetc(f) != 'U')
+ return 0;
+ v = rdint(f);
+ if (v != Abiversion) {
+ fprintf(stderr, "%s: abi version %d, expected %d\n", path, v, Abiversion);
+ return 0;
+ }
+ pkg = rdstr(f);
+ /* if the package names match up, or the usefile has no declared
+ * package, then we simply add to the current stab. Otherwise,
+ * we add a new stab under the current one */
+ if (st->name) {
+ if (pkg && !strcmp(pkg, st->name)) {
+ s = st;
+ }
+ else {
+ s = findstab(st, pkg);
+ }
+ }
+ else {
+ if (pkg) {
+ s = findstab(st, pkg);
+ }
+ else {
+ s = st;
+ }
+ }
+ if (!streq(st->name, pkg))
+ vis = Visintern;
+ if (!s) {
+ printf("could not find matching package for merge: %s in %s\n", st->name, path);
+ exit(1);
+ }
+ tidmap = mkht(ptrhash, ptreq);
+ trmap = mkht(ptrhash, ptreq);
+ if (!initmap)
+ initmap = mkht(namehash, nameeq);
+ /* builtin traits */
+ for (i = 0; i < Ntraits; i++)
+ htput(trmap, itop(i), traittab[i]);
+ while ((c = fgetc(f)) != EOF) {
+ switch (c) {
+ case 'L':
+ lib = rdstr(f);
+ for (i = 0; i < file->file.nlibdeps; i++)
+ if (!strcmp(file->file.libdeps[i], lib))
+ /* break out of both loop and switch */
+ goto foundlib;
+ lappend(&file->file.libdeps, &file->file.nlibdeps, lib);
foundlib:
- break;
- case 'X':
- lib = rdstr(f);
- for (i = 0; i < file->file.nextlibs; i++)
- if (!strcmp(file->file.extlibs[i], lib))
- /* break out of both loop and switch */
- goto foundextlib;
- lappend(&file->file.extlibs, &file->file.nextlibs, lib);
+ break;
+ case 'X':
+ lib = rdstr(f);
+ for (i = 0; i < file->file.nextlibs; i++)
+ if (!strcmp(file->file.extlibs[i], lib))
+ /* break out of both loop and switch */
+ goto foundextlib;
+ lappend(&file->file.extlibs, &file->file.nextlibs, lib);
foundextlib:
- break;
- case 'F':
- lappend(&file->file.files, &file->file.nfiles, rdstr(f));
- break;
- case 'G':
- case 'D':
- dcl = rdsym(f, NULL);
- dcl->decl.vis = vis;
- dcl->decl.isglobl = 1;
- putdcl(s, dcl);
- break;
- case 'S':
- init = unpickle(f);
- if (!hthas(initmap, init)) {
- htput(initmap, init, init);
- lappend(&file->file.init, &file->file.ninit, init);
- }
- break;
- case 'R':
- tr = traitunpickle(f);
- tr->vis = vis;
- puttrait(s, tr->name, tr);
- for (i = 0; i < tr->nfuncs; i++)
- putdcl(s, tr->funcs[i]);
- break;
- case 'T':
- tid = rdint(f);
- ty = tyunpickle(f);
- if(!ty->ishidden)
- ty->vis = vis;
- htput(tidmap, itop(tid), ty);
- /* fix up types */
- if (ty->type == Tyname || ty->type == Tygeneric) {
- if (ty->issynth)
- break;
- if (!streq(s->name, ty->name->name.ns))
- ty->ishidden = 1;
- if (!gettype(s, ty->name) && !ty->ishidden)
- puttype(s, ty->name, ty);
- } else if (ty->type == Tyunion) {
- for (i = 0; i < ty->nmemb; i++)
- if (!getucon(s, ty->udecls[i]->name) && !ty->udecls[i]->synth)
- putucon(s, ty->udecls[i]);
- }
- break;
- case 'I':
- impl = unpickle(f);
- putimpl(s, impl);
- /* specialized declarations always go into the global stab */
- for (i = 0; i < impl->impl.ndecls; i++)
- putdcl(file->file.globls, impl->impl.decls[i]);
- break;
- case EOF:
- break;
- }
- }
- fixtypemappings(s);
- fixtraitmappings(s);
- htfree(tidmap);
- popstab();
- return 1;
+ break;
+ case 'F': lappend(&file->file.files, &file->file.nfiles, rdstr(f)); break;
+ case 'G':
+ case 'D':
+ dcl = rdsym(f, NULL);
+ dcl->decl.vis = vis;
+ dcl->decl.isglobl = 1;
+ putdcl(s, dcl);
+ break;
+ case 'S':
+ init = unpickle(f);
+ if (!hthas(initmap, init)) {
+ htput(initmap, init, init);
+ lappend(&file->file.init, &file->file.ninit, init);
+ }
+ break;
+ case 'R':
+ tr = traitunpickle(f);
+ tr->vis = vis;
+ puttrait(s, tr->name, tr);
+ for (i = 0; i < tr->nfuncs; i++)
+ putdcl(s, tr->funcs[i]);
+ break;
+ case 'T':
+ tid = rdint(f);
+ ty = tyunpickle(f);
+ if (!ty->ishidden)
+ ty->vis = vis;
+ htput(tidmap, itop(tid), ty);
+ /* fix up types */
+ if (ty->type == Tyname || ty->type == Tygeneric) {
+ if (ty->issynth)
+ break;
+ if (!streq(s->name, ty->name->name.ns))
+ ty->ishidden = 1;
+ if (!gettype(s, ty->name) && !ty->ishidden)
+ puttype(s, ty->name, ty);
+ }
+ else if (ty->type == Tyunion) {
+ for (i = 0; i < ty->nmemb; i++)
+ if (!getucon(s, ty->udecls[i]->name) &&
+ !ty->udecls[i]->synth)
+ putucon(s, ty->udecls[i]);
+ }
+ break;
+ case 'I':
+ impl = unpickle(f);
+ putimpl(s, impl);
+ /* specialized declarations always go into the global stab */
+ for (i = 0; i < impl->impl.ndecls; i++)
+ putdcl(file->file.globls, impl->impl.decls[i]);
+ break;
+ case EOF: break;
+ }
+ }
+ fixtypemappings(s);
+ fixtraitmappings(s);
+ htfree(tidmap);
+ popstab();
+ return 1;
}
void readuse(Node *use, Stab *st, Vis vis)
{
- size_t i;
- FILE *fd;
- char *t, *p;
-
- /* local (quoted) uses are always relative to the cwd */
- fd = NULL;
- p = NULL;
- if (use->use.islocal) {
- p = strdup(use->use.name);
- fd = fopen(p, "r");
- /* nonlocal (barename) uses are always searched on the include path */
- } else {
- for (i = 0; i < nincpaths; i++) {
- t = strjoin(incpaths[i], "/");
- p = strjoin(t, use->use.name);
- fd = fopen(p, "r");
- if (fd) {
- free(t);
- break;
- }
- }
- }
- if (!fd)
- fatal(use, "Could not open %s", use->use.name);
-
- if (!loaduse(p, fd, st, vis))
- die("Could not load usefile %s from %s", use->use.name, p);
- free(p);
+ size_t i;
+ FILE *fd;
+ char *t, *p;
+
+ /* local (quoted) uses are always relative to the cwd */
+ fd = NULL;
+ p = NULL;
+ if (use->use.islocal) {
+ p = strdup(use->use.name);
+ fd = fopen(p, "r");
+ /* nonlocal (barename) uses are always searched on the include path */
+ }
+ else {
+ for (i = 0; i < nincpaths; i++) {
+ t = strjoin(incpaths[i], "/");
+ p = strjoin(t, use->use.name);
+ fd = fopen(p, "r");
+ if (fd) {
+ free(t);
+ break;
+ }
+ }
+ }
+ if (!fd)
+ fatal(use, "Could not open %s", use->use.name);
+
+ if (!loaduse(p, fd, st, vis))
+ die("Could not load usefile %s from %s", use->use.name, p);
+ free(p);
}
/* Usefile format:
@@ -988,92 +978,92 @@ void readuse(Node *use, Stab *st, Vis vis)
*/
void writeuse(FILE *f, Node *file)
{
- Stab *st;
- void **k;
- Node *s, *u;
- size_t i, n;
-
- assert(file->type == Nfile);
- st = file->file.globls;
-
- /* usefile name */
- wrbyte(f, 'U');
- wrint(f, Abiversion); /* use version */
- if (st->name)
- wrstr(f, st->name);
- else
- wrstr(f, NULL);
-
- /* library deps */
- for (i = 0; i < file->file.nuses; i++) {
- u = file->file.uses[i];
- if (!u->use.islocal) {
- wrbyte(f, 'L');
- wrstr(f, u->use.name);
- }
- }
- for (i = 0; i < file->file.nlibdeps; i++) {
- wrbyte(f, 'L');
- wrstr(f, file->file.libdeps[i]);
- }
- for (i = 0; i < file->file.nextlibs; i++) {
- wrbyte(f, 'X');
- wrstr(f, file->file.extlibs[i]);
- }
-
- /* source file name */
- wrbyte(f, 'F');
- wrstr(f, file->file.files[0]);
-
- for (i = 0; i < ntypes; i++) {
- if (types[i]->vis == Visexport || types[i]->vis == Vishidden) {
- wrbyte(f, 'T');
- wrint(f, types[i]->tid);
- typickle(f, types[i]);
- }
- }
-
- for (i = 0; i < ntraittab; i++) {
- if (traittab[i]->vis == Visexport || traittab[i]->vis == Vishidden) {
- wrbyte(f, 'R');
- traitpickle(f, traittab[i]);
- }
- }
-
- k = htkeys(st->impl, &n);
- for (i = 0; i < n; i++) {
- /* merging during inference should remove all protos */
- s = getimpl(st, k[i]);
- assert(!s->impl.isproto);
- if (s->impl.vis == Visexport || s->impl.vis == Vishidden) {
- wrbyte(f, 'I');
- pickle(f, s);
- }
- }
- free(k);
-
- k = htkeys(st->dcl, &n);
- for (i = 0; i < n; i++) {
- s = getdcl(st, k[i]);
- assert(s != NULL);
- if (s->decl.vis == Visintern || s->decl.vis == Visbuiltin)
- continue;
- /* trait functions get written out with their traits */
- if (s->decl.trait || s->decl.isinit)
- continue;
- else if (s->decl.isgeneric)
- wrbyte(f, 'G');
- else
- wrbyte(f, 'D');
- wrsym(f, s);
- }
- for (i = 0; i < file->file.ninit; i++) {
- wrbyte(f, 'S');
- pickle(f, file->file.init[i]);
- }
- if (file->file.localinit) {
- wrbyte(f, 'S');
- pickle(f, file->file.localinit->decl.name);
- }
- free(k);
+ Stab *st;
+ void **k;
+ Node *s, *u;
+ size_t i, n;
+
+ assert(file->type == Nfile);
+ st = file->file.globls;
+
+ /* usefile name */
+ wrbyte(f, 'U');
+ wrint(f, Abiversion); /* use version */
+ if (st->name)
+ wrstr(f, st->name);
+ else
+ wrstr(f, NULL);
+
+ /* library deps */
+ for (i = 0; i < file->file.nuses; i++) {
+ u = file->file.uses[i];
+ if (!u->use.islocal) {
+ wrbyte(f, 'L');
+ wrstr(f, u->use.name);
+ }
+ }
+ for (i = 0; i < file->file.nlibdeps; i++) {
+ wrbyte(f, 'L');
+ wrstr(f, file->file.libdeps[i]);
+ }
+ for (i = 0; i < file->file.nextlibs; i++) {
+ wrbyte(f, 'X');
+ wrstr(f, file->file.extlibs[i]);
+ }
+
+ /* source file name */
+ wrbyte(f, 'F');
+ wrstr(f, file->file.files[0]);
+
+ for (i = 0; i < ntypes; i++) {
+ if (types[i]->vis == Visexport || types[i]->vis == Vishidden) {
+ wrbyte(f, 'T');
+ wrint(f, types[i]->tid);
+ typickle(f, types[i]);
+ }
+ }
+
+ for (i = 0; i < ntraittab; i++) {
+ if (traittab[i]->vis == Visexport || traittab[i]->vis == Vishidden) {
+ wrbyte(f, 'R');
+ traitpickle(f, traittab[i]);
+ }
+ }
+
+ k = htkeys(st->impl, &n);
+ for (i = 0; i < n; i++) {
+ /* merging during inference should remove all protos */
+ s = getimpl(st, k[i]);
+ assert(!s->impl.isproto);
+ if (s->impl.vis == Visexport || s->impl.vis == Vishidden) {
+ wrbyte(f, 'I');
+ pickle(f, s);
+ }
+ }
+ free(k);
+
+ k = htkeys(st->dcl, &n);
+ for (i = 0; i < n; i++) {
+ s = getdcl(st, k[i]);
+ assert(s != NULL);
+ if (s->decl.vis == Visintern || s->decl.vis == Visbuiltin)
+ continue;
+ /* trait functions get written out with their traits */
+ if (s->decl.trait || s->decl.isinit)
+ continue;
+ else if (s->decl.isgeneric)
+ wrbyte(f, 'G');
+ else
+ wrbyte(f, 'D');
+ wrsym(f, s);
+ }
+ for (i = 0; i < file->file.ninit; i++) {
+ wrbyte(f, 'S');
+ pickle(f, file->file.init[i]);
+ }
+ if (file->file.localinit) {
+ wrbyte(f, 'S');
+ pickle(f, file->file.localinit->decl.name);
+ }
+ free(k);
}