diff options
-rw-r--r-- | doc/lang.txt | 12 | ||||
-rw-r--r-- | parse/gram.y | 16 | ||||
-rw-r--r-- | parse/infer.c | 8 |
3 files changed, 32 insertions, 4 deletions
diff --git a/doc/lang.txt b/doc/lang.txt index 459ac50..4dc9f12 100644 --- a/doc/lang.txt +++ b/doc/lang.txt @@ -1,6 +1,6 @@ The Myrddin Programming Language Jul 2012 - Updated Feb 2017 + Updated Jul 2018 Ori Bernstein TABLE OF CONTENTS: @@ -785,6 +785,16 @@ TABLE OF CONTENTS: unconstrained type with $t :: numeric $t, floating $t is replaced with flt64. + As a special case, a union type declared with the form + + type u = union + `Foo + ;; + + will have the default type set to the named type, and not the + union itself. This is slightly inconsistent, but it makes the + behavior less surprising. + 4.6. Built In Traits: 4.6.1. numeric: diff --git a/parse/gram.y b/parse/gram.y index 146c842..7d95300 100644 --- a/parse/gram.y +++ b/parse/gram.y @@ -36,6 +36,7 @@ static void setattrs(Node *dcl, char **attrs, size_t nattrs); static void setwith(Type *ty, Traitspec **spec, size_t nspec); static void setupinit(Node *n); static void addinit(Node *blk, Node *dcl); +static void setuname(Type *ty); %} @@ -528,6 +529,7 @@ tydef : Ttype typeid traitspec {$$ = $2;} $$.type = mktyname($2.loc, mkname($2.loc, $2.name), $5); else $$.type = mktygeneric($2.loc, mkname($2.loc, $2.name), $2.params, $2.nparams, $5); + setuname($$.type); setwith($$.type, $3.spec, $3.nspec); } ; @@ -1147,6 +1149,17 @@ setupinit(Node *n) n->decl.name->name.name = strdup(s); } +static void +setuname(Type *ty) +{ + size_t i; + + if (ty->sub[0]->type != Tyunion) + return; + for (i = 0; i < ty->sub[0]->nmemb; i++) + ty->sub[0]->udecls[i]->utype = ty; +} + static Node * mkpseudodecl(Srcloc l, Type *t) { @@ -1231,7 +1244,8 @@ installucons(Stab *st, Type *t) break; case Tyunion: for (i = 0; i < b->nmemb; i++) { - b->udecls[i]->utype = b; + if (!b->udecls[i]->utype) + b->udecls[i]->utype = b; b->udecls[i]->id = i; putucon(st, b->udecls[i]); } diff --git a/parse/infer.c b/parse/infer.c index c5cad2f..8da7e02 100644 --- a/parse/infer.c +++ b/parse/infer.c @@ -514,7 +514,7 @@ tyresolve(Type *t) case Tyunion: inaggr++; for (i = 0; i < t->nmemb; i++) { - t->udecls[i]->utype = t; + assert(t->udecls[i]->utype); t->udecls[i]->utype = tf(t->udecls[i]->utype); if (t->udecls[i]->etype) { tyresolve(t->udecls[i]->etype); @@ -1498,7 +1498,11 @@ inferucon(Node *n, int *isconst) * * To make it compile, for now, we just bind the types in here. */ - t = tysubst(tf(uc->utype), uc->utype); + t = uc->utype; + if (t->type != Tyunion) + t = t->sub[0]; + assert(t->type == Tyunion); + t = tysubst(tf(t), t); uc = tybase(t)->udecls[uc->id]; if (uc->etype) { inferexpr(&n->expr.args[1], NULL, NULL); |