From de253a94aba8fe2116bd9241d39c1c9caf61497b Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 11 Jun 2024 19:17:20 +0200 Subject: [PATCH] fixed: function declarations --- src/ast/ast.c | 19 +++++++++++++++++-- src/ast/ast.h | 7 +++++-- src/compiler.c | 4 ++-- src/llvm/llvm-ir/func.c | 38 +++++++++++++++++++++++--------------- src/llvm/llvm-ir/stmt.c | 3 +++ src/llvm/parser.c | 2 +- src/set/set.c | 4 ++-- src/yacc/parser.y | 9 +++++++++ 8 files changed, 62 insertions(+), 24 deletions(-) diff --git a/src/ast/ast.c b/src/ast/ast.c index 2d6bef6..9abc031 100644 --- a/src/ast/ast.c +++ b/src/ast/ast.c @@ -317,9 +317,24 @@ AST_NODE_PTR AST_get_node_by_kind(AST_NODE_PTR owner, enum AST_SyntaxElement_t k return NULL; } -void AST_merge_modules(AST_NODE_PTR dst, AST_NODE_PTR src) { +void AST_merge_modules(AST_NODE_PTR dst, size_t k, AST_NODE_PTR src) { for (size_t i = 0; i < src->child_count; i++) { - AST_push_node(dst, AST_remove_child(src, i)); + AST_insert_node(dst, k + i, AST_remove_child(src, i)); } AST_delete_node(src); } + +void AST_insert_node(AST_NODE_PTR owner, size_t idx, AST_NODE_PTR child) { + DEBUG("Reallocating old children array"); + + owner->child_count++; + const size_t size = sizeof(struct AST_Node_t *) * owner->child_count; + owner->children = mem_realloc(MemoryNamespaceAst, owner->children, size); + + // shift back every following element backwards by one + for (size_t i = owner->child_count - 1; i > idx; i--) { + owner->children[i] = owner->children[i - 1]; + } + + owner->children[idx] = child; +} diff --git a/src/ast/ast.h b/src/ast/ast.h index 1f17d8c..7f001e5 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -221,7 +221,10 @@ void AST_fprint_graphviz(FILE* stream, const struct AST_Node_t* node); AST_NODE_PTR AST_get_node_by_kind(AST_NODE_PTR owner, enum AST_SyntaxElement_t kind); -[[gnu::nonnull(1), gnu::nonnull(2)]] -void AST_merge_modules(AST_NODE_PTR dst, AST_NODE_PTR src); +[[gnu::nonnull(1), gnu::nonnull(3)]] +void AST_merge_modules(AST_NODE_PTR dst, size_t i, AST_NODE_PTR src); + +[[gnu::nonnull(1), gnu::nonnull(3)]] +void AST_insert_node(AST_NODE_PTR owner, size_t idx, AST_NODE_PTR child); #endif diff --git a/src/compiler.c b/src/compiler.c index 291ad6d..b9dcf9f 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -108,7 +108,7 @@ static int setup_target_environment(const TargetConfig *target) { * @param ast * @param target */ -static void print_ast_to_file(const AST_NODE_PTR ast, const TargetConfig *target) { +static void print_ast_to_file(AST_NODE_PTR ast, const TargetConfig *target) { assert(ast != NULL); assert(target != NULL); DEBUG("printing AST to file: %s", target->name); @@ -178,7 +178,7 @@ static AST_NODE_PTR compile_module_with_dependencies(ModuleFileStack *unit, Modu ModuleFile *imported_file = push_file(unit, child->value); if (compile_file_to_ast(imported_module, imported_file) == EXIT_SUCCESS) { - AST_merge_modules(root_module, imported_module); + AST_merge_modules(root_module, i + 1, imported_module); } } } diff --git a/src/llvm/llvm-ir/func.c b/src/llvm/llvm-ir/func.c index d8b3894..c5a4615 100644 --- a/src/llvm/llvm-ir/func.c +++ b/src/llvm/llvm-ir/func.c @@ -85,16 +85,23 @@ BackendError impl_param_type(LLVMBackendCompileUnit* unit, return err; } -BackendError impl_func_decl(LLVMBackendCompileUnit* unit, - LLVMGlobalScope* scope, FunctionDefinition* fundef, - LLVMValueRef* llvm_fun, const char* name) { - DEBUG("implementing function declaration: %s()", name); +BackendError impl_func_type(LLVMBackendCompileUnit* unit, + LLVMGlobalScope* scope, Function* func, + LLVMValueRef* llvm_fun) { + DEBUG("implementing function declaration: %s()", func->name); BackendError err = SUCCESS; GArray* llvm_params = g_array_new(FALSE, FALSE, sizeof(LLVMTypeRef)); + GArray* func_params = NULL; - for (size_t i = 0; i < fundef->parameter->len; i++) { - Parameter* param = &g_array_index(fundef->parameter, Parameter, i); + if (func->kind == FunctionDeclarationKind) { + func_params = func->impl.declaration.parameter; + } else { + func_params = func->impl.definition.parameter; + } + + for (size_t i = 0; i < func_params->len; i++) { + Parameter* param = &g_array_index(func_params, Parameter, i); LLVMTypeRef llvm_type = NULL; err = impl_param_type(unit, scope, param, &llvm_type); @@ -112,9 +119,9 @@ BackendError impl_func_decl(LLVMBackendCompileUnit* unit, LLVMFunctionType(LLVMVoidTypeInContext(unit->context), (LLVMTypeRef*)llvm_params->data, llvm_params->len, 0); - *llvm_fun = LLVMAddFunction(unit->module, name, llvm_fun_type); + *llvm_fun = LLVMAddFunction(unit->module, func->name, llvm_fun_type); - g_hash_table_insert(scope->functions, name, llvm_fun_type); + g_hash_table_insert(scope->functions, func->name, llvm_fun_type); g_array_free(llvm_params, FALSE); @@ -123,11 +130,11 @@ BackendError impl_func_decl(LLVMBackendCompileUnit* unit, BackendError impl_func_def(LLVMBackendCompileUnit* unit, LLVMGlobalScope* global_scope, - FunctionDefinition* fundef, const char* name) { + Function* func, const char* name) { BackendError err = SUCCESS; LLVMValueRef llvm_func = NULL; - err = impl_func_decl(unit, global_scope, fundef, &llvm_func, name); + err = impl_func_type(unit, global_scope, func, &llvm_func); if (err.kind == Success) { // create local function scope @@ -145,8 +152,8 @@ BackendError impl_func_def(LLVMBackendCompileUnit* unit, LLVMPositionBuilderAtEnd(builder, entry); // create value references for parameter - for (guint i = 0; i < fundef->parameter->len; i++) { - Parameter* param = &g_array_index(fundef->parameter, Parameter, i); + for (guint i = 0; i < func->impl.definition.parameter->len; i++) { + Parameter* param = &g_array_index(func->impl.definition.parameter, Parameter, i); LLVMValueRef llvm_param = LLVMGetParam(llvm_func, i); if (llvm_param == NULL) { @@ -158,7 +165,7 @@ BackendError impl_func_def(LLVMBackendCompileUnit* unit, LLVMBasicBlockRef llvm_start_body_block = NULL; LLVMBasicBlockRef llvm_end_body_block = NULL; - err = impl_block(unit, builder, func_scope, &llvm_start_body_block, &llvm_end_body_block, fundef->body); + err = impl_block(unit, builder, func_scope, &llvm_start_body_block, &llvm_end_body_block, func->impl.definition.body); LLVMPositionBuilderAtEnd(builder, entry); LLVMBuildBr(builder, llvm_start_body_block); @@ -196,9 +203,10 @@ BackendError impl_functions(LLVMBackendCompileUnit* unit, Function* func = (Function*) val; if (func->kind == FunctionDeclarationKind) { - // err = impl_func_decl(unit, scope, &func->impl.declaration, (const char*) key); + LLVMValueRef llvm_func = NULL; + err = impl_func_type(unit, scope, func, &llvm_func); } else { - err = impl_func_def(unit, scope, &func->impl.definition, (const char*)key); + err = impl_func_def(unit, scope, func, (const char*)key); } if (err.kind != Success) { diff --git a/src/llvm/llvm-ir/stmt.c b/src/llvm/llvm-ir/stmt.c index 54f499a..ccb7438 100644 --- a/src/llvm/llvm-ir/stmt.c +++ b/src/llvm/llvm-ir/stmt.c @@ -179,6 +179,9 @@ BackendError impl_func_call(LLVMBackendCompileUnit *unit, if (err.kind == Success) { LLVMValueRef llvm_func = LLVMGetNamedFunction(unit->module, call->function->name); + if (llvm_func == NULL) { + return new_backend_impl_error(Implementation, NULL, "no declared function"); + } LLVMTypeRef llvm_func_type = g_hash_table_lookup(scope->func_scope->global_scope->functions, call->function->name); diff --git a/src/llvm/parser.c b/src/llvm/parser.c index ff2201a..19f0d04 100644 --- a/src/llvm/parser.c +++ b/src/llvm/parser.c @@ -231,7 +231,7 @@ BackendError parse_module(const Module* module, const TargetConfig* config) { DEBUG("creating LLVM context and module"); unit->context = LLVMContextCreate(); unit->module = - LLVMModuleCreateWithNameInContext(config->name, unit->context); + LLVMModuleCreateWithNameInContext(config->root_module, unit->context); LLVMGlobalScope* global_scope = new_global_scope(module); diff --git a/src/set/set.c b/src/set/set.c index acb16f3..4ef19a1 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -2046,7 +2046,7 @@ int createFunDecl(Function *Parentfunction, AST_NODE_PTR currentNode) { fundecl.nodePtr = currentNode; fundecl.name = nameNode->value; - fundecl.parameter = mem_alloc(MemoryNamespaceSet, sizeof(GArray)); + fundecl.parameter = mem_new_g_array(MemoryNamespaceSet, sizeof(Parameter)); for (size_t i = 0; i < paramlistlist->child_count; i++) { @@ -2062,7 +2062,7 @@ int createFunDecl(Function *Parentfunction, AST_NODE_PTR currentNode) { } Parentfunction->nodePtr = currentNode; - Parentfunction->kind = FunctionDefinitionKind; + Parentfunction->kind = FunctionDeclarationKind; Parentfunction->impl.declaration = fundecl; Parentfunction->name = fundecl.name; return SEMANTIC_OK; diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 68c2dba..56234e1 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -55,6 +55,7 @@ %type moduleimport %type programbody %type fundef +%type fundecl %type box %type typedef %type exprlist @@ -141,6 +142,7 @@ program: program programbody {AST_push_node(root, $2); programbody: moduleimport {$$ = $1;} | fundef{$$ = $1;} + | fundecl{$$ = $1;} | box{$$ = $1;} | definition{$$ = $1;} | decl{$$ = $1;} @@ -191,6 +193,13 @@ fundef: KeyFun Ident paramlist '{' statementlist'}' {AST_NODE_PTR fun = AST_new_ $$ = fun; DEBUG("Function");}; +fundecl: KeyFun Ident paramlist {AST_NODE_PTR fun = AST_new_node(new_loc(), AST_Fun, NULL); + AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $2); + AST_push_node(fun, ident); + AST_push_node(fun, $3); + $$ = fun; + DEBUG("Function");}; + paramlist: paramlist '(' params ')' {AST_push_node($1, $3); $$ = $1;} | paramlist '(' ')'{$$ = $1;}