added global variables
This commit is contained in:
parent
e3f8e4b461
commit
b91c277ac4
|
@ -1,17 +1,72 @@
|
||||||
|
|
||||||
|
#include <codegen/backend.h>
|
||||||
|
#include <llvm-c/Core.h>
|
||||||
|
#include <llvm-c/Types.h>
|
||||||
#include <llvm/parser.h>
|
#include <llvm/parser.h>
|
||||||
|
#include <llvm/types.h>
|
||||||
|
#include <llvm/variables.h>
|
||||||
|
#include <set/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
BackendError parse_module(const Module* module, void**) {
|
BackendError parse_module(const Module* module, void**) {
|
||||||
LLVMBackendCompileUnit* unit = malloc(sizeof(LLVMBackendCompileUnit));
|
LLVMBackendCompileUnit* unit = malloc(sizeof(LLVMBackendCompileUnit));
|
||||||
|
|
||||||
// we start with a LLVM module
|
// we start with a LLVM module
|
||||||
unit->context = LLVMContextCreate();
|
unit->context = LLVMContextCreate();
|
||||||
unit->module = LLVMModuleCreateWithNameInContext("gemstone application", unit->context);
|
unit->module = LLVMModuleCreateWithNameInContext("gemstone application",
|
||||||
|
unit->context);
|
||||||
|
|
||||||
|
LLVMGlobalScope* global_scope = new_global_scope();
|
||||||
|
|
||||||
|
BackendError err = new_backend_error(Success);
|
||||||
|
|
||||||
|
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 = impl_global_variables(unit, global_scope, module->variables);
|
||||||
|
|
||||||
|
delete_global_scope(global_scope);
|
||||||
|
|
||||||
LLVMDisposeModule(unit->module);
|
LLVMDisposeModule(unit->module);
|
||||||
LLVMContextDispose(unit->context);
|
LLVMContextDispose(unit->context);
|
||||||
|
|
||||||
return new_backend_error(Success);
|
free(unit);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLVMGlobalScope* new_global_scope() {
|
||||||
|
LLVMGlobalScope* scope = malloc(sizeof(LLVMGlobalScope));
|
||||||
|
|
||||||
|
scope->functions = g_hash_table_new(g_str_hash, g_str_equal);
|
||||||
|
scope->variables = g_hash_table_new(g_str_hash, g_str_equal);
|
||||||
|
scope->types = g_hash_table_new(g_str_hash, g_str_equal);
|
||||||
|
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLVMLocalScope* new_local_scope(LLVMGlobalScope* global_scope,
|
||||||
|
LLVMLocalScope* parent_scope) {
|
||||||
|
LLVMLocalScope* scope = malloc(sizeof(LLVMLocalScope));
|
||||||
|
|
||||||
|
scope->variables = g_hash_table_new(g_str_hash, g_str_equal);
|
||||||
|
scope->params = g_hash_table_new(g_str_hash, g_str_equal);
|
||||||
|
scope->global_scope = global_scope;
|
||||||
|
scope->parent_scope = parent_scope;
|
||||||
|
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_local_scope(LLVMLocalScope* scope) {
|
||||||
|
g_hash_table_unref(scope->variables);
|
||||||
|
free(scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_global_scope(LLVMGlobalScope* scope) {
|
||||||
|
g_hash_table_unref(scope->functions);
|
||||||
|
g_hash_table_unref(scope->types);
|
||||||
|
g_hash_table_unref(scope->variables);
|
||||||
|
free(scope);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
|
|
||||||
#include "set/types.h"
|
#ifndef LLVM_BACKEND_PARSE_H_
|
||||||
|
#define LLVM_BACKEND_PARSE_H_
|
||||||
|
|
||||||
|
#include <set/types.h>
|
||||||
#include <codegen/backend.h>
|
#include <codegen/backend.h>
|
||||||
#include <llvm-c/Types.h>
|
#include <llvm-c/Types.h>
|
||||||
#include <llvm-c/Core.h>
|
#include <llvm-c/Core.h>
|
||||||
|
@ -9,4 +12,29 @@ typedef struct LLVMBackendCompileUnit_t {
|
||||||
LLVMModuleRef module;
|
LLVMModuleRef module;
|
||||||
} LLVMBackendCompileUnit;
|
} LLVMBackendCompileUnit;
|
||||||
|
|
||||||
|
typedef struct LLVMGlobalScope_t {
|
||||||
|
GHashTable* types;
|
||||||
|
GHashTable* variables;
|
||||||
|
GHashTable* functions;
|
||||||
|
} LLVMGlobalScope;
|
||||||
|
|
||||||
|
LLVMGlobalScope* new_global_scope();
|
||||||
|
|
||||||
|
void delete_global_scope(LLVMGlobalScope* scope);
|
||||||
|
|
||||||
|
typedef struct LLVMLocalScope_t LLVMLocalScope;
|
||||||
|
|
||||||
|
typedef struct LLVMLocalScope_t {
|
||||||
|
LLVMGlobalScope* global_scope;
|
||||||
|
LLVMLocalScope* parent_scope;
|
||||||
|
GHashTable* params;
|
||||||
|
GHashTable* variables;
|
||||||
|
} LLVMLocalScope;
|
||||||
|
|
||||||
|
LLVMLocalScope* new_local_scope(LLVMGlobalScope* global_scope, LLVMLocalScope* parent_scope);
|
||||||
|
|
||||||
|
void delete_local_scope(LLVMLocalScope* scope);
|
||||||
|
|
||||||
BackendError parse_module(const Module* module, void**);
|
BackendError parse_module(const Module* module, void**);
|
||||||
|
|
||||||
|
#endif // LLVM_BACKEND_PARSE_H_
|
||||||
|
|
|
@ -0,0 +1,324 @@
|
||||||
|
#include <codegen/backend.h>
|
||||||
|
#include <llvm-c/Core.h>
|
||||||
|
#include <llvm-c/Types.h>
|
||||||
|
#include <llvm/types.h>
|
||||||
|
#include <set/types.h>
|
||||||
|
#include <llvm/parser.h>
|
||||||
|
|
||||||
|
BackendError impl_primtive_type(LLVMBackendCompileUnit* unit,
|
||||||
|
PrimitiveType primtive,
|
||||||
|
LLVMTypeRef* llvm_type) {
|
||||||
|
switch (primtive) {
|
||||||
|
case Int:
|
||||||
|
*llvm_type = LLVMInt32TypeInContext(unit->context);
|
||||||
|
break;
|
||||||
|
case Float:
|
||||||
|
*llvm_type = LLVMFloatTypeInContext(unit->context);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_integral_type(LLVMBackendCompileUnit* unit, Scale scale,
|
||||||
|
LLVMTypeRef* llvm_type) {
|
||||||
|
LLVMTypeRef integral_type =
|
||||||
|
LLVMIntTypeInContext(unit->context, (int)(4 * scale) * 8);
|
||||||
|
|
||||||
|
*llvm_type = integral_type;
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_float_type(LLVMBackendCompileUnit* unit, Scale scale,
|
||||||
|
LLVMTypeRef* llvm_type) {
|
||||||
|
LLVMTypeRef float_type = NULL;
|
||||||
|
|
||||||
|
switch ((int)(scale * 4)) {
|
||||||
|
case 2:
|
||||||
|
float_type = LLVMHalfTypeInContext(unit->context);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
float_type = LLVMFloatTypeInContext(unit->context);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
float_type = LLVMDoubleTypeInContext(unit->context);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
float_type = LLVMFP128TypeInContext(unit->context);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (float_type != NULL) {
|
||||||
|
*llvm_type = float_type;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_backend_impl_error(Implementation, NULL,
|
||||||
|
"floating point with scale not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_composite_type(LLVMBackendCompileUnit* unit,
|
||||||
|
CompositeType* composite,
|
||||||
|
LLVMTypeRef* llvm_type) {
|
||||||
|
BackendError err = SUCCESS;
|
||||||
|
|
||||||
|
switch (composite->primitive) {
|
||||||
|
case Int:
|
||||||
|
err = impl_integral_type(unit, composite->scale, llvm_type);
|
||||||
|
break;
|
||||||
|
case Float:
|
||||||
|
if (composite->sign == Signed) {
|
||||||
|
err = impl_float_type(unit, composite->scale, llvm_type);
|
||||||
|
} else {
|
||||||
|
err = new_backend_impl_error(
|
||||||
|
Implementation, composite->nodePtr,
|
||||||
|
"unsigned floating-point not supported");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_reference_type(LLVMBackendCompileUnit* unit,
|
||||||
|
LLVMGlobalScope* scope,
|
||||||
|
ReferenceType reference,
|
||||||
|
LLVMTypeRef* llvm_type);
|
||||||
|
|
||||||
|
BackendError impl_box_type(LLVMBackendCompileUnit* unit, LLVMGlobalScope* scope,
|
||||||
|
BoxType* reference, LLVMTypeRef* llvm_type);
|
||||||
|
|
||||||
|
BackendError get_type_impl(LLVMBackendCompileUnit* unit, LLVMGlobalScope* scope,
|
||||||
|
Type* gemstone_type, LLVMTypeRef* llvm_type) {
|
||||||
|
BackendError err =
|
||||||
|
new_backend_impl_error(Implementation, gemstone_type->nodePtr,
|
||||||
|
"No type implementation covers type");
|
||||||
|
|
||||||
|
switch (gemstone_type->kind) {
|
||||||
|
case TypeKindPrimitive:
|
||||||
|
err = impl_primtive_type(unit, gemstone_type->impl.primitive,
|
||||||
|
llvm_type);
|
||||||
|
break;
|
||||||
|
case TypeKindComposite:
|
||||||
|
err = impl_composite_type(unit, &gemstone_type->impl.composite,
|
||||||
|
llvm_type);
|
||||||
|
break;
|
||||||
|
case TypeKindReference:
|
||||||
|
err = impl_reference_type(unit, scope,
|
||||||
|
gemstone_type->impl.reference, llvm_type);
|
||||||
|
break;
|
||||||
|
case TypeKindBox:
|
||||||
|
err =
|
||||||
|
impl_box_type(unit, scope, &gemstone_type->impl.box, llvm_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_box_type(LLVMBackendCompileUnit* unit, LLVMGlobalScope* scope,
|
||||||
|
BoxType* box, LLVMTypeRef* llvm_type) {
|
||||||
|
GHashTableIter iterator;
|
||||||
|
g_hash_table_iter_init(&iterator, box->member);
|
||||||
|
|
||||||
|
gpointer key = NULL;
|
||||||
|
gpointer val = NULL;
|
||||||
|
|
||||||
|
BackendError err;
|
||||||
|
|
||||||
|
GArray* members = g_array_new(FALSE, FALSE, sizeof(LLVMTypeRef));
|
||||||
|
|
||||||
|
while (g_hash_table_iter_next(&iterator, &key, &val) != FALSE) {
|
||||||
|
Type* member_type = ((BoxMember*) val)->type;
|
||||||
|
|
||||||
|
LLVMTypeRef llvm_type = NULL;
|
||||||
|
err = get_type_impl(unit, scope, member_type, &llvm_type);
|
||||||
|
|
||||||
|
if (err.kind != Success) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_append_val(members, llvm_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err.kind == Success) {
|
||||||
|
*llvm_type =
|
||||||
|
LLVMStructType((LLVMTypeRef*)members->data, members->len, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_free(members, FALSE);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_reference_type(LLVMBackendCompileUnit* unit,
|
||||||
|
LLVMGlobalScope* scope,
|
||||||
|
ReferenceType reference,
|
||||||
|
LLVMTypeRef* llvm_type) {
|
||||||
|
BackendError err = SUCCESS;
|
||||||
|
LLVMTypeRef type = NULL;
|
||||||
|
err = get_type_impl(unit, scope, reference, &type);
|
||||||
|
|
||||||
|
if (err.kind == Success) {
|
||||||
|
*llvm_type = LLVMPointerType(type, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_type(LLVMBackendCompileUnit* unit, Type* gemstone_type,
|
||||||
|
const char* alias, LLVMGlobalScope* scope) {
|
||||||
|
BackendError err = SUCCESS;
|
||||||
|
|
||||||
|
LLVMTypeRef llvm_type = NULL;
|
||||||
|
err = get_type_impl(unit, scope, gemstone_type, &llvm_type);
|
||||||
|
|
||||||
|
if (err.kind == Success) {
|
||||||
|
g_hash_table_insert(scope->types, (gpointer)alias, llvm_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_types(LLVMBackendCompileUnit* unit, LLVMGlobalScope* scope,
|
||||||
|
GHashTable* types) {
|
||||||
|
GHashTableIter iterator;
|
||||||
|
g_hash_table_iter_init(&iterator, types);
|
||||||
|
|
||||||
|
gpointer key = NULL;
|
||||||
|
gpointer val = NULL;
|
||||||
|
|
||||||
|
BackendError err;
|
||||||
|
|
||||||
|
while (g_hash_table_iter_next(&iterator, &key, &val) != FALSE) {
|
||||||
|
err = impl_type(unit, (Type*)val, (const char*)key, scope);
|
||||||
|
|
||||||
|
if (err.kind != Success) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError get_primitive_default_value(PrimitiveType type,
|
||||||
|
LLVMTypeRef llvm_type,
|
||||||
|
LLVMValueRef* llvm_value) {
|
||||||
|
switch (type) {
|
||||||
|
case Int:
|
||||||
|
*llvm_value = LLVMConstIntOfString(llvm_type, "0", 10);
|
||||||
|
break;
|
||||||
|
case Float:
|
||||||
|
*llvm_value = LLVMConstRealOfString(llvm_type, "0");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return new_backend_impl_error(Implementation, NULL,
|
||||||
|
"unknown primitive type");
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError get_composite_default_value(CompositeType* composite,
|
||||||
|
LLVMTypeRef llvm_type,
|
||||||
|
LLVMValueRef* llvm_value) {
|
||||||
|
BackendError err = SUCCESS;
|
||||||
|
|
||||||
|
switch (composite->primitive) {
|
||||||
|
case Int:
|
||||||
|
err = get_primitive_default_value(Int, llvm_type, llvm_value);
|
||||||
|
break;
|
||||||
|
case Float:
|
||||||
|
if (composite->sign == Signed) {
|
||||||
|
err = get_primitive_default_value(Float, llvm_type, llvm_value);
|
||||||
|
} else {
|
||||||
|
err = new_backend_impl_error(
|
||||||
|
Implementation, composite->nodePtr,
|
||||||
|
"unsigned floating-point not supported");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError get_reference_default_value(LLVMTypeRef llvm_type,
|
||||||
|
LLVMValueRef* llvm_value) {
|
||||||
|
*llvm_value = LLVMConstPointerNull(llvm_type);
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError get_box_default_value(LLVMBackendCompileUnit* unit,
|
||||||
|
LLVMGlobalScope* scope, BoxType* type,
|
||||||
|
LLVMValueRef* llvm_value) {
|
||||||
|
GHashTableIter iterator;
|
||||||
|
g_hash_table_iter_init(&iterator, type->member);
|
||||||
|
|
||||||
|
gpointer key = NULL;
|
||||||
|
gpointer val = NULL;
|
||||||
|
|
||||||
|
BackendError err;
|
||||||
|
|
||||||
|
GArray* constants = g_array_new(FALSE, FALSE, sizeof(LLVMValueRef));
|
||||||
|
|
||||||
|
while (g_hash_table_iter_next(&iterator, &key, &val) != FALSE) {
|
||||||
|
Type* member_type = ((BoxMember*)val)->type;
|
||||||
|
|
||||||
|
LLVMValueRef constant = NULL;
|
||||||
|
err = get_type_default_value(unit, scope, member_type, &constant);
|
||||||
|
|
||||||
|
if (err.kind != Success) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*llvm_value = LLVMConstStructInContext(
|
||||||
|
unit->context, (LLVMValueRef*) constants->data, constants->len, 0);
|
||||||
|
|
||||||
|
g_array_free(constants, FALSE);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError get_type_default_value(LLVMBackendCompileUnit* unit,
|
||||||
|
LLVMGlobalScope* scope, Type* gemstone_type,
|
||||||
|
LLVMValueRef* llvm_value) {
|
||||||
|
BackendError err = new_backend_impl_error(
|
||||||
|
Implementation, gemstone_type->nodePtr, "No default value for type");
|
||||||
|
|
||||||
|
LLVMTypeRef llvm_type = NULL;
|
||||||
|
get_type_impl(unit, scope, gemstone_type, &llvm_type);
|
||||||
|
if (err.kind != Success) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (gemstone_type->kind) {
|
||||||
|
case TypeKindPrimitive:
|
||||||
|
err = get_primitive_default_value(gemstone_type->impl.primitive,
|
||||||
|
llvm_type, llvm_value);
|
||||||
|
break;
|
||||||
|
case TypeKindComposite:
|
||||||
|
err = get_composite_default_value(&gemstone_type->impl.composite,
|
||||||
|
llvm_type, llvm_value);
|
||||||
|
break;
|
||||||
|
case TypeKindReference:
|
||||||
|
err = get_reference_default_value(llvm_type, llvm_value);
|
||||||
|
break;
|
||||||
|
case TypeKindBox:
|
||||||
|
err = get_box_default_value(unit, scope, &gemstone_type->impl.box,
|
||||||
|
llvm_value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
#ifndef LLVM_BACKEND_TYPES_H_
|
||||||
|
#define LLVM_BACKEND_TYPES_H_
|
||||||
|
|
||||||
|
#include <codegen/backend.h>
|
||||||
|
#include <llvm-c/Core.h>
|
||||||
|
#include <llvm-c/Types.h>
|
||||||
|
#include <llvm/parser.h>
|
||||||
|
#include <set/types.h>
|
||||||
|
|
||||||
|
BackendError impl_types(LLVMBackendCompileUnit* unit, LLVMGlobalScope* scope,
|
||||||
|
GHashTable* types);
|
||||||
|
|
||||||
|
BackendError get_type_impl(LLVMBackendCompileUnit* unit, LLVMGlobalScope* scope,
|
||||||
|
Type* gemstone_type, LLVMTypeRef* llvm_type);
|
||||||
|
|
||||||
|
BackendError get_type_default_value(LLVMBackendCompileUnit* unit,
|
||||||
|
LLVMGlobalScope* scope, Type* gemstone_type,
|
||||||
|
LLVMValueRef* llvm_value);
|
||||||
|
|
||||||
|
#endif // LLVM_BACKEND_TYPES_H_
|
|
@ -0,0 +1,104 @@
|
||||||
|
|
||||||
|
#include <codegen/backend.h>
|
||||||
|
#include <llvm-c/Core.h>
|
||||||
|
#include <llvm-c/Types.h>
|
||||||
|
#include <llvm/types.h>
|
||||||
|
#include <llvm/variables.h>
|
||||||
|
#include <set/types.h>
|
||||||
|
|
||||||
|
BackendError impl_global_declaration(LLVMBackendCompileUnit* unit,
|
||||||
|
LLVMGlobalScope* scope,
|
||||||
|
VariableDeclaration* decl,
|
||||||
|
const char* name) {
|
||||||
|
BackendError err = SUCCESS;
|
||||||
|
LLVMTypeRef llvm_type = NULL;
|
||||||
|
err = get_type_impl(unit, scope, &decl->type, &llvm_type);
|
||||||
|
|
||||||
|
if (err.kind != Success) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLVMValueRef global = LLVMAddGlobal(unit->module, llvm_type, name);
|
||||||
|
|
||||||
|
LLVMValueRef initial_value = NULL;
|
||||||
|
err = get_type_default_value(unit, scope, &decl->type, &initial_value);
|
||||||
|
|
||||||
|
if (err.kind == Success) {
|
||||||
|
LLVMSetInitializer(global, initial_value);
|
||||||
|
g_hash_table_insert(scope->variables, (gpointer)name, global);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_global_definiton(LLVMBackendCompileUnit* unit,
|
||||||
|
LLVMGlobalScope* scope,
|
||||||
|
VariableDefiniton* def,
|
||||||
|
const char* name) {
|
||||||
|
BackendError err = SUCCESS;
|
||||||
|
LLVMTypeRef llvm_type = NULL;
|
||||||
|
err = get_type_impl(unit, scope, &def->declaration.type, &llvm_type);
|
||||||
|
|
||||||
|
if (err.kind != Success) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLVMValueRef global = LLVMAddGlobal(unit->module, llvm_type, name);
|
||||||
|
|
||||||
|
// FIXME: resolve initializer expression!
|
||||||
|
LLVMValueRef initial_value = NULL;
|
||||||
|
err = get_type_default_value(unit, scope, &def->declaration.type, &initial_value);
|
||||||
|
|
||||||
|
if (err.kind == Success) {
|
||||||
|
LLVMSetInitializer(global, initial_value);
|
||||||
|
g_hash_table_insert(scope->variables, (gpointer)name, global);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_global_variable(LLVMBackendCompileUnit* unit,
|
||||||
|
Variable* gemstone_var, const char* alias,
|
||||||
|
LLVMGlobalScope* scope) {
|
||||||
|
BackendError err = SUCCESS;
|
||||||
|
|
||||||
|
switch (gemstone_var->kind) {
|
||||||
|
case VariableKindDeclaration:
|
||||||
|
err = impl_global_declaration(
|
||||||
|
unit, scope, &gemstone_var->impl.declaration, alias);
|
||||||
|
break;
|
||||||
|
case VariableKindDefinition:
|
||||||
|
err = impl_global_definiton(
|
||||||
|
unit, scope, &gemstone_var->impl.definiton, alias);
|
||||||
|
break;
|
||||||
|
case VariableKindBoxMember:
|
||||||
|
err = new_backend_impl_error(Implementation, gemstone_var->nodePtr,
|
||||||
|
"member variable cannot be ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_global_variables(LLVMBackendCompileUnit* unit,
|
||||||
|
LLVMGlobalScope* scope,
|
||||||
|
GHashTable* variables) {
|
||||||
|
GHashTableIter iterator;
|
||||||
|
g_hash_table_iter_init(&iterator, variables);
|
||||||
|
|
||||||
|
gpointer key = NULL;
|
||||||
|
gpointer val = NULL;
|
||||||
|
|
||||||
|
BackendError err;
|
||||||
|
|
||||||
|
while (g_hash_table_iter_next(&iterator, &key, &val) != FALSE) {
|
||||||
|
err =
|
||||||
|
impl_global_variable(unit, (Variable*)val, (const char*)key, scope);
|
||||||
|
|
||||||
|
if (err.kind != Success) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
#ifndef LLVM_BACKEND_VARIABLES_H_
|
||||||
|
#define LLVM_BACKEND_VARIABLES_H_
|
||||||
|
|
||||||
|
#include <codegen/backend.h>
|
||||||
|
#include <llvm-c/Core.h>
|
||||||
|
#include <llvm-c/Types.h>
|
||||||
|
#include <llvm/parser.h>
|
||||||
|
#include <set/types.h>
|
||||||
|
|
||||||
|
BackendError impl_global_variables(LLVMBackendCompileUnit* unit,
|
||||||
|
LLVMGlobalScope* scope,
|
||||||
|
GHashTable* variables);
|
||||||
|
|
||||||
|
#endif // LLVM_BACKEND_VARIABLES_H_
|
Loading…
Reference in New Issue