From 150f87990a87944de2b9d8fc6bc9eba115c51315 Mon Sep 17 00:00:00 2001 From: servostar Date: Sat, 8 Jun 2024 14:55:40 +0200 Subject: [PATCH] fixed: memory leaks added: memory cache for GLIB arrays and hashtables --- src/cfg/opt.c | 10 +- src/compiler.c | 4 +- src/main.c | 2 +- src/mem/cache.c | 102 +++- src/mem/cache.h | 5 + src/set/set.c | 1412 +++++++++++++++++++++-------------------------- src/set/types.c | 186 ------- 7 files changed, 741 insertions(+), 980 deletions(-) delete mode 100644 src/set/types.c diff --git a/src/cfg/opt.c b/src/cfg/opt.c index 9829cb2..cd1033f 100644 --- a/src/cfg/opt.c +++ b/src/cfg/opt.c @@ -179,11 +179,11 @@ void print_help(void) { " --mode=[app|lib] set the compilation mode to either application or library", " --output=name name of output files without extension", "Options:", - " --verbose print logs with level information or higher", - " --debug print debug logs (if not disabled at compile time)", - " --version print the version", - " --help print this hel dialog", - " --print-memory-stats print statistics of the garbage collector" + " --verbose print logs with level information or higher", + " --debug print debug logs (if not disabled at compile time)", + " --version print the version", + " --help print this hel dialog", + " --print-gc-stats print statistics of the garbage collector" }; for (unsigned int i = 0; i < sizeof(lines) / sizeof(const char *); i++) { diff --git a/src/compiler.c b/src/compiler.c index 68fd6e1..699dff1 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -142,12 +142,10 @@ static void build_target(ModuleFileStack *unit, const TargetConfig *target) { if (setup_target_environment(target) == 0) { print_ast_to_file(ast, target); - Module * test = create_set(ast); + Module* test = create_set(ast); // TODO: parse AST to semantic values // TODO: backend codegen - - delete_set(test); } } diff --git a/src/main.c b/src/main.c index b987a6a..3cdcdf0 100644 --- a/src/main.c +++ b/src/main.c @@ -60,7 +60,7 @@ int main(int argc, char *argv[]) { run_compiler(); - if (is_option_set("print-memory-stats")) { + if (is_option_set("print-gc-stats")) { print_memory_statistics(); } diff --git a/src/mem/cache.c b/src/mem/cache.c index c7e9a38..0b35f4d 100644 --- a/src/mem/cache.c +++ b/src/mem/cache.c @@ -7,6 +7,7 @@ #include #include #include +#include static GHashTable* namespaces = NULL; @@ -20,6 +21,17 @@ typedef struct MemoryNamespaceStatistic_t { size_t purged_free_count; } MemoryNamespaceStatistic; +typedef enum MemoryBlockType_t { + GenericBlock, + GLIB_Array, + GLIB_HashTable +} MemoryBlockType; + +typedef struct MemoryBlock_t { + void* block_ptr; + MemoryBlockType kind; +} MemoryBlock; + typedef struct MemoryNamespace_t { MemoryNamespaceStatistic statistic; GArray* blocks; @@ -44,9 +56,11 @@ static void* namespace_malloc(MemoryNamespaceRef memoryNamespace, size_t size) { assert(memoryNamespace != NULL); assert(size != 0); - void* block = malloc(size); + MemoryBlock block; + block.block_ptr = malloc(size); + block.kind = GenericBlock; - if (block == NULL) { + if (block.block_ptr == NULL) { memoryNamespace->statistic.faulty_allocations ++; } else { g_array_append_val(memoryNamespace->blocks, block); @@ -55,20 +69,36 @@ static void* namespace_malloc(MemoryNamespaceRef memoryNamespace, size_t size) { memoryNamespace->statistic.bytes_allocated += size; } - return block; + return block.block_ptr; +} + +static void namespace_free_block(MemoryBlock block) { + switch (block.kind) { + case GenericBlock: + free(block.block_ptr); + break; + case GLIB_Array: + g_array_free(block.block_ptr, TRUE); + break; + case GLIB_HashTable: + g_hash_table_destroy(block.block_ptr); + break; + } } static gboolean namespace_free(MemoryNamespaceRef memoryNamespace, void* block) { for (guint i = 0; i < memoryNamespace->blocks->len; i++) { - void* current_block = g_array_index(memoryNamespace->blocks, void*, i); + MemoryBlock current_block = g_array_index(memoryNamespace->blocks, MemoryBlock, i); - if (current_block == block) { + if (current_block.block_ptr == block) { assert(block != NULL); - free(block); + namespace_free_block(current_block); + g_array_remove_index(memoryNamespace->blocks, i); memoryNamespace->statistic.manual_free_count++; + return TRUE; } } @@ -79,13 +109,13 @@ static void* namespace_realloc(MemoryNamespaceRef memoryNamespace, void* block, void* reallocated_block = NULL; for (guint i = 0; i < memoryNamespace->blocks->len; i++) { - void* current_block = g_array_index(memoryNamespace->blocks, void*, i); + MemoryBlock current_block = g_array_index(memoryNamespace->blocks, MemoryBlock, i); - if (current_block == block) { - reallocated_block = realloc(block, size); + if (current_block.block_ptr == block) { + reallocated_block = realloc(current_block.block_ptr, size); if (reallocated_block != NULL) { - g_array_index(memoryNamespace->blocks, void*, i) = reallocated_block; + g_array_index(memoryNamespace->blocks, MemoryBlock, i).block_ptr = reallocated_block; memoryNamespace->statistic.bytes_allocated += size; memoryNamespace->statistic.reallocation_count ++; } else { @@ -107,9 +137,9 @@ static void namespace_delete(MemoryNamespaceRef memoryNamespace) { static void namespace_purge(MemoryNamespaceRef memoryNamespace) { for (guint i = 0; i < memoryNamespace->blocks->len; i++) { - void* current_block = g_array_index(memoryNamespace->blocks, void*, i); + MemoryBlock current_block = g_array_index(memoryNamespace->blocks, MemoryBlock, i); - free(current_block); + namespace_free_block(current_block); memoryNamespace->statistic.purged_free_count ++; } @@ -120,7 +150,7 @@ static void namespace_purge(MemoryNamespaceRef memoryNamespace) { static MemoryNamespaceRef namespace_new() { MemoryNamespaceRef memoryNamespace = malloc(sizeof(MemoryNamespace)); - memoryNamespace->blocks = g_array_new(FALSE, FALSE, sizeof(void*)); + memoryNamespace->blocks = g_array_new(FALSE, FALSE, sizeof(MemoryBlock)); memoryNamespace->statistic.bytes_allocated = 0; memoryNamespace->statistic.allocation_count = 0; memoryNamespace->statistic.manual_free_count = 0; @@ -132,6 +162,30 @@ static MemoryNamespaceRef namespace_new() { return memoryNamespace; } +GArray *namespace_new_g_array(MemoryNamespaceRef namespace, guint size) { + MemoryBlock block; + block.block_ptr = g_array_new(FALSE, FALSE, size); + block.kind = GLIB_Array; + + g_array_append_val(namespace->blocks, block); + namespace->statistic.bytes_allocated += sizeof(GArray*); + namespace->statistic.allocation_count ++; + + return block.block_ptr; +} + +GHashTable *namespace_new_g_hash_table(MemoryNamespaceRef namespace, GHashFunc hash_func, GEqualFunc key_equal_func) { + MemoryBlock block; + block.block_ptr = g_hash_table_new(hash_func, key_equal_func); + block.kind = GLIB_HashTable; + + g_array_append_val(namespace->blocks, block); + namespace->statistic.bytes_allocated += sizeof(GHashTable*); + namespace->statistic.allocation_count ++; + + return block.block_ptr; +} + static void cleanup() { if (namespaces == NULL) { printf("==> Memory cache was unused <==\n"); @@ -267,5 +321,25 @@ void print_memory_statistics() { namespace_statistics_print(&total, "summary"); - printf("Note: untracked are memory allocations from external libraries.\n"); + printf("Note: untracked are memory allocations from external libraries and non-gc managed components.\n"); +} + +GArray* mem_new_g_array(MemoryNamespaceName name, guint element_size) { + MemoryNamespaceRef cache = check_namespace(name); + + if (cache == NULL) { + PANIC("memory namespace not created"); + } + + return namespace_new_g_array(cache, element_size); +} + +GHashTable* mem_new_g_hash_table(MemoryNamespaceName name, GHashFunc hash_func, GEqualFunc key_equal_func) { + MemoryNamespaceRef cache = check_namespace(name); + + if (cache == NULL) { + PANIC("memory namespace not created"); + } + + return namespace_new_g_hash_table(cache, hash_func, key_equal_func); } diff --git a/src/mem/cache.h b/src/mem/cache.h index d6ac067..2c5ddca 100644 --- a/src/mem/cache.h +++ b/src/mem/cache.h @@ -7,6 +7,7 @@ #include #include +#include typedef char* MemoryNamespaceName; @@ -86,4 +87,8 @@ void* mem_clone(MemoryNamespaceName name, void* data, size_t size); void print_memory_statistics(); +GArray* mem_new_g_array(MemoryNamespaceName name, guint element_size); + +GHashTable* mem_new_g_hash_table(MemoryNamespaceName name, GHashFunc hash_func, GEqualFunc key_equal_func); + #endif //GEMSTONE_CACHE_H diff --git a/src/set/set.c b/src/set/set.c index 4330c74..9a64070 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -1,10 +1,6 @@ #include -#include -#include -#include #include #include -#include #include #include #include @@ -12,132 +8,58 @@ #include #include -extern ModuleFile * current_file; +extern ModuleFile *current_file; static GHashTable *declaredComposites = NULL;//pointer to composites with names static GHashTable *declaredBoxes = NULL;//pointer to typeboxes static GHashTable *functionParameter = NULL; static GArray *Scope = NULL;//list of hashtables. last Hashtable is current depth of program. hashtable key: ident, value: Variable* to var -static void delete_declared_composites() { - if (declaredComposites == NULL) { - return; - } - - GHashTableIter iter; - char *name = NULL; - Type* type = NULL; - - g_hash_table_iter_init(&iter, declaredComposites); - - while (g_hash_table_iter_next(&iter, (gpointer)&name, (gpointer)&type)) { - delete_type(type); - mem_free(name); - } - - g_hash_table_destroy(declaredComposites); -} - -static void delete_declared_boxes() { - if (declaredBoxes == NULL) { - return; - } - - GHashTableIter iter; - char *name = NULL; - Type* type = NULL; - - g_hash_table_iter_init(&iter, declaredBoxes); - - while (g_hash_table_iter_next(&iter, (gpointer)&name, (gpointer)&type)) { - delete_type(type); - mem_free(name); - } - - g_hash_table_destroy(declaredBoxes); -} - -static void delete_scopes() { - if (Scope == NULL) { - return; - } - - for (guint i = 0; i < Scope->len; i++) { - GHashTable* scope = g_array_index(Scope, GHashTable*, i); - - GHashTableIter iter; - char *name = NULL; - Variable* variable = NULL; - - g_hash_table_iter_init(&iter, scope); - - while (g_hash_table_iter_next(&iter, (gpointer)&name, (gpointer)&variable)) { - delete_variable(variable); - mem_free(name); - } - - g_hash_table_destroy(scope); - } - - g_array_free(Scope, TRUE); -} - -void delete_set(Module* module) { - assert(module != NULL); - assert(declaredBoxes != NULL); - assert(declaredComposites != NULL); - assert(functionParameter != NULL); - - delete_module(module); - - delete_declared_composites(); - delete_declared_boxes(); - delete_scopes(); -} - const Type ShortShortUnsingedIntType = { - .kind = TypeKindComposite, - .impl = { - .composite = { - .sign = Unsigned, - .scale = 0.25, - .primitive = Int - } - }, - .nodePtr = NULL, + .kind = TypeKindComposite, + .impl = { + .composite = { + .sign = Unsigned, + .scale = 0.25, + .primitive = Int + } + }, + .nodePtr = NULL, }; const Type StringLiteralType = { - .kind = TypeKindReference, - .impl = { - .reference = (ReferenceType) &ShortShortUnsingedIntType, - }, - .nodePtr = NULL, + .kind = TypeKindReference, + .impl = { + .reference = (ReferenceType) &ShortShortUnsingedIntType, + }, + .nodePtr = NULL, }; /** * @brief Convert a string into a sign typ * @return 0 on success, 1 otherwise */ -int sign_from_string(const char* string, Sign* sign) { +int sign_from_string(const char *string, Sign *sign) { assert(string != NULL); assert(sign != NULL); if (strcmp(string, "unsigned") == 0) { *sign = Unsigned; - return 0; - } else if (strcmp(string, "signed") == 0) { - *sign = Signed; - return 0; + return SEMANTIC_OK; } - return 1; + if (strcmp(string, "signed") == 0) { + *sign = Signed; + return SEMANTIC_OK; + } + + return SEMANTIC_ERROR; } /** * @brief Convert a string into a primitive type * @return 0 on success, 1 otherwise */ -int primitive_from_string(const char* string, PrimitiveType* primitive) { +int primitive_from_string(const char *string, PrimitiveType *primitive) { assert(string != NULL); assert(primitive != NULL); DEBUG("find primitive in string"); @@ -155,7 +77,7 @@ int primitive_from_string(const char* string, PrimitiveType* primitive) { return SEMANTIC_ERROR; } -int scale_factor_from(const char* string, double* factor) { +int scale_factor_from(const char *string, double *factor) { assert(string != NULL); assert(factor != NULL); @@ -179,14 +101,16 @@ int check_scale_factor(AST_NODE_PTR node, Scale scale) { print_diagnostic(current_file, &node->location, Error, "Composite scale overflow"); return SEMANTIC_ERROR; } + if (0.25 > scale) { print_diagnostic(current_file, &node->location, Error, "Composite scale underflow"); return SEMANTIC_ERROR; } + return SEMANTIC_OK; } -int merge_scale_list(AST_NODE_PTR scale_list, Scale* scale) { +int merge_scale_list(AST_NODE_PTR scale_list, Scale *scale) { assert(scale_list != NULL); assert(scale != NULL); @@ -208,13 +132,13 @@ int merge_scale_list(AST_NODE_PTR scale_list, Scale* scale) { /** * @brief Get an already declared type from its name */ -int get_type_decl(const char* name, Type** type) { +int get_type_decl(const char *name, Type **type) { assert(name != NULL); assert(type != NULL); if (g_hash_table_contains(declaredComposites, name) == TRUE) { - *type = (Type*) g_hash_table_lookup(declaredComposites, name); + *type = (Type *) g_hash_table_lookup(declaredComposites, name); return SEMANTIC_OK; } @@ -222,7 +146,7 @@ int get_type_decl(const char* name, Type** type) { return SEMANTIC_ERROR; } -int impl_composite_type(AST_NODE_PTR ast_type, CompositeType* composite) { +int impl_composite_type(AST_NODE_PTR ast_type, CompositeType *composite) { assert(ast_type != NULL); assert(composite != NULL); @@ -230,7 +154,7 @@ int impl_composite_type(AST_NODE_PTR ast_type, CompositeType* composite) { int status = SEMANTIC_OK; int scaleNodeOffset = 0; - + composite->sign = Signed; // check if we have a sign @@ -250,7 +174,7 @@ int impl_composite_type(AST_NODE_PTR ast_type, CompositeType* composite) { // check if we have a list of scale factors if (ast_type->children[scaleNodeOffset]->kind == AST_List) { - + status = merge_scale_list(ast_type->children[scaleNodeOffset], &composite->scale); if (status == SEMANTIC_ERROR) { @@ -261,12 +185,12 @@ int impl_composite_type(AST_NODE_PTR ast_type, CompositeType* composite) { AST_NODE_PTR typeKind = ast_type->children[ast_type->child_count - 1]; status = primitive_from_string(typeKind->value, &composite->primitive); - + // type kind is not primitve, must be a predefined composite if (status == SEMANTIC_ERROR) { // not a primitive try to resolve the type by name (must be a composite) - Type* nested_type = NULL; + Type *nested_type = NULL; status = get_type_decl(typeKind->value, &nested_type); if (status == SEMANTIC_ERROR) { @@ -278,14 +202,14 @@ int impl_composite_type(AST_NODE_PTR ast_type, CompositeType* composite) { // valid composite type composite->primitive = nested_type->impl.composite.primitive; - + // no sign was set, use sign of type if (scaleNodeOffset == 0) { composite->sign = nested_type->impl.composite.sign; } composite->scale = composite->scale * nested_type->impl.composite.scale; - + } else { print_diagnostic(current_file, &typeKind->location, Error, "Type must be either composite or primitive"); return SEMANTIC_ERROR; @@ -301,7 +225,7 @@ int impl_composite_type(AST_NODE_PTR ast_type, CompositeType* composite) { * @param type pointer output for the type * @return the gemstone type implementation */ -int get_type_impl(AST_NODE_PTR currentNode, Type** type) { +int get_type_impl(AST_NODE_PTR currentNode, Type **type) { assert(currentNode != NULL); assert(currentNode->kind == AST_Type); assert(currentNode->child_count > 0); @@ -309,7 +233,7 @@ int get_type_impl(AST_NODE_PTR currentNode, Type** type) { int status; - const char *typekind = currentNode->children[currentNode->child_count -1]->value; + const char *typekind = currentNode->children[currentNode->child_count - 1]->value; if (g_hash_table_contains(declaredComposites, typekind) == TRUE) { *type = g_hash_table_lookup(declaredComposites, typekind); @@ -322,13 +246,13 @@ int get_type_impl(AST_NODE_PTR currentNode, Type** type) { } // type is not yet declared, make a new one - Type* new_type = mem_alloc(MemoryNamespaceSet,sizeof(Type)); + Type *new_type = mem_alloc(MemoryNamespaceSet, sizeof(Type)); new_type->nodePtr = currentNode; // only one child means either composite or primitive // try to implement primitive first // if not successfull continue building a composite - if(currentNode->child_count == 1) { + if (currentNode->child_count == 1) { // type is a primitive new_type->kind = TypeKindPrimitive; @@ -347,14 +271,12 @@ int get_type_impl(AST_NODE_PTR currentNode, Type** type) { status = impl_composite_type(currentNode, &new_type->impl.composite); *type = new_type; - - return status; } StorageQualifier Qualifier_from_string(const char *str) { assert(str != NULL); - + if (strcmp(str, "local") == 0) return Local; if (strcmp(str, "static") == 0) @@ -364,14 +286,15 @@ StorageQualifier Qualifier_from_string(const char *str) { PANIC("Provided string is not a storagequalifier: %s", str); } -int addVarToScope(Variable * variable); -int createDecl(AST_NODE_PTR currentNode, GArray** variables) { +int addVarToScope(Variable *variable); + +int createDecl(AST_NODE_PTR currentNode, GArray **variables) { DEBUG("create declaration"); AST_NODE_PTR ident_list = currentNode->children[currentNode->child_count - 1]; - *variables = g_array_new(FALSE, FALSE, sizeof(Variable*)); + *variables = mem_new_g_array(MemoryNamespaceSet, sizeof(Variable *)); VariableDeclaration decl; decl.nodePtr = currentNode; @@ -382,7 +305,7 @@ int createDecl(AST_NODE_PTR currentNode, GArray** variables) { DEBUG("Child Count: %i", currentNode->child_count); for (size_t i = 0; i < currentNode->child_count; i++) { - switch(currentNode->children[i]->kind){ + switch (currentNode->children[i]->kind) { case AST_Storage: DEBUG("fill Qualifier"); decl.qualifier = Qualifier_from_string(currentNode->children[i]->value); @@ -399,8 +322,8 @@ int createDecl(AST_NODE_PTR currentNode, GArray** variables) { } } - for(size_t i = 0; i < ident_list->child_count; i++) { - Variable* variable = mem_alloc(MemoryNamespaceSet,sizeof(Variable)); + for (size_t i = 0; i < ident_list->child_count; i++) { + Variable *variable = mem_alloc(MemoryNamespaceSet, sizeof(Variable)); variable->kind = VariableKindDeclaration; variable->nodePtr = currentNode; @@ -409,17 +332,17 @@ int createDecl(AST_NODE_PTR currentNode, GArray** variables) { g_array_append_val(*variables, variable); int signal = addVarToScope(variable); - if (signal){ + if (signal) { return SEMANTIC_ERROR; } } - + return status; } -Expression* createExpression(AST_NODE_PTR currentNode); +Expression *createExpression(AST_NODE_PTR currentNode); -int createDef(AST_NODE_PTR currentNode, GArray** variables) { +int createDef(AST_NODE_PTR currentNode, GArray **variables) { assert(variables != NULL); assert(currentNode != NULL); assert(currentNode->kind == AST_Def); @@ -430,8 +353,7 @@ int createDef(AST_NODE_PTR currentNode, GArray** variables) { AST_NODE_PTR expression = currentNode->children[1]; AST_NODE_PTR ident_list = declaration->children[currentNode->child_count - 1]; - - *variables = g_array_new(FALSE, FALSE, sizeof(Variable*)); + *variables = mem_new_g_array(MemoryNamespaceSet, sizeof(Variable *)); VariableDeclaration decl; VariableDefiniton def; @@ -442,8 +364,8 @@ int createDef(AST_NODE_PTR currentNode, GArray** variables) { int status = SEMANTIC_OK; DEBUG("Child Count: %i", declaration->child_count); - for (size_t i = 0; i < declaration->child_count; i++){ - switch(declaration->children[i]->kind) { + for (size_t i = 0; i < declaration->child_count; i++) { + switch (declaration->children[i]->kind) { case AST_Storage: DEBUG("fill Qualifier"); decl.qualifier = Qualifier_from_string(declaration->children[i]->value); @@ -457,27 +379,27 @@ int createDef(AST_NODE_PTR currentNode, GArray** variables) { default: PANIC("invalid node type: %ld", declaration->children[i]->kind); break; - } + } } def.declaration = decl; - Expression * name = createExpression(expression); - if (name == NULL){ + Expression *name = createExpression(expression); + if (name == NULL) { status = SEMANTIC_OK; } def.initializer = name; - - for(size_t i = 0; i < ident_list->child_count; i++) { - Variable* variable = mem_alloc(MemoryNamespaceSet,sizeof(Variable)); + for (size_t i = 0; i < ident_list->child_count; i++) { + Variable *variable = mem_alloc(MemoryNamespaceSet, sizeof(Variable)); variable->kind = VariableKindDefinition; variable->nodePtr = currentNode; variable->name = ident_list->children[i]->value; variable->impl.definiton = def; + g_array_append_val(*variables, variable); - int signal = addVarToScope(variable); - if (signal){ + + if (addVarToScope(variable) == SEMANTIC_ERROR) { return SEMANTIC_ERROR; } } @@ -485,39 +407,7 @@ int createDef(AST_NODE_PTR currentNode, GArray** variables) { return status; } -//int: a,b,c = 5 -// -//GArray.data: -// 1. Variable -// kind = VariableKindDefinition; -// name = a; -// impl.definition: -// initilizer: -// createExpression(...) -// decl: -// qulifier: -// type: -// pointer -// -// -// 2. Variable -// kind = VariableKindDefinition; -// name = b; -// impl.definition: -// initilizer: 5 -// decl: -// qulifier: -// type: -// pointer -// . -// . -// . -// - - - - -int getVariableFromScope(const char* name, Variable** variable) { +int getVariableFromScope(const char *name, Variable **variable) { assert(name != NULL); assert(variable != NULL); assert(Scope != NULL); @@ -525,73 +415,73 @@ int getVariableFromScope(const char* name, Variable** variable) { int found = 0; // loop through all variable scope and find a variable - if(functionParameter != NULL) { - if(g_hash_table_contains(functionParameter, name)) { + if (functionParameter != NULL) { + if (g_hash_table_contains(functionParameter, name)) { *variable = g_hash_table_lookup(functionParameter, name); found += 1; } } - for(size_t i = 0; i < Scope->len; i++) { + for (size_t i = 0; i < Scope->len; i++) { - GHashTable* variable_table = g_array_index(Scope,GHashTable* ,i ); - - if(g_hash_table_contains(variable_table, name)) { - if(found == 0){ - *variable = g_hash_table_lookup(variable_table, name); - } + GHashTable *variable_table = g_array_index(Scope, GHashTable*, i); + + if (g_hash_table_contains(variable_table, name)) { + if (found == 0) { + *variable = g_hash_table_lookup(variable_table, name); + } found += 1; } } - if (found == 1){ - DEBUG("Var: %s",(*variable)->name); + if (found == 1) { + DEBUG("Var: %s", (*variable)->name); DEBUG("Var Typekind: %d", (*variable)->kind); DEBUG("Found var"); - return SEMANTIC_OK; - }else if (found > 1) { + return SEMANTIC_OK; + } else if (found > 1) { WARN("Variable %s is a parameter and a declared variable. Returning parameter", name); - return SEMANTIC_OK; + return SEMANTIC_OK; } DEBUG("nothing found"); return SEMANTIC_ERROR; } -int addVarToScope(Variable * variable){ - Variable* tmp = NULL; - if(getVariableFromScope(variable->name, &tmp) == SEMANTIC_OK) { +int addVarToScope(Variable *variable) { + Variable *tmp = NULL; + if (getVariableFromScope(variable->name, &tmp) == SEMANTIC_OK) { INFO("this var already exist: ", variable->name); return SEMANTIC_ERROR; } - GHashTable * currentScope = g_array_index(Scope,GHashTable* ,Scope->len -1); + GHashTable *currentScope = g_array_index(Scope, GHashTable*, Scope->len - 1); g_hash_table_insert(currentScope, (gpointer) variable->name, variable); return SEMANTIC_OK; } -int fillTablesWithVars(GHashTable *variableTable, const GArray* variables) { +int fillTablesWithVars(GHashTable *variableTable, const GArray *variables) { DEBUG("filling vars in scope and table"); - for(size_t i = 0; i < variables->len; i++) { + for (guint i = 0; i < variables->len; i++) { - - Variable* var = g_array_index(variables,Variable *,i); + Variable *var = g_array_index(variables, Variable *, i); // this variable is discarded, only need status code - if(g_hash_table_contains(variableTable, (gpointer)var->name)){ + if (g_hash_table_contains(variableTable, (gpointer) var->name)) { return SEMANTIC_ERROR; } - g_hash_table_insert(variableTable, (gpointer) var->name, var); - } - + g_hash_table_insert(variableTable, (gpointer) var->name, var); + } + return SEMANTIC_OK; } [[nodiscard("type must be freed")]] -TypeValue createTypeValue(AST_NODE_PTR currentNode){ + +TypeValue createTypeValue(AST_NODE_PTR currentNode) { DEBUG("create TypeValue"); TypeValue value; - Type *type = mem_alloc(MemoryNamespaceSet,sizeof(Type)); + Type *type = mem_alloc(MemoryNamespaceSet, sizeof(Type)); value.type = type; type->kind = TypeKindPrimitive; type->nodePtr = currentNode; @@ -600,16 +490,14 @@ TypeValue createTypeValue(AST_NODE_PTR currentNode){ case AST_Int: type->impl.primitive = Int; break; - case AST_Float: type->impl.primitive = Float; break; - default: PANIC("Node is not an expression but from kind: %i", currentNode->kind); break; } - + value.nodePtr = currentNode; value.value = currentNode->value; return value; @@ -620,20 +508,19 @@ TypeValue createTypeValue(AST_NODE_PTR currentNode){ TypeValue createString(AST_NODE_PTR currentNode) { DEBUG("create String"); TypeValue value; - Type *type = CLONE(StringLiteralType); - value.type = type; + value.type = CLONE(StringLiteralType); value.nodePtr = currentNode; - value.value = currentNode->value; + value.value = currentNode->value; return value; } -Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_NODE_PTR currentNode) { +Type *createTypeFromOperands(Type *LeftOperandType, Type *RightOperandType, AST_NODE_PTR currentNode) { DEBUG("create type from operands"); - Type *result = mem_alloc(MemoryNamespaceSet,sizeof(Type)); + Type *result = mem_alloc(MemoryNamespaceSet, sizeof(Type)); result->nodePtr = currentNode; DEBUG("LeftOperandType->kind: %i", LeftOperandType->kind); DEBUG("RightOperandType->kind: %i", RightOperandType->kind); - + if (LeftOperandType->kind == TypeKindComposite && RightOperandType->kind == TypeKindComposite) { result->kind = TypeKindComposite; CompositeType resultImpl; @@ -641,15 +528,16 @@ Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_ resultImpl.nodePtr = currentNode; resultImpl.sign = MAX(LeftOperandType->impl.composite.sign, RightOperandType->impl.composite.sign); resultImpl.scale = MAX(LeftOperandType->impl.composite.scale, RightOperandType->impl.composite.scale); - resultImpl.primitive = MAX(LeftOperandType->impl.composite.primitive , RightOperandType->impl.composite.primitive); + resultImpl.primitive = MAX(LeftOperandType->impl.composite.primitive, + RightOperandType->impl.composite.primitive); result->impl.composite = resultImpl; - + } else if (LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindPrimitive) { DEBUG("both operands are primitive"); result->kind = TypeKindPrimitive; - - result->impl.primitive = MAX(LeftOperandType->impl.primitive , RightOperandType->impl.primitive); + + result->impl.primitive = MAX(LeftOperandType->impl.primitive, RightOperandType->impl.primitive); } else if (LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindComposite) { result->kind = TypeKindComposite; @@ -674,18 +562,25 @@ Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_ return result; } -int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode, [[maybe_unused]] size_t expectedChildCount) { +int createArithOperation(Expression *ParentExpression, AST_NODE_PTR currentNode, [[maybe_unused]] size_t expectedChildCount) { DEBUG("create arithmetic operation"); - ParentExpression->impl.operation.kind = Arithmetic; - ParentExpression->impl.operation.nodePtr = currentNode; - ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE,sizeof(Expression*)); + ParentExpression->impl.operation. + kind = Arithmetic; + ParentExpression->impl.operation. + nodePtr = currentNode; + ParentExpression->impl.operation. + operands = mem_new_g_array(MemoryNamespaceSet, sizeof(Expression *)); assert(expectedChildCount == currentNode->child_count); - for (size_t i = 0; i < currentNode->child_count; i++) { - Expression* expression = createExpression(currentNode->children[i]); + for ( + size_t i = 0; + i < currentNode-> + child_count; + i++) { + Expression *expression = createExpression(currentNode->children[i]); - if(NULL == expression) { + if (NULL == expression) { return SEMANTIC_ERROR; } @@ -694,19 +589,24 @@ int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode, DEBUG("created all Expressions"); switch (currentNode->kind) { case AST_Add: - ParentExpression->impl.operation.impl.arithmetic = Add; + ParentExpression->impl.operation.impl. + arithmetic = Add; break; case AST_Sub: - ParentExpression->impl.operation.impl.arithmetic = Sub; + ParentExpression->impl.operation.impl. + arithmetic = Sub; break; case AST_Mul: - ParentExpression->impl.operation.impl.arithmetic = Mul; + ParentExpression->impl.operation.impl. + arithmetic = Mul; break; case AST_Div: - ParentExpression->impl.operation.impl.arithmetic = Div; + ParentExpression->impl.operation.impl. + arithmetic = Div; break; case AST_Negate: - ParentExpression->impl.operation.impl.arithmetic = Negate; + ParentExpression->impl.operation.impl. + arithmetic = Negate; break; default: PANIC("Current node is not an arithmetic operater"); @@ -714,23 +614,28 @@ int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode, } if (ParentExpression->impl.operation.impl.arithmetic == Negate) { - - Type* result = g_array_index(ParentExpression->impl.operation.operands,Expression *,0)->result; - result->nodePtr = currentNode; - - if (result->kind == TypeKindReference || result->kind == TypeKindBox) { - print_diagnostic(current_file, ¤tNode->location, Error, "Invalid type for arithmetic operation"); - return SEMANTIC_ERROR; - } else if(result->kind == TypeKindComposite) { - result->impl.composite.sign = Signed; - } - ParentExpression->result = result; - - } else { - Type* LeftOperandType = g_array_index(ParentExpression->impl.operation.operands,Expression *,0)->result; - Type* RightOperandType = g_array_index(ParentExpression->impl.operation.operands,Expression *,1)->result; - ParentExpression->result = createTypeFromOperands(LeftOperandType, RightOperandType, currentNode); + Type *result = g_array_index(ParentExpression->impl.operation.operands, Expression *, 0)->result; + result-> + nodePtr = currentNode; + + if (result->kind == TypeKindReference || result->kind == TypeKindBox) { + print_diagnostic(current_file, + ¤tNode->location, Error, "Invalid type for arithmetic operation"); + return SEMANTIC_ERROR; + } else if (result->kind == TypeKindComposite) { + result->impl.composite. + sign = Signed; + } + ParentExpression-> + result = result; + + } else { + Type *LeftOperandType = g_array_index(ParentExpression->impl.operation.operands, Expression *, 0)->result; + Type *RightOperandType = g_array_index(ParentExpression->impl.operation.operands, Expression *, 1)->result; + + ParentExpression-> + result = createTypeFromOperands(LeftOperandType, RightOperandType, currentNode); } if (ParentExpression->result == NULL) { @@ -740,15 +645,16 @@ int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode, return SEMANTIC_OK; } -int createRelationalOperation(Expression* ParentExpression, AST_NODE_PTR currentNode) { +int createRelationalOperation(Expression *ParentExpression, AST_NODE_PTR currentNode) { // fill kind and Nodeptr ParentExpression->impl.operation.kind = Relational; ParentExpression->impl.operation.nodePtr = currentNode; - ParentExpression->impl.operation.operands = g_array_new(FALSE,FALSE,sizeof(Expression*)); + ParentExpression->impl.operation.operands = mem_new_g_array(MemoryNamespaceSet, sizeof(Expression *)); + // fill Operands for (size_t i = 0; i < currentNode->child_count; i++) { - Expression* expression = createExpression(currentNode->children[i]); - if(NULL == expression){ + Expression *expression = createExpression(currentNode->children[i]); + if (NULL == expression) { return SEMANTIC_ERROR; } g_array_append_val(ParentExpression->impl.operation.operands, expression); @@ -763,14 +669,14 @@ int createRelationalOperation(Expression* ParentExpression, AST_NODE_PTR current ParentExpression->impl.operation.impl.relational = Greater; break; case AST_Greater: - ParentExpression->impl.operation.impl.relational= Less; + ParentExpression->impl.operation.impl.relational = Less; break; default: PANIC("Current node is not an relational operater"); break; } - Type* result = mem_alloc(MemoryNamespaceSet,sizeof(Type)); + Type *result = mem_alloc(MemoryNamespaceSet, sizeof(Type)); result->impl.primitive = Int; result->kind = TypeKindPrimitive; result->nodePtr = currentNode; @@ -785,8 +691,8 @@ int createBoolOperation(Expression *ParentExpression, AST_NODE_PTR currentNode) ParentExpression->impl.operation.nodePtr = currentNode; // fill Operands - for (size_t i = 0; i < currentNode->child_count; i++){ - Expression* expression = createExpression(currentNode->children[i]); + for (size_t i = 0; i < currentNode->child_count; i++) { + Expression *expression = createExpression(currentNode->children[i]); if (NULL == expression) { return SEMANTIC_ERROR; } @@ -808,18 +714,18 @@ int createBoolOperation(Expression *ParentExpression, AST_NODE_PTR currentNode) break; } - Expression* lhs = ((Expression**) ParentExpression->impl.operation.operands->data)[0]; - Expression* rhs = ((Expression**) ParentExpression->impl.operation.operands->data)[1]; + Expression *lhs = ((Expression **) ParentExpression->impl.operation.operands->data)[0]; + Expression *rhs = ((Expression **) ParentExpression->impl.operation.operands->data)[1]; - Type* LeftOperandType = lhs->result; - Type* RightOperandType = rhs->result; + Type *LeftOperandType = lhs->result; + Type *RightOperandType = rhs->result; // should not be a box or a reference - if(LeftOperandType->kind != TypeKindPrimitive && LeftOperandType->kind != TypeKindComposite) { + if (LeftOperandType->kind != TypeKindPrimitive && LeftOperandType->kind != TypeKindComposite) { print_diagnostic(current_file, &lhs->nodePtr->location, Error, "invalid type for boolean operation"); return SEMANTIC_ERROR; } - if(RightOperandType->kind != TypeKindPrimitive && RightOperandType->kind != TypeKindComposite) { + if (RightOperandType->kind != TypeKindPrimitive && RightOperandType->kind != TypeKindComposite) { print_diagnostic(current_file, &rhs->nodePtr->location, Error, "invalid type for boolean operation"); return SEMANTIC_ERROR; } @@ -857,39 +763,42 @@ int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNod ParentExpression->impl.operation.nodePtr = currentNode; //fill Operand - Expression* expression = createExpression(currentNode->children[0]); - if(NULL == expression){ + Expression *expression = createExpression(currentNode->children[0]); + if (NULL == expression) { return SEMANTIC_ERROR; } - g_array_append_val(ParentExpression->impl.operation.operands , expression); + g_array_append_val(ParentExpression->impl.operation.operands, expression); ParentExpression->impl.operation.impl.boolean = BooleanNot; - Type* Operand = ((Expression**)ParentExpression->impl.operation.operands)[0]->result; + Type *Operand = ((Expression **) ParentExpression->impl.operation.operands)[0]->result; - Type* result = mem_alloc(MemoryNamespaceSet,sizeof(Type)); + Type *result = mem_alloc(MemoryNamespaceSet, sizeof(Type)); result->nodePtr = currentNode; if (Operand->kind == TypeKindBox || Operand->kind == TypeKindReference) { - print_diagnostic(current_file, &Operand->nodePtr->location, Error, "Operand must be a variant of primitive type int"); + print_diagnostic(current_file, &Operand->nodePtr->location, Error, + "Operand must be a variant of primitive type int"); return SEMANTIC_ERROR; } if (Operand->kind == TypeKindPrimitive) { if (Operand->impl.primitive == Float) { - print_diagnostic(current_file, &Operand->nodePtr->location, Error, "Operand must be a variant of primitive type int"); + print_diagnostic(current_file, &Operand->nodePtr->location, Error, + "Operand must be a variant of primitive type int"); return SEMANTIC_ERROR; } result->kind = Operand->kind; result->impl = Operand->impl; - - } else if(Operand->kind == TypeKindComposite) { + + } else if (Operand->kind == TypeKindComposite) { if (Operand->impl.composite.primitive == Float) { - print_diagnostic(current_file, &Operand->nodePtr->location, Error, "Operand must be a variant of primitive type int"); + print_diagnostic(current_file, &Operand->nodePtr->location, Error, + "Operand must be a variant of primitive type int"); return SEMANTIC_ERROR; } result->kind = Operand->kind; - result->impl = Operand->impl; + result->impl = Operand->impl; } ParentExpression->result = result; @@ -899,24 +808,24 @@ int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNod bool isScaleEqual(double leftScale, double rightScale) { int leftIntScale = (int) (leftScale * BASE_BYTES); int rightIntScale = (int) (rightScale * BASE_BYTES); - + return leftIntScale == rightIntScale; } -int createBitOperation(Expression* ParentExpression, AST_NODE_PTR currentNode) { +int createBitOperation(Expression *ParentExpression, AST_NODE_PTR currentNode) { // fill kind and Nodeptr ParentExpression->impl.operation.kind = Boolean; ParentExpression->impl.operation.nodePtr = currentNode; // fill Operands for (size_t i = 0; i < currentNode->child_count; i++) { - Expression* expression = createExpression(currentNode->children[i]); + Expression *expression = createExpression(currentNode->children[i]); - if(NULL == expression) { + if (NULL == expression) { return SEMANTIC_ERROR; } - g_array_append_val(ParentExpression->impl.operation.operands , expression); + g_array_append_val(ParentExpression->impl.operation.operands, expression); } switch (currentNode->kind) { @@ -934,14 +843,14 @@ int createBitOperation(Expression* ParentExpression, AST_NODE_PTR currentNode) { break; } - Type *result = mem_alloc(MemoryNamespaceSet,sizeof(Type)); + Type *result = mem_alloc(MemoryNamespaceSet, sizeof(Type)); result->nodePtr = currentNode; - Expression* lhs = ((Expression**) ParentExpression->impl.operation.operands->data)[0]; - Expression* rhs = ((Expression**) ParentExpression->impl.operation.operands->data)[1]; - - Type* LeftOperandType = lhs->result; - Type* RightOperandType = rhs->result; + Expression *lhs = ((Expression **) ParentExpression->impl.operation.operands->data)[0]; + Expression *rhs = ((Expression **) ParentExpression->impl.operation.operands->data)[1]; + + Type *LeftOperandType = lhs->result; + Type *RightOperandType = rhs->result; //should not be a box or a reference if (LeftOperandType->kind != TypeKindPrimitive && LeftOperandType->kind != TypeKindComposite) { @@ -984,7 +893,7 @@ int createBitOperation(Expression* ParentExpression, AST_NODE_PTR currentNode) { result->kind = TypeKindPrimitive; result->impl.primitive = Int; - }else if (LeftOperandType->kind == TypeKindComposite && RightOperandType->kind == TypeKindPrimitive) { + } else if (LeftOperandType->kind == TypeKindComposite && RightOperandType->kind == TypeKindPrimitive) { if (LeftOperandType->impl.composite.primitive == Float) { print_diagnostic(current_file, &lhs->nodePtr->location, Error, "Must be a type variant of int"); @@ -1010,7 +919,7 @@ int createBitOperation(Expression* ParentExpression, AST_NODE_PTR currentNode) { return SEMANTIC_ERROR; } - if (!isScaleEqual(LeftOperandType->impl.composite.scale, RightOperandType->impl.composite.scale)) { + if (!isScaleEqual(LeftOperandType->impl.composite.scale, RightOperandType->impl.composite.scale)) { print_diagnostic(current_file, ¤tNode->location, Error, "Operands must be of equal size"); return SEMANTIC_ERROR; } @@ -1025,26 +934,26 @@ int createBitOperation(Expression* ParentExpression, AST_NODE_PTR currentNode) { return 0; } -int createBitNotOperation(Expression* ParentExpression, AST_NODE_PTR currentNode) { +int createBitNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNode) { //fill kind and Nodeptr ParentExpression->impl.operation.kind = Bitwise; ParentExpression->impl.operation.nodePtr = currentNode; //fill Operand - Expression* expression = createExpression(currentNode->children[0]); - if(NULL == expression){ + Expression *expression = createExpression(currentNode->children[0]); + if (NULL == expression) { return SEMANTIC_ERROR; } - g_array_append_val(ParentExpression->impl.operation.operands , expression); + g_array_append_val(ParentExpression->impl.operation.operands, expression); ParentExpression->impl.operation.impl.bitwise = BitwiseNot; - Type* Operand = ((Expression**) ParentExpression->impl.operation.operands)[0]->result; - - Type* result = mem_alloc(MemoryNamespaceSet,sizeof(Type)); + Type *Operand = ((Expression **) ParentExpression->impl.operation.operands)[0]->result; + + Type *result = mem_alloc(MemoryNamespaceSet, sizeof(Type)); result->nodePtr = currentNode; - - if (Operand->kind == TypeKindPrimitive) { + + if (Operand->kind == TypeKindPrimitive) { if (Operand->impl.primitive == Float) { print_diagnostic(current_file, &Operand->nodePtr->location, Error, "Operand type must be a variant of int"); @@ -1053,7 +962,7 @@ int createBitNotOperation(Expression* ParentExpression, AST_NODE_PTR currentNode result->kind = TypeKindPrimitive; result->impl.primitive = Int; - }else if(Operand->kind == TypeKindComposite) { + } else if (Operand->kind == TypeKindComposite) { if (Operand->impl.composite.primitive == Float) { print_diagnostic(current_file, &Operand->nodePtr->location, Error, "Operand type must be a variant of int"); @@ -1065,65 +974,83 @@ int createBitNotOperation(Expression* ParentExpression, AST_NODE_PTR currentNode result->impl.composite.primitive = Int; result->impl.composite.sign = Operand->impl.composite.sign; result->impl.composite.scale = Operand->impl.composite.scale; - } - + } + ParentExpression->result = result; return SEMANTIC_OK; } -GArray* getBoxMember(Type* currentBoxType, GArray *names) { - - GArray *members = g_array_new(FALSE, FALSE, sizeof(BoxMember)); - GHashTable* memberList = currentBoxType->impl.box.member; - - const char* currentName = g_array_index(names,const char *,0); - if(!g_hash_table_contains(memberList, currentName)) { - // TODO: free members - return NULL; - } - BoxMember * currentMember = g_hash_table_lookup(memberList, currentName); - g_array_append_val(members, currentMember); +/** + * @brief Return a copy of all BoxMembers specified by their name in names from a boxes type + * Will run recursively in case the first name refers to a subbox + * @param currentBoxType + * @param names + * @return + */ +GArray *getBoxMember(Type *currentBoxType, GArray *names) { - g_array_remove_index(names,0); - if (names->len == 0) { - return members; - } - if (currentMember->type->kind == TypeKindBox){ - GArray *otherMember = getBoxMember(currentMember->type, names); - if(NULL == otherMember){ - return NULL; + GArray *members = mem_new_g_array(MemoryNamespaceSet, sizeof(BoxMember)); + // list of members of the type + GHashTable *memberList = currentBoxType->impl.box.member; + + // name of member to extract + const char *currentName = g_array_index(names, const char *, 0); + // look for member of this name + if (g_hash_table_contains(memberList, currentName)) { + + // get member and store in array + BoxMember *currentMember = g_hash_table_lookup(memberList, currentName); + g_array_append_val(members, currentMember); + + // last name in list, return + g_array_remove_index(names, 0); + if (names->len == 0) { + return members; } - g_array_append_vals(members,(BoxMember *) otherMember->data, otherMember->len); - return members; - } + + // other names may refer to members of child boxes + if (currentMember->type->kind == TypeKindBox) { + GArray *otherMember = getBoxMember(currentMember->type, names); + + if (NULL == otherMember) { + return NULL; + } + + g_array_append_vals(members, (BoxMember *) otherMember->data, otherMember->len); + + return members; + } + } + return NULL; } -int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) { +int createBoxAccess(Expression *ParentExpression, AST_NODE_PTR currentNode) { - const char* boxname = currentNode->children[0]->value; - Variable* boxVariable = NULL; + const char *boxname = currentNode->children[0]->value; + Variable *boxVariable = NULL; int status = getVariableFromScope(boxname, &boxVariable); - if(status == SEMANTIC_ERROR){ - print_diagnostic(current_file, ¤tNode->children[0]->location, Error, "Variable of name `%s` does not exist"); + if (status == SEMANTIC_ERROR) { + print_diagnostic(current_file, ¤tNode->children[0]->location, Error, + "Variable of name `%s` does not exist"); return SEMANTIC_ERROR; } - Type* boxType; + Type *boxType; + + if (boxVariable->kind == VariableKindDeclaration) { - if(boxVariable->kind == VariableKindDeclaration){ - boxType = boxVariable->impl.declaration.type; - } else if (boxVariable->kind == VariableKindDefinition){ + } else if (boxVariable->kind == VariableKindDefinition) { boxType = boxVariable->impl.definiton.declaration.type; - } else{ + } else { return SEMANTIC_ERROR; } if (boxType->kind != TypeKindBox) { return SEMANTIC_ERROR; } - + // filling boxAccess variable ParentExpression->impl.variable->kind = VariableKindBoxMember; ParentExpression->impl.variable->nodePtr = currentNode; @@ -1134,36 +1061,36 @@ int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) { ParentExpression->impl.variable->impl.member.variable = boxVariable; //first one is the box itself - GArray* names = mem_alloc(MemoryNamespaceSet,sizeof(GArray)); - if(currentNode->kind == AST_IdentList){ - for (size_t i = 1; i < currentNode->child_count; i++){ + GArray *names = mem_alloc(MemoryNamespaceSet, sizeof(GArray)); + if (currentNode->kind == AST_IdentList) { + for (size_t i = 1; i < currentNode->child_count; i++) { g_array_append_val(names, currentNode->children[i]->value); } - }else if(currentNode->kind == AST_List){ - for (size_t i = 1; i < currentNode->children[1]->child_count; i++){ + } else if (currentNode->kind == AST_List) { + for (size_t i = 1; i < currentNode->children[1]->child_count; i++) { g_array_append_val(names, currentNode->children[1]->children[i]->value); } - }else{ + } else { PANIC("current Node is not an Access"); } - GArray * boxMember = getBoxMember(boxType, names); + GArray *boxMember = getBoxMember(boxType, names); ParentExpression->impl.variable->impl.member.member = boxMember; - ParentExpression->result = g_array_index(boxMember,BoxMember,boxMember->len).type; + ParentExpression->result = g_array_index(boxMember, BoxMember, boxMember->len).type; return SEMANTIC_OK; } -int createTypeCast(Expression* ParentExpression, AST_NODE_PTR currentNode){ +int createTypeCast(Expression *ParentExpression, AST_NODE_PTR currentNode) { DEBUG("create type cast"); ParentExpression->impl.typecast.nodePtr = currentNode; - + ParentExpression->impl.typecast.operand = createExpression(currentNode->children[0]); - if (ParentExpression->impl.typecast.operand == NULL){ + if (ParentExpression->impl.typecast.operand == NULL) { return SEMANTIC_ERROR; } - Type* target = mem_alloc(MemoryNamespaceSet,sizeof(Type)); + Type *target = mem_alloc(MemoryNamespaceSet, sizeof(Type)); int status = get_type_impl(currentNode->children[1], &target); if (status) { print_diagnostic(current_file, ¤tNode->children[1]->location, Error, "Unknown type"); @@ -1174,195 +1101,190 @@ int createTypeCast(Expression* ParentExpression, AST_NODE_PTR currentNode){ return SEMANTIC_OK; } -int createTransmute(Expression* ParentExpression, AST_NODE_PTR currentNode){ +int createTransmute(Expression *ParentExpression, AST_NODE_PTR currentNode) { ParentExpression->impl.transmute.nodePtr = currentNode; ParentExpression->impl.transmute.operand = createExpression(currentNode->children[0]); - - if (ParentExpression->impl.transmute.operand == NULL){ + + if (ParentExpression->impl.transmute.operand == NULL) { return SEMANTIC_ERROR; } - Type* target = mem_alloc(MemoryNamespaceSet,sizeof(Type)); + Type *target = mem_alloc(MemoryNamespaceSet, sizeof(Type)); int status = get_type_impl(currentNode->children[1], &target); - if (status){ + if (status) { print_diagnostic(current_file, ¤tNode->children[1]->location, Error, "Unknown type"); return SEMANTIC_ERROR; } ParentExpression->impl.typecast.targetType = target; ParentExpression->result = target; - - return SEMANTIC_OK; + return SEMANTIC_OK; } - - -Expression *createExpression(AST_NODE_PTR currentNode){ +Expression *createExpression(AST_NODE_PTR currentNode) { DEBUG("create Expression"); - Expression *expression = mem_alloc(MemoryNamespaceSet,sizeof(Expression)); + Expression *expression = mem_alloc(MemoryNamespaceSet, sizeof(Expression)); expression->nodePtr = currentNode; - switch(currentNode->kind){ - - case AST_Int: - case AST_Float: - expression->kind = ExpressionKindConstant; - expression->impl.constant = createTypeValue(currentNode); - expression->result = expression->impl.constant.type; - break; - case AST_String: - expression->kind = ExpressionKindConstant; - expression->impl.constant = createString(currentNode); - expression->result = expression->impl.constant.type; - break; - case AST_Ident: - DEBUG("find var"); - expression->kind = ExpressionKindVariable; - int status = getVariableFromScope(currentNode->value, &(expression->impl.variable) ); - if(status == SEMANTIC_ERROR){ - DEBUG("Identifier is not in current scope"); - print_diagnostic(current_file, ¤tNode->location, Error, "Variable not found"); - return NULL; - } - switch (expression->impl.variable->kind) { - case VariableKindDeclaration: - expression->result = expression->impl.variable->impl.declaration.type; - DEBUG("%d",expression->impl.variable->impl.declaration.type->kind ); - break; - case VariableKindDefinition: - expression->result = expression->impl.variable->impl.definiton.declaration.type; - break; - default: - PANIC("current Variable should not be an BoxMember"); - break; - } - break; - case AST_Add: - case AST_Sub: - case AST_Mul: - case AST_Div: - expression->kind = ExpressionKindOperation; - if(createArithOperation(expression, currentNode, 2)){ - return NULL; - } - break; - case AST_Negate: - expression->kind = ExpressionKindOperation; - if(createArithOperation(expression,currentNode, 1)){ - return NULL; - } - break; - case AST_Eq: - case AST_Less: - case AST_Greater: - expression->kind = ExpressionKindOperation; - if(createRelationalOperation(expression,currentNode)){ - return NULL; - } - break; - case AST_BoolAnd: - case AST_BoolOr: - case AST_BoolXor: - expression->kind = ExpressionKindOperation; - if(createBoolOperation(expression,currentNode)){ - return NULL; - } - break; - case AST_BoolNot: - expression->kind= ExpressionKindOperation; - if(createBoolNotOperation(expression, currentNode)){ - return NULL; - } - break; - case AST_BitAnd: - case AST_BitOr: - case AST_BitXor: - expression->kind= ExpressionKindOperation; - if(createBitOperation(expression, currentNode)){ - return NULL; - } - break; - case AST_BitNot: - expression->kind = ExpressionKindOperation; - if(createBitNotOperation(expression, currentNode)){ - return NULL; - } - break; - case AST_IdentList: - case AST_List: - expression->kind = ExpressionKindVariable; - if(createBoxAccess(expression, currentNode)){ - return NULL; - } - break; - case AST_Typecast: - expression->kind = ExpressionKindTypeCast; - if(createTypeCast(expression, currentNode)){ - return NULL; - } - break; - case AST_Transmute: - expression->kind = ExpressionKindTransmute; - if(createTransmute(expression, currentNode)){ - return NULL; - } - break; - default: - PANIC("Node is not an expression but from kind: %i", currentNode->kind); - break; + switch (currentNode->kind) { + case AST_Int: + case AST_Float: + expression->kind = ExpressionKindConstant; + expression->impl.constant = createTypeValue(currentNode); + expression->result = expression->impl.constant.type; + break; + case AST_String: + expression->kind = ExpressionKindConstant; + expression->impl.constant = createString(currentNode); + expression->result = expression->impl.constant.type; + break; + case AST_Ident: + DEBUG("find var"); + expression->kind = ExpressionKindVariable; + int status = getVariableFromScope(currentNode->value, &(expression->impl.variable)); + if (status == SEMANTIC_ERROR) { + DEBUG("Identifier is not in current scope"); + print_diagnostic(current_file, ¤tNode->location, Error, "Variable not found"); + return NULL; + } + switch (expression->impl.variable->kind) { + case VariableKindDeclaration: + expression->result = expression->impl.variable->impl.declaration.type; + DEBUG("%d", expression->impl.variable->impl.declaration.type->kind); + break; + case VariableKindDefinition: + expression->result = expression->impl.variable->impl.definiton.declaration.type; + break; + default: + PANIC("current Variable should not be an BoxMember"); + break; + } + break; + case AST_Add: + case AST_Sub: + case AST_Mul: + case AST_Div: + expression->kind = ExpressionKindOperation; + if (createArithOperation(expression, currentNode, 2)) { + return NULL; + } + break; + case AST_Negate: + expression->kind = ExpressionKindOperation; + if (createArithOperation(expression, currentNode, 1)) { + return NULL; + } + break; + case AST_Eq: + case AST_Less: + case AST_Greater: + expression->kind = ExpressionKindOperation; + if (createRelationalOperation(expression, currentNode)) { + return NULL; + } + break; + case AST_BoolAnd: + case AST_BoolOr: + case AST_BoolXor: + expression->kind = ExpressionKindOperation; + if (createBoolOperation(expression, currentNode)) { + return NULL; + } + break; + case AST_BoolNot: + expression->kind = ExpressionKindOperation; + if (createBoolNotOperation(expression, currentNode)) { + return NULL; + } + break; + case AST_BitAnd: + case AST_BitOr: + case AST_BitXor: + expression->kind = ExpressionKindOperation; + if (createBitOperation(expression, currentNode)) { + return NULL; + } + break; + case AST_BitNot: + expression->kind = ExpressionKindOperation; + if (createBitNotOperation(expression, currentNode)) { + return NULL; + } + break; + case AST_IdentList: + case AST_List: + expression->kind = ExpressionKindVariable; + if (createBoxAccess(expression, currentNode)) { + return NULL; + } + break; + case AST_Typecast: + expression->kind = ExpressionKindTypeCast; + if (createTypeCast(expression, currentNode)) { + return NULL; + } + break; + case AST_Transmute: + expression->kind = ExpressionKindTransmute; + if (createTransmute(expression, currentNode)) { + return NULL; + } + break; + default: + PANIC("Node is not an expression but from kind: %i", currentNode->kind); + break; } - DEBUG("expression result typekind: %d",expression->result->kind); + DEBUG("expression result typekind: %d", expression->result->kind); DEBUG("successfully created Expression"); return expression; } - - int createAssign(Statement* ParentStatement, AST_NODE_PTR currentNode){ + +int createAssign(Statement *ParentStatement, AST_NODE_PTR currentNode) { DEBUG("create Assign"); Assignment assign; assign.nodePtr = currentNode; - const char* varName = currentNode->children[0]->value; + const char *varName = currentNode->children[0]->value; int status = getVariableFromScope(varName, &assign.variable); - if(status){ + if (status) { return SEMANTIC_ERROR; } assign.value = createExpression(currentNode->children[1]); - if(assign.value == NULL){ + if (assign.value == NULL) { return SEMANTIC_ERROR; } ParentStatement->impl.assignment = assign; return SEMANTIC_OK; - } -int createStatement(Block * block, AST_NODE_PTR currentNode); +} -int fillBlock(Block * block,AST_NODE_PTR currentNode){ +int createStatement(Block *block, AST_NODE_PTR currentNode); + +int fillBlock(Block *block, AST_NODE_PTR currentNode) { DEBUG("start filling Block"); block->nodePtr = currentNode; - block->statemnts = g_array_new(FALSE,FALSE,sizeof(Statement*)); - GHashTable * lowerScope = g_hash_table_new(g_str_hash,g_str_equal); + block->statemnts = mem_new_g_array(MemoryNamespaceSet, sizeof(Statement *)); + GHashTable *lowerScope = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal); g_array_append_val(Scope, lowerScope); - - for(size_t i = 0; i < currentNode->child_count; i++){ + for (size_t i = 0; i < currentNode->child_count; i++) { int signal = createStatement(block, AST_get_node(currentNode, i)); - if(signal){ + if (signal) { return SEMANTIC_ERROR; } } - g_hash_table_destroy(lowerScope); - g_array_remove_index(Scope, Scope->len-1); - + g_array_remove_index(Scope, Scope->len - 1); + DEBUG("created Block successfully"); return SEMANTIC_OK; } -int createWhile(Statement * ParentStatement, AST_NODE_PTR currentNode){ +int createWhile(Statement *ParentStatement, AST_NODE_PTR currentNode) { assert(ParentStatement != NULL); assert(currentNode != NULL); assert(currentNode->kind == AST_While); @@ -1370,13 +1292,13 @@ int createWhile(Statement * ParentStatement, AST_NODE_PTR currentNode){ While whileStruct; whileStruct.nodePtr = currentNode; whileStruct.conditon = createExpression(currentNode->children[0]); - if(NULL == whileStruct.conditon){ + if (NULL == whileStruct.conditon) { return SEMANTIC_ERROR; } AST_NODE_PTR statementList = currentNode->children[1]; - int signal = fillBlock(&whileStruct.block,statementList); - if(signal){ + int signal = fillBlock(&whileStruct.block, statementList); + if (signal) { return SEMANTIC_ERROR; } ParentStatement->impl.whileLoop = whileStruct; @@ -1384,82 +1306,78 @@ int createWhile(Statement * ParentStatement, AST_NODE_PTR currentNode){ return SEMANTIC_OK; } - - -int createIf(Branch* Parentbranch, AST_NODE_PTR currentNode){ +int createIf(Branch *Parentbranch, AST_NODE_PTR currentNode) { If ifbranch; ifbranch.nodePtr = currentNode; - - Expression* expression = createExpression(currentNode->children[0]); + + Expression *expression = createExpression(currentNode->children[0]); if (NULL == expression) { return SEMANTIC_ERROR; } + ifbranch.conditon = expression; int status = fillBlock(&ifbranch.block, currentNode->children[1]); - - if(status){ + + if (status) { return SEMANTIC_ERROR; } + Parentbranch->ifBranch = ifbranch; return SEMANTIC_OK; } -int createElse(Branch* Parentbranch, AST_NODE_PTR currentNode){ +int createElse(Branch *Parentbranch, AST_NODE_PTR currentNode) { Else elseBranch; elseBranch.nodePtr = currentNode; - + int status = fillBlock(&elseBranch.block, currentNode->children[0]); - - if(status){ + + if (status) { return SEMANTIC_ERROR; } Parentbranch->elseBranch = elseBranch; return SEMANTIC_OK; } -int createElseIf(Branch* Parentbranch, AST_NODE_PTR currentNode){ +int createElseIf(Branch *Parentbranch, AST_NODE_PTR currentNode) { ElseIf elseIfBranch; elseIfBranch.nodePtr = currentNode; - - Expression* expression = createExpression(currentNode->children[0]); + + Expression *expression = createExpression(currentNode->children[0]); if (NULL == expression) { return SEMANTIC_ERROR; } elseIfBranch.conditon = expression; int status = fillBlock(&elseIfBranch.block, currentNode->children[1]); - - if(status){ + + if (status) { return SEMANTIC_ERROR; } - g_array_append_val(Parentbranch->elseIfBranches,elseIfBranch); + g_array_append_val(Parentbranch->elseIfBranches, elseIfBranch); return SEMANTIC_OK; } - - -int createBranch(Statement* ParentStatement,AST_NODE_PTR currentNode){ +int createBranch(Statement *ParentStatement, AST_NODE_PTR currentNode) { Branch Branch; Branch.nodePtr = currentNode; - for (size_t i = 0; i < currentNode->child_count; i++ ){ - switch (currentNode->children[i]->kind){ + + for (size_t i = 0; i < currentNode->child_count; i++) { + switch (currentNode->children[i]->kind) { case AST_If: - if(createIf(&Branch, currentNode->children[i])){ + if (createIf(&Branch, currentNode->children[i])) { return SEMANTIC_ERROR; } - break; - + break; case AST_IfElse: - if(createElseIf(&Branch, currentNode)){ + if (createElseIf(&Branch, currentNode)) { return SEMANTIC_ERROR; } - break; - + break; case AST_Else: - if(createElse(&Branch, currentNode->children[i])){ + if (createElse(&Branch, currentNode->children[i])) { return SEMANTIC_ERROR; } - break; - + break; default: PANIC("current node is not part of a Branch"); break; @@ -1469,118 +1387,116 @@ int createBranch(Statement* ParentStatement,AST_NODE_PTR currentNode){ return SEMANTIC_OK; } -int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){ +int createStatement(Block *Parentblock, AST_NODE_PTR currentNode) { DEBUG("create Statement"); - - switch(currentNode->kind){ - case AST_Decl:{ - GArray *variable= g_array_new(FALSE, FALSE, sizeof(Variable*)); - + + switch (currentNode->kind) { + case AST_Decl: { + GArray *variable = mem_new_g_array(MemoryNamespaceSet, sizeof(Variable *)); + int status = createDecl(currentNode, &variable); - if(status){ + if (status) { return SEMANTIC_ERROR; } - for(size_t i = 0; i < variable->len ; i++){ - Statement * statement = mem_alloc(MemoryNamespaceSet,sizeof(Statement)); - statement->nodePtr = currentNode; - statement->kind = StatementKindDeclaration; + for (size_t i = 0; i < variable->len; i++) { - - statement->impl.variable = g_array_index(variable,Variable *,i); - g_array_append_val(Parentblock->statemnts,statement); + Statement *statement = mem_alloc(MemoryNamespaceSet, sizeof(Statement)); + statement->nodePtr = currentNode; + statement->kind = StatementKindDeclaration; + + statement->impl.variable = g_array_index(variable, Variable *, i); + g_array_append_val(Parentblock->statemnts, statement); } } break; + case AST_Def: { + GArray *variable = mem_new_g_array(MemoryNamespaceSet, sizeof(Variable *)); - case AST_Def:{ - GArray *variable= g_array_new(FALSE, FALSE, sizeof(Variable*)); - int status = createDef(currentNode, &variable); - if(status){ + if (status) { return SEMANTIC_ERROR; } - for(size_t i = 0; i < variable->len ; i++){ - Statement * statement = mem_alloc(MemoryNamespaceSet,sizeof(Statement)); - statement->nodePtr = currentNode; - statement->kind = StatementKindDefinition; - - statement->impl.variable = g_array_index(variable,Variable *,i); - g_array_append_val(Parentblock->statemnts,statement); + for (size_t i = 0; i < variable->len; i++) { + + Statement *statement = mem_alloc(MemoryNamespaceSet, sizeof(Statement)); + statement->nodePtr = currentNode; + statement->kind = StatementKindDefinition; + + statement->impl.variable = g_array_index(variable, Variable *, i); + g_array_append_val(Parentblock->statemnts, statement); } - } break; - case AST_While:{ - Statement * statement = mem_alloc(MemoryNamespaceSet,sizeof(Statement)); + case AST_While: { + Statement *statement = mem_alloc(MemoryNamespaceSet, sizeof(Statement)); statement->nodePtr = currentNode; statement->kind = StatementKindWhile; - if(createWhile(statement, currentNode)){ + if (createWhile(statement, currentNode)) { return SEMANTIC_ERROR; } - g_array_append_val(Parentblock->statemnts,statement); + g_array_append_val(Parentblock->statemnts, statement); } break; - case AST_Stmt:{ - Statement * statement = mem_alloc(MemoryNamespaceSet,sizeof(Statement)); + case AST_Stmt: { + Statement *statement = mem_alloc(MemoryNamespaceSet, sizeof(Statement)); statement->nodePtr = currentNode; statement->kind = StatementKindBranch; - if(createBranch(statement, currentNode)){ + if (createBranch(statement, currentNode)) { return SEMANTIC_ERROR; } - g_array_append_val(Parentblock->statemnts,statement); + g_array_append_val(Parentblock->statemnts, statement); } break; - case AST_Assign:{ - Statement * statement = mem_alloc(MemoryNamespaceSet,sizeof(Statement)); + case AST_Assign: { + Statement *statement = mem_alloc(MemoryNamespaceSet, sizeof(Statement)); statement->nodePtr = currentNode; statement->kind = StatementKindAssignment; - if(createAssign(statement, currentNode)){ + if (createAssign(statement, currentNode)) { return SEMANTIC_ERROR; } - g_array_append_val(Parentblock->statemnts,statement); - } - break; - case AST_Call: + g_array_append_val(Parentblock->statemnts, statement); + } + break; + case AST_Call: //TODO both funcall and boxfuncall default: - break; + break; } - + return SEMANTIC_OK; } - -int createParam(GArray * Paramlist ,AST_NODE_PTR currentNode){ +int createParam(GArray *Paramlist, AST_NODE_PTR currentNode) { assert(currentNode->kind == AST_Parameter); DEBUG("start param"); - DEBUG("current node child count: %i",currentNode->child_count); + DEBUG("current node child count: %i", currentNode->child_count); AST_NODE_PTR paramdecl = currentNode->children[1]; - AST_NODE_PTR ioQualifierList = currentNode->children[0]; + AST_NODE_PTR ioQualifierList = currentNode->children[0]; ParameterDeclaration decl; decl.nodePtr = paramdecl; - DEBUG("iolistnode child count: %i", ioQualifierList->child_count ); - if(ioQualifierList->child_count == 2){ + DEBUG("iolistnode child count: %i", ioQualifierList->child_count); + if (ioQualifierList->child_count == 2) { decl.qualifier = InOut; - }else if(ioQualifierList->child_count == 1){ - if(strcmp(ioQualifierList->children[0]->value , "in") == 0){ + } else if (ioQualifierList->child_count == 1) { + if (strcmp(ioQualifierList->children[0]->value, "in") == 0) { decl.qualifier = In; - }else if(strcmp(ioQualifierList->children[0]->value , "out") == 0){ + } else if (strcmp(ioQualifierList->children[0]->value, "out") == 0) { decl.qualifier = Out; - }else{ + } else { PANIC("IO_Qualifier is not in or out"); } - }else{ + } else { PANIC("IO_Qualifier has not the right amount of children"); } - + int signal = get_type_impl(paramdecl->children[0], &(decl.type)); - if(signal){ + if (signal) { return SEMANTIC_ERROR; } Parameter param; @@ -1588,13 +1504,13 @@ int createParam(GArray * Paramlist ,AST_NODE_PTR currentNode){ param.kind = ParameterDeclarationKind; param.impl.declaration = decl; param.name = paramdecl->children[1]->value; - + DEBUG("param name: %s", param.name); g_array_append_val(Paramlist, param); DEBUG("create var for param"); - Variable * paramvar = mem_alloc(MemoryNamespaceSet,sizeof(Variable)); + Variable *paramvar = mem_alloc(MemoryNamespaceSet, sizeof(Variable)); paramvar->kind = VariableKindDeclaration; paramvar->name = param.name; paramvar->nodePtr = currentNode; @@ -1602,92 +1518,83 @@ int createParam(GArray * Paramlist ,AST_NODE_PTR currentNode){ paramvar->impl.declaration.qualifier = Local; paramvar->impl.declaration.type = param.impl.declaration.type; - - if (g_hash_table_contains(functionParameter, param.name)){ + if (g_hash_table_contains(functionParameter, param.name)) { return SEMANTIC_ERROR; } - g_hash_table_insert(functionParameter, (gpointer)param.name, paramvar); + g_hash_table_insert(functionParameter, (gpointer) param.name, paramvar); DEBUG("created param successfully"); return SEMANTIC_OK; } - -int createFunDef(Function * Parentfunction ,AST_NODE_PTR currentNode){ +int createFunDef(Function *Parentfunction, AST_NODE_PTR currentNode) { DEBUG("start fundef"); AST_NODE_PTR nameNode = currentNode->children[0]; AST_NODE_PTR paramlistlist = currentNode->children[1]; AST_NODE_PTR statementlist = currentNode->children[2]; - - FunctionDefinition fundef; fundef.nodePtr = currentNode; fundef.name = nameNode->value; - fundef.body = mem_alloc(MemoryNamespaceSet,sizeof(Block)); - fundef.parameter = g_array_new(FALSE, FALSE, sizeof(Parameter)); + fundef.body = mem_alloc(MemoryNamespaceSet, sizeof(Block)); + fundef.parameter = mem_new_g_array(MemoryNamespaceSet, sizeof(Parameter)); DEBUG("paramlistlist child count: %i", paramlistlist->child_count); - for(size_t i = 0; i < paramlistlist->child_count; i++){ + for (guint i = 0; i < paramlistlist->child_count; i++) { - //all parameterlists + // all parameterlists AST_NODE_PTR paramlist = paramlistlist->children[i]; DEBUG("paramlist child count: %i", paramlist->child_count); - for (size_t j = 0; j < paramlist->child_count; j++){ + for (guint j = 0; j < paramlist->child_count; j++) { DEBUG("param child count: %i", AST_get_node(paramlist, j)->child_count); - int signal = createParam(fundef.parameter ,AST_get_node(paramlist, j)); + int signal = createParam(fundef.parameter, AST_get_node(paramlist, j)); //all params per list - - if (signal){ + + if (signal) { return SEMANTIC_ERROR; } } DEBUG("End of Paramlist"); - } + } int signal = fillBlock(fundef.body, statementlist); - if(signal){ + if (signal) { return SEMANTIC_ERROR; } - + Parentfunction->nodePtr = currentNode; Parentfunction->kind = FunctionDefinitionKind; Parentfunction->impl.definition = fundef; Parentfunction->name = fundef.name; return SEMANTIC_OK; - - } -int createFunDecl(Function * Parentfunction ,AST_NODE_PTR currentNode){ +int createFunDecl(Function *Parentfunction, AST_NODE_PTR currentNode) { DEBUG("start fundecl"); AST_NODE_PTR nameNode = currentNode->children[0]; AST_NODE_PTR paramlistlist = currentNode->children[1]; - - FunctionDeclaration fundecl; fundecl.nodePtr = currentNode; fundecl.name = nameNode->value; - fundecl.parameter = mem_alloc(MemoryNamespaceSet,sizeof(GArray)); + fundecl.parameter = mem_alloc(MemoryNamespaceSet, sizeof(GArray)); - - for(size_t i = 0; i < paramlistlist->child_count; i++){ + for (size_t i = 0; i < paramlistlist->child_count; i++) { //all parameterlists AST_NODE_PTR paramlist = paramlistlist->children[i]; - for (size_t j = 0; j < paramlistlist->child_count; j++){ + for (size_t j = 0; j < paramlistlist->child_count; j++) { - int signal = createParam(fundecl.parameter ,paramlist->children[i]); + int signal = createParam(fundecl.parameter, paramlist->children[i]); //all params per list - if (signal){ + if (signal) { return SEMANTIC_ERROR; } } - } + } Parentfunction->nodePtr = currentNode; Parentfunction->kind = FunctionDefinitionKind; @@ -1697,197 +1604,167 @@ int createFunDecl(Function * Parentfunction ,AST_NODE_PTR currentNode){ } //TODO check if a function is present and if a declaration is present and identical. -int createFunction(GHashTable* functions, AST_NODE_PTR currentNode){ +int createFunction(GHashTable *functions, AST_NODE_PTR currentNode) { assert(currentNode->kind == AST_Fun); - Function * fun = mem_alloc(MemoryNamespaceSet,sizeof(Function)); - functionParameter = g_hash_table_new(g_str_hash,g_str_equal); - - if(currentNode->child_count == 2){ + Function *fun = mem_alloc(MemoryNamespaceSet, sizeof(Function)); + functionParameter = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal); + + if (currentNode->child_count == 2) { int signal = createFunDecl(fun, currentNode); - if (signal){ + if (signal) { return SEMANTIC_ERROR; } - }else if(currentNode->child_count == 3){ + } else if (currentNode->child_count == 3) { int signal = createFunDef(fun, currentNode); - if (signal){ + if (signal) { return SEMANTIC_ERROR; } - }else { + } else { PANIC("function should have 2 or 3 children"); } - if(g_hash_table_contains(functions,fun->name)){ + if (g_hash_table_contains(functions, fun->name)) { // TODO: delete fun return SEMANTIC_ERROR; } - g_hash_table_insert(functions,(gpointer)fun->name, fun); - - g_hash_table_destroy(functionParameter); + g_hash_table_insert(functions, (gpointer) fun->name, fun); + return SEMANTIC_OK; -} +} +int createDeclMember(BoxType *ParentBox, AST_NODE_PTR currentNode) { -int createDeclMember(BoxType * ParentBox, AST_NODE_PTR currentNode){ - - Type * declType = mem_alloc(MemoryNamespaceSet,sizeof(Type)); - int status = get_type_impl(currentNode->children[0],&declType); - if(status){ - return SEMANTIC_ERROR; + Type *declType = mem_alloc(MemoryNamespaceSet, sizeof(Type)); + int status = get_type_impl(currentNode->children[0], &declType); + if (status) { + return SEMANTIC_ERROR; } AST_NODE_PTR nameList = currentNode->children[1]; - for(size_t i = 0; i < nameList->child_count; i++){ - BoxMember * decl = mem_alloc(MemoryNamespaceSet,sizeof(BoxMember)); + for (size_t i = 0; i < nameList->child_count; i++) { + BoxMember *decl = mem_alloc(MemoryNamespaceSet, sizeof(BoxMember)); decl->name = nameList->children[i]->value; decl->nodePtr = currentNode; decl->box = ParentBox; decl->initalizer = NULL; decl->type = declType; - if(g_hash_table_contains(ParentBox->member, (gpointer)decl->name)){ + if (g_hash_table_contains(ParentBox->member, (gpointer) decl->name)) { return SEMANTIC_ERROR; } - g_hash_table_insert(ParentBox->member,(gpointer)decl->name,decl); + g_hash_table_insert(ParentBox->member, (gpointer) decl->name, decl); } return SEMANTIC_OK; } -int createDefMember(BoxType *ParentBox, AST_NODE_PTR currentNode){ +int createDefMember(BoxType *ParentBox, AST_NODE_PTR currentNode) { AST_NODE_PTR declNode = currentNode->children[0]; AST_NODE_PTR expressionNode = currentNode->children[1]; AST_NODE_PTR nameList = declNode->children[1]; - Type * declType = mem_alloc(MemoryNamespaceSet,sizeof(Type)); - int status = get_type_impl(currentNode->children[0],&declType); - if(status){ - return SEMANTIC_ERROR; - } - - Expression * init = createExpression(expressionNode);; - if (init == NULL){ + Type *declType = mem_alloc(MemoryNamespaceSet, sizeof(Type)); + int status = get_type_impl(currentNode->children[0], &declType); + if (status) { return SEMANTIC_ERROR; } - - for (size_t i = 0; i < nameList->child_count; i++){ - BoxMember *def = mem_alloc(MemoryNamespaceSet,sizeof(BoxMember)); - def->box = ParentBox; - def->type = declType; - def->initalizer = init; - def->name = nameList->children[i]->value; - def->nodePtr = currentNode; - if(g_hash_table_contains(ParentBox->member, (gpointer)def->name)){ + + Expression *init = createExpression(expressionNode);; + if (init == NULL) { return SEMANTIC_ERROR; } - g_hash_table_insert(ParentBox->member,(gpointer)def->name,def); + + for (guint i = 0; i < nameList->child_count; i++) { + BoxMember *def = mem_alloc(MemoryNamespaceSet, sizeof(BoxMember)); + def->box = ParentBox; + def->type = declType; + def->initalizer = init; + def->name = nameList->children[i]->value; + def->nodePtr = currentNode; + if (g_hash_table_contains(ParentBox->member, (gpointer) def->name)) { + return SEMANTIC_ERROR; + } + g_hash_table_insert(ParentBox->member, (gpointer) def->name, def); } return SEMANTIC_OK; } -int createBox(GHashTable *boxes, AST_NODE_PTR currentNode){ - BoxType * box = mem_alloc(MemoryNamespaceSet,sizeof(BoxType)); - +int createBox(GHashTable *boxes, AST_NODE_PTR currentNode) { + BoxType *box = mem_alloc(MemoryNamespaceSet, sizeof(BoxType)); + box->nodePtr = currentNode; - const char * boxName = currentNode->children[0]->value; + const char *boxName = currentNode->children[0]->value; AST_NODE_PTR boxMemberList = currentNode->children[1]; - for (size_t i = 0; boxMemberList->child_count; i++){ + for (guint i = 0; boxMemberList->child_count; i++) { switch (boxMemberList->children[i]->kind) { - case AST_Decl: - if(createDeclMember(box, boxMemberList->children[i]->children[i])){ - return SEMANTIC_ERROR; - } - break; case AST_Def: - if(createDeclMember(box, boxMemberList->children[i]->children[i])){ + case AST_Decl: + if (createDeclMember(box, boxMemberList->children[i]->children[i])) { return SEMANTIC_ERROR; } break; case AST_Fun: - //TODO FUNCTION Wait for createFunction() + //TODO FUNCTION Wait for createFunction() default: break; } - } - if(g_hash_table_contains(boxes, (gpointer)boxName)){ + if (g_hash_table_contains(boxes, (gpointer) boxName)) { return SEMANTIC_ERROR; } - g_hash_table_insert(boxes, (gpointer)boxName, box); + g_hash_table_insert(boxes, (gpointer) boxName, box); return SEMANTIC_OK; - - - // - //box - // name - // list - // decl - // def // change BoxMember to have an - // fun //create static function - // a.b(dsadsadas) - - //type box: boxy { - // - //long short int: a - // - //short short float: floaty = 0.54 - // - //fun main (){ - //int: a = 5 - //} - } - -int createTypeDef(GHashTable *types, AST_NODE_PTR currentNode){ + +int createTypeDef(GHashTable *types, AST_NODE_PTR currentNode) { DEBUG("create Type define"); AST_NODE_PTR typeNode = currentNode->children[0]; AST_NODE_PTR nameNode = currentNode->children[1]; - - - Type * type = mem_alloc(MemoryNamespaceSet,sizeof(Type)); - int status = get_type_impl( typeNode, &type); - if(status){ + + Type *type = mem_alloc(MemoryNamespaceSet, sizeof(Type)); + int status = get_type_impl(typeNode, &type); + if (status) { return SEMANTIC_ERROR; } - - Typedefine *def = mem_alloc(MemoryNamespaceSet,sizeof(Typedefine)); + + Typedefine *def = mem_alloc(MemoryNamespaceSet, sizeof(Typedefine)); def->name = nameNode->value; def->nodePtr = currentNode; def->type = type; - - if(g_hash_table_contains(types, (gpointer)def->name)){ + + if (g_hash_table_contains(types, (gpointer) def->name)) { return SEMANTIC_ERROR; } - g_hash_table_insert(types, (gpointer)def->name, def); - if(g_hash_table_contains(declaredComposites, (gpointer)def->name)){ + g_hash_table_insert(types, (gpointer) def->name, def); + if (g_hash_table_contains(declaredComposites, (gpointer) def->name)) { return SEMANTIC_ERROR; } - g_hash_table_insert(declaredComposites, (gpointer)def->name, def); + g_hash_table_insert(declaredComposites, (gpointer) def->name, def); return SEMANTIC_OK; } -Module *create_set(AST_NODE_PTR currentNode){ +Module *create_set(AST_NODE_PTR currentNode) { DEBUG("create root Module"); //create tables for types - declaredComposites = g_hash_table_new(g_str_hash,g_str_equal); - declaredBoxes = g_hash_table_new(g_str_hash,g_str_equal); + declaredComposites = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal); + declaredBoxes = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal); //create scope - Scope = g_array_new(FALSE, FALSE, sizeof(GHashTable*)); - + Scope = mem_new_g_array(MemoryNamespaceSet, sizeof(GHashTable *)); //building current scope for module - GHashTable *globalscope = g_hash_table_new(g_str_hash, g_str_equal); - globalscope = g_hash_table_new(g_str_hash,g_str_equal); + GHashTable *globalscope = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal); + globalscope = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal); g_array_append_val(Scope, globalscope); - Module *rootModule = mem_alloc(MemoryNamespaceSet,sizeof(Module)); + Module *rootModule = mem_alloc(MemoryNamespaceSet, sizeof(Module)); + + GHashTable *boxes = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal); + GHashTable *types = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal); + GHashTable *functions = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal); + GHashTable *variables = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal); + GArray *imports = mem_new_g_array(MemoryNamespaceSet, sizeof(const char *)); - GHashTable *boxes = g_hash_table_new(g_str_hash,g_str_equal); - GHashTable *types = g_hash_table_new(g_str_hash,g_str_equal); - GHashTable *functions = g_hash_table_new(g_str_hash,g_str_equal); - GHashTable *variables = g_hash_table_new(g_str_hash,g_str_equal); - GArray *imports = g_array_new(FALSE, FALSE, sizeof(const char*)); - rootModule->boxes = boxes; rootModule->types = types; rootModule->functions = functions; @@ -1896,83 +1773,76 @@ Module *create_set(AST_NODE_PTR currentNode){ DEBUG("created Module struct"); + for (size_t i = 0; i < currentNode->child_count; i++) { + DEBUG("created Child: %i", currentNode->children[i]->kind); + switch (currentNode->children[i]->kind) { - for (size_t i = 0; i < currentNode->child_count; i++){ - DEBUG("created Child: %i" ,currentNode->children[i]->kind); - switch(currentNode->children[i]->kind){ - - case AST_Decl: { - GArray* vars; - int status = createDecl(currentNode->children[i], &vars); - if (status){ - // TODO: free vars - return NULL; - } - if (fillTablesWithVars(variables, vars) == SEMANTIC_ERROR) { - // TODO: this diagnostic will highlight entire declaration of - // of variables even if just one of the declared variables - // is duplicate. Consider moving this diagnostic to - // `fillTablesWithVars` for more precise messaging. - print_diagnostic(current_file, ¤tNode->children[i]->location, Error, "Variable already declared"); - INFO("var already exists"); - // TODO: free vars + case AST_Decl: { + GArray *vars; + int status = createDecl(currentNode->children[i], &vars); + if (status) { + return NULL; + } + if (fillTablesWithVars(variables, vars) == SEMANTIC_ERROR) { + // TODO: this diagnostic will highlight entire declaration of + // of variables even if just one of the declared variables + // is duplicate. Consider moving this diagnostic to + // `fillTablesWithVars` for more precise messaging. + print_diagnostic(current_file, ¤tNode->children[i]->location, Error, + "Variable already declared"); + INFO("var already exists"); + break; + } + DEBUG("filled successfull the module and scope with vars"); break; } - // TODO: free vars - DEBUG("filled successfull the module and scope with vars"); - break; - } - case AST_Def: { - GArray* vars; - int status = createDef(currentNode->children[i], &vars); - if (status){ + case AST_Def: { + GArray *vars; + int status = createDef(currentNode->children[i], &vars); + if (status) { + return NULL; + } // TODO: free vars - // TODO: cleanup global memory - return NULL; + DEBUG("created Definition successfully"); + break; } - // TODO: free vars - DEBUG("created Definition successfully"); - break; - } - case AST_Box:{ - int status = createBox(boxes, currentNode->children[i]); - if (status){ - // TODO: cleanup global memory - return NULL; + case AST_Box: { + int status = createBox(boxes, currentNode->children[i]); + if (status) { + return NULL; + } + DEBUG("created Box successfully"); + break; } - DEBUG("created Box successfully"); - break; - } - case AST_Fun:{ - DEBUG("start function"); - int status = createFunction(functions,currentNode->children[i]); - if (status){ - // TODO: cleanup global memory - return NULL; - } - DEBUG("created function successfully"); - break; + case AST_Fun: { + DEBUG("start function"); + int status = createFunction(functions, currentNode->children[i]); + if (status) { + return NULL; + } + DEBUG("created function successfully"); + break; } - case AST_Typedef:{ - int status = createTypeDef(types, currentNode->children[i]); - if (status){ - // TODO: cleanup global memory - return NULL; + case AST_Typedef: { + int status = createTypeDef(types, currentNode->children[i]); + if (status) { + return NULL; + } + DEBUG("created Typedef successfully"); + break; } - DEBUG("created Typedef successfully"); - break; - } - case AST_Import: - DEBUG("create Import"); - g_array_append_val(imports, currentNode->children[i]->value); - break; - default: - INFO("Provided source file could not be parsed because of semantic error."); - break; + case AST_Import: + DEBUG("create Import"); + g_array_append_val(imports, currentNode->children[i]->value); + break; + default: + INFO("Provided source file could not be parsed because of semantic error."); + break; } } + DEBUG("created set successfully"); return rootModule; } diff --git a/src/set/types.c b/src/set/types.c deleted file mode 100644 index a589952..0000000 --- a/src/set/types.c +++ /dev/null @@ -1,186 +0,0 @@ -// -// Created by servostar on 6/7/24. -// - -#include -#include - -void delete_box(BoxType *box) { - g_hash_table_destroy(box->member); - mem_free(box); -} - -static void delete_box_table(GHashTable *box_table) { - GHashTableIter iter; - char *name = NULL; - BoxType *box = NULL; - - g_hash_table_iter_init(&iter, box_table); - - while (g_hash_table_iter_next(&iter, (gpointer)&name, (gpointer)&box)) { - delete_box(box); - mem_free(name); - } - - g_hash_table_destroy(box_table); -} - -static void delete_imports(GArray *imports) { g_array_free(imports, TRUE); } - -void delete_box_member(BoxMember *member) { - member->box = NULL; - delete_expression(member->initalizer); - delete_type(member->type); - mem_free((void *)member->name); -} - -void delete_box_type(BoxType *box_type) { - GHashTableIter iter; - char *name = NULL; - BoxMember *member = NULL; - - g_hash_table_iter_init(&iter, box_type->member); - - while (g_hash_table_iter_next(&iter, (gpointer)&name, (gpointer)&member)) { - delete_box_member(member); - mem_free(name); - } - - g_hash_table_destroy(box_type->member); -} - -void delete_composite([[maybe_unused]] CompositeType *composite) {} - -void delete_type(Type *type) { - switch (type->kind) { - case TypeKindBox: - delete_box_type(&type->impl.box); - break; - case TypeKindReference: - delete_type(type->impl.reference); - break; - case TypeKindPrimitive: - break; - case TypeKindComposite: - delete_composite(&type->impl.composite); - break; - } -} - -static void delete_type_table(GHashTable *type_table) { - - GHashTableIter iter; - char *name = NULL; - Type *type = NULL; - - g_hash_table_iter_init(&iter, type_table); - - while (g_hash_table_iter_next(&iter, (gpointer)&name, (gpointer)&type)) { - delete_type(type); - mem_free(name); - } - - g_hash_table_destroy(type_table); -} - -void delete_box_access(BoxAccess *access) { - delete_variable(access->variable); - - for (guint i = 0; i < access->member->len; i++) { - delete_box_member(g_array_index(access->member, BoxMember *, i)); - } - - g_array_free(access->member, TRUE); -} - -void delete_variable(Variable *variable) { - switch (variable->kind) { - case VariableKindBoxMember: - delete_box_access(&variable->impl.member); - break; - case VariableKindDeclaration: - delete_declaration(&variable->impl.declaration); - break; - case VariableKindDefinition: - delete_definition(&variable->impl.definiton); - break; - } -} - -void delete_declaration(VariableDeclaration *decl) { delete_type(decl->type); } - -void delete_definition(VariableDefiniton *definition) { - delete_declaration(&definition->declaration); - delete_expression(definition->initializer); -} - -void delete_type_value(TypeValue *value) { - delete_type(value->type); - mem_free(value); -} - -void delete_operation(Operation *operation) { - for (guint i = 0; i < operation->operands->len; i++) { - delete_expression(g_array_index(operation->operands, Expression *, i)); - } - - g_array_free(operation->operands, TRUE); -} - -void delete_transmute(Transmute *trans) { - delete_expression(trans->operand); - delete_type(trans->targetType); -} - -void delete_typecast(TypeCast *cast) { - delete_expression(cast->operand); - delete_type(cast->targetType); -} - -void delete_expression(Expression *expr) { - delete_type(expr->result); - - switch (expr->kind) { - case ExpressionKindConstant: - delete_type_value(&expr->impl.constant); - break; - case ExpressionKindOperation: - delete_operation(&expr->impl.operation); - break; - case ExpressionKindTransmute: - delete_transmute(&expr->impl.transmute); - break; - case ExpressionKindTypeCast: - delete_typecast(&expr->impl.typecast); - break; - case ExpressionKindVariable: - delete_variable(expr->impl.variable); - break; - } -} - -static void delete_variable_table(GHashTable *variable_table) { - - GHashTableIter iter; - char *name = NULL; - Variable *variable = NULL; - - g_hash_table_iter_init(&iter, variable_table); - - while (g_hash_table_iter_next(&iter, (gpointer)&name, (gpointer)&variable)) { - delete_variable(variable); - mem_free(name); - } - - g_hash_table_destroy(variable_table); -} - -void delete_module(Module *module) { - - delete_box_table(module->boxes); - delete_imports(module->imports); - delete_type_table(module->types); - delete_variable_table(module->variables); - - mem_free(module); -}