shithub: mc

Download patch

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))
+}
+