summaryrefslogtreecommitdiff
path: root/parse/specialize.c
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-11-17 20:53:32 -0800
committerOri Bernstein <ori@eigenstate.org>2015-11-17 20:53:32 -0800
commit8531896f8d21ba1e727262aaf5cd96043590b480 (patch)
tree7c01441755f56ab66d33c37d3ac41642ddc46c0b /parse/specialize.c
parentc20862cda53c711fe476f6c7d0f6631af47a4933 (diff)
downloadmc-8531896f8d21ba1e727262aaf5cd96043590b480.tar.gz
MEGAPATCH: Tabification.
Tabs > spaces. By 4 spaces, to be precise. Let's use them.
Diffstat (limited to 'parse/specialize.c')
-rw-r--r--parse/specialize.c832
1 files changed, 415 insertions, 417 deletions
diff --git a/parse/specialize.c b/parse/specialize.c
index de884de..1414119 100644
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -16,11 +16,11 @@ static Node *specializenode(Node *g, Htab *tsmap);
void addtraits(Type *t, Bitset *traits)
{
- size_t b;
+ size_t b;
- if (traits)
- for (b = 0; bsiter(traits, &b); b++)
- settrait(t, traittab[b]);
+ if (traits)
+ for (b = 0; bsiter(traits, &b); b++)
+ settrait(t, traittab[b]);
}
/*
@@ -34,78 +34,80 @@ void addtraits(Type *t, Bitset *traits)
* against */
Type *tyspecialize(Type *t, Htab *tsmap, Htab *delayed)
{
- Type *ret, *tmp, **arg;
- size_t i, narg;
-
- t = tysearch(t);
- if (hthas(tsmap, t))
- return htget(tsmap, t);
- arg = NULL;
- narg = 0;
- switch (t->type) {
- case Typaram:
- ret = mktyvar(t->loc);
- addtraits(ret, t->traits);
- htput(tsmap, t, ret);
- break;
- case Tygeneric:
- ret = mktyname(t->loc, t->name, tyspecialize(t->sub[0], tsmap, delayed));
- ret->issynth = 1;
- htput(tsmap, t, ret);
- for (i = 0; i < t->ngparam; i++)
- lappend(&ret->arg, &ret->narg, tyspecialize(t->gparam[i], tsmap, delayed));
- break;
- case Tyname:
- if (!hasparams(t))
- return t;
- for (i = 0; i < t->narg; i++)
- lappend(&arg, &narg, tyspecialize(t->arg[i], tsmap, delayed));
- ret = mktyname(t->loc, t->name, tyspecialize(t->sub[0], tsmap, delayed));
- ret->arg = arg;
- ret->narg = narg;
- break;
- case Tystruct:
- ret = tydup(t);
- htput(tsmap, t, ret);
- pushstab(NULL);
- for (i = 0; i < t->nmemb; i++)
- ret->sdecls[i] = specializenode(t->sdecls[i], tsmap);
- popstab();
- break;
- case Tyunion:
- ret = tydup(t);
- htput(tsmap, t, ret);
- for (i = 0; i < t->nmemb; i++) {
- tmp = NULL;
- if (ret->udecls[i]->etype)
- tmp = tyspecialize(t->udecls[i]->etype, tsmap, delayed);
- ret->udecls[i] = mkucon(t->loc, t->udecls[i]->name, ret, tmp);
- ret->udecls[i]->utype = ret;
- ret->udecls[i]->id = i;
- ret->udecls[i]->synth = 1;
- }
- break;
- case Tyvar:
- if (delayed && hthas(delayed, t)) {
- ret = tydup(t);
- tmp = htget(delayed, t);
- htput(delayed, ret, tyspecialize(tmp, tsmap, delayed));
- } else {
- ret = t;
- }
- break;
- default:
- if (t->nsub > 0) {
- ret = tydup(t);
- htput(tsmap, t, ret);
- for (i = 0; i < t->nsub; i++)
- ret->sub[i] = tyspecialize(t->sub[i], tsmap, delayed);
- } else {
- ret = t;
- }
- break;
- }
- return ret;
+ Type *ret, *tmp, **arg;
+ size_t i, narg;
+
+ t = tysearch(t);
+ if (hthas(tsmap, t))
+ return htget(tsmap, t);
+ arg = NULL;
+ narg = 0;
+ switch (t->type) {
+ case Typaram:
+ ret = mktyvar(t->loc);
+ addtraits(ret, t->traits);
+ htput(tsmap, t, ret);
+ break;
+ case Tygeneric:
+ ret = mktyname(t->loc, t->name, tyspecialize(t->sub[0], tsmap, delayed));
+ ret->issynth = 1;
+ htput(tsmap, t, ret);
+ for (i = 0; i < t->ngparam; i++)
+ lappend(&ret->arg, &ret->narg, tyspecialize(t->gparam[i], tsmap, delayed));
+ break;
+ case Tyname:
+ if (!hasparams(t))
+ return t;
+ for (i = 0; i < t->narg; i++)
+ lappend(&arg, &narg, tyspecialize(t->arg[i], tsmap, delayed));
+ ret = mktyname(t->loc, t->name, tyspecialize(t->sub[0], tsmap, delayed));
+ ret->arg = arg;
+ ret->narg = narg;
+ break;
+ case Tystruct:
+ ret = tydup(t);
+ htput(tsmap, t, ret);
+ pushstab(NULL);
+ for (i = 0; i < t->nmemb; i++)
+ ret->sdecls[i] = specializenode(t->sdecls[i], tsmap);
+ popstab();
+ break;
+ case Tyunion:
+ ret = tydup(t);
+ htput(tsmap, t, ret);
+ for (i = 0; i < t->nmemb; i++) {
+ tmp = NULL;
+ if (ret->udecls[i]->etype)
+ tmp = tyspecialize(t->udecls[i]->etype, tsmap, delayed);
+ ret->udecls[i] = mkucon(t->loc, t->udecls[i]->name, ret, tmp);
+ ret->udecls[i]->utype = ret;
+ ret->udecls[i]->id = i;
+ ret->udecls[i]->synth = 1;
+ }
+ break;
+ case Tyvar:
+ if (delayed && hthas(delayed, t)) {
+ ret = tydup(t);
+ tmp = htget(delayed, t);
+ htput(delayed, ret, tyspecialize(tmp, tsmap, delayed));
+ }
+ else {
+ ret = t;
+ }
+ break;
+ default:
+ if (t->nsub > 0) {
+ ret = tydup(t);
+ htput(tsmap, t, ret);
+ for (i = 0; i < t->nsub; i++)
+ ret->sub[i] = tyspecialize(t->sub[i], tsmap, delayed);
+ }
+ else {
+ ret = t;
+ }
+ break;
+ }
+ return ret;
}
/* Checks if the type 't' is generic, and if it is
@@ -113,33 +115,33 @@ Type *tyspecialize(Type *t, Htab *tsmap, Htab *delayed)
* so we don't gratuitously duplicate types */
static Type *tysubst(Type *t, Htab *tsmap)
{
- if (hasparams(t))
- return tyspecialize(t, tsmap, NULL);
- else
- return t;
+ if (hasparams(t))
+ return tyspecialize(t, tsmap, NULL);
+ else
+ return t;
}
-/*
+/*
* Fills the substitution map with a mapping from
* the type parameter 'from' to it's substititon 'to'
*/
static void fillsubst(Htab *tsmap, Type *to, Type *from)
{
- size_t i;
-
- if (from->type == Typaram) {
- if (debugopt['S'])
- printf("mapping %s => %s\n", tystr(from), tystr(to));
- htput(tsmap, from, to);
- return;
- }
- assert(to->nsub == from->nsub);
- for (i = 0; i < to->nsub; i++)
- fillsubst(tsmap, to->sub[i], from->sub[i]);
- if (to->type == Tyname && to->narg > 0) {
- for (i = 0; i < to->narg; i++)
- fillsubst(tsmap, to->arg[i], from->arg[i]);
- }
+ size_t i;
+
+ if (from->type == Typaram) {
+ if (debugopt['S'])
+ printf("mapping %s => %s\n", tystr(from), tystr(to));
+ htput(tsmap, from, to);
+ return;
+ }
+ assert(to->nsub == from->nsub);
+ for (i = 0; i < to->nsub; i++)
+ fillsubst(tsmap, to->sub[i], from->sub[i]);
+ if (to->type == Tyname && to->narg > 0) {
+ for (i = 0; i < to->narg; i++)
+ fillsubst(tsmap, to->arg[i], from->arg[i]);
+ }
}
/*
@@ -148,98 +150,94 @@ static void fillsubst(Htab *tsmap, Type *to, Type *from)
*/
static void fixup(Node *n)
{
- size_t i;
- Node *d;
- Stab *ns;
-
- if (!n)
- return;
- switch (n->type) {
- case Nfile:
- case Nuse:
- die("Node %s not allowed here\n", nodestr[n->type]);
- break;
- case Nexpr:
- fixup(n->expr.idx);
- for (i = 0; i < n->expr.nargs; i++)
- fixup(n->expr.args[i]);
- if (n->expr.op == Ovar) {
- ns = curstab();
- if (n->expr.args[0]->name.ns)
- ns = getns(file, n->expr.args[0]->name.ns);
- if (!ns)
- fatal(n, "No namespace %s\n", n->expr.args[0]->name.ns);
- d = getdcl(ns, n->expr.args[0]);
- if (!d)
- die("Missing decl %s", namestr(n->expr.args[0]));
- if (d->decl.isgeneric)
- d = specializedcl(d, n->expr.type, &n->expr.args[0]);
- n->expr.did = d->decl.did;
- }
- break;
- case Nlit:
- switch (n->lit.littype) {
- case Lfunc: fixup(n->lit.fnval); break;
- case Lchr: case Lint: case Lflt:
- case Lstr: case Llbl: case Lbool:
- break;
- }
- break;
- case Nifstmt:
- fixup(n->ifstmt.cond);
- fixup(n->ifstmt.iftrue);
- fixup(n->ifstmt.iffalse);
- break;
- case Nloopstmt:
- pushstab(n->loopstmt.scope);
- fixup(n->loopstmt.init);
- fixup(n->loopstmt.cond);
- fixup(n->loopstmt.step);
- fixup(n->loopstmt.body);
- popstab();
- break;
- case Niterstmt:
- pushstab(n->iterstmt.body->block.scope);
- fixup(n->iterstmt.elt);
- popstab();
- fixup(n->iterstmt.seq);
- fixup(n->iterstmt.body);
- break;
- case Nmatchstmt:
- fixup(n->matchstmt.val);
- for (i = 0; i < n->matchstmt.nmatches; i++)
- fixup(n->matchstmt.matches[i]);
- break;
- case Nmatch:
- /* patterns are evaluated in their block's scope */
- pushstab(n->match.block->block.scope);
- fixup(n->match.pat);
- popstab();
- fixup(n->match.block);
- break;
- case Nblock:
- pushstab(n->block.scope);
- for (i = 0; i < n->block.nstmts; i++)
- fixup(n->block.stmts[i]);
- popstab();
- break;
- case Ndecl:
- fixup(n->decl.init);
- break;
- case Nfunc:
- pushstab(n->func.scope);
- fixup(n->func.body);
- popstab();
- break;
- case Nnone: case Nname:
- break;
- case Nimpl:
- die("trait/impl not implemented");
- break;
- }
+ size_t i;
+ Node *d;
+ Stab *ns;
+
+ if (!n)
+ return;
+ switch (n->type) {
+ case Nfile:
+ case Nuse: die("Node %s not allowed here\n", nodestr[n->type]); break;
+ case Nexpr:
+ fixup(n->expr.idx);
+ for (i = 0; i < n->expr.nargs; i++)
+ fixup(n->expr.args[i]);
+ if (n->expr.op == Ovar) {
+ ns = curstab();
+ if (n->expr.args[0]->name.ns)
+ ns = getns(file, n->expr.args[0]->name.ns);
+ if (!ns)
+ fatal(n, "No namespace %s\n", n->expr.args[0]->name.ns);
+ d = getdcl(ns, n->expr.args[0]);
+ if (!d)
+ die("Missing decl %s", namestr(n->expr.args[0]));
+ if (d->decl.isgeneric)
+ d = specializedcl(d, n->expr.type, &n->expr.args[0]);
+ n->expr.did = d->decl.did;
+ }
+ break;
+ case Nlit:
+ switch (n->lit.littype) {
+ case Lfunc: fixup(n->lit.fnval); break;
+ case Lchr:
+ case Lint:
+ case Lflt:
+ case Lstr:
+ case Llbl:
+ case Lbool: break;
+ }
+ break;
+ case Nifstmt:
+ fixup(n->ifstmt.cond);
+ fixup(n->ifstmt.iftrue);
+ fixup(n->ifstmt.iffalse);
+ break;
+ case Nloopstmt:
+ pushstab(n->loopstmt.scope);
+ fixup(n->loopstmt.init);
+ fixup(n->loopstmt.cond);
+ fixup(n->loopstmt.step);
+ fixup(n->loopstmt.body);
+ popstab();
+ break;
+ case Niterstmt:
+ pushstab(n->iterstmt.body->block.scope);
+ fixup(n->iterstmt.elt);
+ popstab();
+ fixup(n->iterstmt.seq);
+ fixup(n->iterstmt.body);
+ break;
+ case Nmatchstmt:
+ fixup(n->matchstmt.val);
+ for (i = 0; i < n->matchstmt.nmatches; i++)
+ fixup(n->matchstmt.matches[i]);
+ break;
+ case Nmatch:
+ /* patterns are evaluated in their block's scope */
+ pushstab(n->match.block->block.scope);
+ fixup(n->match.pat);
+ popstab();
+ fixup(n->match.block);
+ break;
+ case Nblock:
+ pushstab(n->block.scope);
+ for (i = 0; i < n->block.nstmts; i++)
+ fixup(n->block.stmts[i]);
+ popstab();
+ break;
+ case Ndecl: fixup(n->decl.init); break;
+ case Nfunc:
+ pushstab(n->func.scope);
+ fixup(n->func.body);
+ popstab();
+ break;
+ case Nnone:
+ case Nname: break;
+ case Nimpl: die("trait/impl not implemented"); break;
+ }
}
-
/*
* Duplicates a node, replacing all things that
* need to be specialized to make it concrete
@@ -247,142 +245,141 @@ static void fixup(Node *n)
*/
static Node *specializenode(Node *n, Htab *tsmap)
{
- Node *r;
- size_t i;
-
- if (!n)
- return NULL;
- r = mknode(n->loc, n->type);
- switch (n->type) {
- case Nfile:
- case Nuse:
- die("Node %s not allowed here\n", nodestr[n->type]);
- break;
- case Nexpr:
- r->expr.op = n->expr.op;
- r->expr.type = tysubst(n->expr.type, tsmap);
- r->expr.isconst = n->expr.isconst;
- r->expr.nargs = n->expr.nargs;
- r->expr.idx = specializenode(n->expr.idx, tsmap);
- r->expr.args = xalloc(n->expr.nargs * sizeof(Node*));
- for (i = 0; i < n->expr.nargs; i++)
- r->expr.args[i] = specializenode(n->expr.args[i], tsmap);
- break;
- case Nname:
- if (n->name.ns)
- r->name.ns = strdup(n->name.ns);
- r->name.name = strdup(n->name.name);
- break;
- case Nlit:
- r->lit.littype = n->lit.littype;
- r->lit.type = tysubst(n->expr.type, tsmap);
- switch (n->lit.littype) {
- case Lchr: r->lit.chrval = n->lit.chrval; break;
- case Lint: r->lit.intval = n->lit.intval; break;
- case Lflt: r->lit.fltval = n->lit.fltval; break;
- case Lstr: r->lit.strval = n->lit.strval; break;
- case Llbl: r->lit.lblval = n->lit.lblval; break;
- case Lbool: r->lit.boolval = n->lit.boolval; break;
- case Lfunc: r->lit.fnval = specializenode(n->lit.fnval, tsmap); break;
- }
- break;
- case Nifstmt:
- r->ifstmt.cond = specializenode(n->ifstmt.cond, tsmap);
- r->ifstmt.iftrue = specializenode(n->ifstmt.iftrue, tsmap);
- r->ifstmt.iffalse = specializenode(n->ifstmt.iffalse, tsmap);
- break;
- case Nloopstmt:
- r->loopstmt.scope = mkstab(0);
- r->loopstmt.scope->super = curstab();
- pushstab(r->loopstmt.scope);
- r->loopstmt.init = specializenode(n->loopstmt.init, tsmap);
- r->loopstmt.cond = specializenode(n->loopstmt.cond, tsmap);
- r->loopstmt.step = specializenode(n->loopstmt.step, tsmap);
- r->loopstmt.body = specializenode(n->loopstmt.body, tsmap);
- popstab();
- break;
- case Niterstmt:
- r->iterstmt.elt = specializenode(n->iterstmt.elt, tsmap);
- r->iterstmt.seq = specializenode(n->iterstmt.seq, tsmap);
- r->iterstmt.body = specializenode(n->iterstmt.body, tsmap);
- break;
- case Nmatchstmt:
- r->matchstmt.val = specializenode(n->matchstmt.val, tsmap);
- r->matchstmt.nmatches = n->matchstmt.nmatches;
- r->matchstmt.matches = xalloc(n->matchstmt.nmatches * sizeof(Node*));
- for (i = 0; i < n->matchstmt.nmatches; i++)
- r->matchstmt.matches[i] = specializenode(n->matchstmt.matches[i], tsmap);
- break;
- case Nmatch:
- r->match.pat = specializenode(n->match.pat, tsmap);
- r->match.block = specializenode(n->match.block, tsmap);
- break;
- case Nblock:
- r->block.scope = mkstab(0);
- r->block.scope->super = curstab();
- pushstab(r->block.scope);
- r->block.nstmts = n->block.nstmts;
- r->block.stmts = xalloc(sizeof(Node *)*n->block.nstmts);
- for (i = 0; i < n->block.nstmts; i++)
- r->block.stmts[i] = specializenode(n->block.stmts[i], tsmap);
- popstab();
- break;
- case Ndecl:
- r->decl.did = ndecls;
- /* sym */
- r->decl.name = specializenode(n->decl.name, tsmap);
- r->decl.type = tysubst(n->decl.type, tsmap);
-
- /* symflags */
- r->decl.isconst = n->decl.isconst;
- r->decl.isgeneric = n->decl.isgeneric;
- r->decl.isextern = n->decl.isextern;
- r->decl.isglobl = n->decl.isglobl;
- if (curstab())
- putdcl(curstab(), r);
-
- /* init */
- r->decl.init = specializenode(n->decl.init, tsmap);
- lappend(&decls, &ndecls, r);
- break;
- case Nfunc:
- r->func.scope = mkstab(0);
- r->func.scope->super = curstab();
- pushstab(r->func.scope);
- r->func.type = tysubst(n->func.type, tsmap);
- r->func.nargs = n->func.nargs;
- r->func.args = xalloc(sizeof(Node *)*n->func.nargs);
- for (i = 0; i < n->func.nargs; i++)
- r->func.args[i] = specializenode(n->func.args[i], tsmap);
- r->func.body = specializenode(n->func.body, tsmap);
- popstab();
- break;
- case Nimpl:
- die("trait/impl not implemented");
- case Nnone:
- die("Nnone should not be seen as node type!");
- break;
- }
- return r;
+ Node *r;
+ size_t i;
+
+ if (!n)
+ return NULL;
+ r = mknode(n->loc, n->type);
+ switch (n->type) {
+ case Nfile:
+ case Nuse: die("Node %s not allowed here\n", nodestr[n->type]); break;
+ case Nexpr:
+ r->expr.op = n->expr.op;
+ r->expr.type = tysubst(n->expr.type, tsmap);
+ r->expr.isconst = n->expr.isconst;
+ r->expr.nargs = n->expr.nargs;
+ r->expr.idx = specializenode(n->expr.idx, tsmap);
+ r->expr.args = xalloc(n->expr.nargs * sizeof(Node *));
+ for (i = 0; i < n->expr.nargs; i++)
+ r->expr.args[i] = specializenode(n->expr.args[i], tsmap);
+ break;
+ case Nname:
+ if (n->name.ns)
+ r->name.ns = strdup(n->name.ns);
+ r->name.name = strdup(n->name.name);
+ break;
+ case Nlit:
+ r->lit.littype = n->lit.littype;
+ r->lit.type = tysubst(n->expr.type, tsmap);
+ switch (n->lit.littype) {
+ case Lchr: r->lit.chrval = n->lit.chrval; break;
+ case Lint: r->lit.intval = n->lit.intval; break;
+ case Lflt: r->lit.fltval = n->lit.fltval; break;
+ case Lstr: r->lit.strval = n->lit.strval; break;
+ case Llbl: r->lit.lblval = n->lit.lblval; break;
+ case Lbool: r->lit.boolval = n->lit.boolval; break;
+ case Lfunc: r->lit.fnval = specializenode(n->lit.fnval, tsmap); break;
+ }
+ break;
+ case Nifstmt:
+ r->ifstmt.cond = specializenode(n->ifstmt.cond, tsmap);
+ r->ifstmt.iftrue = specializenode(n->ifstmt.iftrue, tsmap);
+ r->ifstmt.iffalse = specializenode(n->ifstmt.iffalse, tsmap);
+ break;
+ case Nloopstmt:
+ r->loopstmt.scope = mkstab(0);
+ r->loopstmt.scope->super = curstab();
+ pushstab(r->loopstmt.scope);
+ r->loopstmt.init = specializenode(n->loopstmt.init, tsmap);
+ r->loopstmt.cond = specializenode(n->loopstmt.cond, tsmap);
+ r->loopstmt.step = specializenode(n->loopstmt.step, tsmap);
+ r->loopstmt.body = specializenode(n->loopstmt.body, tsmap);
+ popstab();
+ break;
+ case Niterstmt:
+ r->iterstmt.elt = specializenode(n->iterstmt.elt, tsmap);
+ r->iterstmt.seq = specializenode(n->iterstmt.seq, tsmap);
+ r->iterstmt.body = specializenode(n->iterstmt.body, tsmap);
+ break;
+ case Nmatchstmt:
+ r->matchstmt.val = specializenode(n->matchstmt.val, tsmap);
+ r->matchstmt.nmatches = n->matchstmt.nmatches;
+ r->matchstmt.matches = xalloc(n->matchstmt.nmatches * sizeof(Node *));
+ for (i = 0; i < n->matchstmt.nmatches; i++)
+ r->matchstmt.matches[i] = specializenode(n->matchstmt.matches[i], tsmap);
+ break;
+ case Nmatch:
+ r->match.pat = specializenode(n->match.pat, tsmap);
+ r->match.block = specializenode(n->match.block, tsmap);
+ break;
+ case Nblock:
+ r->block.scope = mkstab(0);
+ r->block.scope->super = curstab();
+ pushstab(r->block.scope);
+ r->block.nstmts = n->block.nstmts;
+ r->block.stmts = xalloc(sizeof(Node *) * n->block.nstmts);
+ for (i = 0; i < n->block.nstmts; i++)
+ r->block.stmts[i] = specializenode(n->block.stmts[i], tsmap);
+ popstab();
+ break;
+ case Ndecl:
+ r->decl.did = ndecls;
+ /* sym */
+ r->decl.name = specializenode(n->decl.name, tsmap);
+ r->decl.type = tysubst(n->decl.type, tsmap);
+
+ /* symflags */
+ r->decl.isconst = n->decl.isconst;
+ r->decl.isgeneric = n->decl.isgeneric;
+ r->decl.isextern = n->decl.isextern;
+ r->decl.isglobl = n->decl.isglobl;
+ if (curstab())
+ putdcl(curstab(), r);
+
+ /* init */
+ r->decl.init = specializenode(n->decl.init, tsmap);
+ lappend(&decls, &ndecls, r);
+ break;
+ case Nfunc:
+ r->func.scope = mkstab(0);
+ r->func.scope->super = curstab();
+ pushstab(r->func.scope);
+ r->func.type = tysubst(n->func.type, tsmap);
+ r->func.nargs = n->func.nargs;
+ r->func.args = xalloc(sizeof(Node *) * n->func.nargs);
+ for (i = 0; i < n->func.nargs; i++)
+ r->func.args[i] = specializenode(n->func.args[i], tsmap);
+ r->func.body = specializenode(n->func.body, tsmap);
+ popstab();
+ break;
+ case Nimpl:
+ die("trait/impl not implemented");
+ break;
+ case Nnone:
+ die("Nnone should not be seen as node type!");
+ break;
+ }
+ return r;
}
Node *genericname(Node *n, Type *t)
{
- char buf[1024];
- char *p;
- char *end;
- Node *name;
-
- if (!n->decl.isgeneric)
- return n->decl.name;
- p = buf;
- end = buf + sizeof buf;
- p += bprintf(p, end - p, "%s", n->decl.name->name.name);
- p += bprintf(p, end - p, "$");
- p += tyidfmt(p, end - p, t);
- name = mkname(n->loc, buf);
- if (n->decl.name->name.ns)
- setns(name, n->decl.name->name.ns);
- return name;
+ char buf[1024];
+ char *p;
+ char *end;
+ Node *name;
+
+ if (!n->decl.isgeneric)
+ return n->decl.name;
+ p = buf;
+ end = buf + sizeof buf;
+ p += bprintf(p, end - p, "%s", n->decl.name->name.name);
+ p += bprintf(p, end - p, "$");
+ p += tyidfmt(p, end - p, t);
+ name = mkname(n->loc, buf);
+ if (n->decl.name->name.ns)
+ setns(name, n->decl.name->name.ns);
+ return name;
}
/*
@@ -392,53 +389,54 @@ Node *genericname(Node *n, Type *t)
*/
Node *specializedcl(Node *g, Type *to, Node **name)
{
- extern int stabstkoff;
- Node *d, *n;
- Htab *tsmap;
- Stab *st;
-
- assert(g->type == Ndecl);
- assert(g->decl.isgeneric);
-
- n = genericname(g, to);
- *name = n;
- if (n->name.ns)
- st = getns(file, n->name.ns);
- else
- st = file->file.globls;
- if (!st)
- fatal(n, "Can't find symbol table for %s.%s", n->name.ns, n->name.name);
- d = getdcl(st, n);
- if (debugopt['S'])
- printf("depth[%d] specializing [%d]%s => %s\n", stabstkoff, g->loc.line, namestr(g->decl.name), namestr(n));
- if (d)
- return d;
- if (g->decl.trait) {
- printf("%s\n", namestr(n));
- fatal(g, "No trait implemented for for %s:%s", namestr(g->decl.name), tystr(to));
- }
- /* namespaced names need to be looked up in their correct
- * context. */
- if (n->name.ns)
- pushstab(st);
-
- /* specialize */
- tsmap = mkht(tyhash, tyeq);
- fillsubst(tsmap, to, g->decl.type);
-
- d = mkdecl(g->loc, n, tysubst(g->decl.type, tsmap));
- d->decl.isconst = g->decl.isconst;
- d->decl.isextern = g->decl.isextern;
- d->decl.isglobl = g->decl.isglobl;
- d->decl.init = specializenode(g->decl.init, tsmap);
- putdcl(st, d);
-
- fixup(d);
-
- lappend(&file->file.stmts, &file->file.nstmts, d);
- if (d->decl.name->name.ns)
- popstab();
- return d;
+ extern int stabstkoff;
+ Node *d, *n;
+ Htab *tsmap;
+ Stab *st;
+
+ assert(g->type == Ndecl);
+ assert(g->decl.isgeneric);
+
+ n = genericname(g, to);
+ *name = n;
+ if (n->name.ns)
+ st = getns(file, n->name.ns);
+ else
+ st = file->file.globls;
+ if (!st)
+ fatal(n, "Can't find symbol table for %s.%s", n->name.ns, n->name.name);
+ d = getdcl(st, n);
+ if (debugopt['S'])
+ printf("depth[%d] specializing [%d]%s => %s\n", stabstkoff, g->loc.line,
+ namestr(g->decl.name), namestr(n));
+ if (d)
+ return d;
+ if (g->decl.trait) {
+ printf("%s\n", namestr(n));
+ fatal(g, "No trait implemented for for %s:%s", namestr(g->decl.name), tystr(to));
+ }
+ /* namespaced names need to be looked up in their correct
+ * context. */
+ if (n->name.ns)
+ pushstab(st);
+
+ /* specialize */
+ tsmap = mkht(tyhash, tyeq);
+ fillsubst(tsmap, to, g->decl.type);
+
+ d = mkdecl(g->loc, n, tysubst(g->decl.type, tsmap));
+ d->decl.isconst = g->decl.isconst;
+ d->decl.isextern = g->decl.isextern;
+ d->decl.isglobl = g->decl.isglobl;
+ d->decl.init = specializenode(g->decl.init, tsmap);
+ putdcl(st, d);
+
+ fixup(d);
+
+ lappend(&file->file.stmts, &file->file.nstmts, d);
+ if (d->decl.name->name.ns)
+ popstab();
+ return d;
}
/*
@@ -455,65 +453,65 @@ Node *specializedcl(Node *g, Type *to, Node **name)
*/
static Node *initdecl(Node *file, Node *name, Type *tyvoidfn)
{
- Node *dcl;
-
- dcl = getdcl(file->file.globls, name);
- if (!dcl) {
- dcl = mkdecl(Zloc, name, tyvoidfn);
- dcl->decl.isconst = 1;
- dcl->decl.isglobl = 1;
- dcl->decl.isinit = 1;
- dcl->decl.isextern = 1;
- dcl->decl.ishidden = 1;
- putdcl(file->file.globls, dcl);
- }
- return dcl;
+ Node *dcl;
+
+ dcl = getdcl(file->file.globls, name);
+ if (!dcl) {
+ dcl = mkdecl(Zloc, name, tyvoidfn);
+ dcl->decl.isconst = 1;
+ dcl->decl.isglobl = 1;
+ dcl->decl.isinit = 1;
+ dcl->decl.isextern = 1;
+ dcl->decl.ishidden = 1;
+ putdcl(file->file.globls, dcl);
+ }
+ return dcl;
}
static void callinit(Node *block, Node *init, Type *tyvoid, Type *tyvoidfn)
{
- Node *call, *var;
+ Node *call, *var;
- var = mkexpr(Zloc, Ovar, init->decl.name, NULL);
- call = mkexpr(Zloc, Ocall, var, NULL);
+ var = mkexpr(Zloc, Ovar, init->decl.name, NULL);
+ call = mkexpr(Zloc, Ocall, var, NULL);
- var->expr.type = tyvoidfn;
- call->expr.type = tyvoid;
- var->expr.did = init->decl.did;
- var->expr.isconst = 1;
- lappend(&block->block.stmts, &block->block.nstmts, call);
+ var->expr.type = tyvoidfn;
+ call->expr.type = tyvoid;
+ var->expr.did = init->decl.did;
+ var->expr.isconst = 1;
+ lappend(&block->block.stmts, &block->block.nstmts, call);
}
void geninit(Node *file)
{
- Node *name, *decl, *func, *block, *init;
- Type *tyvoid, *tyvoidfn;
- size_t i;
-
- name = mkname(Zloc, "__init__");
- decl = mkdecl(Zloc, name, mktyvar(Zloc));
- block = mkblock(Zloc, mkstab(0));
- block->block.scope->super = file->file.globls;
- tyvoid = mktype(Zloc, Tyvoid);
- tyvoidfn = mktyfunc(Zloc, NULL, 0, tyvoid);
-
- for (i = 0; i < file->file.ninit; i++) {
- init = initdecl(file, file->file.init[i], tyvoidfn);
- callinit(block, init, tyvoid, tyvoidfn);
- }
- if (file->file.localinit)
- callinit(block, file->file.localinit, tyvoid, tyvoidfn);
-
- func = mkfunc(Zloc, NULL, 0, mktype(Zloc, Tyvoid), block);
- func->expr.type = tyvoidfn;
- init = mkexpr(Zloc, Olit, func, NULL);
- init->expr.type = tyvoidfn;
-
- decl->decl.init = init;
- decl->decl.isconst = 1;
- decl->decl.isglobl = 1;
- decl->decl.type = tyvoidfn;
- decl->decl.vis = Vishidden;
-
- lappend(&file->file.stmts, &file->file.nstmts, decl);
+ Node *name, *decl, *func, *block, *init;
+ Type *tyvoid, *tyvoidfn;
+ size_t i;
+
+ name = mkname(Zloc, "__init__");
+ decl = mkdecl(Zloc, name, mktyvar(Zloc));
+ block = mkblock(Zloc, mkstab(0));
+ block->block.scope->super = file->file.globls;
+ tyvoid = mktype(Zloc, Tyvoid);
+ tyvoidfn = mktyfunc(Zloc, NULL, 0, tyvoid);
+
+ for (i = 0; i < file->file.ninit; i++) {
+ init = initdecl(file, file->file.init[i], tyvoidfn);
+ callinit(block, init, tyvoid, tyvoidfn);
+ }
+ if (file->file.localinit)
+ callinit(block, file->file.localinit, tyvoid, tyvoidfn);
+
+ func = mkfunc(Zloc, NULL, 0, mktype(Zloc, Tyvoid), block);
+ func->expr.type = tyvoidfn;
+ init = mkexpr(Zloc, Olit, func, NULL);
+ init->expr.type = tyvoidfn;
+
+ decl->decl.init = init;
+ decl->decl.isconst = 1;
+ decl->decl.isglobl = 1;
+ decl->decl.type = tyvoidfn;
+ decl->decl.vis = Vishidden;
+
+ lappend(&file->file.stmts, &file->file.nstmts, decl);
}