diff --git a/doc/17-language-reference.md b/doc/17-language-reference.md
index d2a865811..9bd31d6b7 100644
--- a/doc/17-language-reference.md
+++ b/doc/17-language-reference.md
@@ -830,7 +830,7 @@ Example:
var list = [ "a", "b", "c" ]
- for (item in list) {
+ for (var item in list) {
log("Item: " + item)
}
@@ -841,7 +841,7 @@ Iterating over dictionaries can be accomplished in a similar manner:
var dict = { a = 3, b = 7 }
- for (key => value in dict) {
+ for (var key => var value in dict) {
log("Key: " + key + ", Value: " + value)
}
@@ -849,6 +849,9 @@ The `continue` and `break` keywords can be used to control how the loop is execu
skips over the remaining expressions for the loop body and begins the next loop evaluation. The `break` keyword
breaks out of the loop.
+The `var` keyword is optional when declaring variables in the loop's header. Variables declared without the `var`
+keyword are nonetheless local to the function.
+
## Constructors
In order to create a new value of a specific type constructor calls may be used.
diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy
index 70f309bd3..1a47c6932 100644
--- a/lib/config/config_parser.yy
+++ b/lib/config/config_parser.yy
@@ -469,6 +469,10 @@ combined_set_op: T_SET
| T_SET_BINARY_OR
;
+optional_var: /* empty */
+ | T_VAR
+ ;
+
lterm: T_LIBRARY rterm
{
$$ = new LibraryExpression(std::unique_ptr($2), @$);
@@ -603,7 +607,7 @@ lterm: T_LIBRARY rterm
}
| apply
| object
- | T_FOR '(' identifier T_FOLLOWS identifier T_IN rterm ')'
+ | T_FOR '(' optional_var identifier T_FOLLOWS optional_var identifier T_IN rterm ')'
{
BeginFlowControlBlock(context, FlowControlContinue | FlowControlBreak, true);
}
@@ -611,11 +615,11 @@ lterm: T_LIBRARY rterm
{
EndFlowControlBlock(context);
- $$ = new ForExpression(*$3, *$5, std::unique_ptr($7), std::unique_ptr($10), @$);
- delete $3;
- delete $5;
+ $$ = new ForExpression(*$4, *$7, std::unique_ptr($9), std::unique_ptr($12), @$);
+ delete $4;
+ delete $7;
}
- | T_FOR '(' identifier T_IN rterm ')'
+ | T_FOR '(' optional_var identifier T_IN rterm ')'
{
BeginFlowControlBlock(context, FlowControlContinue | FlowControlBreak, true);
}
@@ -623,8 +627,8 @@ lterm: T_LIBRARY rterm
{
EndFlowControlBlock(context);
- $$ = new ForExpression(*$3, "", std::unique_ptr($5), std::unique_ptr($8), @$);
- delete $3;
+ $$ = new ForExpression(*$4, "", std::unique_ptr($6), std::unique_ptr($9), @$);
+ delete $4;
}
| T_FUNCTION identifier '(' identifier_items ')' use_specifier
{
@@ -1103,24 +1107,24 @@ use_specifier_item: identifier
;
apply_for_specifier: /* empty */
- | T_FOR '(' identifier T_FOLLOWS identifier T_IN rterm ')'
+ | T_FOR '(' optional_var identifier T_FOLLOWS optional_var identifier T_IN rterm ')'
{
- context->m_FKVar.top() = *$3;
- delete $3;
+ context->m_FKVar.top() = *$4;
+ delete $4;
- context->m_FVVar.top() = *$5;
- delete $5;
+ context->m_FVVar.top() = *$7;
+ delete $7;
- context->m_FTerm.top() = $7;
+ context->m_FTerm.top() = $9;
}
- | T_FOR '(' identifier T_IN rterm ')'
+ | T_FOR '(' optional_var identifier T_IN rterm ')'
{
- context->m_FKVar.top() = *$3;
- delete $3;
+ context->m_FKVar.top() = *$4;
+ delete $4;
context->m_FVVar.top() = "";
- context->m_FTerm.top() = $5;
+ context->m_FTerm.top() = $6;
}
;