diff --git a/src/codegen/backend.h b/src/codegen/backend.h index 02cbc43..c00859b 100644 --- a/src/codegen/backend.h +++ b/src/codegen/backend.h @@ -89,4 +89,6 @@ BackendError new_backend_error(BackendErrorKind kind); BackendError new_backend_impl_error(BackendErrorKind kind, AST_NODE_PTR node, const char* message); +#define SUCCESS new_backend_error(Success) + #endif // CODEGN_BACKEND_H_ diff --git a/src/llvm/backend.c b/src/llvm/backend.c index 204e06a..235f59c 100644 --- a/src/llvm/backend.c +++ b/src/llvm/backend.c @@ -21,6 +21,8 @@ static BackendError llvm_backend_codegen(const AST_NODE_PTR module_node, void**) LLVMContextRef context = LLVMContextCreate(); LLVMModuleRef module = LLVMModuleCreateWithNameInContext("gemstone application", context); + BackendError err; + TypeScopeRef global_scope = type_scope_new(); for (size_t i = 0; i < module_node->child_count; i++) { @@ -47,8 +49,13 @@ static BackendError llvm_backend_codegen(const AST_NODE_PTR module_node, void**) for (size_t i = 0; i < decls->len; i++) { GemstoneDeclRef decl = ((GemstoneDeclRef*) decls->data)[i]; type_scope_add_variable(global_scope, decl); + + LLVMValueRef llvm_decl = NULL; + err = llvm_create_declaration(module, NULL, decl, &llvm_decl); + + if (err.kind != Success) + break; } - // TODO: create LLVMValueRef of global/static variables break; default: diff --git a/src/llvm/decl/variable.c b/src/llvm/decl/variable.c index 878dc2d..d1d7a15 100644 --- a/src/llvm/decl/variable.c +++ b/src/llvm/decl/variable.c @@ -1,12 +1,12 @@ -#include "llvm/types/scope.h" -#include "llvm/types/structs.h" +#include +#include +#include #include #include #include #include #include #include -#include static StorageQualifier get_storage_qualifier_from_ast(AST_NODE_PTR storageQualifierNode) { if (storageQualifierNode->kind != AST_Storage) { @@ -67,26 +67,28 @@ GArray* declaration_from_ast(TypeScopeRef scope, const AST_NODE_PTR node) { return decls; } -LLVMValueRef create_declaration_reference(LLVMModuleRef module, LLVMBuilderRef builder, GemstoneDeclRef decl) { - LLVMContextRef context = LLVMGetModuleContext(module); - LLVMTypeRef llvmTypeRef = llvm_type_from_gemstone_type(context, decl->type); - LLVMValueRef defaultValue = llvm_default_value_of_type(context, decl->type); - LLVMValueRef variable = NULL; +BackendError llvm_create_declaration(LLVMModuleRef llvm_module, LLVMBuilderRef llvm_builder, GemstoneDeclRef gem_decl, LLVMValueRef* llvm_decl) { + LLVMContextRef context = LLVMGetModuleContext(llvm_module); + LLVMTypeRef llvmTypeRef = llvm_type_from_gemstone_type(context, gem_decl->type); + LLVMValueRef defaultValue = llvm_default_value_of_type(context, gem_decl->type); - switch(decl->storageQualifier) { + switch(gem_decl->storageQualifier) { case StorageQualifierLocal: - variable = LLVMBuildAlloca(builder, llvmTypeRef, decl->name); - LLVMBuildStore(builder, defaultValue, variable); + if (llvm_builder == NULL) { + return new_backend_impl_error(Implementation, NULL, "initializing a local variable on non-local scope"); + } + *llvm_decl = LLVMBuildAlloca(llvm_builder, llvmTypeRef, gem_decl->name); + LLVMBuildStore(llvm_builder, defaultValue, *llvm_decl); break; case StorageQualifierStatic: // add global - variable = LLVMAddGlobal(module, llvmTypeRef, decl->name); - LLVMSetInitializer(variable, defaultValue); + *llvm_decl = LLVMAddGlobal(llvm_module, llvmTypeRef, gem_decl->name); + LLVMSetInitializer(*llvm_decl, defaultValue); break; case StorageQualifierGlobal: PANIC("Global not implemented"); break; } - return variable; + return SUCCESS; } diff --git a/src/llvm/decl/variable.h b/src/llvm/decl/variable.h index 8548391..07cd9f2 100644 --- a/src/llvm/decl/variable.h +++ b/src/llvm/decl/variable.h @@ -2,10 +2,15 @@ #ifndef LLVM_DECL_VAR_H_ #define LLVM_DECL_VAR_H_ +#include #include +#include #include #include +#include GArray* declaration_from_ast(TypeScopeRef scope, const AST_NODE_PTR node); +BackendError llvm_create_declaration(LLVMModuleRef llvm_module, LLVMBuilderRef llvm_builder, GemstoneDeclRef gem_decl, LLVMValueRef* llvm_decl); + #endif // LLVM_DECL_VAR_H_ diff --git a/src/llvm/types/scope.c b/src/llvm/types/scope.c index 851da03..445c5ee 100644 --- a/src/llvm/types/scope.c +++ b/src/llvm/types/scope.c @@ -1,115 +1,113 @@ #include #include -#include #include +#include #include struct TypeScope_t { - GArray* types; - GArray* scopes; - GArray* funcs; - GHashTable* vars; - TypeScopeRef parent; + GArray *types; + GArray *scopes; + GArray *funcs; + GHashTable *vars; + TypeScopeRef parent; }; TypeScopeRef type_scope_new() { - TypeScopeRef scope = malloc(sizeof(TypeScope)); + TypeScopeRef scope = malloc(sizeof(TypeScope)); - // neither zero termination no initialisazion to zero needed - scope->scopes = g_array_new(FALSE, FALSE, sizeof(TypeScopeRef)); - scope->types = g_array_new(FALSE, FALSE, sizeof(GemstoneTypedefRef)); - scope->funcs = g_array_new(FALSE, FALSE, sizeof(GemstoneFunRef)); - scope->vars = g_hash_table_new(g_str_hash, g_str_equal); - scope->parent = NULL; + // neither zero termination no initialisazion to zero needed + scope->scopes = g_array_new(FALSE, FALSE, sizeof(TypeScopeRef)); + scope->types = g_array_new(FALSE, FALSE, sizeof(GemstoneTypedefRef)); + scope->funcs = g_array_new(FALSE, FALSE, sizeof(GemstoneFunRef)); + scope->vars = g_hash_table_new(g_str_hash, g_str_equal); + scope->parent = NULL; - return scope; + return scope; } void type_scope_append_type(TypeScopeRef scope, GemstoneTypedefRef type) { - g_array_append_val(scope->types, type); + g_array_append_val(scope->types, type); } void type_scope_append_scope(TypeScopeRef scope, TypeScopeRef child_scope) { - g_array_append_val(scope->scopes, child_scope); - child_scope->parent = scope; + g_array_append_val(scope->scopes, child_scope); + child_scope->parent = scope; } GemstoneTypedefRef type_scope_get_type(TypeScopeRef scope, size_t index) { - return ((GemstoneTypedefRef*) scope->types->data)[index]; + return ((GemstoneTypedefRef *)scope->types->data)[index]; } -size_t type_scope_types_len(TypeScopeRef scope) { - return scope->types->len; -} +size_t type_scope_types_len(TypeScopeRef scope) { return scope->types->len; } -size_t type_scope_scopes_len(TypeScopeRef scope) { - return scope->scopes->len; -} +size_t type_scope_scopes_len(TypeScopeRef scope) { return scope->scopes->len; } -GemstoneTypedefRef type_scope_get_type_from_name(TypeScopeRef scope, const char* name) { - for (guint i = 0; i < scope->types->len; i++) { - GemstoneTypedefRef typeref = ((GemstoneTypedefRef*) scope->types->data)[i]; +GemstoneTypedefRef type_scope_get_type_from_name(TypeScopeRef scope, + const char *name) { + for (guint i = 0; i < scope->types->len; i++) { + GemstoneTypedefRef typeref = ((GemstoneTypedefRef *)scope->types->data)[i]; - if (strcmp(typeref->name, name) == 0) { - return typeref; - } + if (strcmp(typeref->name, name) == 0) { + return typeref; } + } - if (scope->parent == NULL) { - return NULL; - } + if (scope->parent == NULL) { + return NULL; + } - return type_scope_get_type_from_name(scope->parent, name); + return type_scope_get_type_from_name(scope->parent, name); } void type_scope_delete(TypeScopeRef scope) { - for (guint i = 0; i < scope->scopes->len; i++) { - TypeScopeRef scoperef = ((TypeScopeRef*) scope->scopes->data)[i]; - type_scope_delete(scoperef); - } + for (guint i = 0; i < scope->scopes->len; i++) { + TypeScopeRef scoperef = ((TypeScopeRef *)scope->scopes->data)[i]; + type_scope_delete(scoperef); + } - for (guint i = 0; i < scope->types->len; i++) { - // TODO: free gemstone type - } + for (guint i = 0; i < scope->types->len; i++) { + // TODO: free gemstone type + } - g_array_free(scope->scopes, TRUE); - g_array_free(scope->types, TRUE); - g_array_free(scope->funcs, TRUE); - g_hash_table_destroy(scope->vars); + g_array_free(scope->scopes, TRUE); + g_array_free(scope->types, TRUE); + g_array_free(scope->funcs, TRUE); + g_hash_table_destroy(scope->vars); - free(scope); + free(scope); } void type_scope_add_variable(TypeScopeRef scope, GemstoneDeclRef decl) { - g_hash_table_insert(scope->vars, (gpointer) decl->name, decl); + g_hash_table_insert(scope->vars, (gpointer)decl->name, decl); } -GemstoneDeclRef type_scope_get_variable(TypeScopeRef scope, const char* name) { - if (g_hash_table_contains(scope->vars, name)) { - return g_hash_table_lookup(scope->vars, name); - } +GemstoneDeclRef type_scope_get_variable(TypeScopeRef scope, const char *name) { + if (g_hash_table_contains(scope->vars, name)) { + return g_hash_table_lookup(scope->vars, name); + } - return NULL; + return NULL; } void type_scope_add_fun(TypeScopeRef scope, GemstoneFunRef function) { - g_array_append_val(scope->funcs, function); + g_array_append_val(scope->funcs, function); } -GemstoneFunRef type_scope_get_fun_from_name(TypeScopeRef scope, const char* name) { - for (guint i = 0; i < scope->funcs->len; i++) { - GemstoneFunRef funref = ((GemstoneFunRef*) scope->funcs->data)[i]; +GemstoneFunRef type_scope_get_fun_from_name(TypeScopeRef scope, + const char *name) { + for (guint i = 0; i < scope->funcs->len; i++) { + GemstoneFunRef funref = ((GemstoneFunRef *)scope->funcs->data)[i]; - if (strcmp(funref->name, name) == 0) { - return funref; - } + if (strcmp(funref->name, name) == 0) { + return funref; } + } - if (scope->parent == NULL) { - return NULL; - } + if (scope->parent == NULL) { + return NULL; + } - return type_scope_get_fun_from_name(scope->parent, name); + return type_scope_get_fun_from_name(scope->parent, name); }