aboutsummaryrefslogtreecommitdiff
path: root/src/ast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast.c')
-rw-r--r--src/ast.c61
1 files changed, 45 insertions, 16 deletions
diff --git a/src/ast.c b/src/ast.c
index 4ee0934..a2a927c 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -128,6 +128,7 @@ int scope_init(Scope *self, Scope *parent, ScopedAllocator *allocator) {
return_if_error(buffer_init(&self->ast_objects, allocator));
return_if_error(hash_map_init(&self->named_objects, allocator, sizeof(Ast*), hash_compare_string, amal_hash_string));
self->parent = parent;
+ self->parser = NULL;
return 0;
}
@@ -271,7 +272,6 @@ static void import_resolve(Ast *ast, AstCompilerContext *context) {
assert(ast->resolve_data.type);
}
-/* LhsExpr has to be resolved before this is called */
static Scope* lhsexpr_get_scope(LhsExpr *self) {
AstValue value;
value = self->rhs_expr->value;
@@ -289,6 +289,19 @@ static Scope* lhsexpr_get_scope(LhsExpr *self) {
return NULL;
}
+/* @self has to be resolved before calling this */
+static Parser* get_resolved_type_parser(Ast *self) {
+ Scope *scope;
+ scope = lhsexpr_get_scope(self->resolve_data.type);
+ while(scope) {
+ if(scope->parser)
+ return scope->parser;
+ scope = scope->parent;
+ }
+ assert(bool_false && "BUG: At least some parent is supposed to have a parser");
+ return NULL;
+}
+
static void funcdecl_resolve(FunctionDecl *self, AstCompilerContext *context) {
/* TODO: Implement parameters and return types */
scope_resolve(&self->body, context);
@@ -301,6 +314,22 @@ static void funccall_resolve(Ast *self, AstCompilerContext *context) {
func_call = self->value.func_call;
variable_resolve(&func_call->func, context, &self->resolve_data);
+ if(self->resolve_data.type->rhs_expr->type != AST_FUNCTION_DECL) {
+ Parser *callee_parser;
+ BufferView callee_code_ref;
+ callee_parser = get_resolved_type_parser(self);
+ callee_code_ref = self->resolve_data.type->var_name;
+
+ tokenizer_print_error(&context->parser->tokenizer,
+ tokenizer_get_code_reference_index(&context->parser->tokenizer, func_call->func.name.data),
+ "\"%.*s\" is not a function. Only functions can be called", func_call->func.name.size, func_call->func.name.data);
+ /* TODO: use tokenizer_print_note, once it has been added */
+ /* TODO: Print type */
+ tokenizer_print_error(&context->parser->tokenizer,
+ tokenizer_get_code_reference_index(&callee_parser->tokenizer, callee_code_ref.data),
+ "Type was declared here");
+ throw(AST_ERR);
+ }
ast = buffer_start(&func_call->args);
ast_end = buffer_end(&func_call->args);
@@ -327,6 +356,7 @@ static void binop_resolve_dot_access(Ast *ast, AstCompilerContext *context) {
Scope *lhs_scope;
Parser *callee_parser;
BufferView caller_code_ref;
+ BufferView callee_code_ref;
assert(ast->type == AST_BINOP);
self = ast->value.binop;
@@ -343,24 +373,20 @@ static void binop_resolve_dot_access(Ast *ast, AstCompilerContext *context) {
lhs_scope = lhsexpr_get_scope(self->lhs->resolve_data.type);
self->rhs->resolve_data.type = scope_get_resolved_variable(lhs_scope, context, self->rhs->value.variable->name)->resolve_data.type;
- self->rhs->resolve_data.status = AST_RESOLVED;
- /*
- const io = @import("std.io");
- io.write ^
- ^-from this, to-'
- */
- if(self->lhs->resolve_data.type->rhs_expr->type == AST_IMPORT)
- callee_parser = self->lhs->resolve_data.type->rhs_expr->value.import->file_scope->parser;
-
+ callee_parser = get_resolved_type_parser(self->rhs);
caller_code_ref = ast_get_code_reference(self->rhs);
- callee_parser = context->parser;
+ callee_code_ref = self->rhs->resolve_data.type->var_name;
- if(self->rhs->resolve_data.type->rhs_expr->type != AST_STRUCT_DECL) {
- /* TODO: Add note where the referenced data was declared */
+ if(self->lhs->resolve_data.type->rhs_expr->type != AST_STRUCT_DECL) {
tokenizer_print_error(&context->parser->tokenizer,
tokenizer_get_code_reference_index(&context->parser->tokenizer, caller_code_ref.data),
- "Can only access field of struct's");
+ "Can only access field of structs");
+ /* TODO: use tokenizer_print_note, once it has been added */
+ /* TODO: Print type */
+ tokenizer_print_error(&context->parser->tokenizer,
+ tokenizer_get_code_reference_index(&callee_parser->tokenizer, callee_code_ref.data),
+ "Type was declared here");
throw(AST_ERR);
}
@@ -371,7 +397,7 @@ static void binop_resolve_dot_access(Ast *ast, AstCompilerContext *context) {
/* TODO: use tokenizer_print_note, once it has been added */
/* TODO: Print type */
tokenizer_print_error(&context->parser->tokenizer,
- tokenizer_get_code_reference_index(&callee_parser->tokenizer, caller_code_ref.data),
+ tokenizer_get_code_reference_index(&callee_parser->tokenizer, callee_code_ref.data),
"Type was declared non-public here");
throw(AST_ERR);
}
@@ -382,8 +408,11 @@ static void binop_resolve(Ast *ast, AstCompilerContext *context) {
assert(ast->type == AST_BINOP);
self = ast->value.binop;
ast_resolve(self->lhs, context);
- if(self->type == BINOP_DOT && self->rhs->type == AST_VARIABLE) {
+ if(self->type == BINOP_DOT && (self->rhs->type == AST_VARIABLE || self->rhs->type == AST_FUNCTION_CALL)) {
binop_resolve_dot_access(ast, context);
+ /* Only function call has extra data that needs to be resolved (args) */
+ if(self->rhs->type == AST_FUNCTION_CALL)
+ ast_resolve(self->rhs, context);
self->rhs->resolve_data.status = AST_RESOLVED;
ast->resolve_data.type = self->rhs->resolve_data.type;
} else {