harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 6faec06c9543a42593ce939eeec8d47ed02879ea
parent a2ca744f88807e7f895ca42261a8f57e50261dff
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Tue, 12 Jan 2021 18:35:32 -0500

parse: implement break/continue

Diffstat:
Minclude/ast.h | 6++++++
Msrc/parse.c | 29++++++++++++++++++++++++++---
2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/include/ast.h b/include/ast.h @@ -201,7 +201,12 @@ struct ast_expression_constant { }; }; +struct ast_expression_control { + char *label; +}; + struct ast_expression_for { + char *label; struct ast_expression *bindings; struct ast_expression *cond; struct ast_expression *afterthought; @@ -275,6 +280,7 @@ struct ast_expression { struct ast_expression_call call; struct ast_expression_cast cast; struct ast_expression_constant constant; + struct ast_expression_control control; struct ast_expression_for _for; struct ast_expression_if _if; struct ast_expression_list list; diff --git a/src/parse.c b/src/parse.c @@ -1530,6 +1530,17 @@ parse_for_expression(struct lexer *lexer) exp->type = EXPR_FOR; struct token tok = {0}; + switch (lex(lexer, &tok)) { + case T_FOR: + break; + case T_LABEL: + exp->_for.label = tok.name; + want(lexer, T_FOR, NULL); + break; + default: + assert(0); + } + want(lexer, T_LPAREN, &tok); switch (lex(lexer, &tok)) { case T_LET: @@ -1570,9 +1581,9 @@ parse_complex_expression(struct lexer *lexer) case T_IF: return parse_if_expression(lexer); case T_FOR: - return parse_for_expression(lexer); case T_LABEL: - assert(0); // TODO: Loop labels + unlex(lexer, &tok); + return parse_for_expression(lexer); case T_MATCH: case T_SWITCH: assert(0); // TODO @@ -1688,6 +1699,7 @@ parse_scope_expression(struct lexer *lexer) assert(0); // TODO: This is a static binding list or assert case T_IF: case T_FOR: + case T_LABEL: case T_MATCH: case T_SWITCH: unlex(lexer, &tok); @@ -1750,7 +1762,18 @@ parse_control_statement(struct lexer *lexer) switch (lex(lexer, &tok)) { case T_BREAK: case T_CONTINUE: - assert(0); // TODO + trace(TR_PARSE, tok.token == T_BREAK ? "break" : "continue"); + exp->type = tok.token == T_BREAK ? EXPR_BREAK : EXPR_CONTINUE; + exp->control.label = NULL; + switch (lex(lexer, &tok)) { + case T_LABEL: + exp->control.label = tok.name; + break; + default: + unlex(lexer, &tok); + break; + } + break; case T_RETURN: trace(TR_PARSE, "return"); exp->type = EXPR_RETURN;