diff --git a/src/compiler.c b/src/compiler.c index 38ce793..68fd6e1 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -147,7 +147,7 @@ static void build_target(ModuleFileStack *unit, const TargetConfig *target) { // TODO: parse AST to semantic values // TODO: backend codegen - mem_free(test); + delete_set(test); } } @@ -155,6 +155,7 @@ static void build_target(ModuleFileStack *unit, const TargetConfig *target) { mem_purge_namespace(MemoryNamespaceLex); mem_purge_namespace(MemoryNamespaceAst); + mem_purge_namespace(MemoryNamespaceSet); print_file_statistics(file); } diff --git a/src/set/set.c b/src/set/set.c index c11fc64..4330c74 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -12,13 +12,88 @@ #include #include - 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 = { @@ -70,7 +145,9 @@ int primitive_from_string(const char* string, PrimitiveType* primitive) { if (strcmp(string, "int") == 0) { *primitive = Int; return SEMANTIC_OK; - } else if (strcmp(string, "float") == 0) { + } + + if (strcmp(string, "float") == 0) { *primitive = Float; return SEMANTIC_OK; } @@ -85,7 +162,9 @@ int scale_factor_from(const char* string, double* factor) { if (strcmp(string, "half") == 0 || strcmp(string, "short") == 0) { *factor = 0.5; return SEMANTIC_OK; - } else if (strcmp(string, "double") == 0 || strcmp(string, "long") == 0) { + } + + if (strcmp(string, "double") == 0 || strcmp(string, "long") == 0) { *factor = 2.0; return SEMANTIC_OK; } @@ -1637,6 +1716,7 @@ int createFunction(GHashTable* functions, AST_NODE_PTR currentNode){ PANIC("function should have 2 or 3 children"); } if(g_hash_table_contains(functions,fun->name)){ + // TODO: delete fun return SEMANTIC_ERROR; } g_hash_table_insert(functions,(gpointer)fun->name, fun); @@ -1796,7 +1876,7 @@ Module *create_set(AST_NODE_PTR currentNode){ //building current scope for module - GHashTable *globalscope = mem_alloc(MemoryNamespaceSet,sizeof(GHashTable*)); + GHashTable *globalscope = g_hash_table_new(g_str_hash, g_str_equal); globalscope = g_hash_table_new(g_str_hash,g_str_equal); g_array_append_val(Scope, globalscope); @@ -1825,13 +1905,20 @@ Module *create_set(AST_NODE_PTR currentNode){ 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 break; } + // TODO: free vars DEBUG("filled successfull the module and scope with vars"); break; } @@ -1839,14 +1926,18 @@ Module *create_set(AST_NODE_PTR currentNode){ GArray* vars; int status = createDef(currentNode->children[i], &vars); if (status){ + // TODO: free vars + // TODO: cleanup global memory return NULL; } + // 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; } DEBUG("created Box successfully"); @@ -1856,6 +1947,7 @@ Module *create_set(AST_NODE_PTR currentNode){ DEBUG("start function"); int status = createFunction(functions,currentNode->children[i]); if (status){ + // TODO: cleanup global memory return NULL; } DEBUG("created function successfully"); @@ -1865,6 +1957,7 @@ Module *create_set(AST_NODE_PTR currentNode){ case AST_Typedef:{ int status = createTypeDef(types, currentNode->children[i]); if (status){ + // TODO: cleanup global memory return NULL; } DEBUG("created Typedef successfully"); diff --git a/src/set/set.h b/src/set/set.h index e7a5048..e321fd4 100644 --- a/src/set/set.h +++ b/src/set/set.h @@ -9,4 +9,6 @@ Module * create_set(AST_NODE_PTR rootNodePtr ); +void delete_set(Module* module); + #endif diff --git a/src/set/types.c b/src/set/types.c new file mode 100644 index 0000000..a589952 --- /dev/null +++ b/src/set/types.c @@ -0,0 +1,186 @@ +// +// 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); +} diff --git a/src/set/types.h b/src/set/types.h index 1d415c1..2b4c180 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -543,4 +543,38 @@ typedef struct Module_t { GArray* imports; } Module; +// .------------------------------------------------. +// | Cleanup Code | +// '------------------------------------------------' + +void delete_box_access(BoxAccess* access); + +void delete_variable(Variable* variable); + +void delete_type(Type* type); + +void delete_box(BoxType* box); + +void delete_declaration(VariableDeclaration* decl); + +void delete_definition(VariableDefiniton* definition); + +void delete_expression(Expression* expr); + +void delete_operation(Operation* operation); + +void delete_type_value(TypeValue* value); + +void delete_transmute(Transmute* trans); + +void delete_typecast(TypeCast* cast); + +void delete_box_member(BoxMember* member); + +void delete_box_type(BoxType *box_type); + +void delete_composite([[maybe_unused]] CompositeType* composite); + +void delete_module(Module* module); + #endif // SET_TYPES_H_