diff options
Diffstat (limited to 'parse/use.c')
-rw-r--r-- | parse/use.c | 1826 |
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); } |