added: new types.h

This commit is contained in:
Sven Vogel 2024-06-08 16:14:24 +02:00
parent bd368f99ef
commit 6e59b7ac73
9 changed files with 303 additions and 107 deletions

View File

@ -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;
} }

View File

@ -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);

View File

@ -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 = &param->impl.declaration.type; gemstone_type = param->impl.declaration.type;
qualifier = param->impl.declaration.qualifier; qualifier = param->impl.declaration.qualifier;
} else { } else {
gemstone_type = &param->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 = &params[i]; Parameter* param = &params[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;
} }

View File

@ -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);
@ -67,7 +74,7 @@ BackendError impl_while(LLVMBackendCompileUnit *unit,
LLVMPositionBuilderAtEnd(builder, while_cond_block); LLVMPositionBuilderAtEnd(builder, while_cond_block);
// Resolve condition in block to a variable // Resolve condition in block to a variable
LLVMValueRef cond_result = NULL; LLVMValueRef cond_result = NULL;
impl_expr(unit, scope, builder, (Expression*) &while_stmt->conditon, &cond_result); impl_expr(unit, scope, builder, (Expression *) &while_stmt->conditon, &cond_result);
// build body of loop // build body of loop
LLVMBasicBlockRef while_body_block = NULL; LLVMBasicBlockRef while_body_block = NULL;
@ -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);
@ -198,10 +222,10 @@ BackendError impl_branch(LLVMBackendCompileUnit *unit,
} }
for (size_t i = 0; i < cond_blocks->len - 1; i++) { for (size_t i = 0; i < cond_blocks->len - 1; i++) {
LLVMBasicBlockRef next_block = ((LLVMBasicBlockRef*) cond_blocks->data)[i + 1]; LLVMBasicBlockRef next_block = ((LLVMBasicBlockRef *) cond_blocks->data)[i + 1];
LLVMBasicBlockRef cond_block = ((LLVMBasicBlockRef*) cond_blocks->data)[i]; LLVMBasicBlockRef cond_block = ((LLVMBasicBlockRef *) cond_blocks->data)[i];
LLVMBasicBlockRef body_block = ((LLVMBasicBlockRef*) body_blocks->data)[i]; LLVMBasicBlockRef body_block = ((LLVMBasicBlockRef *) body_blocks->data)[i];
LLVMValueRef cond_value = ((LLVMValueRef*) cond_values->data)[i]; LLVMValueRef cond_value = ((LLVMValueRef *) cond_values->data)[i];
LLVMPositionBuilderAtEnd(builder, cond_block); LLVMPositionBuilderAtEnd(builder, cond_block);
LLVMBuildCondBr(builder, cond_value, body_block, next_block); LLVMBuildCondBr(builder, cond_value, body_block, next_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;
} }

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -5,39 +5,42 @@
#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;
/** /**
* @brief Represents the sign of a composite type. * @brief Represents the sign of a composite type.
* *
*/ */
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;
/** /**
* @brief Represents the scale of composite type which is multiplied * @brief Represents the scale of composite type which is multiplied
* with the base size in order to retrieve the the composites size. * with the base size in order to retrieve the the composites size.
* @attention Valid value are: { 1/8, 1/4, 1/2, 1, 2, 4, 8 } * @attention Valid value are: { 1/8, 1/4, 1/2, 1, 2, 4, 8 }
* *
*/ */
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 {
// sign of composite // sign of composite
@ -49,7 +52,7 @@ typedef struct CompositeType_t {
/** /**
* @brief Specifies the specific type of the generic type struct. * @brief Specifies the specific type of the generic type struct.
* *
*/ */
typedef enum TypeKind_t { typedef enum TypeKind_t {
TypeKindPrimitive, TypeKindPrimitive,
@ -63,27 +66,32 @@ typedef struct Type_t Type;
/** /**
* @brief Reference points to a type. * @brief Reference points to a type.
* @attention Can be nested. A reference can point to another reference: REF -> REF -> REF -> Primitive * @attention Can be nested. A reference can point to another reference: REF -> REF -> REF -> Primitive
* *
*/ */
typedef Type* ReferenceType; 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;
/** /**
* @brief Essentially a glorified struct * @brief Essentially a g lorified struct
* *
*/ */
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;
@ -136,7 +146,7 @@ typedef struct TypeValue_t {
/** /**
* @brief Specifies a parameters I/O properties * @brief Specifies a parameters I/O properties
* *
*/ */
typedef enum IO_Qualifier_t { typedef enum IO_Qualifier_t {
// Can be read from but not written to. // Can be read from but not written to.
@ -152,23 +162,23 @@ typedef enum IO_Qualifier_t {
/** /**
* @brief A functions parameter declaration. * @brief A functions parameter declaration.
* *
*/ */
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;
/** /**
* @brief A functions parameter. * @brief A functions parameter.
* *
*/ */
typedef struct ParameterDefinition_t { 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;
@ -249,15 +287,16 @@ typedef struct Variable_t {
/** /**
* @brief Perform a type cast, converting a value to different type whilest preserving as much of the original * @brief Perform a type cast, converting a value to different type whilest preserving as much of the original
* values information. * values information.
* *
* @attention NOTE: Must check wether the given value's type can be parsed into * @attention NOTE: Must check wether the given value's type can be parsed into
* the target type without loss. * the target type without loss.
* Lossy mean possibly loosing information such when casting a float into an int (no fraction anymore). * Lossy mean possibly loosing information such when casting a float into an int (no fraction anymore).
* *
*/ */
typedef struct TypeCast_t { typedef struct TypeCast_t {
Type targetType; Type *targetType;
Expression* operand;
AST_NODE_PTR nodePtr; AST_NODE_PTR nodePtr;
} TypeCast; } TypeCast;
@ -266,10 +305,11 @@ typedef struct TypeCast_t {
* *
* @attention NOTE: The given value's type must have the size in bytes as the target type. * @attention NOTE: The given value's type must have the size in bytes as the target type.
* Transmuting a short int into a float should yield an error. * Transmuting a short int into a float should yield an error.
* *
*/ */
typedef struct Transmute_t { typedef struct Transmute_t {
Type targetType; Type *targetType;
Expression* operand;
AST_NODE_PTR nodePtr; AST_NODE_PTR nodePtr;
} Transmute; } Transmute;
@ -279,13 +319,14 @@ typedef struct Transmute_t {
/** /**
* @brief Represents the arithmetic operator. * @brief Represents the arithmetic operator.
* *
*/ */
typedef enum ArithmeticOperator_t { typedef enum ArithmeticOperator_t {
Add, Add,
Sub, Sub,
Mul, Mul,
Div Div,
Negate
} ArithmeticOperator; } ArithmeticOperator;
// .------------------------------------------------. // .------------------------------------------------.
@ -294,7 +335,7 @@ typedef enum ArithmeticOperator_t {
/** /**
* @brief Represents the relational operator. * @brief Represents the relational operator.
* *
*/ */
typedef enum RelationalOperator_t { typedef enum RelationalOperator_t {
Equal, Equal,
@ -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