lang: Add a for loop statement for iterating over a list
This adds a for statement which is used to iterate over a list with a body of statements. This is an important data transformation tool which should be used sparingly, but is important to have. An import statement inside of a for loop is not currently supported. We have a simple hack to detect the obvious cases, but more deeply nested scenarios probably won't be caught, and you'll get an obscure error message if you try to do this. This was incredibly challenging to get right, and it's all thanks to Sam for his brilliance. Co-authored-by: Samuel Gélineau <gelisam@gmail.com>
This commit is contained in:
@@ -154,6 +154,11 @@
|
||||
lval.str = yylex.Text()
|
||||
return IN
|
||||
}
|
||||
/for/ {
|
||||
yylex.pos(lval) // our pos
|
||||
lval.str = yylex.Text()
|
||||
return FOR
|
||||
}
|
||||
/\->/ {
|
||||
yylex.pos(lval) // our pos
|
||||
lval.str = yylex.Text()
|
||||
|
||||
@@ -92,7 +92,7 @@ func init() {
|
||||
%token OPEN_CURLY CLOSE_CURLY
|
||||
%token OPEN_PAREN CLOSE_PAREN
|
||||
%token OPEN_BRACK CLOSE_BRACK
|
||||
%token IF ELSE
|
||||
%token IF ELSE FOR
|
||||
%token BOOL STRING INTEGER FLOAT
|
||||
%token EQUALS DOLLAR
|
||||
%token COMMA COLON SEMICOLON
|
||||
@@ -216,6 +216,18 @@ stmt:
|
||||
}
|
||||
locate(yylex, $1, yyDollar[len(yyDollar)-1], $$.stmt)
|
||||
}
|
||||
// iterate over lists
|
||||
// `for $index, $value in $list { <body> }`
|
||||
| FOR var_identifier COMMA var_identifier IN expr OPEN_CURLY prog CLOSE_CURLY
|
||||
{
|
||||
$$.stmt = &ast.StmtFor{
|
||||
Index: $2.str, // no $ prefix
|
||||
Value: $4.str, // no $ prefix
|
||||
Expr: $6.expr, // XXX: name this List ?
|
||||
Body: $8.stmt,
|
||||
}
|
||||
locate(yylex, $1, yyDollar[len(yyDollar)-1], $$.stmt)
|
||||
}
|
||||
// this is the named version, iow, a user-defined function (statement)
|
||||
// `func name() { <expr> }`
|
||||
// `func name(<arg>) { <expr> }`
|
||||
|
||||
Reference in New Issue
Block a user