From 0d1f312ae214a36ebdc08455ac3bbba25c8e3cce Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 28 May 2024 00:12:32 +0200 Subject: [PATCH 01/29] fixed: various implementation faults fixed typo of parameter added function struct to group their declaration and definitons added block to function definiton added operands to cast and operators --- src/set/types.h | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/set/types.h b/src/set/types.h index 52744a1..6fcc02c 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -69,6 +69,8 @@ typedef Type* ReferenceType; typedef struct BoxType_t BoxType; +typedef struct Block_t Block; + typedef struct BoxMember_t { const char* name; Type* type; @@ -88,6 +90,7 @@ typedef struct BoxType_t { } BoxType; typedef struct Variable_t Variable; +typedef struct Expression_t Expression; typedef struct BoxAccess_t { // list of recursive box accesses @@ -168,7 +171,7 @@ typedef struct ParameterDefinition_t { ParameterDeclaration declaration; // value to initalize the declaration with // NOTE: type of initializer and declaration MUST be equal - TypeValue initializer; + Expression initializer; AST_NODE_PTR nodePtr; } ParameterDefinition; @@ -189,15 +192,37 @@ typedef struct Parameter_t { ParameterDefinition definiton; } impl; AST_NODE_PTR nodePtr; -} Paramer; +} Parameter; // fix typo + +typedef enum FunctionKind_t { + FunctionDeclarationKind, + FunctionDefinitionKind +} FunctionKind; typedef struct FunctionDefinition_t { // hashtable of parameters // associates a parameters name (const char*) with its parameter declaration (ParameterDeclaration) GArray* parameter; AST_NODE_PTR nodePtr; + // body of function + Block body; } FunctionDefinition; +typedef struct FunctionDeclaration_t { + // hashtable of parameters + // associates a parameters name (const char*) with its parameter declaration (ParameterDeclaration) + GArray* parameter; + AST_NODE_PTR nodePtr; +} FunctionDeclaration; + +typedef struct Function_t { + FunctionKind kind; + union FunctionImplementation { + FunctionDefinition definition; + FunctionDeclaration declaration; + } impl; +} Function; + // .------------------------------------------------. // | Variables | // '------------------------------------------------' @@ -222,7 +247,7 @@ typedef struct VariableDeclaration_t { */ typedef struct VariableDefiniton_t { VariableDeclaration declaration; - TypeValue initializer; + Expression initializer; AST_NODE_PTR nodePtr; } VariableDefiniton; @@ -258,6 +283,7 @@ typedef struct Variable_t { */ typedef struct TypeCast_t { Type targetType; + Expression* operand; AST_NODE_PTR nodePtr; } TypeCast; @@ -270,6 +296,7 @@ typedef struct TypeCast_t { */ typedef struct Transmute_t { Type targetType; + Expression* operand; AST_NODE_PTR nodePtr; } Transmute; @@ -358,6 +385,7 @@ typedef struct Operation_t { LogicalOperator logical; BitwiseOperator bitwise; } impl; + Expression* operands; AST_NODE_PTR nodePtr; } Operation; From 1aa82062687510dc689d59868e58299eb0175d26 Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 28 May 2024 12:36:33 +0200 Subject: [PATCH 02/29] fixed: missing kind in statement --- src/set/types.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/set/types.h b/src/set/types.h index 52744a1..aedb167 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -471,6 +471,7 @@ typedef enum StatementKind_t { } StatementKind; typedef struct Statement_t { + StatementKind kind; union StatementImplementation { FunctionCall call; FunctionBoxCall boxCall; From f590e3c42ea94f81cd06ca5ef8aba892ace07111 Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 28 May 2024 13:44:40 +0200 Subject: [PATCH 03/29] fixed: missing box member access in assignment --- src/set/types.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/set/types.h b/src/set/types.h index 828783a..cc230f0 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -484,8 +484,22 @@ typedef struct Branch_t { // | Statements | // '------------------------------------------------' +typedef enum AssignmentKind_t { + // direct access to a variable + AssignmentKindVariable, + // access to a member of a box + // can be nested such as: foo.bar.kee + AssignmentKindBoxMember +} AssignmentKind; + +// Can either be a direct variable access or +// a nested box member access typedef struct Assignment_t { Variable* variable; + AssignmentKind kind; + union AssignmentImplementation_t { + BoxAccess accees; + } impl; Expression value; AST_NODE_PTR nodePtr; } Assignment; From 0fe3fb68a6a482295686d394d15992dabdb53fda Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 28 May 2024 13:57:13 +0200 Subject: [PATCH 04/29] reverted: removed box access from assignment --- src/set/types.h | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/set/types.h b/src/set/types.h index cc230f0..0b92e2b 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -96,6 +96,8 @@ typedef struct BoxAccess_t { // list of recursive box accesses // contains a list of BoxMembers (each specifying their own type, name and box type) GArray* member; + // box variable to access + Variable* variable; AST_NODE_PTR nodePtr; } BoxAccess; @@ -263,7 +265,7 @@ typedef struct Variable_t { union VariableImplementation { VariableDeclaration declaration; VariableDefiniton definiton; - BoxMember member; + BoxAccess member; } impl; AST_NODE_PTR nodePtr; } Variable; @@ -484,22 +486,8 @@ typedef struct Branch_t { // | Statements | // '------------------------------------------------' -typedef enum AssignmentKind_t { - // direct access to a variable - AssignmentKindVariable, - // access to a member of a box - // can be nested such as: foo.bar.kee - AssignmentKindBoxMember -} AssignmentKind; - -// Can either be a direct variable access or -// a nested box member access typedef struct Assignment_t { Variable* variable; - AssignmentKind kind; - union AssignmentImplementation_t { - BoxAccess accees; - } impl; Expression value; AST_NODE_PTR nodePtr; } Assignment; From 8494df56cd0e7107fdc7d9ba77f16f1ac934e93b Mon Sep 17 00:00:00 2001 From: servostar Date: Wed, 29 May 2024 21:21:03 +0200 Subject: [PATCH 05/29] feature: added name to function --- src/set/types.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/set/types.h b/src/set/types.h index 6fcc02c..974542e 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -206,6 +206,8 @@ typedef struct FunctionDefinition_t { AST_NODE_PTR nodePtr; // body of function Block body; + // name of function + const char* name; } FunctionDefinition; typedef struct FunctionDeclaration_t { From 875574eb690e2ee9f0ef22904de7c07b6a2d0955 Mon Sep 17 00:00:00 2001 From: servostar Date: Wed, 29 May 2024 21:24:17 +0200 Subject: [PATCH 06/29] fixed: added type to expressions --- src/set/types.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/set/types.h b/src/set/types.h index 974542e..1bead83 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -404,6 +404,8 @@ typedef enum ExpressionKind_t { typedef struct Expression_t { ExpressionKind kind; + // type of resulting data + Type* result; union ExpressionImplementation_t { Operation operation; TypeCast typecast; From 5a06c17fa4b067fb4d1d418666adf9cf052444d8 Mon Sep 17 00:00:00 2001 From: Filleo Date: Fri, 31 May 2024 16:17:06 +0200 Subject: [PATCH 07/29] first implementation of the sematic analysis --- src/lex/lexer.l | 2 +- src/main.c | 3 +- src/set/set.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++ src/set/set.h | 8 ++ src/set/types.h | 18 ++-- src/yacc/parser.y | 6 +- 6 files changed, 281 insertions(+), 13 deletions(-) create mode 100644 src/set/set.c create mode 100644 src/set/set.h diff --git a/src/lex/lexer.l b/src/lex/lexer.l index 7c0cc0c..3df609f 100644 --- a/src/lex/lexer.l +++ b/src/lex/lexer.l @@ -99,7 +99,7 @@ DEBUG("\"%s\" tokenized with \'ValStr\'", yytext); yylval.string = strdup(yytext); return(ValStr);}; \"\"\"([^\"\n]|\\\n)*\"\"\" { yytext = yytext +3; - yytext[yyleng - 4] = 0; + yytext[yyleng - 6] = 0; DEBUG("\"%s\" tokenized with \'ValMultistr\'", yytext); yylval.string = strdup(yytext); return(ValMultistr);}; [ \r\t] { /* ignore whitespace */ }; diff --git a/src/main.c b/src/main.c index 27bca44..9e349fe 100644 --- a/src/main.c +++ b/src/main.c @@ -4,6 +4,7 @@ #include #include #include +#include #define LOG_LEVEL LOG_LEVEL_DEBUG @@ -74,7 +75,7 @@ int main(int argc, char *argv[]) { root = AST_new_node(AST_Module, NULL); yyparse(); - + create_set(root); FILE *output = fopen("test.txt", "w"); AST_fprint_graphviz(output, root); fclose(output); diff --git a/src/set/set.c b/src/set/set.c new file mode 100644 index 0000000..bed1e4d --- /dev/null +++ b/src/set/set.c @@ -0,0 +1,257 @@ +#include +#include +#include +#include +#include +#include + +GHashTable *declaredComposites;//pointer to composites with names, +GHashTable *declaredBoxes;//pointer to typeboxes +GArray *Scope;//last object is current scope + + + + + + +Type *findType(AST_NODE_PTR currentNode){ + + const char *typekind = currentNode->children[currentNode->child_count -1]->value; + if (0 == strcmp(typekind, "int")||0 == strcmp(typekind, "float")){ + + Type *type = malloc(sizeof(Type)); + type->nodePtr = currentNode; + if(AST_Typekind != currentNode->children[0]->kind){ + DEBUG("Type is a Composite"); + type->kind = TypeKindComposite; + + + CompositeType composite; + composite.nodePtr = currentNode; + + + if(0 == strcmp(typekind, "int")){ + composite.primitive = Int; + }else{ + composite.primitive = Float; + } + composite.sign = Signed; + + size_t scalelist = 0; + if(AST_Sign == currentNode->children[0]->kind){ + if(0 == strcmp(currentNode->children[0]->value, "unsigned")){ + composite.sign = Unsigned; + } + scalelist = 1; + } + + composite.scale = 1.0; + if(AST_List == currentNode->children[scalelist]->kind){ + for (size_t i = 0; i < currentNode->children[scalelist]->child_count; i++){ + if (0 == strcmp(currentNode->children[scalelist]->children[i]->value, "short") || 0 == strcmp(currentNode->children[scalelist]->children[i]->value, "half")){ + composite.scale /= 2; + }else{ + composite.scale *= 2; + } + if (0.25 > composite.scale || 8 > composite.scale) { + //TODO scale not right + } + } + } + + type->impl.composite = composite; + + + }else{ + type->kind = TypeKindPrimitive; + if(0 == strcmp(typekind, "int")){ + type->impl.primitive = Int; + }else{ + type->impl.primitive = Float; + } + return type; + } + }else if(g_hash_table_contains(declaredBoxes, typekind)){ + if(AST_Typekind != currentNode->children[0]->kind){ + //TODO composite Box try + } + return (Type *) g_hash_table_lookup(declaredBoxes, typekind); + }else if(g_hash_table_contains(declaredComposites, typekind)){ + if(AST_Typekind != currentNode->children[0]->kind){ + Type *composite = malloc(sizeof(Type)); + + *composite = *(Type*) g_hash_table_lookup(declaredComposites, typekind); + + + + size_t scalelist = 0; + if(AST_Sign == currentNode->children[0]->kind){ + if(0 == strcmp(currentNode->children[0]->value, "unsigned")){ + composite->impl.composite.sign = Unsigned; + }else if(0 == strcmp(currentNode->children[0]->value, "unsigned")){ + composite->impl.composite.sign = Signed; + } + scalelist = 1; + } + + + if(AST_List == currentNode->children[scalelist]->kind){ + for (size_t i = 0; i < currentNode->children[scalelist]->child_count; i++){ + if (0 == strcmp(currentNode->children[scalelist]->children[i]->value, "short") || 0 == strcmp(currentNode->children[scalelist]->children[i]->value, "half")){ + composite->impl.composite.scale /= 2; + }else{ + composite->impl.composite.scale *= 2; + } + if (0.25 > composite->impl.composite.scale || 8 > composite->impl.composite.scale) { + //TODO scale not right + return NULL; + } + } + } + return composite; + } + return (Type *) g_hash_table_lookup(declaredComposites, typekind); + }else{ + //TODO doesnt know typekind + return NULL; + } + return NULL; +} + + + +StorageQualifier Qualifier_from_string(const char *str) { + if (!strncmp(str, "local", 5)) return Local; + if (!strncmp(str, "static", 6)) return Static; + if (!strncmp(str, "global", 6)) return Global; + PANIC("Provided string is not a storagequalifier: %s", str); +} + +Variable **create_decl(AST_NODE_PTR currentNode){ + DEBUG("create declaration"); + Variable **variables = malloc(currentNode->children[currentNode->child_count -1]->child_count * sizeof(Variable)); + + VariableDeclaration decl; + decl.nodePtr = currentNode; + + DEBUG("Child Count: %i", currentNode->child_count); + for (size_t i = 0; i < currentNode->child_count; i++){ + + switch(currentNode->children[i]->kind){ + case AST_Storage: + DEBUG("fill Qualifier"); + decl.qualifier = Qualifier_from_string(currentNode->children[i]->value); + break; + case AST_Type: + DEBUG("fill Type"); + decl.type = findType(currentNode->children[i]); + break; + case AST_IdentList: + for(size_t i = 0; i < currentNode->children[currentNode->child_count -1]->child_count; i++){ + Variable *variable = malloc(sizeof(Variable)); + variable->kind = VariableKindDeclaration; + variable->nodePtr = currentNode; + variable->name = currentNode->children[currentNode->child_count -1]->children[i]->value; + variable->impl.declaration = decl; + variables[i] = variable; + } + break; + default: + //TODO PANIC maybe + break; + } + } + + return variables; +} + +int isVariableInScope(const char* name){ + + for(size_t i = 0; i < Scope->len; i++){ + if(g_hash_table_contains(((GHashTable **) Scope->data)[i], name)) + { + return 1; + } + } + return 0; +} + +int fillTablesWithVars(GHashTable *variableTable,GHashTable *currentScope , Variable** content, size_t amount){ + DEBUG("filling vars in scope and table"); + for(size_t i = 0; i < amount; i++){ + if(isVariableInScope(content[i]->name)){ + DEBUG("this var already exist: ",content[i]->name); + return 1; + } + g_hash_table_insert(variableTable, (gpointer) content[i]->name, content[i] ); + g_hash_table_insert(currentScope, (gpointer) content[i]->name, content[i] ); + } + return 0; +} + + + + +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); + + //create scope + Scope = g_array_new(FALSE, FALSE, sizeof(GHashTable*)); + + + //building current scope for module + GHashTable *globalscope = malloc(sizeof(GHashTable*)); + globalscope = g_hash_table_new(g_str_hash,g_str_equal); + g_array_append_val(Scope, globalscope); + + Module *rootModule = malloc(sizeof(Module)); + + 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; + rootModule->variables = variables; + rootModule->imports = imports; + + 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){ + + case AST_Decl: + if (1 == fillTablesWithVars(variables,globalscope,create_decl(currentNode->children[i]) ,currentNode->children[i]->children[currentNode->children[i]->child_count -1]->child_count)){ + //TODO behandlung, wenn var schon existiert + DEBUG("var already exists"); + break; + } + DEBUG("filled successfull the module and scope with vars"); + break; + case AST_Def: + case AST_Box: + case AST_Fun: + 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 beecause of semantic error."); + break; + + } + } + + return rootModule; +} + + + diff --git a/src/set/set.h b/src/set/set.h new file mode 100644 index 0000000..033dee5 --- /dev/null +++ b/src/set/set.h @@ -0,0 +1,8 @@ +#ifndef _SET_H_ +#define _SET_H_ + +#include + +void create_set(AST_NODE_PTR rootNodePtr ); + +#endif diff --git a/src/set/types.h b/src/set/types.h index a035854..4650c86 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -117,7 +117,7 @@ typedef struct Type_t { typedef struct Typedefine_t { const char* name; - Type type; + Type *type; AST_NODE_PTR nodePtr; } Typedefine; @@ -129,7 +129,7 @@ typedef struct Typedefine_t { */ typedef struct TypeValue_t { // the type - Type type; + Type *type; // UTF-8 representation of the type's value const char* value; AST_NODE_PTR nodePtr; @@ -160,7 +160,7 @@ typedef enum IO_Qualifier_t { * */ typedef struct ParameterDeclaration_t { - Type type; + Type *type; IO_Qualifier qualifier; AST_NODE_PTR nodePtr; } ParameterDeclaration; @@ -173,7 +173,7 @@ typedef struct ParameterDefinition_t { ParameterDeclaration declaration; // value to initalize the declaration with // NOTE: type of initializer and declaration MUST be equal - Expression initializer; + Expression *initializer; AST_NODE_PTR nodePtr; } ParameterDefinition; @@ -207,7 +207,7 @@ typedef struct FunctionDefinition_t { GArray* parameter; AST_NODE_PTR nodePtr; // body of function - Block body; + Block *body; // name of function const char* name; } FunctionDefinition; @@ -239,7 +239,7 @@ typedef enum StorageQualifier_t { typedef struct VariableDeclaration_t { StorageQualifier qualifier; - Type type; + Type *type; AST_NODE_PTR nodePtr; } VariableDeclaration; @@ -251,7 +251,7 @@ typedef struct VariableDeclaration_t { */ typedef struct VariableDefiniton_t { VariableDeclaration declaration; - Expression initializer; + Expression *initializer; AST_NODE_PTR nodePtr; } VariableDefiniton; @@ -286,7 +286,7 @@ typedef struct Variable_t { * */ typedef struct TypeCast_t { - Type targetType; + Type *targetType; Expression* operand; AST_NODE_PTR nodePtr; } TypeCast; @@ -299,7 +299,7 @@ typedef struct TypeCast_t { * */ typedef struct Transmute_t { - Type targetType; + Type *targetType; Expression* operand; AST_NODE_PTR nodePtr; } Transmute; diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 753c7bc..4b8c156 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -5,6 +5,7 @@ #include #include #include + extern int yylineno; @@ -132,7 +133,8 @@ %left '(' ')' %% -program: program programbody {AST_push_node(root, $2);} +program: program programbody {AST_push_node(root, $2); + } | programbody {AST_push_node(root, $1);}; programbody: moduleimport {$$ = $1;} @@ -365,7 +367,7 @@ decl: type ':' identlist {AST_NODE_PTR decl = AST_new_node(AST_Decl, NULL); AST_push_node(decl, $1); AST_push_node(decl, $2); AST_push_node(decl, $4); - $$ = decl;} + $$ = decl;}; definition: decl '=' expr { AST_NODE_PTR def = AST_new_node(AST_Def, NULL); From 8e1a1664da47c8bf5c1010f9829b3052811e3a57 Mon Sep 17 00:00:00 2001 From: Filleo Date: Fri, 31 May 2024 18:36:40 +0200 Subject: [PATCH 08/29] added enum type values to set --- src/set/set.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++-- src/set/types.h | 3 +- 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/src/set/set.c b/src/set/set.c index bed1e4d..bad66a8 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -127,7 +127,7 @@ StorageQualifier Qualifier_from_string(const char *str) { PANIC("Provided string is not a storagequalifier: %s", str); } -Variable **create_decl(AST_NODE_PTR currentNode){ +Variable **createDecl(AST_NODE_PTR currentNode){ DEBUG("create declaration"); Variable **variables = malloc(currentNode->children[currentNode->child_count -1]->child_count * sizeof(Variable)); @@ -189,9 +189,76 @@ int fillTablesWithVars(GHashTable *variableTable,GHashTable *currentScope , Vari return 0; } +Variable **createDef(AST_NODE_PTR currentNode){ + +} +TypeValue createTypeValue(AST_NODE_PTR currentNode){ + TypeValue value; + Type *type = malloc(sizeof(Type)); + value.type = type; + type->kind = TypeKindPrimitive; + type->nodePtr = currentNode; + + switch (currentNode->kind) { + + case AST_Int: + type->impl.primitive = Int; + case AST_Float: + type->impl.primitive = Int; + default: + PANIC("Node is not an expression but from kind: %i", currentNode->kind); + break; + } + + value.nodePtr = currentNode; + value.value = currentNode->value; + return value; +} + +Expression *createExpression(AST_NODE_PTR currentNode){ + Expression *expression = malloc(sizeof(Expression)); + + switch(currentNode->kind){ + + case AST_Int: + case AST_Float: + expression->kind = ExpressionKindConstant; + expression->impl.constant = createTypeValue(currentNode); + + case AST_String: + //TODO + case AST_Ident: + + case AST_Add: + case AST_Sub: + case AST_Mul: + case AST_Div: + case AST_Negate: + + case AST_Eq: + case AST_Less: + case AST_Greater: + + case AST_BoolAnd: + case AST_BoolNot: + case AST_BoolOr: + case AST_BoolXor: + + case AST_BitAnd: + case AST_BitOr: + case AST_BitXor: + case AST_BitNot: + + + default: + PANIC("Node is not an expression but from kind: %i", currentNode->kind); + break; + } +} + Module *create_set(AST_NODE_PTR currentNode){ DEBUG("create root Module"); //create tables for types @@ -229,7 +296,7 @@ Module *create_set(AST_NODE_PTR currentNode){ switch(currentNode->children[i]->kind){ case AST_Decl: - if (1 == fillTablesWithVars(variables,globalscope,create_decl(currentNode->children[i]) ,currentNode->children[i]->children[currentNode->children[i]->child_count -1]->child_count)){ + if (1 == fillTablesWithVars(variables,globalscope,createDecl(currentNode->children[i]) ,currentNode->children[i]->children[currentNode->children[i]->child_count -1]->child_count)){ //TODO behandlung, wenn var schon existiert DEBUG("var already exists"); break; @@ -237,6 +304,12 @@ Module *create_set(AST_NODE_PTR currentNode){ DEBUG("filled successfull the module and scope with vars"); break; case AST_Def: + if (1 == fillTablesWithVars(variables,globalscope,createDef(currentNode->children[i]) ,currentNode->children[i]->children[currentNode->children[i]->child_count -1]->child_count)){ + //TODO behandlung, wenn var schon existiert + DEBUG("var already exists"); + break; + } + DEBUG("filled successfull the module and scope with vars"); case AST_Box: case AST_Fun: case AST_Import: diff --git a/src/set/types.h b/src/set/types.h index 4650c86..286a2aa 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -401,7 +401,8 @@ typedef enum ExpressionKind_t { ExpressionKindOperation, ExpressionKindTypeCast, ExpressionKindTransmute, - ExpressionKindConstant + ExpressionKindConstant, + ExpressionKindVariable } ExpressionKind; typedef struct Expression_t { From 7922fbc8b79435d47c8be1f3a3071fee72e87d66 Mon Sep 17 00:00:00 2001 From: Filleo Date: Sun, 2 Jun 2024 23:26:51 +0200 Subject: [PATCH 09/29] added expressions and types --- src/set/set.c | 190 +++++++++++++++++++++++++++++++++++++++++++++--- src/set/types.h | 8 +- 2 files changed, 184 insertions(+), 14 deletions(-) diff --git a/src/set/set.c b/src/set/set.c index bad66a8..9b673a0 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,13 +6,30 @@ #include #include + GHashTable *declaredComposites;//pointer to composites with names, GHashTable *declaredBoxes;//pointer to typeboxes -GArray *Scope;//last object is current scope - - +GArray *Scope;//list of hashtables. last Hashtable is current depth of program. hashtable key: ident, value: Variable* to var +const Type ShortShortUnsingedIntType = { + .kind = TypeKindComposite, + .impl = { + .composite = { + .sign = Unsigned, + .scale = 0.25, + .primitive = Int + } + }, + .nodePtr = NULL, +}; +const Type StringLiteralType = { + .kind = TypeKindReference, + .impl = { + .reference = (ReferenceType) &ShortShortUnsingedIntType, + }, + .nodePtr = NULL, +}; Type *findType(AST_NODE_PTR currentNode){ @@ -129,7 +147,7 @@ StorageQualifier Qualifier_from_string(const char *str) { Variable **createDecl(AST_NODE_PTR currentNode){ DEBUG("create declaration"); - Variable **variables = malloc(currentNode->children[currentNode->child_count -1]->child_count * sizeof(Variable)); + Variable **variables = malloc(currentNode->children[currentNode->child_count -1]->child_count * sizeof(Variable*)); VariableDeclaration decl; decl.nodePtr = currentNode; @@ -165,21 +183,22 @@ Variable **createDecl(AST_NODE_PTR currentNode){ return variables; } -int isVariableInScope(const char* name){ - +Variable* getVariableFromScope(const char* name){ for(size_t i = 0; i < Scope->len; i++){ if(g_hash_table_contains(((GHashTable **) Scope->data)[i], name)) { - return 1; + return g_hash_table_lookup(((GHashTable**)Scope->data)[i], name); } } - return 0; + return NULL; } + + int fillTablesWithVars(GHashTable *variableTable,GHashTable *currentScope , Variable** content, size_t amount){ DEBUG("filling vars in scope and table"); for(size_t i = 0; i < amount; i++){ - if(isVariableInScope(content[i]->name)){ + if(!(NULL == getVariableFromScope(content[i]->name))){ DEBUG("this var already exist: ",content[i]->name); return 1; } @@ -218,25 +237,167 @@ TypeValue createTypeValue(AST_NODE_PTR currentNode){ return value; } +TypeValue createString(AST_NODE_PTR currentNode){ + TypeValue value; + Type *type =(Type*) &StringLiteralType; + value.type = type; + value.nodePtr = currentNode; + value.value = currentNode->value; + return value; +} + +Expression *createExpression(AST_NODE_PTR currentNode); + + +Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_NODE_PTR currentNode){ + Type *result = malloc(sizeof(Type)); + result->nodePtr = currentNode; + + + if(LeftOperandType->kind == TypeKindComposite && RightOperandType->kind == TypeKindComposite) + { + result->kind = TypeKindComposite; + CompositeType resultImpl; + + 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); + + result->impl.composite = resultImpl; + + + } else if(LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindPrimitive){ + result->kind = TypeKindPrimitive; + + result->impl.primitive = MAX(LeftOperandType->impl.primitive , RightOperandType->impl.primitive); + + } else if(LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindComposite){ + result->kind = TypeKindComposite; + + result->impl.composite.sign = Signed; + result->impl.composite.scale = MAX( 1.0, RightOperandType->impl.composite.scale); + result->impl.composite.primitive = MAX(Int, RightOperandType->impl.composite.primitive); + result->impl.composite.nodePtr = currentNode; + + } else if(LeftOperandType->kind == TypeKindComposite && RightOperandType->kind == TypeKindPrimitive){ + result->kind = TypeKindComposite; + + result->impl.composite.sign = Signed; + result->impl.composite.scale = MAX( 1.0, LeftOperandType->impl.composite.scale); + result->impl.composite.primitive = MAX(Int, LeftOperandType->impl.composite.primitive); + result->impl.composite.nodePtr = currentNode; + }else{ + return NULL; + } + return result; +} + +int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode, size_t expectedChildCount){ + + ParentExpression->impl.operation.kind = Arithmetic; + ParentExpression->impl.operation.nodePtr = currentNode; + if (expectedChildCount > currentNode->child_count){ + PANIC("Operation has to many children"); + } + for (size_t i = 0; i < currentNode->child_count; i++){ + Expression* expression = createExpression(currentNode->children[i]); + if(NULL == expression){ + return 1; + } + g_array_append_val(ParentExpression->impl.operation.operands , expression); + + } + + switch (currentNode->kind){ + case AST_Add: + ParentExpression->impl.operation.impl.arithmetic = Add; + case AST_Sub: + ParentExpression->impl.operation.impl.arithmetic = Sub; + case AST_Mul: + ParentExpression->impl.operation.impl.arithmetic = Mul; + case AST_Div: + ParentExpression->impl.operation.impl.arithmetic = Div; + case AST_Negate: + ParentExpression->impl.operation.impl.arithmetic = Negate; + default: + PANIC("Current node is not an arithmetic operater"); + break; + } + + + if(ParentExpression->impl.operation.impl.arithmetic == Negate){ + Type* result = malloc(sizeof(Type)); + result = ((Expression**) ParentExpression->impl.operation.operands->data)[0]->result; + result->nodePtr = currentNode; + if (result->kind == TypeKindReference || result->kind == TypeKindBox){ + return 1; + }else if(result->kind == TypeKindComposite){ + result->impl.composite.sign = Signed; + } + ParentExpression->result = result; + + }else{ + + Type* LeftOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[0]->result; + Type* RightOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[1]->result; + + ParentExpression->result = createTypeFromOperands(LeftOperandType, RightOperandType, currentNode); + } + + + + return 0; +} + + + Expression *createExpression(AST_NODE_PTR currentNode){ Expression *expression = malloc(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; case AST_String: - //TODO + expression->kind = ExpressionKindConstant; + expression->impl.constant = createString(currentNode); + expression->result = expression->impl.constant.type; case AST_Ident: + expression->kind = ExpressionKindVariable; + expression->impl.variable = getVariableFromScope(currentNode->value); + if(NULL == expression->impl.variable){ + DEBUG("Identifier is not in current scope"); + return NULL; + } + switch (expression->impl.variable->kind) { + case VariableKindDeclaration: + expression->result = expression->impl.variable->impl.declaration.type; + case VariableKindDefinition: + expression->result = expression->impl.variable->impl.definiton.declaration.type; + default: + PANIC("current Variable should not be an BoxMember"); + break; + } case AST_Add: case AST_Sub: case AST_Mul: case AST_Div: + expression->kind = ExpressionKindOperation; + if(createArithOperation(expression, currentNode, 2)){ + return NULL; + } case AST_Negate: + expression->kind = ExpressionKindOperation; + if(createArithOperation(expression,currentNode, 1)){ + return NULL; + } + case AST_Eq: case AST_Less: @@ -252,6 +413,13 @@ Expression *createExpression(AST_NODE_PTR currentNode){ case AST_BitXor: case AST_BitNot: + case AST_IdentList: + //Box Accsess + case AST_List: + // Box Self Access + case AST_Typekind: + case AST_Transmute: + default: PANIC("Node is not an expression but from kind: %i", currentNode->kind); diff --git a/src/set/types.h b/src/set/types.h index 286a2aa..d425066 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -188,6 +188,7 @@ typedef enum ParameterKind_t { */ typedef struct Parameter_t { const char* name; + ParameterKind kind; union ParameterImplementation { ParameterDeclaration declaration; @@ -316,7 +317,8 @@ typedef enum ArithmeticOperator_t { Add, Sub, Mul, - Div + Div, + Negate } ArithmeticOperator; // .------------------------------------------------. @@ -389,7 +391,7 @@ typedef struct Operation_t { LogicalOperator logical; BitwiseOperator bitwise; } impl; - Expression* operands; + GArray* operands; //Expression* AST_NODE_PTR nodePtr; } Operation; @@ -414,7 +416,7 @@ typedef struct Expression_t { TypeCast typecast; Transmute transmute; TypeValue constant; - Variable variable; + Variable* variable; } impl; AST_NODE_PTR nodePtr; } Expression; From 70859e0a6a04deb5021d5e8356f31550c19d5da7 Mon Sep 17 00:00:00 2001 From: Filleo Date: Sun, 2 Jun 2024 23:27:22 +0200 Subject: [PATCH 10/29] added default values to enums --- src/set/types.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/set/types.h b/src/set/types.h index d425066..08e8418 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -11,9 +11,9 @@ */ typedef enum PrimitiveType_t { // 4 byte signed integer in two's complement - Int, + Int =0, // 4 byte IEEE-754 single precision - Float + Float =1 } PrimitiveType; /** @@ -21,10 +21,10 @@ typedef enum PrimitiveType_t { * */ typedef enum Sign_t { - // type has a sign bit - Signed, // type has no sign bit - Unsigned + Unsigned = 0, + // type has a sign bit + Signed = 1 } Sign; /** @@ -387,7 +387,7 @@ typedef struct Operation_t { union OperationImplementation { ArithmeticOperator arithmetic; RelationalOperator relational; - BooleanOperator boolean; + BooleanOperator boolean; LogicalOperator logical; BitwiseOperator bitwise; } impl; From 523a9f19cc7cb27f803b118fd73d0b637a924c4a Mon Sep 17 00:00:00 2001 From: Filleo Date: Mon, 3 Jun 2024 11:53:09 +0200 Subject: [PATCH 11/29] added relational and boolian operands --- src/set/set.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/src/set/set.c b/src/set/set.c index 9b673a0..39caba4 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -345,12 +345,110 @@ int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode, ParentExpression->result = createTypeFromOperands(LeftOperandType, RightOperandType, currentNode); } + if(ParentExpression->result == NULL){ + return 1; + } return 0; } +int createRelationalOperation(Expression* ParentExpression,AST_NODE_PTR currentNode){ + //fill kind and Nodeptr + ParentExpression->impl.operation.kind = Relational; + ParentExpression->impl.operation.nodePtr = currentNode; + //fill Operands + for (size_t i = 0; i < currentNode->child_count; i++){ + Expression* expression = createExpression(currentNode->children[i]); + if(NULL == expression){ + return 1; + } + g_array_append_val(ParentExpression->impl.operation.operands , expression); + } + + //fill impl + switch (currentNode->kind){ + case AST_Eq: + ParentExpression->impl.operation.impl.relational = Equal; + case AST_Less: + ParentExpression->impl.operation.impl.relational = Greater; + case AST_Greater: + ParentExpression->impl.operation.impl.relational= Less; + default: + PANIC("Current node is not an relational operater"); + break; + } + Type * result = malloc(sizeof(Type)); + result->impl.primitive = Int; + result->kind = TypeKindPrimitive; + result->nodePtr = currentNode; + + ParentExpression->result = result; + return 0; +} + + +int createBoolOperation(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]); + if(NULL == expression){ + return 1; + } + g_array_append_val(ParentExpression->impl.operation.operands , expression); + } + + switch (currentNode->kind){ + case AST_BoolAnd: + ParentExpression->impl.operation.impl.boolean = BooleanAnd; + case AST_BoolOr: + ParentExpression->impl.operation.impl.boolean = BooleanOr; + case AST_BoolXor: + ParentExpression->impl.operation.impl.boolean = BooleanXor; + default: + PANIC("Current node is not an boolean operater"); + break; + } + + + Type* LeftOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[0]->result; + Type* RightOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[1]->result; + + //should not be a box or a reference + if(LeftOperandType->kind != TypeKindPrimitive && LeftOperandType->kind != TypeKindComposite){ + return 1; + } + if(RightOperandType->kind != TypeKindPrimitive && RightOperandType->kind != TypeKindComposite){ + return 1; + } + //should not be a float + if(LeftOperandType->kind == TypeKindComposite){ + if(LeftOperandType->impl.composite.primitive == Float){ + return 1; + } + }else if(LeftOperandType->kind == TypeKindPrimitive){ + if(LeftOperandType->impl.primitive == Float){ + return 1; + } + }else if(RightOperandType->kind == TypeKindComposite){ + if(RightOperandType->impl.composite.primitive == Float){ + return 1; + } + }else if(RightOperandType->kind == TypeKindPrimitive){ + if(RightOperandType->impl.primitive == Float){ + return 1; + } + } + + + ParentExpression->result = createTypeFromOperands(LeftOperandType, RightOperandType, currentNode); + return 0; +} Expression *createExpression(AST_NODE_PTR currentNode){ Expression *expression = malloc(sizeof(Expression)); @@ -402,11 +500,19 @@ Expression *createExpression(AST_NODE_PTR currentNode){ case AST_Eq: case AST_Less: case AST_Greater: + expression->kind = ExpressionKindOperation; + if(createRelationalOperation(expression,currentNode)){ + return NULL; + } case AST_BoolAnd: - case AST_BoolNot: case AST_BoolOr: case AST_BoolXor: + expression->kind = ExpressionKindOperation; + if(createRelationalOperation(expression,currentNode)){ + return NULL; + } + case AST_BoolNot: case AST_BitAnd: case AST_BitOr: From 8a2eeb63b843173a28c0afb88f3cde0fd9ac990a Mon Sep 17 00:00:00 2001 From: Filleo Date: Mon, 3 Jun 2024 13:54:03 +0200 Subject: [PATCH 12/29] added Bool Not to expression --- src/set/set.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/set/set.c b/src/set/set.c index 39caba4..3fda6a3 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -450,6 +450,48 @@ int createBoolOperation(Expression *ParentExpression, AST_NODE_PTR currentNode){ return 0; } +int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNode){ + //fill kind and Nodeptr + ParentExpression->impl.operation.kind = Boolean; + ParentExpression->impl.operation.nodePtr = currentNode; + + //fill Operand + Expression* expression = createExpression(currentNode->children[0]); + if(NULL == expression){ + return 1; + } + 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* result = malloc(sizeof(Type)); + result->nodePtr = currentNode; + if (Operand->kind == TypeKindBox || Operand->kind == TypeKindReference){ + return 1; + } + if(Operand->kind == TypeKindPrimitive){ + if(Operand->impl.primitive == Float){ + return 1; + } + result->kind = Operand->kind; + result->impl = Operand->impl; + }else if(Operand->kind == TypeKindComposite){ + if(Operand->impl.composite.primitive == Float){ + return 1; + } + result->kind = Operand->kind; + result->impl = Operand->impl; + } + + ParentExpression->result = result; + return 0; +} + + + + Expression *createExpression(AST_NODE_PTR currentNode){ Expression *expression = malloc(sizeof(Expression)); expression->nodePtr = currentNode; @@ -509,14 +551,19 @@ Expression *createExpression(AST_NODE_PTR currentNode){ case AST_BoolOr: case AST_BoolXor: expression->kind = ExpressionKindOperation; - if(createRelationalOperation(expression,currentNode)){ + if(createBoolOperation(expression,currentNode)){ return NULL; } case AST_BoolNot: + expression->kind= ExpressionKindOperation; + if(createBoolNotOperation(expression, currentNode)){ + return NULL; + } case AST_BitAnd: case AST_BitOr: case AST_BitXor: + case AST_BitNot: case AST_IdentList: From 879940dee9ce56a05ea60a2c2777315be32841bb Mon Sep 17 00:00:00 2001 From: Filleo Date: Mon, 3 Jun 2024 19:42:58 +0200 Subject: [PATCH 13/29] midway of creating Bit Operation in expression --- src/set/set.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/set/set.c b/src/set/set.c index 3fda6a3..5c73209 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -489,7 +489,21 @@ int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNod return 0; } +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]); + if(NULL == expression){ + return 1; + } + g_array_append_val(ParentExpression->impl.operation.operands , expression); + } + +} Expression *createExpression(AST_NODE_PTR currentNode){ @@ -563,6 +577,10 @@ Expression *createExpression(AST_NODE_PTR currentNode){ case AST_BitAnd: case AST_BitOr: case AST_BitXor: + expression->kind= ExpressionKindOperation; + if(createBitOperation(expression, currentNode)){ + return NULL; + } case AST_BitNot: From 1de671cd8b877dae094c75fdb42f5190dffd6973 Mon Sep 17 00:00:00 2001 From: Filleo Date: Mon, 3 Jun 2024 21:39:07 +0200 Subject: [PATCH 14/29] major reconstruction Co-authored-by: servostar Co-authored-by: SirTalksalot75 --- src/set/set.c | 354 ++++++++++++++++++++++++++++++++++++++++---------- src/set/set.h | 3 + 2 files changed, 286 insertions(+), 71 deletions(-) diff --git a/src/set/set.c b/src/set/set.c index 5c73209..1e385cb 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -3,13 +3,15 @@ #include #include #include +#include #include #include +#include +#include - -GHashTable *declaredComposites;//pointer to composites with names, -GHashTable *declaredBoxes;//pointer to typeboxes -GArray *Scope;//list of hashtables. last Hashtable is current depth of program. hashtable key: ident, value: Variable* to var +GHashTable *declaredComposites = NULL;//pointer to composites with names, +GHashTable *declaredBoxes = NULL;//pointer to typeboxes +GArray *Scope = NULL;//list of hashtables. last Hashtable is current depth of program. hashtable key: ident, value: Variable* to var const Type ShortShortUnsingedIntType = { .kind = TypeKindComposite, @@ -31,64 +33,154 @@ const Type StringLiteralType = { .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) { -Type *findType(AST_NODE_PTR currentNode){ + if (strcmp(string, "unsigned") == 0) { + *sign = Unsigned; + return 0; + } else if (strcmp(string, "signed") == 0) { + *sign = Signed; + return 0; + } + + return 1; +} + +/** + * @brief Convert a string into a primitive type + * @return 0 on success, 1 otherwise + */ +int primitive_from_string(const char* string, PrimitiveType* primitive) { + + if (strcmp(string, "int") == 0) { + *primitive = Int; + return 0; + } else if (strcmp(string, "float") == 0) { + *primitive = Float; + return 0; + } + + return 1; +} + +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) { + *factor = 2.0; + return SEMANTIC_OK; + } + + return SEMANTIC_ERROR; +} + +int merge_scale_list(AST_NODE_PTR scale_list, Scale* scale) { + for (size_t i = 0; i < scale_list->child_count; i++) { + + double scale_in_list = 1.0; + int scale_invalid = scale_factor_from(AST_get_node(scale_list, i)->value, &scale_in_list); + + if (scale_invalid == SEMANTIC_ERROR) { + return SEMANTIC_ERROR; + } + + *scale *= scale_in_list; + + if (0.25 > *scale || 8 > *scale) { + // TODO: print diagnostic: Invalid composite scale + return SEMANTIC_ERROR; + } + } + + return SEMANTIC_OK; +} + +Type *findType(AST_NODE_PTR currentNode); + +int impl_composite_type(AST_NODE_PTR ast_type, CompositeType* composite) { + DEBUG("Type is a Composite"); + + int status = SEMANTIC_OK; + int scaleNodeOffset = 0; + + // check if we have a sign + if (AST_Sign == ast_type->children[0]->kind) { + + status = sign_from_string(ast_type->children[0]->value, &composite->sign); + + if (status == SEMANTIC_ERROR) { + ERROR("invalid sign: %s", ast_type->children[0]->value); + return SEMANTIC_ERROR; + } + + scaleNodeOffset++; + } + + composite->scale = 1.0; + + // 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) { + return SEMANTIC_ERROR; + } + } + + const char* typeKind = ast_type->children[ast_type->child_count - 1]->value; + + status = primitive_from_string(typeKind, &composite->primitive); + + if (status == SEMANTIC_ERROR) { + // not a primitive try to resolve the type by name (must be a composite) + status = impl_composite_type(); + } + + return SEMANTIC_OK; +} + +/** + * @brief Converts the given AST node to a gemstone type implementation. + * @param currentNode AST node of type kind type + * @return the gemstone type implementation + */ +Type *findType(AST_NODE_PTR currentNode) { + assert(currentNode != NULL); + assert(currentNode->kind == AST_Type); + assert(currentNode->child_count > 0); const char *typekind = currentNode->children[currentNode->child_count -1]->value; - if (0 == strcmp(typekind, "int")||0 == strcmp(typekind, "float")){ + + // type implementation + Type *type = malloc(sizeof(Type)); + type->nodePtr = currentNode; + + // primitive type OR composit + if (0 == strcmp(typekind, "int") || 0 == strcmp(typekind, "float")) { - Type *type = malloc(sizeof(Type)); - type->nodePtr = currentNode; - if(AST_Typekind != currentNode->children[0]->kind){ - DEBUG("Type is a Composite"); + if(AST_Typekind != currentNode->children[0]->kind) { + type->kind = TypeKindComposite; - - - CompositeType composite; - composite.nodePtr = currentNode; - - - if(0 == strcmp(typekind, "int")){ - composite.primitive = Int; - }else{ - composite.primitive = Float; - } - composite.sign = Signed; - - size_t scalelist = 0; - if(AST_Sign == currentNode->children[0]->kind){ - if(0 == strcmp(currentNode->children[0]->value, "unsigned")){ - composite.sign = Unsigned; - } - scalelist = 1; - } - - composite.scale = 1.0; - if(AST_List == currentNode->children[scalelist]->kind){ - for (size_t i = 0; i < currentNode->children[scalelist]->child_count; i++){ - if (0 == strcmp(currentNode->children[scalelist]->children[i]->value, "short") || 0 == strcmp(currentNode->children[scalelist]->children[i]->value, "half")){ - composite.scale /= 2; - }else{ - composite.scale *= 2; - } - if (0.25 > composite.scale || 8 > composite.scale) { - //TODO scale not right - } - } - } - - type->impl.composite = composite; - - - }else{ + type->impl.composite.nodePtr = currentNode; + impl_composite_type(currentNode, &type->impl.composite, typekind); + + } else { + // type is a primitive type->kind = TypeKindPrimitive; - if(0 == strcmp(typekind, "int")){ - type->impl.primitive = Int; - }else{ - type->impl.primitive = Float; + + int primitive_invalid = primitive_from_string(typekind, &type->impl.primitive); + + if (primitive_invalid) { + PANIC("invalid primitive: %s", typekind); } - return type; } + }else if(g_hash_table_contains(declaredBoxes, typekind)){ if(AST_Typekind != currentNode->children[0]->kind){ //TODO composite Box try @@ -208,9 +300,7 @@ int fillTablesWithVars(GHashTable *variableTable,GHashTable *currentScope , Vari return 0; } -Variable **createDef(AST_NODE_PTR currentNode){ -} @@ -489,6 +579,16 @@ int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNod return 0; } +bool isScaleEqual(double leftScale, double rightScale){ + int leftIntScale =(int)(leftScale *4); + int rightIntScale =(int)(rightScale *4); + + if (leftIntScale == rightIntScale){ + return TRUE; + } + return FALSE; +} + int createBitOperation(Expression* ParentExpression, AST_NODE_PTR currentNode){ //fill kind and Nodeptr ParentExpression->impl.operation.kind = Boolean; @@ -503,6 +603,113 @@ int createBitOperation(Expression* ParentExpression, AST_NODE_PTR currentNode){ g_array_append_val(ParentExpression->impl.operation.operands , expression); } + + switch (currentNode->kind){ + case AST_BitAnd: + ParentExpression->impl.operation.impl.bitwise = BitwiseAnd; + case AST_BitOr: + ParentExpression->impl.operation.impl.bitwise = BitwiseOr; + case AST_BitXor: + ParentExpression->impl.operation.impl.bitwise = BitwiseXor; + default: + PANIC("Current node is not an bitwise operater"); + break; + } + + + Type *result = malloc(sizeof(Type)); + result->nodePtr = currentNode; + + Type* LeftOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[0]->result; + Type* RightOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[1]->result; + + //should not be a box or a reference + if(LeftOperandType->kind != TypeKindPrimitive && LeftOperandType->kind != TypeKindComposite){ + return 1; + } + if(RightOperandType->kind != TypeKindPrimitive && RightOperandType->kind != TypeKindComposite){ + return 1; + } + if(LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindPrimitive){ + if(LeftOperandType->impl.primitive == Float || RightOperandType->impl.primitive == Float){ + return 1; + } + result->kind = TypeKindPrimitive; + result->impl.primitive = Int; + }else if(LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindComposite){ + if(LeftOperandType->impl.primitive == Float || RightOperandType->impl.composite.primitive == Float){ + return 1; + } + if((int)RightOperandType->impl.composite.scale != 1){ + return 1; + } + result->kind = TypeKindPrimitive; + result->impl.primitive = Int; + }else if(LeftOperandType->kind == TypeKindComposite && RightOperandType->kind == TypeKindPrimitive){ + if(LeftOperandType->impl.composite.primitive == Float || RightOperandType->impl.primitive == Float){ + return 1; + } + if((int)LeftOperandType->impl.composite.scale != 1){ + return 1; + } + result->kind = TypeKindPrimitive; + result->impl.primitive = Int; + }else{ + if(LeftOperandType->impl.composite.primitive == Float || RightOperandType->impl.composite.primitive == Float){ + return 1; + } + if(!isScaleEqual(LeftOperandType->impl.composite.scale, RightOperandType->impl.composite.scale)){ + return 1; + } + result->kind = TypeKindComposite; + result->impl.composite.nodePtr = currentNode; + result->impl.composite.scale = LeftOperandType->impl.composite.scale; + result->impl.composite.sign = MAX(LeftOperandType->impl.composite.sign, RightOperandType->impl.composite.sign); + } + + ParentExpression->result = result; + return 0; +} + +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){ + return 1; + } + 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 = malloc(sizeof(Type)); + result->nodePtr = currentNode; + + + if (Operand->kind == TypeKindPrimitive){ + if(Operand->impl.primitive == Float){ + return SEMANTIC_ERROR; + } + result->kind = TypeKindPrimitive; + result->impl.primitive = Int; + }else if(Operand->kind == TypeKindComposite){ + if (Operand->impl.composite.primitive == Float){ + return SEMANTIC_ERROR; + } + result->kind = TypeKindComposite; + result->impl.composite.nodePtr = 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; } @@ -516,11 +723,12 @@ Expression *createExpression(AST_NODE_PTR currentNode){ 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: expression->kind = ExpressionKindVariable; expression->impl.variable = getVariableFromScope(currentNode->value); @@ -531,13 +739,15 @@ Expression *createExpression(AST_NODE_PTR currentNode){ switch (expression->impl.variable->kind) { case VariableKindDeclaration: expression->result = expression->impl.variable->impl.declaration.type; + 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: @@ -545,14 +755,14 @@ Expression *createExpression(AST_NODE_PTR currentNode){ 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: @@ -560,7 +770,7 @@ Expression *createExpression(AST_NODE_PTR currentNode){ if(createRelationalOperation(expression,currentNode)){ return NULL; } - + break; case AST_BoolAnd: case AST_BoolOr: case AST_BoolXor: @@ -568,12 +778,13 @@ Expression *createExpression(AST_NODE_PTR currentNode){ 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: @@ -581,8 +792,13 @@ Expression *createExpression(AST_NODE_PTR currentNode){ if(createBitOperation(expression, currentNode)){ return NULL; } - + break; case AST_BitNot: + expression->kind = ExpressionKindOperation; + if(createBitNotOperation(expression, currentNode)){ + return NULL; + } + break; case AST_IdentList: //Box Accsess @@ -590,12 +806,14 @@ Expression *createExpression(AST_NODE_PTR currentNode){ // Box Self Access case AST_Typekind: case AST_Transmute: - + + default: PANIC("Node is not an expression but from kind: %i", currentNode->kind); break; } + return expression; } Module *create_set(AST_NODE_PTR currentNode){ @@ -643,12 +861,6 @@ Module *create_set(AST_NODE_PTR currentNode){ DEBUG("filled successfull the module and scope with vars"); break; case AST_Def: - if (1 == fillTablesWithVars(variables,globalscope,createDef(currentNode->children[i]) ,currentNode->children[i]->children[currentNode->children[i]->child_count -1]->child_count)){ - //TODO behandlung, wenn var schon existiert - DEBUG("var already exists"); - break; - } - DEBUG("filled successfull the module and scope with vars"); case AST_Box: case AST_Fun: case AST_Import: diff --git a/src/set/set.h b/src/set/set.h index 033dee5..1ec9e85 100644 --- a/src/set/set.h +++ b/src/set/set.h @@ -3,6 +3,9 @@ #include +#define SEMANTIC_OK 0 +#define SEMANTIC_ERROR 1 + void create_set(AST_NODE_PTR rootNodePtr ); #endif From 40ba9ad95dc25c6d436da16b537b559e14d3e869 Mon Sep 17 00:00:00 2001 From: Filleo Date: Mon, 3 Jun 2024 21:52:49 +0200 Subject: [PATCH 15/29] commit before merge --- src/set/set.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/set/set.c b/src/set/set.c index 1e385cb..c2761ea 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -133,13 +133,13 @@ int impl_composite_type(AST_NODE_PTR ast_type, CompositeType* composite) { } } - const char* typeKind = ast_type->children[ast_type->child_count - 1]->value; + AST_NODE_PTR typeKind = ast_type->children[ast_type->child_count - 1]; - status = primitive_from_string(typeKind, &composite->primitive); + status = primitive_from_string(typeKind->value, &composite->primitive); if (status == SEMANTIC_ERROR) { // not a primitive try to resolve the type by name (must be a composite) - status = impl_composite_type(); + } return SEMANTIC_OK; @@ -861,6 +861,8 @@ Module *create_set(AST_NODE_PTR currentNode){ DEBUG("filled successfull the module and scope with vars"); break; case AST_Def: + DEBUG("created Definition successfully"); + break; case AST_Box: case AST_Fun: case AST_Import: @@ -868,7 +870,7 @@ Module *create_set(AST_NODE_PTR currentNode){ g_array_append_val(imports, currentNode->children[i]->value); break; default: - INFO("Provided source file could not be parsed beecause of semantic error."); + INFO("Provided source file could not be parsed because of semantic error."); break; } From 4d33c81c3feed46752baadb09ebedc254a48a922 Mon Sep 17 00:00:00 2001 From: Filleo Date: Mon, 3 Jun 2024 23:58:19 +0200 Subject: [PATCH 16/29] major reconstruction of SET Co-authored-by: servostar Co-authored-by: SirTalksalot75 --- src/set/set.c | 673 +++++++++++++++++++++++++++++++----------------- src/set/set.h | 3 +- src/set/types.h | 2 +- 3 files changed, 434 insertions(+), 244 deletions(-) diff --git a/src/set/set.c b/src/set/set.c index c2761ea..f63aa83 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -1,3 +1,5 @@ +#include "io/files.h" +#include "yacc/parser.tab.h" #include #include #include @@ -38,6 +40,8 @@ const Type StringLiteralType = { * @return 0 on success, 1 otherwise */ int sign_from_string(const char* string, Sign* sign) { + assert(string != NULL); + assert(sign != NULL); if (strcmp(string, "unsigned") == 0) { *sign = Unsigned; @@ -55,6 +59,8 @@ int sign_from_string(const char* string, Sign* sign) { * @return 0 on success, 1 otherwise */ int primitive_from_string(const char* string, PrimitiveType* primitive) { + assert(string != NULL); + assert(primitive != NULL); if (strcmp(string, "int") == 0) { *primitive = Int; @@ -68,6 +74,9 @@ int primitive_from_string(const char* string, PrimitiveType* primitive) { } int scale_factor_from(const char* string, double* factor) { + assert(string != NULL); + assert(factor != NULL); + if (strcmp(string, "half") == 0 || strcmp(string, "short") == 0) { *factor = 0.5; return SEMANTIC_OK; @@ -79,7 +88,24 @@ int scale_factor_from(const char* string, double* factor) { return SEMANTIC_ERROR; } +int check_scale_factor(AST_NODE_PTR node, Scale scale) { + assert(node != NULL); + + if (8 > 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) { + assert(scale_list != NULL); + assert(scale != NULL); + for (size_t i = 0; i < scale_list->child_count; i++) { double scale_in_list = 1.0; @@ -90,24 +116,39 @@ int merge_scale_list(AST_NODE_PTR scale_list, Scale* scale) { } *scale *= scale_in_list; - - if (0.25 > *scale || 8 > *scale) { - // TODO: print diagnostic: Invalid composite scale - return SEMANTIC_ERROR; - } } return SEMANTIC_OK; } -Type *findType(AST_NODE_PTR currentNode); +/** + * @brief Get an already declared type from its name + */ +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); + + return SEMANTIC_OK; + } + + return SEMANTIC_ERROR; +} int impl_composite_type(AST_NODE_PTR ast_type, CompositeType* composite) { + assert(ast_type != NULL); + assert(composite != NULL); + DEBUG("Type is a Composite"); int status = SEMANTIC_OK; int scaleNodeOffset = 0; + composite->sign = Signed; + // check if we have a sign if (AST_Sign == ast_type->children[0]->kind) { @@ -137,12 +178,37 @@ int impl_composite_type(AST_NODE_PTR ast_type, CompositeType* composite) { 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; + status = get_type_decl(typeKind->value, &nested_type); + + if (status == SEMANTIC_ERROR) { + print_diagnostic(current_file, &typeKind->location, Error, "Unknown composite type in declaration"); + return SEMANTIC_ERROR; + } + + if (nested_type->kind == TypeKindComposite) { + // 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; + } } - return SEMANTIC_OK; + return check_scale_factor(ast_type, composite->scale); } /** @@ -150,86 +216,53 @@ int impl_composite_type(AST_NODE_PTR ast_type, CompositeType* composite) { * @param currentNode AST node of type kind type * @return the gemstone type implementation */ -Type *findType(AST_NODE_PTR currentNode) { +int get_type_impl(AST_NODE_PTR currentNode, Type** type) { assert(currentNode != NULL); assert(currentNode->kind == AST_Type); assert(currentNode->child_count > 0); + int status; + const char *typekind = currentNode->children[currentNode->child_count -1]->value; - - // type implementation - Type *type = malloc(sizeof(Type)); - type->nodePtr = currentNode; - // primitive type OR composit - if (0 == strcmp(typekind, "int") || 0 == strcmp(typekind, "float")) { - - if(AST_Typekind != currentNode->children[0]->kind) { - - type->kind = TypeKindComposite; - type->impl.composite.nodePtr = currentNode; - impl_composite_type(currentNode, &type->impl.composite, typekind); - - } else { - // type is a primitive - type->kind = TypeKindPrimitive; - - int primitive_invalid = primitive_from_string(typekind, &type->impl.primitive); - - if (primitive_invalid) { - PANIC("invalid primitive: %s", typekind); - } - } - - }else if(g_hash_table_contains(declaredBoxes, typekind)){ - if(AST_Typekind != currentNode->children[0]->kind){ - //TODO composite Box try - } - return (Type *) g_hash_table_lookup(declaredBoxes, typekind); - }else if(g_hash_table_contains(declaredComposites, typekind)){ - if(AST_Typekind != currentNode->children[0]->kind){ - Type *composite = malloc(sizeof(Type)); - - *composite = *(Type*) g_hash_table_lookup(declaredComposites, typekind); - - - - size_t scalelist = 0; - if(AST_Sign == currentNode->children[0]->kind){ - if(0 == strcmp(currentNode->children[0]->value, "unsigned")){ - composite->impl.composite.sign = Unsigned; - }else if(0 == strcmp(currentNode->children[0]->value, "unsigned")){ - composite->impl.composite.sign = Signed; - } - scalelist = 1; - } - - - if(AST_List == currentNode->children[scalelist]->kind){ - for (size_t i = 0; i < currentNode->children[scalelist]->child_count; i++){ - if (0 == strcmp(currentNode->children[scalelist]->children[i]->value, "short") || 0 == strcmp(currentNode->children[scalelist]->children[i]->value, "half")){ - composite->impl.composite.scale /= 2; - }else{ - composite->impl.composite.scale *= 2; - } - if (0.25 > composite->impl.composite.scale || 8 > composite->impl.composite.scale) { - //TODO scale not right - return NULL; - } - } - } - return composite; - } - return (Type *) g_hash_table_lookup(declaredComposites, typekind); - }else{ - //TODO doesnt know typekind - return NULL; + if (g_hash_table_contains(declaredComposites, typekind) == TRUE) { + *type = g_hash_table_lookup(declaredComposites, typekind); + return SEMANTIC_OK; } - return NULL; + + if (g_hash_table_contains(declaredBoxes, typekind) == TRUE) { + *type = g_hash_table_lookup(declaredBoxes, typekind); + return SEMANTIC_OK; + } + + // type is not yet declared, make a new one + + Type* new_type = malloc(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) { + // type is a primitive + new_type->kind = TypeKindPrimitive; + + status = primitive_from_string(typekind, &new_type->impl.primitive); + + // if err continue at composite construction + if (status == SEMANTIC_OK) { + return SEMANTIC_OK; + } + } + + new_type->kind = TypeKindComposite; + new_type->impl.composite.nodePtr = currentNode; + status = impl_composite_type(currentNode, &new_type->impl.composite); + *type = new_type; + + return status; } - - StorageQualifier Qualifier_from_string(const char *str) { if (!strncmp(str, "local", 5)) return Local; if (!strncmp(str, "static", 6)) return Static; @@ -237,73 +270,127 @@ StorageQualifier Qualifier_from_string(const char *str) { PANIC("Provided string is not a storagequalifier: %s", str); } -Variable **createDecl(AST_NODE_PTR currentNode){ +int createDecl(AST_NODE_PTR currentNode, GArray** variables) { DEBUG("create declaration"); - Variable **variables = malloc(currentNode->children[currentNode->child_count -1]->child_count * sizeof(Variable*)); + + AST_NODE_PTR ident_list = currentNode->children[currentNode->child_count - 1]; + + *variables = g_array_new(FALSE, FALSE, sizeof(Variable*)); VariableDeclaration decl; decl.nodePtr = currentNode; + int status = SEMANTIC_OK; + + DEBUG("Child Count: %i", currentNode->child_count); + + for (size_t i = 0; i < currentNode->child_count; i++) { + switch(currentNode->children[i]->kind){ + case AST_Storage: + DEBUG("fill Qualifier"); + decl.qualifier = Qualifier_from_string(currentNode->children[i]->value); + break; + case AST_Type: + DEBUG("fill Type"); + status = get_type_impl(currentNode->children[i], &decl.type); + break; + case AST_IdentList: + break; + default: + PANIC("invalid node type: %ld", currentNode->children[i]->kind); + break; + } + } + + for(size_t i = 0; i < ident_list->child_count; i++) { + Variable* variable = malloc(sizeof(Variable)); + + variable->kind = VariableKindDeclaration; + variable->nodePtr = currentNode; + variable->name = ident_list->children[i]->value; + variable->impl.declaration = decl; + + g_array_append_val(*variables, variable); + } + + return status; +} + +int createDef(AST_NODE_PTR currentNode, GArray** variables) { + assert(variables != NULL); + assert(currentNode != NULL); + + DEBUG("create definition"); + + AST_NODE_PTR declaration = currentNode->children[currentNode->child_count - 1]; + + * variables = g_array_new(FALSE, FALSE, sizeof(Variable*)); + + VariableDefiniton def; + def.nodePtr = currentNode; + + Variable* variable = malloc(sizeof(Variable)); + variable->kind = VariableKindDefinition; + variable->nodePtr = currentNode; + variable->name = declaration->children[1]->value; + variable->impl.definiton= def; + g_array_append_val(*variables, variable); + + int status = SEMANTIC_OK; + DEBUG("Child Count: %i", currentNode->child_count); for (size_t i = 0; i < currentNode->child_count; i++){ - switch(currentNode->children[i]->kind){ - case AST_Storage: - DEBUG("fill Qualifier"); - decl.qualifier = Qualifier_from_string(currentNode->children[i]->value); - break; - case AST_Type: - DEBUG("fill Type"); - decl.type = findType(currentNode->children[i]); - break; - case AST_IdentList: - for(size_t i = 0; i < currentNode->children[currentNode->child_count -1]->child_count; i++){ - Variable *variable = malloc(sizeof(Variable)); - variable->kind = VariableKindDeclaration; - variable->nodePtr = currentNode; - variable->name = currentNode->children[currentNode->child_count -1]->children[i]->value; - variable->impl.declaration = decl; - variables[i] = variable; - } - break; - default: - //TODO PANIC maybe - break; + switch(currentNode->children[i]->kind) { + case AST_Decl: + break; + default: + PANIC("invalid node type: %ld", currentNode->children[i]->kind); + break; } } + return status; +} + +int getVariableFromScope(const char* name, Variable** variable) { + assert(name != NULL); + assert(variable != NULL); + assert(Scope != NULL); + + // loop through all variable scope and find a variable + for(size_t i = 0; i < Scope->len; i++) { + GHashTable* variable_table = ((GHashTable**) Scope->data)[i]; + + if(g_hash_table_contains(variable_table, name)) { + *variable = g_hash_table_lookup(variable_table, name); + return SEMANTIC_OK; + } + } + + return SEMANTIC_ERROR; +} + +int fillTablesWithVars(GHashTable *variableTable, GHashTable *currentScope , GArray* variables) { + DEBUG("filling vars in scope and table"); + + for(size_t i = 0; i < variables->len; i++) { + Variable* var = (Variable*) variables->data + i; + + // this variable is discarded, only need status code + Variable* tmp = NULL; + if(getVariableFromScope(var->name, &tmp) == SEMANTIC_OK) { + INFO("this var already exist: ", var->name); + return SEMANTIC_ERROR; + } + + g_hash_table_insert(variableTable, (gpointer) var->name, var); + g_hash_table_insert(currentScope, (gpointer) var->name, var); + } - return variables; + return SEMANTIC_OK; } -Variable* getVariableFromScope(const char* name){ - for(size_t i = 0; i < Scope->len; i++){ - if(g_hash_table_contains(((GHashTable **) Scope->data)[i], name)) - { - return g_hash_table_lookup(((GHashTable**)Scope->data)[i], name); - } - } - return NULL; -} - - - -int fillTablesWithVars(GHashTable *variableTable,GHashTable *currentScope , Variable** content, size_t amount){ - DEBUG("filling vars in scope and table"); - for(size_t i = 0; i < amount; i++){ - if(!(NULL == getVariableFromScope(content[i]->name))){ - DEBUG("this var already exist: ",content[i]->name); - return 1; - } - g_hash_table_insert(variableTable, (gpointer) content[i]->name, content[i] ); - g_hash_table_insert(currentScope, (gpointer) content[i]->name, content[i] ); - } - return 0; -} - - - - - +[[nodiscard("type must be freed")]] TypeValue createTypeValue(AST_NODE_PTR currentNode){ TypeValue value; Type *type = malloc(sizeof(Type)); @@ -312,40 +399,36 @@ TypeValue createTypeValue(AST_NODE_PTR currentNode){ type->nodePtr = currentNode; switch (currentNode->kind) { - case AST_Int: type->impl.primitive = Int; case AST_Float: - type->impl.primitive = Int; + type->impl.primitive = Float; 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; - } + } value.nodePtr = currentNode; value.value = currentNode->value; return value; } -TypeValue createString(AST_NODE_PTR currentNode){ +TypeValue createString(AST_NODE_PTR currentNode) { TypeValue value; - Type *type =(Type*) &StringLiteralType; + Type *type = (Type*) &StringLiteralType; value.type = type; value.nodePtr = currentNode; value.value = currentNode->value; return value; } -Expression *createExpression(AST_NODE_PTR currentNode); +Expression* createExpression(AST_NODE_PTR currentNode); - -Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_NODE_PTR currentNode){ +Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_NODE_PTR currentNode) { Type *result = malloc(sizeof(Type)); result->nodePtr = currentNode; - - if(LeftOperandType->kind == TypeKindComposite && RightOperandType->kind == TypeKindComposite) - { + if (LeftOperandType->kind == TypeKindComposite && RightOperandType->kind == TypeKindComposite) { result->kind = TypeKindComposite; CompositeType resultImpl; @@ -353,81 +436,87 @@ Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_ 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); - - result->impl.composite = resultImpl; + result->impl.composite = resultImpl; - } else if(LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindPrimitive){ + } else if (LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindPrimitive) { result->kind = TypeKindPrimitive; result->impl.primitive = MAX(LeftOperandType->impl.primitive , RightOperandType->impl.primitive); - } else if(LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindComposite){ + } else if (LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindComposite) { result->kind = TypeKindComposite; result->impl.composite.sign = Signed; - result->impl.composite.scale = MAX( 1.0, RightOperandType->impl.composite.scale); + result->impl.composite.scale = MAX(1.0, RightOperandType->impl.composite.scale); result->impl.composite.primitive = MAX(Int, RightOperandType->impl.composite.primitive); result->impl.composite.nodePtr = currentNode; - } else if(LeftOperandType->kind == TypeKindComposite && RightOperandType->kind == TypeKindPrimitive){ + } else if (LeftOperandType->kind == TypeKindComposite && RightOperandType->kind == TypeKindPrimitive) { result->kind = TypeKindComposite; result->impl.composite.sign = Signed; - result->impl.composite.scale = MAX( 1.0, LeftOperandType->impl.composite.scale); + result->impl.composite.scale = MAX(1.0, LeftOperandType->impl.composite.scale); result->impl.composite.primitive = MAX(Int, LeftOperandType->impl.composite.primitive); result->impl.composite.nodePtr = currentNode; - }else{ + } else { + free(result); return NULL; } return result; } -int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode, size_t expectedChildCount){ +int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode, [[maybe_unused]] size_t expectedChildCount) { ParentExpression->impl.operation.kind = Arithmetic; ParentExpression->impl.operation.nodePtr = currentNode; - if (expectedChildCount > currentNode->child_count){ - PANIC("Operation has to many children"); - } - for (size_t i = 0; i < currentNode->child_count; i++){ + + assert(expectedChildCount > currentNode->child_count); + + for (size_t i = 0; i < currentNode->child_count; i++) { Expression* expression = createExpression(currentNode->children[i]); - if(NULL == expression){ - return 1; - } - g_array_append_val(ParentExpression->impl.operation.operands , expression); + if(NULL == expression) { + return SEMANTIC_OK; + } + + g_array_append_val(ParentExpression->impl.operation.operands, expression); } - switch (currentNode->kind){ + switch (currentNode->kind) { case AST_Add: ParentExpression->impl.operation.impl.arithmetic = Add; + break; case AST_Sub: ParentExpression->impl.operation.impl.arithmetic = Sub; + break; case AST_Mul: ParentExpression->impl.operation.impl.arithmetic = Mul; + break; case AST_Div: ParentExpression->impl.operation.impl.arithmetic = Div; + break; case AST_Negate: ParentExpression->impl.operation.impl.arithmetic = Negate; + break; default: PANIC("Current node is not an arithmetic operater"); - break; + break; } - - if(ParentExpression->impl.operation.impl.arithmetic == Negate){ - Type* result = malloc(sizeof(Type)); - result = ((Expression**) ParentExpression->impl.operation.operands->data)[0]->result; + if (ParentExpression->impl.operation.impl.arithmetic == Negate) { + Type* result = ((Expression**) ParentExpression->impl.operation.operands->data)[0]->result; result->nodePtr = currentNode; - if (result->kind == TypeKindReference || result->kind == TypeKindBox){ - return 1; - }else if(result->kind == TypeKindComposite){ + + 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{ + } else { Type* LeftOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[0]->result; Type* RightOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[1]->result; @@ -435,41 +524,44 @@ int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode, ParentExpression->result = createTypeFromOperands(LeftOperandType, RightOperandType, currentNode); } - if(ParentExpression->result == NULL){ - return 1; + if (ParentExpression->result == NULL) { + return SEMANTIC_ERROR; } - - return 0; + return SEMANTIC_OK; } -int createRelationalOperation(Expression* ParentExpression,AST_NODE_PTR currentNode){ - //fill kind and Nodeptr +int createRelationalOperation(Expression* ParentExpression, AST_NODE_PTR currentNode) { + // fill kind and Nodeptr ParentExpression->impl.operation.kind = Relational; ParentExpression->impl.operation.nodePtr = currentNode; - //fill Operands - for (size_t i = 0; i < currentNode->child_count; i++){ + // fill Operands + for (size_t i = 0; i < currentNode->child_count; i++) { Expression* expression = createExpression(currentNode->children[i]); if(NULL == expression){ - return 1; + return SEMANTIC_ERROR; } - g_array_append_val(ParentExpression->impl.operation.operands , expression); + g_array_append_val(ParentExpression->impl.operation.operands, expression); } - //fill impl - switch (currentNode->kind){ - case AST_Eq: - ParentExpression->impl.operation.impl.relational = Equal; - case AST_Less: - ParentExpression->impl.operation.impl.relational = Greater; - case AST_Greater: - ParentExpression->impl.operation.impl.relational= Less; - default: - PANIC("Current node is not an relational operater"); - break; + // fill impl + switch (currentNode->kind) { + case AST_Eq: + ParentExpression->impl.operation.impl.relational = Equal; + break; + case AST_Less: + ParentExpression->impl.operation.impl.relational = Greater; + break; + case AST_Greater: + ParentExpression->impl.operation.impl.relational= Less; + break; + default: + PANIC("Current node is not an relational operater"); + break; } - Type * result = malloc(sizeof(Type)); + + Type* result = malloc(sizeof(Type)); result->impl.primitive = Int; result->kind = TypeKindPrimitive; result->nodePtr = currentNode; @@ -478,66 +570,76 @@ int createRelationalOperation(Expression* ParentExpression,AST_NODE_PTR currentN return 0; } - -int createBoolOperation(Expression *ParentExpression, AST_NODE_PTR currentNode){ - //fill kind and Nodeptr +int createBoolOperation(Expression *ParentExpression, AST_NODE_PTR currentNode) { + // fill kind and Nodeptr ParentExpression->impl.operation.kind = Boolean; ParentExpression->impl.operation.nodePtr = currentNode; - //fill Operands + // fill Operands for (size_t i = 0; i < currentNode->child_count; i++){ Expression* expression = createExpression(currentNode->children[i]); - if(NULL == expression){ - return 1; + 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){ - case AST_BoolAnd: - ParentExpression->impl.operation.impl.boolean = BooleanAnd; - case AST_BoolOr: - ParentExpression->impl.operation.impl.boolean = BooleanOr; - case AST_BoolXor: - ParentExpression->impl.operation.impl.boolean = BooleanXor; - default: - PANIC("Current node is not an boolean operater"); - break; + switch (currentNode->kind) { + case AST_BoolAnd: + ParentExpression->impl.operation.impl.boolean = BooleanAnd; + break; + case AST_BoolOr: + ParentExpression->impl.operation.impl.boolean = BooleanOr; + break; + case AST_BoolXor: + ParentExpression->impl.operation.impl.boolean = BooleanXor; + break; + default: + PANIC("Current node is not an boolean operater"); + break; } + Expression* lhs = ((Expression**) ParentExpression->impl.operation.operands->data)[0]; + Expression* rhs = ((Expression**) ParentExpression->impl.operation.operands->data)[1]; - Type* LeftOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[0]->result; - Type* RightOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[1]->result; + Type* LeftOperandType = lhs->result; + Type* RightOperandType = rhs->result; - //should not be a box or a reference - if(LeftOperandType->kind != TypeKindPrimitive && LeftOperandType->kind != TypeKindComposite){ - return 1; + // should not be a box or a reference + 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){ - return 1; + if(RightOperandType->kind != TypeKindPrimitive && RightOperandType->kind != TypeKindComposite) { + print_diagnostic(current_file, &rhs->nodePtr->location, Error, "invalid type for boolean operation"); + return SEMANTIC_ERROR; } - //should not be a float - if(LeftOperandType->kind == TypeKindComposite){ - if(LeftOperandType->impl.composite.primitive == Float){ - return 1; + // should not be a float + if (LeftOperandType->kind == TypeKindComposite) { + if (LeftOperandType->impl.composite.primitive == Float) { + print_diagnostic(current_file, &lhs->nodePtr->location, Error, "operand must not be a float"); + return SEMANTIC_ERROR; } - }else if(LeftOperandType->kind == TypeKindPrimitive){ - if(LeftOperandType->impl.primitive == Float){ - return 1; + } else if (LeftOperandType->kind == TypeKindPrimitive) { + if (LeftOperandType->impl.primitive == Float) { + print_diagnostic(current_file, &lhs->nodePtr->location, Error, "operand must not be a float"); + return SEMANTIC_ERROR; } - }else if(RightOperandType->kind == TypeKindComposite){ - if(RightOperandType->impl.composite.primitive == Float){ - return 1; + } else if (RightOperandType->kind == TypeKindComposite) { + if (RightOperandType->impl.composite.primitive == Float) { + print_diagnostic(current_file, &rhs->nodePtr->location, Error, "operand must not be a float"); + return SEMANTIC_ERROR; } - }else if(RightOperandType->kind == TypeKindPrimitive){ - if(RightOperandType->impl.primitive == Float){ - return 1; + } else if (RightOperandType->kind == TypeKindPrimitive) { + if (RightOperandType->impl.primitive == Float) { + print_diagnostic(current_file, &rhs->nodePtr->location, Error, "operand must not be a float"); + return SEMANTIC_ERROR; } } - ParentExpression->result = createTypeFromOperands(LeftOperandType, RightOperandType, currentNode); - return 0; + + return SEMANTIC_OK; } int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNode){ @@ -590,11 +692,11 @@ bool isScaleEqual(double leftScale, double rightScale){ } int createBitOperation(Expression* ParentExpression, AST_NODE_PTR currentNode){ - //fill kind and Nodeptr + // fill kind and Nodeptr ParentExpression->impl.operation.kind = Boolean; ParentExpression->impl.operation.nodePtr = currentNode; - //fill Operands + // fill Operands for (size_t i = 0; i < currentNode->child_count; i++){ Expression* expression = createExpression(currentNode->children[i]); if(NULL == expression){ @@ -712,6 +814,78 @@ int createBitNotOperation(Expression* ParentExpression, AST_NODE_PTR currentNode 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 = ((const char **) names)[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); + + 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; + } + g_array_append_vals(members,(BoxMember *) otherMember->data, otherMember->len); + return members; + } + return NULL; +} + +int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) { + + const char* boxname = currentNode->children[0]->value; + Variable* boxVariable = NULL; + int status = getVariableFromScope(boxname, &boxVariable); + + if(status == SEMANTIC_ERROR){ + return SEMANTIC_ERROR; + } + Type* boxType; + + if(boxVariable->kind == VariableKindDeclaration){ + + boxType = boxVariable->impl.declaration.type; + } else if (boxVariable->kind == VariableKindDefinition){ + boxType = boxVariable->impl.definiton.declaration.type; + } else{ + return SEMANTIC_ERROR; + } + if (boxType->kind != TypeKindBox){ + return SEMANTIC_ERROR; + } + //filling boxAccess variable + ParentExpression->impl.variable->kind = VariableKindBoxMember; + ParentExpression->impl.variable->nodePtr = currentNode; + ParentExpression->impl.variable->name = NULL; + ParentExpression->impl.variable->impl.member.nodePtr = currentNode; + + //filling boxacces.variable + ParentExpression->impl.variable->impl.member.variable = boxVariable; + + //first one is the box itself + GArray* names = malloc(sizeof(GArray)); + for (size_t i = 1; i < currentNode->child_count; i++){ + g_array_append_val(names, currentNode->children[1]->value); + } + + GArray * boxMember = getBoxMember(boxType, names); + ParentExpression->impl.variable->impl.member.member = boxMember; + ParentExpression->result = ((BoxMember *)boxMember->data)[boxMember->len].type; + return SEMANTIC_OK; + +} Expression *createExpression(AST_NODE_PTR currentNode){ Expression *expression = malloc(sizeof(Expression)); @@ -731,8 +905,8 @@ Expression *createExpression(AST_NODE_PTR currentNode){ break; case AST_Ident: expression->kind = ExpressionKindVariable; - expression->impl.variable = getVariableFromScope(currentNode->value); - if(NULL == expression->impl.variable){ + int status = getVariableFromScope(currentNode->value, &expression->impl.variable ); + if(status == SEMANTIC_ERROR){ DEBUG("Identifier is not in current scope"); return NULL; } @@ -801,6 +975,8 @@ Expression *createExpression(AST_NODE_PTR currentNode){ break; case AST_IdentList: + expression->kind = ExpressionKindVariable; + //Box Accsess case AST_List: // Box Self Access @@ -816,6 +992,12 @@ Expression *createExpression(AST_NODE_PTR currentNode){ return expression; } + + + + + + Module *create_set(AST_NODE_PTR currentNode){ DEBUG("create root Module"); //create tables for types @@ -852,17 +1034,24 @@ Module *create_set(AST_NODE_PTR currentNode){ DEBUG("created Child: %i" ,currentNode->children[i]->kind); switch(currentNode->children[i]->kind){ - case AST_Decl: - if (1 == fillTablesWithVars(variables,globalscope,createDecl(currentNode->children[i]) ,currentNode->children[i]->children[currentNode->children[i]->child_count -1]->child_count)){ - //TODO behandlung, wenn var schon existiert - DEBUG("var already exists"); + case AST_Decl: { + GArray* vars; + int status = createDecl(currentNode->children[i], &vars); + + if (fillTablesWithVars(variables, globalscope, vars) == SEMANTIC_ERROR) { + 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; - case AST_Def: + } + case AST_Def: { + GArray* vars; + int status = createDef(currentNode->children[i], &vars); DEBUG("created Definition successfully"); break; + } case AST_Box: case AST_Fun: case AST_Import: diff --git a/src/set/set.h b/src/set/set.h index 1ec9e85..e7a5048 100644 --- a/src/set/set.h +++ b/src/set/set.h @@ -2,10 +2,11 @@ #define _SET_H_ #include +#include #define SEMANTIC_OK 0 #define SEMANTIC_ERROR 1 -void create_set(AST_NODE_PTR rootNodePtr ); +Module * create_set(AST_NODE_PTR rootNodePtr ); #endif diff --git a/src/set/types.h b/src/set/types.h index 08e8418..2e5e1ff 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -79,7 +79,7 @@ typedef struct BoxMember_t { } BoxMember; /** - * @brief Essentially a glorified struct + * @brief Essentially a g lorified struct * */ typedef struct BoxType_t { From d0b1d367d52d3c52b173c957a11c84d38fd0a2db Mon Sep 17 00:00:00 2001 From: Filleo Date: Wed, 5 Jun 2024 00:31:40 +0200 Subject: [PATCH 17/29] major set building Co-authored-by: SirTalksalot75 Co-authored-by: servostar --- src/io/files.c | 16 +- src/io/files.h | 2 +- src/set/set.c | 552 ++++++++++++++++++++++++++++++++++++++---------- src/set/types.h | 24 ++- 4 files changed, 471 insertions(+), 123 deletions(-) diff --git a/src/io/files.c b/src/io/files.c index 5f3ad02..d091d06 100644 --- a/src/io/files.c +++ b/src/io/files.c @@ -3,6 +3,8 @@ // #include +#include +#include #include #include #include @@ -79,7 +81,7 @@ static void custom_fgets(char *buffer, size_t n, FILE *stream) { } } -void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, const char *message) { +void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, const char *message, ...) { assert(file->handle != NULL); assert(location != NULL); assert(message != NULL); @@ -117,8 +119,16 @@ void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, c const char *absolute_path = get_absolute_path(file->path); - printf("%s%s:%ld:%s %s%s:%s %s\n", BOLD, absolute_path, location->line_start, RESET, accent_color, kind_text, RESET, - message); + printf("%s%s:%ld:%s %s%s:%s ", BOLD, absolute_path, location->line_start, RESET, accent_color, kind_text, RESET); + + va_list args; + va_start(args, format); + + vprintf(message, args); + + va_end(args); + + printf("\n"); free((void *) absolute_path); diff --git a/src/io/files.h b/src/io/files.h index 61c7ebb..1e436b5 100644 --- a/src/io/files.h +++ b/src/io/files.h @@ -92,7 +92,7 @@ TokenLocation empty_location(void); * @param message */ [[gnu::nonnull(1), gnu::nonnull(2)]] -void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, const char *message); +void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, const char *message, ...); [[gnu::nonnull(2)]] /** diff --git a/src/set/set.c b/src/set/set.c index f63aa83..3ac0add 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -1,5 +1,5 @@ -#include "io/files.h" -#include "yacc/parser.tab.h" +#include +#include #include #include #include @@ -11,9 +11,17 @@ #include #include -GHashTable *declaredComposites = NULL;//pointer to composites with names, -GHashTable *declaredBoxes = NULL;//pointer to typeboxes -GArray *Scope = NULL;//list of hashtables. last Hashtable is current depth of program. hashtable key: ident, value: Variable* to var +// +// .--. +// | '----------. . +// > | ~ ~ ~ ~ ~ .o O +// | .----------' o +// `--' +// + +static GHashTable *declaredComposites = NULL;//pointer to composites with names +static GHashTable *declaredBoxes = NULL;//pointer to typeboxes +static GArray *Scope = NULL;//list of hashtables. last Hashtable is current depth of program. hashtable key: ident, value: Variable* to var const Type ShortShortUnsingedIntType = { .kind = TypeKindComposite, @@ -264,9 +272,15 @@ int get_type_impl(AST_NODE_PTR currentNode, Type** type) { } StorageQualifier Qualifier_from_string(const char *str) { - if (!strncmp(str, "local", 5)) return Local; - if (!strncmp(str, "static", 6)) return Static; - if (!strncmp(str, "global", 6)) return Global; + assert(str != NULL); + + if (strcmp(str, "local") == 0) + return Local; + if (strcmp(str, "static") == 0) + return Static; + if (strcmp(str, "global") == 0) + return Global; + PANIC("Provided string is not a storagequalifier: %s", str); } @@ -316,42 +330,99 @@ int createDecl(AST_NODE_PTR currentNode, GArray** variables) { return status; } +Expression* createExpression(AST_NODE_PTR currentNode); + int createDef(AST_NODE_PTR currentNode, GArray** variables) { assert(variables != NULL); assert(currentNode != NULL); + assert(currentNode->kind == AST_Def); DEBUG("create definition"); - AST_NODE_PTR declaration = currentNode->children[currentNode->child_count - 1]; + AST_NODE_PTR declaration = currentNode->children[0]; + AST_NODE_PTR expression = currentNode->children[1]; + AST_NODE_PTR ident_list = currentNode->children[0]->children[currentNode->child_count - 1]; - * variables = g_array_new(FALSE, FALSE, sizeof(Variable*)); - + *variables = g_array_new(FALSE, FALSE, sizeof(Variable*)); + + VariableDeclaration decl; VariableDefiniton def; def.nodePtr = currentNode; - Variable* variable = malloc(sizeof(Variable)); - variable->kind = VariableKindDefinition; - variable->nodePtr = currentNode; - variable->name = declaration->children[1]->value; - variable->impl.definiton= def; - g_array_append_val(*variables, variable); - int status = SEMANTIC_OK; - DEBUG("Child Count: %i", currentNode->child_count); - for (size_t i = 0; i < currentNode->child_count; i++){ - - switch(currentNode->children[i]->kind) { - case AST_Decl: + DEBUG("Child Count: %i", declaration->child_count); + for (size_t i = 0; i < declaration->children[i]->child_count; i++){ + switch(declaration->children[i]->kind) { + case AST_Storage: + DEBUG("fill Qualifier"); + decl.qualifier = Qualifier_from_string(currentNode->children[i]->value); + break; + case AST_Type: + DEBUG("fill Type"); + status = get_type_impl(currentNode->children[i], &decl.type); + break; + case AST_IdentList: break; default: PANIC("invalid node type: %ld", currentNode->children[i]->kind); break; - } + } } + + def.declaration = decl; + 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 = malloc(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); + } + 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) { assert(name != NULL); assert(variable != NULL); @@ -413,17 +484,23 @@ TypeValue createTypeValue(AST_NODE_PTR currentNode){ return value; } +static inline void* clone(int size, void* ptr) { + char* data = malloc(size); + memcpy(data, ptr, size); + return data; +} + +#define CLONE(x) clone(sizeof(x), (void*)&(x)) + TypeValue createString(AST_NODE_PTR currentNode) { TypeValue value; - Type *type = (Type*) &StringLiteralType; + Type *type = CLONE(StringLiteralType); value.type = type; value.nodePtr = currentNode; value.value = currentNode->value; return value; } -Expression* createExpression(AST_NODE_PTR currentNode); - Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_NODE_PTR currentNode) { Type *result = malloc(sizeof(Type)); result->nodePtr = currentNode; @@ -642,7 +719,7 @@ int createBoolOperation(Expression *ParentExpression, AST_NODE_PTR currentNode) return SEMANTIC_OK; } -int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNode){ +int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNode) { //fill kind and Nodeptr ParentExpression->impl.operation.kind = Boolean; ParentExpression->impl.operation.nodePtr = currentNode; @@ -650,7 +727,7 @@ int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNod //fill Operand Expression* expression = createExpression(currentNode->children[0]); if(NULL == expression){ - return 1; + return SEMANTIC_ERROR; } g_array_append_val(ParentExpression->impl.operation.operands , expression); @@ -660,109 +737,152 @@ int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNod Type* result = malloc(sizeof(Type)); result->nodePtr = currentNode; - if (Operand->kind == TypeKindBox || Operand->kind == TypeKindReference){ - return 1; + + if (Operand->kind == TypeKindBox || Operand->kind == TypeKindReference) { + 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){ - return 1; + + 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"); + return SEMANTIC_ERROR; } result->kind = Operand->kind; result->impl = Operand->impl; - }else if(Operand->kind == TypeKindComposite){ - if(Operand->impl.composite.primitive == Float){ - return 1; + + } 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"); + return SEMANTIC_ERROR; } result->kind = Operand->kind; result->impl = Operand->impl; } ParentExpression->result = result; - return 0; + return SEMANTIC_OK; } -bool isScaleEqual(double leftScale, double rightScale){ - int leftIntScale =(int)(leftScale *4); - int rightIntScale =(int)(rightScale *4); +bool isScaleEqual(double leftScale, double rightScale) { + int leftIntScale = (int) (leftScale * BASE_BYTES); + int rightIntScale = (int) (rightScale * BASE_BYTES); - if (leftIntScale == rightIntScale){ - return TRUE; - } - return FALSE; + 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++){ + for (size_t i = 0; i < currentNode->child_count; i++) { Expression* expression = createExpression(currentNode->children[i]); - if(NULL == expression){ - return 1; + + if(NULL == expression) { + return SEMANTIC_ERROR; } + g_array_append_val(ParentExpression->impl.operation.operands , expression); } - - switch (currentNode->kind){ - case AST_BitAnd: - ParentExpression->impl.operation.impl.bitwise = BitwiseAnd; - case AST_BitOr: - ParentExpression->impl.operation.impl.bitwise = BitwiseOr; - case AST_BitXor: - ParentExpression->impl.operation.impl.bitwise = BitwiseXor; - default: - PANIC("Current node is not an bitwise operater"); - break; + switch (currentNode->kind) { + case AST_BitAnd: + ParentExpression->impl.operation.impl.bitwise = BitwiseAnd; + break; + case AST_BitOr: + ParentExpression->impl.operation.impl.bitwise = BitwiseOr; + break; + case AST_BitXor: + ParentExpression->impl.operation.impl.bitwise = BitwiseXor; + break; + default: + PANIC("Current node is not an bitwise operater"); + break; } - Type *result = malloc(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 = ((Expression**) ParentExpression->impl.operation.operands->data)[0]->result; - Type* RightOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[1]->result; + Type* LeftOperandType = lhs->result; + Type* RightOperandType = rhs->result; //should not be a box or a reference - if(LeftOperandType->kind != TypeKindPrimitive && LeftOperandType->kind != TypeKindComposite){ - return 1; + if (LeftOperandType->kind != TypeKindPrimitive && LeftOperandType->kind != TypeKindComposite) { + print_diagnostic(current_file, &lhs->nodePtr->location, Error, "Must be a type variant of int"); + return SEMANTIC_ERROR; } - if(RightOperandType->kind != TypeKindPrimitive && RightOperandType->kind != TypeKindComposite){ - return 1; + + if (RightOperandType->kind != TypeKindPrimitive && RightOperandType->kind != TypeKindComposite) { + print_diagnostic(current_file, &rhs->nodePtr->location, Error, "Must be a type variant of int"); + return SEMANTIC_ERROR; } - if(LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindPrimitive){ - if(LeftOperandType->impl.primitive == Float || RightOperandType->impl.primitive == Float){ - return 1; + + if (LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindPrimitive) { + + if (LeftOperandType->impl.primitive == Float) { + print_diagnostic(current_file, &lhs->nodePtr->location, Error, "Must be a type variant of int"); + return SEMANTIC_ERROR; } + + if (RightOperandType->impl.primitive == Float) { + print_diagnostic(current_file, &rhs->nodePtr->location, Error, "Must be a type variant of int"); + return SEMANTIC_ERROR; + } + result->kind = TypeKindPrimitive; result->impl.primitive = Int; - }else if(LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindComposite){ - if(LeftOperandType->impl.primitive == Float || RightOperandType->impl.composite.primitive == Float){ - return 1; + + } else if (LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindComposite) { + + if (LeftOperandType->impl.primitive == Float) { + print_diagnostic(current_file, &lhs->nodePtr->location, Error, "Must be a type variant of int"); + return SEMANTIC_ERROR; } - if((int)RightOperandType->impl.composite.scale != 1){ - return 1; + + if (RightOperandType->impl.composite.primitive == Float) { + print_diagnostic(current_file, &rhs->nodePtr->location, Error, "Must be a type variant of int"); + return SEMANTIC_ERROR; } + result->kind = TypeKindPrimitive; result->impl.primitive = Int; - }else if(LeftOperandType->kind == TypeKindComposite && RightOperandType->kind == TypeKindPrimitive){ - if(LeftOperandType->impl.composite.primitive == Float || RightOperandType->impl.primitive == Float){ - return 1; + + }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"); + return SEMANTIC_ERROR; } - if((int)LeftOperandType->impl.composite.scale != 1){ - return 1; + + if (RightOperandType->impl.primitive == Float) { + print_diagnostic(current_file, &rhs->nodePtr->location, Error, "Must be a type variant of int"); + return SEMANTIC_ERROR; } + result->kind = TypeKindPrimitive; result->impl.primitive = Int; - }else{ - if(LeftOperandType->impl.composite.primitive == Float || RightOperandType->impl.composite.primitive == Float){ - return 1; + } else { + + if (RightOperandType->impl.composite.primitive == Float) { + print_diagnostic(current_file, &rhs->nodePtr->location, Error, "Must be a type variant of int"); + return SEMANTIC_ERROR; } - if(!isScaleEqual(LeftOperandType->impl.composite.scale, RightOperandType->impl.composite.scale)){ - return 1; + + if (LeftOperandType->impl.composite.primitive == Float) { + print_diagnostic(current_file, &lhs->nodePtr->location, Error, "Must be a type variant of int"); + return SEMANTIC_ERROR; } + + 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; + } + result->kind = TypeKindComposite; result->impl.composite.nodePtr = currentNode; result->impl.composite.scale = LeftOperandType->impl.composite.scale; @@ -773,7 +893,7 @@ 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; @@ -781,28 +901,33 @@ int createBitNotOperation(Expression* ParentExpression, AST_NODE_PTR currentNode //fill Operand Expression* expression = createExpression(currentNode->children[0]); if(NULL == expression){ - return 1; + return SEMANTIC_ERROR; } 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* Operand = ((Expression**) ParentExpression->impl.operation.operands)[0]->result; Type* result = malloc(sizeof(Type)); result->nodePtr = currentNode; - - if (Operand->kind == TypeKindPrimitive){ - if(Operand->impl.primitive == Float){ + 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"); return SEMANTIC_ERROR; } + result->kind = TypeKindPrimitive; result->impl.primitive = Int; - }else if(Operand->kind == TypeKindComposite){ - if (Operand->impl.composite.primitive == Float){ + }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"); return SEMANTIC_ERROR; } + result->kind = TypeKindComposite; result->impl.composite.nodePtr = currentNode; result->impl.composite.primitive = Int; @@ -811,17 +936,17 @@ int createBitNotOperation(Expression* ParentExpression, AST_NODE_PTR currentNode } ParentExpression->result = result; + return SEMANTIC_OK; } -GArray* getBoxMember(Type* currentBoxType, GArray *names){ - +GArray* getBoxMember(Type* currentBoxType, GArray *names) { GArray *members = g_array_new(FALSE, FALSE, sizeof(BoxMember)); GHashTable* memberList = currentBoxType->impl.box.member; const char* currentName = ((const char **) names)[0]; - if(!g_hash_table_contains(memberList, currentName)){ + if(!g_hash_table_contains(memberList, currentName)) { // TODO: free members return NULL; } @@ -829,7 +954,7 @@ GArray* getBoxMember(Type* currentBoxType, GArray *names){ g_array_append_val(members, currentMember); g_array_remove_index(names,0); - if (names->len == 0){ + if (names->len == 0) { return members; } if (currentMember->type->kind == TypeKindBox){ @@ -850,6 +975,7 @@ int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) { 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"); return SEMANTIC_ERROR; } Type* boxType; @@ -862,10 +988,11 @@ int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) { } else{ return SEMANTIC_ERROR; } - if (boxType->kind != TypeKindBox){ + if (boxType->kind != TypeKindBox) { return SEMANTIC_ERROR; } - //filling boxAccess variable + + // filling boxAccess variable ParentExpression->impl.variable->kind = VariableKindBoxMember; ParentExpression->impl.variable->nodePtr = currentNode; ParentExpression->impl.variable->name = NULL; @@ -876,8 +1003,16 @@ int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) { //first one is the box itself GArray* names = malloc(sizeof(GArray)); - for (size_t i = 1; i < currentNode->child_count; i++){ - g_array_append_val(names, currentNode->children[1]->value); + 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++){ + g_array_append_val(names, currentNode->children[1]->children[i]->value); + } + }else{ + PANIC("current Node is not an Access"); } GArray * boxMember = getBoxMember(boxType, names); @@ -887,6 +1022,50 @@ int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) { } +int createTypeCast(Expression* ParentExpression, AST_NODE_PTR currentNode){ + ParentExpression->impl.typecast.nodePtr = currentNode; + + ParentExpression->impl.typecast.operand = createExpression(currentNode->children[0]); + if (ParentExpression->impl.typecast.operand == NULL){ + return SEMANTIC_ERROR; + } + + Type* target = malloc(sizeof(Type)); + int status = get_type_impl(currentNode->children[1], &target); + 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; +} + +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){ + return SEMANTIC_ERROR; + } + + Type* target = malloc(sizeof(Type)); + int status = get_type_impl(currentNode->children[1], &target); + 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; + +} + + + Expression *createExpression(AST_NODE_PTR currentNode){ Expression *expression = malloc(sizeof(Expression)); expression->nodePtr = currentNode; @@ -908,6 +1087,7 @@ Expression *createExpression(AST_NODE_PTR currentNode){ 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) { @@ -975,28 +1155,178 @@ Expression *createExpression(AST_NODE_PTR currentNode){ break; case AST_IdentList: - expression->kind = ExpressionKindVariable; - - //Box Accsess case AST_List: - // Box Self Access - case AST_Typekind: + 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); + PANIC("Node is not an expression but from kind: %i", currentNode->kind); break; } return expression; } + + + int createAssign(Statement* ParentStatement, AST_NODE_PTR currentNode){ + Assignment assign; + assign.nodePtr = currentNode; + const char* varName = currentNode->children[0]->value; + + int status = getVariableFromScope(varName, &assign.variable); + if(status){ + return SEMANTIC_ERROR; + } + + assign.value = createExpression(currentNode->children[1]); + if(assign.value == NULL){ + return SEMANTIC_ERROR; + } + + ParentStatement->impl.assignment = assign; + return SEMANTIC_ERROR; + } +Statement *createStatement(AST_NODE_PTR currentNode); + +int createWhile(Statement * ParentStatement, AST_NODE_PTR currentNode){ + assert(ParentExpression == NULL); + assert(currentNode == NULL); + assert(currentNode->kind == AST_While); + + While whileStruct; + whileStruct.nodePtr = currentNode; + whileStruct.conditon = createExpression(currentNode->children[0]); + if(NULL == whileStruct.conditon){ + return SEMANTIC_ERROR; + } + AST_NODE_PTR statementList = currentNode->children[1]; + whileStruct.block.nodePtr = statementList; + + for(size_t i = 0; i < statementList->child_count; i++){ + Statement* statement = createStatement(statementList->children[i]); + if (NULL == statement) { + return SEMANTIC_ERROR; + } + g_array_append_val(whileStruct.block.statemnts, statement); + } + ParentStatement->impl.whileLoop = whileStruct; + + return SEMANTIC_OK; +} + +int fillBlock(Block * block,AST_NODE_PTR currentNode){ + block->nodePtr = currentNode; + + for(size_t i = 0; i < currentNode->child_count; i++){ + Statement* statement = createStatement(currentNode->children[i]); + if(statement == NULL){ + return SEMANTIC_ERROR; + } + g_array_append_val(block->statemnts,statement); + } + return SEMANTIC_OK; +} + +int createIf(Branch* Parentbranch, AST_NODE_PTR currentNode){ + If ifbranch; + ifbranch.nodePtr = currentNode; + + Expression* expression = createExpression(currentNode->children[0]); + if (NULL == expression) { + return SEMANTIC_ERROR; + } + ifbranch.conditon = expression; + int status = fillBlock(&ifbranch.block, currentNode->children[1]); + +} + +int createBranch(Statement* ParentStatement,AST_NODE_PTR currentNode){ + Branch Branch; + + for (size_t i = 0; i < currentNode->child_count; i++ ){ + switch (currentNode->children[i]->kind){ + case AST_If: + createIf(&Branch, currentNode->children[i]); + case AST_IfElse: + case AST_Else: + default: + PANIC("current node is not part of a Branch") + break; + + + } + } + +} + +Statement *createStatement(AST_NODE_PTR currentNode){ + Statement* statement = malloc(sizeof(Statement)); + statement->nodePtr = currentNode; + + switch(currentNode->kind){ + case AST_Decl: + statement->kind = StatementKindDeclaration; + + case AST_Def: + statement->kind = StatementKindDefinition; + case AST_While: + statement->kind = StatementKindWhile; + if(createWhile(statement, currentNode)){ + return NULL; + } + case AST_Stmt: + statement->kind = StatementKindBranch; + //ifbrnches: + + case AST_Assign: + statement->kind = StatementKindAssignment; + if(createAssign(statement, currentNode)){ + return NULL; + } + case AST_Call: + //both funcall and boxfuncall + default: + break; + } + +} +Function *createFunction(AST_NODE_PTR currentNode){ + +} +BoxType *createBox(AST_NODE_PTR currentNode){ + BoxType * box = malloc(sizeof(BoxType)); + + box->nodePtr = currentNode; + // + //box + // name + // list + // decl + // def // change BoxMember to have an + // fun //create static function + // a.b(dsadsadas) + + +} Module *create_set(AST_NODE_PTR currentNode){ DEBUG("create root Module"); @@ -1053,7 +1383,9 @@ Module *create_set(AST_NODE_PTR currentNode){ break; } case AST_Box: + case AST_Fun: + case AST_Typedef: case AST_Import: DEBUG("create Import"); g_array_append_val(imports, currentNode->children[i]->value); diff --git a/src/set/types.h b/src/set/types.h index 2e5e1ff..ae157bc 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -5,6 +5,9 @@ #include #include +// with of primitive types (int/float) in bytes +#define BASE_BYTES 4 + /** * @brief Primitive types form the basis of all other types. * @@ -36,7 +39,7 @@ typedef enum Sign_t { typedef double Scale; /** - * @brief A composite type is an extended definiton of a primitive type. + * @brief A composite type is an extended definition of a primitive type. * */ typedef struct CompositeType_t { @@ -124,7 +127,7 @@ typedef struct Typedefine_t { /** - * @brief Reprents the value of type. Can be used to definitons, initialization and for expressions contants. + * @brief Reprents the value of type. Can be used to definitions, initialization and for expressions contants. * */ typedef struct TypeValue_t { @@ -183,7 +186,7 @@ typedef enum ParameterKind_t { } ParameterKind; /** - * @brief A parameter can either be a declaration or a definiton + * @brief A parameter can either be a declaration or a definition * */ typedef struct Parameter_t { @@ -245,7 +248,7 @@ typedef struct VariableDeclaration_t { } VariableDeclaration; /** - * @brief Definiton of a variable + * @brief Definition of a variable * * @attention NOTE: The types of the initializer and the declaration must be equal * @@ -455,7 +458,7 @@ typedef struct Block_t { // '------------------------------------------------' typedef struct While_t { - Expression conditon; + Expression *conditon; Block block; AST_NODE_PTR nodePtr; } While; @@ -465,13 +468,13 @@ typedef struct While_t { // '------------------------------------------------' typedef struct If_t { - Expression conditon; + Expression *conditon; Block block; AST_NODE_PTR nodePtr; } If; typedef struct ElseIf_t { - Expression conditon; + Expression *conditon; Block block; AST_NODE_PTR nodePtr; } ElseIf; @@ -495,7 +498,7 @@ typedef struct Branch_t { typedef struct Assignment_t { Variable* variable; - Expression value; + Expression* value; AST_NODE_PTR nodePtr; } Assignment; @@ -504,7 +507,9 @@ typedef enum StatementKind_t { StatementKindFunctionBoxCall, StatementKindWhile, StatementKindBranch, - StatementKindAssignment + StatementKindAssignment, + StatementKindDeclaration, + StatementKindDefinition } StatementKind; typedef struct Statement_t { @@ -515,6 +520,7 @@ typedef struct Statement_t { While whileLoop; Branch branch; Assignment assignment; + Variable variable; } impl; AST_NODE_PTR nodePtr; } Statement; From 80c73e8b81c3c7bfcd0f44cd58cb6a8e9b27e993 Mon Sep 17 00:00:00 2001 From: Filleo Date: Wed, 5 Jun 2024 12:53:50 +0200 Subject: [PATCH 18/29] finished if branch --- src/set/set.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/set/set.c b/src/set/set.c index 3ac0add..8ed9f80 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -18,7 +18,7 @@ // | .----------' o // `--' // - +extern ModuleFile * current_file; static GHashTable *declaredComposites = NULL;//pointer to composites with names static GHashTable *declaredBoxes = NULL;//pointer to typeboxes static GArray *Scope = NULL;//list of hashtables. last Hashtable is current depth of program. hashtable key: ident, value: Variable* to var @@ -1251,6 +1251,15 @@ int createIf(Branch* Parentbranch, AST_NODE_PTR currentNode){ ifbranch.conditon = expression; int status = fillBlock(&ifbranch.block, currentNode->children[1]); + if(status){ + return SEMANTIC_ERROR; + } + Parentbranch->ifBranch = ifbranch; + return SEMANTIC_OK; +} + +int createElse(){ + } int createBranch(Statement* ParentStatement,AST_NODE_PTR currentNode){ @@ -1259,11 +1268,13 @@ int createBranch(Statement* ParentStatement,AST_NODE_PTR currentNode){ for (size_t i = 0; i < currentNode->child_count; i++ ){ switch (currentNode->children[i]->kind){ case AST_If: - createIf(&Branch, currentNode->children[i]); + if(createIf(&Branch, currentNode->children[i])){ + return SEMANTIC_ERROR; + } case AST_IfElse: case AST_Else: default: - PANIC("current node is not part of a Branch") + PANIC("current node is not part of a Branch"); break; From b8660c1595cc3c7d80def9daea181a1c3e67aec0 Mon Sep 17 00:00:00 2001 From: Filleo Date: Wed, 5 Jun 2024 21:16:52 +0200 Subject: [PATCH 19/29] major set build Co-authored-by: SirTalksalot75 --- src/set/set.c | 529 +++++++++++++++++++++++++++++++++++++++++------- src/set/types.h | 20 +- 2 files changed, 468 insertions(+), 81 deletions(-) diff --git a/src/set/set.c b/src/set/set.c index 8ed9f80..ac1af6a 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -11,13 +11,7 @@ #include #include -// -// .--. -// | '----------. . -// > | ~ ~ ~ ~ ~ .o O -// | .----------' o -// `--' -// + extern ModuleFile * current_file; static GHashTable *declaredComposites = NULL;//pointer to composites with names static GHashTable *declaredBoxes = NULL;//pointer to typeboxes @@ -283,6 +277,7 @@ 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) { DEBUG("create declaration"); @@ -325,6 +320,10 @@ int createDecl(AST_NODE_PTR currentNode, GArray** variables) { variable->impl.declaration = decl; g_array_append_val(*variables, variable); + int signal = addVarToScope(variable); + if (signal){ + return SEMANTIC_ERROR; + } } return status; @@ -386,6 +385,10 @@ int createDef(AST_NODE_PTR currentNode, GArray** variables) { variable->name = ident_list->children[i]->value; variable->impl.definiton = def; g_array_append_val(*variables, variable); + int signal = addVarToScope(variable); + if (signal){ + return SEMANTIC_ERROR; + } } return status; @@ -430,7 +433,9 @@ int getVariableFromScope(const char* name, Variable** variable) { // loop through all variable scope and find a variable for(size_t i = 0; i < Scope->len; i++) { - GHashTable* variable_table = ((GHashTable**) Scope->data)[i]; + + + GHashTable* variable_table = g_array_index(Scope,GHashTable* ,i ); if(g_hash_table_contains(variable_table, name)) { *variable = g_hash_table_lookup(variable_table, name); @@ -441,22 +446,33 @@ int getVariableFromScope(const char* name, Variable** variable) { return SEMANTIC_ERROR; } -int fillTablesWithVars(GHashTable *variableTable, GHashTable *currentScope , GArray* variables) { +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); + g_hash_table_insert(currentScope, (gpointer) variable->name, variable); + + return SEMANTIC_OK; +} + +int fillTablesWithVars(GHashTable *variableTable, GArray* variables) { DEBUG("filling vars in scope and table"); for(size_t i = 0; i < variables->len; i++) { - Variable* var = (Variable*) variables->data + i; + + + Variable* var = g_array_index(variables,Variable *,i); // this variable is discarded, only need status code - Variable* tmp = NULL; - if(getVariableFromScope(var->name, &tmp) == SEMANTIC_OK) { - INFO("this var already exist: ", 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(currentScope, (gpointer) var->name, var); - } + } return SEMANTIC_OK; } @@ -472,8 +488,12 @@ TypeValue createTypeValue(AST_NODE_PTR currentNode){ switch (currentNode->kind) { 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; @@ -945,7 +965,7 @@ GArray* getBoxMember(Type* currentBoxType, GArray *names) { GArray *members = g_array_new(FALSE, FALSE, sizeof(BoxMember)); GHashTable* memberList = currentBoxType->impl.box.member; - const char* currentName = ((const char **) names)[0]; + const char* currentName = g_array_index(names,const char *,0); if(!g_hash_table_contains(memberList, currentName)) { // TODO: free members return NULL; @@ -1017,7 +1037,7 @@ int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) { GArray * boxMember = getBoxMember(boxType, names); ParentExpression->impl.variable->impl.member.member = boxMember; - ParentExpression->result = ((BoxMember *)boxMember->data)[boxMember->len].type; + ParentExpression->result = g_array_index(boxMember,BoxMember,boxMember->len).type; return SEMANTIC_OK; } @@ -1199,10 +1219,30 @@ Expression *createExpression(AST_NODE_PTR currentNode){ ParentStatement->impl.assignment = assign; return SEMANTIC_ERROR; } -Statement *createStatement(AST_NODE_PTR currentNode); +int createStatement(Block * block, AST_NODE_PTR currentNode); + +int fillBlock(Block * block,AST_NODE_PTR currentNode){ + block->nodePtr = currentNode; + + GHashTable * lowerScope = g_hash_table_new(g_str_hash,g_str_equal); + g_array_append_val(Scope, lowerScope); + + + for(size_t i = 0; i < currentNode->child_count; i++){ + int signal = createStatement(block, currentNode->children[i]); + if(signal){ + return SEMANTIC_ERROR; + } + } + + g_hash_table_destroy(lowerScope); + g_array_remove_index(Scope, Scope->len-1); + + return SEMANTIC_OK; +} int createWhile(Statement * ParentStatement, AST_NODE_PTR currentNode){ - assert(ParentExpression == NULL); + assert(ParentStatement == NULL); assert(currentNode == NULL); assert(currentNode->kind == AST_While); @@ -1213,32 +1253,17 @@ int createWhile(Statement * ParentStatement, AST_NODE_PTR currentNode){ return SEMANTIC_ERROR; } AST_NODE_PTR statementList = currentNode->children[1]; - whileStruct.block.nodePtr = statementList; - - for(size_t i = 0; i < statementList->child_count; i++){ - Statement* statement = createStatement(statementList->children[i]); - if (NULL == statement) { - return SEMANTIC_ERROR; - } - g_array_append_val(whileStruct.block.statemnts, statement); + + int signal = fillBlock(&whileStruct.block,statementList); + if(signal){ + return SEMANTIC_ERROR; } ParentStatement->impl.whileLoop = whileStruct; return SEMANTIC_OK; } -int fillBlock(Block * block,AST_NODE_PTR currentNode){ - block->nodePtr = currentNode; - for(size_t i = 0; i < currentNode->child_count; i++){ - Statement* statement = createStatement(currentNode->children[i]); - if(statement == NULL){ - return SEMANTIC_ERROR; - } - g_array_append_val(block->statemnts,statement); - } - return SEMANTIC_OK; -} int createIf(Branch* Parentbranch, AST_NODE_PTR currentNode){ If ifbranch; @@ -1258,74 +1283,383 @@ int createIf(Branch* Parentbranch, AST_NODE_PTR currentNode){ return SEMANTIC_OK; } -int createElse(){ +int createElse(Branch* Parentbranch, AST_NODE_PTR currentNode){ + Else elseBranch; + elseBranch.nodePtr = currentNode; + int status = fillBlock(&elseBranch.block, currentNode->children[0]); + + if(status){ + return SEMANTIC_ERROR; + } + Parentbranch->elseBranch = elseBranch; + return SEMANTIC_OK; } +int createElseIf(Branch* Parentbranch, AST_NODE_PTR currentNode){ + ElseIf elseIfBranch; + elseIfBranch.nodePtr = currentNode; + + 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){ + return SEMANTIC_ERROR; + } + g_array_append_val(Parentbranch->elseIfBranches,elseIfBranch); + return SEMANTIC_OK; +} + + + 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){ case AST_If: if(createIf(&Branch, currentNode->children[i])){ return SEMANTIC_ERROR; } + break; + case AST_IfElse: + if(createElseIf(&Branch, currentNode)){ + return SEMANTIC_ERROR; + } + break; + case AST_Else: + if(createElse(&Branch, currentNode->children[i])){ + return SEMANTIC_ERROR; + } + break; + default: PANIC("current node is not part of a Branch"); break; - - } } - + ParentStatement->impl.branch = Branch; + return SEMANTIC_OK; } -Statement *createStatement(AST_NODE_PTR currentNode){ - Statement* statement = malloc(sizeof(Statement)); - statement->nodePtr = currentNode; - - switch(currentNode->kind){ - case AST_Decl: - statement->kind = StatementKindDeclaration; +int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){ - case AST_Def: - statement->kind = StatementKindDefinition; - case AST_While: - statement->kind = StatementKindWhile; - if(createWhile(statement, currentNode)){ - return NULL; + + switch(currentNode->kind){ + case AST_Decl:{ + GArray *variable= g_array_new(FALSE, FALSE, sizeof(Variable*)); + + int status = createDecl(currentNode, &variable); + if(status){ + return SEMANTIC_ERROR; + } + for(size_t i = 0; i < variable->len ; i++){ + + Statement * statement = malloc(sizeof(Statement)); + statement->nodePtr = currentNode; + statement->kind = StatementKindDeclaration; + + + statement->impl.variable = g_array_index(variable,Variable *,i); + g_array_append_val(Parentblock->statemnts,statement); + } } - case AST_Stmt: - statement->kind = StatementKindBranch; - //ifbrnches: - - case AST_Assign: - statement->kind = StatementKindAssignment; - if(createAssign(statement, currentNode)){ - return NULL; + break; + + case AST_Def:{ + GArray *variable= g_array_new(FALSE, FALSE, sizeof(Variable*)); + + int status = createDef(currentNode, &variable); + + if(status){ + return SEMANTIC_ERROR; + } + for(size_t i = 0; i < variable->len ; i++){ + + Statement * statement = malloc(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 = malloc(sizeof(Statement)); + statement->nodePtr = currentNode; + statement->kind = StatementKindWhile; + if(createWhile(statement, currentNode)){ + return SEMANTIC_ERROR; + } + g_array_append_val(Parentblock->statemnts,statement); + } + break; + case AST_Stmt:{ + Statement * statement = malloc(sizeof(Statement)); + statement->nodePtr = currentNode; + statement->kind = StatementKindBranch; + if(createBranch(statement, currentNode)){ + return SEMANTIC_ERROR; + } + g_array_append_val(Parentblock->statemnts,statement); + } + break; + case AST_Assign:{ + Statement * statement = malloc(sizeof(Statement)); + statement->nodePtr = currentNode; + statement->kind = StatementKindAssignment; + if(createAssign(statement, currentNode)){ + return SEMANTIC_ERROR; + } + g_array_append_val(Parentblock->statemnts,statement); + } + break; case AST_Call: - //both funcall and boxfuncall + //TODO both funcall and boxfuncall default: break; } + return SEMANTIC_OK; } +int createParam(GArray * Paramlist ,AST_NODE_PTR currentNode){ + AST_NODE_PTR paramdecl = currentNode->children[1]; + AST_NODE_PTR ioQualifierList = currentNode->children[0]; + + ParameterDeclaration decl; + decl.nodePtr = paramdecl; + + if(ioQualifierList->child_count == 2){ + decl.qualifier = InOut; + }else if(ioQualifierList->child_count == 1){ + if(strcmp(ioQualifierList->children[0]->value , "in")){ + decl.qualifier = In; + }else if(strcmp(ioQualifierList->children[0]->value , "out")){ + decl.qualifier = Out; + }else{ + PANIC("IO_Qualifier is not in or out"); + } + }else{ + PANIC("IO_Qualifier has not the right amount of children"); + } + + int signal = get_type_impl(paramdecl->children[0],&decl.type); + if(signal){ + return SEMANTIC_ERROR; + } -Function *createFunction(AST_NODE_PTR currentNode){ + Parameter param; + param.nodePtr = currentNode; + param.kind = ParameterDeclarationKind; + param.impl.declaration = decl; + param.name = paramdecl->children[1]->value; + + g_array_append_val(Paramlist,param); + return SEMANTIC_OK; } -BoxType *createBox(AST_NODE_PTR currentNode){ + +int createFunDef(Function * Parentfunction ,AST_NODE_PTR currentNode){ + + 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 = malloc(sizeof(Block)); + fundef.parameter = malloc(sizeof(GArray)); + + int signal = fillBlock(fundef.body, statementlist); + if(signal){ + return SEMANTIC_ERROR; + } + + 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++){ + + int signal = createParam(fundef.parameter ,paramlist->children[i]); + //all params per list + if (signal){ + return SEMANTIC_ERROR; + } + } + } + + Parentfunction->nodePtr = currentNode; + Parentfunction->kind = FunctionDefinitionKind; + Parentfunction->impl.definition = fundef; + return SEMANTIC_OK; + + +} + +int createFunDecl(Function * Parentfunction ,AST_NODE_PTR currentNode){ + + 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 = malloc(sizeof(GArray)); + + + 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++){ + + int signal = createParam(fundecl.parameter ,paramlist->children[i]); + //all params per list + if (signal){ + return SEMANTIC_ERROR; + } + } + } + + Parentfunction->nodePtr = currentNode; + Parentfunction->kind = FunctionDefinitionKind; + Parentfunction->impl.declaration = fundecl; + return SEMANTIC_OK; +} +//TODO check if a function is present and if a declaration is present and identical. + +Function * createFunction( AST_NODE_PTR currentNode){ + Function * fun = malloc(sizeof(Function)); + + + if(currentNode->child_count == 2){ + int signal = createFunDecl(fun, currentNode); + if (signal){ + return NULL; + } + }else if(currentNode->child_count == 3){ + int signal = createFunDef(fun, currentNode); + if (signal){ + return NULL; + } + }else { + PANIC("function should have 2 or 3 children"); + } + + return fun; +} + + + +int createDeclMember(BoxType * ParentBox, AST_NODE_PTR currentNode){ + + Type * declType = malloc(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 = malloc(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)){ + return SEMANTIC_ERROR; + } + g_hash_table_insert(ParentBox->member,(gpointer)decl->name,decl); + } + return SEMANTIC_OK; +} + +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 = malloc(sizeof(Type)); + int status = get_type_impl(currentNode->children[0],&declType); + if(status){ + return SEMANTIC_ERROR; + } + + Expression * init = createExpression(expressionNode);; + if (init == NULL){ + return SEMANTIC_ERROR; + } + + for (size_t i = 0; i < nameList->child_count; i++){ + BoxMember *def = malloc(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 = malloc(sizeof(BoxType)); box->nodePtr = currentNode; + const char * boxName = currentNode->children[0]->value; + AST_NODE_PTR boxMemberList = currentNode->children[1]; + for (size_t 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])){ + return SEMANTIC_ERROR; + } + break; + case AST_Fun: + //TODO FUNCTION Wait for createFunction() + default: + break; + } + + } + if(g_hash_table_contains(boxes, (gpointer)boxName)){ + return SEMANTIC_ERROR; + } + g_hash_table_insert(boxes, (gpointer)boxName, box); + return SEMANTIC_OK; + + // //box // name @@ -1335,9 +1669,40 @@ BoxType *createBox(AST_NODE_PTR currentNode){ // 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){ + AST_NODE_PTR typeNode = currentNode->children[0]; + AST_NODE_PTR nameNode = currentNode->children[1]; -} + Type * type = malloc(sizeof(Type)); + int status = get_type_impl( typeNode, &type); + if(status){ + return SEMANTIC_ERROR; + } + + Typedefine *def = malloc(sizeof(Typedefine)); + def->name = nameNode->value; + def->nodePtr = currentNode; + def->type = type; + + if(g_hash_table_contains(types, (gpointer)def->name)){ + return SEMANTIC_ERROR; + } + g_hash_table_insert(types, (gpointer)def->name, def); + return SEMANTIC_OK; +} Module *create_set(AST_NODE_PTR currentNode){ DEBUG("create root Module"); @@ -1378,8 +1743,10 @@ Module *create_set(AST_NODE_PTR currentNode){ case AST_Decl: { GArray* vars; int status = createDecl(currentNode->children[i], &vars); - - if (fillTablesWithVars(variables, globalscope, vars) == SEMANTIC_ERROR) { + if (status){ + return NULL; + } + if (fillTablesWithVars(variables, vars) == SEMANTIC_ERROR) { print_diagnostic(current_file, ¤tNode->children[i]->location, Error, "Variable already declared"); INFO("var already exists"); break; @@ -1390,13 +1757,29 @@ Module *create_set(AST_NODE_PTR currentNode){ case AST_Def: { GArray* vars; int status = createDef(currentNode->children[i], &vars); + if (status){ + return NULL; + } DEBUG("created Definition successfully"); break; } - case AST_Box: - + case AST_Box:{ + int status = createBox(boxes, currentNode->children[i]); + if (status){ + return NULL; + } + DEBUG("created Box successfully"); + break; + } case AST_Fun: - case AST_Typedef: + case AST_Typedef:{ + int status = createTypeDef(types, currentNode->children[i]); + if (status){ + return NULL; + } + DEBUG("created Typedef successfully"); + break; + } case AST_Import: DEBUG("create Import"); g_array_append_val(imports, currentNode->children[i]->value); diff --git a/src/set/types.h b/src/set/types.h index ae157bc..b73112c 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -74,10 +74,13 @@ typedef struct BoxType_t BoxType; typedef struct Block_t Block; +typedef struct Expression_t Expression; + typedef struct BoxMember_t { const char* name; Type* type; BoxType* box; + Expression* initalizer; AST_NODE_PTR nodePtr; } BoxMember; @@ -88,12 +91,11 @@ typedef struct BoxMember_t { typedef struct BoxType_t { // hashtable of members. // Associates the memebers name (const char*) with its type (BoxMember) - GHashTable* member; + GHashTable* member; //BoxMember Pointer AST_NODE_PTR nodePtr; } BoxType; typedef struct Variable_t Variable; -typedef struct Expression_t Expression; typedef struct BoxAccess_t { // list of recursive box accesses @@ -208,7 +210,7 @@ typedef enum FunctionKind_t { typedef struct FunctionDefinition_t { // hashtable of parameters // associates a parameters name (const char*) with its parameter declaration (ParameterDeclaration) - GArray* parameter; + GArray* parameter; // Parameter AST_NODE_PTR nodePtr; // body of function Block *body; @@ -219,8 +221,9 @@ typedef struct FunctionDefinition_t { typedef struct FunctionDeclaration_t { // hashtable of parameters // associates a parameters name (const char*) with its parameter declaration (ParameterDeclaration) - GArray* parameter; + GArray* parameter; // Parameter AST_NODE_PTR nodePtr; + const char* name; } FunctionDeclaration; typedef struct Function_t { @@ -229,6 +232,7 @@ typedef struct Function_t { FunctionDefinition definition; FunctionDeclaration declaration; } impl; + AST_NODE_PTR nodePtr; } Function; // .------------------------------------------------. @@ -449,7 +453,7 @@ typedef struct FunctionBoxCall_t { typedef struct Block_t { // array of statements - GArray* statemnts; + GArray* statemnts; // array of type(Statement) AST_NODE_PTR nodePtr; } Block; @@ -520,7 +524,7 @@ typedef struct Statement_t { While whileLoop; Branch branch; Assignment assignment; - Variable variable; + Variable *variable; } impl; AST_NODE_PTR nodePtr; } Statement; @@ -530,8 +534,8 @@ typedef struct Statement_t { // '------------------------------------------------' typedef struct Module_t { - GHashTable* boxes; - GHashTable* types; + GHashTable* boxes; //BoxType + GHashTable* types; // GHashTable* functions; GHashTable* variables; // to be resolved after the module has been parsed completely From 069369ca61644fe68724727e1ba46ab7c01d9e5a Mon Sep 17 00:00:00 2001 From: Filleo Date: Wed, 5 Jun 2024 21:20:21 +0200 Subject: [PATCH 20/29] minor change --- src/io/files.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io/files.c b/src/io/files.c index d091d06..6e5ab34 100644 --- a/src/io/files.c +++ b/src/io/files.c @@ -122,7 +122,7 @@ void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, c printf("%s%s:%ld:%s %s%s:%s ", BOLD, absolute_path, location->line_start, RESET, accent_color, kind_text, RESET); va_list args; - va_start(args, format); + va_start(args, message); vprintf(message, args); From 4067339df812c2c90650453c97e50b817876b3d1 Mon Sep 17 00:00:00 2001 From: Filleo Date: Wed, 5 Jun 2024 23:55:30 +0200 Subject: [PATCH 21/29] first kind of working implementation of set --- src/compiler.c | 3 ++- src/set/set.c | 67 ++++++++++++++++++++++++++++++++++++------------- src/set/types.h | 1 + 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/compiler.c b/src/compiler.c index 709592e..8bb446a 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -11,6 +11,7 @@ #include #include #include +#include extern void yyrestart(FILE *); @@ -140,7 +141,7 @@ 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); // TODO: parse AST to semantic values // TODO: backend codegen } diff --git a/src/set/set.c b/src/set/set.c index ac1af6a..d16ab0e 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -93,7 +93,7 @@ int scale_factor_from(const char* string, double* factor) { int check_scale_factor(AST_NODE_PTR node, Scale scale) { assert(node != NULL); - if (8 > scale) { + if (8 < scale) { print_diagnostic(current_file, &node->location, Error, "Composite scale overflow"); return SEMANTIC_ERROR; } @@ -222,6 +222,7 @@ int get_type_impl(AST_NODE_PTR currentNode, Type** type) { assert(currentNode != NULL); assert(currentNode->kind == AST_Type); assert(currentNode->child_count > 0); + DEBUG("start Type"); int status; @@ -340,7 +341,8 @@ int createDef(AST_NODE_PTR currentNode, GArray** variables) { AST_NODE_PTR declaration = currentNode->children[0]; AST_NODE_PTR expression = currentNode->children[1]; - AST_NODE_PTR ident_list = currentNode->children[0]->children[currentNode->child_count - 1]; + AST_NODE_PTR ident_list = declaration->children[currentNode->child_count - 1]; + *variables = g_array_new(FALSE, FALSE, sizeof(Variable*)); @@ -351,20 +353,20 @@ 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->children[i]->child_count; i++){ + 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(currentNode->children[i]->value); + decl.qualifier = Qualifier_from_string(declaration->children[i]->value); break; case AST_Type: DEBUG("fill Type"); - status = get_type_impl(currentNode->children[i], &decl.type); + status = get_type_impl(declaration->children[i], &decl.type); break; case AST_IdentList: break; default: - PANIC("invalid node type: %ld", currentNode->children[i]->kind); + PANIC("invalid node type: %ld", declaration->children[i]->kind); break; } } @@ -1087,6 +1089,7 @@ int createTransmute(Expression* ParentExpression, AST_NODE_PTR currentNode){ Expression *createExpression(AST_NODE_PTR currentNode){ + DEBUG("create Expression"); Expression *expression = malloc(sizeof(Expression)); expression->nodePtr = currentNode; switch(currentNode->kind){ @@ -1222,6 +1225,7 @@ Expression *createExpression(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; GHashTable * lowerScope = g_hash_table_new(g_str_hash,g_str_equal); @@ -1238,6 +1242,7 @@ int fillBlock(Block * block,AST_NODE_PTR currentNode){ g_hash_table_destroy(lowerScope); g_array_remove_index(Scope, Scope->len-1); + DEBUG("created Block successfully"); return SEMANTIC_OK; } @@ -1349,7 +1354,7 @@ int createBranch(Statement* ParentStatement,AST_NODE_PTR currentNode){ } int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){ - + DEBUG("create Statement"); switch(currentNode->kind){ case AST_Decl:{ @@ -1433,12 +1438,18 @@ int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){ int createParam(GArray * Paramlist ,AST_NODE_PTR currentNode){ + DEBUG("start param"); + DEBUG("current node child count: %i",currentNode->kind); + if( currentNode->kind == AST_Parameter){ + DEBUG("current n"); + } AST_NODE_PTR paramdecl = currentNode->children[1]; AST_NODE_PTR ioQualifierList = currentNode->children[0]; ParameterDeclaration decl; decl.nodePtr = paramdecl; + DEBUG("paramnode child count: %i", ioQualifierList->child_count ); if(ioQualifierList->child_count == 2){ decl.qualifier = InOut; }else if(ioQualifierList->child_count == 1){ @@ -1452,7 +1463,7 @@ int createParam(GArray * Paramlist ,AST_NODE_PTR currentNode){ }else{ PANIC("IO_Qualifier has not the right amount of children"); } - + int signal = get_type_impl(paramdecl->children[0],&decl.type); if(signal){ return SEMANTIC_ERROR; @@ -1466,12 +1477,13 @@ int createParam(GArray * Paramlist ,AST_NODE_PTR currentNode){ param.name = paramdecl->children[1]->value; g_array_append_val(Paramlist,param); + DEBUG("created param successfully"); return SEMANTIC_OK; } 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]; @@ -1508,13 +1520,14 @@ int createFunDef(Function * Parentfunction ,AST_NODE_PTR currentNode){ 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){ - + DEBUG("start fundecl"); AST_NODE_PTR nameNode = currentNode->children[0]; AST_NODE_PTR paramlistlist = currentNode->children[1]; @@ -1545,29 +1558,34 @@ int createFunDecl(Function * Parentfunction ,AST_NODE_PTR currentNode){ Parentfunction->nodePtr = currentNode; Parentfunction->kind = FunctionDefinitionKind; Parentfunction->impl.declaration = fundecl; + Parentfunction->name = fundecl.name; return SEMANTIC_OK; } //TODO check if a function is present and if a declaration is present and identical. -Function * createFunction( AST_NODE_PTR currentNode){ +int createFunction(GHashTable* functions, AST_NODE_PTR currentNode){ + assert(currentNode->kind == AST_Fun); Function * fun = malloc(sizeof(Function)); - + if(currentNode->child_count == 2){ int signal = createFunDecl(fun, currentNode); if (signal){ - return NULL; + return SEMANTIC_ERROR; } }else if(currentNode->child_count == 3){ int signal = createFunDef(fun, currentNode); if (signal){ - return NULL; + return SEMANTIC_ERROR; } }else { PANIC("function should have 2 or 3 children"); } - - return fun; + if(g_hash_table_contains(functions,fun->name)){ + return SEMANTIC_ERROR; + } + g_hash_table_insert(functions,(gpointer)fun->name, fun); + return SEMANTIC_OK; } @@ -1682,6 +1700,7 @@ int createBox(GHashTable *boxes, 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]; @@ -1701,6 +1720,11 @@ int createTypeDef(GHashTable *types, AST_NODE_PTR currentNode){ return SEMANTIC_ERROR; } 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); + return SEMANTIC_OK; } @@ -1771,7 +1795,16 @@ Module *create_set(AST_NODE_PTR currentNode){ DEBUG("created Box successfully"); break; } - case AST_Fun: + 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){ diff --git a/src/set/types.h b/src/set/types.h index b73112c..1d415c1 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -233,6 +233,7 @@ typedef struct Function_t { FunctionDeclaration declaration; } impl; AST_NODE_PTR nodePtr; + const char * name; } Function; // .------------------------------------------------. From 6502a7f4bbf9aa52ea76b47c2d57958a93d60959 Mon Sep 17 00:00:00 2001 From: Filleo Date: Thu, 6 Jun 2024 21:48:41 +0200 Subject: [PATCH 22/29] first working implementation of set --- src/compiler.c | 1 + src/set/set.c | 166 +++++++++++++++++++++++++++++++++---------------- 2 files changed, 113 insertions(+), 54 deletions(-) diff --git a/src/compiler.c b/src/compiler.c index 8bb446a..f614c7f 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -142,6 +142,7 @@ static void build_target(ModuleFileStack *unit, const TargetConfig *target) { print_ast_to_file(ast, target); Module * test = create_set(ast); + free(test); // TODO: parse AST to semantic values // TODO: backend codegen } diff --git a/src/set/set.c b/src/set/set.c index d16ab0e..bafcf4b 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -15,6 +15,7 @@ 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 const Type ShortShortUnsingedIntType = { @@ -63,16 +64,17 @@ int sign_from_string(const char* string, Sign* sign) { int primitive_from_string(const char* string, PrimitiveType* primitive) { assert(string != NULL); assert(primitive != NULL); + DEBUG("find primitive in string"); if (strcmp(string, "int") == 0) { *primitive = Int; - return 0; + return SEMANTIC_OK; } else if (strcmp(string, "float") == 0) { *primitive = Float; - return 0; + return SEMANTIC_OK; } - return 1; + return SEMANTIC_ERROR; } int scale_factor_from(const char* string, double* factor) { @@ -237,7 +239,6 @@ int get_type_impl(AST_NODE_PTR currentNode, Type** type) { *type = g_hash_table_lookup(declaredBoxes, typekind); return SEMANTIC_OK; } - // type is not yet declared, make a new one Type* new_type = malloc(sizeof(Type)); @@ -251,11 +252,13 @@ int get_type_impl(AST_NODE_PTR currentNode, Type** type) { new_type->kind = TypeKindPrimitive; status = primitive_from_string(typekind, &new_type->impl.primitive); - + // if err continue at composite construction if (status == SEMANTIC_OK) { + *type = new_type; return SEMANTIC_OK; } + return SEMANTIC_ERROR; } new_type->kind = TypeKindComposite; @@ -263,6 +266,8 @@ int get_type_impl(AST_NODE_PTR currentNode, Type** type) { status = impl_composite_type(currentNode, &new_type->impl.composite); *type = new_type; + + return status; } @@ -432,19 +437,38 @@ int getVariableFromScope(const char* name, Variable** variable) { assert(name != NULL); assert(variable != NULL); assert(Scope != NULL); + DEBUG("getting var from scope"); + int found = 0; // loop through all variable scope and find a variable + 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++) { GHashTable* variable_table = g_array_index(Scope,GHashTable* ,i ); if(g_hash_table_contains(variable_table, name)) { - *variable = g_hash_table_lookup(variable_table, name); - return SEMANTIC_OK; + if(found == 0){ + *variable = g_hash_table_lookup(variable_table, name); + } + found += 1; } } - + if (found == 1){ + DEBUG("Var: %s",(*variable)->name); + DEBUG("Var Typekind: %d", (*variable)->kind); + DEBUG("Found var"); + return SEMANTIC_OK; + }else if (found > 1) { + WARN("Variable %s is a parameter and a declared variable. Returning parameter", name); + return SEMANTIC_OK; + } + DEBUG("nothing found"); return SEMANTIC_ERROR; } @@ -481,6 +505,7 @@ int fillTablesWithVars(GHashTable *variableTable, GArray* variables) { [[nodiscard("type must be freed")]] TypeValue createTypeValue(AST_NODE_PTR currentNode){ + DEBUG("create TypeValue"); TypeValue value; Type *type = malloc(sizeof(Type)); value.type = type; @@ -515,6 +540,7 @@ static inline void* clone(int size, void* ptr) { #define CLONE(x) clone(sizeof(x), (void*)&(x)) TypeValue createString(AST_NODE_PTR currentNode) { + DEBUG("create String"); TypeValue value; Type *type = CLONE(StringLiteralType); value.type = type; @@ -524,8 +550,11 @@ TypeValue createString(AST_NODE_PTR currentNode) { } Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_NODE_PTR currentNode) { + DEBUG("create type from operands"); Type *result = malloc(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; @@ -539,6 +568,7 @@ Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_ 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); @@ -562,26 +592,28 @@ Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_ free(result); return NULL; } + DEBUG("Succsessfully created type"); return result; } 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*)); - assert(expectedChildCount > currentNode->child_count); + assert(expectedChildCount == currentNode->child_count); for (size_t i = 0; i < currentNode->child_count; i++) { Expression* expression = createExpression(currentNode->children[i]); if(NULL == expression) { - return SEMANTIC_OK; + return SEMANTIC_ERROR; } g_array_append_val(ParentExpression->impl.operation.operands, expression); } - + DEBUG("created all Expressions"); switch (currentNode->kind) { case AST_Add: ParentExpression->impl.operation.impl.arithmetic = Add; @@ -604,7 +636,8 @@ int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode, } if (ParentExpression->impl.operation.impl.arithmetic == Negate) { - Type* result = ((Expression**) ParentExpression->impl.operation.operands->data)[0]->result; + + Type* result = g_array_index(ParentExpression->impl.operation.operands,Expression *,0)->result; result->nodePtr = currentNode; if (result->kind == TypeKindReference || result->kind == TypeKindBox) { @@ -616,9 +649,8 @@ int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode, ParentExpression->result = result; } else { - - Type* LeftOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[0]->result; - Type* RightOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[1]->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; ParentExpression->result = createTypeFromOperands(LeftOperandType, RightOperandType, currentNode); } @@ -634,7 +666,7 @@ int createRelationalOperation(Expression* ParentExpression, AST_NODE_PTR current // 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*)); // fill Operands for (size_t i = 0; i < currentNode->child_count; i++) { Expression* expression = createExpression(currentNode->children[i]); @@ -1045,6 +1077,7 @@ int createBoxAccess(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]); @@ -1060,7 +1093,6 @@ int createTypeCast(Expression* ParentExpression, AST_NODE_PTR currentNode){ } ParentExpression->impl.typecast.targetType = target; ParentExpression->result = target; - return SEMANTIC_OK; } @@ -1106,16 +1138,18 @@ Expression *createExpression(AST_NODE_PTR 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 ); + 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: + 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; @@ -1200,11 +1234,15 @@ Expression *createExpression(AST_NODE_PTR currentNode){ PANIC("Node is not an expression but from kind: %i", currentNode->kind); break; } + + DEBUG("expression result typekind: %d",expression->result->kind); + DEBUG("successfully created Expression"); return expression; } int createAssign(Statement* ParentStatement, AST_NODE_PTR currentNode){ + DEBUG("create Assign"); Assignment assign; assign.nodePtr = currentNode; const char* varName = currentNode->children[0]->value; @@ -1220,20 +1258,20 @@ Expression *createExpression(AST_NODE_PTR currentNode){ } ParentStatement->impl.assignment = assign; - return SEMANTIC_ERROR; + return SEMANTIC_OK; } 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); g_array_append_val(Scope, lowerScope); for(size_t i = 0; i < currentNode->child_count; i++){ - int signal = createStatement(block, currentNode->children[i]); + int signal = createStatement(block, AST_get_node(currentNode, i)); if(signal){ return SEMANTIC_ERROR; } @@ -1247,8 +1285,8 @@ int fillBlock(Block * block,AST_NODE_PTR currentNode){ } int createWhile(Statement * ParentStatement, AST_NODE_PTR currentNode){ - assert(ParentStatement == NULL); - assert(currentNode == NULL); + assert(ParentStatement != NULL); + assert(currentNode != NULL); assert(currentNode->kind == AST_While); While whileStruct; @@ -1438,24 +1476,23 @@ int createStatement(Block * Parentblock , 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->kind); - if( currentNode->kind == AST_Parameter){ - DEBUG("current n"); - } + DEBUG("current node child count: %i",currentNode->child_count); + AST_NODE_PTR paramdecl = currentNode->children[1]; AST_NODE_PTR ioQualifierList = currentNode->children[0]; ParameterDeclaration decl; decl.nodePtr = paramdecl; - DEBUG("paramnode child count: %i", ioQualifierList->child_count ); + 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")){ + if(strcmp(ioQualifierList->children[0]->value , "in") == 0){ decl.qualifier = In; - }else if(strcmp(ioQualifierList->children[0]->value , "out")){ + }else if(strcmp(ioQualifierList->children[0]->value , "out") == 0){ decl.qualifier = Out; }else{ PANIC("IO_Qualifier is not in or out"); @@ -1464,19 +1501,35 @@ int createParam(GArray * Paramlist ,AST_NODE_PTR currentNode){ PANIC("IO_Qualifier has not the right amount of children"); } - int signal = get_type_impl(paramdecl->children[0],&decl.type); + int signal = get_type_impl(paramdecl->children[0], &(decl.type)); if(signal){ return SEMANTIC_ERROR; } - - Parameter param; param.nodePtr = 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 = malloc(sizeof(Variable)); + paramvar->kind = VariableKindDeclaration; + paramvar->name = param.name; + paramvar->nodePtr = currentNode; + paramvar->impl.declaration.nodePtr = currentNode; + paramvar->impl.declaration.qualifier = Local; + paramvar->impl.declaration.type = param.impl.declaration.type; + + + if (g_hash_table_contains(functionParameter, param.name)){ + return SEMANTIC_ERROR; + } + g_hash_table_insert(functionParameter, (gpointer)param.name, paramvar); - g_array_append_val(Paramlist,param); DEBUG("created param successfully"); return SEMANTIC_OK; } @@ -1495,28 +1548,31 @@ int createFunDef(Function * Parentfunction ,AST_NODE_PTR currentNode){ fundef.nodePtr = currentNode; fundef.name = nameNode->value; fundef.body = malloc(sizeof(Block)); - fundef.parameter = malloc(sizeof(GArray)); + fundef.parameter = g_array_new(FALSE, FALSE, sizeof(Parameter)); + DEBUG("paramlistlist child count: %i", paramlistlist->child_count); + for(size_t i = 0; i < paramlistlist->child_count; i++){ + + //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++){ + + DEBUG("param child count: %i", AST_get_node(paramlist, j)->child_count); + int signal = createParam(fundef.parameter ,AST_get_node(paramlist, j)); + //all params per list + + if (signal){ + return SEMANTIC_ERROR; + } + } + DEBUG("End of Paramlist"); + } int signal = fillBlock(fundef.body, statementlist); if(signal){ return SEMANTIC_ERROR; } - 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++){ - - int signal = createParam(fundef.parameter ,paramlist->children[i]); - //all params per list - if (signal){ - return SEMANTIC_ERROR; - } - } - } - Parentfunction->nodePtr = currentNode; Parentfunction->kind = FunctionDefinitionKind; Parentfunction->impl.definition = fundef; @@ -1566,7 +1622,7 @@ int createFunDecl(Function * Parentfunction ,AST_NODE_PTR currentNode){ int createFunction(GHashTable* functions, AST_NODE_PTR currentNode){ assert(currentNode->kind == AST_Fun); Function * fun = malloc(sizeof(Function)); - + functionParameter = g_hash_table_new(g_str_hash,g_str_equal); if(currentNode->child_count == 2){ int signal = createFunDecl(fun, currentNode); @@ -1585,6 +1641,8 @@ int createFunction(GHashTable* functions, AST_NODE_PTR currentNode){ return SEMANTIC_ERROR; } g_hash_table_insert(functions,(gpointer)fun->name, fun); + + g_hash_table_destroy(functionParameter); return SEMANTIC_OK; } @@ -1823,7 +1881,7 @@ Module *create_set(AST_NODE_PTR currentNode){ } } - + DEBUG("created set successfully"); return rootModule; } From b9226ad3f5e84bac6dfc40310ace92430f2f8c8c Mon Sep 17 00:00:00 2001 From: Filleo Date: Thu, 6 Jun 2024 23:21:06 +0200 Subject: [PATCH 23/29] merged main in branch --- src/mem/cache.c | 2 +- src/set/set.c | 75 ++++++++++++++++++++++++++----------------------- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/mem/cache.c b/src/mem/cache.c index 57779c2..c7e9a38 100644 --- a/src/mem/cache.c +++ b/src/mem/cache.c @@ -221,7 +221,7 @@ void mem_purge_namespace(MemoryNamespaceName name) { namespace_purge(cache); } else { - PANIC("purging invalid namespace: %s", name); + WARN("purging invalid namespace: %s", name); } } diff --git a/src/set/set.c b/src/set/set.c index bafcf4b..d6f369c 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -10,6 +10,7 @@ #include #include #include +#include extern ModuleFile * current_file; @@ -218,6 +219,7 @@ int impl_composite_type(AST_NODE_PTR ast_type, CompositeType* composite) { /** * @brief Converts the given AST node to a gemstone type implementation. * @param currentNode AST node of type kind type + * @param type pointer output for the type * @return the gemstone type implementation */ int get_type_impl(AST_NODE_PTR currentNode, Type** type) { @@ -241,7 +243,7 @@ int get_type_impl(AST_NODE_PTR currentNode, Type** type) { } // type is not yet declared, make a new one - Type* new_type = malloc(sizeof(Type)); + Type* new_type = mem_alloc(MemoryNamespaceSet,sizeof(Type)); new_type->nodePtr = currentNode; // only one child means either composite or primitive @@ -294,6 +296,7 @@ int createDecl(AST_NODE_PTR currentNode, GArray** variables) { VariableDeclaration decl; decl.nodePtr = currentNode; + decl.qualifier = Static; int status = SEMANTIC_OK; @@ -318,7 +321,7 @@ int createDecl(AST_NODE_PTR currentNode, GArray** variables) { } for(size_t i = 0; i < ident_list->child_count; i++) { - Variable* variable = malloc(sizeof(Variable)); + Variable* variable = mem_alloc(MemoryNamespaceSet,sizeof(Variable)); variable->kind = VariableKindDeclaration; variable->nodePtr = currentNode; @@ -354,6 +357,8 @@ int createDef(AST_NODE_PTR currentNode, GArray** variables) { VariableDeclaration decl; VariableDefiniton def; def.nodePtr = currentNode; + decl.qualifier = Static; + decl.nodePtr = AST_get_node(currentNode, 0); int status = SEMANTIC_OK; @@ -385,7 +390,7 @@ int createDef(AST_NODE_PTR currentNode, GArray** variables) { for(size_t i = 0; i < ident_list->child_count; i++) { - Variable* variable = malloc(sizeof(Variable)); + Variable* variable = mem_alloc(MemoryNamespaceSet,sizeof(Variable)); variable->kind = VariableKindDefinition; variable->nodePtr = currentNode; @@ -484,7 +489,7 @@ int addVarToScope(Variable * variable){ return SEMANTIC_OK; } -int fillTablesWithVars(GHashTable *variableTable, 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++) { @@ -507,7 +512,7 @@ int fillTablesWithVars(GHashTable *variableTable, GArray* variables) { TypeValue createTypeValue(AST_NODE_PTR currentNode){ DEBUG("create TypeValue"); TypeValue value; - Type *type = malloc(sizeof(Type)); + Type *type = mem_alloc(MemoryNamespaceSet,sizeof(Type)); value.type = type; type->kind = TypeKindPrimitive; type->nodePtr = currentNode; @@ -532,7 +537,7 @@ TypeValue createTypeValue(AST_NODE_PTR currentNode){ } static inline void* clone(int size, void* ptr) { - char* data = malloc(size); + char* data = mem_alloc(MemoryNamespaceSet,size); memcpy(data, ptr, size); return data; } @@ -551,7 +556,7 @@ TypeValue createString(AST_NODE_PTR currentNode) { Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_NODE_PTR currentNode) { DEBUG("create type from operands"); - Type *result = malloc(sizeof(Type)); + Type *result = mem_alloc(MemoryNamespaceSet,sizeof(Type)); result->nodePtr = currentNode; DEBUG("LeftOperandType->kind: %i", LeftOperandType->kind); DEBUG("RightOperandType->kind: %i", RightOperandType->kind); @@ -589,7 +594,7 @@ Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_ result->impl.composite.primitive = MAX(Int, LeftOperandType->impl.composite.primitive); result->impl.composite.nodePtr = currentNode; } else { - free(result); + mem_free(result); return NULL; } DEBUG("Succsessfully created type"); @@ -692,7 +697,7 @@ int createRelationalOperation(Expression* ParentExpression, AST_NODE_PTR current break; } - Type* result = malloc(sizeof(Type)); + Type* result = mem_alloc(MemoryNamespaceSet,sizeof(Type)); result->impl.primitive = Int; result->kind = TypeKindPrimitive; result->nodePtr = currentNode; @@ -789,7 +794,7 @@ int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNod Type* Operand = ((Expression**)ParentExpression->impl.operation.operands)[0]->result; - Type* result = malloc(sizeof(Type)); + Type* result = mem_alloc(MemoryNamespaceSet,sizeof(Type)); result->nodePtr = currentNode; if (Operand->kind == TypeKindBox || Operand->kind == TypeKindReference) { @@ -856,7 +861,7 @@ int createBitOperation(Expression* ParentExpression, AST_NODE_PTR currentNode) { break; } - Type *result = malloc(sizeof(Type)); + Type *result = mem_alloc(MemoryNamespaceSet,sizeof(Type)); result->nodePtr = currentNode; Expression* lhs = ((Expression**) ParentExpression->impl.operation.operands->data)[0]; @@ -963,7 +968,7 @@ int createBitNotOperation(Expression* ParentExpression, AST_NODE_PTR currentNode Type* Operand = ((Expression**) ParentExpression->impl.operation.operands)[0]->result; - Type* result = malloc(sizeof(Type)); + Type* result = mem_alloc(MemoryNamespaceSet,sizeof(Type)); result->nodePtr = currentNode; if (Operand->kind == TypeKindPrimitive) { @@ -1056,7 +1061,7 @@ int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) { ParentExpression->impl.variable->impl.member.variable = boxVariable; //first one is the box itself - GArray* names = malloc(sizeof(GArray)); + 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); @@ -1085,7 +1090,7 @@ int createTypeCast(Expression* ParentExpression, AST_NODE_PTR currentNode){ return SEMANTIC_ERROR; } - Type* target = malloc(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"); @@ -1104,7 +1109,7 @@ int createTransmute(Expression* ParentExpression, AST_NODE_PTR currentNode){ return SEMANTIC_ERROR; } - Type* target = malloc(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"); @@ -1122,7 +1127,7 @@ int createTransmute(Expression* ParentExpression, AST_NODE_PTR currentNode){ Expression *createExpression(AST_NODE_PTR currentNode){ DEBUG("create Expression"); - Expression *expression = malloc(sizeof(Expression)); + Expression *expression = mem_alloc(MemoryNamespaceSet,sizeof(Expression)); expression->nodePtr = currentNode; switch(currentNode->kind){ @@ -1404,7 +1409,7 @@ int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){ } for(size_t i = 0; i < variable->len ; i++){ - Statement * statement = malloc(sizeof(Statement)); + Statement * statement = mem_alloc(MemoryNamespaceSet,sizeof(Statement)); statement->nodePtr = currentNode; statement->kind = StatementKindDeclaration; @@ -1425,7 +1430,7 @@ int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){ } for(size_t i = 0; i < variable->len ; i++){ - Statement * statement = malloc(sizeof(Statement)); + Statement * statement = mem_alloc(MemoryNamespaceSet,sizeof(Statement)); statement->nodePtr = currentNode; statement->kind = StatementKindDefinition; @@ -1436,7 +1441,7 @@ int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){ } break; case AST_While:{ - Statement * statement = malloc(sizeof(Statement)); + Statement * statement = mem_alloc(MemoryNamespaceSet,sizeof(Statement)); statement->nodePtr = currentNode; statement->kind = StatementKindWhile; if(createWhile(statement, currentNode)){ @@ -1446,7 +1451,7 @@ int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){ } break; case AST_Stmt:{ - Statement * statement = malloc(sizeof(Statement)); + Statement * statement = mem_alloc(MemoryNamespaceSet,sizeof(Statement)); statement->nodePtr = currentNode; statement->kind = StatementKindBranch; if(createBranch(statement, currentNode)){ @@ -1456,7 +1461,7 @@ int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){ } break; case AST_Assign:{ - Statement * statement = malloc(sizeof(Statement)); + Statement * statement = mem_alloc(MemoryNamespaceSet,sizeof(Statement)); statement->nodePtr = currentNode; statement->kind = StatementKindAssignment; if(createAssign(statement, currentNode)){ @@ -1516,7 +1521,7 @@ int createParam(GArray * Paramlist ,AST_NODE_PTR currentNode){ DEBUG("create var for param"); - Variable * paramvar = malloc(sizeof(Variable)); + Variable * paramvar = mem_alloc(MemoryNamespaceSet,sizeof(Variable)); paramvar->kind = VariableKindDeclaration; paramvar->name = param.name; paramvar->nodePtr = currentNode; @@ -1547,7 +1552,7 @@ int createFunDef(Function * Parentfunction ,AST_NODE_PTR currentNode){ fundef.nodePtr = currentNode; fundef.name = nameNode->value; - fundef.body = malloc(sizeof(Block)); + fundef.body = mem_alloc(MemoryNamespaceSet,sizeof(Block)); fundef.parameter = g_array_new(FALSE, FALSE, sizeof(Parameter)); DEBUG("paramlistlist child count: %i", paramlistlist->child_count); @@ -1593,7 +1598,7 @@ int createFunDecl(Function * Parentfunction ,AST_NODE_PTR currentNode){ fundecl.nodePtr = currentNode; fundecl.name = nameNode->value; - fundecl.parameter = malloc(sizeof(GArray)); + fundecl.parameter = mem_alloc(MemoryNamespaceSet,sizeof(GArray)); for(size_t i = 0; i < paramlistlist->child_count; i++){ @@ -1621,7 +1626,7 @@ int createFunDecl(Function * Parentfunction ,AST_NODE_PTR currentNode){ int createFunction(GHashTable* functions, AST_NODE_PTR currentNode){ assert(currentNode->kind == AST_Fun); - Function * fun = malloc(sizeof(Function)); + Function * fun = mem_alloc(MemoryNamespaceSet,sizeof(Function)); functionParameter = g_hash_table_new(g_str_hash,g_str_equal); if(currentNode->child_count == 2){ @@ -1650,7 +1655,7 @@ int createFunction(GHashTable* functions, AST_NODE_PTR currentNode){ int createDeclMember(BoxType * ParentBox, AST_NODE_PTR currentNode){ - Type * declType = malloc(sizeof(Type)); + Type * declType = mem_alloc(MemoryNamespaceSet,sizeof(Type)); int status = get_type_impl(currentNode->children[0],&declType); if(status){ return SEMANTIC_ERROR; @@ -1658,7 +1663,7 @@ int createDeclMember(BoxType * ParentBox, AST_NODE_PTR currentNode){ AST_NODE_PTR nameList = currentNode->children[1]; for(size_t i = 0; i < nameList->child_count; i++){ - BoxMember * decl = malloc(sizeof(BoxMember)); + BoxMember * decl = mem_alloc(MemoryNamespaceSet,sizeof(BoxMember)); decl->name = nameList->children[i]->value; decl->nodePtr = currentNode; decl->box = ParentBox; @@ -1677,7 +1682,7 @@ int createDefMember(BoxType *ParentBox, AST_NODE_PTR currentNode){ AST_NODE_PTR expressionNode = currentNode->children[1]; AST_NODE_PTR nameList = declNode->children[1]; - Type * declType = malloc(sizeof(Type)); + Type * declType = mem_alloc(MemoryNamespaceSet,sizeof(Type)); int status = get_type_impl(currentNode->children[0],&declType); if(status){ return SEMANTIC_ERROR; @@ -1689,7 +1694,7 @@ int createDefMember(BoxType *ParentBox, AST_NODE_PTR currentNode){ } for (size_t i = 0; i < nameList->child_count; i++){ - BoxMember *def = malloc(sizeof(BoxMember)); + BoxMember *def = mem_alloc(MemoryNamespaceSet,sizeof(BoxMember)); def->box = ParentBox; def->type = declType; def->initalizer = init; @@ -1704,7 +1709,7 @@ int createDefMember(BoxType *ParentBox, AST_NODE_PTR currentNode){ } int createBox(GHashTable *boxes, AST_NODE_PTR currentNode){ - BoxType * box = malloc(sizeof(BoxType)); + BoxType * box = mem_alloc(MemoryNamespaceSet,sizeof(BoxType)); box->nodePtr = currentNode; const char * boxName = currentNode->children[0]->value; @@ -1763,13 +1768,13 @@ int createTypeDef(GHashTable *types, AST_NODE_PTR currentNode){ AST_NODE_PTR nameNode = currentNode->children[1]; - Type * type = malloc(sizeof(Type)); + Type * type = mem_alloc(MemoryNamespaceSet,sizeof(Type)); int status = get_type_impl( typeNode, &type); if(status){ return SEMANTIC_ERROR; } - Typedefine *def = malloc(sizeof(Typedefine)); + Typedefine *def = mem_alloc(MemoryNamespaceSet,sizeof(Typedefine)); def->name = nameNode->value; def->nodePtr = currentNode; def->type = type; @@ -1797,11 +1802,11 @@ Module *create_set(AST_NODE_PTR currentNode){ //building current scope for module - GHashTable *globalscope = malloc(sizeof(GHashTable*)); + GHashTable *globalscope = mem_alloc(MemoryNamespaceSet,sizeof(GHashTable*)); globalscope = g_hash_table_new(g_str_hash,g_str_equal); g_array_append_val(Scope, globalscope); - Module *rootModule = malloc(sizeof(Module)); + Module *rootModule = mem_alloc(MemoryNamespaceSet,sizeof(Module)); GHashTable *boxes = g_hash_table_new(g_str_hash,g_str_equal); GHashTable *types = g_hash_table_new(g_str_hash,g_str_equal); @@ -1881,7 +1886,7 @@ Module *create_set(AST_NODE_PTR currentNode){ } } - DEBUG("created set successfully"); + DEBUG("created set successfully"); return rootModule; } From f51e72d1549cdbfb0e98716af4adda00f2066a3e Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 7 Jun 2024 12:37:50 +0200 Subject: [PATCH 24/29] fixed: clone not using memory cache --- src/compiler.c | 4 +++- src/set/set.c | 8 +------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/compiler.c b/src/compiler.c index dd2d388..38ce793 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -143,9 +143,11 @@ static void build_target(ModuleFileStack *unit, const TargetConfig *target) { print_ast_to_file(ast, target); Module * test = create_set(ast); - free(test); + // TODO: parse AST to semantic values // TODO: backend codegen + + mem_free(test); } } diff --git a/src/set/set.c b/src/set/set.c index d6f369c..c11fc64 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -536,13 +536,7 @@ TypeValue createTypeValue(AST_NODE_PTR currentNode){ return value; } -static inline void* clone(int size, void* ptr) { - char* data = mem_alloc(MemoryNamespaceSet,size); - memcpy(data, ptr, size); - return data; -} - -#define CLONE(x) clone(sizeof(x), (void*)&(x)) +#define CLONE(x) mem_clone(MemoryNamespaceSet, (void*)&(x), sizeof(x)) TypeValue createString(AST_NODE_PTR currentNode) { DEBUG("create String"); From 7f0ca78f921168d0e0dbe99d45404d124cfbd338 Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 7 Jun 2024 15:36:02 +0200 Subject: [PATCH 25/29] added: delete routines for set --- src/compiler.c | 3 +- src/set/set.c | 101 ++++++++++++++++++++++++-- src/set/set.h | 2 + src/set/types.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++ src/set/types.h | 34 +++++++++ 5 files changed, 321 insertions(+), 5 deletions(-) create mode 100644 src/set/types.c 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_ From 150f87990a87944de2b9d8fc6bc9eba115c51315 Mon Sep 17 00:00:00 2001 From: servostar Date: Sat, 8 Jun 2024 14:55:40 +0200 Subject: [PATCH 26/29] 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); -} From 71755e48a4a4eb0fb095ab4313f44abc0f177ab2 Mon Sep 17 00:00:00 2001 From: Filleo Date: Sat, 8 Jun 2024 17:06:55 +0200 Subject: [PATCH 27/29] added references, derefs and addressOf to set --- src/set/set.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++-- src/set/types.c | 4 +- src/set/types.h | 20 ++++- 3 files changed, 239 insertions(+), 8 deletions(-) diff --git a/src/set/set.c b/src/set/set.c index 4330c74..6bc2c7a 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -311,13 +311,20 @@ int get_type_impl(AST_NODE_PTR currentNode, Type** type) { const char *typekind = currentNode->children[currentNode->child_count -1]->value; + //find type in composites if (g_hash_table_contains(declaredComposites, typekind) == TRUE) { *type = g_hash_table_lookup(declaredComposites, typekind); return SEMANTIC_OK; + //TODO change composite based on other nodes } + if (g_hash_table_contains(declaredBoxes, typekind) == TRUE) { *type = g_hash_table_lookup(declaredBoxes, typekind); + if(currentNode->child_count > 1) { + //TODO free + return SEMANTIC_ERROR; + } return SEMANTIC_OK; } // type is not yet declared, make a new one @@ -366,6 +373,29 @@ StorageQualifier Qualifier_from_string(const char *str) { } int addVarToScope(Variable * variable); +int createRef(AST_NODE_PTR currentNode, Type** reftype) { + assert(currentNode != NULL); + assert(currentNode->child_count = 1); + assert(AST_get_node(currentNode,0)->kind = AST_Type); + + + + Type * type = malloc(sizeof(Type)); + (*reftype)->kind = TypeKindReference; + (*reftype)->nodePtr = currentNode; + + + int signal = get_type_impl(currentNode->children[0],&type); + if(signal) { + //TODO free type + return SEMANTIC_ERROR; + } + (*reftype)->impl.reference = type; + + return SEMANTIC_OK; + +} + int createDecl(AST_NODE_PTR currentNode, GArray** variables) { DEBUG("create declaration"); @@ -385,14 +415,16 @@ int createDecl(AST_NODE_PTR currentNode, GArray** variables) { switch(currentNode->children[i]->kind){ case AST_Storage: DEBUG("fill Qualifier"); - decl.qualifier = Qualifier_from_string(currentNode->children[i]->value); + decl.qualifier = Qualifier_from_string(AST_get_node(currentNode,i)->value); break; case AST_Type: DEBUG("fill Type"); - status = get_type_impl(currentNode->children[i], &decl.type); + status = get_type_impl(AST_get_node(currentNode,i), &decl.type); break; case AST_IdentList: break; + case AST_Reference: + status = createRef(AST_get_node(currentNode,i), &decl.type); default: PANIC("invalid node type: %ld", currentNode->children[i]->kind); break; @@ -1075,7 +1107,7 @@ int createBitNotOperation(Expression* ParentExpression, AST_NODE_PTR currentNode GArray* getBoxMember(Type* currentBoxType, GArray *names) { GArray *members = g_array_new(FALSE, FALSE, sizeof(BoxMember)); - GHashTable* memberList = currentBoxType->impl.box.member; + GHashTable* memberList = currentBoxType->impl.box->member; const char* currentName = g_array_index(names,const char *,0); if(!g_hash_table_contains(memberList, currentName)) { @@ -1163,12 +1195,25 @@ int createTypeCast(Expression* ParentExpression, AST_NODE_PTR currentNode){ return SEMANTIC_ERROR; } + if (ParentExpression->impl.typecast.operand->result->kind != TypeKindComposite + && ParentExpression->impl.typecast.operand->result->kind != TypeKindPrimitive){ + //TODO free everything + return SEMANTIC_ERROR; + } + 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"); return SEMANTIC_ERROR; } + + if (target->kind != TypeKindComposite + && target->kind != TypeKindPrimitive){ + //TODO free everything + return SEMANTIC_ERROR; + } + ParentExpression->impl.typecast.targetType = target; ParentExpression->result = target; return SEMANTIC_OK; @@ -1182,6 +1227,18 @@ int createTransmute(Expression* ParentExpression, AST_NODE_PTR currentNode){ return SEMANTIC_ERROR; } + //cand cast from box + if (ParentExpression->impl.transmute.operand->result->kind == TypeKindBox){ + //TODO free everything + return SEMANTIC_ERROR; + } + Type * inputExpressionType = ParentExpression->impl.transmute.operand->result; + double inputSize = 1; + if(inputExpressionType->kind == TypeKindComposite) { + inputSize= inputExpressionType->impl.composite.scale; + } + + Type* target = mem_alloc(MemoryNamespaceSet,sizeof(Type)); int status = get_type_impl(currentNode->children[1], &target); if (status){ @@ -1189,6 +1246,22 @@ int createTransmute(Expression* ParentExpression, AST_NODE_PTR currentNode){ return SEMANTIC_ERROR; } + if (target->kind != TypeKindComposite + && target->kind != TypeKindPrimitive){ + //TODO free everything + return SEMANTIC_ERROR; + } + double targetSize = 1; + if(target->kind == TypeKindComposite) { + targetSize = target->impl.composite.scale; + } + + + if(inputSize != targetSize) { + //TODO free everything + return SEMANTIC_ERROR; + } + ParentExpression->impl.typecast.targetType = target; ParentExpression->result = target; @@ -1196,7 +1269,69 @@ int createTransmute(Expression* ParentExpression, AST_NODE_PTR currentNode){ } +int createDeref(Expression* ParentExpression, AST_NODE_PTR currentNode) { + assert(currentNode->child_count = 2); + Dereference deref; + deref.nodePtr = currentNode; + deref.index = createExpression(AST_get_node(currentNode,0)); + //index has to be made + if(deref.index == NULL) { + return SEMANTIC_ERROR; + } + Type * indexType = deref.index->result; + //indexType can only be a composite or a primitive + if(indexType->kind != TypeKindComposite && indexType->kind != TypeKindPrimitive) { + //TODO free deref index + return SEMANTIC_ERROR; + } + + //indexType can only be int + if(indexType->kind == TypeKindPrimitive) { + if (indexType->impl.primitive != Int) { + //TODO free deref index + return SEMANTIC_ERROR; + } + } + if(indexType->kind == TypeKindComposite) { + if (indexType->impl.composite.primitive != Int) { + //TODO free deref index + return SEMANTIC_ERROR; + } + } + + deref.variable = createExpression(AST_get_node(currentNode,1)); + + //variable has to be made + if(deref.index == NULL) { + //TODO free deref index + return SEMANTIC_ERROR; + } + //variable can only be a reference + if(deref.variable->result->kind != TypeKindReference) { + //TODO free deref index and variable + return SEMANTIC_ERROR; + } + + ParentExpression->impl.dereference = deref; + ParentExpression->result = deref.variable->result->impl.reference; + return SEMANTIC_OK; +} + +int createAddressOf(Expression* ParentExpression, AST_NODE_PTR currentNode) { + assert(currentNode != NULL); + assert(currentNode->child_count == 1); + + AddressOf address_of; + address_of.node_ptr = currentNode; + address_of.variable = createExpression(AST_get_node(currentNode,0)); + + if (address_of.variable == NULL) { + //TODO free + return SEMANTIC_ERROR; + } + return SEMANTIC_OK; +} Expression *createExpression(AST_NODE_PTR currentNode){ DEBUG("create Expression"); @@ -1308,6 +1443,20 @@ Expression *createExpression(AST_NODE_PTR currentNode){ return NULL; } break; + case AST_Dereference: + expression->kind = ExpressionKindDereference; + if(createDeref(expression, currentNode)) { + //TODO free expression + return NULL; + } + break; + case AST_AddressOf: + expression->kind = ExpressionKindAddressOf; + if(createAddressOf(expression,currentNode)) { + //TODO free space + return NULL; + } + break; default: PANIC("Node is not an expression but from kind: %i", currentNode->kind); break; @@ -1317,7 +1466,47 @@ Expression *createExpression(AST_NODE_PTR currentNode){ DEBUG("successfully created Expression"); return expression; } - + + +bool compareTypes(Type * leftType, Type * rightType) { + if (leftType->kind != rightType->kind) { + return FALSE; + } + if (leftType->kind == TypeKindPrimitive) { + if(leftType->impl.primitive != rightType->impl.primitive) { + return FALSE; + } + return TRUE; + } + if ( leftType->kind == TypeKindComposite) { + CompositeType leftComposite = leftType->impl.composite; + CompositeType rightComposite = leftType->impl.composite; + if(leftComposite.primitive != rightComposite.primitive) { + return FALSE; + } + if(leftComposite.sign != rightComposite.sign) { + return FALSE; + } + if(leftComposite.scale != rightComposite.scale) { + return FALSE; + } + return TRUE; + } + + if(leftType->kind == TypeKindBox) { + if(leftType->impl.box != rightType->impl.box) { + return FALSE; + } + return TRUE; + } + + if(leftType->kind == TypeKindReference) { + bool result = compareTypes(leftType->impl.reference, rightType->impl.reference); + return result; + } + + return FALSE; +} int createAssign(Statement* ParentStatement, AST_NODE_PTR currentNode){ DEBUG("create Assign"); @@ -1335,6 +1524,19 @@ Expression *createExpression(AST_NODE_PTR currentNode){ return SEMANTIC_ERROR; } + Type * varType = NULL; + if(assign.variable->kind == VariableKindDeclaration) { + varType = assign.variable->impl.declaration.type; + }else if(assign.variable->kind == VariableKindDefinition) { + varType = assign.variable->impl.definiton.declaration.type; + }else { + PANIC("the vartype should be a declaration or a definition"); + } + + if(!compareTypes(varType,assign.value->result)) { + //TODO free everything + return SEMANTIC_ERROR; + } ParentStatement->impl.assignment = assign; return SEMANTIC_OK; } @@ -1812,6 +2014,16 @@ int createBox(GHashTable *boxes, AST_NODE_PTR currentNode){ } g_hash_table_insert(boxes, (gpointer)boxName, box); + Type* boxType = malloc(sizeof(Type)); + boxType->nodePtr = currentNode; + boxType->kind = TypeKindBox; + boxType->impl.box = box; + + if(g_hash_table_contains(declaredBoxes, (gpointer)boxName)){ + return SEMANTIC_ERROR; + } + g_hash_table_insert(declaredBoxes, (gpointer)boxName, boxType); + return SEMANTIC_OK; @@ -1898,7 +2110,7 @@ Module *create_set(AST_NODE_PTR currentNode){ for (size_t i = 0; i < currentNode->child_count; i++){ - DEBUG("created Child: %i" ,currentNode->children[i]->kind); + DEBUG("created Child with type: %i" ,currentNode->children[i]->kind); switch(currentNode->children[i]->kind){ case AST_Decl: { @@ -1940,6 +2152,7 @@ Module *create_set(AST_NODE_PTR currentNode){ // TODO: cleanup global memory return NULL; } + DEBUG("created Box successfully"); break; } diff --git a/src/set/types.c b/src/set/types.c index a589952..e82a9ba 100644 --- a/src/set/types.c +++ b/src/set/types.c @@ -54,7 +54,7 @@ void delete_composite([[maybe_unused]] CompositeType *composite) {} void delete_type(Type *type) { switch (type->kind) { case TypeKindBox: - delete_box_type(&type->impl.box); + delete_box_type(type->impl.box); break; case TypeKindReference: delete_type(type->impl.reference); @@ -155,6 +155,8 @@ void delete_expression(Expression *expr) { break; case ExpressionKindVariable: delete_variable(expr->impl.variable); + default: + //TODO free Reference and AddressOf break; } } diff --git a/src/set/types.h b/src/set/types.h index 2b4c180..402f885 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -114,7 +114,7 @@ typedef struct Type_t { union TypeImplementation_t { PrimitiveType primitive; CompositeType composite; - BoxType box; + BoxType* box; ReferenceType reference; } impl; AST_NODE_PTR nodePtr; @@ -281,6 +281,17 @@ typedef struct Variable_t { AST_NODE_PTR nodePtr; } Variable; +typedef struct Dereference_t { + Expression* index; + Expression* variable; + AST_NODE_PTR nodePtr; +}Dereference; + +typedef struct AddressOf_t { + Expression* variable; + AST_NODE_PTR node_ptr; +}AddressOf; + // .------------------------------------------------. // | Casts | // '------------------------------------------------' @@ -412,7 +423,9 @@ typedef enum ExpressionKind_t { ExpressionKindTypeCast, ExpressionKindTransmute, ExpressionKindConstant, - ExpressionKindVariable + ExpressionKindVariable, + ExpressionKindDereference, + ExpressionKindAddressOf, } ExpressionKind; typedef struct Expression_t { @@ -425,6 +438,8 @@ typedef struct Expression_t { Transmute transmute; TypeValue constant; Variable* variable; + Dereference dereference; + AddressOf addressOf; } impl; AST_NODE_PTR nodePtr; } Expression; @@ -543,6 +558,7 @@ typedef struct Module_t { GArray* imports; } Module; + // .------------------------------------------------. // | Cleanup Code | // '------------------------------------------------' From 5eded1aa2065899ffe75b2212167d651ac41b1d0 Mon Sep 17 00:00:00 2001 From: Filleo Date: Sat, 8 Jun 2024 17:33:28 +0200 Subject: [PATCH 28/29] added references, derefs and addressOf to set --- src/set/set.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/set/set.c b/src/set/set.c index 9a3d506..cf07331 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -301,8 +301,8 @@ int addVarToScope(Variable *variable); int createRef(AST_NODE_PTR currentNode, Type** reftype) { assert(currentNode != NULL); - assert(currentNode->child_count = 1); - assert(AST_get_node(currentNode,0)->kind = AST_Type); + assert(currentNode->child_count == 1); + assert(AST_get_node(currentNode,0)->kind == AST_Type); @@ -351,6 +351,7 @@ int createDecl(AST_NODE_PTR currentNode, GArray **variables) { break; case AST_Reference: status = createRef(AST_get_node(currentNode,i), &decl.type); + break; default: PANIC("invalid node type: %ld", currentNode->children[i]->kind); break; @@ -1145,7 +1146,7 @@ int createTransmute(Expression* ParentExpression, AST_NODE_PTR currentNode){ } int createDeref(Expression* ParentExpression, AST_NODE_PTR currentNode) { - assert(currentNode->child_count = 2); + assert(currentNode->child_count == 2); Dereference deref; deref.nodePtr = currentNode; deref.index = createExpression(AST_get_node(currentNode,0)); @@ -1205,6 +1206,14 @@ int createAddressOf(Expression* ParentExpression, AST_NODE_PTR currentNode) { //TODO free return SEMANTIC_ERROR; } + + Type *resultType = malloc(sizeof(Type)); + resultType->nodePtr = currentNode; + resultType->kind = TypeKindReference; + resultType->impl.reference = address_of.variable->result; + + ParentExpression->impl.addressOf = address_of; + ParentExpression->result = resultType; return SEMANTIC_OK; } From c53c3c33f364fbba6005fe1fa3e505ada646fc2f Mon Sep 17 00:00:00 2001 From: Filleo Date: Sat, 8 Jun 2024 17:52:50 +0200 Subject: [PATCH 29/29] solved segfault --- src/set/set.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/set/set.c b/src/set/set.c index cf07331..81f82da 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -307,8 +307,9 @@ int createRef(AST_NODE_PTR currentNode, Type** reftype) { Type * type = malloc(sizeof(Type)); - (*reftype)->kind = TypeKindReference; - (*reftype)->nodePtr = currentNode; + Type * referenceType = malloc(sizeof(Type)); + referenceType->kind = TypeKindReference; + referenceType->nodePtr = currentNode; int signal = get_type_impl(currentNode->children[0],&type); @@ -316,8 +317,8 @@ int createRef(AST_NODE_PTR currentNode, Type** reftype) { //TODO free type return SEMANTIC_ERROR; } - (*reftype)->impl.reference = type; - + referenceType->impl.reference = type; + *reftype = referenceType; return SEMANTIC_OK; }