aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ast.h2
-rw-r--r--include/compiler.h1
-rw-r--r--src/ast.c143
-rw-r--r--src/parser.c1
4 files changed, 36 insertions, 111 deletions
diff --git a/include/ast.h b/include/ast.h
index bdab6c3..edf225b 100644
--- a/include/ast.h
+++ b/include/ast.h
@@ -130,8 +130,6 @@ struct Scope {
Buffer/*<Ast*>*/ ast_objects;
HashMapType(BufferView, Ast*) named_objects; /* Value is always an Ast* with type LhsExpr */
Scope *parent;
- /* Is null unless the scope is a file scope, in which case this is the parser that owns the scope */
- Parser *parser;
FunctionSignature *function_signature; /* Borrowed from FunctionDecl. Only used if the scope belongs to FunctionDecl */
};
diff --git a/include/compiler.h b/include/compiler.h
index 3e3cc92..1ed98f3 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -70,6 +70,7 @@ CHECK_RESULT int amal_compiler_internal_load_file(amal_compiler *self, const cha
/*
Returns a reference to the parsers tokenizer that contains the code reference, or NULL.
Note: The lifetime of the tokenizer returned is the same as the lifetime of the parser that owns it.
+ Should only be called once code has been parsed (in AST stage or later), in which case it's thread-safe.
*/
Tokenizer* amal_compiler_find_tokenizer_by_code_reference(amal_compiler *self, const char *code_ref);
diff --git a/src/ast.c b/src/ast.c
index cb4d875..76cbf9c 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -17,7 +17,6 @@
static void variable_type_resolve(VariableType *self, AstCompilerContext *context, AstResolvedType *resolved_type);
static void ast_resolve(Ast *self, AstCompilerContext *context);
-static BufferView variable_type_get_name(VariableType *self);
static void scope_named_object_init(ScopeNamedObject *self) {
self->type = NAMED_OBJECT_NONE;
@@ -56,7 +55,7 @@ static BufferView ast_resolved_type_get_name(AstResolvedType *self) {
result = create_buffer_view("", 0);
break;
case RESOLVED_TYPE_LHS_EXPR:
- result = variable_type_get_name(&self->value.lhs_expr->type);
+ result = self->value.lhs_expr->var_name;
break;
case RESOLVED_TYPE_FUNC_SIG: {
if(!self->value.func_sig->func_decl || !self->value.func_sig->func_decl->lhs_expr) {
@@ -381,7 +380,6 @@ int scope_init(Scope *self, Scope *parent, ArenaAllocator *allocator) {
return_if_error(buffer_init(&self->ast_objects, allocator));
return_if_error(hash_map_init(&self->named_objects, allocator, sizeof(Ast*), hash_map_compare_string, amal_hash_string));
self->parent = parent;
- self->parser = NULL;
self->function_signature = NULL;
return 0;
}
@@ -432,27 +430,18 @@ void scope_resolve(Scope *self, AstCompilerContext *context) {
context->scope = prev_scope;
}
-static Parser* scope_get_parser(Scope *scope) {
- while(scope) {
- if(scope->parser)
- return scope->parser;
- scope = scope->parent;
+static void compiler_print_error(amal_compiler *compiler, const char *ref, const char *fmt, ...) {
+ Tokenizer *tokenizer = amal_compiler_find_tokenizer_by_code_reference(compiler, ref);
+ if(!tokenizer) {
+ amal_log_error("Failed to find tokenizer for code reference %p. Is it an invalid reference?", ref ? ref : "(null)");
+ return;
}
- 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_args(&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("TODO: Fix this:");
- amal_log_error(fmt, args);
- }
+ tokenizer_print_error_args(tokenizer,
+ tokenizer_get_code_reference_index(tokenizer, ref),
+ fmt, args);
va_end(args);
}
@@ -485,12 +474,8 @@ static void __scope_get_resolved_variable(Scope *self, Scope *start, AstCompiler
return;
}
- {
- Parser *parser;
- parser = scope_get_parser(start);
- parser_print_error(parser, name.data, "Undefined reference to variable \"%.*s\"", name.size, name.data);
- throw(AST_ERR);
- }
+ compiler_print_error(context->compiler, name.data, "Undefined reference to variable \"%.*s\"", name.size, name.data);
+ throw(AST_ERR);
}
/*
@@ -563,25 +548,6 @@ void variable_type_resolve(VariableType *self, AstCompilerContext *context, AstR
}
}
-BufferView variable_type_get_name(VariableType *self) {
- BufferView result;
- switch(self->type) {
- case VARIABLE_TYPE_NONE:
- result.data = NULL;
- result.size = 0;
- break;
- case VARIABLE_TYPE_VARIABLE:
- result = self->value.variable->name;
- break;
- case VARIABLE_TYPE_SIGNATURE:
- /* TODO: Save reference to signature in code in the FunctionSignature type */
- result.data = "fn()";
- result.size = 4;
- break;
- }
- return result;
-}
-
static void lhsexpr_resolve_rhs(LhsExpr *self, AstCompilerContext *context, AstResolvedType *result) {
ast_resolve(self->rhs_expr, context);
if(ast_is_decl(self->rhs_expr)) {
@@ -629,14 +595,11 @@ static void lhsexpr_resolve(Ast *ast, AstCompilerContext *context) {
/* TODO: Add casting */
if(ast->resolve_data.type.type == RESOLVED_TYPE_LHS_EXPR && !ast_resolved_type_equals(&ast->resolve_data.type, &rhs_resolve_type)) {
- Parser *parser;
- parser = scope_get_parser(context->scope);
/*
- TODO: Instead of using self->var_name, using type name. This cant be done right now because
+ TODO: Instead of using self->var_name, use type name. This cant be done right now because
type can be function signature.
*/
- parser_print_error(parser, self->var_name.data,
- "Variable type and variable assignment type (right-hand side) do not match");
+ compiler_print_error(context->compiler, self->var_name.data, "Variable type and variable assignment type (right-hand side) do not match");
throw(AST_ERR);
}
ast->resolve_data.type = rhs_resolve_type;
@@ -683,26 +646,19 @@ static void assignmentexpr_resolve(Ast *ast, AstCompilerContext *context) {
/* This also covers extern variables, since extern variables are always const */
/* TODO: var.field type expressions should also be checked */
if(is_lhs_const) {
- Parser *parser;
- parser = scope_get_parser(context->scope);
- parser_print_error(parser, ast_get_code_reference(self->lhs_expr).data, "Can't assign to a const value");
+ compiler_print_error(context->compiler, ast_get_code_reference(self->lhs_expr).data, "Can't assign to a const value");
throw(AST_ERR);
}
/* TODO: Add casting */
if(!ast_resolved_type_equals(&self->lhs_expr->resolve_data.type, &self->rhs_expr->resolve_data.type)) {
- Parser *parser;
- BufferView rhs_type_name;
- BufferView lhs_type_name;
-
- parser = scope_get_parser(context->scope);
- rhs_type_name = ast_resolved_type_get_name(&self->rhs_expr->resolve_data.type);
- lhs_type_name = ast_resolved_type_get_name(&self->lhs_expr->resolve_data.type);
+ BufferView rhs_type_name = ast_resolved_type_get_name(&self->rhs_expr->resolve_data.type);
+ BufferView lhs_type_name = ast_resolved_type_get_name(&self->lhs_expr->resolve_data.type);
/*
- TODO: Instead of using self->var_name, using type name. This cant be done right now because
+ TODO: Instead of using self->var_name, use type name. This cant be done right now because
type can be function signature.
*/
- parser_print_error(parser, ast_get_code_reference(self->lhs_expr).data,
+ compiler_print_error(context->compiler, ast_get_code_reference(self->lhs_expr).data,
"Can't cast data of type %.*s to type %.*s", rhs_type_name.size, rhs_type_name.data, lhs_type_name.size, lhs_type_name.data);
throw(AST_ERR);
}
@@ -750,12 +706,6 @@ static Scope* ast_resolved_type_get_scope(AstResolvedType *self) {
return NULL;
}
-/* @self has to have a resolved type before calling this */
-static Parser* get_resolved_type_parser(Ast *self) {
- assert(self->resolve_data.type.type == RESOLVED_TYPE_LHS_EXPR && "Expected get_resolved_type_parser to only be called for non-extern function declaration, struct declaration and import");
- return scope_get_parser(lhsexpr_get_scope(self->resolve_data.type.value.lhs_expr));
-}
-
static void funcdecl_resolve(Ast *self, AstCompilerContext *context) {
FunctionDecl *func_decl;
func_decl = self->value.func_decl;
@@ -787,19 +737,12 @@ static void funccall_resolve(Ast *self, AstCompilerContext *context) {
variable_resolve(&func_call->func, context, &self->resolve_data.type);
/* Attemping to use call syntax (variable_name ( ) ) with a variable that is not a function */
if(self->resolve_data.type.type != RESOLVED_TYPE_FUNC_SIG) {
- Parser *caller_parser;
- Parser *callee_parser;
- BufferView callee_code_ref;
-
- caller_parser = scope_get_parser(context->scope);
- callee_parser = get_resolved_type_parser(self);
- callee_code_ref = ast_resolved_type_get_name(&self->resolve_data.type);
-
- parser_print_error(caller_parser, func_call->func.name.data,
+ BufferView callee_code_ref = ast_resolved_type_get_name(&self->resolve_data.type);
+ compiler_print_error(context->compiler, 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 */
- parser_print_error(callee_parser, callee_code_ref.data, "Type was declared here");
+ compiler_print_error(context->compiler, callee_code_ref.data, "Type was declared here");
throw(AST_ERR);
}
@@ -835,21 +778,16 @@ static bool is_struct_decl(Ast *self) {
static void binop_resolve_dot_access(Ast *ast, AstCompilerContext *context) {
Binop *self;
Scope *lhs_scope;
- Parser *caller_parser;
- Parser *callee_parser;
BufferView caller_code_ref;
BufferView callee_code_ref;
ScopeNamedObject rhs_resolved_var;
assert(ast->type == AST_BINOP);
self = ast->value.binop;
- caller_parser = scope_get_parser(context->scope);
if(self->lhs->type != AST_VARIABLE) {
/* TODO: Allow field access for numbers and string as well */
- BufferView code_ref;
- code_ref = ast_get_code_reference(self->lhs);
- parser_print_error(caller_parser, code_ref.data, "Accessing fields is only applicable for variables");
+ compiler_print_error(context->compiler, ast_get_code_reference(self->lhs).data, "Accessing fields is only applicable for variables");
throw(AST_ERR);
}
@@ -857,23 +795,22 @@ static void binop_resolve_dot_access(Ast *ast, AstCompilerContext *context) {
scope_get_resolved_variable(lhs_scope, context, self->rhs->value.variable->name, &rhs_resolved_var);
self->rhs->resolve_data.type = scope_named_object_get_resolved_type(&rhs_resolved_var, context);
- callee_parser = get_resolved_type_parser(self->rhs);
caller_code_ref = ast_get_code_reference(self->rhs);
callee_code_ref = ast_resolved_type_get_name(&self->rhs->resolve_data.type);
if(!is_struct_decl(self->lhs)) {
- parser_print_error(caller_parser, caller_code_ref.data, "Can only access field of structs");
+ compiler_print_error(context->compiler, caller_code_ref.data, "Can only access field of structs");
/* TODO: use tokenizer_print_note, once it has been added */
/* TODO: Print type */
- parser_print_error(callee_parser, callee_code_ref.data, "Type was declared here");
+ compiler_print_error(context->compiler, callee_code_ref.data, "Type was declared here");
throw(AST_ERR);
}
if(self->rhs->resolve_data.type.type != RESOLVED_TYPE_LHS_EXPR || !LHS_EXPR_IS_PUB(self->rhs->resolve_data.type.value.lhs_expr)) {
- parser_print_error(caller_parser, caller_code_ref.data, "Can't access non-public field \"%.*s\"", caller_code_ref.size, caller_code_ref.data);
+ compiler_print_error(context->compiler, 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 */
- parser_print_error(callee_parser, callee_code_ref.data, "Type was declared non-public here");
+ compiler_print_error(context->compiler, callee_code_ref.data, "Type was declared non-public here");
throw(AST_ERR);
}
}
@@ -906,32 +843,24 @@ static void binop_resolve(Ast *ast, AstCompilerContext *context) {
TODO: Use note for the additional information instead of error.
*/
- BufferView lhs_type_name, rhs_type_name;
- Parser *parser;
-
- lhs_type_name = ast_resolved_type_get_name(&self->lhs->resolve_data.type);
- rhs_type_name = ast_resolved_type_get_name(&self->rhs->resolve_data.type);
- parser = scope_get_parser(context->scope);
- parser_print_error(parser, ast_get_code_reference(self->rhs).data,
- "Can't cast type \"%.*s\" to type \"%.*s\"",
+ BufferView lhs_type_name = ast_resolved_type_get_name(&self->lhs->resolve_data.type);
+ BufferView rhs_type_name = ast_resolved_type_get_name(&self->rhs->resolve_data.type);
+ compiler_print_error(context->compiler, ast_get_code_reference(self->rhs).data,
+ "Can't cast type %.*s to type %.*s",
rhs_type_name.size, rhs_type_name.data,
lhs_type_name.size, lhs_type_name.data);
- parser_print_error(parser, ast_get_code_reference(self->lhs).data,
+ compiler_print_error(context->compiler, ast_get_code_reference(self->lhs).data,
"Left-hand side is of type %.*s",
lhs_type_name.size, lhs_type_name.data);
- parser_print_error(parser, ast_get_code_reference(self->rhs).data,
+ compiler_print_error(context->compiler, ast_get_code_reference(self->rhs).data,
"Right-hand side is of type %.*s",
rhs_type_name.size, rhs_type_name.data);
throw(AST_ERR);
/* TODO: Optimize this? store arithmetic type in the LhsExpr itself? */
} else if(self->lhs->resolve_data.type.type != RESOLVED_TYPE_LHS_EXPR || !is_arithmetic_type(self->lhs->resolve_data.type.value.lhs_expr, context->compiler)) {
/* TODO: Point the error at the binop instead of LHS */
- BufferView lhs_type_name;
- Parser *parser;
-
- lhs_type_name = ast_resolved_type_get_name(&self->lhs->resolve_data.type);
- parser = scope_get_parser(context->scope);
- parser_print_error(parser, ast_get_code_reference(self->lhs).data,
+ BufferView lhs_type_name = ast_resolved_type_get_name(&self->lhs->resolve_data.type);
+ compiler_print_error(context->compiler, ast_get_code_reference(self->lhs).data,
"Arithmetic operation can only be performed with the types i8, u8, i16, u16, i32, u32, i64, u64, isize and usize",
lhs_type_name.size, lhs_type_name.data);
throw(AST_ERR);
@@ -992,9 +921,7 @@ void ast_resolve(Ast *self, AstCompilerContext *context) {
before another file has done it, and it can be different everytime the files are compiled.
*/
} else if(self->resolve_data.status == AST_RESOLVING && self->parser == context->parser) {
- Parser *parser;
- parser = scope_get_parser(context->scope);
- parser_print_error(parser, ast_get_code_reference(self).data, "Found recursive dependency");
+ compiler_print_error(context->compiler, ast_get_code_reference(self).data, "Found recursive dependency");
throw(AST_ERR);
}
diff --git a/src/parser.c b/src/parser.c
index a6b4ecf..df326f0 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -39,7 +39,6 @@ int parser_init(Parser *self, amal_compiler *compiler, ArenaAllocator *allocator
self->error.str = NULL;
self->error_context = ERROR_CONTEXT_NONE;
return_if_error(structdecl_init(&self->struct_decl, &compiler->root_scope, allocator));
- self->struct_decl.body.parser = self;
lhsexpr_init(&self->file_decl, DECL_FLAG_EXTERN | DECL_FLAG_PUB | DECL_FLAG_CONST, create_buffer_view_null());
return_if_error(ast_create(self->allocator, &self->struct_decl, AST_STRUCT_DECL, &self->file_decl.rhs_expr));
self->current_scope = &self->struct_decl.body;