diff options
author | Carlos Maniero <carlosmaniero@gmail.com> | 2023-04-20 11:05:54 -0300 |
---|---|---|
committer | Johnny Richard <johnny@johnnyrichard.com> | 2023-04-20 16:14:14 +0200 |
commit | a47e5ceb6eefdac9c5f5473e1fee0d33a5f4646e (patch) | |
tree | 20beb62b87998ec301d461175c8500f222101a75 /src/parser.c | |
parent | 547643d357aadfcb402ec9b951e23975da8593cc (diff) |
ast: Allows recursive nodes
Previously, the abstract syntax tree (AST) used static types, meaning
that an ast_function_t would always have a ast_return_stmt_t as
its body. However, this assumption is not always true, as we may have
void functions that do not have a return statement. Additionally, the
ast_return_stmt_t always had a number associated with it, but this too
is not always the case.
To make this possible, I need to perform a few changes in the whole
project. One of the main changes is that there is no longer the
inheritance hack. That mechanism was replaced by composition and
pointers where required for recursive type reference.
It is important to mention that I decided to use union type to implement
the composition. There is two main advantages in this approach:
1. There is only one function to allocate memory for all kind of nodes.
2. There is no need to cast the data.
In summary, this commit introduces changes to support dynamic typing
in the AST, by replacing the inheritance hack with composition and
using union types to simplify memory allocation and type casting.
Signed-off-by: Carlos Maniero <carlosmaniero@gmail.com>
Reviewed-by: Johnny Richard <johnny@johnnyrichard.com>
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/src/parser.c b/src/parser.c index b956c4e..b1e6a1f 100644 --- a/src/parser.c +++ b/src/parser.c @@ -70,12 +70,12 @@ parser_parse_type(parser_t *parser) return TYPE_I32; } - fprintf(stderr, "[ERROR]: expected type 'i32' but got '"SVFMT"'\n", SVARG(&token.value)); + fprintf(stderr, "[ERROR]: expected type 'i32' but got '"SVFMT"'\n", SVARG(&token.value)); exit(EXIT_FAILURE); } -static ast_return_stmt_t -parser_parse_return_stmt(parser_t *parser) +void +parser_parse_return_stmt(parser_t *parser, ast_node_t *node) { expected_token(parser, TOKEN_OCURLY); token_t return_keyword_token = expected_token(parser, TOKEN_NAME); @@ -93,11 +93,11 @@ parser_parse_return_stmt(parser_t *parser) char number_as_str[number_token.value.size]; string_view_to_str(&number_token.value, number_as_str); - return ast_return_stmt_create(atoi(number_as_str)); + ast_node_init_return_stmt(node, atoi(number_as_str)); } -ast_function_t -parser_parse_function(parser_t *parser) +void +parser_parse_function_declaration(parser_t *parser, ast_node_t *node) { token_t func_name_token = expected_token(parser, TOKEN_NAME); expected_token(parser, TOKEN_OPAREN); @@ -105,9 +105,13 @@ parser_parse_function(parser_t *parser) expected_token(parser, TOKEN_COLON); type_t return_type = parser_parse_type(parser); - return ast_function_create( + ast_node_t *return_node = ast_node_new(); + parser_parse_return_stmt(parser, return_node); + + ast_node_init_function_declaration( + node, func_name_token.value, return_type, - parser_parse_return_stmt(parser) + return_node ); } |