ref: 1efff8a755b22b20bec7c671c25a63825cfd90f1
parent: f666a9b2a62c4f8588c6add2bcc2071f95ef357c
author: Ori Bernstein <[email protected]>
date: Thu Feb 20 17:47:18 EST 2014
Traits specialize!
--- a/6/simp.c
+++ b/6/simp.c
@@ -1682,7 +1682,7 @@
e = dcl->decl.init;
if (e && exprop(e) == Olit) {
if (e->expr.args[0]->lit.littype == Lfunc)
- simpblob(s, e->expr.args[0], &file->file.stmts, &file->file.nstmts);
+ simpblob(s, e, &file->file.stmts, &file->file.nstmts);
else
lappend(&s->blobs, &s->nblobs, dcl);
} else if (dcl->decl.isconst) {
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -330,6 +330,7 @@
$$ = $1;
d = mkdecl($2->line, mkname($2->line, $2->str), mktyvar($2->line));
d->decl.init = $4;
+ d->decl.isconst = 1;
lappend(&$$.nl, &$$.nn, d);
}
;
@@ -338,7 +339,10 @@
$$ = mktrait($1->line, mkname($2->line, $2->str), $3, NULL, 0, NULL, 0, 1);
}
| Ttrait Tident generictype Tasn traitbody Tendblk /* trait definition */ {
+ size_t i;
$$ = mktrait($1->line, mkname($2->line, $2->str), $3, NULL, 0, $5.nl, $5.nn, 0);
+ for (i = 0; i < $5.nn; i++)
+ $5.nl[i]->decl.isgeneric = 1;
}
;
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1298,7 +1298,7 @@
static void specializeimpl(Inferstate *st, Node *n)
{
- Node *dcl, *proto;
+ Node *dcl, *proto, *name;
Htab *ht;
Trait *t;
Type *ty;
@@ -1333,6 +1333,14 @@
inferdecl(st, dcl);
unify(st, n, type(st, dcl), ty);
+
+ /* and put the specialization into the global stab */
+ name = genericname(proto, ty);
+ dcl->decl.name = name;
+ putdcl(file->file.globls, dcl);
+ if (debugopt['S'])
+ printf("specializing trait [%d]%s => %s\n", n->line, namestr(n->decl.name), namestr(name));
+ lappend(&file->file.stmts, &file->file.nstmts, dcl);
}
}
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -475,6 +475,7 @@
/* specialize generics */
Node *specializedcl(Node *n, Type *to, Node **name);
Type *tyspecialize(Type *t, Htab *tymap);
+Node *genericname(Node *n, Type *t);
/* usefiles */
int loaduse(FILE *f, Stab *into);
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -351,7 +351,7 @@
}
return r;
}
-static Node *genericname(Node *n, Type *t)
+Node *genericname(Node *n, Type *t)
{
char buf[1024];
char *p, *s;
--- a/test/tests
+++ b/test/tests
@@ -73,7 +73,7 @@
B genericval E 42
B trait-builtin E 42
B emptytrait E 123
-# B traitimpl E 24 ##BUGGERED
+B traitimpl E 24
B nestucon P asdf
B mkunion E 0
B genericcall E 42
--- a/test/trait.myr
+++ /dev/null
@@ -1,20 +1,0 @@
-use std
-
-trait frobable @a =
- frob : (val : @a -> @a)
-;;
-
-impl frobable int =
- frob = {val
- -> val * 2
- }
-;;
-
-generic foo = {x : @a::frobable
- -> frob(x)
-}
-
-const main = {
- std.exit(foo(12))
-}
-
--- /dev/null
+++ b/test/traitimpl.myr
@@ -1,0 +1,20 @@
+use std
+
+trait frobable @a =
+ frob : (val : @a -> @a)
+;;
+
+impl frobable int =
+ frob = {val
+ -> val * 2
+ }
+;;
+
+generic foo = {x : @a::frobable
+ -> frob(x)
+}
+
+const main = {
+ std.exit(foo(12))
+}
+