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

View File

@ -248,7 +248,7 @@ BackendError impl_transmute(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope,
LLVMValueRef operand = NULL;
LLVMTypeRef target_type = NULL;
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 (err.kind == Success) {
*llvm_result =
@ -276,13 +276,13 @@ BackendError impl_typecast(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope,
LLVMValueRef operand = NULL;
LLVMTypeRef target_type = NULL;
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 (err.kind != Success) {
return err;
}
LLVMBool dst_signed = is_type_signed(&typecast->targetType);
LLVMBool dst_signed = is_type_signed(typecast->targetType);
// TODO: derive source type sign
const LLVMOpcode opcode =
LLVMGetCastOpcode(operand, 0, target_type, dst_signed);

View File

@ -6,6 +6,7 @@
#include <llvm/llvm-ir/func.h>
#include <llvm/parser.h>
#include <llvm/llvm-ir/types.h>
#include <llvm/llvm-ir/stmt.h>
#include <set/types.h>
#include <sys/log.h>
@ -46,18 +47,18 @@ LLVMValueRef get_variable(const LLVMLocalScope* scope, const char* name) {
}
BackendError impl_param_type(LLVMBackendCompileUnit* unit,
LLVMGlobalScope* scope, Paramer* param,
LLVMGlobalScope* scope, Parameter* param,
LLVMTypeRef* llvm_type) {
BackendError err = SUCCESS;
Type* gemstone_type = NULL;
IO_Qualifier qualifier = In;
IO_Qualifier qualifier;
if (param->kind == ParameterDeclarationKind) {
gemstone_type = &param->impl.declaration.type;
gemstone_type = param->impl.declaration.type;
qualifier = param->impl.declaration.qualifier;
} else {
gemstone_type = &param->impl.definiton.declaration.type;
gemstone_type = param->impl.definiton.declaration.type;
qualifier = param->impl.definiton.declaration.qualifier;
}
@ -82,11 +83,11 @@ BackendError impl_func_decl(LLVMBackendCompileUnit* unit,
DEBUG("implementing function declaration: %s()", name);
BackendError err = SUCCESS;
Paramer* params = (Paramer*)fundef->parameter;
Parameter* params = (Parameter*)fundef->parameter;
GArray* llvm_params = g_array_new(FALSE, FALSE, sizeof(LLVMTypeRef));
for (size_t i = 0; i < fundef->parameter->len; i++) {
Paramer* param = &params[i];
Parameter* param = &params[i];
LLVMTypeRef llvm_type = NULL;
err = impl_param_type(unit, scope, param, &llvm_type);
@ -138,12 +139,12 @@ BackendError impl_func(LLVMBackendCompileUnit* unit,
// create value references for parameter
const size_t params = fundef->parameter->len;
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,
LLVMGetParam(llvm_func, i));
}
// TODO: parse function body
err = impl_block(unit, builder, func_scope, fundef->body);
LLVMDisposeBuilder(builder);
@ -165,7 +166,7 @@ BackendError impl_functions(LLVMBackendCompileUnit* unit,
BackendError err = SUCCESS;
size_t variable_count = 0;
size_t function_count = 0;
while (g_hash_table_iter_next(&iterator, &key, &val) != FALSE) {
err =
impl_func(unit, scope, (FunctionDefinition*)val, (const char*)key);
@ -174,8 +175,9 @@ BackendError impl_functions(LLVMBackendCompileUnit* unit,
break;
}
variable_count++;
function_count++;
}
INFO("implemented %ld functions", function_count);
return err;
}

View File

@ -8,22 +8,31 @@
#include <llvm/llvm-ir/stmt.h>
#include <llvm/llvm-ir/expr.h>
#include <llvm/llvm-ir/func.h>
#include <llvm/llvm-ir/types.h>
BackendError impl_assign_stmt([[maybe_unused]] LLVMBackendCompileUnit *unit,
const LLVMBuilderRef builder, const LLVMLocalScope *scope,
const Assignment *assignment) {
BackendError impl_assign_stmt(
LLVMBackendCompileUnit *unit,
LLVMBuilderRef
builder,
LLVMLocalScope *scope,
const Assignment *assignment
) {
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
const LLVMValueRef llvm_value = NULL;
LLVMValueRef llvm_value = NULL;
err = impl_expr(unit, scope, builder, assignment->value, &llvm_value);
if (err.kind != Success) {
return err;
}
switch (assignment->variable->kind) {
case VariableKindDeclaration:
case VariableKindDefinition:
const LLVMValueRef llvm_ptr =
LLVMValueRef llvm_ptr =
get_variable(scope, assignment->variable->name);
LLVMBuildStore(builder, llvm_value, llvm_ptr);
LLVMBuildStore(builder, llvm_value, llvm_ptr
);
break;
case VariableKindBoxMember:
// TODO: resolve LLVMValueRef from BoxAccess
@ -45,10 +54,8 @@ BackendError impl_basic_block(LLVMBackendCompileUnit *unit,
LLVMPositionBuilderAtEnd(builder, *llvm_block);
for (size_t i = 0; i < block->statemnts->len; i++) {
[[maybe_unused]]
Statement *stmt = ((Statement *) block->statemnts->data) + i;
// TODO: implement statement
impl_stmt(unit, builder, scope, stmt);
}
delete_local_scope(block_scope);
@ -67,7 +74,7 @@ BackendError impl_while(LLVMBackendCompileUnit *unit,
LLVMPositionBuilderAtEnd(builder, while_cond_block);
// Resolve condition in block to a variable
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
LLVMBasicBlockRef while_body_block = NULL;
@ -88,6 +95,19 @@ BackendError impl_while(LLVMBackendCompileUnit *unit,
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,
LLVMBuilderRef builder, LLVMLocalScope *scope,
const FunctionCall *call) {
@ -104,9 +124,12 @@ BackendError impl_func_call(LLVMBackendCompileUnit *unit,
break;
}
[[maybe_unused]]
Paramer* parameter = (Paramer*) call->function->parameter->data + i;
// TODO: create a pointer to LLVMValueRef in case parameter is `out`
Parameter *parameter = g_array_index(call->function->parameter, Parameter*, i);
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);
}
@ -157,7 +180,8 @@ BackendError impl_branch(LLVMBackendCompileUnit *unit,
LLVMBasicBlockRef body_block = 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);
g_array_append_val(cond_blocks, cond_block);
@ -173,7 +197,7 @@ BackendError impl_branch(LLVMBackendCompileUnit *unit,
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);
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++) {
LLVMBasicBlockRef next_block = ((LLVMBasicBlockRef*) cond_blocks->data)[i + 1];
LLVMBasicBlockRef cond_block = ((LLVMBasicBlockRef*) cond_blocks->data)[i];
LLVMBasicBlockRef body_block = ((LLVMBasicBlockRef*) body_blocks->data)[i];
LLVMValueRef cond_value = ((LLVMValueRef*) cond_values->data)[i];
LLVMBasicBlockRef next_block = ((LLVMBasicBlockRef *) cond_blocks->data)[i + 1];
LLVMBasicBlockRef cond_block = ((LLVMBasicBlockRef *) cond_blocks->data)[i];
LLVMBasicBlockRef body_block = ((LLVMBasicBlockRef *) body_blocks->data)[i];
LLVMValueRef cond_value = ((LLVMValueRef *) cond_values->data)[i];
LLVMPositionBuilderAtEnd(builder, cond_block);
LLVMBuildCondBr(builder, cond_value, body_block, next_block);
@ -217,7 +241,128 @@ BackendError impl_branch(LLVMBackendCompileUnit *unit,
return err;
}
BackendError impl_stmt([[maybe_unused]] LLVMBackendCompileUnit *unit, [[maybe_unused]] Statement *stmt) {
// TODO: implement
return SUCCESS;
BackendError impl_decl(LLVMBackendCompileUnit *unit,
LLVMBuilderRef builder,
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
#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

View File

@ -41,19 +41,19 @@ BackendError get_const_type_value(LLVMBackendCompileUnit* unit,
Implementation, gemstone_value->nodePtr, "No default value for type");
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) {
return err;
}
switch (gemstone_value->type.kind) {
switch (gemstone_value->type->kind) {
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_value);
break;
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_value);
break;
@ -68,7 +68,7 @@ BackendError get_const_type_value(LLVMBackendCompileUnit* unit,
"boxes cannot be constant value");
break;
default:
PANIC("invalid value kind: %ld", gemstone_value->type.kind);
PANIC("invalid value kind: %ld", gemstone_value->type->kind);
}
return err;

View File

@ -14,7 +14,7 @@ BackendError impl_global_declaration(LLVMBackendCompileUnit* unit,
DEBUG("implementing global declaration: %s", name);
BackendError err = SUCCESS;
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) {
return err;
@ -24,7 +24,7 @@ BackendError impl_global_declaration(LLVMBackendCompileUnit* unit,
LLVMValueRef global = LLVMAddGlobal(unit->module, llvm_type, name);
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) {
DEBUG("setting default value...");
@ -43,7 +43,7 @@ BackendError impl_global_definiton(LLVMBackendCompileUnit* unit,
DEBUG("implementing global definition: %s", name);
BackendError err = SUCCESS;
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) {
return err;
@ -54,7 +54,7 @@ BackendError impl_global_definiton(LLVMBackendCompileUnit* unit,
// FIXME: resolve initializer expression!
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);
if (err.kind == Success) {
@ -87,7 +87,6 @@ BackendError impl_global_variable(LLVMBackendCompileUnit* unit,
break;
default:
PANIC("invalid variable kind: %ld", gemstone_var->kind);
break;
}
return err;

View File

@ -243,7 +243,7 @@ BackendError parse_module(const Module* module, const TargetConfig* 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);

View File

@ -5,15 +5,18 @@
#include <glib.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.
*
*/
typedef enum PrimitiveType_t {
// 4 byte signed integer in two's complement
Int,
Int =0,
// 4 byte IEEE-754 single precision
Float
Float =1
} PrimitiveType;
/**
@ -21,10 +24,10 @@ typedef enum PrimitiveType_t {
*
*/
typedef enum Sign_t {
// type has a sign bit
Signed,
// type has no sign bit
Unsigned
Unsigned = 0,
// type has a sign bit
Signed = 1
} Sign;
/**
@ -36,7 +39,7 @@ typedef enum Sign_t {
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 {
@ -69,21 +72,26 @@ typedef Type* ReferenceType;
typedef struct BoxType_t BoxType;
typedef struct Block_t Block;
typedef struct Expression_t Expression;
typedef struct BoxMember_t {
const char* name;
Type* type;
BoxType* box;
Expression* initalizer;
AST_NODE_PTR nodePtr;
} BoxMember;
/**
* @brief Essentially a glorified struct
* @brief Essentially a g lorified struct
*
*/
typedef struct BoxType_t {
// hashtable of members.
// Associates the memebers name (const char*) with its type (BoxMember)
GHashTable* member;
GHashTable* member; //BoxMember Pointer
AST_NODE_PTR nodePtr;
} BoxType;
@ -93,6 +101,8 @@ typedef struct BoxAccess_t {
// list of recursive box accesses
// contains a list of BoxMembers (each specifying their own type, name and box type)
GArray* member;
// box variable to access
Variable* variable;
AST_NODE_PTR nodePtr;
} BoxAccess;
@ -112,19 +122,19 @@ typedef struct Type_t {
typedef struct Typedefine_t {
const char* name;
Type type;
Type *type;
AST_NODE_PTR nodePtr;
} 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 {
// the type
Type type;
Type *type;
// UTF-8 representation of the type's value
const char* value;
AST_NODE_PTR nodePtr;
@ -155,7 +165,7 @@ typedef enum IO_Qualifier_t {
*
*/
typedef struct ParameterDeclaration_t {
Type type;
Type *type;
IO_Qualifier qualifier;
AST_NODE_PTR nodePtr;
} ParameterDeclaration;
@ -168,7 +178,7 @@ typedef struct ParameterDefinition_t {
ParameterDeclaration declaration;
// value to initalize the declaration with
// NOTE: type of initializer and declaration MUST be equal
TypeValue initializer;
Expression *initializer;
AST_NODE_PTR nodePtr;
} ParameterDefinition;
@ -178,26 +188,54 @@ typedef enum ParameterKind_t {
} 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 {
const char* name;
ParameterKind kind;
union ParameterImplementation {
ParameterDeclaration declaration;
ParameterDefinition definiton;
} impl;
AST_NODE_PTR nodePtr;
} Paramer;
} Parameter; // fix typo
typedef enum FunctionKind_t {
FunctionDeclarationKind,
FunctionDefinitionKind
} FunctionKind;
typedef struct FunctionDefinition_t {
// hashtable of parameters
// associates a parameters name (const char*) with its parameter declaration (ParameterDeclaration)
GArray* parameter;
GArray* parameter; // Parameter
AST_NODE_PTR nodePtr;
// body of function
Block *body;
// name of function
const char* name;
} 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 |
// '------------------------------------------------'
@ -210,19 +248,19 @@ typedef enum StorageQualifier_t {
typedef struct VariableDeclaration_t {
StorageQualifier qualifier;
Type type;
Type *type;
AST_NODE_PTR nodePtr;
} VariableDeclaration;
/**
* @brief Definiton of a variable
* @brief Definition of a variable
*
* @attention NOTE: The types of the initializer and the declaration must be equal
*
*/
typedef struct VariableDefiniton_t {
VariableDeclaration declaration;
TypeValue initializer;
Expression *initializer;
AST_NODE_PTR nodePtr;
} VariableDefiniton;
@ -238,7 +276,7 @@ typedef struct Variable_t {
union VariableImplementation {
VariableDeclaration declaration;
VariableDefiniton definiton;
BoxMember member;
BoxAccess member;
} impl;
AST_NODE_PTR nodePtr;
} Variable;
@ -257,7 +295,8 @@ typedef struct Variable_t {
*
*/
typedef struct TypeCast_t {
Type targetType;
Type *targetType;
Expression* operand;
AST_NODE_PTR nodePtr;
} TypeCast;
@ -269,7 +308,8 @@ typedef struct TypeCast_t {
*
*/
typedef struct Transmute_t {
Type targetType;
Type *targetType;
Expression* operand;
AST_NODE_PTR nodePtr;
} Transmute;
@ -285,7 +325,8 @@ typedef enum ArithmeticOperator_t {
Add,
Sub,
Mul,
Div
Div,
Negate
} ArithmeticOperator;
// .------------------------------------------------.
@ -358,6 +399,7 @@ typedef struct Operation_t {
LogicalOperator logical;
BitwiseOperator bitwise;
} impl;
GArray* operands; //Expression*
AST_NODE_PTR nodePtr;
} Operation;
@ -369,17 +411,20 @@ typedef enum ExpressionKind_t {
ExpressionKindOperation,
ExpressionKindTypeCast,
ExpressionKindTransmute,
ExpressionKindConstant
ExpressionKindConstant,
ExpressionKindVariable
} ExpressionKind;
typedef struct Expression_t {
ExpressionKind kind;
// type of resulting data
Type* result;
union ExpressionImplementation_t {
Operation operation;
TypeCast typecast;
Transmute transmute;
TypeValue constant;
Variable variable;
Variable* variable;
} impl;
AST_NODE_PTR nodePtr;
} Expression;
@ -409,7 +454,7 @@ typedef struct FunctionBoxCall_t {
typedef struct Block_t {
// array of statements
GArray* statemnts;
GArray* statemnts; // array of type(Statement)
AST_NODE_PTR nodePtr;
} Block;
@ -418,7 +463,7 @@ typedef struct Block_t {
// '------------------------------------------------'
typedef struct While_t {
Expression conditon;
Expression *conditon;
Block block;
AST_NODE_PTR nodePtr;
} While;
@ -428,13 +473,13 @@ typedef struct While_t {
// '------------------------------------------------'
typedef struct If_t {
Expression conditon;
Expression *conditon;
Block block;
AST_NODE_PTR nodePtr;
} If;
typedef struct ElseIf_t {
Expression conditon;
Expression *conditon;
Block block;
AST_NODE_PTR nodePtr;
} ElseIf;
@ -458,7 +503,7 @@ typedef struct Branch_t {
typedef struct Assignment_t {
Variable* variable;
Expression value;
Expression* value;
AST_NODE_PTR nodePtr;
} Assignment;
@ -467,16 +512,20 @@ typedef enum StatementKind_t {
StatementKindFunctionBoxCall,
StatementKindWhile,
StatementKindBranch,
StatementKindAssignment
StatementKindAssignment,
StatementKindDeclaration,
StatementKindDefinition
} StatementKind;
typedef struct Statement_t {
StatementKind kind;
union StatementImplementation {
FunctionCall call;
FunctionBoxCall boxCall;
While whileLoop;
Branch branch;
Assignment assignment;
Variable *variable;
} impl;
AST_NODE_PTR nodePtr;
} Statement;
@ -486,8 +535,8 @@ typedef struct Statement_t {
// '------------------------------------------------'
typedef struct Module_t {
GHashTable* boxes;
GHashTable* types;
GHashTable* boxes; //BoxType
GHashTable* types; //
GHashTable* functions;
GHashTable* variables;
// to be resolved after the module has been parsed completely