finished global variable test
This commit is contained in:
parent
0fcb0d7af8
commit
fb6f6e9777
|
@ -136,6 +136,29 @@ BackendError export_module(LLVMBackendCompileUnit* unit, const Target* target) {
|
||||||
return err;
|
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**) {
|
BackendError parse_module(const Module* module, void**) {
|
||||||
DEBUG("generating code for module %p", module);
|
DEBUG("generating code for module %p", module);
|
||||||
if (module == NULL) {
|
if (module == NULL) {
|
||||||
|
@ -157,18 +180,14 @@ BackendError parse_module(const Module* module, void**) {
|
||||||
|
|
||||||
DEBUG("generating code...");
|
DEBUG("generating code...");
|
||||||
|
|
||||||
err = impl_types(unit, global_scope, module->types);
|
err = build_module(unit, global_scope, module);
|
||||||
// NOTE: functions of boxes are not stored in the box itself,
|
if (err.kind == Success) {
|
||||||
// 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);
|
|
||||||
|
|
||||||
Target target = create_native_target();
|
Target target = create_native_target();
|
||||||
|
|
||||||
export_module(unit, &target);
|
export_module(unit, &target);
|
||||||
|
|
||||||
delete_target(target);
|
delete_target(target);
|
||||||
|
}
|
||||||
|
|
||||||
delete_global_scope(global_scope);
|
delete_global_scope(global_scope);
|
||||||
|
|
||||||
|
|
|
@ -333,7 +333,7 @@ BackendError get_type_default_value(LLVMBackendCompileUnit* unit,
|
||||||
Implementation, gemstone_type->nodePtr, "No default value for type");
|
Implementation, gemstone_type->nodePtr, "No default value for type");
|
||||||
|
|
||||||
LLVMTypeRef llvm_type = NULL;
|
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) {
|
if (err.kind != Success) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ BackendError impl_global_declaration(LLVMBackendCompileUnit* unit,
|
||||||
LLVMGlobalScope* scope,
|
LLVMGlobalScope* scope,
|
||||||
VariableDeclaration* decl,
|
VariableDeclaration* decl,
|
||||||
const char* name) {
|
const char* name) {
|
||||||
DEBUG("implementing global declaration: ", name);
|
DEBUG("implementing global declaration: %s", name);
|
||||||
BackendError err = SUCCESS;
|
BackendError err = SUCCESS;
|
||||||
LLVMTypeRef llvm_type = NULL;
|
LLVMTypeRef llvm_type = NULL;
|
||||||
err = get_type_impl(unit, scope, &decl->type, &llvm_type);
|
err = get_type_impl(unit, scope, &decl->type, &llvm_type);
|
||||||
|
@ -30,6 +30,8 @@ BackendError impl_global_declaration(LLVMBackendCompileUnit* unit,
|
||||||
DEBUG("setting default value...");
|
DEBUG("setting default value...");
|
||||||
LLVMSetInitializer(global, initial_value);
|
LLVMSetInitializer(global, initial_value);
|
||||||
g_hash_table_insert(scope->variables, (gpointer)name, global);
|
g_hash_table_insert(scope->variables, (gpointer)name, global);
|
||||||
|
} else {
|
||||||
|
ERROR("unable to initialize global variable: %s", err.impl.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -67,6 +69,7 @@ BackendError impl_global_definiton(LLVMBackendCompileUnit* unit,
|
||||||
BackendError impl_global_variable(LLVMBackendCompileUnit* unit,
|
BackendError impl_global_variable(LLVMBackendCompileUnit* unit,
|
||||||
Variable* gemstone_var, const char* alias,
|
Variable* gemstone_var, const char* alias,
|
||||||
LLVMGlobalScope* scope) {
|
LLVMGlobalScope* scope) {
|
||||||
|
DEBUG("implementing global variable: %s", alias);
|
||||||
BackendError err = SUCCESS;
|
BackendError err = SUCCESS;
|
||||||
|
|
||||||
switch (gemstone_var->kind) {
|
switch (gemstone_var->kind) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
|
|
||||||
|
#include <alloca.h>
|
||||||
#include <codegen/backend.h>
|
#include <codegen/backend.h>
|
||||||
#include <llvm/backend.h>
|
#include <llvm/backend.h>
|
||||||
#include <sys/log.h>
|
#include <sys/log.h>
|
||||||
|
@ -7,8 +8,25 @@
|
||||||
// NOTE: unused
|
// NOTE: unused
|
||||||
AST_NODE_PTR root;
|
AST_NODE_PTR root;
|
||||||
|
|
||||||
Module* create_module() {
|
[[gnu::always_inline]]
|
||||||
Module* module = malloc(sizeof(Module));
|
[[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->boxes = g_hash_table_new(g_str_hash, g_str_equal);
|
||||||
module->functions = 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->variables = g_hash_table_new(g_str_hash, g_str_equal);
|
||||||
module->types = 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;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
log_init();
|
log_init();
|
||||||
|
|
||||||
|
// no need to clean up ;-)
|
||||||
Module* module = create_module();
|
Module* module = create_module();
|
||||||
|
|
||||||
llvm_backend_init();
|
llvm_backend_init();
|
||||||
|
|
Loading…
Reference in New Issue