fixed: function declarations

This commit is contained in:
Sven Vogel 2024-06-11 19:17:20 +02:00
parent 09871cce76
commit de253a94ab
8 changed files with 62 additions and 24 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -55,6 +55,7 @@
%type <node_ptr> moduleimport
%type <node_ptr> programbody
%type <node_ptr> fundef
%type <node_ptr> fundecl
%type <node_ptr> box
%type <node_ptr> typedef
%type <node_ptr> 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;}