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; 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++) { 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); 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); AST_NODE_PTR AST_get_node_by_kind(AST_NODE_PTR owner, enum AST_SyntaxElement_t kind);
[[gnu::nonnull(1), gnu::nonnull(2)]] [[gnu::nonnull(1), gnu::nonnull(3)]]
void AST_merge_modules(AST_NODE_PTR dst, AST_NODE_PTR src); 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 #endif

View File

@ -108,7 +108,7 @@ static int setup_target_environment(const TargetConfig *target) {
* @param ast * @param ast
* @param target * @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(ast != NULL);
assert(target != NULL); assert(target != NULL);
DEBUG("printing AST to file: %s", target->name); 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); ModuleFile *imported_file = push_file(unit, child->value);
if (compile_file_to_ast(imported_module, imported_file) == EXIT_SUCCESS) { 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; return err;
} }
BackendError impl_func_decl(LLVMBackendCompileUnit* unit, BackendError impl_func_type(LLVMBackendCompileUnit* unit,
LLVMGlobalScope* scope, FunctionDefinition* fundef, LLVMGlobalScope* scope, Function* func,
LLVMValueRef* llvm_fun, const char* name) { LLVMValueRef* llvm_fun) {
DEBUG("implementing function declaration: %s()", name); DEBUG("implementing function declaration: %s()", func->name);
BackendError err = SUCCESS; BackendError err = SUCCESS;
GArray* llvm_params = g_array_new(FALSE, FALSE, sizeof(LLVMTypeRef)); GArray* llvm_params = g_array_new(FALSE, FALSE, sizeof(LLVMTypeRef));
GArray* func_params = NULL;
for (size_t i = 0; i < fundef->parameter->len; i++) { if (func->kind == FunctionDeclarationKind) {
Parameter* param = &g_array_index(fundef->parameter, Parameter, i); 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; LLVMTypeRef llvm_type = NULL;
err = impl_param_type(unit, scope, param, &llvm_type); err = impl_param_type(unit, scope, param, &llvm_type);
@ -112,9 +119,9 @@ BackendError impl_func_decl(LLVMBackendCompileUnit* unit,
LLVMFunctionType(LLVMVoidTypeInContext(unit->context), LLVMFunctionType(LLVMVoidTypeInContext(unit->context),
(LLVMTypeRef*)llvm_params->data, llvm_params->len, 0); (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); g_array_free(llvm_params, FALSE);
@ -123,11 +130,11 @@ BackendError impl_func_decl(LLVMBackendCompileUnit* unit,
BackendError impl_func_def(LLVMBackendCompileUnit* unit, BackendError impl_func_def(LLVMBackendCompileUnit* unit,
LLVMGlobalScope* global_scope, LLVMGlobalScope* global_scope,
FunctionDefinition* fundef, const char* name) { Function* func, const char* name) {
BackendError err = SUCCESS; BackendError err = SUCCESS;
LLVMValueRef llvm_func = NULL; 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) { if (err.kind == Success) {
// create local function scope // create local function scope
@ -145,8 +152,8 @@ BackendError impl_func_def(LLVMBackendCompileUnit* unit,
LLVMPositionBuilderAtEnd(builder, entry); LLVMPositionBuilderAtEnd(builder, entry);
// create value references for parameter // create value references for parameter
for (guint i = 0; i < fundef->parameter->len; i++) { for (guint i = 0; i < func->impl.definition.parameter->len; i++) {
Parameter* param = &g_array_index(fundef->parameter, Parameter, i); Parameter* param = &g_array_index(func->impl.definition.parameter, Parameter, i);
LLVMValueRef llvm_param = LLVMGetParam(llvm_func, i); LLVMValueRef llvm_param = LLVMGetParam(llvm_func, i);
if (llvm_param == NULL) { if (llvm_param == NULL) {
@ -158,7 +165,7 @@ BackendError impl_func_def(LLVMBackendCompileUnit* unit,
LLVMBasicBlockRef llvm_start_body_block = NULL; LLVMBasicBlockRef llvm_start_body_block = NULL;
LLVMBasicBlockRef llvm_end_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); LLVMPositionBuilderAtEnd(builder, entry);
LLVMBuildBr(builder, llvm_start_body_block); LLVMBuildBr(builder, llvm_start_body_block);
@ -196,9 +203,10 @@ BackendError impl_functions(LLVMBackendCompileUnit* unit,
Function* func = (Function*) val; Function* func = (Function*) val;
if (func->kind == FunctionDeclarationKind) { 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 { } 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) { if (err.kind != Success) {

View File

@ -179,6 +179,9 @@ BackendError impl_func_call(LLVMBackendCompileUnit *unit,
if (err.kind == Success) { if (err.kind == Success) {
LLVMValueRef llvm_func = LLVMGetNamedFunction(unit->module, call->function->name); 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); 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"); DEBUG("creating LLVM context and module");
unit->context = LLVMContextCreate(); unit->context = LLVMContextCreate();
unit->module = unit->module =
LLVMModuleCreateWithNameInContext(config->name, unit->context); LLVMModuleCreateWithNameInContext(config->root_module, unit->context);
LLVMGlobalScope* global_scope = new_global_scope(module); 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.nodePtr = currentNode;
fundecl.name = nameNode->value; 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++) { 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->nodePtr = currentNode;
Parentfunction->kind = FunctionDefinitionKind; Parentfunction->kind = FunctionDeclarationKind;
Parentfunction->impl.declaration = fundecl; Parentfunction->impl.declaration = fundecl;
Parentfunction->name = fundecl.name; Parentfunction->name = fundecl.name;
return SEMANTIC_OK; return SEMANTIC_OK;

View File

@ -55,6 +55,7 @@
%type <node_ptr> moduleimport %type <node_ptr> moduleimport
%type <node_ptr> programbody %type <node_ptr> programbody
%type <node_ptr> fundef %type <node_ptr> fundef
%type <node_ptr> fundecl
%type <node_ptr> box %type <node_ptr> box
%type <node_ptr> typedef %type <node_ptr> typedef
%type <node_ptr> exprlist %type <node_ptr> exprlist
@ -141,6 +142,7 @@ program: program programbody {AST_push_node(root, $2);
programbody: moduleimport {$$ = $1;} programbody: moduleimport {$$ = $1;}
| fundef{$$ = $1;} | fundef{$$ = $1;}
| fundecl{$$ = $1;}
| box{$$ = $1;} | box{$$ = $1;}
| definition{$$ = $1;} | definition{$$ = $1;}
| decl{$$ = $1;} | decl{$$ = $1;}
@ -191,6 +193,13 @@ fundef: KeyFun Ident paramlist '{' statementlist'}' {AST_NODE_PTR fun = AST_new_
$$ = fun; $$ = fun;
DEBUG("Function");}; 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); paramlist: paramlist '(' params ')' {AST_push_node($1, $3);
$$ = $1;} $$ = $1;}
| paramlist '(' ')'{$$ = $1;} | paramlist '(' ')'{$$ = $1;}