ref: a2207af9fb5f49a2663e058658571638a509a3e6
parent: 290af5c176be42347969ad80ed9d73391a36c61e
author: Ori Bernstein <[email protected]>
date: Fri Jun 22 16:20:36 EDT 2012
Correctly generate specialized versions of funcs. Yay!
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -16,6 +16,10 @@
static size_t npostcheck;
static Htab **tybindings;
static size_t ntybindings;
+static Node **genericdecls;
+static size_t ngenericdecls;
+static Node **specializations;
+static size_t nspecializations;
static void infernode(Node *n, Type *ret, int *sawret);
static void inferexpr(Node *n, Type *ret, int *sawret);
@@ -464,6 +468,10 @@
t = s->decl.type;
settype(n, t);
n->expr.did = s->decl.did;
+ if (s->decl.isgeneric) {
+ lappend(&specializations, &nspecializations, n);
+ lappend(&genericdecls, &ngenericdecls, s);
+ }
break;
case Olit: /* <lit>:@a::tyclass -> @a */
switch (args[0]->lit.littype) {
@@ -867,6 +875,17 @@
popstab();
}
+void specialize(Node *f)
+{
+ Node *n;
+ size_t i;
+
+ for (i = 0; i < nspecializations; i++) {
+ n = specializedcl(genericdecls[i], specializations[i]->expr.type, NULL);
+ dump(n, stdout);
+ }
+}
+
void infer(Node *file)
{
assert(file->type == Nfile);
@@ -877,4 +896,5 @@
infercompn(file);
checkcast(file);
typesub(file);
+ specialize(file);
}
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -346,7 +346,7 @@
Node **aggrmemb(Type *t, size_t *n);
/* specialize generics */
-Node *specialize(Node *n, Type *to, Type *from);
+Node *specializedcl(Node *n, Type *to, Node **dcl);
/* usefiles */
void readuse(Node *use, Stab *into);
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -45,12 +45,14 @@
Type *ret;
size_t i;
- if (t->type == Typaram)
- return htget(tsmap, t);
-
- ret = tydup(t);
- for (i = 0; i < t->nsub; i++)
- ret->sub[i] = dosubst(t->sub[i], tsmap);
+ if (t->type == Typaram) {
+ ret = htget(tsmap, t);
+ } else {
+ ret = tydup(t);
+ for (i = 0; i < t->nsub; i++)
+ ret->sub[i] = dosubst(t->sub[i], tsmap);
+ }
+ assert(ret != NULL);
return ret;
}
@@ -79,6 +81,8 @@
Node *r;
size_t i;
+ if (!n)
+ return NULL;
r = mknode(n->line, n->type);
switch (n->type) {
case Nfile:
@@ -103,13 +107,13 @@
r->lit.littype = n->lit.littype;
r->lit.type = tysubst(n->expr.type, tsmap);
switch (n->lit.littype) {
- case Lchr: n->lit.chrval = n->lit.chrval; break;
- case Lint: n->lit.intval = n->lit.intval; break;
- case Lflt: n->lit.fltval = n->lit.fltval; break;
- case Lstr: n->lit.strval = n->lit.strval; break;
- case Lbool: n->lit.boolval = n->lit.boolval; break;
- case Lfunc: n->lit.fnval = specializenode(n->lit.fnval, tsmap); break;
- case Larray: n->lit.arrval = specializenode(n->lit.arrval, tsmap); break;
+ 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 Lbool: r->lit.boolval = n->lit.boolval; break;
+ case Lfunc: r->lit.fnval = specializenode(n->lit.fnval, tsmap); break;
+ case Larray: r->lit.arrval = specializenode(n->lit.arrval, tsmap); break;
}
break;
case Nloopstmt:
@@ -136,7 +140,7 @@
case Ndecl:
/* sym */
r->decl.name = specializenode(n->decl.name, tsmap);
- n->decl.type = tysubst(n->decl.type, tsmap);
+ r->decl.type = tysubst(n->decl.type, tsmap);
/* symflags */
r->decl.isconst = n->decl.isconst;
@@ -161,11 +165,14 @@
return r;
}
-Node *specialize(Node *n, Type *to, Type *from)
+Node *specializedcl(Node *n, Type *to, Node **dcl)
{
Htab *tsmap;
+ assert(n->type == Ndecl);
+ assert(n->decl.isgeneric);
+
tsmap = mkht(tidhash, tideq);
- fillsubst(tsmap, to, from);
+ fillsubst(tsmap, to, n->decl.type);
return specializenode(n, tsmap);
}