diff options
Diffstat (limited to 'src/ast.c')
-rw-r--r-- | src/ast.c | 70 |
1 files changed, 31 insertions, 39 deletions
@@ -4,6 +4,7 @@ #include "../include/std/log.h" #include "../include/std/hash.h" #include <assert.h> +#include <stdarg.h> #define throw(result) do { throw_debug_msg; longjmp(context->env, (result)); } while(0) #define throw_if_error(result) \ @@ -26,6 +27,7 @@ int ast_create(ScopedAllocator *allocator, void *value, AstType type, Ast **resu (*result)->value.data = value; (*result)->type = type; resolve_data_init(&(*result)->resolve_data); + (*result)->ssa_reg = 0; return 0; } @@ -186,10 +188,23 @@ static Parser* scope_get_parser(Scope *scope) { return scope->parser; scope = scope->parent; } - assert(bool_false && "BUG: At least some scope parent is supposed to have a parser"); return NULL; } +static void parser_print_error(Parser *parser, const char *ref, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + if(parser) { + tokenizer_print_error(&parser->tokenizer, + tokenizer_get_code_reference_index(&parser->tokenizer, ref), + fmt, args); + } else { + /* TODO: Redirect error to compiler error callback if set */ + amal_log_error(fmt, args); + } + va_end(args); +} + static Ast* scope_get_resolved_variable(Scope *self, AstCompilerContext *context, BufferView name) { Ast *result; bool exists; @@ -203,9 +218,7 @@ static Ast* scope_get_resolved_variable(Scope *self, AstCompilerContext *context return scope_get_resolved_variable(self->parent, context, name); parser = scope_get_parser(self); - tokenizer_print_error(&parser->tokenizer, - tokenizer_get_code_reference_index(&parser->tokenizer, name.data), - "Undefined reference to variable \"%.*s\"", name.size, name.data); + parser_print_error(parser, name.data, "Undefined reference to variable \"%.*s\"", name.size, name.data); throw(AST_ERR); } @@ -264,9 +277,8 @@ static void lhsexpr_resolve(Ast *ast, AstCompilerContext *context) { if(ast->resolve_data.type && self->rhs_expr && ast->resolve_data.type != rhs_resolve_type) { Parser *parser; parser = scope_get_parser(context->scope); - tokenizer_print_error(&parser->tokenizer, - tokenizer_get_code_reference_index(&parser->tokenizer, self->type.name.data), - "Variable type and variable assignment type (right-hand side) do not match"); + parser_print_error(parser, self->type.name.data, + "Variable type and variable assignment type (right-hand side) do not match"); throw(AST_ERR); } } @@ -328,14 +340,11 @@ static void funccall_resolve(Ast *self, AstCompilerContext *context) { callee_parser = get_resolved_type_parser(self); callee_code_ref = self->resolve_data.type->var_name; - tokenizer_print_error(&caller_parser->tokenizer, - tokenizer_get_code_reference_index(&caller_parser->tokenizer, func_call->func.name.data), + parser_print_error(caller_parser, 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(&callee_parser->tokenizer, - tokenizer_get_code_reference_index(&callee_parser->tokenizer, callee_code_ref.data), - "Type was declared here"); + parser_print_error(callee_parser, callee_code_ref.data, "Type was declared here"); throw(AST_ERR); } @@ -375,9 +384,7 @@ static void binop_resolve_dot_access(Ast *ast, AstCompilerContext *context) { /* TODO: Allow field access for numbers and string as well */ BufferView code_ref; code_ref = ast_get_code_reference(self->lhs); - tokenizer_print_error(&caller_parser->tokenizer, - tokenizer_get_code_reference_index(&caller_parser->tokenizer, code_ref.data), - "Accessing fields is only applicable for variables"); + parser_print_error(caller_parser, code_ref.data, "Accessing fields is only applicable for variables"); throw(AST_ERR); } @@ -389,26 +396,18 @@ static void binop_resolve_dot_access(Ast *ast, AstCompilerContext *context) { callee_code_ref = self->rhs->resolve_data.type->var_name; if(self->lhs->resolve_data.type->rhs_expr->type != AST_STRUCT_DECL) { - tokenizer_print_error(&caller_parser->tokenizer, - tokenizer_get_code_reference_index(&caller_parser->tokenizer, caller_code_ref.data), - "Can only access field of structs"); + parser_print_error(caller_parser, caller_code_ref.data, "Can only access field of structs"); /* TODO: use tokenizer_print_note, once it has been added */ /* TODO: Print type */ - tokenizer_print_error(&callee_parser->tokenizer, - tokenizer_get_code_reference_index(&callee_parser->tokenizer, callee_code_ref.data), - "Type was declared here"); + parser_print_error(callee_parser, callee_code_ref.data, "Type was declared here"); throw(AST_ERR); } if(!self->rhs->resolve_data.type->is_pub) { - tokenizer_print_error(&caller_parser->tokenizer, - tokenizer_get_code_reference_index(&caller_parser->tokenizer, caller_code_ref.data), - "Can't access non-public field \"%.*s\"", caller_code_ref.size, caller_code_ref.data); + parser_print_error(caller_parser, caller_code_ref.data, "Can't access non-public field \"%.*s\"", caller_code_ref.size, caller_code_ref.data); /* TODO: use tokenizer_print_note, once it has been added */ /* TODO: Print type */ - tokenizer_print_error(&callee_parser->tokenizer, - tokenizer_get_code_reference_index(&callee_parser->tokenizer, callee_code_ref.data), - "Type was declared non-public here"); + parser_print_error(callee_parser, callee_code_ref.data, "Type was declared non-public here"); throw(AST_ERR); } } @@ -437,17 +436,14 @@ static void binop_resolve(Ast *ast, AstCompilerContext *context) { */ Parser *parser; parser = scope_get_parser(context->scope); - tokenizer_print_error(&parser->tokenizer, - tokenizer_get_code_reference_index(&parser->tokenizer, ast_get_code_reference(self->rhs).data), + parser_print_error(parser, ast_get_code_reference(self->rhs).data, "Can't cast type \"%.*s\" to type \"%.*s\"", self->rhs->resolve_data.type->var_name.size, self->rhs->resolve_data.type->var_name.data, self->lhs->resolve_data.type->var_name.size, self->lhs->resolve_data.type->var_name.data); - tokenizer_print_error(&parser->tokenizer, - tokenizer_get_code_reference_index(&parser->tokenizer, ast_get_code_reference(self->lhs).data), + parser_print_error(parser, ast_get_code_reference(self->lhs).data, "Left-hand side is of type %.*s", self->lhs->resolve_data.type->var_name.size, self->lhs->resolve_data.type->var_name.data); - tokenizer_print_error(&parser->tokenizer, - tokenizer_get_code_reference_index(&parser->tokenizer, ast_get_code_reference(self->rhs).data), + parser_print_error(parser, ast_get_code_reference(self->rhs).data, "Right-hand side is of type %.*s", self->rhs->resolve_data.type->var_name.size, self->rhs->resolve_data.type->var_name.data); throw(AST_ERR); @@ -474,9 +470,7 @@ void ast_resolve(Ast *self, AstCompilerContext *context) { } else if(self->resolve_data.status == AST_RESOLVING) { Parser *parser; parser = scope_get_parser(context->scope); - tokenizer_print_error(&parser->tokenizer, - tokenizer_get_code_reference_index(&parser->tokenizer, ast_get_code_reference(self).data), - "Found recursive dependency"); + parser_print_error(parser, ast_get_code_reference(self).data, "Found recursive dependency"); throw(AST_ERR); } @@ -489,9 +483,7 @@ void ast_resolve(Ast *self, AstCompilerContext *context) { Parser *parser; parser = scope_get_parser(context->scope); amal_mutex_tryunlock(self->value.lhs_expr->mutex); - tokenizer_print_error(&parser->tokenizer, - tokenizer_get_code_reference_index(&parser->tokenizer, ast_get_code_reference(self).data), - "Found recursive dependency"); + parser_print_error(parser, ast_get_code_reference(self).data, "Found recursive dependency"); throw(AST_ERR); } } |