diff --git a/c/containers/mlr_dsl_ast.c b/c/containers/mlr_dsl_ast.c index d9e2dcbe6..c7aeec3b0 100644 --- a/c/containers/mlr_dsl_ast.c +++ b/c/containers/mlr_dsl_ast.c @@ -146,6 +146,7 @@ char* mlr_dsl_ast_node_describe_type(mlr_dsl_ast_node_type_t type) { switch(type) { case MD_AST_NODE_TYPE_STATEMENT_LIST: return "statement_list"; break; case MD_AST_NODE_TYPE_DEF: return "def"; break; + case MD_AST_NODE_TYPE_LOCAL: return "local"; break; case MD_AST_NODE_TYPE_RETURN: return "return"; break; case MD_AST_NODE_TYPE_BEGIN: return "begin"; break; case MD_AST_NODE_TYPE_END: return "end"; break; diff --git a/c/containers/mlr_dsl_ast.h b/c/containers/mlr_dsl_ast.h index b0b69035f..eeebad29b 100644 --- a/c/containers/mlr_dsl_ast.h +++ b/c/containers/mlr_dsl_ast.h @@ -10,6 +10,7 @@ typedef enum _mlr_dsl_ast_node_type_t { MD_AST_NODE_TYPE_STATEMENT_LIST, MD_AST_NODE_TYPE_DEF, + MD_AST_NODE_TYPE_LOCAL, MD_AST_NODE_TYPE_RETURN, MD_AST_NODE_TYPE_BEGIN, MD_AST_NODE_TYPE_END, diff --git a/c/dsls/mlr_dsl_lexer.l b/c/dsls/mlr_dsl_lexer.l index 0572feaa7..60f51926d 100644 --- a/c/dsls/mlr_dsl_lexer.l +++ b/c/dsls/mlr_dsl_lexer.l @@ -93,6 +93,10 @@ *yyextra = mlr_dsl_ast_node_alloc(yytext, MD_AST_NODE_TYPE_STRIPPED_AWAY); return MD_TOKEN_DEF; } +"local" { + *yyextra = mlr_dsl_ast_node_alloc(yytext, MD_AST_NODE_TYPE_STRIPPED_AWAY); + return MD_TOKEN_LOCAL; +} "return" { *yyextra = mlr_dsl_ast_node_alloc(yytext, MD_AST_NODE_TYPE_STRIPPED_AWAY); return MD_TOKEN_RETURN; diff --git a/c/dsls/mlr_dsl_parse.y b/c/dsls/mlr_dsl_parse.y index 764b60a7a..f4ba55d52 100644 --- a/c/dsls/mlr_dsl_parse.y +++ b/c/dsls/mlr_dsl_parse.y @@ -20,6 +20,7 @@ // * begin{end{}} -- begin/end not at top level // * begin{$x=1} -- references to stream records at begin/end // * break/continue outside of for/while/do-while +// * return outside of a function definition // * $x=x -- boundvars outside of for-loop variable bindings // All of the above are enforced by the CST builder, which takes this parser's output AST as input. // This is done (a) to keep this grammar from being overly complex, and (b) so we can get much more @@ -109,6 +110,9 @@ md_statement_not_braced_end(A) ::= . { } // Only valid in def blocks +md_statement_not_braced_end(A) ::= MD_TOKEN_LOCAL MD_TOKEN_NON_SIGIL_NAME(N) MD_TOKEN_ASSIGN md_rhs(B). { + A = mlr_dsl_ast_node_alloc_binary("local", MD_AST_NODE_TYPE_RETURN, N, B); +} md_statement_not_braced_end(A) ::= MD_TOKEN_RETURN md_rhs(B). { A = mlr_dsl_ast_node_alloc_unary("return", MD_AST_NODE_TYPE_RETURN, B); }