diff options
author | Himbeer <himbeer@disroot.org> | 2024-10-02 15:47:53 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-10-02 15:50:02 +0200 |
commit | 5ba544c4e016de3d61a296ceeaf7c4a143f3c118 (patch) | |
tree | 2d3e948856a315fa9a9fca8da16d7c6d48c511ed | |
parent | 6dcaccdab64366d086898dc289fda9d80b98e636 (diff) |
Implement optional break expressions
-rw-r--r-- | include/parse.h | 7 | ||||
-rw-r--r-- | src/parse.c | 23 |
2 files changed, 21 insertions, 9 deletions
diff --git a/include/parse.h b/include/parse.h index b3e8eee..0889f91 100644 --- a/include/parse.h +++ b/include/parse.h @@ -28,6 +28,11 @@ struct ast_return { struct ast_expr *value; }; +struct ast_break { + const char *label; + struct ast_expr *value; +}; + struct ast_declaration { bool mut; const char *name; @@ -72,7 +77,7 @@ struct ast_statement { enum statement action; union { struct ast_return ret; - const char *brklabel; + struct ast_break brk; struct ast_declaration decl; struct ast_assign assign; struct call_e call; diff --git a/src/parse.c b/src/parse.c index 3fa1498..ee115d8 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1107,14 +1107,14 @@ parse_return(struct lexer *lexer, struct ast_return *out) } static bool -parse_break(struct lexer *lexer, const char **out) +parse_break(struct lexer *lexer, struct ast_break *out) { if (!match(lexer, T_BREAK)) { return false; } if (!match(lexer, T_COLON)) { - *out = NULL; + out->label = NULL; return true; } @@ -1122,20 +1122,26 @@ parse_break(struct lexer *lexer, const char **out) if (lex(lexer, &label) != T_NAME) { error(lex_loc(lexer), "syntax error: expected name"); } - *out = label.info.str; + out->label = label.info.str; + + out->value = must_malloc(sizeof(struct ast_expr)); + if (!parse_expr(lexer, out->value)) { + free(out->value); + out->value = NULL; + } return true; } static bool -parse_continue(struct lexer *lexer, const char **out) +parse_continue(struct lexer *lexer, struct ast_break *out) { if (!match(lexer, T_CONTINUE)) { return false; } if (!match(lexer, T_COLON)) { - *out = NULL; + out->label = NULL; return true; } @@ -1143,8 +1149,9 @@ parse_continue(struct lexer *lexer, const char **out) if (lex(lexer, &label) != T_NAME) { error(lex_loc(lexer), "syntax error: expected name"); } - *out = label.info.str; + out->label = label.info.str; + out->value = NULL; return true; } @@ -1307,14 +1314,14 @@ parse_statement(struct lexer *lexer, struct ast_statement *out) } return true; } - if (parse_break(lexer, &out->stmt.brklabel)) { + if (parse_break(lexer, &out->stmt.brk)) { out->action = STM_BREAK; if (!match(lexer, T_SEMICOLON)) { error(lex_loc(lexer), "syntax error: expected semicolon"); } return true; } - if (parse_continue(lexer, &out->stmt.brklabel)) { + if (parse_continue(lexer, &out->stmt.brk)) { out->action = STM_CONTINUE; if (!match(lexer, T_SEMICOLON)) { error(lex_loc(lexer), "syntax error: expected semicolon"); |