added: new types.h
This commit is contained in:
parent
bd368f99ef
commit
6e59b7ac73
|
@ -72,12 +72,6 @@ TargetLinkConfig* lld_create_link_config(const Target* target, const TargetConfi
|
||||||
BackendError lld_link_target(TargetLinkConfig* config) {
|
BackendError lld_link_target(TargetLinkConfig* config) {
|
||||||
BackendError err = SUCCESS;
|
BackendError err = SUCCESS;
|
||||||
|
|
||||||
char*
|
|
||||||
|
|
||||||
for (guint i = 0; i < config->object_file_names->len; i++) {
|
|
||||||
const char* path = g_array_index(config->object_file_names, const char*, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -248,7 +248,7 @@ BackendError impl_transmute(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope,
|
||||||
LLVMValueRef operand = NULL;
|
LLVMValueRef operand = NULL;
|
||||||
LLVMTypeRef target_type = NULL;
|
LLVMTypeRef target_type = NULL;
|
||||||
BackendError err = get_type_impl(unit, scope->func_scope->global_scope,
|
BackendError err = get_type_impl(unit, scope->func_scope->global_scope,
|
||||||
&transmute->targetType, &target_type);
|
transmute->targetType, &target_type);
|
||||||
// if target type is valid
|
// if target type is valid
|
||||||
if (err.kind == Success) {
|
if (err.kind == Success) {
|
||||||
*llvm_result =
|
*llvm_result =
|
||||||
|
@ -276,13 +276,13 @@ BackendError impl_typecast(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope,
|
||||||
LLVMValueRef operand = NULL;
|
LLVMValueRef operand = NULL;
|
||||||
LLVMTypeRef target_type = NULL;
|
LLVMTypeRef target_type = NULL;
|
||||||
BackendError err = get_type_impl(unit, scope->func_scope->global_scope,
|
BackendError err = get_type_impl(unit, scope->func_scope->global_scope,
|
||||||
&typecast->targetType, &target_type);
|
typecast->targetType, &target_type);
|
||||||
// if target type is valid
|
// if target type is valid
|
||||||
if (err.kind != Success) {
|
if (err.kind != Success) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMBool dst_signed = is_type_signed(&typecast->targetType);
|
LLVMBool dst_signed = is_type_signed(typecast->targetType);
|
||||||
// TODO: derive source type sign
|
// TODO: derive source type sign
|
||||||
const LLVMOpcode opcode =
|
const LLVMOpcode opcode =
|
||||||
LLVMGetCastOpcode(operand, 0, target_type, dst_signed);
|
LLVMGetCastOpcode(operand, 0, target_type, dst_signed);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <llvm/llvm-ir/func.h>
|
#include <llvm/llvm-ir/func.h>
|
||||||
#include <llvm/parser.h>
|
#include <llvm/parser.h>
|
||||||
#include <llvm/llvm-ir/types.h>
|
#include <llvm/llvm-ir/types.h>
|
||||||
|
#include <llvm/llvm-ir/stmt.h>
|
||||||
#include <set/types.h>
|
#include <set/types.h>
|
||||||
#include <sys/log.h>
|
#include <sys/log.h>
|
||||||
|
|
||||||
|
@ -46,18 +47,18 @@ LLVMValueRef get_variable(const LLVMLocalScope* scope, const char* name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
BackendError impl_param_type(LLVMBackendCompileUnit* unit,
|
BackendError impl_param_type(LLVMBackendCompileUnit* unit,
|
||||||
LLVMGlobalScope* scope, Paramer* param,
|
LLVMGlobalScope* scope, Parameter* param,
|
||||||
LLVMTypeRef* llvm_type) {
|
LLVMTypeRef* llvm_type) {
|
||||||
BackendError err = SUCCESS;
|
BackendError err = SUCCESS;
|
||||||
|
|
||||||
Type* gemstone_type = NULL;
|
Type* gemstone_type = NULL;
|
||||||
IO_Qualifier qualifier = In;
|
IO_Qualifier qualifier;
|
||||||
|
|
||||||
if (param->kind == ParameterDeclarationKind) {
|
if (param->kind == ParameterDeclarationKind) {
|
||||||
gemstone_type = ¶m->impl.declaration.type;
|
gemstone_type = param->impl.declaration.type;
|
||||||
qualifier = param->impl.declaration.qualifier;
|
qualifier = param->impl.declaration.qualifier;
|
||||||
} else {
|
} else {
|
||||||
gemstone_type = ¶m->impl.definiton.declaration.type;
|
gemstone_type = param->impl.definiton.declaration.type;
|
||||||
qualifier = param->impl.definiton.declaration.qualifier;
|
qualifier = param->impl.definiton.declaration.qualifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,11 +83,11 @@ BackendError impl_func_decl(LLVMBackendCompileUnit* unit,
|
||||||
DEBUG("implementing function declaration: %s()", name);
|
DEBUG("implementing function declaration: %s()", name);
|
||||||
BackendError err = SUCCESS;
|
BackendError err = SUCCESS;
|
||||||
|
|
||||||
Paramer* params = (Paramer*)fundef->parameter;
|
Parameter* params = (Parameter*)fundef->parameter;
|
||||||
GArray* llvm_params = g_array_new(FALSE, FALSE, sizeof(LLVMTypeRef));
|
GArray* llvm_params = g_array_new(FALSE, FALSE, sizeof(LLVMTypeRef));
|
||||||
|
|
||||||
for (size_t i = 0; i < fundef->parameter->len; i++) {
|
for (size_t i = 0; i < fundef->parameter->len; i++) {
|
||||||
Paramer* param = ¶ms[i];
|
Parameter* param = ¶ms[i];
|
||||||
|
|
||||||
LLVMTypeRef llvm_type = NULL;
|
LLVMTypeRef llvm_type = NULL;
|
||||||
err = impl_param_type(unit, scope, param, &llvm_type);
|
err = impl_param_type(unit, scope, param, &llvm_type);
|
||||||
|
@ -138,12 +139,12 @@ BackendError impl_func(LLVMBackendCompileUnit* unit,
|
||||||
// create value references for parameter
|
// create value references for parameter
|
||||||
const size_t params = fundef->parameter->len;
|
const size_t params = fundef->parameter->len;
|
||||||
for (size_t i = 0; i < params; i++) {
|
for (size_t i = 0; i < params; i++) {
|
||||||
const Paramer* param = ((Paramer*)fundef->parameter) + i;
|
const Parameter* param = ((Parameter*)fundef->parameter) + i;
|
||||||
g_hash_table_insert(func_scope->params, (gpointer)param->name,
|
g_hash_table_insert(func_scope->params, (gpointer)param->name,
|
||||||
LLVMGetParam(llvm_func, i));
|
LLVMGetParam(llvm_func, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: parse function body
|
err = impl_block(unit, builder, func_scope, fundef->body);
|
||||||
|
|
||||||
LLVMDisposeBuilder(builder);
|
LLVMDisposeBuilder(builder);
|
||||||
|
|
||||||
|
@ -165,7 +166,7 @@ BackendError impl_functions(LLVMBackendCompileUnit* unit,
|
||||||
|
|
||||||
BackendError err = SUCCESS;
|
BackendError err = SUCCESS;
|
||||||
|
|
||||||
size_t variable_count = 0;
|
size_t function_count = 0;
|
||||||
while (g_hash_table_iter_next(&iterator, &key, &val) != FALSE) {
|
while (g_hash_table_iter_next(&iterator, &key, &val) != FALSE) {
|
||||||
err =
|
err =
|
||||||
impl_func(unit, scope, (FunctionDefinition*)val, (const char*)key);
|
impl_func(unit, scope, (FunctionDefinition*)val, (const char*)key);
|
||||||
|
@ -174,8 +175,9 @@ BackendError impl_functions(LLVMBackendCompileUnit* unit,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
variable_count++;
|
function_count++;
|
||||||
}
|
}
|
||||||
|
INFO("implemented %ld functions", function_count);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,22 +8,31 @@
|
||||||
#include <llvm/llvm-ir/stmt.h>
|
#include <llvm/llvm-ir/stmt.h>
|
||||||
#include <llvm/llvm-ir/expr.h>
|
#include <llvm/llvm-ir/expr.h>
|
||||||
#include <llvm/llvm-ir/func.h>
|
#include <llvm/llvm-ir/func.h>
|
||||||
|
#include <llvm/llvm-ir/types.h>
|
||||||
|
|
||||||
BackendError impl_assign_stmt([[maybe_unused]] LLVMBackendCompileUnit *unit,
|
BackendError impl_assign_stmt(
|
||||||
const LLVMBuilderRef builder, const LLVMLocalScope *scope,
|
LLVMBackendCompileUnit *unit,
|
||||||
const Assignment *assignment) {
|
LLVMBuilderRef
|
||||||
|
builder,
|
||||||
|
LLVMLocalScope *scope,
|
||||||
|
const Assignment *assignment
|
||||||
|
) {
|
||||||
BackendError err = SUCCESS;
|
BackendError err = SUCCESS;
|
||||||
DEBUG("implementing assignment for variabel: %s", assignment->variable->name);
|
DEBUG("implementing assignment for variable: %s", assignment->variable->name);
|
||||||
|
|
||||||
// TODO: resolve expression to LLVMValueRef
|
LLVMValueRef llvm_value = NULL;
|
||||||
const LLVMValueRef llvm_value = NULL;
|
err = impl_expr(unit, scope, builder, assignment->value, &llvm_value);
|
||||||
|
if (err.kind != Success) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
switch (assignment->variable->kind) {
|
switch (assignment->variable->kind) {
|
||||||
case VariableKindDeclaration:
|
case VariableKindDeclaration:
|
||||||
case VariableKindDefinition:
|
case VariableKindDefinition:
|
||||||
const LLVMValueRef llvm_ptr =
|
LLVMValueRef llvm_ptr =
|
||||||
get_variable(scope, assignment->variable->name);
|
get_variable(scope, assignment->variable->name);
|
||||||
LLVMBuildStore(builder, llvm_value, llvm_ptr);
|
LLVMBuildStore(builder, llvm_value, llvm_ptr
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case VariableKindBoxMember:
|
case VariableKindBoxMember:
|
||||||
// TODO: resolve LLVMValueRef from BoxAccess
|
// TODO: resolve LLVMValueRef from BoxAccess
|
||||||
|
@ -45,10 +54,8 @@ BackendError impl_basic_block(LLVMBackendCompileUnit *unit,
|
||||||
LLVMPositionBuilderAtEnd(builder, *llvm_block);
|
LLVMPositionBuilderAtEnd(builder, *llvm_block);
|
||||||
|
|
||||||
for (size_t i = 0; i < block->statemnts->len; i++) {
|
for (size_t i = 0; i < block->statemnts->len; i++) {
|
||||||
[[maybe_unused]]
|
|
||||||
Statement *stmt = ((Statement *) block->statemnts->data) + i;
|
Statement *stmt = ((Statement *) block->statemnts->data) + i;
|
||||||
|
impl_stmt(unit, builder, scope, stmt);
|
||||||
// TODO: implement statement
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_local_scope(block_scope);
|
delete_local_scope(block_scope);
|
||||||
|
@ -88,6 +95,19 @@ BackendError impl_while(LLVMBackendCompileUnit *unit,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean is_parameter_out(Parameter *param) {
|
||||||
|
gboolean is_out = FALSE;
|
||||||
|
|
||||||
|
if (param->kind == ParameterDeclarationKind) {
|
||||||
|
is_out = param->impl.declaration.qualifier == Out || param->impl.declaration.qualifier == InOut;
|
||||||
|
} else {
|
||||||
|
is_out = param->impl.definiton.declaration.qualifier == Out ||
|
||||||
|
param->impl.definiton.declaration.qualifier == InOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_out;
|
||||||
|
}
|
||||||
|
|
||||||
BackendError impl_func_call(LLVMBackendCompileUnit *unit,
|
BackendError impl_func_call(LLVMBackendCompileUnit *unit,
|
||||||
LLVMBuilderRef builder, LLVMLocalScope *scope,
|
LLVMBuilderRef builder, LLVMLocalScope *scope,
|
||||||
const FunctionCall *call) {
|
const FunctionCall *call) {
|
||||||
|
@ -104,9 +124,12 @@ BackendError impl_func_call(LLVMBackendCompileUnit *unit,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[maybe_unused]]
|
Parameter *parameter = g_array_index(call->function->parameter, Parameter*, i);
|
||||||
Paramer* parameter = (Paramer*) call->function->parameter->data + i;
|
|
||||||
// TODO: create a pointer to LLVMValueRef in case parameter is `out`
|
if (is_parameter_out(parameter)) {
|
||||||
|
LLVMValueRef zero = LLVMConstInt(LLVMInt32TypeInContext(unit->context), 0, 0);
|
||||||
|
llvm_arg = LLVMBuildGEP2(builder, LLVMTypeOf(llvm_arg), llvm_arg, &zero, 1, "");
|
||||||
|
}
|
||||||
|
|
||||||
g_array_append_vals(arguments, &llvm_arg, 1);
|
g_array_append_vals(arguments, &llvm_arg, 1);
|
||||||
}
|
}
|
||||||
|
@ -157,7 +180,8 @@ BackendError impl_branch(LLVMBackendCompileUnit *unit,
|
||||||
LLVMBasicBlockRef body_block = NULL;
|
LLVMBasicBlockRef body_block = NULL;
|
||||||
LLVMValueRef cond_value = NULL;
|
LLVMValueRef cond_value = NULL;
|
||||||
|
|
||||||
err = impl_cond_block(unit, builder, scope, (Expression*) &branch->ifBranch.conditon, &branch->ifBranch.block, &cond_block,
|
err = impl_cond_block(unit, builder, scope, (Expression *) &branch->ifBranch.conditon, &branch->ifBranch.block,
|
||||||
|
&cond_block,
|
||||||
&body_block, &cond_value);
|
&body_block, &cond_value);
|
||||||
|
|
||||||
g_array_append_val(cond_blocks, cond_block);
|
g_array_append_val(cond_blocks, cond_block);
|
||||||
|
@ -173,7 +197,7 @@ BackendError impl_branch(LLVMBackendCompileUnit *unit,
|
||||||
|
|
||||||
ElseIf *elseIf = ((ElseIf *) branch->elseIfBranches->data) + i;
|
ElseIf *elseIf = ((ElseIf *) branch->elseIfBranches->data) + i;
|
||||||
|
|
||||||
err = impl_cond_block(unit, builder, scope, &elseIf->conditon, &elseIf->block, &cond_block,
|
err = impl_cond_block(unit, builder, scope, elseIf->conditon, &elseIf->block, &cond_block,
|
||||||
&body_block, &cond_value);
|
&body_block, &cond_value);
|
||||||
|
|
||||||
g_array_append_val(cond_blocks, cond_block);
|
g_array_append_val(cond_blocks, cond_block);
|
||||||
|
@ -217,7 +241,128 @@ BackendError impl_branch(LLVMBackendCompileUnit *unit,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
BackendError impl_stmt([[maybe_unused]] LLVMBackendCompileUnit *unit, [[maybe_unused]] Statement *stmt) {
|
BackendError impl_decl(LLVMBackendCompileUnit *unit,
|
||||||
// TODO: implement
|
LLVMBuilderRef builder,
|
||||||
return SUCCESS;
|
LLVMLocalScope *scope,
|
||||||
|
VariableDeclaration *decl,
|
||||||
|
const char *name) {
|
||||||
|
DEBUG("implementing local declaration: %s", name);
|
||||||
|
BackendError err = SUCCESS;
|
||||||
|
LLVMTypeRef llvm_type = NULL;
|
||||||
|
err = get_type_impl(unit, scope->func_scope->global_scope, decl->type, &llvm_type);
|
||||||
|
|
||||||
|
if (err.kind != Success) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG("creating local variable...");
|
||||||
|
LLVMValueRef local = LLVMBuildAlloca(builder, llvm_type, name);
|
||||||
|
|
||||||
|
LLVMValueRef initial_value = NULL;
|
||||||
|
err = get_type_default_value(unit, scope->func_scope->global_scope, decl->type, &initial_value);
|
||||||
|
|
||||||
|
if (err.kind == Success) {
|
||||||
|
DEBUG("setting default value...");
|
||||||
|
LLVMBuildStore(builder, initial_value, local);
|
||||||
|
g_hash_table_insert(scope->vars, (gpointer) name, local);
|
||||||
|
} else {
|
||||||
|
ERROR("unable to initialize local variable: %s", err.impl.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_def(LLVMBackendCompileUnit *unit,
|
||||||
|
LLVMBuilderRef builder,
|
||||||
|
LLVMLocalScope *scope,
|
||||||
|
VariableDefiniton *def,
|
||||||
|
const char *name) {
|
||||||
|
DEBUG("implementing local definition: %s", name);
|
||||||
|
BackendError err = SUCCESS;
|
||||||
|
LLVMTypeRef llvm_type = NULL;
|
||||||
|
err = get_type_impl(unit, scope->func_scope->global_scope, def->declaration.type, &llvm_type);
|
||||||
|
|
||||||
|
if (err.kind != Success) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLVMValueRef initial_value = NULL;
|
||||||
|
err = impl_expr(unit, scope, builder, def->initializer, &initial_value);
|
||||||
|
if (err.kind != Success) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG("creating local variable...");
|
||||||
|
LLVMValueRef local = LLVMBuildAlloca(builder, llvm_type, name);
|
||||||
|
|
||||||
|
DEBUG("setting default value");
|
||||||
|
LLVMBuildStore(builder, initial_value, local);
|
||||||
|
g_hash_table_insert(scope->vars, (gpointer) name, local);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_var(LLVMBackendCompileUnit *unit,
|
||||||
|
LLVMBuilderRef builder,
|
||||||
|
LLVMLocalScope *scope,
|
||||||
|
Variable *var) {
|
||||||
|
BackendError err;
|
||||||
|
|
||||||
|
switch (var->kind) {
|
||||||
|
VariableKindDeclaration:
|
||||||
|
err = impl_decl(unit, builder, scope, &var->impl.declaration, var->name);
|
||||||
|
break;
|
||||||
|
VariableKindDefinition:
|
||||||
|
err = impl_def(unit, builder, scope, &var->impl.definiton, var->name);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err = new_backend_impl_error(Implementation, NULL, "Unexpected variable kind in statement");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_stmt(LLVMBackendCompileUnit *unit, LLVMBuilderRef builder, LLVMLocalScope *scope, Statement *stmt) {
|
||||||
|
BackendError err;
|
||||||
|
|
||||||
|
switch (stmt->kind) {
|
||||||
|
StatementKindAssignment:
|
||||||
|
err = impl_assign_stmt(unit, builder, scope, &stmt->impl.assignment);
|
||||||
|
break;
|
||||||
|
StatementKindBranch:
|
||||||
|
err = impl_branch(unit, builder, scope, &stmt->impl.branch);
|
||||||
|
break;
|
||||||
|
StatementKindDeclaration:
|
||||||
|
StatementKindDefinition:
|
||||||
|
err = impl_var(unit, builder, scope, stmt->impl.variable);
|
||||||
|
break;
|
||||||
|
StatementKindWhile:
|
||||||
|
err = impl_while(unit, builder, scope, &stmt->impl.whileLoop);
|
||||||
|
break;
|
||||||
|
StatementKindFunctionCall:
|
||||||
|
err = impl_func_call(unit, builder, scope, &stmt->impl.call);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err = new_backend_impl_error(Implementation, NULL, "Unexpected statement kind");
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_block(LLVMBackendCompileUnit *unit,
|
||||||
|
LLVMBuilderRef builder, LLVMFuncScope *scope,
|
||||||
|
const Block *block) {
|
||||||
|
BackendError err = SUCCESS;
|
||||||
|
|
||||||
|
LLVMLocalScope *function_entry_scope = malloc(sizeof(LLVMLocalScope));
|
||||||
|
function_entry_scope->func_scope = scope;
|
||||||
|
function_entry_scope->vars = g_hash_table_new(g_str_hash, g_str_equal);
|
||||||
|
function_entry_scope->parent_scope = NULL;
|
||||||
|
|
||||||
|
LLVMBasicBlockRef llvm_block = NULL;
|
||||||
|
err = impl_basic_block(unit, builder, function_entry_scope, block, &llvm_block);
|
||||||
|
|
||||||
|
delete_local_scope(function_entry_scope);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,5 +5,12 @@
|
||||||
#ifndef LLVM_BACKEND_STMT_H
|
#ifndef LLVM_BACKEND_STMT_H
|
||||||
#define LLVM_BACKEND_STMT_H
|
#define LLVM_BACKEND_STMT_H
|
||||||
|
|
||||||
|
#include <llvm/llvm-ir/func.h>
|
||||||
|
|
||||||
|
BackendError impl_block(LLVMBackendCompileUnit *unit,
|
||||||
|
LLVMBuilderRef builder, LLVMFuncScope *scope,
|
||||||
|
const Block *block);
|
||||||
|
|
||||||
|
BackendError impl_stmt(LLVMBackendCompileUnit *unit, LLVMBuilderRef builder, LLVMLocalScope *scope, Statement *stmt);
|
||||||
|
|
||||||
#endif // LLVM_BACKEND_STMT_H
|
#endif // LLVM_BACKEND_STMT_H
|
||||||
|
|
|
@ -41,19 +41,19 @@ BackendError get_const_type_value(LLVMBackendCompileUnit* unit,
|
||||||
Implementation, gemstone_value->nodePtr, "No default value for type");
|
Implementation, gemstone_value->nodePtr, "No default value for type");
|
||||||
|
|
||||||
LLVMTypeRef llvm_type = NULL;
|
LLVMTypeRef llvm_type = NULL;
|
||||||
err = get_type_impl(unit, scope, &gemstone_value->type, &llvm_type);
|
err = get_type_impl(unit, scope, gemstone_value->type, &llvm_type);
|
||||||
if (err.kind != Success) {
|
if (err.kind != Success) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (gemstone_value->type.kind) {
|
switch (gemstone_value->type->kind) {
|
||||||
case TypeKindPrimitive:
|
case TypeKindPrimitive:
|
||||||
err = get_const_primitive_value(gemstone_value->type.impl.primitive,
|
err = get_const_primitive_value(gemstone_value->type->impl.primitive,
|
||||||
llvm_type, gemstone_value->value,
|
llvm_type, gemstone_value->value,
|
||||||
llvm_value);
|
llvm_value);
|
||||||
break;
|
break;
|
||||||
case TypeKindComposite:
|
case TypeKindComposite:
|
||||||
err = get_const_composite_value(gemstone_value->type.impl.composite,
|
err = get_const_composite_value(gemstone_value->type->impl.composite,
|
||||||
llvm_type, gemstone_value->value,
|
llvm_type, gemstone_value->value,
|
||||||
llvm_value);
|
llvm_value);
|
||||||
break;
|
break;
|
||||||
|
@ -68,7 +68,7 @@ BackendError get_const_type_value(LLVMBackendCompileUnit* unit,
|
||||||
"boxes cannot be constant value");
|
"boxes cannot be constant value");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PANIC("invalid value kind: %ld", gemstone_value->type.kind);
|
PANIC("invalid value kind: %ld", gemstone_value->type->kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -14,7 +14,7 @@ BackendError impl_global_declaration(LLVMBackendCompileUnit* unit,
|
||||||
DEBUG("implementing global declaration: %s", 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);
|
||||||
|
|
||||||
if (err.kind != Success) {
|
if (err.kind != Success) {
|
||||||
return err;
|
return err;
|
||||||
|
@ -24,7 +24,7 @@ BackendError impl_global_declaration(LLVMBackendCompileUnit* unit,
|
||||||
LLVMValueRef global = LLVMAddGlobal(unit->module, llvm_type, name);
|
LLVMValueRef global = LLVMAddGlobal(unit->module, llvm_type, name);
|
||||||
|
|
||||||
LLVMValueRef initial_value = NULL;
|
LLVMValueRef initial_value = NULL;
|
||||||
err = get_type_default_value(unit, scope, &decl->type, &initial_value);
|
err = get_type_default_value(unit, scope, decl->type, &initial_value);
|
||||||
|
|
||||||
if (err.kind == Success) {
|
if (err.kind == Success) {
|
||||||
DEBUG("setting default value...");
|
DEBUG("setting default value...");
|
||||||
|
@ -43,7 +43,7 @@ BackendError impl_global_definiton(LLVMBackendCompileUnit* unit,
|
||||||
DEBUG("implementing global definition: %s", name);
|
DEBUG("implementing global definition: %s", name);
|
||||||
BackendError err = SUCCESS;
|
BackendError err = SUCCESS;
|
||||||
LLVMTypeRef llvm_type = NULL;
|
LLVMTypeRef llvm_type = NULL;
|
||||||
err = get_type_impl(unit, scope, &def->declaration.type, &llvm_type);
|
err = get_type_impl(unit, scope, def->declaration.type, &llvm_type);
|
||||||
|
|
||||||
if (err.kind != Success) {
|
if (err.kind != Success) {
|
||||||
return err;
|
return err;
|
||||||
|
@ -54,7 +54,7 @@ BackendError impl_global_definiton(LLVMBackendCompileUnit* unit,
|
||||||
|
|
||||||
// FIXME: resolve initializer expression!
|
// FIXME: resolve initializer expression!
|
||||||
LLVMValueRef initial_value = NULL;
|
LLVMValueRef initial_value = NULL;
|
||||||
err = get_type_default_value(unit, scope, &def->declaration.type,
|
err = get_type_default_value(unit, scope, def->declaration.type,
|
||||||
&initial_value);
|
&initial_value);
|
||||||
|
|
||||||
if (err.kind == Success) {
|
if (err.kind == Success) {
|
||||||
|
@ -87,7 +87,6 @@ BackendError impl_global_variable(LLVMBackendCompileUnit* unit,
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PANIC("invalid variable kind: %ld", gemstone_var->kind);
|
PANIC("invalid variable kind: %ld", gemstone_var->kind);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -243,7 +243,7 @@ BackendError parse_module(const Module* module, const TargetConfig* config) {
|
||||||
|
|
||||||
export_module(unit, &target, config);
|
export_module(unit, &target, config);
|
||||||
|
|
||||||
TargetLinkConfig* link_config = lld_create_link_config(&target, target, module);
|
TargetLinkConfig* link_config = lld_create_link_config(&target, config, module);
|
||||||
|
|
||||||
lld_link_target(link_config);
|
lld_link_target(link_config);
|
||||||
|
|
||||||
|
|
113
src/set/types.h
113
src/set/types.h
|
@ -5,15 +5,18 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <ast/ast.h>
|
#include <ast/ast.h>
|
||||||
|
|
||||||
|
// with of primitive types (int/float) in bytes
|
||||||
|
#define BASE_BYTES 4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Primitive types form the basis of all other types.
|
* @brief Primitive types form the basis of all other types.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef enum PrimitiveType_t {
|
typedef enum PrimitiveType_t {
|
||||||
// 4 byte signed integer in two's complement
|
// 4 byte signed integer in two's complement
|
||||||
Int,
|
Int =0,
|
||||||
// 4 byte IEEE-754 single precision
|
// 4 byte IEEE-754 single precision
|
||||||
Float
|
Float =1
|
||||||
} PrimitiveType;
|
} PrimitiveType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,10 +24,10 @@ typedef enum PrimitiveType_t {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef enum Sign_t {
|
typedef enum Sign_t {
|
||||||
// type has a sign bit
|
|
||||||
Signed,
|
|
||||||
// type has no sign bit
|
// type has no sign bit
|
||||||
Unsigned
|
Unsigned = 0,
|
||||||
|
// type has a sign bit
|
||||||
|
Signed = 1
|
||||||
} Sign;
|
} Sign;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,7 +39,7 @@ typedef enum Sign_t {
|
||||||
typedef double Scale;
|
typedef double Scale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A composite type is an extended definiton of a primitive type.
|
* @brief A composite type is an extended definition of a primitive type.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct CompositeType_t {
|
typedef struct CompositeType_t {
|
||||||
|
@ -69,10 +72,15 @@ typedef Type* ReferenceType;
|
||||||
|
|
||||||
typedef struct BoxType_t BoxType;
|
typedef struct BoxType_t BoxType;
|
||||||
|
|
||||||
|
typedef struct Block_t Block;
|
||||||
|
|
||||||
|
typedef struct Expression_t Expression;
|
||||||
|
|
||||||
typedef struct BoxMember_t {
|
typedef struct BoxMember_t {
|
||||||
const char* name;
|
const char* name;
|
||||||
Type* type;
|
Type* type;
|
||||||
BoxType* box;
|
BoxType* box;
|
||||||
|
Expression* initalizer;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} BoxMember;
|
} BoxMember;
|
||||||
|
|
||||||
|
@ -83,7 +91,7 @@ typedef struct BoxMember_t {
|
||||||
typedef struct BoxType_t {
|
typedef struct BoxType_t {
|
||||||
// hashtable of members.
|
// hashtable of members.
|
||||||
// Associates the memebers name (const char*) with its type (BoxMember)
|
// Associates the memebers name (const char*) with its type (BoxMember)
|
||||||
GHashTable* member;
|
GHashTable* member; //BoxMember Pointer
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} BoxType;
|
} BoxType;
|
||||||
|
|
||||||
|
@ -93,6 +101,8 @@ typedef struct BoxAccess_t {
|
||||||
// list of recursive box accesses
|
// list of recursive box accesses
|
||||||
// contains a list of BoxMembers (each specifying their own type, name and box type)
|
// contains a list of BoxMembers (each specifying their own type, name and box type)
|
||||||
GArray* member;
|
GArray* member;
|
||||||
|
// box variable to access
|
||||||
|
Variable* variable;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} BoxAccess;
|
} BoxAccess;
|
||||||
|
|
||||||
|
@ -112,19 +122,19 @@ typedef struct Type_t {
|
||||||
|
|
||||||
typedef struct Typedefine_t {
|
typedef struct Typedefine_t {
|
||||||
const char* name;
|
const char* name;
|
||||||
Type type;
|
Type *type;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} Typedefine;
|
} Typedefine;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reprents the value of type. Can be used to definitons, initialization and for expressions contants.
|
* @brief Reprents the value of type. Can be used to definitions, initialization and for expressions contants.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct TypeValue_t {
|
typedef struct TypeValue_t {
|
||||||
// the type
|
// the type
|
||||||
Type type;
|
Type *type;
|
||||||
// UTF-8 representation of the type's value
|
// UTF-8 representation of the type's value
|
||||||
const char* value;
|
const char* value;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
|
@ -155,7 +165,7 @@ typedef enum IO_Qualifier_t {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct ParameterDeclaration_t {
|
typedef struct ParameterDeclaration_t {
|
||||||
Type type;
|
Type *type;
|
||||||
IO_Qualifier qualifier;
|
IO_Qualifier qualifier;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} ParameterDeclaration;
|
} ParameterDeclaration;
|
||||||
|
@ -168,7 +178,7 @@ typedef struct ParameterDefinition_t {
|
||||||
ParameterDeclaration declaration;
|
ParameterDeclaration declaration;
|
||||||
// value to initalize the declaration with
|
// value to initalize the declaration with
|
||||||
// NOTE: type of initializer and declaration MUST be equal
|
// NOTE: type of initializer and declaration MUST be equal
|
||||||
TypeValue initializer;
|
Expression *initializer;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} ParameterDefinition;
|
} ParameterDefinition;
|
||||||
|
|
||||||
|
@ -178,26 +188,54 @@ typedef enum ParameterKind_t {
|
||||||
} ParameterKind;
|
} ParameterKind;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A parameter can either be a declaration or a definiton
|
* @brief A parameter can either be a declaration or a definition
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct Parameter_t {
|
typedef struct Parameter_t {
|
||||||
const char* name;
|
const char* name;
|
||||||
|
|
||||||
ParameterKind kind;
|
ParameterKind kind;
|
||||||
union ParameterImplementation {
|
union ParameterImplementation {
|
||||||
ParameterDeclaration declaration;
|
ParameterDeclaration declaration;
|
||||||
ParameterDefinition definiton;
|
ParameterDefinition definiton;
|
||||||
} impl;
|
} impl;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} Paramer;
|
} Parameter; // fix typo
|
||||||
|
|
||||||
|
typedef enum FunctionKind_t {
|
||||||
|
FunctionDeclarationKind,
|
||||||
|
FunctionDefinitionKind
|
||||||
|
} FunctionKind;
|
||||||
|
|
||||||
typedef struct FunctionDefinition_t {
|
typedef struct FunctionDefinition_t {
|
||||||
// hashtable of parameters
|
// hashtable of parameters
|
||||||
// associates a parameters name (const char*) with its parameter declaration (ParameterDeclaration)
|
// associates a parameters name (const char*) with its parameter declaration (ParameterDeclaration)
|
||||||
GArray* parameter;
|
GArray* parameter; // Parameter
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
|
// body of function
|
||||||
|
Block *body;
|
||||||
|
// name of function
|
||||||
|
const char* name;
|
||||||
} FunctionDefinition;
|
} FunctionDefinition;
|
||||||
|
|
||||||
|
typedef struct FunctionDeclaration_t {
|
||||||
|
// hashtable of parameters
|
||||||
|
// associates a parameters name (const char*) with its parameter declaration (ParameterDeclaration)
|
||||||
|
GArray* parameter; // Parameter
|
||||||
|
AST_NODE_PTR nodePtr;
|
||||||
|
const char* name;
|
||||||
|
} FunctionDeclaration;
|
||||||
|
|
||||||
|
typedef struct Function_t {
|
||||||
|
FunctionKind kind;
|
||||||
|
union FunctionImplementation {
|
||||||
|
FunctionDefinition definition;
|
||||||
|
FunctionDeclaration declaration;
|
||||||
|
} impl;
|
||||||
|
AST_NODE_PTR nodePtr;
|
||||||
|
const char * name;
|
||||||
|
} Function;
|
||||||
|
|
||||||
// .------------------------------------------------.
|
// .------------------------------------------------.
|
||||||
// | Variables |
|
// | Variables |
|
||||||
// '------------------------------------------------'
|
// '------------------------------------------------'
|
||||||
|
@ -210,19 +248,19 @@ typedef enum StorageQualifier_t {
|
||||||
|
|
||||||
typedef struct VariableDeclaration_t {
|
typedef struct VariableDeclaration_t {
|
||||||
StorageQualifier qualifier;
|
StorageQualifier qualifier;
|
||||||
Type type;
|
Type *type;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} VariableDeclaration;
|
} VariableDeclaration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Definiton of a variable
|
* @brief Definition of a variable
|
||||||
*
|
*
|
||||||
* @attention NOTE: The types of the initializer and the declaration must be equal
|
* @attention NOTE: The types of the initializer and the declaration must be equal
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct VariableDefiniton_t {
|
typedef struct VariableDefiniton_t {
|
||||||
VariableDeclaration declaration;
|
VariableDeclaration declaration;
|
||||||
TypeValue initializer;
|
Expression *initializer;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} VariableDefiniton;
|
} VariableDefiniton;
|
||||||
|
|
||||||
|
@ -238,7 +276,7 @@ typedef struct Variable_t {
|
||||||
union VariableImplementation {
|
union VariableImplementation {
|
||||||
VariableDeclaration declaration;
|
VariableDeclaration declaration;
|
||||||
VariableDefiniton definiton;
|
VariableDefiniton definiton;
|
||||||
BoxMember member;
|
BoxAccess member;
|
||||||
} impl;
|
} impl;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} Variable;
|
} Variable;
|
||||||
|
@ -257,7 +295,8 @@ typedef struct Variable_t {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct TypeCast_t {
|
typedef struct TypeCast_t {
|
||||||
Type targetType;
|
Type *targetType;
|
||||||
|
Expression* operand;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} TypeCast;
|
} TypeCast;
|
||||||
|
|
||||||
|
@ -269,7 +308,8 @@ typedef struct TypeCast_t {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct Transmute_t {
|
typedef struct Transmute_t {
|
||||||
Type targetType;
|
Type *targetType;
|
||||||
|
Expression* operand;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} Transmute;
|
} Transmute;
|
||||||
|
|
||||||
|
@ -285,7 +325,8 @@ typedef enum ArithmeticOperator_t {
|
||||||
Add,
|
Add,
|
||||||
Sub,
|
Sub,
|
||||||
Mul,
|
Mul,
|
||||||
Div
|
Div,
|
||||||
|
Negate
|
||||||
} ArithmeticOperator;
|
} ArithmeticOperator;
|
||||||
|
|
||||||
// .------------------------------------------------.
|
// .------------------------------------------------.
|
||||||
|
@ -358,6 +399,7 @@ typedef struct Operation_t {
|
||||||
LogicalOperator logical;
|
LogicalOperator logical;
|
||||||
BitwiseOperator bitwise;
|
BitwiseOperator bitwise;
|
||||||
} impl;
|
} impl;
|
||||||
|
GArray* operands; //Expression*
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} Operation;
|
} Operation;
|
||||||
|
|
||||||
|
@ -369,17 +411,20 @@ typedef enum ExpressionKind_t {
|
||||||
ExpressionKindOperation,
|
ExpressionKindOperation,
|
||||||
ExpressionKindTypeCast,
|
ExpressionKindTypeCast,
|
||||||
ExpressionKindTransmute,
|
ExpressionKindTransmute,
|
||||||
ExpressionKindConstant
|
ExpressionKindConstant,
|
||||||
|
ExpressionKindVariable
|
||||||
} ExpressionKind;
|
} ExpressionKind;
|
||||||
|
|
||||||
typedef struct Expression_t {
|
typedef struct Expression_t {
|
||||||
ExpressionKind kind;
|
ExpressionKind kind;
|
||||||
|
// type of resulting data
|
||||||
|
Type* result;
|
||||||
union ExpressionImplementation_t {
|
union ExpressionImplementation_t {
|
||||||
Operation operation;
|
Operation operation;
|
||||||
TypeCast typecast;
|
TypeCast typecast;
|
||||||
Transmute transmute;
|
Transmute transmute;
|
||||||
TypeValue constant;
|
TypeValue constant;
|
||||||
Variable variable;
|
Variable* variable;
|
||||||
} impl;
|
} impl;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} Expression;
|
} Expression;
|
||||||
|
@ -409,7 +454,7 @@ typedef struct FunctionBoxCall_t {
|
||||||
|
|
||||||
typedef struct Block_t {
|
typedef struct Block_t {
|
||||||
// array of statements
|
// array of statements
|
||||||
GArray* statemnts;
|
GArray* statemnts; // array of type(Statement)
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} Block;
|
} Block;
|
||||||
|
|
||||||
|
@ -418,7 +463,7 @@ typedef struct Block_t {
|
||||||
// '------------------------------------------------'
|
// '------------------------------------------------'
|
||||||
|
|
||||||
typedef struct While_t {
|
typedef struct While_t {
|
||||||
Expression conditon;
|
Expression *conditon;
|
||||||
Block block;
|
Block block;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} While;
|
} While;
|
||||||
|
@ -428,13 +473,13 @@ typedef struct While_t {
|
||||||
// '------------------------------------------------'
|
// '------------------------------------------------'
|
||||||
|
|
||||||
typedef struct If_t {
|
typedef struct If_t {
|
||||||
Expression conditon;
|
Expression *conditon;
|
||||||
Block block;
|
Block block;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} If;
|
} If;
|
||||||
|
|
||||||
typedef struct ElseIf_t {
|
typedef struct ElseIf_t {
|
||||||
Expression conditon;
|
Expression *conditon;
|
||||||
Block block;
|
Block block;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} ElseIf;
|
} ElseIf;
|
||||||
|
@ -458,7 +503,7 @@ typedef struct Branch_t {
|
||||||
|
|
||||||
typedef struct Assignment_t {
|
typedef struct Assignment_t {
|
||||||
Variable* variable;
|
Variable* variable;
|
||||||
Expression value;
|
Expression* value;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} Assignment;
|
} Assignment;
|
||||||
|
|
||||||
|
@ -467,16 +512,20 @@ typedef enum StatementKind_t {
|
||||||
StatementKindFunctionBoxCall,
|
StatementKindFunctionBoxCall,
|
||||||
StatementKindWhile,
|
StatementKindWhile,
|
||||||
StatementKindBranch,
|
StatementKindBranch,
|
||||||
StatementKindAssignment
|
StatementKindAssignment,
|
||||||
|
StatementKindDeclaration,
|
||||||
|
StatementKindDefinition
|
||||||
} StatementKind;
|
} StatementKind;
|
||||||
|
|
||||||
typedef struct Statement_t {
|
typedef struct Statement_t {
|
||||||
|
StatementKind kind;
|
||||||
union StatementImplementation {
|
union StatementImplementation {
|
||||||
FunctionCall call;
|
FunctionCall call;
|
||||||
FunctionBoxCall boxCall;
|
FunctionBoxCall boxCall;
|
||||||
While whileLoop;
|
While whileLoop;
|
||||||
Branch branch;
|
Branch branch;
|
||||||
Assignment assignment;
|
Assignment assignment;
|
||||||
|
Variable *variable;
|
||||||
} impl;
|
} impl;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} Statement;
|
} Statement;
|
||||||
|
@ -486,8 +535,8 @@ typedef struct Statement_t {
|
||||||
// '------------------------------------------------'
|
// '------------------------------------------------'
|
||||||
|
|
||||||
typedef struct Module_t {
|
typedef struct Module_t {
|
||||||
GHashTable* boxes;
|
GHashTable* boxes; //BoxType
|
||||||
GHashTable* types;
|
GHashTable* types; //
|
||||||
GHashTable* functions;
|
GHashTable* functions;
|
||||||
GHashTable* variables;
|
GHashTable* variables;
|
||||||
// to be resolved after the module has been parsed completely
|
// to be resolved after the module has been parsed completely
|
||||||
|
|
Loading…
Reference in New Issue