fixed: memory leaks
added: memory cache for GLIB arrays and hashtables
This commit is contained in:
parent
7f0ca78f92
commit
150f87990a
|
@ -183,7 +183,7 @@ void print_help(void) {
|
||||||
" --debug print debug logs (if not disabled at compile time)",
|
" --debug print debug logs (if not disabled at compile time)",
|
||||||
" --version print the version",
|
" --version print the version",
|
||||||
" --help print this hel dialog",
|
" --help print this hel dialog",
|
||||||
" --print-memory-stats print statistics of the garbage collector"
|
" --print-gc-stats print statistics of the garbage collector"
|
||||||
};
|
};
|
||||||
|
|
||||||
for (unsigned int i = 0; i < sizeof(lines) / sizeof(const char *); i++) {
|
for (unsigned int i = 0; i < sizeof(lines) / sizeof(const char *); i++) {
|
||||||
|
|
|
@ -146,8 +146,6 @@ static void build_target(ModuleFileStack *unit, const TargetConfig *target) {
|
||||||
|
|
||||||
// TODO: parse AST to semantic values
|
// TODO: parse AST to semantic values
|
||||||
// TODO: backend codegen
|
// TODO: backend codegen
|
||||||
|
|
||||||
delete_set(test);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
run_compiler();
|
run_compiler();
|
||||||
|
|
||||||
if (is_option_set("print-memory-stats")) {
|
if (is_option_set("print-gc-stats")) {
|
||||||
print_memory_statistics();
|
print_memory_statistics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
102
src/mem/cache.c
102
src/mem/cache.c
|
@ -7,6 +7,7 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <cfg/opt.h>
|
||||||
|
|
||||||
static GHashTable* namespaces = NULL;
|
static GHashTable* namespaces = NULL;
|
||||||
|
|
||||||
|
@ -20,6 +21,17 @@ typedef struct MemoryNamespaceStatistic_t {
|
||||||
size_t purged_free_count;
|
size_t purged_free_count;
|
||||||
} MemoryNamespaceStatistic;
|
} 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 {
|
typedef struct MemoryNamespace_t {
|
||||||
MemoryNamespaceStatistic statistic;
|
MemoryNamespaceStatistic statistic;
|
||||||
GArray* blocks;
|
GArray* blocks;
|
||||||
|
@ -44,9 +56,11 @@ static void* namespace_malloc(MemoryNamespaceRef memoryNamespace, size_t size) {
|
||||||
assert(memoryNamespace != NULL);
|
assert(memoryNamespace != NULL);
|
||||||
assert(size != 0);
|
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 ++;
|
memoryNamespace->statistic.faulty_allocations ++;
|
||||||
} else {
|
} else {
|
||||||
g_array_append_val(memoryNamespace->blocks, block);
|
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;
|
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) {
|
static gboolean namespace_free(MemoryNamespaceRef memoryNamespace, void* block) {
|
||||||
for (guint i = 0; i < memoryNamespace->blocks->len; i++) {
|
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);
|
assert(block != NULL);
|
||||||
|
|
||||||
free(block);
|
namespace_free_block(current_block);
|
||||||
|
|
||||||
g_array_remove_index(memoryNamespace->blocks, i);
|
g_array_remove_index(memoryNamespace->blocks, i);
|
||||||
|
|
||||||
memoryNamespace->statistic.manual_free_count++;
|
memoryNamespace->statistic.manual_free_count++;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,13 +109,13 @@ static void* namespace_realloc(MemoryNamespaceRef memoryNamespace, void* block,
|
||||||
void* reallocated_block = NULL;
|
void* reallocated_block = NULL;
|
||||||
|
|
||||||
for (guint i = 0; i < memoryNamespace->blocks->len; i++) {
|
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) {
|
||||||
reallocated_block = realloc(block, size);
|
reallocated_block = realloc(current_block.block_ptr, size);
|
||||||
|
|
||||||
if (reallocated_block != NULL) {
|
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.bytes_allocated += size;
|
||||||
memoryNamespace->statistic.reallocation_count ++;
|
memoryNamespace->statistic.reallocation_count ++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -107,9 +137,9 @@ static void namespace_delete(MemoryNamespaceRef memoryNamespace) {
|
||||||
static void namespace_purge(MemoryNamespaceRef memoryNamespace) {
|
static void namespace_purge(MemoryNamespaceRef memoryNamespace) {
|
||||||
|
|
||||||
for (guint i = 0; i < memoryNamespace->blocks->len; i++) {
|
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 ++;
|
memoryNamespace->statistic.purged_free_count ++;
|
||||||
}
|
}
|
||||||
|
@ -120,7 +150,7 @@ static void namespace_purge(MemoryNamespaceRef memoryNamespace) {
|
||||||
static MemoryNamespaceRef namespace_new() {
|
static MemoryNamespaceRef namespace_new() {
|
||||||
MemoryNamespaceRef memoryNamespace = malloc(sizeof(MemoryNamespace));
|
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.bytes_allocated = 0;
|
||||||
memoryNamespace->statistic.allocation_count = 0;
|
memoryNamespace->statistic.allocation_count = 0;
|
||||||
memoryNamespace->statistic.manual_free_count = 0;
|
memoryNamespace->statistic.manual_free_count = 0;
|
||||||
|
@ -132,6 +162,30 @@ static MemoryNamespaceRef namespace_new() {
|
||||||
return memoryNamespace;
|
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() {
|
static void cleanup() {
|
||||||
if (namespaces == NULL) {
|
if (namespaces == NULL) {
|
||||||
printf("==> Memory cache was unused <==\n");
|
printf("==> Memory cache was unused <==\n");
|
||||||
|
@ -267,5 +321,25 @@ void print_memory_statistics() {
|
||||||
|
|
||||||
namespace_statistics_print(&total, "summary");
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <mem/cache.h>
|
#include <mem/cache.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
typedef char* MemoryNamespaceName;
|
typedef char* MemoryNamespaceName;
|
||||||
|
|
||||||
|
@ -86,4 +87,8 @@ void* mem_clone(MemoryNamespaceName name, void* data, size_t size);
|
||||||
|
|
||||||
void print_memory_statistics();
|
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
|
#endif //GEMSTONE_CACHE_H
|
||||||
|
|
360
src/set/set.c
360
src/set/set.c
|
@ -1,10 +1,6 @@
|
||||||
#include <io/files.h>
|
#include <io/files.h>
|
||||||
#include <yacc/parser.tab.h>
|
|
||||||
#include <complex.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ast/ast.h>
|
#include <ast/ast.h>
|
||||||
#include <set/types.h>
|
#include <set/types.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/log.h>
|
#include <sys/log.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
@ -18,82 +14,6 @@ static GHashTable *declaredBoxes = NULL;//pointer to typeboxes
|
||||||
static GHashTable *functionParameter = NULL;
|
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 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 = {
|
const Type ShortShortUnsingedIntType = {
|
||||||
.kind = TypeKindComposite,
|
.kind = TypeKindComposite,
|
||||||
.impl = {
|
.impl = {
|
||||||
|
@ -124,13 +44,15 @@ int sign_from_string(const char* string, Sign* sign) {
|
||||||
|
|
||||||
if (strcmp(string, "unsigned") == 0) {
|
if (strcmp(string, "unsigned") == 0) {
|
||||||
*sign = Unsigned;
|
*sign = Unsigned;
|
||||||
return 0;
|
return SEMANTIC_OK;
|
||||||
} else if (strcmp(string, "signed") == 0) {
|
|
||||||
*sign = Signed;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
if (strcmp(string, "signed") == 0) {
|
||||||
|
*sign = Signed;
|
||||||
|
return SEMANTIC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -179,10 +101,12 @@ int check_scale_factor(AST_NODE_PTR node, Scale scale) {
|
||||||
print_diagnostic(current_file, &node->location, Error, "Composite scale overflow");
|
print_diagnostic(current_file, &node->location, Error, "Composite scale overflow");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0.25 > scale) {
|
if (0.25 > scale) {
|
||||||
print_diagnostic(current_file, &node->location, Error, "Composite scale underflow");
|
print_diagnostic(current_file, &node->location, Error, "Composite scale underflow");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,8 +271,6 @@ int get_type_impl(AST_NODE_PTR currentNode, Type** type) {
|
||||||
status = impl_composite_type(currentNode, &new_type->impl.composite);
|
status = impl_composite_type(currentNode, &new_type->impl.composite);
|
||||||
*type = new_type;
|
*type = new_type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,6 +286,7 @@ StorageQualifier Qualifier_from_string(const char *str) {
|
||||||
|
|
||||||
PANIC("Provided string is not a storagequalifier: %s", str);
|
PANIC("Provided string is not a storagequalifier: %s", str);
|
||||||
}
|
}
|
||||||
|
|
||||||
int addVarToScope(Variable *variable);
|
int addVarToScope(Variable *variable);
|
||||||
|
|
||||||
int createDecl(AST_NODE_PTR currentNode, GArray **variables) {
|
int createDecl(AST_NODE_PTR currentNode, GArray **variables) {
|
||||||
|
@ -371,7 +294,7 @@ int createDecl(AST_NODE_PTR currentNode, GArray** variables) {
|
||||||
|
|
||||||
AST_NODE_PTR ident_list = currentNode->children[currentNode->child_count - 1];
|
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;
|
VariableDeclaration decl;
|
||||||
decl.nodePtr = currentNode;
|
decl.nodePtr = currentNode;
|
||||||
|
@ -430,8 +353,7 @@ int createDef(AST_NODE_PTR currentNode, GArray** variables) {
|
||||||
AST_NODE_PTR expression = currentNode->children[1];
|
AST_NODE_PTR expression = currentNode->children[1];
|
||||||
AST_NODE_PTR ident_list = declaration->children[currentNode->child_count - 1];
|
AST_NODE_PTR ident_list = declaration->children[currentNode->child_count - 1];
|
||||||
|
|
||||||
|
*variables = mem_new_g_array(MemoryNamespaceSet, sizeof(Variable *));
|
||||||
*variables = g_array_new(FALSE, FALSE, sizeof(Variable*));
|
|
||||||
|
|
||||||
VariableDeclaration decl;
|
VariableDeclaration decl;
|
||||||
VariableDefiniton def;
|
VariableDefiniton def;
|
||||||
|
@ -467,7 +389,6 @@ int createDef(AST_NODE_PTR currentNode, GArray** variables) {
|
||||||
}
|
}
|
||||||
def.initializer = name;
|
def.initializer = name;
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 0; i < ident_list->child_count; i++) {
|
for (size_t i = 0; i < ident_list->child_count; i++) {
|
||||||
Variable *variable = mem_alloc(MemoryNamespaceSet, sizeof(Variable));
|
Variable *variable = mem_alloc(MemoryNamespaceSet, sizeof(Variable));
|
||||||
|
|
||||||
|
@ -475,9 +396,10 @@ int createDef(AST_NODE_PTR currentNode, GArray** variables) {
|
||||||
variable->nodePtr = currentNode;
|
variable->nodePtr = currentNode;
|
||||||
variable->name = ident_list->children[i]->value;
|
variable->name = ident_list->children[i]->value;
|
||||||
variable->impl.definiton = def;
|
variable->impl.definiton = def;
|
||||||
|
|
||||||
g_array_append_val(*variables, variable);
|
g_array_append_val(*variables, variable);
|
||||||
int signal = addVarToScope(variable);
|
|
||||||
if (signal){
|
if (addVarToScope(variable) == SEMANTIC_ERROR) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -485,38 +407,6 @@ int createDef(AST_NODE_PTR currentNode, GArray** variables) {
|
||||||
return status;
|
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(name != NULL);
|
||||||
assert(variable != NULL);
|
assert(variable != NULL);
|
||||||
|
@ -531,8 +421,8 @@ int getVariableFromScope(const char* name, Variable** variable) {
|
||||||
found += 1;
|
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);
|
GHashTable *variable_table = g_array_index(Scope, GHashTable*, i);
|
||||||
|
|
||||||
|
@ -571,8 +461,7 @@ int addVarToScope(Variable * variable){
|
||||||
int fillTablesWithVars(GHashTable *variableTable, const GArray *variables) {
|
int fillTablesWithVars(GHashTable *variableTable, const GArray *variables) {
|
||||||
DEBUG("filling vars in scope and table");
|
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);
|
||||||
|
|
||||||
|
@ -588,6 +477,7 @@ int fillTablesWithVars(GHashTable *variableTable, const GArray* variables) {
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard("type must be freed")]]
|
[[nodiscard("type must be freed")]]
|
||||||
|
|
||||||
TypeValue createTypeValue(AST_NODE_PTR currentNode) {
|
TypeValue createTypeValue(AST_NODE_PTR currentNode) {
|
||||||
DEBUG("create TypeValue");
|
DEBUG("create TypeValue");
|
||||||
TypeValue value;
|
TypeValue value;
|
||||||
|
@ -600,11 +490,9 @@ TypeValue createTypeValue(AST_NODE_PTR currentNode){
|
||||||
case AST_Int:
|
case AST_Int:
|
||||||
type->impl.primitive = Int;
|
type->impl.primitive = Int;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_Float:
|
case AST_Float:
|
||||||
type->impl.primitive = Float;
|
type->impl.primitive = Float;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PANIC("Node is not an expression but from kind: %i", currentNode->kind);
|
PANIC("Node is not an expression but from kind: %i", currentNode->kind);
|
||||||
break;
|
break;
|
||||||
|
@ -620,8 +508,7 @@ TypeValue createTypeValue(AST_NODE_PTR currentNode){
|
||||||
TypeValue createString(AST_NODE_PTR currentNode) {
|
TypeValue createString(AST_NODE_PTR currentNode) {
|
||||||
DEBUG("create String");
|
DEBUG("create String");
|
||||||
TypeValue value;
|
TypeValue value;
|
||||||
Type *type = CLONE(StringLiteralType);
|
value.type = CLONE(StringLiteralType);
|
||||||
value.type = type;
|
|
||||||
value.nodePtr = currentNode;
|
value.nodePtr = currentNode;
|
||||||
value.value = currentNode->value;
|
value.value = currentNode->value;
|
||||||
return value;
|
return value;
|
||||||
|
@ -641,7 +528,8 @@ Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_
|
||||||
resultImpl.nodePtr = currentNode;
|
resultImpl.nodePtr = currentNode;
|
||||||
resultImpl.sign = MAX(LeftOperandType->impl.composite.sign, RightOperandType->impl.composite.sign);
|
resultImpl.sign = MAX(LeftOperandType->impl.composite.sign, RightOperandType->impl.composite.sign);
|
||||||
resultImpl.scale = MAX(LeftOperandType->impl.composite.scale, RightOperandType->impl.composite.scale);
|
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;
|
result->impl.composite = resultImpl;
|
||||||
|
|
||||||
|
@ -676,13 +564,20 @@ Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_
|
||||||
|
|
||||||
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");
|
DEBUG("create arithmetic operation");
|
||||||
ParentExpression->impl.operation.kind = Arithmetic;
|
ParentExpression->impl.operation.
|
||||||
ParentExpression->impl.operation.nodePtr = currentNode;
|
kind = Arithmetic;
|
||||||
ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE,sizeof(Expression*));
|
ParentExpression->impl.operation.
|
||||||
|
nodePtr = currentNode;
|
||||||
|
ParentExpression->impl.operation.
|
||||||
|
operands = mem_new_g_array(MemoryNamespaceSet, sizeof(Expression *));
|
||||||
|
|
||||||
assert(expectedChildCount == currentNode->child_count);
|
assert(expectedChildCount == currentNode->child_count);
|
||||||
|
|
||||||
for (size_t i = 0; i < currentNode->child_count; i++) {
|
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) {
|
||||||
|
@ -694,19 +589,24 @@ int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode,
|
||||||
DEBUG("created all Expressions");
|
DEBUG("created all Expressions");
|
||||||
switch (currentNode->kind) {
|
switch (currentNode->kind) {
|
||||||
case AST_Add:
|
case AST_Add:
|
||||||
ParentExpression->impl.operation.impl.arithmetic = Add;
|
ParentExpression->impl.operation.impl.
|
||||||
|
arithmetic = Add;
|
||||||
break;
|
break;
|
||||||
case AST_Sub:
|
case AST_Sub:
|
||||||
ParentExpression->impl.operation.impl.arithmetic = Sub;
|
ParentExpression->impl.operation.impl.
|
||||||
|
arithmetic = Sub;
|
||||||
break;
|
break;
|
||||||
case AST_Mul:
|
case AST_Mul:
|
||||||
ParentExpression->impl.operation.impl.arithmetic = Mul;
|
ParentExpression->impl.operation.impl.
|
||||||
|
arithmetic = Mul;
|
||||||
break;
|
break;
|
||||||
case AST_Div:
|
case AST_Div:
|
||||||
ParentExpression->impl.operation.impl.arithmetic = Div;
|
ParentExpression->impl.operation.impl.
|
||||||
|
arithmetic = Div;
|
||||||
break;
|
break;
|
||||||
case AST_Negate:
|
case AST_Negate:
|
||||||
ParentExpression->impl.operation.impl.arithmetic = Negate;
|
ParentExpression->impl.operation.impl.
|
||||||
|
arithmetic = Negate;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PANIC("Current node is not an arithmetic operater");
|
PANIC("Current node is not an arithmetic operater");
|
||||||
|
@ -716,21 +616,26 @@ int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode,
|
||||||
if (ParentExpression->impl.operation.impl.arithmetic == Negate) {
|
if (ParentExpression->impl.operation.impl.arithmetic == Negate) {
|
||||||
|
|
||||||
Type *result = g_array_index(ParentExpression->impl.operation.operands, Expression *, 0)->result;
|
Type *result = g_array_index(ParentExpression->impl.operation.operands, Expression *, 0)->result;
|
||||||
result->nodePtr = currentNode;
|
result->
|
||||||
|
nodePtr = currentNode;
|
||||||
|
|
||||||
if (result->kind == TypeKindReference || result->kind == TypeKindBox) {
|
if (result->kind == TypeKindReference || result->kind == TypeKindBox) {
|
||||||
print_diagnostic(current_file, ¤tNode->location, Error, "Invalid type for arithmetic operation");
|
print_diagnostic(current_file,
|
||||||
|
¤tNode->location, Error, "Invalid type for arithmetic operation");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
} else if (result->kind == TypeKindComposite) {
|
} else if (result->kind == TypeKindComposite) {
|
||||||
result->impl.composite.sign = Signed;
|
result->impl.composite.
|
||||||
|
sign = Signed;
|
||||||
}
|
}
|
||||||
ParentExpression->result = result;
|
ParentExpression->
|
||||||
|
result = result;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Type *LeftOperandType = g_array_index(ParentExpression->impl.operation.operands, Expression *, 0)->result;
|
Type *LeftOperandType = g_array_index(ParentExpression->impl.operation.operands, Expression *, 0)->result;
|
||||||
Type *RightOperandType = g_array_index(ParentExpression->impl.operation.operands, Expression *, 1)->result;
|
Type *RightOperandType = g_array_index(ParentExpression->impl.operation.operands, Expression *, 1)->result;
|
||||||
|
|
||||||
ParentExpression->result = createTypeFromOperands(LeftOperandType, RightOperandType, currentNode);
|
ParentExpression->
|
||||||
|
result = createTypeFromOperands(LeftOperandType, RightOperandType, currentNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ParentExpression->result == NULL) {
|
if (ParentExpression->result == NULL) {
|
||||||
|
@ -744,7 +649,8 @@ int createRelationalOperation(Expression* ParentExpression, AST_NODE_PTR current
|
||||||
// fill kind and Nodeptr
|
// fill kind and Nodeptr
|
||||||
ParentExpression->impl.operation.kind = Relational;
|
ParentExpression->impl.operation.kind = Relational;
|
||||||
ParentExpression->impl.operation.nodePtr = currentNode;
|
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
|
// fill Operands
|
||||||
for (size_t i = 0; i < currentNode->child_count; i++) {
|
for (size_t i = 0; i < currentNode->child_count; i++) {
|
||||||
Expression *expression = createExpression(currentNode->children[i]);
|
Expression *expression = createExpression(currentNode->children[i]);
|
||||||
|
@ -871,13 +777,15 @@ int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNod
|
||||||
result->nodePtr = currentNode;
|
result->nodePtr = currentNode;
|
||||||
|
|
||||||
if (Operand->kind == TypeKindBox || Operand->kind == TypeKindReference) {
|
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;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Operand->kind == TypeKindPrimitive) {
|
if (Operand->kind == TypeKindPrimitive) {
|
||||||
if (Operand->impl.primitive == Float) {
|
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;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
result->kind = Operand->kind;
|
result->kind = Operand->kind;
|
||||||
|
@ -885,7 +793,8 @@ int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNod
|
||||||
|
|
||||||
} else if (Operand->kind == TypeKindComposite) {
|
} else if (Operand->kind == TypeKindComposite) {
|
||||||
if (Operand->impl.composite.primitive == Float) {
|
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;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
result->kind = Operand->kind;
|
result->kind = Operand->kind;
|
||||||
|
@ -1072,31 +981,48 @@ int createBitNotOperation(Expression* ParentExpression, AST_NODE_PTR currentNode
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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) {
|
GArray *getBoxMember(Type *currentBoxType, GArray *names) {
|
||||||
|
|
||||||
GArray *members = g_array_new(FALSE, FALSE, sizeof(BoxMember));
|
GArray *members = mem_new_g_array(MemoryNamespaceSet, sizeof(BoxMember));
|
||||||
|
// list of members of the type
|
||||||
GHashTable *memberList = currentBoxType->impl.box.member;
|
GHashTable *memberList = currentBoxType->impl.box.member;
|
||||||
|
|
||||||
|
// name of member to extract
|
||||||
const char *currentName = g_array_index(names, const char *, 0);
|
const char *currentName = g_array_index(names, const char *, 0);
|
||||||
if(!g_hash_table_contains(memberList, currentName)) {
|
// look for member of this name
|
||||||
// TODO: free members
|
if (g_hash_table_contains(memberList, currentName)) {
|
||||||
return NULL;
|
|
||||||
}
|
// get member and store in array
|
||||||
BoxMember *currentMember = g_hash_table_lookup(memberList, currentName);
|
BoxMember *currentMember = g_hash_table_lookup(memberList, currentName);
|
||||||
g_array_append_val(members, currentMember);
|
g_array_append_val(members, currentMember);
|
||||||
|
|
||||||
|
// last name in list, return
|
||||||
g_array_remove_index(names, 0);
|
g_array_remove_index(names, 0);
|
||||||
if (names->len == 0) {
|
if (names->len == 0) {
|
||||||
return members;
|
return members;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// other names may refer to members of child boxes
|
||||||
if (currentMember->type->kind == TypeKindBox) {
|
if (currentMember->type->kind == TypeKindBox) {
|
||||||
GArray *otherMember = getBoxMember(currentMember->type, names);
|
GArray *otherMember = getBoxMember(currentMember->type, names);
|
||||||
|
|
||||||
if (NULL == otherMember) {
|
if (NULL == otherMember) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_array_append_vals(members, (BoxMember *) otherMember->data, otherMember->len);
|
g_array_append_vals(members, (BoxMember *) otherMember->data, otherMember->len);
|
||||||
|
|
||||||
return members;
|
return members;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1107,7 +1033,8 @@ int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) {
|
||||||
int status = getVariableFromScope(boxname, &boxVariable);
|
int status = getVariableFromScope(boxname, &boxVariable);
|
||||||
|
|
||||||
if (status == SEMANTIC_ERROR) {
|
if (status == SEMANTIC_ERROR) {
|
||||||
print_diagnostic(current_file, ¤tNode->children[0]->location, Error, "Variable of name `%s` does not exist");
|
print_diagnostic(current_file, ¤tNode->children[0]->location, Error,
|
||||||
|
"Variable of name `%s` does not exist");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
Type *boxType;
|
Type *boxType;
|
||||||
|
@ -1193,17 +1120,14 @@ int createTransmute(Expression* ParentExpression, AST_NODE_PTR currentNode){
|
||||||
ParentExpression->result = 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");
|
DEBUG("create Expression");
|
||||||
Expression *expression = mem_alloc(MemoryNamespaceSet, sizeof(Expression));
|
Expression *expression = mem_alloc(MemoryNamespaceSet, sizeof(Expression));
|
||||||
expression->nodePtr = currentNode;
|
expression->nodePtr = currentNode;
|
||||||
switch(currentNode->kind){
|
|
||||||
|
|
||||||
|
switch (currentNode->kind) {
|
||||||
case AST_Int:
|
case AST_Int:
|
||||||
case AST_Float:
|
case AST_Float:
|
||||||
expression->kind = ExpressionKindConstant;
|
expression->kind = ExpressionKindConstant;
|
||||||
|
@ -1288,7 +1212,6 @@ Expression *createExpression(AST_NODE_PTR currentNode){
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_IdentList:
|
case AST_IdentList:
|
||||||
case AST_List:
|
case AST_List:
|
||||||
expression->kind = ExpressionKindVariable;
|
expression->kind = ExpressionKindVariable;
|
||||||
|
@ -1338,16 +1261,16 @@ Expression *createExpression(AST_NODE_PTR currentNode){
|
||||||
ParentStatement->impl.assignment = assign;
|
ParentStatement->impl.assignment = assign;
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int createStatement(Block *block, AST_NODE_PTR currentNode);
|
int createStatement(Block *block, AST_NODE_PTR currentNode);
|
||||||
|
|
||||||
int fillBlock(Block *block, AST_NODE_PTR currentNode) {
|
int fillBlock(Block *block, AST_NODE_PTR currentNode) {
|
||||||
DEBUG("start filling Block");
|
DEBUG("start filling Block");
|
||||||
block->nodePtr = currentNode;
|
block->nodePtr = currentNode;
|
||||||
block->statemnts = g_array_new(FALSE,FALSE,sizeof(Statement*));
|
block->statemnts = mem_new_g_array(MemoryNamespaceSet, sizeof(Statement *));
|
||||||
GHashTable * lowerScope = g_hash_table_new(g_str_hash,g_str_equal);
|
GHashTable *lowerScope = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal);
|
||||||
g_array_append_val(Scope, lowerScope);
|
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));
|
int signal = createStatement(block, AST_get_node(currentNode, i));
|
||||||
if (signal) {
|
if (signal) {
|
||||||
|
@ -1355,7 +1278,6 @@ int fillBlock(Block * block,AST_NODE_PTR currentNode){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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");
|
DEBUG("created Block successfully");
|
||||||
|
@ -1384,8 +1306,6 @@ int createWhile(Statement * ParentStatement, AST_NODE_PTR currentNode){
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int createIf(Branch *Parentbranch, AST_NODE_PTR currentNode) {
|
int createIf(Branch *Parentbranch, AST_NODE_PTR currentNode) {
|
||||||
If ifbranch;
|
If ifbranch;
|
||||||
ifbranch.nodePtr = currentNode;
|
ifbranch.nodePtr = currentNode;
|
||||||
|
@ -1394,12 +1314,14 @@ int createIf(Branch* Parentbranch, AST_NODE_PTR currentNode){
|
||||||
if (NULL == expression) {
|
if (NULL == expression) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ifbranch.conditon = expression;
|
ifbranch.conditon = expression;
|
||||||
int status = fillBlock(&ifbranch.block, currentNode->children[1]);
|
int status = fillBlock(&ifbranch.block, currentNode->children[1]);
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parentbranch->ifBranch = ifbranch;
|
Parentbranch->ifBranch = ifbranch;
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
@ -1435,11 +1357,10 @@ int createElseIf(Branch* Parentbranch, AST_NODE_PTR currentNode){
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int createBranch(Statement *ParentStatement, AST_NODE_PTR currentNode) {
|
int createBranch(Statement *ParentStatement, AST_NODE_PTR currentNode) {
|
||||||
Branch Branch;
|
Branch Branch;
|
||||||
Branch.nodePtr = currentNode;
|
Branch.nodePtr = currentNode;
|
||||||
|
|
||||||
for (size_t i = 0; i < currentNode->child_count; i++) {
|
for (size_t i = 0; i < currentNode->child_count; i++) {
|
||||||
switch (currentNode->children[i]->kind) {
|
switch (currentNode->children[i]->kind) {
|
||||||
case AST_If:
|
case AST_If:
|
||||||
|
@ -1447,19 +1368,16 @@ int createBranch(Statement* ParentStatement,AST_NODE_PTR currentNode){
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_IfElse:
|
case AST_IfElse:
|
||||||
if (createElseIf(&Branch, currentNode)) {
|
if (createElseIf(&Branch, currentNode)) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_Else:
|
case AST_Else:
|
||||||
if (createElse(&Branch, currentNode->children[i])) {
|
if (createElse(&Branch, currentNode->children[i])) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PANIC("current node is not part of a Branch");
|
PANIC("current node is not part of a Branch");
|
||||||
break;
|
break;
|
||||||
|
@ -1474,33 +1392,33 @@ int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){
|
||||||
|
|
||||||
switch (currentNode->kind) {
|
switch (currentNode->kind) {
|
||||||
case AST_Decl: {
|
case AST_Decl: {
|
||||||
GArray *variable= g_array_new(FALSE, FALSE, sizeof(Variable*));
|
GArray *variable = mem_new_g_array(MemoryNamespaceSet, sizeof(Variable *));
|
||||||
|
|
||||||
int status = createDecl(currentNode, &variable);
|
int status = createDecl(currentNode, &variable);
|
||||||
if (status) {
|
if (status) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < variable->len; i++) {
|
for (size_t i = 0; i < variable->len; i++) {
|
||||||
|
|
||||||
Statement *statement = mem_alloc(MemoryNamespaceSet, sizeof(Statement));
|
Statement *statement = mem_alloc(MemoryNamespaceSet, sizeof(Statement));
|
||||||
statement->nodePtr = currentNode;
|
statement->nodePtr = currentNode;
|
||||||
statement->kind = StatementKindDeclaration;
|
statement->kind = StatementKindDeclaration;
|
||||||
|
|
||||||
|
|
||||||
statement->impl.variable = g_array_index(variable, Variable *, i);
|
statement->impl.variable = g_array_index(variable, Variable *, i);
|
||||||
g_array_append_val(Parentblock->statemnts, statement);
|
g_array_append_val(Parentblock->statemnts, statement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_Def: {
|
case AST_Def: {
|
||||||
GArray *variable= g_array_new(FALSE, FALSE, sizeof(Variable*));
|
GArray *variable = mem_new_g_array(MemoryNamespaceSet, sizeof(Variable *));
|
||||||
|
|
||||||
int status = createDef(currentNode, &variable);
|
int status = createDef(currentNode, &variable);
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < variable->len; i++) {
|
for (size_t i = 0; i < variable->len; i++) {
|
||||||
|
|
||||||
Statement *statement = mem_alloc(MemoryNamespaceSet, sizeof(Statement));
|
Statement *statement = mem_alloc(MemoryNamespaceSet, sizeof(Statement));
|
||||||
|
@ -1510,7 +1428,6 @@ int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){
|
||||||
statement->impl.variable = g_array_index(variable, Variable *, i);
|
statement->impl.variable = g_array_index(variable, Variable *, i);
|
||||||
g_array_append_val(Parentblock->statemnts, statement);
|
g_array_append_val(Parentblock->statemnts, statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AST_While: {
|
case AST_While: {
|
||||||
|
@ -1552,7 +1469,6 @@ int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int createParam(GArray *Paramlist, AST_NODE_PTR currentNode) {
|
int createParam(GArray *Paramlist, AST_NODE_PTR currentNode) {
|
||||||
assert(currentNode->kind == AST_Parameter);
|
assert(currentNode->kind == AST_Parameter);
|
||||||
DEBUG("start param");
|
DEBUG("start param");
|
||||||
|
@ -1602,7 +1518,6 @@ int createParam(GArray * Paramlist ,AST_NODE_PTR currentNode){
|
||||||
paramvar->impl.declaration.qualifier = Local;
|
paramvar->impl.declaration.qualifier = Local;
|
||||||
paramvar->impl.declaration.type = param.impl.declaration.type;
|
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;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1612,29 +1527,26 @@ int createParam(GArray * Paramlist ,AST_NODE_PTR currentNode){
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int createFunDef(Function *Parentfunction, AST_NODE_PTR currentNode) {
|
int createFunDef(Function *Parentfunction, AST_NODE_PTR currentNode) {
|
||||||
DEBUG("start fundef");
|
DEBUG("start fundef");
|
||||||
AST_NODE_PTR nameNode = currentNode->children[0];
|
AST_NODE_PTR nameNode = currentNode->children[0];
|
||||||
AST_NODE_PTR paramlistlist = currentNode->children[1];
|
AST_NODE_PTR paramlistlist = currentNode->children[1];
|
||||||
AST_NODE_PTR statementlist = currentNode->children[2];
|
AST_NODE_PTR statementlist = currentNode->children[2];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FunctionDefinition fundef;
|
FunctionDefinition fundef;
|
||||||
|
|
||||||
fundef.nodePtr = currentNode;
|
fundef.nodePtr = currentNode;
|
||||||
fundef.name = nameNode->value;
|
fundef.name = nameNode->value;
|
||||||
fundef.body = mem_alloc(MemoryNamespaceSet, sizeof(Block));
|
fundef.body = mem_alloc(MemoryNamespaceSet, sizeof(Block));
|
||||||
fundef.parameter = g_array_new(FALSE, FALSE, sizeof(Parameter));
|
fundef.parameter = mem_new_g_array(MemoryNamespaceSet, sizeof(Parameter));
|
||||||
|
|
||||||
DEBUG("paramlistlist child count: %i", paramlistlist->child_count);
|
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];
|
AST_NODE_PTR paramlist = paramlistlist->children[i];
|
||||||
DEBUG("paramlist child count: %i", paramlist->child_count);
|
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);
|
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));
|
||||||
|
@ -1656,8 +1568,6 @@ int createFunDef(Function * Parentfunction ,AST_NODE_PTR currentNode){
|
||||||
Parentfunction->impl.definition = fundef;
|
Parentfunction->impl.definition = fundef;
|
||||||
Parentfunction->name = fundef.name;
|
Parentfunction->name = fundef.name;
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int createFunDecl(Function *Parentfunction, AST_NODE_PTR currentNode) {
|
int createFunDecl(Function *Parentfunction, AST_NODE_PTR currentNode) {
|
||||||
|
@ -1665,15 +1575,12 @@ int createFunDecl(Function * Parentfunction ,AST_NODE_PTR currentNode){
|
||||||
AST_NODE_PTR nameNode = currentNode->children[0];
|
AST_NODE_PTR nameNode = currentNode->children[0];
|
||||||
AST_NODE_PTR paramlistlist = currentNode->children[1];
|
AST_NODE_PTR paramlistlist = currentNode->children[1];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FunctionDeclaration fundecl;
|
FunctionDeclaration fundecl;
|
||||||
|
|
||||||
fundecl.nodePtr = currentNode;
|
fundecl.nodePtr = currentNode;
|
||||||
fundecl.name = nameNode->value;
|
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
|
//all parameterlists
|
||||||
|
@ -1700,7 +1607,7 @@ int createFunDecl(Function * Parentfunction ,AST_NODE_PTR currentNode){
|
||||||
int createFunction(GHashTable *functions, AST_NODE_PTR currentNode) {
|
int createFunction(GHashTable *functions, AST_NODE_PTR currentNode) {
|
||||||
assert(currentNode->kind == AST_Fun);
|
assert(currentNode->kind == AST_Fun);
|
||||||
Function *fun = mem_alloc(MemoryNamespaceSet, sizeof(Function));
|
Function *fun = mem_alloc(MemoryNamespaceSet, sizeof(Function));
|
||||||
functionParameter = g_hash_table_new(g_str_hash,g_str_equal);
|
functionParameter = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal);
|
||||||
|
|
||||||
if (currentNode->child_count == 2) {
|
if (currentNode->child_count == 2) {
|
||||||
int signal = createFunDecl(fun, currentNode);
|
int signal = createFunDecl(fun, currentNode);
|
||||||
|
@ -1721,12 +1628,10 @@ int createFunction(GHashTable* functions, AST_NODE_PTR currentNode){
|
||||||
}
|
}
|
||||||
g_hash_table_insert(functions, (gpointer) fun->name, fun);
|
g_hash_table_insert(functions, (gpointer) fun->name, fun);
|
||||||
|
|
||||||
g_hash_table_destroy(functionParameter);
|
|
||||||
return SEMANTIC_OK;
|
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));
|
Type *declType = mem_alloc(MemoryNamespaceSet, sizeof(Type));
|
||||||
|
@ -1767,7 +1672,7 @@ int createDefMember(BoxType *ParentBox, AST_NODE_PTR currentNode){
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < nameList->child_count; i++){
|
for (guint i = 0; i < nameList->child_count; i++) {
|
||||||
BoxMember *def = mem_alloc(MemoryNamespaceSet, sizeof(BoxMember));
|
BoxMember *def = mem_alloc(MemoryNamespaceSet, sizeof(BoxMember));
|
||||||
def->box = ParentBox;
|
def->box = ParentBox;
|
||||||
def->type = declType;
|
def->type = declType;
|
||||||
|
@ -1788,14 +1693,10 @@ int createBox(GHashTable *boxes, AST_NODE_PTR currentNode){
|
||||||
box->nodePtr = currentNode;
|
box->nodePtr = currentNode;
|
||||||
const char *boxName = currentNode->children[0]->value;
|
const char *boxName = currentNode->children[0]->value;
|
||||||
AST_NODE_PTR boxMemberList = currentNode->children[1];
|
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) {
|
switch (boxMemberList->children[i]->kind) {
|
||||||
case AST_Decl:
|
|
||||||
if(createDeclMember(box, boxMemberList->children[i]->children[i])){
|
|
||||||
return SEMANTIC_ERROR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AST_Def:
|
case AST_Def:
|
||||||
|
case AST_Decl:
|
||||||
if (createDeclMember(box, boxMemberList->children[i]->children[i])) {
|
if (createDeclMember(box, boxMemberList->children[i]->children[i])) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1805,7 +1706,6 @@ int createBox(GHashTable *boxes, AST_NODE_PTR currentNode){
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (g_hash_table_contains(boxes, (gpointer) boxName)) {
|
if (g_hash_table_contains(boxes, (gpointer) boxName)) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
|
@ -1813,27 +1713,6 @@ int createBox(GHashTable *boxes, AST_NODE_PTR currentNode){
|
||||||
g_hash_table_insert(boxes, (gpointer) boxName, box);
|
g_hash_table_insert(boxes, (gpointer) boxName, box);
|
||||||
|
|
||||||
return SEMANTIC_OK;
|
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) {
|
||||||
|
@ -1841,7 +1720,6 @@ int createTypeDef(GHashTable *types, AST_NODE_PTR currentNode){
|
||||||
AST_NODE_PTR typeNode = currentNode->children[0];
|
AST_NODE_PTR typeNode = currentNode->children[0];
|
||||||
AST_NODE_PTR nameNode = currentNode->children[1];
|
AST_NODE_PTR nameNode = currentNode->children[1];
|
||||||
|
|
||||||
|
|
||||||
Type *type = mem_alloc(MemoryNamespaceSet, sizeof(Type));
|
Type *type = mem_alloc(MemoryNamespaceSet, sizeof(Type));
|
||||||
int status = get_type_impl(typeNode, &type);
|
int status = get_type_impl(typeNode, &type);
|
||||||
if (status) {
|
if (status) {
|
||||||
|
@ -1868,25 +1746,24 @@ int createTypeDef(GHashTable *types, AST_NODE_PTR currentNode){
|
||||||
Module *create_set(AST_NODE_PTR currentNode) {
|
Module *create_set(AST_NODE_PTR currentNode) {
|
||||||
DEBUG("create root Module");
|
DEBUG("create root Module");
|
||||||
//create tables for types
|
//create tables for types
|
||||||
declaredComposites = g_hash_table_new(g_str_hash,g_str_equal);
|
declaredComposites = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal);
|
||||||
declaredBoxes = g_hash_table_new(g_str_hash,g_str_equal);
|
declaredBoxes = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal);
|
||||||
|
|
||||||
//create scope
|
//create scope
|
||||||
Scope = g_array_new(FALSE, FALSE, sizeof(GHashTable*));
|
Scope = mem_new_g_array(MemoryNamespaceSet, sizeof(GHashTable *));
|
||||||
|
|
||||||
|
|
||||||
//building current scope for module
|
//building current scope for module
|
||||||
GHashTable *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 = g_hash_table_new(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);
|
g_array_append_val(Scope, globalscope);
|
||||||
|
|
||||||
Module *rootModule = mem_alloc(MemoryNamespaceSet, sizeof(Module));
|
Module *rootModule = mem_alloc(MemoryNamespaceSet, sizeof(Module));
|
||||||
|
|
||||||
GHashTable *boxes = g_hash_table_new(g_str_hash,g_str_equal);
|
GHashTable *boxes = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal);
|
||||||
GHashTable *types = g_hash_table_new(g_str_hash,g_str_equal);
|
GHashTable *types = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal);
|
||||||
GHashTable *functions = g_hash_table_new(g_str_hash,g_str_equal);
|
GHashTable *functions = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal);
|
||||||
GHashTable *variables = g_hash_table_new(g_str_hash,g_str_equal);
|
GHashTable *variables = mem_new_g_hash_table(MemoryNamespaceSet,g_str_hash, g_str_equal);
|
||||||
GArray *imports = g_array_new(FALSE, FALSE, sizeof(const char*));
|
GArray *imports = mem_new_g_array(MemoryNamespaceSet, sizeof(const char *));
|
||||||
|
|
||||||
rootModule->boxes = boxes;
|
rootModule->boxes = boxes;
|
||||||
rootModule->types = types;
|
rootModule->types = types;
|
||||||
|
@ -1896,7 +1773,6 @@ Module *create_set(AST_NODE_PTR currentNode){
|
||||||
|
|
||||||
DEBUG("created Module struct");
|
DEBUG("created Module struct");
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 0; i < currentNode->child_count; i++) {
|
for (size_t i = 0; i < currentNode->child_count; i++) {
|
||||||
DEBUG("created Child: %i", currentNode->children[i]->kind);
|
DEBUG("created Child: %i", currentNode->children[i]->kind);
|
||||||
switch (currentNode->children[i]->kind) {
|
switch (currentNode->children[i]->kind) {
|
||||||
|
@ -1905,7 +1781,6 @@ Module *create_set(AST_NODE_PTR currentNode){
|
||||||
GArray *vars;
|
GArray *vars;
|
||||||
int status = createDecl(currentNode->children[i], &vars);
|
int status = createDecl(currentNode->children[i], &vars);
|
||||||
if (status) {
|
if (status) {
|
||||||
// TODO: free vars
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (fillTablesWithVars(variables, vars) == SEMANTIC_ERROR) {
|
if (fillTablesWithVars(variables, vars) == SEMANTIC_ERROR) {
|
||||||
|
@ -1913,12 +1788,11 @@ Module *create_set(AST_NODE_PTR currentNode){
|
||||||
// of variables even if just one of the declared variables
|
// of variables even if just one of the declared variables
|
||||||
// is duplicate. Consider moving this diagnostic to
|
// is duplicate. Consider moving this diagnostic to
|
||||||
// `fillTablesWithVars` for more precise messaging.
|
// `fillTablesWithVars` for more precise messaging.
|
||||||
print_diagnostic(current_file, ¤tNode->children[i]->location, Error, "Variable already declared");
|
print_diagnostic(current_file, ¤tNode->children[i]->location, Error,
|
||||||
|
"Variable already declared");
|
||||||
INFO("var already exists");
|
INFO("var already exists");
|
||||||
// TODO: free vars
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// TODO: free vars
|
|
||||||
DEBUG("filled successfull the module and scope with vars");
|
DEBUG("filled successfull the module and scope with vars");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1926,8 +1800,6 @@ Module *create_set(AST_NODE_PTR currentNode){
|
||||||
GArray *vars;
|
GArray *vars;
|
||||||
int status = createDef(currentNode->children[i], &vars);
|
int status = createDef(currentNode->children[i], &vars);
|
||||||
if (status) {
|
if (status) {
|
||||||
// TODO: free vars
|
|
||||||
// TODO: cleanup global memory
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// TODO: free vars
|
// TODO: free vars
|
||||||
|
@ -1937,7 +1809,6 @@ Module *create_set(AST_NODE_PTR currentNode){
|
||||||
case AST_Box: {
|
case AST_Box: {
|
||||||
int status = createBox(boxes, currentNode->children[i]);
|
int status = createBox(boxes, currentNode->children[i]);
|
||||||
if (status) {
|
if (status) {
|
||||||
// TODO: cleanup global memory
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
DEBUG("created Box successfully");
|
DEBUG("created Box successfully");
|
||||||
|
@ -1947,7 +1818,6 @@ Module *create_set(AST_NODE_PTR currentNode){
|
||||||
DEBUG("start function");
|
DEBUG("start function");
|
||||||
int status = createFunction(functions, currentNode->children[i]);
|
int status = createFunction(functions, currentNode->children[i]);
|
||||||
if (status) {
|
if (status) {
|
||||||
// TODO: cleanup global memory
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
DEBUG("created function successfully");
|
DEBUG("created function successfully");
|
||||||
|
@ -1957,7 +1827,6 @@ Module *create_set(AST_NODE_PTR currentNode){
|
||||||
case AST_Typedef: {
|
case AST_Typedef: {
|
||||||
int status = createTypeDef(types, currentNode->children[i]);
|
int status = createTypeDef(types, currentNode->children[i]);
|
||||||
if (status) {
|
if (status) {
|
||||||
// TODO: cleanup global memory
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
DEBUG("created Typedef successfully");
|
DEBUG("created Typedef successfully");
|
||||||
|
@ -1973,6 +1842,7 @@ Module *create_set(AST_NODE_PTR currentNode){
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("created set successfully");
|
DEBUG("created set successfully");
|
||||||
return rootModule;
|
return rootModule;
|
||||||
}
|
}
|
||||||
|
|
186
src/set/types.c
186
src/set/types.c
|
@ -1,186 +0,0 @@
|
||||||
//
|
|
||||||
// Created by servostar on 6/7/24.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <mem/cache.h>
|
|
||||||
#include <set/types.h>
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
Loading…
Reference in New Issue