diff --git a/src/llvm/link/lld.c b/src/llvm/link/lld.c index 62b5e65..7aa5be4 100644 --- a/src/llvm/link/lld.c +++ b/src/llvm/link/lld.c @@ -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; } diff --git a/src/llvm/llvm-ir/expr.c b/src/llvm/llvm-ir/expr.c index 6896ce1..771b471 100644 --- a/src/llvm/llvm-ir/expr.c +++ b/src/llvm/llvm-ir/expr.c @@ -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); diff --git a/src/llvm/llvm-ir/func.c b/src/llvm/llvm-ir/func.c index 107b697..5fa251e 100644 --- a/src/llvm/llvm-ir/func.c +++ b/src/llvm/llvm-ir/func.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -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 = ¶m->impl.declaration.type; + gemstone_type = param->impl.declaration.type; qualifier = param->impl.declaration.qualifier; } else { - gemstone_type = ¶m->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 = ¶ms[i]; + Parameter* param = ¶ms[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; } diff --git a/src/llvm/llvm-ir/stmt.c b/src/llvm/llvm-ir/stmt.c index 8692168..189636b 100644 --- a/src/llvm/llvm-ir/stmt.c +++ b/src/llvm/llvm-ir/stmt.c @@ -8,22 +8,31 @@ #include #include #include +#include -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; } diff --git a/src/llvm/llvm-ir/stmt.h b/src/llvm/llvm-ir/stmt.h index bde984d..a20c27c 100644 --- a/src/llvm/llvm-ir/stmt.h +++ b/src/llvm/llvm-ir/stmt.h @@ -5,5 +5,12 @@ #ifndef LLVM_BACKEND_STMT_H #define LLVM_BACKEND_STMT_H +#include + +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 diff --git a/src/llvm/llvm-ir/types.c b/src/llvm/llvm-ir/types.c index 3e4892d..9b241c4 100644 --- a/src/llvm/llvm-ir/types.c +++ b/src/llvm/llvm-ir/types.c @@ -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; diff --git a/src/llvm/llvm-ir/variables.c b/src/llvm/llvm-ir/variables.c index 595dd35..05465d7 100644 --- a/src/llvm/llvm-ir/variables.c +++ b/src/llvm/llvm-ir/variables.c @@ -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; diff --git a/src/llvm/parser.c b/src/llvm/parser.c index 05181d9..6cc1d21 100644 --- a/src/llvm/parser.c +++ b/src/llvm/parser.c @@ -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); diff --git a/src/set/types.h b/src/set/types.h index 52744a1..b4744c9 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -5,39 +5,42 @@ #include #include +// 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; /** * @brief Represents the sign of a composite type. - * + * */ 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; /** * @brief Represents the scale of composite type which is multiplied * 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 } - * + * */ 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 { // sign of composite @@ -49,7 +52,7 @@ typedef struct CompositeType_t { /** * @brief Specifies the specific type of the generic type struct. - * + * */ typedef enum TypeKind_t { TypeKindPrimitive, @@ -63,27 +66,32 @@ typedef struct Type_t Type; /** * @brief Reference points to a type. * @attention Can be nested. A reference can point to another reference: REF -> REF -> REF -> Primitive - * + * */ 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; + // Associates the memebers name (const char*) with its type (BoxMember) + 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; @@ -136,7 +146,7 @@ typedef struct TypeValue_t { /** * @brief Specifies a parameters I/O properties - * + * */ typedef enum IO_Qualifier_t { // Can be read from but not written to. @@ -152,23 +162,23 @@ typedef enum IO_Qualifier_t { /** * @brief A functions parameter declaration. - * + * */ typedef struct ParameterDeclaration_t { - Type type; + Type *type; IO_Qualifier qualifier; AST_NODE_PTR nodePtr; } ParameterDeclaration; /** * @brief A functions parameter. - * + * */ 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; @@ -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 - * values information. + * values information. * * @attention NOTE: Must check wether the given value's type can be parsed into * 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 { - Type targetType; + Type *targetType; + Expression* operand; AST_NODE_PTR nodePtr; } 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. * Transmuting a short int into a float should yield an error. - * + * */ typedef struct Transmute_t { - Type targetType; + Type *targetType; + Expression* operand; AST_NODE_PTR nodePtr; } Transmute; @@ -279,13 +319,14 @@ typedef struct Transmute_t { /** * @brief Represents the arithmetic operator. - * + * */ typedef enum ArithmeticOperator_t { Add, Sub, Mul, - Div + Div, + Negate } ArithmeticOperator; // .------------------------------------------------. @@ -294,7 +335,7 @@ typedef enum ArithmeticOperator_t { /** * @brief Represents the relational operator. - * + * */ typedef enum RelationalOperator_t { Equal, @@ -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