diff options
Diffstat (limited to 'parse')
-rw-r--r-- | parse/dump.c | 1 | ||||
-rw-r--r-- | parse/gram.y | 15 | ||||
-rw-r--r-- | parse/infer.c | 35 | ||||
-rw-r--r-- | parse/ops.def | 2 | ||||
-rw-r--r-- | parse/parse.h | 7 | ||||
-rw-r--r-- | parse/stab.c | 4 |
6 files changed, 31 insertions, 33 deletions
diff --git a/parse/dump.c b/parse/dump.c index 847c0ed..9437984 100644 --- a/parse/dump.c +++ b/parse/dump.c @@ -186,7 +186,6 @@ outnode(Node *n, FILE *fd, int depth) findentf(fd, depth + 1, "isimport=%d\n", n->decl.isimport); findentf(fd, depth + 1, "isnoret=%d\n", n->decl.isnoret); findentf(fd, depth + 1, "isexportinit=%d\n", n->decl.isexportinit); - findentf(fd, depth + 1, "isauto=%d\n", n->decl.isauto); findentf(fd, depth, ")\n"); outsym(n, fd, depth + 1); outnode(n->decl.init, fd, depth + 1); diff --git a/parse/gram.y b/parse/gram.y index 8fb448b..9d9ddef 100644 --- a/parse/gram.y +++ b/parse/gram.y @@ -148,7 +148,7 @@ static void setupinit(Node *n); %type<node> littok literal lorexpr landexpr borexpr strlit bandexpr %type<node> cmpexpr addexpr mulexpr shiftexpr prefixexpr ternexpr %type<node> postfixexpr funclit seqlit tuplit name block stmt label -%type<node> use fnparam declbody declcore typedeclcore autodecl structent +%type<node> use fnparam declbody declcore typedeclcore structent %type<node> arrayelt structelt tuphead ifstmt forstmt whilestmt %type<node> matchstmt elifs optexprln loopcond optexpr match @@ -420,8 +420,8 @@ pkgtydef: attrs tydef { } ; -declbody: autodecl Tasn expr {$$ = $1; $1->decl.init = $3;} - | autodecl +declbody: declcore Tasn expr {$$ = $1; $1->decl.init = $3;} + | declcore ; declcore: name {$$ = mkdecl($1->loc, $1, mktyvar($1->loc));} @@ -432,10 +432,6 @@ typedeclcore : name Tcolon type {$$ = mkdecl($1->loc, $1, $3);} ; -autodecl: Tauto declcore {$$ = $2; $$->decl.isauto = 1;} - | declcore - ; - name : Tident {$$ = mkname($1->loc, $1->id);} | Tident Tdot Tident { $$ = mknsname($3->loc, $1->id, $3->id); @@ -771,7 +767,8 @@ shiftexpr shiftop : Tbsl | Tbsr; prefixexpr - : Tinc prefixexpr {$$ = mkexpr($1->loc, Opreinc, $2, NULL);} + : Tauto prefixexpr {$$ = mkexpr($1->loc, Oauto, $2, NULL);} + | Tinc prefixexpr {$$ = mkexpr($1->loc, Opreinc, $2, NULL);} | Tdec prefixexpr {$$ = mkexpr($1->loc, Opredec, $2, NULL);} | Tband prefixexpr {$$ = mkexpr($1->loc, Oaddr, $2, NULL);} | Tlnot prefixexpr {$$ = mkexpr($1->loc, Olnot, $2, NULL);} @@ -930,7 +927,7 @@ params : fnparam { | /* empty */ {$$.nl = NULL; $$.nn = 0;} ; -fnparam : autodecl {$$ = $1;} +fnparam : declcore {$$ = $1;} | Tgap { $$ = mkpseudodecl($1->loc, mktyvar($1->loc)); } | Tgap Tcolon type { $$ = mkpseudodecl($1->loc, $3); } ; diff --git a/parse/infer.c b/parse/infer.c index e5aa09e..58399b0 100644 --- a/parse/infer.c +++ b/parse/infer.c @@ -263,7 +263,7 @@ adddispspecialization(Node *n, Stab *stab) Type *ty; tr = traittab[Tcdisp]; - ty = decltype(n); + ty = exprtype(n); assert(tr->nproto == 1); if (hthas(tr->proto[0]->decl.impls, ty)) return; @@ -883,7 +883,7 @@ tryconstrain(Type *base, Trait *tr, int update) if (update) bsput(ty->trneed, tr->uid); return 1; - } + } if (bshas(tm->traits, tr->uid)) return 1; if (tm->name && ty->type == Tyname) { @@ -1641,6 +1641,13 @@ inferexpr(Node **np, Type *ret, int *sawret) infernode(&n->expr.idx, NULL, NULL); n = checkns(n, np); switch (exprop(n)) { + case Oauto: /* @a -> @a */ + infersub(n, ret, sawret, &isconst); + t = type(args[0]); + constrain(n, t, traittab[Tcdisp]); + n->expr.isconst = isconst; + settype(n, t); + break; /* all operands are same type */ case Oadd: /* @a + @a -> @a */ case Osub: /* @a - @a -> @a */ @@ -2058,8 +2065,6 @@ infernode(Node **np, Type *ret, int *sawret) inferdecl(n); if (hasparams(type(n)) && !ingeneric) fatal(n, "generic type in non-generic near %s", ctxstr(n)); - if (n->decl.isauto) - constrain(n, type(n), traittab[Tcdisp]); popenv(n->decl.env); indentdepth--; if (n->decl.isgeneric) @@ -2618,8 +2623,6 @@ typesub(Node *n, int noerr) if (streq(declname(n), "__init__")) if (!initcompatible(tybase(decltype(n)))) fatal(n, "__init__ must be (->void), got %s", tystr(decltype(n))); - if (n->decl.isauto) - adddispspecialization(n, curstab()); popenv(n->decl.env); break; case Nblock: @@ -2666,6 +2669,8 @@ typesub(Node *n, int noerr) settype(n->expr.args[0], exprtype(n)); settype(n->expr.args[0]->expr.args[0], exprtype(n)); } + if (exprop(n) == Oauto) + adddispspecialization(n, curstab()); for (i = 0; i < n->expr.nargs; i++) typesub(n->expr.args[i], noerr); if (!noerr) @@ -2731,7 +2736,15 @@ specialize(void) for (i = 0; i < nspecializations; i++) { pushstab(specializationscope[i]); n = specializations[i]; - if (n->type == Nexpr) { + if (n->type == Nexpr && exprop(n) == Oauto) { + tr = traittab[Tcdisp]; + assert(tr->nproto == 1); + ty = exprtype(n); + dt = mktyfunc(n->loc, NULL, 0, mktype(n->loc, Tyvoid)); + lappend(&dt->sub, &dt->nsub, ty); + d = specializedcl(tr->proto[0], ty, dt, &name); + htput(tr->proto[0]->decl.impls, ty, d); + } else if (n->type == Nexpr && exprop(n) == Ovar) { d = specializedcl(genericdecls[i], n->expr.param, n->expr.type, &name); n->expr.args[0] = name; n->expr.did = d->decl.did; @@ -2753,14 +2766,6 @@ specialize(void) it = itertype(n->iterstmt.seq, mktype(n->loc, Tyvoid)); d = specializedcl(tr->proto[1], ty, it, &name); htput(tr->proto[1]->decl.impls, ty, d); - } else if (n->type == Ndecl && n->decl.isauto) { - tr = traittab[Tcdisp]; - assert(tr->nproto == 1); - ty = decltype(n); - dt = mktyfunc(n->loc, NULL, 0, mktype(n->loc, Tyvoid)); - lappend(&dt->sub, &dt->nsub, ty); - d = specializedcl(tr->proto[0], ty, dt, &name); - htput(tr->proto[0]->decl.impls, ty, d); } else { die("unknown node for specialization\n"); } diff --git a/parse/ops.def b/parse/ops.def index c29ca1e..909736e 100644 --- a/parse/ops.def +++ b/parse/ops.def @@ -1,5 +1,6 @@ /* operator name, is it pure, pretty name */ O(Obad, 1, OTmisc, "BAD") +O(Oauto, 1, OTpre, "auto") O(Oadd, 1, OTbin, "+") O(Osub, 1, OTbin, "-") O(Omul, 1, OTbin, "*") @@ -105,4 +106,3 @@ O(Ougt, 1, OTmisc, NULL) O(Ouge, 1, OTmisc, NULL) O(Oult, 1, OTmisc, NULL) O(Oule, 1, OTmisc, NULL) - diff --git a/parse/parse.h b/parse/parse.h index 61cff0e..62392ca 100644 --- a/parse/parse.h +++ b/parse/parse.h @@ -108,10 +108,12 @@ struct Stab { Htab *lbl; /* labels */ Htab *impl; /* trait implementations: really a set of implemented traits. */ - Node **autodcl; /* declarations in dcl marked 'auto' */ - size_t nautodcl; + /* See mi/flatten.c for the following. */ + Node **autotmp; /* temporaries for 'auto' expressions */ + size_t nautotmp; Node *exit[Nexits]; + size_t ndisposed[Nexits]; }; struct Tyenv { @@ -331,7 +333,6 @@ struct Node { char isnoret; char isexportinit; char isinit; - char isauto; } decl; struct { diff --git a/parse/stab.c b/parse/stab.c index 7d94218..0319d13 100644 --- a/parse/stab.c +++ b/parse/stab.c @@ -417,10 +417,6 @@ putdcl(Stab *st, Node *s) st = findstab(st, s->decl.name); old = htget(st->dcl, s->decl.name); - if (s->decl.isauto) { - assert(!old); - lappend(&st->autodcl, &st->nautodcl, s); - } if (!old) forcedcl(st, s); else if (!mergedecl(old, s)) |