From fb6f6e9777bc1bf8ba7cfc5f9c62d90c3bb4b52f Mon Sep 17 00:00:00 2001 From: servostar Date: Mon, 27 May 2024 18:17:15 +0200 Subject: [PATCH] finished global variable test --- src/llvm/parser.c | 39 ++++++++++++++++------ src/llvm/types.c | 2 +- src/llvm/variables.c | 5 ++- tests/llvm/global_vars.c | 71 ++++++++++++++++++++++++++++++++++++++-- 4 files changed, 103 insertions(+), 14 deletions(-) diff --git a/src/llvm/parser.c b/src/llvm/parser.c index 4bda673..0f22e17 100644 --- a/src/llvm/parser.c +++ b/src/llvm/parser.c @@ -136,6 +136,29 @@ BackendError export_module(LLVMBackendCompileUnit* unit, const Target* target) { return err; } +static BackendError build_module(LLVMBackendCompileUnit* unit, LLVMGlobalScope* global_scope, const Module* module) { + BackendError err = SUCCESS; + + err = impl_types(unit, global_scope, module->types); + if (err.kind != Success) { + return err; + } + + // NOTE: functions of boxes are not stored in the box itself, + // thus for a box we only implement the type + err = impl_types(unit, global_scope, module->boxes); + if (err.kind != Success) { + return err; + } + + err = impl_global_variables(unit, global_scope, module->variables); + if (err.kind != Success) { + return err; + } + + return err; +} + BackendError parse_module(const Module* module, void**) { DEBUG("generating code for module %p", module); if (module == NULL) { @@ -157,18 +180,14 @@ BackendError parse_module(const Module* module, void**) { DEBUG("generating code..."); - err = impl_types(unit, global_scope, module->types); - // NOTE: functions of boxes are not stored in the box itself, - // thus for a box we only implement the type - err = impl_types(unit, global_scope, module->boxes); + err = build_module(unit, global_scope, module); + if (err.kind == Success) { + Target target = create_native_target(); - err = impl_global_variables(unit, global_scope, module->variables); + export_module(unit, &target); - Target target = create_native_target(); - - export_module(unit, &target); - - delete_target(target); + delete_target(target); + } delete_global_scope(global_scope); diff --git a/src/llvm/types.c b/src/llvm/types.c index e41ff95..bc95f83 100644 --- a/src/llvm/types.c +++ b/src/llvm/types.c @@ -333,7 +333,7 @@ BackendError get_type_default_value(LLVMBackendCompileUnit* unit, Implementation, gemstone_type->nodePtr, "No default value for type"); LLVMTypeRef llvm_type = NULL; - get_type_impl(unit, scope, gemstone_type, &llvm_type); + err = get_type_impl(unit, scope, gemstone_type, &llvm_type); if (err.kind != Success) { return err; } diff --git a/src/llvm/variables.c b/src/llvm/variables.c index 4552e39..5519313 100644 --- a/src/llvm/variables.c +++ b/src/llvm/variables.c @@ -11,7 +11,7 @@ BackendError impl_global_declaration(LLVMBackendCompileUnit* unit, LLVMGlobalScope* scope, VariableDeclaration* decl, const char* name) { - DEBUG("implementing global declaration: ", name); + DEBUG("implementing global declaration: %s", name); BackendError err = SUCCESS; LLVMTypeRef llvm_type = NULL; err = get_type_impl(unit, scope, &decl->type, &llvm_type); @@ -30,6 +30,8 @@ BackendError impl_global_declaration(LLVMBackendCompileUnit* unit, DEBUG("setting default value..."); LLVMSetInitializer(global, initial_value); g_hash_table_insert(scope->variables, (gpointer)name, global); + } else { + ERROR("unable to initialize global variable: %s", err.impl.message); } return err; @@ -67,6 +69,7 @@ BackendError impl_global_definiton(LLVMBackendCompileUnit* unit, BackendError impl_global_variable(LLVMBackendCompileUnit* unit, Variable* gemstone_var, const char* alias, LLVMGlobalScope* scope) { + DEBUG("implementing global variable: %s", alias); BackendError err = SUCCESS; switch (gemstone_var->kind) { diff --git a/tests/llvm/global_vars.c b/tests/llvm/global_vars.c index aca3d42..52a104b 100644 --- a/tests/llvm/global_vars.c +++ b/tests/llvm/global_vars.c @@ -1,4 +1,5 @@ +#include #include #include #include @@ -7,8 +8,25 @@ // NOTE: unused AST_NODE_PTR root; -Module* create_module() { - Module* module = malloc(sizeof(Module)); +[[gnu::always_inline]] +[[clang::always_inline]] +inline Variable* create_variable_decl(const char* name, StorageQualifier qualifier, Type type) { + Variable* variable = alloca(sizeof(Variable)); + + variable->name = name; + variable->kind = VariableKindDeclaration; + variable->nodePtr = NULL; + variable->impl.declaration.nodePtr = NULL; + variable->impl.declaration.qualifier = qualifier; + variable->impl.declaration.type = type; + + return variable; +} + +[[gnu::always_inline]] +[[clang::always_inline]] +inline Module* create_module() { + Module* module = alloca(sizeof(Module)); module->boxes = g_hash_table_new(g_str_hash, g_str_equal); module->functions = g_hash_table_new(g_str_hash, g_str_equal); @@ -16,12 +34,61 @@ Module* create_module() { module->variables = g_hash_table_new(g_str_hash, g_str_equal); module->types = g_hash_table_new(g_str_hash, g_str_equal); + Type type_int; + type_int.kind = TypeKindPrimitive; + type_int.impl.primitive = Int; + + g_hash_table_insert(module->variables, "a", create_variable_decl("a", Global, type_int)); + + Type type_composite; + type_composite.kind = TypeKindComposite; + type_composite.impl.composite.primitive = Float; + type_composite.impl.composite.scale = 2.0; + type_composite.impl.composite.sign = Signed; + + g_hash_table_insert(module->variables, "b", create_variable_decl("b", Global, type_composite)); + + Type type_box; + type_box.kind = TypeKindBox; + type_box.impl.box.member = g_hash_table_new(g_str_hash, g_str_equal); + + BoxMember* member1 = alloca(sizeof(BoxMember)); + member1->box = NULL; + member1->name = "foo"; + member1->type = alloca(sizeof(Type)); + *(member1->type) = type_int; + + g_hash_table_insert(type_box.impl.box.member, "foo", member1); + + Type type_half; + type_half.kind = TypeKindComposite; + type_half.impl.composite.primitive = Float; + type_half.impl.composite.scale = 0.5; + type_half.impl.composite.sign = Signed; + + BoxMember* member2 = alloca(sizeof(BoxMember)); + member2->box = NULL; + member2->name = "bar"; + member2->type = alloca(sizeof(Type)); + *(member2->type) = type_half; + + g_hash_table_insert(type_box.impl.box.member, "bar", member2); + + g_hash_table_insert(module->variables, "c", create_variable_decl("c", Global, type_box)); + + Type type_reference; + type_reference.kind = TypeKindReference; + type_reference.impl.reference = &type_box; + + g_hash_table_insert(module->variables, "d", create_variable_decl("d", Global, type_reference)); + return module; } int main() { log_init(); + // no need to clean up ;-) Module* module = create_module(); llvm_backend_init();