summaryrefslogtreecommitdiff
path: root/src/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c27
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;
}