summaryrefslogtreecommitdiff
path: root/src/parser.c
diff options
context:
space:
mode:
authorCarlos Maniero <carlos@maniero.me>2023-05-02 23:45:50 -0300
committerJohnny Richard <johnny@johnnyrichard.com>2023-05-03 22:39:26 +0200
commit990f4d3e4c662c401a08e3704a39878fd6c1c1b6 (patch)
treeeb8e7469afafc6babae582304b8695611e179ad3 /src/parser.c
parent77dbf3a5011566b4a6274b3cdfa075dd723642d3 (diff)
parser: Refactor return statement to return an ast_node
During the refactoring process, I identified a memory leak where the return argument was allocated but not freed in case of an error. It also introduces the concept of keyword tokens. Where return is now a keyword simplifying the parser. Signed-off-by: Carlos Maniero <carlos@maniero.me>
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/src/parser.c b/src/parser.c
index ca5600d..8218c87 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -221,18 +221,23 @@ parser_parse_expression(parser_t *parser, ast_node_t *node)
return true;
}
-static bool
-parser_parse_return_stmt(parser_t *parser, ast_node_t *node)
+static ast_node_t *
+parser_parse_return_stmt(parser_t *parser)
{
ast_node_t *argument_token = ast_node_new();
- if (!parser_parse_expression(parser, argument_token))
- return false;
+ if (!parser_parse_expression(parser, argument_token)) {
+ ast_node_destroy(argument_token);
+ return NULL;
+ }
- if (!drop_expected_token(parser, TOKEN_SEMICOLON))
- return false;
+ if (!drop_expected_token(parser, TOKEN_SEMICOLON)) {
+ ast_node_destroy(argument_token);
+ return NULL;
+ }
+ ast_node_t *node = ast_node_new();
ast_node_init_return_stmt(node, argument_token);
- return true;
+ return node;
}
static bool
@@ -311,19 +316,17 @@ parser_parse_block_declarations(parser_t *parser)
vector_t *body = vector_new();
while (current_token.kind != TOKEN_CCURLY && current_token.kind != TOKEN_EOF) {
- if (current_token.kind != TOKEN_NAME) {
+ if (current_token.kind != TOKEN_NAME && current_token.kind != TOKEN_KEYWORD_RETURN) {
parser_error_push_unexpected_kind(parser, &current_token, TOKEN_NAME);
scope_leave(parser->scope);
vector_destroy(body);
return NULL;
}
- if (string_view_eq(current_token.value, string_view_from_str("return"))) {
- ast_node_t *return_node = ast_node_new();
- bool parsed_return = parser_parse_return_stmt(parser, return_node);
+ if (current_token.kind == TOKEN_KEYWORD_RETURN) {
+ ast_node_t *return_node = parser_parse_return_stmt(parser);
- if (!parsed_return) {
- ast_node_destroy(return_node);
+ if (return_node == NULL) {
scope_leave(parser->scope);
vector_destroy(body);
return NULL;
@@ -367,6 +370,7 @@ parser_parse_block_declarations(parser_t *parser)
case TOKEN_CCURLY:
case TOKEN_NUMBER:
case TOKEN_PLUS:
+ case TOKEN_KEYWORD_RETURN:
case TOKEN_MINUS:
case TOKEN_STAR:
case TOKEN_SLASH: