shithub: mc

Download patch

ref: 0c454eb69e126d7180b0a05598de1fac65dc3fd3
parent: cb804dc4af19cad9ba86a55aa5cc8b3c1a9a4159
author: Ori Bernstein <[email protected]>
date: Fri Feb 14 14:25:17 EST 2014

More work towards implementing traits.

--- a/parse/gram.y
+++ b/parse/gram.y
@@ -152,7 +152,7 @@
 %type <nodelist> structbody structelts arrayelts 
 %type <nodelist> tupbody tuprest 
 %type <nodelist> decl decllist
-%type <nodelist> traitbody
+%type <nodelist> traitbody implbody
 
 %type <uconlist> unionbody
 
@@ -283,7 +283,7 @@
         | tydef {puttype(file->file.exports, mkname($1.line, $1.name), $1.type);
              installucons(file->file.exports, $1.type);}
         | traitdef
-        | implstmt
+        /*| implstmt*/
         | visdef {die("Unimplemented visdef");}
         | /* empty */
         ;
@@ -310,21 +310,32 @@
         ;
 
 implstmt: Timpl name type 
-            {$$ = mkimplstmt($1->line, $2, $3);}
+            {$$ = mkimplstmt($1->line, $2, $3, NULL, 0);}
+        | Timpl name type Tasn Tendln implbody Tendblk 
+            {$$ = mkimplstmt($1->line, $2, $3, $6.nl, $6.nn);}
         ;
 
-traitdef: Ttrait Tident generictype Tasn traitbody Tendblk
-            {$$ = mktrait($1->line, mkname($2->line, $2->str), NULL, 0, $5.nl, $5.nn);}
+implbody
+        : optendlns {$$.nl = NULL; $$.nn = 0;}
+        | implbody Tident Tasn exprln optendlns
+            {Node *d;
+             $$ = $1;
+             d = mkdecl($2->line, mkname($2->line, $2->str), mktyvar($2->line));
+             d->decl.init = $4;
+             lappend(&$$.nl, &$$.nn, d);}
         ;
 
+traitdef: Ttrait Tident generictype Tendln /* trait prototype */
+            {$$ = mktrait($1->line, mkname($2->line, $2->str), NULL, 0, NULL, 0, 1);}
+        | Ttrait Tident generictype Tasn traitbody Tendblk /* trait definition */
+            {$$ = mktrait($1->line, mkname($2->line, $2->str), NULL, 0, $5.nl, $5.nn, 0);}
+        ;
+
 traitbody
-        : endlns {$$.nl = NULL; $$.nn = 0;}
-        | traitbody decl endlns
-            {size_t i;
-             $$ = $1;
-             for (i = 0; i < $2.nn; i++)
-                lappend(&$$.nl, &$$.nn, $2.nl[i]);
-            }
+        : optendlns {$$.nl = NULL; $$.nn = 0;}
+        | traitbody Tident Tcolon type optendlns
+            {$$ = $1;
+             lappend(&$$.nl, &$$.nn, mkdecl($2->line, mkname($2->line, $2->str), $4));}
         ;
 
 
@@ -687,15 +698,15 @@
         ;
 
 arrayelts
-        : endlns arrayelt
+        : optendlns arrayelt
             {$$.nl = NULL; $$.nn = 0;
              lappend(&$$.nl, &$$.nn, mkidxinit($2->line, mkint($2->line, 0), $2));}
-        | arrayelts Tcomma endlns arrayelt
+        | arrayelts Tcomma optendlns arrayelt
              {lappend(&$$.nl, &$$.nn, mkidxinit($4->line, mkint($4->line, $$.nn), $4));}
-        | arrayelts Tcomma endlns
+        | arrayelts Tcomma optendlns
         ;
 
-arrayelt: expr endlns {$$ = $1;}
+arrayelt: expr optendlns {$$ = $1;}
         ;
 
 structelts
@@ -706,12 +717,12 @@
              {lappend(&$$.nl, &$$.nn, $3);}
         ;
 
-structelt: endlns Tdot Tident Tasn expr endlns 
+structelt: optendlns Tdot Tident Tasn expr optendlns 
             {$$ = mkidxinit($2->line, mkname($3->line, $3->str), $5);}
          ;
 
-endlns  : /* none */
-        | endlns Tendln
+optendlns  : /* none */
+        | optendlns Tendln
         ;
 
 stmt    : goto
@@ -761,7 +772,7 @@
             {$$ = NULL;}
         ;
 
-matchstmt: Tmatch exprln endlns Tbor matches Tendblk
+matchstmt: Tmatch exprln optendlns Tbor matches Tendblk
             {$$ = mkmatchstmt($1->line, $2, $5.nl, $5.nn);}
          ;
 
--- a/parse/node.c
+++ b/parse/node.c
@@ -183,7 +183,7 @@
     return n;
 }
 
-Node *mkimplstmt(int line, Node *name, Type *t)
+Node *mkimplstmt(int line, Node *name, Type *t, Node **decls, size_t ndecls)
 {
     Node *n;
 
@@ -190,6 +190,8 @@
     n = mknode(line, Nimpl);
     n->impl.traitname = name;
     n->impl.type = t;
+    n->impl.decls = decls;
+    n->impl.ndecls = ndecls;
     return n;
 }
 
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -147,8 +147,9 @@
 };
 
 struct Trait {
-    int cid;    /* unique id */
-    Node *name;
+    int cid;            /* unique id */
+    int isproto;        /* is it a prototype for exporting */
+    Node *name;         /* the name of the trait */
     Node **memb;        /* type must have these members */
     size_t nmemb;
     Node **funcs;       /* and declare these funcs */
@@ -287,6 +288,8 @@
         struct {
             Node *traitname;
             Type *type;
+            Node **decls;
+            size_t ndecls;
         } impl;
     };
 };
@@ -400,7 +403,7 @@
 Type *mktyfunc(int line, Node **args, size_t nargs, Type *ret);
 Type *mktystruct(int line, Node **decls, size_t ndecls);
 Type *mktyunion(int line, Ucon **decls, size_t ndecls);
-Trait *mktrait(int line, Node *name, Node **memb, size_t nmemb, Node **funcs, size_t nfuncs);
+Trait *mktrait(int line, Node *name, Node **memb, size_t nmemb, Node **funcs, size_t nfuncs, int isproto);
 Type *mktylike(int line, Ty ty); /* constrains tyvar t like it was builtin ty */
 int   istysigned(Type *t);
 int   istyfloat(Type *t);
@@ -432,7 +435,7 @@
 Node *mkmatchstmt(int line, Node *val, Node **matches, size_t nmatches);
 Node *mkmatch(int line, Node *pat, Node *body);
 Node *mkblock(int line, Stab *scope);
-Node *mkimplstmt(int line, Node *name, Type *type);
+Node *mkimplstmt(int line, Node *name, Type *type, Node **impls, size_t nimpls);
 Node *mkintlit(int line, uvlong val);
 Node *mkidxinit(int line, Node *idx, Node *init);
 
--- a/parse/type.c
+++ b/parse/type.c
@@ -111,21 +111,22 @@
 }
 
 /* steals memb, funcs */
-Trait *mktrait(int line, Node *name, Node **memb, size_t nmemb, Node **funcs, size_t nfuncs)
+Trait *mktrait(int line, Node *name, Node **memb, size_t nmemb, Node **funcs, size_t nfuncs, int isproto)
 {
-    Trait *c;
+    Trait *t;
 
-    c = zalloc(sizeof(Trait));
-    c->name = name;
-    c->memb = memb;
-    c->nmemb = nmemb;
-    c->funcs = funcs;
-    c->nfuncs = nfuncs;
-    c->cid = ntraits++;
+    t = zalloc(sizeof(Trait));
+    t->name = name;
+    t->memb = memb;
+    t->nmemb = nmemb;
+    t->funcs = funcs;
+    t->nfuncs = nfuncs;
+    t->isproto = isproto;
+    t->cid = ntraits++;
 
     traittab = xrealloc(traittab, ntraits*sizeof(Trait*));
-    traittab[c->cid] = c;
-    return c;
+    traittab[t->cid] = t;
+    return t;
 }
 
 Type *mktyvar(int line)
@@ -642,7 +643,7 @@
     Type *ty;
 
 #define Tc(c, n) \
-    mktrait(-1, mkname(-1, n), NULL, 0, NULL, 0);
+    mktrait(-1, mkname(-1, n), NULL, 0, NULL, 0, 0);
 #include "trait.def"
 #undef Tc