diff --git a/doc/macroprocessor/macroprocessor.tex b/doc/macroprocessor/macroprocessor.tex
index fec6052f31b3a3464a0a57bfddf8e68712dac9b6..4d26aa165780b430ca2fce86a0e674c8d05fa0d0 100644
--- a/doc/macroprocessor/macroprocessor.tex
+++ b/doc/macroprocessor/macroprocessor.tex
@@ -399,12 +399,26 @@ end;
 \end{frame}
 
 \begin{frame}[fragile=singleslide]
-  \frametitle{Loop directive}
-  \begin{block}{Syntax}
+  \frametitle{Loop directive (1/2)}
+  \begin{block}{Syntax 1}
 \verb+@#for +\textit{variable\_name}\verb+ in +\textit{array\_expr} \\
 \verb+   +\textit{loop\_body} \\
 \verb+@#endfor+
   \end{block}
+  \begin{block}{Syntax 2}
+\verb+@#for +\textit{tuple}\verb+ in +\textit{array\_expr} \\
+\verb+   +\textit{loop\_body} \\
+\verb+@#endfor+
+  \end{block}
+  \begin{block}{Syntax 3}
+\verb+@#for +\textit{tuple\_or\_variable}\verb+ in +\textit{array\_expr} \verb+ when +\textit{expr}\\
+\verb+   +\textit{loop\_body} \\
+\verb+@#endfor+
+  \end{block}
+\end{frame}
+
+\begin{frame}[fragile=singleslide]
+  \frametitle{Loop directive (2/2)}
   \begin{block}{Example: before macro processing}
     \small
 \begin{verbatim}
diff --git a/src/macro/Parser.yy b/src/macro/Parser.yy
index e6ba09dc79e0e38a6d86da9102621290fda44f6f..b46cea4bacf15ab09b62c7ca3dfd57d4ad4c29bc 100644
--- a/src/macro/Parser.yy
+++ b/src/macro/Parser.yy
@@ -95,11 +95,10 @@ using namespace macro;
 %type <DirectivePtr> directive directive_one_line directive_multiline for if ifdef ifndef text eval
 %type <vector<pair<ExpressionPtr, vector<DirectivePtr>>>> if_list if_list1
 %type <pair<ExpressionPtr, vector<DirectivePtr>>> elseif else
-%type <ExpressionPtr> primary_expr oper_expr colon_expr expr
+%type <ExpressionPtr> primary_expr oper_expr colon_expr expr for_when
 %type <FunctionPtr> function
 %type <VariablePtr> symbol
 
-%type <vector<VariablePtr>> comma_name
 %type <vector<ExpressionPtr>> comma_expr function_args tuple_comma_expr
 
 %%
@@ -149,38 +148,43 @@ directive_multiline : for
                     | ifndef
                     ;
 
-for_begin : FOR { driver.pushContext(); } ;
+for_when : %empty
+           { $$ = shared_ptr<Expression>(); }
+         | WHEN expr
+           { $$ = $2; }
+         ;
 
-for : for_begin symbol IN expr EOL statements ENDFOR
-      {
-        vector<VariablePtr> vvnp = {$2};
-        auto vdp = driver.popContext();
-        vdp.emplace_back(make_shared<TextNode>("\n", driver.env, @7));
-        $$ = make_shared<For>(vvnp, $4, vdp, driver.env, @$);
-      }
-    | for_begin LPAREN comma_name RPAREN IN expr EOL statements ENDFOR
+for : FOR { driver.pushContext(); } expr IN expr for_when EOL statements ENDFOR
       {
         vector<VariablePtr> vvnp;
-        for (auto & it : $3)
-          {
-            auto vnp = dynamic_pointer_cast<Variable>(it);
-            if (!vnp)
-              error(@$, "For loop indices must be variables");
-            vvnp.push_back(vnp);
-          }
+        auto tmpt = dynamic_pointer_cast<Tuple>($3);
+        auto tmpv = dynamic_pointer_cast<Variable>($3);
+        if (tmpv)
+          vvnp.emplace_back(tmpv);
+        else if (tmpt)
+          for (auto & it : tmpt->getValue())
+            {
+              auto vnp = dynamic_pointer_cast<Variable>(it);
+              if (!vnp)
+                error(@$, "For loop indices must be variables");
+              vvnp.emplace_back(vnp);
+            }
+        else
+          error(@1, "For loop indices must be a variable or a tuple");
+
         auto vdp = driver.popContext();
         vdp.emplace_back(make_shared<TextNode>("\n", driver.env, @9));
-        $$ = make_shared<For>(vvnp, $6, vdp, driver.env, @$);
+
+        if (!$6)
+          $$ = make_shared<For>(vvnp, $5, vdp, driver.env, @$);
+        else
+          {
+            auto tmpc = make_shared<Comprehension>(true, $3, $5, $6, driver.env, @6);
+            $$ = make_shared<For>(vvnp, tmpc, vdp, driver.env, @$);
+          }
       }
     ;
 
-comma_name : NAME
-             { $$ = vector<VariablePtr>{make_shared<Variable>($1, driver.env, @$)}; }
-           | comma_name COMMA NAME
-             { $1.emplace_back(make_shared<Variable>($3, driver.env, @3)); $$ = $1; }
-           ;
-
-
 if : IF { driver.pushContext(); } if_list ENDIF
      { $$ = make_shared<If>($3, driver.env, @$); }
    ;