added error handling
This commit is contained in:
parent
3b78d117b5
commit
00089a4939
|
@ -89,4 +89,6 @@ BackendError new_backend_error(BackendErrorKind kind);
|
||||||
|
|
||||||
BackendError new_backend_impl_error(BackendErrorKind kind, AST_NODE_PTR node, const char* message);
|
BackendError new_backend_impl_error(BackendErrorKind kind, AST_NODE_PTR node, const char* message);
|
||||||
|
|
||||||
|
#define SUCCESS new_backend_error(Success)
|
||||||
|
|
||||||
#endif // CODEGN_BACKEND_H_
|
#endif // CODEGN_BACKEND_H_
|
||||||
|
|
|
@ -21,6 +21,8 @@ static BackendError llvm_backend_codegen(const AST_NODE_PTR module_node, void**)
|
||||||
LLVMContextRef context = LLVMContextCreate();
|
LLVMContextRef context = LLVMContextCreate();
|
||||||
LLVMModuleRef module = LLVMModuleCreateWithNameInContext("gemstone application", context);
|
LLVMModuleRef module = LLVMModuleCreateWithNameInContext("gemstone application", context);
|
||||||
|
|
||||||
|
BackendError err;
|
||||||
|
|
||||||
TypeScopeRef global_scope = type_scope_new();
|
TypeScopeRef global_scope = type_scope_new();
|
||||||
|
|
||||||
for (size_t i = 0; i < module_node->child_count; i++) {
|
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++) {
|
for (size_t i = 0; i < decls->len; i++) {
|
||||||
GemstoneDeclRef decl = ((GemstoneDeclRef*) decls->data)[i];
|
GemstoneDeclRef decl = ((GemstoneDeclRef*) decls->data)[i];
|
||||||
type_scope_add_variable(global_scope, decl);
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#include "llvm/types/scope.h"
|
#include <codegen/backend.h>
|
||||||
#include "llvm/types/structs.h"
|
#include <llvm/types/scope.h>
|
||||||
|
#include <llvm/types/structs.h>
|
||||||
#include <llvm-c/Types.h>
|
#include <llvm-c/Types.h>
|
||||||
#include <llvm/types/type.h>
|
#include <llvm/types/type.h>
|
||||||
#include <ast/ast.h>
|
#include <ast/ast.h>
|
||||||
#include <llvm/decl/variable.h>
|
#include <llvm/decl/variable.h>
|
||||||
#include <sys/log.h>
|
#include <sys/log.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <llvm-c/Core.h>
|
|
||||||
|
|
||||||
static StorageQualifier get_storage_qualifier_from_ast(AST_NODE_PTR storageQualifierNode) {
|
static StorageQualifier get_storage_qualifier_from_ast(AST_NODE_PTR storageQualifierNode) {
|
||||||
if (storageQualifierNode->kind != AST_Storage) {
|
if (storageQualifierNode->kind != AST_Storage) {
|
||||||
|
@ -67,26 +67,28 @@ GArray* declaration_from_ast(TypeScopeRef scope, const AST_NODE_PTR node) {
|
||||||
return decls;
|
return decls;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMValueRef create_declaration_reference(LLVMModuleRef module, LLVMBuilderRef builder, GemstoneDeclRef decl) {
|
BackendError llvm_create_declaration(LLVMModuleRef llvm_module, LLVMBuilderRef llvm_builder, GemstoneDeclRef gem_decl, LLVMValueRef* llvm_decl) {
|
||||||
LLVMContextRef context = LLVMGetModuleContext(module);
|
LLVMContextRef context = LLVMGetModuleContext(llvm_module);
|
||||||
LLVMTypeRef llvmTypeRef = llvm_type_from_gemstone_type(context, decl->type);
|
LLVMTypeRef llvmTypeRef = llvm_type_from_gemstone_type(context, gem_decl->type);
|
||||||
LLVMValueRef defaultValue = llvm_default_value_of_type(context, decl->type);
|
LLVMValueRef defaultValue = llvm_default_value_of_type(context, gem_decl->type);
|
||||||
LLVMValueRef variable = NULL;
|
|
||||||
|
|
||||||
switch(decl->storageQualifier) {
|
switch(gem_decl->storageQualifier) {
|
||||||
case StorageQualifierLocal:
|
case StorageQualifierLocal:
|
||||||
variable = LLVMBuildAlloca(builder, llvmTypeRef, decl->name);
|
if (llvm_builder == NULL) {
|
||||||
LLVMBuildStore(builder, defaultValue, variable);
|
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;
|
break;
|
||||||
case StorageQualifierStatic:
|
case StorageQualifierStatic:
|
||||||
// add global
|
// add global
|
||||||
variable = LLVMAddGlobal(module, llvmTypeRef, decl->name);
|
*llvm_decl = LLVMAddGlobal(llvm_module, llvmTypeRef, gem_decl->name);
|
||||||
LLVMSetInitializer(variable, defaultValue);
|
LLVMSetInitializer(*llvm_decl, defaultValue);
|
||||||
break;
|
break;
|
||||||
case StorageQualifierGlobal:
|
case StorageQualifierGlobal:
|
||||||
PANIC("Global not implemented");
|
PANIC("Global not implemented");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return variable;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,15 @@
|
||||||
#ifndef LLVM_DECL_VAR_H_
|
#ifndef LLVM_DECL_VAR_H_
|
||||||
#define LLVM_DECL_VAR_H_
|
#define LLVM_DECL_VAR_H_
|
||||||
|
|
||||||
|
#include <codegen/backend.h>
|
||||||
#include <ast/ast.h>
|
#include <ast/ast.h>
|
||||||
|
#include <llvm-c/Types.h>
|
||||||
#include <llvm/types/structs.h>
|
#include <llvm/types/structs.h>
|
||||||
#include <llvm/types/scope.h>
|
#include <llvm/types/scope.h>
|
||||||
|
#include <llvm-c/Core.h>
|
||||||
|
|
||||||
GArray* declaration_from_ast(TypeScopeRef scope, const AST_NODE_PTR node);
|
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_
|
#endif // LLVM_DECL_VAR_H_
|
||||||
|
|
|
@ -1,115 +1,113 @@
|
||||||
|
|
||||||
#include <llvm/decl/variable.h>
|
#include <llvm/decl/variable.h>
|
||||||
#include <llvm/function/function-types.h>
|
#include <llvm/function/function-types.h>
|
||||||
#include <llvm/types/type.h>
|
|
||||||
#include <llvm/types/scope.h>
|
#include <llvm/types/scope.h>
|
||||||
|
#include <llvm/types/type.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct TypeScope_t {
|
struct TypeScope_t {
|
||||||
GArray* types;
|
GArray *types;
|
||||||
GArray* scopes;
|
GArray *scopes;
|
||||||
GArray* funcs;
|
GArray *funcs;
|
||||||
GHashTable* vars;
|
GHashTable *vars;
|
||||||
TypeScopeRef parent;
|
TypeScopeRef parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
TypeScopeRef type_scope_new() {
|
TypeScopeRef type_scope_new() {
|
||||||
TypeScopeRef scope = malloc(sizeof(TypeScope));
|
TypeScopeRef scope = malloc(sizeof(TypeScope));
|
||||||
|
|
||||||
// neither zero termination no initialisazion to zero needed
|
// neither zero termination no initialisazion to zero needed
|
||||||
scope->scopes = g_array_new(FALSE, FALSE, sizeof(TypeScopeRef));
|
scope->scopes = g_array_new(FALSE, FALSE, sizeof(TypeScopeRef));
|
||||||
scope->types = g_array_new(FALSE, FALSE, sizeof(GemstoneTypedefRef));
|
scope->types = g_array_new(FALSE, FALSE, sizeof(GemstoneTypedefRef));
|
||||||
scope->funcs = g_array_new(FALSE, FALSE, sizeof(GemstoneFunRef));
|
scope->funcs = g_array_new(FALSE, FALSE, sizeof(GemstoneFunRef));
|
||||||
scope->vars = g_hash_table_new(g_str_hash, g_str_equal);
|
scope->vars = g_hash_table_new(g_str_hash, g_str_equal);
|
||||||
scope->parent = NULL;
|
scope->parent = NULL;
|
||||||
|
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
void type_scope_append_type(TypeScopeRef scope, GemstoneTypedefRef type) {
|
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) {
|
void type_scope_append_scope(TypeScopeRef scope, TypeScopeRef child_scope) {
|
||||||
g_array_append_val(scope->scopes, child_scope);
|
g_array_append_val(scope->scopes, child_scope);
|
||||||
child_scope->parent = scope;
|
child_scope->parent = scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
GemstoneTypedefRef type_scope_get_type(TypeScopeRef scope, size_t index) {
|
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) {
|
size_t type_scope_types_len(TypeScopeRef scope) { return scope->types->len; }
|
||||||
return scope->types->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t type_scope_scopes_len(TypeScopeRef scope) {
|
size_t type_scope_scopes_len(TypeScopeRef scope) { return scope->scopes->len; }
|
||||||
return scope->scopes->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
GemstoneTypedefRef type_scope_get_type_from_name(TypeScopeRef scope, const char* name) {
|
GemstoneTypedefRef type_scope_get_type_from_name(TypeScopeRef scope,
|
||||||
for (guint i = 0; i < scope->types->len; i++) {
|
const char *name) {
|
||||||
GemstoneTypedefRef typeref = ((GemstoneTypedefRef*) scope->types->data)[i];
|
for (guint i = 0; i < scope->types->len; i++) {
|
||||||
|
GemstoneTypedefRef typeref = ((GemstoneTypedefRef *)scope->types->data)[i];
|
||||||
|
|
||||||
if (strcmp(typeref->name, name) == 0) {
|
if (strcmp(typeref->name, name) == 0) {
|
||||||
return typeref;
|
return typeref;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (scope->parent == NULL) {
|
if (scope->parent == NULL) {
|
||||||
return 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) {
|
void type_scope_delete(TypeScopeRef scope) {
|
||||||
|
|
||||||
for (guint i = 0; i < scope->scopes->len; i++) {
|
for (guint i = 0; i < scope->scopes->len; i++) {
|
||||||
TypeScopeRef scoperef = ((TypeScopeRef*) scope->scopes->data)[i];
|
TypeScopeRef scoperef = ((TypeScopeRef *)scope->scopes->data)[i];
|
||||||
type_scope_delete(scoperef);
|
type_scope_delete(scoperef);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (guint i = 0; i < scope->types->len; i++) {
|
for (guint i = 0; i < scope->types->len; i++) {
|
||||||
// TODO: free gemstone type
|
// TODO: free gemstone type
|
||||||
}
|
}
|
||||||
|
|
||||||
g_array_free(scope->scopes, TRUE);
|
g_array_free(scope->scopes, TRUE);
|
||||||
g_array_free(scope->types, TRUE);
|
g_array_free(scope->types, TRUE);
|
||||||
g_array_free(scope->funcs, TRUE);
|
g_array_free(scope->funcs, TRUE);
|
||||||
g_hash_table_destroy(scope->vars);
|
g_hash_table_destroy(scope->vars);
|
||||||
|
|
||||||
free(scope);
|
free(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
void type_scope_add_variable(TypeScopeRef scope, GemstoneDeclRef decl) {
|
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) {
|
GemstoneDeclRef type_scope_get_variable(TypeScopeRef scope, const char *name) {
|
||||||
if (g_hash_table_contains(scope->vars, name)) {
|
if (g_hash_table_contains(scope->vars, name)) {
|
||||||
return g_hash_table_lookup(scope->vars, name);
|
return g_hash_table_lookup(scope->vars, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void type_scope_add_fun(TypeScopeRef scope, GemstoneFunRef function) {
|
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) {
|
GemstoneFunRef type_scope_get_fun_from_name(TypeScopeRef scope,
|
||||||
for (guint i = 0; i < scope->funcs->len; i++) {
|
const char *name) {
|
||||||
GemstoneFunRef funref = ((GemstoneFunRef*) scope->funcs->data)[i];
|
for (guint i = 0; i < scope->funcs->len; i++) {
|
||||||
|
GemstoneFunRef funref = ((GemstoneFunRef *)scope->funcs->data)[i];
|
||||||
|
|
||||||
if (strcmp(funref->name, name) == 0) {
|
if (strcmp(funref->name, name) == 0) {
|
||||||
return funref;
|
return funref;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (scope->parent == NULL) {
|
if (scope->parent == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return type_scope_get_fun_from_name(scope->parent, name);
|
return type_scope_get_fun_from_name(scope->parent, name);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue