diff options
author | Johnny Richard <johnny@johnnyrichard.com> | 2023-04-30 01:48:18 +0200 |
---|---|---|
committer | Johnny Richard <johnny@johnnyrichard.com> | 2023-04-30 01:55:29 +0200 |
commit | ef07fab261cce781ca750c1288574d4001f14bcf (patch) | |
tree | 9b4da44aee7cc64cec448adeee31b38e12d29e6d /src/parser.c | |
parent | 88a08db927629032d6d4c662e00f0dce2c112ce4 (diff) |
parser: Registry identifiers on scope
We are parsing variables/functions and checking if they are defined on
scope. Otherwise we fail the parsing with a nice message.
Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
Co-authored-by: Carlos Maniero <carlosmaniero@gmail.com>
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/src/parser.c b/src/parser.c index 6b954c2..469fa99 100644 --- a/src/parser.c +++ b/src/parser.c @@ -24,14 +24,16 @@ #include "ast.h" #include "lexer.h" #include "parser.h" +#include "scope.h" #include "vector.h" void -parser_init(parser_t *parser, lexer_t *lexer) +parser_init(parser_t *parser, lexer_t *lexer, scope_t *scope) { assert(parser && "parser must be defined"); assert(lexer && "lexer must be defined"); parser->lexer = lexer; + parser->scope = scope; parser->errors_len = 0; } @@ -134,8 +136,16 @@ parser_parse_factor(parser_t *parser, ast_node_t *node) return false; return true; case TOKEN_NAME: - /// FIXME: Check if the identifier is defined ast_node_init_identifier(node, token.value); + // TODO: Check node kind, today accepts only variables + if (scope_get(parser->scope, token.value) == NULL) { + parser_error_t error; + error.token = token; + sprintf(error.message, "identifier '" SVFMT "' not defined", SVARG(&token.value)); + parser->errors[parser->errors_len++] = error; + return false; + } + return true; default: { parser_error_t error; @@ -143,7 +153,7 @@ parser_parse_factor(parser_t *parser, ast_node_t *node) sprintf(error.message, "unexpected '%s (" SVFMT ")' token", token_kind_to_str(token.kind), SVARG(&token.value)); parser->errors[parser->errors_len++] = error; return false; - } + } } } @@ -247,6 +257,7 @@ parser_parse_variable_definition(parser_t *parser, string_view_t variable_name, } ast_node_init_variable_declaration(node, variable_name, type, expression); + scope_push(parser->scope, &node->data.variable.identifier, node); return true; } @@ -333,11 +344,17 @@ parser_parse_function_declaration(parser_t *parser, ast_node_t *node) return false; vector_t *body = vector_new(); + ast_node_init_function_declaration(node, func_name_token.value, return_type, body); + scope_push(parser->scope, &node->data.function.identifier, node); + + scope_enter(parser->scope); - if (!parser_parse_block_declarations(parser, body)) + if (!parser_parse_block_declarations(parser, body)) { + scope_leave(parser->scope); return false; + } - ast_node_init_function_declaration(node, func_name_token.value, return_type, body); + scope_leave(parser->scope); return true; } |