grammar: add `for_group` in `for` for multi-iterators
authorJean Privat <jean@pryen.org>
Wed, 7 Oct 2015 01:30:20 +0000 (21:30 -0400)
committerJean Privat <jean@pryen.org>
Wed, 7 Oct 2015 01:30:20 +0000 (21:30 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

src/parser/nit.sablecc3xx
src/parser/parser_nodes.nit

index ef6260d..694da7b 100644 (file)
@@ -511,8 +511,16 @@ while~withelse {-> expr}
        ;
 
 for~withelse {-> expr}
-       = kwfor no [ids]:idlist [n2]:no kwin [n3]:no expr [n4]:no kwdo stmtso_withend label {-> New expr.for(kwfor, [ids.id], kwin, expr, kwdo, stmtso_withend.expr, label)}
-       | {nolabel} kwfor no [ids]:idlist [n2]:no kwin [n3]:no expr [n4]:no kwdo stmtso~withelse {-> New expr.for(kwfor, [ids.id], kwin, expr, kwdo, stmtso~withelse.expr, Null)}
+       = kwfor no for_groups [n4]:no kwdo stmtso_withend label {-> New expr.for(kwfor, [for_groups.for_group], kwdo, stmtso_withend.expr, label)}
+       | {nolabel} kwfor no for_groups [n4]:no kwdo stmtso~withelse {-> New expr.for(kwfor, [for_groups.for_group], kwdo, stmtso~withelse.expr, Null)}
+       ;
+
+for_groups {-> for_group*}
+       = {one} for_group {-> [for_group]}
+       | {many} for_groups no comma [n2]:no for_group {-> [for_groups.for_group, for_group] }
+       ;
+for_group
+       = [ids]:idlist [n2]:no kwin [n3]:no expr {-> New for_group([ids.id], kwin, expr)}
        ;
 
 with~withelse {-> expr}
@@ -673,7 +681,7 @@ array_items_tail {-> expr}
        ;
 array_item {-> expr}
        = expr no {-> expr}
-       | {for} kwfor no [ids]:idlist [n2]:no kwin [n3]:no expr [n4]:no kwdo [block]:array_item {-> New expr.for(kwfor, [ids.id], kwin, expr, kwdo, block.expr, Null)}
+       | {for} kwfor no for_groups [n4]:no kwdo [block]:array_item {-> New expr.for(kwfor, [for_groups.for_group], kwdo, block.expr, Null)}
        | {if} kwif [n1]:no expr [n2]:no kwthen [n3]:no [then]:array_item {-> New expr.if(kwif, expr, kwthen, then.expr, Null, Null)}
        ;
 
@@ -951,7 +959,7 @@ expr        = {block} expr* kwend?
        | {ifexpr} kwif expr kwthen [then]:expr kwelse [else]:expr
        | {while} kwwhile expr kwdo [block]:expr? label?
        | {loop} kwloop [block]:expr? label?
-       | {for} kwfor [ids]:id* kwin expr kwdo [block]:expr? label?
+       | {for} kwfor [groups]:for_group* kwdo [block]:expr? label?
        | {with} kwwith expr kwdo [block]:expr? label?
        | {assert} kwassert id? expr kwelse? [else]:expr?
        | {once} kwonce expr 
@@ -1046,6 +1054,9 @@ assign_op
        | {ll} [op]:lleq
        | {gg} [op]:ggeq
        ;
+for_group
+       = [ids]:id* kwin expr
+       ;
 
 module_name = quad? [path]:id* id;
 extern_calls = kwimport [extern_calls]:extern_call*
index 5204376..df01109 100644 (file)
@@ -1907,6 +1907,23 @@ class AForExpr
        # The `for` keyword
        var n_kwfor: TKwfor is writable, noinit
 
+       # The list of groups to iterate
+       var n_groups = new ANodes[AForGroup](self)
+
+       # The `do` keyword
+       var n_kwdo: TKwdo is writable, noinit
+
+       # The body of the loop
+       var n_block: nullable AExpr = null is writable
+end
+
+# A collection iterated by a for, its automatic variables and its implicit iterator.
+#
+# Standard `for` iterate on a single collection.
+# Multiple `for` can iterate on more than one collection at once.
+class AForGroup
+       super Prod
+
        # The list of name of the automatic variables
        var n_ids = new ANodes[TId](self)
 
@@ -1915,12 +1932,6 @@ class AForExpr
 
        # The expression used as the collection to iterate on
        var n_expr: AExpr is writable, noinit
-
-       # The `do` keyword
-       var n_kwdo: TKwdo is writable, noinit
-
-       # The body of the loop
-       var n_block: nullable AExpr = null is writable
 end
 
 # A `with` statement