summaryrefslogtreecommitdiff
path: root/parse
diff options
context:
space:
mode:
authorS. Gilles <sgilles@math.umd.edu>2018-03-13 10:53:55 -0400
committerS. Gilles <sgilles@math.umd.edu>2018-03-13 10:53:55 -0400
commit599feae2daa1392f20e1dc807c58bcd74c20b45e (patch)
treea358d75af648afa2aa08a465c374ef32210c48ab /parse
parent5e1154d69efc86f5fe3831b047e3531d9cfd3478 (diff)
parent2c113af58d9f63bc4f720adbb6aa8ac2cae52781 (diff)
downloadmc-599feae2daa1392f20e1dc807c58bcd74c20b45e.tar.gz
Merge branch 'autoexpr' into libmath
Diffstat (limited to 'parse')
-rw-r--r--parse/dump.c1
-rw-r--r--parse/gram.y15
-rw-r--r--parse/infer.c35
-rw-r--r--parse/ops.def2
-rw-r--r--parse/parse.h7
-rw-r--r--parse/stab.c4
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 5424be9..bb1ea59 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -260,7 +260,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;
@@ -880,7 +880,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) {
@@ -1637,6 +1637,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 */
@@ -2054,8 +2061,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)
@@ -2614,8 +2619,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:
@@ -2662,6 +2665,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)
@@ -2727,7 +2732,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;
@@ -2749,14 +2762,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 52946a9..11b28ac 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 2d190d9..7e1b8c0 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))