fixed: function declarations
This commit is contained in:
parent
09871cce76
commit
de253a94ab
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;}
|
||||||
|
|
Loading…
Reference in New Issue