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