ref: e07b79bf077459eda3d7d59cbaf1b4f431e3b2c6
parent: 58550115b787023de68c7f760e8dd68c7d57c719
author: Ori Bernstein <[email protected]>
date: Sat Dec 28 10:09:48 EST 2013
Make for _ in _ loops use pattern matches. Now, the syntax for 'for x in y' will use a pattern match for x, and only matching elements will be iterated over.
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -690,7 +690,7 @@
forstmt : Tfor optexprln optexprln optexprln block
{$$ = mkloopstmt($1->line, $2, $3, $4, $5);}
- | Tfor expr Tin exprln block
+ | Tfor pat Tin exprln block
{$$ = mkiterstmt($1->line, $2, $4, $5);}
/* FIXME: allow decls in for loops
| Tfor decl Tendln optexprln optexprln block
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1318,10 +1318,17 @@
constrain(st, n, type(st, n->loopstmt.cond), cstrtab[Tctest]);
break;
case Niterstmt:
- infernode(st, n->iterstmt.elt, NULL, sawret);
+ bound = NULL;
+ nbound = 0;
+
+ inferpat(st, n->iterstmt.elt, NULL, &bound, &nbound);
+ addbindings(st, n->iterstmt.body, bound, nbound);
+
infernode(st, n->iterstmt.seq, NULL, sawret);
- infernode(st, n->loopstmt.body, ret, sawret);
- constrain(st, n, type(st, n->loopstmt.cond), cstrtab[Tctest]);
+ infernode(st, n->iterstmt.body, ret, sawret);
+
+ constrain(st, n, type(st, n->iterstmt.seq), cstrtab[Tcidx]);
+ unify(st, n, type(st, n->iterstmt.elt), type(st, n->iterstmt.seq)->sub[0]);
break;
case Nmatchstmt:
infernode(st, n->matchstmt.val, NULL, sawret);