shithub: mc

Download patch

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);