From ef07fab261cce781ca750c1288574d4001f14bcf Mon Sep 17 00:00:00 2001 From: Johnny Richard Date: Sun, 30 Apr 2023 01:48:18 +0200 Subject: 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 Co-authored-by: Carlos Maniero --- src/parser.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'src/parser.c') 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; } -- cgit v1.2.3