From eccce505e56e7a182389fab3a1a249379b1a0279 Mon Sep 17 00:00:00 2001 From: Ur Mom Date: Sun, 12 May 2024 22:54:58 +0200 Subject: [PATCH 01/43] -added Type-Cast -added Reinterpret-Cast --- src/yacc/parser.y | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/yacc/parser.y b/src/yacc/parser.y index ddcae10..654e0a8 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -96,6 +96,10 @@ IOqualifyier: KeyIn | KeyOut KeyIn | ; +typecast: expr KeyAs type { DEBUG("Type-Cast"); }; + +reinterpretcast: '(' type ')' expr { DEBUG("Reinterpret-Cast"); }; + paramdecl: type ':' Ident { DEBUG("Param-Declaration"); }; funcall: Ident argumentlist { DEBUG("Function call"); }; @@ -131,7 +135,9 @@ identlist: Ident ',' identlist decl: type ':' identlist; -definition: decl '=' expr { DEBUG("Definition"); }; +definition: decl '=' expr { DEBUG("Definition"); } + | decl '=' typecast { DEBUG("Definition"); }; + | decl '=' reinterpretcast { DEBUG("Definition"); }; assign: Ident '=' expr { DEBUG("Assignment"); }; From bb474d75ad9c1c34a1aac5ae7549304b38f3cc4e Mon Sep 17 00:00:00 2001 From: Filleo Date: Sun, 12 May 2024 23:33:15 +0200 Subject: [PATCH 02/43] start of the syntax tree --- src/ast/ast.c | 1 + src/ast/ast.h | 1 + src/yacc/parser.y | 114 ++++++++++++++++++++++++++++++------------ tests/ast/test_ast.py | 67 +++++++++++++------------ 4 files changed, 117 insertions(+), 66 deletions(-) diff --git a/src/ast/ast.c b/src/ast/ast.c index 233e8da..b36d191 100644 --- a/src/ast/ast.c +++ b/src/ast/ast.c @@ -35,6 +35,7 @@ void AST_init() { INFO("filling lookup table..."); lookup_table[AST_Stmt] = "stmt"; + lookup_table[AST_Module] = "module"; lookup_table[AST_Expr] = "expr"; lookup_table[AST_Add] = "+"; diff --git a/src/ast/ast.h b/src/ast/ast.h index 5129765..abd60bc 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -12,6 +12,7 @@ */ enum AST_SyntaxElement_t { AST_Stmt = 0, + AST_Module, AST_Expr, // Literals AST_Int, diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 36c5931..0fdffd4 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -1,5 +1,6 @@ %{ #include + #include extern int yylineno; int yyerror(char*); @@ -11,6 +12,29 @@ char *string; } +%type expr +%type operation +%type boxaccess +%type boxselfaccess +%type statement +%type statementlist +%type assign +%type oparith +%type decl +%type definition +%type while +%type branch +%type funcall +%type boxcall +%type branchelseifs +%type branchelse +%type branchelseif +%type branchif +%type type +%type identlist +%type storagequalifier + + %token KeyInt %token KeyFloat %token KeySelf @@ -65,7 +89,8 @@ %% program: program programbody - | programbody; + | programbody {AST_NODE_PTR daineMudda = AST_new_node(AST_Module, NULL); + AST_fprint_graphviz(stdout, daineMudda); }; programbody: moduleimport | fundef @@ -76,17 +101,17 @@ programbody: moduleimport -expr: ValFloat - | ValInt - | ValMultistr - | ValStr - | Ident - | operation - | boxaccess - | boxselfaccess; +expr: ValFloat {$$ = AST_new_node{AST_Float, $1};} + | ValInt {$$ = AST_new_node{AST_Int, $1};} + | ValMultistr {$$ = AST_new_node{AST_String, $1};} + | ValStr {$$ = AST_new_node{AST_String, $1};} + | Ident {$$ = AST_new_node{AST_Ident, $1};} + | operation {$$ = $1;} + | boxaccess {$$ = $1;} + | boxselfaccess{$$ = $1;}; exprlist: expr ',' exprlist - | expr; + | expr ; argumentlist: argumentlist '(' exprlist ')' | ; @@ -120,11 +145,11 @@ boxcontent: decl { DEBUG("Box decl Content"); } | definition { DEBUG("Box def Content"); } | fundef { DEBUG("Box fun Content"); }; -boxselfaccess: KeySelf '.' Ident - | KeySelf '.' boxaccess; +boxselfaccess: KeySelf '.' Ident {$$ = AST_new_node(AST_Call, NULL);} + | KeySelf '.' boxaccess {$$ = AST_new_node(AST_Call, NULL);}; -boxaccess: Ident '.' Ident - | Ident '.' boxaccess; +boxaccess: Ident '.' Ident {$$ = AST_new_node(AST_Call, NULL);} + | Ident '.' boxaccess {$$ = AST_new_node(AST_Ident, $1);}; boxcall: boxaccess argumentlist | boxselfaccess argumentlist; @@ -134,33 +159,48 @@ funcall: Ident argumentlist { DEBUG("Function call"); }; moduleimport: KeyImport ValStr { DEBUG("Module-Import"); }; statementlist: statement statementlist - | statement; + | statement {$$ = $1;}; -statement: assign - | decl - | definition - | while - | branch - | funcall - | boxcall; +statement: assign {$$ = $1;} + | decl {$$ = $1;} + | definition {$$ = $1;} + | while {$$ = $1;} + | branch {$$ = $1;} + | funcall {$$ = $1;} + | boxcall{$$ = $1;}; branchif: KeyIf expr '{' statementlist '}' { DEBUG("if"); }; branchelse: KeyElse '{' statementlist '}' { DEBUG("if-else"); }; branchelseif: KeyElse KeyIf expr '{' statementlist '}' { DEBUG("else-if"); }; -branchelseifs: branchelseifs branchelseif - | branchelseif; +branchelseifs: branchelseifs branchelseif {AST_NODE_PTR ifelse = AST_new_node(AST_IfElse, NULL); + AST_push_node(ifelse, $1); + AST_push_node(ifelse, $2); + $$ = ifelse;} + | branchelseif {$$ = $1;}; -branch: branchif branchelseifs - | branchif branchelseifs branchelse; +branch: branchif branchelseifs {AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); + AST_push_node(branch, $1); + AST_push_node(branch, $2); + $$ = branch;} + + | branchif branchelseifs branchelse { AST_NODE_PTR branch = AST_new_node(AST_IF, NULL);}; while: KeyWhile expr '{' statementlist '}' { DEBUG("while"); }; -identlist: Ident ',' identlist - | Ident; +identlist: Ident ',' identlist {AST_push_node($3, $1); + $$ = $3;} + | Ident; -decl: type ':' identlist - | storagequalifier type ':' identlist +decl: type ':' identlist {AST_NODE_PTR decl = AST_new_node(AST_Decl, NULL); + AST_push_node(decl, $1); + AST_push_node(decl, $3); + $$ = decl;} + | storagequalifier 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;} definition: decl '=' expr { DEBUG("Definition"); }; @@ -169,7 +209,12 @@ storagequalifier: KeyGlobal | KeyStatic | KeyLocal; -assign: Ident '=' expr { DEBUG("Assignment"); } +assign: Ident '=' expr { AST_NODE_PTR assign = AST_new_node(AST_Assign, NULL); + AST_NODE_PTR ident = AST_new_node(AST_Ident, $1); + AST_push_node(assign, ident); + AST_push_node(assign, $3); + $$ = assign; + DEBUG("Assignment"); } | boxaccess '=' expr | boxselfaccess '=' expr ; @@ -196,12 +241,15 @@ type: typekind | sign typekind | sign scale typekind; -operation: oparith +operation: oparith {$$ = $1;} | oplogic | opbool | opbit; -oparith: expr '+' expr +oparith: expr '+' expr {AST_NODE_PTR add = AST_new_node{AST_add, NULL}; + AST_push_node(add, $1); + AST_push_node(add, $3); + $$ = add;} | expr '-' expr | expr '*' expr | expr '/' expr diff --git a/tests/ast/test_ast.py b/tests/ast/test_ast.py index 0f9b757..926671d 100644 --- a/tests/ast/test_ast.py +++ b/tests/ast/test_ast.py @@ -29,42 +29,43 @@ def run_check_print_node(): assert p.returncode == 0 assert """0 stmt -1 expr -2 value +1 module +2 expr 3 value 4 value -5 while -6 if -7 else if -8 else -9 condition -10 decl -11 assign -12 def -13 value -14 + -15 - -16 * -17 / -18 & -19 | -20 ^ -21 ! -22 && -23 || -24 ^^ -25 !! -26 == -27 > -28 < -29 cast -30 as -31 value +5 value +6 while +7 if +8 else if +9 else +10 condition +11 decl +12 assign +13 def +14 value +15 + +16 - +17 * +18 / +19 & +20 | +21 ^ +22 ! +23 && +24 || +25 ^^ +26 !! +27 == +28 > +29 < +30 cast +31 as 32 value -33 typedef -34 box -35 fun -36 value +33 value +34 typedef +35 box +36 fun +37 value """ == p.stdout From 0e5736e50c0efe428234bb97d634f356f0431706 Mon Sep 17 00:00:00 2001 From: Filleo Date: Mon, 13 May 2024 11:33:23 +0200 Subject: [PATCH 03/43] AST implementation WIP --- CMakeLists.txt | 2 +- src/ast/ast.c | 6 +++ src/ast/ast.h | 8 +++- src/yacc/parser.y | 109 ++++++++++++++++++++++++++++++------------ tests/ast/test_ast.py | 2 + 5 files changed, 95 insertions(+), 32 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 12e8c66..0ffa084 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,7 @@ set(YACC_SOURCE_FILE ${PROJECT_SOURCE_DIR}/src/yacc/parser.y) set(YACC_GENERATED_SOURCE_FILE ${PROJECT_SOURCE_DIR}/src/yacc/parser.tab.c) add_custom_command(OUTPUT ${YACC_GENERATED_SOURCE_FILE} - COMMAND yacc + COMMAND bison ARGS -Wcounterexamples -d -o ${YACC_GENERATED_SOURCE_FILE} ${YACC_SOURCE_FILE} COMMENT "generate C source file for parser" VERBATIM) diff --git a/src/ast/ast.c b/src/ast/ast.c index b36d191..69d48fb 100644 --- a/src/ast/ast.c +++ b/src/ast/ast.c @@ -73,6 +73,8 @@ void AST_init() { lookup_table[AST_Typecast] = "cast"; lookup_table[AST_Transmute] = "as"; lookup_table[AST_Condition] = "condition"; + lookup_table[AST_List] = "list"; + lookup_table[AST_Type] = "type"; } const char* AST_node_to_string(const struct AST_Node_t* node) { @@ -89,6 +91,10 @@ const char* AST_node_to_string(const struct AST_Node_t* node) { case AST_Macro: case AST_Import: case AST_Call: + case AST_Storage: + case AST_Typekind: + case AST_Sign: + case AST_Scale: string = node->value; break; default: diff --git a/src/ast/ast.h b/src/ast/ast.h index abd60bc..430f284 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -60,7 +60,13 @@ enum AST_SyntaxElement_t { AST_Import, // amount of variants // in this enum - AST_ELEMENT_COUNT + AST_ELEMENT_COUNT, + AST_List, + AST_Storage, + AST_Type, + AST_Typekind, + AST_Sign, + AST_Scale }; /** diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 0fdffd4..ce25bc4 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -33,6 +33,12 @@ %type type %type identlist %type storagequalifier +%type typekind +%type scale +%type sign +%type oplogic +%type opbool +%type opbit %token KeyInt @@ -89,8 +95,8 @@ %% program: program programbody - | programbody {AST_NODE_PTR daineMudda = AST_new_node(AST_Module, NULL); - AST_fprint_graphviz(stdout, daineMudda); }; + | programbody {AST_NODE_PTR program = AST_new_node(AST_Module, NULL); + AST_fprint_graphviz(stdout, program); }; programbody: moduleimport | fundef @@ -190,7 +196,9 @@ while: KeyWhile expr '{' statementlist '}' { DEBUG("while"); }; identlist: Ident ',' identlist {AST_push_node($3, $1); $$ = $3;} - | Ident; + | Ident {AST_NODE_PTR list = AST_new_node(AST_List, NULL); + AST_push_node(list, $1); + $$ = list;}; decl: type ':' identlist {AST_NODE_PTR decl = AST_new_node(AST_Decl, NULL); AST_push_node(decl, $1); @@ -205,9 +213,9 @@ decl: type ':' identlist {AST_NODE_PTR decl = AST_new_node(AST_Decl, NULL); definition: decl '=' expr { DEBUG("Definition"); }; -storagequalifier: KeyGlobal - | KeyStatic - | KeyLocal; +storagequalifier: KeyGlobal {$$ = AST_new_node(AST_Storage, "global");} + | KeyStatic {$$ = AST_new_node(AST_Storage, "static");} + | KeyLocal {$$ = AST_new_node(AST_Storage, "local");}; assign: Ident '=' expr { AST_NODE_PTR assign = AST_new_node(AST_Assign, NULL); AST_NODE_PTR ident = AST_new_node(AST_Ident, $1); @@ -218,41 +226,82 @@ assign: Ident '=' expr { AST_NODE_PTR assign = AST_new_node(AST_Assign, NULL); | boxaccess '=' expr | boxselfaccess '=' expr ; -sign: KeySigned - | KeyUnsigned; +sign: KeySigned {$$ = AST_new_node(AST_Sign, "signed");} + | KeyUnsigned{$$ = AST_new_node(AST_Sign, "unsigned");}; typedef: KeyType type':' Ident; -scale: scale KeyShort - | scale KeyHalf - | scale KeyLong - | scale KeyDouble - | KeyShort - | KeyHalf - | KeyLong - | KeyDouble; +scale: scale KeyShort {AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "short"); + AST_push_node($1, shortnode); + $$ = $1;} + | scale KeyHalf {AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "half"); + AST_push_node($1, shortnode); + $$ = $1;} + | scale KeyLong {AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "long"); + AST_push_node($1, shortnode); + $$ = $1;} + | scale KeyDouble {AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "double"); + AST_push_node($1, shortnode); + $$ = $1;} + | KeyShort {AST_NODE_PTR scale = AST_new_node(AST_List, NULL); + AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "short"); + AST_push_node(scale, shortnode); + $$ = scale;} + | KeyHalf {AST_NODE_PTR scale = AST_new_node(AST_List, NULL); + AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "half"); + AST_push_node(scale, shortnode); + $$ = scale;} + | KeyLong {AST_NODE_PTR scale = AST_new_node(AST_List, NULL); + AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "long"); + AST_push_node(scale, shortnode); + $$ = scale;} + | KeyDouble {AST_NODE_PTR scale = AST_new_node(AST_List, NULL); + AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "double"); + AST_push_node(scale, shortnode); + $$ = scale;}; -typekind: Ident - | KeyInt - | KeyFloat; +typekind: Ident {$$ = AST_new_node(AST_Typekind, $1);} + | KeyInt {$$ = AST_new_node(AST_Typekind, "int");} + | KeyFloat {$$ = AST_new_node(AST_Typekind, "float");}; -type: typekind - | scale typekind - | sign typekind - | sign scale typekind; +type: typekind {AST_NODE_PTR type = AST_new_node(AST_type, NULL); + AST_push_node(type, $1); + $$ = type;} + | scale typekind {AST_NODE_PTR type = AST_new_node(AST_type, NULL); + AST_push_node(type, $1); + AST_push_node(type, $2); + $$ = type;} + | sign typekind {AST_NODE_PTR type = AST_new_node(AST_type, NULL); + AST_push_node(type, $1); + AST_push_node(type, $2); + $$ = type;} + | sign scale typekind {AST_NODE_PTR type = AST_new_node(AST_type, NULL); + AST_push_node(type, $1); + AST_push_node(type, $2); + AST_push_node(type, $3); + $$ = type;}; operation: oparith {$$ = $1;} - | oplogic - | opbool - | opbit; + | oplogic {$$ = $1;} + | opbool {$$ = $1;} + | opbit {$$ = $1;}; -oparith: expr '+' expr {AST_NODE_PTR add = AST_new_node{AST_add, NULL}; +oparith: expr '+' expr {AST_NODE_PTR add = AST_new_node{AST_Add, NULL}; AST_push_node(add, $1); AST_push_node(add, $3); $$ = add;} - | expr '-' expr - | expr '*' expr - | expr '/' expr + | expr '-' expr {AST_NODE_PTR subtract = AST_new_node{AST_Sub, NULL}; + AST_push_node(subtract, $1); + AST_push_node(subtract, $3); + $$ = subtract;} + | expr '*' expr {AST_NODE_PTR mul = AST_new_node{AST_Mul, NULL}; + AST_push_node(mul, $1); + AST_push_node(mul, $3); + $$ = mul;} + | expr '/' expr {AST_NODE_PTR div = AST_new_node{AST_Div, NULL}; + AST_push_node(div, $1); + AST_push_node(div, $3); + $$ = div;} | '-' expr %prec '*'; oplogic: expr OpEquals expr diff --git a/tests/ast/test_ast.py b/tests/ast/test_ast.py index 926671d..91d637a 100644 --- a/tests/ast/test_ast.py +++ b/tests/ast/test_ast.py @@ -66,6 +66,8 @@ def run_check_print_node(): 35 box 36 fun 37 value +38 list +39 storage """ == p.stdout From 9eba9d1437dda4710e51bece656b7ee981a9a4a9 Mon Sep 17 00:00:00 2001 From: Ur Mom Date: Mon, 13 May 2024 13:45:22 +0200 Subject: [PATCH 04/43] fixed shift-reduce conflict --- src/yacc/parser.y | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 78c2948..c9cd81f 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -62,6 +62,7 @@ %left OpEquals OpNot '<' '>' %left OpAnd OpOr OpXor %left OpBitand OpBitor OpBitxor OpBitnot +%nonassoc KeyAs '(' ')' %% program: program programbody @@ -74,8 +75,6 @@ programbody: moduleimport | decl | typedef; - - expr: ValFloat | ValInt | ValMultistr @@ -83,7 +82,9 @@ expr: ValFloat | Ident | operation | boxaccess - | boxselfaccess; + | boxselfaccess + | typecast + | reinterpretcast; exprlist: expr ',' exprlist | expr; @@ -166,10 +167,7 @@ identlist: Ident ',' identlist decl: type ':' identlist | storagequalifier type ':' identlist - -definition: decl '=' expr { DEBUG("Definition"); } - | decl '=' typecast { DEBUG("Definition"); }; - | decl '=' reinterpretcast { DEBUG("Definition"); }; +definition: decl '=' expr { DEBUG("Definition"); }; storagequalifier: KeyGlobal | KeyStatic From 3d3083c8948c4fb148aedd2d887f5184c1fa0373 Mon Sep 17 00:00:00 2001 From: Filleo Date: Mon, 13 May 2024 22:17:43 +0200 Subject: [PATCH 05/43] first functional state of syntax tree --- src/ast/ast.c | 6 +- src/ast/ast.h | 10 +- src/yacc/parser.y | 360 +++++++++++++++++++++++++++++++++------------- 3 files changed, 271 insertions(+), 105 deletions(-) diff --git a/src/ast/ast.c b/src/ast/ast.c index 69d48fb..a554b35 100644 --- a/src/ast/ast.c +++ b/src/ast/ast.c @@ -70,11 +70,15 @@ void AST_init() { lookup_table[AST_Box] = "box"; lookup_table[AST_Fun] = "fun"; + lookup_table[AST_Call] = "funcall"; lookup_table[AST_Typecast] = "cast"; lookup_table[AST_Transmute] = "as"; lookup_table[AST_Condition] = "condition"; lookup_table[AST_List] = "list"; lookup_table[AST_Type] = "type"; + lookup_table[AST_Negate] = "-"; + lookup_table[AST_Parameter] = "parameter"; + lookup_table[AST_ParamDecl] = "parameter-declaration"; } const char* AST_node_to_string(const struct AST_Node_t* node) { @@ -90,11 +94,11 @@ const char* AST_node_to_string(const struct AST_Node_t* node) { case AST_Ident: case AST_Macro: case AST_Import: - case AST_Call: case AST_Storage: case AST_Typekind: case AST_Sign: case AST_Scale: + case AST_Qualifyier: string = node->value; break; default: diff --git a/src/ast/ast.h b/src/ast/ast.h index 430f284..e42e0c9 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -59,14 +59,18 @@ enum AST_SyntaxElement_t { AST_Fun, AST_Import, // amount of variants - // in this enum - AST_ELEMENT_COUNT, + // in this enums AST_List, AST_Storage, AST_Type, AST_Typekind, AST_Sign, - AST_Scale + AST_Scale, + AST_Negate, + AST_Parameter, + AST_Qualifyier, + AST_ParamDecl, + AST_ELEMENT_COUNT }; /** diff --git a/src/yacc/parser.y b/src/yacc/parser.y index ce25bc4..e654eff 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -1,4 +1,4 @@ -%{ +%code requires { #include #include extern int yylineno; @@ -6,39 +6,56 @@ int yyerror(char*); extern int yylex(); -%} + + +} %union { char *string; + AST_NODE_PTR node_ptr; } -%type expr -%type operation -%type boxaccess -%type boxselfaccess -%type statement -%type statementlist -%type assign -%type oparith -%type decl -%type definition -%type while -%type branch -%type funcall -%type boxcall -%type branchelseifs -%type branchelse -%type branchelseif -%type branchif -%type type -%type identlist -%type storagequalifier -%type typekind -%type scale -%type sign -%type oplogic -%type opbool -%type opbit +%type operation +%type boxaccess +%type boxselfaccess +%type statement +%type statementlist +%type assign +%type oparith +%type decl +%type definition +%type while +%type branch +%type funcall +%type boxcall +%type branchelseifs +%type branchelse +%type branchelseif +%type branchif +%type type +%type identlist +%type storagequalifier +%type typekind +%type scale +%type sign +%type expr +%type oplogic +%type opbool +%type opbit +%type moduleimport +%type programbody +%type fundef +%type box +%type typedef +%type exprlist +%type argumentlist +%type paramlist +%type params +%type IOqualifyier +%type paramdecl +%type boxbody +%type boxcontent +%type program %token KeyInt @@ -94,78 +111,172 @@ %left OpBitand OpBitor OpBitxor OpBitnot %% -program: program programbody +program: program programbody {AST_push_node($1, $2); + FILE *file = fopen("test.txt", "w"); + AST_fprint_graphviz(file, $1); + fclose(file);} | programbody {AST_NODE_PTR program = AST_new_node(AST_Module, NULL); - AST_fprint_graphviz(stdout, program); }; + AST_push_node(program, $1); + FILE *file = fopen("test.txt", "w"); + AST_fprint_graphviz(file, program); + fclose(file); }; -programbody: moduleimport - | fundef - | box - | definition - | decl - | typedef; +programbody: moduleimport {$$ = $1;} + | fundef{$$ = $1;} + | box{$$ = $1;} + | definition{$$ = $1;} + | decl{$$ = $1;} + | typedef{$$ = $1;}; -expr: ValFloat {$$ = AST_new_node{AST_Float, $1};} - | ValInt {$$ = AST_new_node{AST_Int, $1};} - | ValMultistr {$$ = AST_new_node{AST_String, $1};} - | ValStr {$$ = AST_new_node{AST_String, $1};} - | Ident {$$ = AST_new_node{AST_Ident, $1};} +expr: ValFloat {$$ = AST_new_node(AST_Float, $1);} + | ValInt {$$ = AST_new_node(AST_Int, $1);} + | ValMultistr {$$ = AST_new_node(AST_String, $1);} + | ValStr {$$ = AST_new_node(AST_String, $1);} + | Ident {$$ = AST_new_node(AST_Ident, $1);} | operation {$$ = $1;} | boxaccess {$$ = $1;} | boxselfaccess{$$ = $1;}; -exprlist: expr ',' exprlist - | expr ; +exprlist: expr ',' exprlist {AST_push_node($3, $1); + $$ = $3;} + | expr {AST_NODE_PTR list = AST_new_node(AST_List, NULL); + AST_push_node(list, $1); + $$ = list;}; -argumentlist: argumentlist '(' exprlist ')' - | ; +argumentlist: argumentlist '(' exprlist ')' {AST_push_node($1, $3); + $$ = $1;} + | '(' exprlist ')'{AST_NODE_PTR list = AST_new_node(AST_List, NULL); + AST_push_node(list, $2); + $$ = list;}; -fundef: KeyFun Ident paramlist '{' statementlist'}' { DEBUG("Function");}; +fundef: KeyFun Ident paramlist '{' statementlist'}' {AST_NODE_PTR fun = AST_new_node(AST_Fun, NULL); + AST_NODE_PTR ident = AST_new_node(AST_Ident, $2); + AST_push_node(fun, ident); + AST_push_node(fun, $3); + AST_push_node(fun, $5); + $$ = fun; + DEBUG("Function");}; -paramlist: paramlist '(' params ')' - | paramlist '(' ')' - | '(' params ')' - | '(' ')'; +paramlist: paramlist '(' params ')' {AST_push_node($1, $3); + $$ = $1;} + | paramlist '(' ')'{$$ = $1;} + | '(' params ')' {AST_NODE_PTR list = AST_new_node(AST_List, NULL); + AST_push_node(list, $2);} + | '(' ')' {$$ = AST_new_node(AST_List, NULL);}; -params: IOqualifyier paramdecl ',' params - | IOqualifyier paramdecl; +params: IOqualifyier paramdecl ',' params {AST_NODE_PTR parameter = AST_new_node(AST_Parameter, NULL); + AST_push_node(parameter, $1); + AST_push_node(parameter, $2); + AST_push_node($4, parameter); + $$ = $4;} + | IOqualifyier paramdecl {AST_NODE_PTR list = AST_new_node(AST_List, NULL); + AST_NODE_PTR parameter = AST_new_node(AST_Parameter, NULL); + AST_push_node(parameter, $1); + AST_push_node(parameter, $2); + AST_push_node(list, parameter); + $$ = list;}; -IOqualifyier: KeyIn - | KeyOut - | KeyIn KeyOut - | KeyOut KeyIn - | ; +IOqualifyier: KeyIn { AST_NODE_PTR in = AST_new_node(AST_Qualifyier, "in"); + AST_NODE_PTR list = AST_new_node(AST_List, NULL); + AST_push_node(list, in); + $$ = list;} + | KeyOut{ AST_NODE_PTR out = AST_new_node(AST_Qualifyier, "out"); + AST_NODE_PTR list = AST_new_node(AST_List, NULL); + AST_push_node(list, out); + $$ = list;} + | KeyIn KeyOut{ AST_NODE_PTR in = AST_new_node(AST_Qualifyier, "in"); + AST_NODE_PTR out = AST_new_node(AST_Qualifyier, "out"); + AST_NODE_PTR list = AST_new_node(AST_List, NULL); + AST_push_node(list, in); + AST_push_node(list, out); + $$ = list;} + | KeyOut KeyIn{ AST_NODE_PTR in = AST_new_node(AST_Qualifyier, "in"); + AST_NODE_PTR out = AST_new_node(AST_Qualifyier, "out"); + AST_NODE_PTR list = AST_new_node(AST_List, NULL); + AST_push_node(list, in); + AST_push_node(list, out); + $$ = list;} + | {$$ = AST_new_node(AST_List, NULL);}; -paramdecl: type ':' Ident { DEBUG("Param-Declaration"); }; +paramdecl: type ':' Ident { AST_NODE_PTR paramdecl = AST_new_node(AST_ParamDecl, NULL); + AST_push_node(paramdecl, $1); + AST_NODE_PTR ident = AST_new_node(AST_Ident, $3); + AST_push_node(paramdecl, ident); + $$ = paramdecl; + DEBUG("Param-Declaration"); }; -box: KeyType KeyBox ':' Ident '{' boxbody '}' { DEBUG("Box"); } - | KeyType KeyBox ':' Ident '{' '}'; +box: KeyType KeyBox ':' Ident '{' boxbody '}' {AST_NODE_PTR box = AST_new_node(AST_Box, NULL); + AST_NODE_PTR ident = AST_new_node(AST_Ident, $4); + AST_push_node(box, ident); + AST_push_node(box, $6); + $$ = box; + DEBUG("Box"); } + | KeyType KeyBox ':' Ident '{' '}' {AST_NODE_PTR box = AST_new_node(AST_Box, NULL); + AST_NODE_PTR ident = AST_new_node(AST_Ident, $4); + AST_push_node(box, ident); + $$ = box;}; -boxbody: boxbody boxcontent - | boxcontent; +boxbody: boxbody boxcontent {AST_push_node($1, $2); + $$ = $1;} + | boxcontent {AST_NODE_PTR list = AST_new_node(AST_List, NULL); + AST_push_node(list, $1); + $$ = list;}; -boxcontent: decl { DEBUG("Box decl Content"); } - | definition { DEBUG("Box def Content"); } - | fundef { DEBUG("Box fun Content"); }; +boxcontent: decl { $$ = $1;DEBUG("Box decl Content"); } + | definition { $$ = $1;DEBUG("Box def Content"); } + | fundef { $$ = $1;DEBUG("Box fun Content"); }; -boxselfaccess: KeySelf '.' Ident {$$ = AST_new_node(AST_Call, NULL);} - | KeySelf '.' boxaccess {$$ = AST_new_node(AST_Call, NULL);}; +boxselfaccess: KeySelf '.' Ident {AST_NODE_PTR boxselfaccess = AST_new_node(AST_List, NULL); + AST_NODE_PTR self = AST_new_node(AST_Ident, "self"); + AST_push_node(boxselfaccess, self); + AST_NODE_PTR identlist = AST_new_node(AST_List, NULL); + AST_NODE_PTR ident = AST_new_node(AST_Ident, $3); + AST_push_node(identlist,ident); + AST_push_node(boxselfaccess, identlist); + $$ = boxselfaccess;} + | KeySelf '.' boxaccess {AST_NODE_PTR boxselfaccess = AST_new_node(AST_List, NULL); + AST_NODE_PTR self = AST_new_node(AST_Ident, "self"); + AST_push_node(boxselfaccess, self); + AST_push_node(boxselfaccess, $3); + $$ = boxselfaccess;}; -boxaccess: Ident '.' Ident {$$ = AST_new_node(AST_Call, NULL);} - | Ident '.' boxaccess {$$ = AST_new_node(AST_Ident, $1);}; +boxaccess: Ident '.' Ident {AST_NODE_PTR identlist = AST_new_node(AST_List, NULL); + AST_NODE_PTR ident1 = AST_new_node(AST_Ident, $1); + AST_NODE_PTR ident2 = AST_new_node(AST_Ident, $3); + AST_push_node(identlist,ident1); + AST_push_node(identlist,ident2); + $$ = identlist;} + | Ident '.' boxaccess {AST_NODE_PTR ident = AST_new_node(AST_Ident, $1); + AST_push_node($3,ident); + $$ = $3;}; -boxcall: boxaccess argumentlist - | boxselfaccess argumentlist; +boxcall: boxaccess argumentlist {AST_NODE_PTR boxcall = AST_new_node(AST_Call, NULL); + AST_push_node(boxcall, $1); + AST_push_node(boxcall, $2); + $$ = boxcall;} + | boxselfaccess argumentlist {AST_NODE_PTR boxcall = AST_new_node(AST_Call, NULL); + AST_push_node(boxcall, $1); + AST_push_node(boxcall, $2); + $$ = boxcall;}; -funcall: Ident argumentlist { DEBUG("Function call"); }; +funcall: Ident argumentlist {AST_NODE_PTR funcall = AST_new_node(AST_Call, NULL); + AST_NODE_PTR ident = AST_new_node(AST_Ident, $1); + AST_push_node(funcall, ident); + AST_push_node(funcall, $2); + $$ = funcall; + DEBUG("Function call"); }; -moduleimport: KeyImport ValStr { DEBUG("Module-Import"); }; +moduleimport: KeyImport ValStr {$$ = AST_new_node(AST_Import, $2); + DEBUG("Module-Import"); }; -statementlist: statement statementlist - | statement {$$ = $1;}; +statementlist: statementlist statement {AST_push_node($1, $2); + $$ = $1;} + | statement {AST_NODE_PTR list = AST_new_node(AST_List, NULL); + AST_push_node(list, $1); + $$ = list;}; statement: assign {$$ = $1;} | decl {$$ = $1;} @@ -190,14 +301,20 @@ branch: branchif branchelseifs {AST_NODE_PTR branch = AST_new_node(AST_Stmt, NUL AST_push_node(branch, $2); $$ = branch;} - | branchif branchelseifs branchelse { AST_NODE_PTR branch = AST_new_node(AST_IF, NULL);}; + | branchif branchelseifs branchelse { AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); + AST_push_node(branch, $1); + AST_push_node(branch, $2); + AST_push_node(branch, $3); + $$ = branch;}; while: KeyWhile expr '{' statementlist '}' { DEBUG("while"); }; -identlist: Ident ',' identlist {AST_push_node($3, $1); +identlist: Ident ',' identlist {AST_NODE_PTR ident = AST_new_node(AST_Ident, $1); + AST_push_node($3, ident); $$ = $3;} | Ident {AST_NODE_PTR list = AST_new_node(AST_List, NULL); - AST_push_node(list, $1); + AST_NODE_PTR ident = AST_new_node(AST_Ident, $1); + AST_push_node(list, ident); $$ = list;}; decl: type ':' identlist {AST_NODE_PTR decl = AST_new_node(AST_Decl, NULL); @@ -211,7 +328,11 @@ decl: type ':' identlist {AST_NODE_PTR decl = AST_new_node(AST_Decl, NULL); $$ = decl;} -definition: decl '=' expr { DEBUG("Definition"); }; +definition: decl '=' expr { AST_NODE_PTR def = AST_new_node(AST_Def, NULL); + AST_push_node(def, $1); + AST_push_node(def, $3); + $$ = def; + DEBUG("Definition"); }; storagequalifier: KeyGlobal {$$ = AST_new_node(AST_Storage, "global");} | KeyStatic {$$ = AST_new_node(AST_Storage, "static");} @@ -229,7 +350,11 @@ assign: Ident '=' expr { AST_NODE_PTR assign = AST_new_node(AST_Assign, NULL); sign: KeySigned {$$ = AST_new_node(AST_Sign, "signed");} | KeyUnsigned{$$ = AST_new_node(AST_Sign, "unsigned");}; -typedef: KeyType type':' Ident; +typedef: KeyType type':' Ident {AST_NODE_PTR typeDef = AST_new_node(AST_Typedef, NULL); + AST_push_node(typeDef, $2); + AST_NODE_PTR ident = AST_new_node(AST_Ident, $4); + AST_push_node(typeDef, ident); + $$ = typeDef;}; scale: scale KeyShort {AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "short"); AST_push_node($1, shortnode); @@ -264,18 +389,18 @@ typekind: Ident {$$ = AST_new_node(AST_Typekind, $1);} | KeyInt {$$ = AST_new_node(AST_Typekind, "int");} | KeyFloat {$$ = AST_new_node(AST_Typekind, "float");}; -type: typekind {AST_NODE_PTR type = AST_new_node(AST_type, NULL); +type: typekind {AST_NODE_PTR type = AST_new_node(AST_Type, NULL); AST_push_node(type, $1); $$ = type;} - | scale typekind {AST_NODE_PTR type = AST_new_node(AST_type, NULL); + | scale typekind {AST_NODE_PTR type = AST_new_node(AST_Type, NULL); AST_push_node(type, $1); AST_push_node(type, $2); $$ = type;} - | sign typekind {AST_NODE_PTR type = AST_new_node(AST_type, NULL); + | sign typekind {AST_NODE_PTR type = AST_new_node(AST_Type, NULL); AST_push_node(type, $1); AST_push_node(type, $2); $$ = type;} - | sign scale typekind {AST_NODE_PTR type = AST_new_node(AST_type, NULL); + | sign scale typekind {AST_NODE_PTR type = AST_new_node(AST_Type, NULL); AST_push_node(type, $1); AST_push_node(type, $2); AST_push_node(type, $3); @@ -286,37 +411,70 @@ operation: oparith {$$ = $1;} | opbool {$$ = $1;} | opbit {$$ = $1;}; -oparith: expr '+' expr {AST_NODE_PTR add = AST_new_node{AST_Add, NULL}; +oparith: expr '+' expr {AST_NODE_PTR add = AST_new_node(AST_Add, NULL); AST_push_node(add, $1); AST_push_node(add, $3); $$ = add;} - | expr '-' expr {AST_NODE_PTR subtract = AST_new_node{AST_Sub, NULL}; + | expr '-' expr {AST_NODE_PTR subtract = AST_new_node(AST_Sub, NULL); AST_push_node(subtract, $1); AST_push_node(subtract, $3); $$ = subtract;} - | expr '*' expr {AST_NODE_PTR mul = AST_new_node{AST_Mul, NULL}; + | expr '*' expr {AST_NODE_PTR mul = AST_new_node(AST_Mul, NULL); AST_push_node(mul, $1); AST_push_node(mul, $3); $$ = mul;} - | expr '/' expr {AST_NODE_PTR div = AST_new_node{AST_Div, NULL}; + | expr '/' expr {AST_NODE_PTR div = AST_new_node(AST_Div, NULL); AST_push_node(div, $1); AST_push_node(div, $3); $$ = div;} - | '-' expr %prec '*'; + | '-' expr %prec '*'{AST_NODE_PTR negator = AST_new_node(AST_Negate, NULL); + AST_push_node(negator, $2); + $$ = negator;}; -oplogic: expr OpEquals expr - | expr '<' expr - | expr '>' expr; +oplogic: expr OpEquals expr {AST_NODE_PTR equals = AST_new_node(AST_Eq, NULL); + AST_push_node(equals, $1); + AST_push_node(equals, $3); + $$ = equals;} + | expr '<' expr {AST_NODE_PTR less = AST_new_node(AST_Less, NULL); + AST_push_node(less, $1); + AST_push_node(less, $3); + $$ = less;} + | expr '>' expr{AST_NODE_PTR greater = AST_new_node(AST_Greater, NULL); + AST_push_node(greater, $1); + AST_push_node(greater, $3); + $$ = greater;}; -opbool: expr OpAnd expr - | expr OpOr expr - | expr OpXor expr - | OpNot expr %prec OpAnd; +opbool: expr OpAnd expr {AST_NODE_PTR and = AST_new_node(AST_BoolAnd, NULL); + AST_push_node(and, $1); + AST_push_node(and, $3); + $$ = and;} + | expr OpOr expr{AST_NODE_PTR or = AST_new_node(AST_BoolOr, NULL); + AST_push_node(or, $1); + AST_push_node(or, $3); + $$ = or;} + | expr OpXor expr{AST_NODE_PTR xor = AST_new_node(AST_BoolXor, NULL); + AST_push_node(xor, $1); + AST_push_node(xor, $3); + $$ = xor;} + | OpNot expr %prec OpAnd{AST_NODE_PTR not = AST_new_node(AST_BoolNot, NULL); + AST_push_node(not, $2); + $$ = not;}; -opbit: expr OpBitand expr - | expr OpBitor expr - | expr OpBitxor expr - | OpBitnot expr %prec OpBitand; +opbit: expr OpBitand expr {AST_NODE_PTR and = AST_new_node(AST_BitAnd, NULL); + AST_push_node(and, $1); + AST_push_node(and, $3); + $$ = and;} + | expr OpBitor expr{AST_NODE_PTR or = AST_new_node(AST_BitOr, NULL); + AST_push_node(or, $1); + AST_push_node(or, $3); + $$ = or;} + | expr OpBitxor expr{AST_NODE_PTR xor = AST_new_node(AST_BitXor, NULL); + AST_push_node(xor, $1); + AST_push_node(xor, $3); + $$ = xor;} + | OpBitnot expr %prec OpBitand{AST_NODE_PTR not = AST_new_node(AST_BitNot, NULL); + AST_push_node(not, $2); + $$ = not;}; %% int yyerror(char *s) { From b3ad82cc49cc92b7d97b57a086894d9f7633d1be Mon Sep 17 00:00:00 2001 From: Filleo Date: Tue, 14 May 2024 14:03:45 +0200 Subject: [PATCH 06/43] moved root node to main moved output code to main removed '"' from string literals --- src/lex/lexer.l | 12 ++++++++++-- src/main.c | 5 +++++ src/yacc/parser.y | 13 +++---------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/lex/lexer.l b/src/lex/lexer.l index c9bf739..2307af7 100644 --- a/src/lex/lexer.l +++ b/src/lex/lexer.l @@ -79,7 +79,15 @@ [0-9]+ {DEBUG("\"%s\" tokenized with \'ValInt\'", yytext); yylval.string = strdup(yytext); return(ValInt); }; [0-9]*\.[0-9]+ {DEBUG("\"%s\" tokenized with \'ValFloat\'", yytext); yylval.string = strdup(yytext); return(ValFloat);}; [a-zA-Z_0-9]+ {DEBUG("\"%s\" tokenized with \'Ident\'", yytext); yylval.string = strdup(yytext); return(Ident); }; -\"([^\"\n])*\" {DEBUG("\"%s\" tokenized with \'ValStr\'", yytext); yylval.string = strdup(yytext); return(ValStr);}; -\"\"\"([^\"\n]|\\\n)*\"\"\" {DEBUG("\"%s\" tokenized with \'ValMultistr\'", yytext); yylval.string = strdup(yytext); return(ValMultistr);}; +\"([^\"\n])*\" { + yytext = yytext +1; + yytext[yyleng - 2] = 0; + + DEBUG("\"%s\" tokenized with \'ValStr\'", yytext); yylval.string = strdup(yytext); return(ValStr);}; +\"\"\"([^\"\n]|\\\n)*\"\"\" { + yytext = yytext +3; + yytext[yyleng - 4] = 0; + + DEBUG("\"%s\" tokenized with \'ValMultistr\'", yytext); yylval.string = strdup(yytext); return(ValMultistr);}; .; %% diff --git a/src/main.c b/src/main.c index 03ab6b9..fab7659 100644 --- a/src/main.c +++ b/src/main.c @@ -6,6 +6,7 @@ #define LOG_LEVEL LOG_LEVEL_DEBUG extern FILE *yyin; +AST_NODE_PTR root; /** * @brief Log a debug message to inform about beginning exit procedures @@ -65,7 +66,11 @@ int main(int argc, char *argv[]) { } yyin = file; + root = AST_new_node(AST_Module, NULL); yyparse(); + FILE *output = fopen("test.txt", "w"); + AST_fprint_graphviz(file, root); + fclose(output); return 0; } diff --git a/src/yacc/parser.y b/src/yacc/parser.y index e654eff..89c4433 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -6,7 +6,7 @@ int yyerror(char*); extern int yylex(); - + extern AST_NODE_PTR root; } @@ -111,15 +111,8 @@ %left OpBitand OpBitor OpBitxor OpBitnot %% -program: program programbody {AST_push_node($1, $2); - FILE *file = fopen("test.txt", "w"); - AST_fprint_graphviz(file, $1); - fclose(file);} - | programbody {AST_NODE_PTR program = AST_new_node(AST_Module, NULL); - AST_push_node(program, $1); - FILE *file = fopen("test.txt", "w"); - AST_fprint_graphviz(file, program); - fclose(file); }; +program: program programbody {AST_push_node(root, $2);} + | programbody {AST_push_node(root, $1);}; programbody: moduleimport {$$ = $1;} | fundef{$$ = $1;} From 8c063d701622e1a4e1b0beff44220579526f3343 Mon Sep 17 00:00:00 2001 From: Filleo Date: Tue, 14 May 2024 14:57:15 +0200 Subject: [PATCH 07/43] changed little error in main --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index fab7659..0591208 100644 --- a/src/main.c +++ b/src/main.c @@ -70,7 +70,7 @@ int main(int argc, char *argv[]) { yyparse(); FILE *output = fopen("test.txt", "w"); - AST_fprint_graphviz(file, root); + AST_fprint_graphviz(output, root); fclose(output); return 0; } From a14faeeee7d080266fdd1cfd64e46d4d6ff2b0a2 Mon Sep 17 00:00:00 2001 From: Filleo Date: Tue, 14 May 2024 15:30:13 +0200 Subject: [PATCH 08/43] added specific lists solved bug in Funcall --- src/ast/ast.c | 5 +++++ src/ast/ast.h | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/ast/ast.c b/src/ast/ast.c index a554b35..742bb73 100644 --- a/src/ast/ast.c +++ b/src/ast/ast.c @@ -75,6 +75,11 @@ void AST_init() { lookup_table[AST_Transmute] = "as"; lookup_table[AST_Condition] = "condition"; lookup_table[AST_List] = "list"; + lookup_table[AST_ExprList] = "expr list"; + lookup_table[AST_ArgList] = "arg list"; + lookup_table[AST_ParamList] = "param list"; + lookup_table[AST_StmtList] = "stmt list"; + lookup_table[AST_IdentList] = "ident list"; lookup_table[AST_Type] = "type"; lookup_table[AST_Negate] = "-"; lookup_table[AST_Parameter] = "parameter"; diff --git a/src/ast/ast.h b/src/ast/ast.h index e42e0c9..ff8297b 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -61,6 +61,11 @@ enum AST_SyntaxElement_t { // amount of variants // in this enums AST_List, + AST_ExprList, + AST_ArgList, + AST_ParamList, + AST_StmtList, + AST_IdentList, AST_Storage, AST_Type, AST_Typekind, From 1055aa0f73371cbc4cbc91683cb531cc391063b3 Mon Sep 17 00:00:00 2001 From: Filleo Date: Tue, 14 May 2024 17:01:42 +0200 Subject: [PATCH 09/43] add identlist --- src/yacc/parser.y | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 89c4433..1084112 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -134,15 +134,18 @@ expr: ValFloat {$$ = AST_new_node(AST_Float, $1);} exprlist: expr ',' exprlist {AST_push_node($3, $1); $$ = $3;} - | expr {AST_NODE_PTR list = AST_new_node(AST_List, NULL); + | expr {AST_NODE_PTR list = AST_new_node(AST_ExprList, NULL); AST_push_node(list, $1); $$ = list;}; argumentlist: argumentlist '(' exprlist ')' {AST_push_node($1, $3); $$ = $1;} - | '(' exprlist ')'{AST_NODE_PTR list = AST_new_node(AST_List, NULL); + | '(' exprlist ')'{AST_NODE_PTR list = AST_new_node(AST_ArgList, NULL); AST_push_node(list, $2); - $$ = list;}; + $$ = list;} + | argumentlist '(' ')' + | '(' ')'{AST_NODE_PTR list = AST_new_node(AST_ArgList, NULL); + $$ = list;}; fundef: KeyFun Ident paramlist '{' statementlist'}' {AST_NODE_PTR fun = AST_new_node(AST_Fun, NULL); @@ -158,14 +161,14 @@ paramlist: paramlist '(' params ')' {AST_push_node($1, $3); | paramlist '(' ')'{$$ = $1;} | '(' params ')' {AST_NODE_PTR list = AST_new_node(AST_List, NULL); AST_push_node(list, $2);} - | '(' ')' {$$ = AST_new_node(AST_List, NULL);}; + | '(' ')' {$$ = AST_new_node(AST_ParamList, NULL);}; params: IOqualifyier paramdecl ',' params {AST_NODE_PTR parameter = AST_new_node(AST_Parameter, NULL); AST_push_node(parameter, $1); AST_push_node(parameter, $2); AST_push_node($4, parameter); $$ = $4;} - | IOqualifyier paramdecl {AST_NODE_PTR list = AST_new_node(AST_List, NULL); + | IOqualifyier paramdecl {AST_NODE_PTR list = AST_new_node(AST_ParamList, NULL); AST_NODE_PTR parameter = AST_new_node(AST_Parameter, NULL); AST_push_node(parameter, $1); AST_push_node(parameter, $2); @@ -225,7 +228,7 @@ boxcontent: decl { $$ = $1;DEBUG("Box decl Content"); } boxselfaccess: KeySelf '.' Ident {AST_NODE_PTR boxselfaccess = AST_new_node(AST_List, NULL); AST_NODE_PTR self = AST_new_node(AST_Ident, "self"); AST_push_node(boxselfaccess, self); - AST_NODE_PTR identlist = AST_new_node(AST_List, NULL); + AST_NODE_PTR identlist = AST_new_node(AST_IdentList, NULL); AST_NODE_PTR ident = AST_new_node(AST_Ident, $3); AST_push_node(identlist,ident); AST_push_node(boxselfaccess, identlist); @@ -236,7 +239,7 @@ boxselfaccess: KeySelf '.' Ident {AST_NODE_PTR boxselfaccess = AST_new_node(AST_ AST_push_node(boxselfaccess, $3); $$ = boxselfaccess;}; -boxaccess: Ident '.' Ident {AST_NODE_PTR identlist = AST_new_node(AST_List, NULL); +boxaccess: Ident '.' Ident {AST_NODE_PTR identlist = AST_new_node(AST_IdentList, NULL); AST_NODE_PTR ident1 = AST_new_node(AST_Ident, $1); AST_NODE_PTR ident2 = AST_new_node(AST_Ident, $3); AST_push_node(identlist,ident1); @@ -267,7 +270,7 @@ moduleimport: KeyImport ValStr {$$ = AST_new_node(AST_Import, $2); statementlist: statementlist statement {AST_push_node($1, $2); $$ = $1;} - | statement {AST_NODE_PTR list = AST_new_node(AST_List, NULL); + | statement {AST_NODE_PTR list = AST_new_node(AST_StmtList, NULL); AST_push_node(list, $1); $$ = list;}; @@ -305,7 +308,7 @@ while: KeyWhile expr '{' statementlist '}' { DEBUG("while"); }; identlist: Ident ',' identlist {AST_NODE_PTR ident = AST_new_node(AST_Ident, $1); AST_push_node($3, ident); $$ = $3;} - | Ident {AST_NODE_PTR list = AST_new_node(AST_List, NULL); + | Ident {AST_NODE_PTR list = AST_new_node(AST_IdentList, NULL); AST_NODE_PTR ident = AST_new_node(AST_Ident, $1); AST_push_node(list, ident); $$ = list;}; From 3ea179b4a9a60631a366701a4a8647a77847bae8 Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 14 May 2024 19:08:42 +0200 Subject: [PATCH 10/43] added precedence for +,-,*,/ --- src/yacc/parser.y | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 1084112..9224fb4 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -105,7 +105,8 @@ /* Operator associativity */ %right '=' -%left '+' '-' '*' '/' +%left '+' '-' +%left '*' '/' %left OpEquals OpNot '<' '>' %left OpAnd OpOr OpXor %left OpBitand OpBitor OpBitxor OpBitnot From 32b964444a32db659f1fc51f5c6154092f66b2e7 Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 14 May 2024 19:20:58 +0200 Subject: [PATCH 11/43] added C like precedence for operators --- src/yacc/parser.y | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 9224fb4..ee219e9 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -104,12 +104,19 @@ %token FunExtsupport /* Operator associativity */ +/* Operators at lower line number have lower precedence */ +/* Operators in same line have same precedence */ %right '=' +%left OpOr +%left OpXor +%left OpAnd +%left OpBitor +%left OpBitxor +%left OpBitand +%left OpEquals '<' '>' %left '+' '-' %left '*' '/' -%left OpEquals OpNot '<' '>' -%left OpAnd OpOr OpXor -%left OpBitand OpBitor OpBitxor OpBitnot +%left OpNot OpBitnot %% program: program programbody {AST_push_node(root, $2);} From c24a430fd28bd6267130ccff7d555ff462c08a61 Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 14 May 2024 20:23:29 +0200 Subject: [PATCH 12/43] fixed if statement --- src/yacc/parser.y | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/yacc/parser.y b/src/yacc/parser.y index ee219e9..aef70f3 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -290,26 +290,40 @@ statement: assign {$$ = $1;} | funcall {$$ = $1;} | boxcall{$$ = $1;}; -branchif: KeyIf expr '{' statementlist '}' { DEBUG("if"); }; -branchelse: KeyElse '{' statementlist '}' { DEBUG("if-else"); }; -branchelseif: KeyElse KeyIf expr '{' statementlist '}' { DEBUG("else-if"); }; +branchif: KeyIf expr '{' statementlist '}' { AST_NODE_PTR branch = AST_new_node(AST_If, NULL); + AST_push_node(branch, $2); + AST_push_node(branch, $4); + $$ = branch; }; -branchelseifs: branchelseifs branchelseif {AST_NODE_PTR ifelse = AST_new_node(AST_IfElse, NULL); - AST_push_node(ifelse, $1); - AST_push_node(ifelse, $2); - $$ = ifelse;} - | branchelseif {$$ = $1;}; +branchelse: KeyElse '{' statementlist '}' { AST_NODE_PTR branch = AST_new_node(AST_Else, NULL); + AST_push_node(branch, $3); + $$ = branch; }; -branch: branchif branchelseifs {AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); +branchelseif: KeyElse KeyIf expr '{' statementlist '}' { AST_NODE_PTR branch = AST_new_node(AST_IfElse, NULL); + AST_push_node(branch, $3); + AST_push_node(branch, $5); + $$ = branch; }; + +branchelseifs: branchelseifs branchelseif { AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); + AST_push_node(branch, $1); + AST_push_node(branch, $2); + $$ = branch; } + | branchelseif { $$ = $1; }; + +branch: branchif { $$ = $1; } + | branchif branchelseifs { AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); AST_push_node(branch, $1); AST_push_node(branch, $2); - $$ = branch;} - - | branchif branchelseifs branchelse { AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); - AST_push_node(branch, $1); - AST_push_node(branch, $2); - AST_push_node(branch, $3); - $$ = branch;}; + $$ = branch; } + | branchif branchelseifs branchelse { AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); + AST_push_node(branch, $1); + AST_push_node(branch, $2); + AST_push_node(branch, $3); + $$ = branch; } + | branchif branchelse { AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); + AST_push_node(branch, $1); + AST_push_node(branch, $2); + $$ = branch; }; while: KeyWhile expr '{' statementlist '}' { DEBUG("while"); }; From f11ade2ef20a7c07bd3d5b8c9194df1cc686f1af Mon Sep 17 00:00:00 2001 From: Filleo Date: Wed, 15 May 2024 10:29:47 +0200 Subject: [PATCH 13/43] changed If else branches, so that the whole branch is under one stmt node --- src/yacc/parser.y | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/yacc/parser.y b/src/yacc/parser.y index aef70f3..db70070 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -25,10 +25,10 @@ %type decl %type definition %type while -%type branch %type funcall %type boxcall -%type branchelseifs +%type branchhalf +%type branchfull %type branchelse %type branchelseif %type branchif @@ -286,7 +286,7 @@ statement: assign {$$ = $1;} | decl {$$ = $1;} | definition {$$ = $1;} | while {$$ = $1;} - | branch {$$ = $1;} + | branchfull {$$ = $1;} | funcall {$$ = $1;} | boxcall{$$ = $1;}; @@ -304,26 +304,15 @@ branchelseif: KeyElse KeyIf expr '{' statementlist '}' { AST_NODE_PTR branch = A AST_push_node(branch, $5); $$ = branch; }; -branchelseifs: branchelseifs branchelseif { AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); - AST_push_node(branch, $1); - AST_push_node(branch, $2); - $$ = branch; } - | branchelseif { $$ = $1; }; +branchfull: branchhalf { $$ = $1;}; + |branchhalf branchelse { AST_push_node($1 , $2); + $$ = $1; } +branchhalf: branchif { AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); + AST_push_node(branch, $1); + $$ = branch; } + | branchhalf branchelseif { AST_push_node($1 , $2); + $$ = $1; } -branch: branchif { $$ = $1; } - | branchif branchelseifs { AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); - AST_push_node(branch, $1); - AST_push_node(branch, $2); - $$ = branch; } - | branchif branchelseifs branchelse { AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); - AST_push_node(branch, $1); - AST_push_node(branch, $2); - AST_push_node(branch, $3); - $$ = branch; } - | branchif branchelse { AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); - AST_push_node(branch, $1); - AST_push_node(branch, $2); - $$ = branch; }; while: KeyWhile expr '{' statementlist '}' { DEBUG("while"); }; From ac7ceaab9b489f9ee93d2b9bf648f902833bab58 Mon Sep 17 00:00:00 2001 From: Filleo Date: Wed, 15 May 2024 10:41:08 +0200 Subject: [PATCH 14/43] added while to the syntax tree --- src/yacc/parser.y | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/yacc/parser.y b/src/yacc/parser.y index db70070..811f222 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -314,7 +314,10 @@ branchhalf: branchif { AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); $$ = $1; } -while: KeyWhile expr '{' statementlist '}' { DEBUG("while"); }; +while: KeyWhile expr '{' statementlist '}' {AST_NODE_PTR whilenode = AST_new_node(AST_While, NULL); + AST_push_node(whilenode, $2); + AST_push_node(whilenode, $4); + $$ = whilenode;}; identlist: Ident ',' identlist {AST_NODE_PTR ident = AST_new_node(AST_Ident, $1); AST_push_node($3, ident); From 7da3c9151d669a830a67c91227cfa516412ec635 Mon Sep 17 00:00:00 2001 From: Ur Mom Date: Wed, 15 May 2024 15:50:26 +0200 Subject: [PATCH 15/43] fixed shift reduce conflicts in typecast --- src/yacc/parser.y | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/yacc/parser.y b/src/yacc/parser.y index c9cd81f..f02fad7 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -58,11 +58,18 @@ /* Operator associativity */ %right '=' -%left '+' '-' '*' '/' -%left OpEquals OpNot '<' '>' -%left OpAnd OpOr OpXor -%left OpBitand OpBitor OpBitxor OpBitnot -%nonassoc KeyAs '(' ')' +%left OpOr +%left OpXor +%left OpAnd +%left OpBitor +%left OpBitxor +%left OpBitand +%left OpEquals '<' '>' +%left '+' '-' +%left '*' '/' +%left OpNot OpBitnot +%left KeyAs +%left '(' ')' %% program: program programbody @@ -109,7 +116,7 @@ IOqualifyier: KeyIn | KeyOut KeyIn | ; -typecast: expr KeyAs type { DEBUG("Type-Cast"); }; +typecast: expr KeyAs type %prec KeyAs { DEBUG("Type-Cast"); }; reinterpretcast: '(' type ')' expr { DEBUG("Reinterpret-Cast"); }; From f2317c78ce69a3f80a40fecd022858c11b708989 Mon Sep 17 00:00:00 2001 From: Filleo Date: Wed, 15 May 2024 16:14:55 +0200 Subject: [PATCH 16/43] solved bug from fun def --- src/yacc/parser.y | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 811f222..5c15452 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -168,8 +168,9 @@ paramlist: paramlist '(' params ')' {AST_push_node($1, $3); $$ = $1;} | paramlist '(' ')'{$$ = $1;} | '(' params ')' {AST_NODE_PTR list = AST_new_node(AST_List, NULL); - AST_push_node(list, $2);} - | '(' ')' {$$ = AST_new_node(AST_ParamList, NULL);}; + AST_push_node(list, $2); + $$ = list;} + | '(' ')' {$$ = AST_new_node(AST_List, NULL);}; params: IOqualifyier paramdecl ',' params {AST_NODE_PTR parameter = AST_new_node(AST_Parameter, NULL); AST_push_node(parameter, $1); @@ -311,7 +312,7 @@ branchhalf: branchif { AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); AST_push_node(branch, $1); $$ = branch; } | branchhalf branchelseif { AST_push_node($1 , $2); - $$ = $1; } + $$ = $1; }; while: KeyWhile expr '{' statementlist '}' {AST_NODE_PTR whilenode = AST_new_node(AST_While, NULL); From d7b690ec8a893a1a4b4515886cd93426ba85123d Mon Sep 17 00:00:00 2001 From: Filleo Date: Wed, 15 May 2024 16:26:40 +0200 Subject: [PATCH 17/43] solved error in test --- src/ast/ast.c | 1 - tests/ast/test_ast.py | 17 +++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/ast/ast.c b/src/ast/ast.c index 742bb73..e503e1e 100644 --- a/src/ast/ast.c +++ b/src/ast/ast.c @@ -33,7 +33,6 @@ void AST_init() { DEBUG("initializing global syntax tree..."); INFO("filling lookup table..."); - lookup_table[AST_Stmt] = "stmt"; lookup_table[AST_Module] = "module"; lookup_table[AST_Expr] = "expr"; diff --git a/tests/ast/test_ast.py b/tests/ast/test_ast.py index 91d637a..28407f9 100644 --- a/tests/ast/test_ast.py +++ b/tests/ast/test_ast.py @@ -60,14 +60,27 @@ def run_check_print_node(): 29 < 30 cast 31 as -32 value +32 funcall 33 value 34 typedef 35 box 36 fun 37 value 38 list -39 storage +39 expr list +40 arg list +41 param list +42 stmt list +43 ident list +44 value +45 type +46 value +47 value +48 value +49 - +50 parameter +51 value +52 parameter-declaration """ == p.stdout From 7789c7e597e1a23f3a2c00fb236d249511139efe Mon Sep 17 00:00:00 2001 From: Filleo Date: Wed, 15 May 2024 17:03:18 +0200 Subject: [PATCH 18/43] added removal of root node after output generation --- src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.c b/src/main.c index 0591208..ac54e76 100644 --- a/src/main.c +++ b/src/main.c @@ -72,5 +72,6 @@ int main(int argc, char *argv[]) { FILE *output = fopen("test.txt", "w"); AST_fprint_graphviz(output, root); fclose(output); + AST_delete_node(root); return 0; } From addaff4818c214669163d3f65340d4efdd3b9049 Mon Sep 17 00:00:00 2001 From: Filleo Date: Wed, 15 May 2024 19:30:29 +0200 Subject: [PATCH 19/43] i am not a smart man --- src/yacc/parser.y | 1 + 1 file changed, 1 insertion(+) diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 5667d24..d8bf1a1 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -4,6 +4,7 @@ %code requires { #include #include + #include extern int yylineno; From 2757132cf21c916ddbd2980e590b1f9abb909056 Mon Sep 17 00:00:00 2001 From: Ur Mom Date: Thu, 16 May 2024 10:27:44 +0200 Subject: [PATCH 20/43] Fixed Typo --- src/yacc/parser.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 471948f..3a5c92c 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -283,7 +283,7 @@ boxcall: boxaccess argumentlist {AST_NODE_PTR boxcall = AST_new_node(AST_Call, N $$ = boxcall;}; -typecast: expr KeyAs type %prec KeyAs {{AST_NODE_PTR reinterpretcast = AST_new_node(AST_reinterpretcast, NULL); +typecast: expr KeyAs type %prec KeyAs {AST_NODE_PTR reinterpretcast = AST_new_node(AST_reinterpretcast, NULL); $$ = typecast; DEBUG("Type-Cast"); }; From e57682d717704c807545c2064152636fefe55d8c Mon Sep 17 00:00:00 2001 From: Ur Mom Date: Thu, 16 May 2024 11:34:51 +0200 Subject: [PATCH 21/43] changed node-name according to ast.h --- src/yacc/parser.y | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 3a5c92c..ece2282 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -283,12 +283,10 @@ boxcall: boxaccess argumentlist {AST_NODE_PTR boxcall = AST_new_node(AST_Call, N $$ = boxcall;}; -typecast: expr KeyAs type %prec KeyAs {AST_NODE_PTR reinterpretcast = AST_new_node(AST_reinterpretcast, NULL); - $$ = typecast; +typecast: expr KeyAs type %prec KeyAs {$$ = AST_new_node(AST_Typecast, $1); DEBUG("Type-Cast"); }; -reinterpretcast: '(' type ')' expr {AST_NODE_PTR reinterpretcast = AST_new_node(AST_reinterpretcast, NULL); - $$ = reinterpretcast; +reinterpretcast: '(' type ')' expr {$$ = AST_new_node(AST_Transmute, $4); DEBUG("Reinterpret-Cast"); }; From 8d7c6a4a2b41969423c6e7408fab5666ec1b1a62 Mon Sep 17 00:00:00 2001 From: Ur Mom Date: Thu, 16 May 2024 18:04:02 +0200 Subject: [PATCH 22/43] changed ast implementation for cast --- CMakeLists.txt | 2 +- src/yacc/parser.y | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 213143c..ced5f45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,7 +62,7 @@ set(YACC_GENERATED_SOURCE_FILE ${PROJECT_SOURCE_DIR}/src/yacc/parser.tab.c) add_custom_command(OUTPUT ${YACC_GENERATED_SOURCE_FILE} - COMMAND bison + COMMAND yacc ARGS -Wno-yacc -Wcounterexamples -d -o ${YACC_GENERATED_SOURCE_FILE} ${YACC_SOURCE_FILE} COMMENT "generate C source file for parser" diff --git a/src/yacc/parser.y b/src/yacc/parser.y index ece2282..753c7bc 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -283,10 +283,16 @@ boxcall: boxaccess argumentlist {AST_NODE_PTR boxcall = AST_new_node(AST_Call, N $$ = boxcall;}; -typecast: expr KeyAs type %prec KeyAs {$$ = AST_new_node(AST_Typecast, $1); +typecast: expr KeyAs type %prec KeyAs {AST_NODE_PTR cast = AST_new_node(AST_Typecast, NULL); + AST_push_node(cast, $1); + AST_push_node(cast, $3); + $$ = cast; DEBUG("Type-Cast"); }; -reinterpretcast: '(' type ')' expr {$$ = AST_new_node(AST_Transmute, $4); +reinterpretcast: '(' type ')' expr { AST_NODE_PTR cast = AST_new_node(AST_Transmute, NULL); + AST_push_node(cast, $4); + AST_push_node(cast, $2); + $$ = cast; DEBUG("Reinterpret-Cast"); }; From 6d03b97b9c5da64ea8d47ef412007692581defda Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 17 May 2024 15:39:07 +0200 Subject: [PATCH 23/43] added klib as external library --- .env | 1 + .github/workflows/build-check-sdk.yaml | 6 ++-- CMakeLists.txt | 27 +++++++++++++- Dockerfile | 5 +-- dep/klib | 1 + run-docker-build.sh | 50 ++++++++++++++++++++++++++ sdk/Dockerfile | 4 +-- tests/CMakeLists.txt | 3 +- tests/klib/CMakeLists.txt | 20 +++++++++++ tests/klib/hashmap.c | 36 +++++++++++++++++++ 10 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 .env create mode 160000 dep/klib create mode 100755 run-docker-build.sh create mode 100644 tests/klib/CMakeLists.txt create mode 100644 tests/klib/hashmap.c diff --git a/.env b/.env new file mode 100644 index 0000000..e09c958 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +SDK=0.2.4-alpine-3.19.1 \ No newline at end of file diff --git a/.github/workflows/build-check-sdk.yaml b/.github/workflows/build-check-sdk.yaml index b17b734..e7a9561 100644 --- a/.github/workflows/build-check-sdk.yaml +++ b/.github/workflows/build-check-sdk.yaml @@ -1,14 +1,12 @@ name: "Build check gemstone in SDK" run-name: SDK build check to ${{ inputs.deploy_target }} by @${{ github.actor }} on: [push, pull_request] -env: - SDK: 0.2.3-alpine-3.19.1 jobs: build-check-sdk: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup SDK - run: docker pull servostar/gemstone:sdk-"$SDK" && docker build --tag gemstone:devkit-"$SDK" . + run: docker pull servostar/gemstone:sdk-"$SDK" - name: Compile - run: docker run gemstone:devkit-"$SDK" sh run-check-test.sh + run: run-check-test.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 213143c..a0cbd38 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,8 @@ cmake_minimum_required(VERSION 3.15...3.25) # Header must be included this way: #include # # ├─ res +# ├─ dep +# │ └─ klib # ├─ src # │ ├─ lex # │ │ └─ lexer.l @@ -68,17 +70,34 @@ add_custom_command(OUTPUT ${YACC_GENERATED_SOURCE_FILE} COMMENT "generate C source file for parser" VERBATIM) +# ------------------------------------------------ # +# Klib # +# ------------------------------------------------ # + +file(GLOB KLIB_SOURCE_FILES ${PROJECT_SOURCE_DIR}/dep/klib/*.c) + +add_library(klib + STATIC + ${KLIB_SOURCE_FILES}) + +set_target_properties(klib + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/dep) + # ------------------------------------------------ # # Source # # ------------------------------------------------ # +include_directories(${PROJECT_SOURCE_DIR}/src) +include_directories(SYSTEM ${PROJECT_SOURCE_DIR}/dep) + file(GLOB_RECURSE SOURCE_FILES src/*.c) # define default compile flags if (MSVC) set(FLAGS /Wall /W3 /permissive) else() - set(FLAGS -Wall -Wextra -Wconversion -Wpedantic) + set(FLAGS -Wall -Wextra -Wpedantic) endif() # ------------------------------------------------ # @@ -95,6 +114,8 @@ set_target_properties(release OUTPUT_NAME "gsc" RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/release) +target_link_libraries(release klib) + # FIXME: cannot compile with /O2 because of /RTC1 flag if (MSVC) set(RELEASE_FLAGS) @@ -127,6 +148,8 @@ set_target_properties(debug OUTPUT_NAME "gsc" RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/debug) +target_link_libraries(debug klib) + if (MSVC) set(DEBUG_FLAGS /DEBUG) else() @@ -156,6 +179,8 @@ set_target_properties(check OUTPUT_NAME "gsc" RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/check) +target_link_libraries(check klib) + if (MSVC) set(CHECK_FLAGS /DEBUG /WX) else() diff --git a/Dockerfile b/Dockerfile index a8c2f7f..0693935 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,11 @@ -FROM servostar/gemstone:sdk-0.2.3-alpine-3.19.1 +FROM servostar/gemstone:sdk-0.2.4-alpine-3.19.1 LABEL authors="servostar" -LABEL version="0.2.3" +LABEL version="0.2.4" LABEL description="docker image for setting up the build pipeline on SDK" LABEL website="https://github.com/Servostar/gemstone" COPY --chown=lorang src /home/lorang/src +COPY --chown=lorang dep /home/lorang/dep COPY --chown=lorang tests /home/lorang/tests COPY --chown=lorang CMakeLists.txt /home/lorang/ COPY --chown=lorang run-check-test.sh /home/lorang/ diff --git a/dep/klib b/dep/klib new file mode 160000 index 0000000..4988b65 --- /dev/null +++ b/dep/klib @@ -0,0 +1 @@ +Subproject commit 4988b65b9c90473d155268c8ee15f3aad546406b diff --git a/run-docker-build.sh b/run-docker-build.sh new file mode 100755 index 0000000..9a6635a --- /dev/null +++ b/run-docker-build.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env sh + +# Author: Sven Vogel +# Created: 17.05.2024 +# Description: Builds the Dockerfile for SDK and DEVKIT + +echo "+--------------------------------------+" +echo "| CHECKING prelude |" +echo "+--------------------------------------+" + +source ./.env + +if [ -z "$SDK" ]; then + echo "no SDK specified" + exit 1 +fi + +echo "+--------------------------------------+" +echo "| BUILDING SDK |" +echo "+--------------------------------------+" + +docker build --tag servostar/gemstone:sdk-"$SDK" sdk/. +if [ ! $? -eq 0 ]; then + echo "===> failed to build sdk" + exit 1 +fi + +echo "+--------------------------------------+" +echo "| BUILDING DEVKIT |" +echo "+--------------------------------------+" + +docker build --tag servostar/gemstone:devkit-"$SDK" . +if [ ! $? -eq 0 ]; then + echo "===> failed to build devkit" + exit 1 +fi + +echo "+--------------------------------------+" +echo "| RUNNING check test |" +echo "+--------------------------------------+" + +docker run -it servostar/gemstone:devkit-"$SDK" sh run-check-test.sh +if [ ! $? -eq 0 ]; then + echo "===> failed to build devkit" + exit 1 +fi + +echo "+--------------------------------------+" +echo "| DONE |" +echo "+--------------------------------------+" diff --git a/sdk/Dockerfile b/sdk/Dockerfile index aae7438..fe3592b 100644 --- a/sdk/Dockerfile +++ b/sdk/Dockerfile @@ -1,11 +1,11 @@ FROM alpine:3.19.1 LABEL authors="servostar" -LABEL version="0.2.3" +LABEL version="0.2.4" LABEL description="base image for building the gemstone programming language compiler" LABEL website="https://github.com/Servostar/gemstone" # install dependencies -RUN apk add build-base gcc make cmake bison flex git python3 graphviz +RUN apk add build-base gcc make cmake bison flex git python3 graphviz zlib zlib-dev curl-dev # create user for build RUN adduser --disabled-password lorang diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b5c1111..d3447bd 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,4 +8,5 @@ set(CTEST_BINARY_DIRECTORY ${PROJECT_BINARY_DIR}/tests) add_subdirectory(logging) add_subdirectory(input_file) -add_subdirectory(ast) \ No newline at end of file +add_subdirectory(ast) +add_subdirectory(klib) \ No newline at end of file diff --git a/tests/klib/CMakeLists.txt b/tests/klib/CMakeLists.txt new file mode 100644 index 0000000..7542f70 --- /dev/null +++ b/tests/klib/CMakeLists.txt @@ -0,0 +1,20 @@ +include(CTest) + +include_directories(SYSTEM ${PROJECT_SOURCE_DIR}/dep) +include_directories(${PROJECT_SOURCE_DIR}/src) + +# ------------------------------------------------------- # +# CTEST 1 +# test build configuration and dependency of Klib + +add_executable(klib_hashmap + hashmap.c) +set_target_properties(klib_hashmap + PROPERTIES + OUTPUT_NAME "klib_hashmap" + RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/tests/klib) +target_link_libraries(klib_hashmap klib) +target_compile_options(klib_hashmap PUBLIC -Wall -Wextra -Wpedantic -Werror) + add_test(NAME klib_hashmap + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + COMMAND ${GEMSTONE_BINARY_DIR}/tests/klib/klib_hashmap) diff --git a/tests/klib/hashmap.c b/tests/klib/hashmap.c new file mode 100644 index 0000000..abd7ab0 --- /dev/null +++ b/tests/klib/hashmap.c @@ -0,0 +1,36 @@ + +#include + +struct Book { + const char* author; + size_t pages; +}; + +KHASH_MAP_INIT_STR(books, struct Book) + +void put(const char* key, const struct Book book, khash_t(books)* books) { + khint_t idx; + int ret; + + idx = kh_put(books, books, key, &ret); + + if (!ret) + kh_del(books, books, idx); + + kh_value(books, idx) = book; +} + +int main(void) { + + khash_t(books) *map = kh_init(books); + + struct Book book; + book.author = "Bob"; + book.pages = 45; + + put("Pharao of Egypt", book, map); + + kh_destroy(books, map); + + return 0; +} From 47edaea82bd0bbd3c112bf81c0d44bc601c1d3ec Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 17 May 2024 15:41:52 +0200 Subject: [PATCH 24/43] sourcing .env file in action --- .github/workflows/build-check-sdk.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-check-sdk.yaml b/.github/workflows/build-check-sdk.yaml index e7a9561..91525a3 100644 --- a/.github/workflows/build-check-sdk.yaml +++ b/.github/workflows/build-check-sdk.yaml @@ -6,6 +6,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - name: Setup environment + run: source ./.env - name: Setup SDK run: docker pull servostar/gemstone:sdk-"$SDK" - name: Compile From 24dbfc7b20a4b1a67873064371cff57c870c48bf Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 17 May 2024 15:45:34 +0200 Subject: [PATCH 25/43] sourcing env file in same shell --- .github/workflows/build-check-sdk.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-check-sdk.yaml b/.github/workflows/build-check-sdk.yaml index 91525a3..841c8a3 100644 --- a/.github/workflows/build-check-sdk.yaml +++ b/.github/workflows/build-check-sdk.yaml @@ -6,9 +6,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Setup environment - run: source ./.env - name: Setup SDK - run: docker pull servostar/gemstone:sdk-"$SDK" + run: source ./.env && docker pull servostar/gemstone:sdk-"$SDK" - name: Compile - run: run-check-test.sh + run: source ./.env && run-check-test.sh From 0bfd54dfb08d59ce05cfe46e2a7316c8cc058691 Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 17 May 2024 15:46:35 +0200 Subject: [PATCH 26/43] calling run-docker-build.sh --- .github/workflows/build-check-sdk.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-check-sdk.yaml b/.github/workflows/build-check-sdk.yaml index 841c8a3..24118f8 100644 --- a/.github/workflows/build-check-sdk.yaml +++ b/.github/workflows/build-check-sdk.yaml @@ -9,4 +9,4 @@ jobs: - name: Setup SDK run: source ./.env && docker pull servostar/gemstone:sdk-"$SDK" - name: Compile - run: source ./.env && run-check-test.sh + run: source ./.env && run-docker-build.sh From 2ad8d8334123ae28076e3f7493714c5b54dc20e1 Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 17 May 2024 15:47:25 +0200 Subject: [PATCH 27/43] calling script in shell --- .github/workflows/build-check-sdk.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-check-sdk.yaml b/.github/workflows/build-check-sdk.yaml index 24118f8..d63c874 100644 --- a/.github/workflows/build-check-sdk.yaml +++ b/.github/workflows/build-check-sdk.yaml @@ -9,4 +9,4 @@ jobs: - name: Setup SDK run: source ./.env && docker pull servostar/gemstone:sdk-"$SDK" - name: Compile - run: source ./.env && run-docker-build.sh + run: source ./.env && sh run-docker-build.sh From fa7e5d468811ffe02b475a0024409c6dff6a6dc4 Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 17 May 2024 15:49:10 +0200 Subject: [PATCH 28/43] added missing files to devkit --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index 0693935..cf32591 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,5 +9,7 @@ COPY --chown=lorang dep /home/lorang/dep COPY --chown=lorang tests /home/lorang/tests COPY --chown=lorang CMakeLists.txt /home/lorang/ COPY --chown=lorang run-check-test.sh /home/lorang/ +COPY --chown=lorang .env /home/lorang/ +COPY --chown=lorang run-docker-build /home/lorang/ RUN cmake . From 54682b4a395334aac8cb0dd6749a8f037263898d Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 17 May 2024 15:53:27 +0200 Subject: [PATCH 29/43] made command source optional --- run-docker-build.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/run-docker-build.sh b/run-docker-build.sh index 9a6635a..2ad358a 100755 --- a/run-docker-build.sh +++ b/run-docker-build.sh @@ -8,7 +8,10 @@ echo "+--------------------------------------+" echo "| CHECKING prelude |" echo "+--------------------------------------+" -source ./.env +if [ -z "$SDK" ]; then + echo "no SDK specified, sourcing .env" + source ./.env +fi if [ -z "$SDK" ]; then echo "no SDK specified" From 00eab344ecf4734bc5de886cbf861883edc5553f Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 17 May 2024 16:02:40 +0200 Subject: [PATCH 30/43] fixed some errors --- .github/workflows/build-check-sdk.yaml | 2 +- Dockerfile | 2 +- run-docker-build.sh | 13 +++++++++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-check-sdk.yaml b/.github/workflows/build-check-sdk.yaml index d63c874..586e0dd 100644 --- a/.github/workflows/build-check-sdk.yaml +++ b/.github/workflows/build-check-sdk.yaml @@ -9,4 +9,4 @@ jobs: - name: Setup SDK run: source ./.env && docker pull servostar/gemstone:sdk-"$SDK" - name: Compile - run: source ./.env && sh run-docker-build.sh + run: set -a && source ./.env && sh run-docker-build.sh diff --git a/Dockerfile b/Dockerfile index cf32591..dd774f4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,6 +10,6 @@ COPY --chown=lorang tests /home/lorang/tests COPY --chown=lorang CMakeLists.txt /home/lorang/ COPY --chown=lorang run-check-test.sh /home/lorang/ COPY --chown=lorang .env /home/lorang/ -COPY --chown=lorang run-docker-build /home/lorang/ +COPY --chown=lorang run-docker-build.sh /home/lorang/ RUN cmake . diff --git a/run-docker-build.sh b/run-docker-build.sh index 2ad358a..2d6f99f 100755 --- a/run-docker-build.sh +++ b/run-docker-build.sh @@ -11,11 +11,16 @@ echo "+--------------------------------------+" if [ -z "$SDK" ]; then echo "no SDK specified, sourcing .env" source ./.env -fi -if [ -z "$SDK" ]; then - echo "no SDK specified" - exit 1 + if [ -z "$SDK" ]; then + echo "no SDK specified" + exit 1 + else + echo "using SDK $SDK" + fi + +else + echo "using SDK $SDK" fi echo "+--------------------------------------+" From 13c176322797afab4481c64f0136c6786cf74b24 Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 17 May 2024 16:16:16 +0200 Subject: [PATCH 31/43] removed klib --- dep/klib | 1 - 1 file changed, 1 deletion(-) delete mode 160000 dep/klib diff --git a/dep/klib b/dep/klib deleted file mode 160000 index 4988b65..0000000 --- a/dep/klib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4988b65b9c90473d155268c8ee15f3aad546406b From df63cffba47f71b70c7e9176bbe1d0b566ccd58a Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 17 May 2024 16:17:04 +0200 Subject: [PATCH 32/43] added submodule klib --- .gitmodules | 3 +++ dep/klib | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 dep/klib diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..48d9717 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "dep/klib"] + path = dep/klib + url = https://github.com/attractivechaos/klib.git diff --git a/dep/klib b/dep/klib new file mode 160000 index 0000000..4988b65 --- /dev/null +++ b/dep/klib @@ -0,0 +1 @@ +Subproject commit 4988b65b9c90473d155268c8ee15f3aad546406b From 330ffc3b2ff0c7a6992c3827a3e30da7ae090f37 Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 17 May 2024 16:50:04 +0200 Subject: [PATCH 33/43] initialized git submodule --- .github/workflows/build-check-sdk.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-check-sdk.yaml b/.github/workflows/build-check-sdk.yaml index 586e0dd..d71dcf8 100644 --- a/.github/workflows/build-check-sdk.yaml +++ b/.github/workflows/build-check-sdk.yaml @@ -6,7 +6,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - name: Setup repository + run: git submodule init && git submodule update - name: Setup SDK - run: source ./.env && docker pull servostar/gemstone:sdk-"$SDK" + run: source ./.env && docker pull servostar/gemstone:sdk-"$SDK" - name: Compile run: set -a && source ./.env && sh run-docker-build.sh From 858a6a3c4e304bea365d461e7052a8d09cf51727 Mon Sep 17 00:00:00 2001 From: servostar Date: Sat, 18 May 2024 12:25:13 +0200 Subject: [PATCH 34/43] transioned to glib --- .gitmodules | 3 --- CMakeLists.txt | 21 +++++++-------------- Dockerfile | 1 - dep/klib | 1 - run-check-test.sh | 2 ++ sdk/Dockerfile | 2 +- tests/CMakeLists.txt | 2 +- tests/glib/CMakeLists.txt | 22 ++++++++++++++++++++++ tests/glib/glib_hashmap.c | 27 +++++++++++++++++++++++++++ tests/klib/CMakeLists.txt | 20 -------------------- tests/klib/hashmap.c | 36 ------------------------------------ 11 files changed, 60 insertions(+), 77 deletions(-) delete mode 100644 .gitmodules delete mode 160000 dep/klib create mode 100644 tests/glib/CMakeLists.txt create mode 100644 tests/glib/glib_hashmap.c delete mode 100644 tests/klib/CMakeLists.txt delete mode 100644 tests/klib/hashmap.c diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 48d9717..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "dep/klib"] - path = dep/klib - url = https://github.com/attractivechaos/klib.git diff --git a/CMakeLists.txt b/CMakeLists.txt index a0cbd38..b304447 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,25 +71,18 @@ add_custom_command(OUTPUT ${YACC_GENERATED_SOURCE_FILE} VERBATIM) # ------------------------------------------------ # -# Klib # +# Setup Glib 2.0 # # ------------------------------------------------ # -file(GLOB KLIB_SOURCE_FILES ${PROJECT_SOURCE_DIR}/dep/klib/*.c) - -add_library(klib - STATIC - ${KLIB_SOURCE_FILES}) - -set_target_properties(klib - PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/dep) +find_package(PkgConfig REQUIRED) +pkg_search_module(GLIB REQUIRED IMPORTED_TARGET glib-2.0) # ------------------------------------------------ # # Source # # ------------------------------------------------ # include_directories(${PROJECT_SOURCE_DIR}/src) -include_directories(SYSTEM ${PROJECT_SOURCE_DIR}/dep) +include_directories(PRIVATE ${GLIB_INCLUDE_DIRS}) file(GLOB_RECURSE SOURCE_FILES src/*.c) @@ -114,7 +107,7 @@ set_target_properties(release OUTPUT_NAME "gsc" RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/release) -target_link_libraries(release klib) +target_link_libraries(release PkgConfig::GLIB) # FIXME: cannot compile with /O2 because of /RTC1 flag if (MSVC) @@ -148,7 +141,7 @@ set_target_properties(debug OUTPUT_NAME "gsc" RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/debug) -target_link_libraries(debug klib) +target_link_libraries(debug PkgConfig::GLIB) if (MSVC) set(DEBUG_FLAGS /DEBUG) @@ -179,7 +172,7 @@ set_target_properties(check OUTPUT_NAME "gsc" RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/check) -target_link_libraries(check klib) +target_link_libraries(check PkgConfig::GLIB) if (MSVC) set(CHECK_FLAGS /DEBUG /WX) diff --git a/Dockerfile b/Dockerfile index dd774f4..68265d8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,6 @@ LABEL description="docker image for setting up the build pipeline on SDK" LABEL website="https://github.com/Servostar/gemstone" COPY --chown=lorang src /home/lorang/src -COPY --chown=lorang dep /home/lorang/dep COPY --chown=lorang tests /home/lorang/tests COPY --chown=lorang CMakeLists.txt /home/lorang/ COPY --chown=lorang run-check-test.sh /home/lorang/ diff --git a/dep/klib b/dep/klib deleted file mode 160000 index 4988b65..0000000 --- a/dep/klib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4988b65b9c90473d155268c8ee15f3aad546406b diff --git a/run-check-test.sh b/run-check-test.sh index a2a3ab4..bd7e5cc 100644 --- a/run-check-test.sh +++ b/run-check-test.sh @@ -9,6 +9,8 @@ echo "+--------------------------------------+" echo "| BUILDING all TARGETS |" echo "+--------------------------------------+" +cmake . + make -B if [ ! $? -eq 0 ]; then echo "===> failed to build targets" diff --git a/sdk/Dockerfile b/sdk/Dockerfile index fe3592b..b5523b3 100644 --- a/sdk/Dockerfile +++ b/sdk/Dockerfile @@ -5,7 +5,7 @@ LABEL description="base image for building the gemstone programming language com LABEL website="https://github.com/Servostar/gemstone" # install dependencies -RUN apk add build-base gcc make cmake bison flex git python3 graphviz zlib zlib-dev curl-dev +RUN apk add build-base gcc make cmake bison flex git python3 graphviz glib glib-dev # create user for build RUN adduser --disabled-password lorang diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d3447bd..1228d2b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,4 +9,4 @@ set(CTEST_BINARY_DIRECTORY ${PROJECT_BINARY_DIR}/tests) add_subdirectory(logging) add_subdirectory(input_file) add_subdirectory(ast) -add_subdirectory(klib) \ No newline at end of file +add_subdirectory(glib) \ No newline at end of file diff --git a/tests/glib/CMakeLists.txt b/tests/glib/CMakeLists.txt new file mode 100644 index 0000000..e3ede27 --- /dev/null +++ b/tests/glib/CMakeLists.txt @@ -0,0 +1,22 @@ +include(CTest) + +include_directories(${PROJECT_SOURCE_DIR}/src) +include_directories(PRIVATE ${GLIB_INCLUDE_DIRS}) + +find_package(PkgConfig REQUIRED) +pkg_search_module(GLIB REQUIRED IMPORTED_TARGET glib-2.0) + +# ------------------------------------------------------- # +# CTEST 1 +# test Glib's hashmap + +add_executable(glib_hashmap + glib_hashmap.c) +set_target_properties(glib_hashmap + PROPERTIES + OUTPUT_NAME "glib_hashmap" + RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/tests/glib) +target_link_libraries(glib_hashmap PkgConfig::GLIB) +add_test(NAME glib_hashmap + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + COMMAND ${GEMSTONE_BINARY_DIR}/tests/glib/glib_hashmap) diff --git a/tests/glib/glib_hashmap.c b/tests/glib/glib_hashmap.c new file mode 100644 index 0000000..70c1e01 --- /dev/null +++ b/tests/glib/glib_hashmap.c @@ -0,0 +1,27 @@ + +#include + +int main(int argc, char* argv[]) { + + GHashTable* map = g_hash_table_new(g_str_hash, g_str_equal); + + for (int i = 0; i < argc; i++) { + int* index = malloc(sizeof(int)); + + *index = i; + + g_hash_table_insert(map, argv[i], &index); + } + + for (int i = 0; i < argc; i++) { + int* index = (int*) g_hash_table_lookup(map, argv[i]); + + g_hash_table_remove(map, argv[i]); + + free(index); + } + + g_hash_table_destroy(map); + + return 0; +} diff --git a/tests/klib/CMakeLists.txt b/tests/klib/CMakeLists.txt deleted file mode 100644 index 7542f70..0000000 --- a/tests/klib/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -include(CTest) - -include_directories(SYSTEM ${PROJECT_SOURCE_DIR}/dep) -include_directories(${PROJECT_SOURCE_DIR}/src) - -# ------------------------------------------------------- # -# CTEST 1 -# test build configuration and dependency of Klib - -add_executable(klib_hashmap - hashmap.c) -set_target_properties(klib_hashmap - PROPERTIES - OUTPUT_NAME "klib_hashmap" - RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/tests/klib) -target_link_libraries(klib_hashmap klib) -target_compile_options(klib_hashmap PUBLIC -Wall -Wextra -Wpedantic -Werror) - add_test(NAME klib_hashmap - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - COMMAND ${GEMSTONE_BINARY_DIR}/tests/klib/klib_hashmap) diff --git a/tests/klib/hashmap.c b/tests/klib/hashmap.c deleted file mode 100644 index abd7ab0..0000000 --- a/tests/klib/hashmap.c +++ /dev/null @@ -1,36 +0,0 @@ - -#include - -struct Book { - const char* author; - size_t pages; -}; - -KHASH_MAP_INIT_STR(books, struct Book) - -void put(const char* key, const struct Book book, khash_t(books)* books) { - khint_t idx; - int ret; - - idx = kh_put(books, books, key, &ret); - - if (!ret) - kh_del(books, books, idx); - - kh_value(books, idx) = book; -} - -int main(void) { - - khash_t(books) *map = kh_init(books); - - struct Book book; - book.author = "Bob"; - book.pages = 45; - - put("Pharao of Egypt", book, map); - - kh_destroy(books, map); - - return 0; -} From 8894c6f8423a8b9e5b3c0e1e9f3dad3f6ba1acc4 Mon Sep 17 00:00:00 2001 From: servostar Date: Sat, 18 May 2024 12:52:00 +0200 Subject: [PATCH 35/43] fixed docker builld script --- run-docker-build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run-docker-build.sh b/run-docker-build.sh index 2d6f99f..aaec9c6 100755 --- a/run-docker-build.sh +++ b/run-docker-build.sh @@ -47,9 +47,9 @@ echo "+--------------------------------------+" echo "| RUNNING check test |" echo "+--------------------------------------+" -docker run -it servostar/gemstone:devkit-"$SDK" sh run-check-test.sh +docker run servostar/gemstone:devkit-"$SDK" sh run-check-test.sh if [ ! $? -eq 0 ]; then - echo "===> failed to build devkit" + echo "===> failed to run build or checks" exit 1 fi From e4334216264e06da26b89b639356108e930d012b Mon Sep 17 00:00:00 2001 From: servostar Date: Sat, 18 May 2024 14:05:12 +0200 Subject: [PATCH 36/43] fixed hashtable --- tests/glib/glib_hashmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/glib/glib_hashmap.c b/tests/glib/glib_hashmap.c index 70c1e01..116df77 100644 --- a/tests/glib/glib_hashmap.c +++ b/tests/glib/glib_hashmap.c @@ -10,7 +10,7 @@ int main(int argc, char* argv[]) { *index = i; - g_hash_table_insert(map, argv[i], &index); + g_hash_table_insert(map, argv[i], index); } for (int i = 0; i < argc; i++) { From 58f7170df63ec42b4f1dedc3628b1117da3ba362 Mon Sep 17 00:00:00 2001 From: SirTalksalot75 <132705706+SirTalksalot75@users.noreply.github.com> Date: Tue, 21 May 2024 12:20:45 +0200 Subject: [PATCH 37/43] changed lookuptable for casts in ast.c --- src/ast/ast.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ast/ast.c b/src/ast/ast.c index e503e1e..892af1f 100644 --- a/src/ast/ast.c +++ b/src/ast/ast.c @@ -70,8 +70,8 @@ void AST_init() { lookup_table[AST_Fun] = "fun"; lookup_table[AST_Call] = "funcall"; - lookup_table[AST_Typecast] = "cast"; - lookup_table[AST_Transmute] = "as"; + lookup_table[AST_Typecast] = "typecast"; + lookup_table[AST_Transmute] = "transmute"; lookup_table[AST_Condition] = "condition"; lookup_table[AST_List] = "list"; lookup_table[AST_ExprList] = "expr list"; From 0e098db7261fea530cdb7b33d5d538294dbb2f0d Mon Sep 17 00:00:00 2001 From: SirTalksalot75 <132705706+SirTalksalot75@users.noreply.github.com> Date: Tue, 21 May 2024 12:21:54 +0200 Subject: [PATCH 38/43] Update test_ast.py --- tests/ast/test_ast.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ast/test_ast.py b/tests/ast/test_ast.py index 28407f9..e3e5d48 100644 --- a/tests/ast/test_ast.py +++ b/tests/ast/test_ast.py @@ -58,8 +58,8 @@ def run_check_print_node(): 27 == 28 > 29 < -30 cast -31 as +30 typecast +31 transmute 32 funcall 33 value 34 typedef From 1d7fb31da56d6784a9de4d950c6a429d8338acfd Mon Sep 17 00:00:00 2001 From: SirTalksalot75 <132705706+SirTalksalot75@users.noreply.github.com> Date: Tue, 21 May 2024 14:20:15 +0200 Subject: [PATCH 39/43] Update CMakeLists.txt changed yacc ->bison --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ced5f45..213143c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,7 +62,7 @@ set(YACC_GENERATED_SOURCE_FILE ${PROJECT_SOURCE_DIR}/src/yacc/parser.tab.c) add_custom_command(OUTPUT ${YACC_GENERATED_SOURCE_FILE} - COMMAND yacc + COMMAND bison ARGS -Wno-yacc -Wcounterexamples -d -o ${YACC_GENERATED_SOURCE_FILE} ${YACC_SOURCE_FILE} COMMENT "generate C source file for parser" From 8c17749923b4088fb41eeaa65dbac60d474676fc Mon Sep 17 00:00:00 2001 From: servostar Date: Sun, 26 May 2024 14:09:53 +0200 Subject: [PATCH 40/43] refactored transmute rule and added bracketed expressions --- src/lex/lexer.l | 1 + src/yacc/parser.y | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lex/lexer.l b/src/lex/lexer.l index 7c0cc0c..a3a2f32 100644 --- a/src/lex/lexer.l +++ b/src/lex/lexer.l @@ -52,6 +52,7 @@ "float" {DEBUG("\"%s\" tokenized with \'KeyFloat\'", yytext); return(KeyFloat);}; "self" {DEBUG("\"%s\" tokenized with \'KeySelf\'", yytext); return(KeySelf);}; "as" {DEBUG("\"%s\" tokenized with \'KeyAs'", yytext); return (KeyAs);}; +"to" {DEBUG("\"%s\" tokenized with \'KeyTo'", yytext); return (KeyTo);}; "short" {DEBUG("\"%s\" tokenized with \'KeyShort\'", yytext); return(KeyShort);}; "long" {DEBUG("\"%s\" tokenized with \'KeyLong\'", yytext); return(KeyLong);}; "half" {DEBUG("\"%s\" tokenized with \'KeyHalf\'", yytext); return(KeyHalf);}; diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 753c7bc..8e6baf9 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -72,6 +72,7 @@ %token KeyFloat %token KeySelf %token KeyAs +%token KeyTo %token ValInt %token Ident %token ValFloat @@ -128,7 +129,7 @@ %left '+' '-' %left '*' '/' %left OpNot OpBitnot -%left KeyAs +%left KeyAs KeyTo %left '(' ')' %% @@ -154,6 +155,7 @@ expr: ValFloat {$$ = AST_new_node(AST_Float, $1);} | boxselfaccess{$$ = $1;} | typecast{$$ = $1;} | reinterpretcast{$$ = $1;} + | '(' expr ')' {$$=$2;} exprlist: expr ',' exprlist {AST_push_node($3, $1); $$ = $3;} @@ -289,9 +291,9 @@ typecast: expr KeyAs type %prec KeyAs {AST_NODE_PTR cast = AST_new_node(AST_Typ $$ = cast; DEBUG("Type-Cast"); }; -reinterpretcast: '(' type ')' expr { AST_NODE_PTR cast = AST_new_node(AST_Transmute, NULL); - AST_push_node(cast, $4); - AST_push_node(cast, $2); +reinterpretcast: expr KeyTo type %prec KeyTo { AST_NODE_PTR cast = AST_new_node(AST_Transmute, NULL); + AST_push_node(cast, $1); + AST_push_node(cast, $3); $$ = cast; DEBUG("Reinterpret-Cast"); }; From 472a4a623c8af480b0ace97b32af7210de2812e9 Mon Sep 17 00:00:00 2001 From: servostar Date: Thu, 30 May 2024 21:06:03 +0200 Subject: [PATCH 41/43] feature: added error diagnostics and the ability to parse multiple files --- src/ast/ast.c | 17 ++- src/ast/ast.h | 5 +- src/io/files.c | 224 ++++++++++++++++++++++++++++++++++++ src/io/files.h | 77 +++++++++++++ src/lex/util.c | 14 ++- src/lex/util.h | 2 + src/main.c | 116 +++++++++++++------ src/sys/log.h | 2 +- src/yacc/parser.y | 286 ++++++++++++++++++---------------------------- 9 files changed, 530 insertions(+), 213 deletions(-) create mode 100644 src/io/files.c create mode 100644 src/io/files.h diff --git a/src/ast/ast.c b/src/ast/ast.c index 892af1f..8c65510 100644 --- a/src/ast/ast.c +++ b/src/ast/ast.c @@ -5,7 +5,7 @@ #include #include -struct AST_Node_t *AST_new_node(enum AST_SyntaxElement_t kind, const char* value) { +struct AST_Node_t *AST_new_node(TokenLocation location, enum AST_SyntaxElement_t kind, const char* value) { DEBUG("creating new AST node: %d \"%s\"", kind, value); assert(kind < AST_ELEMENT_COUNT); @@ -23,6 +23,7 @@ struct AST_Node_t *AST_new_node(enum AST_SyntaxElement_t kind, const char* value node->child_count = 0; node->kind = kind; node->value = value; + node->location = location; return node; } @@ -114,6 +115,14 @@ const char* AST_node_to_string(const struct AST_Node_t* node) { return string; } +static inline unsigned long int min(unsigned long int a, unsigned long int b) { + return a > b ? b : a; +} + +static inline unsigned long int max(unsigned long int a, unsigned long int b) { + return a > b ? a : b; +} + void AST_push_node(struct AST_Node_t *owner, struct AST_Node_t *child) { DEBUG("Adding new node %p to %p", child, owner); assert(owner != NULL); @@ -134,6 +143,12 @@ void AST_push_node(struct AST_Node_t *owner, struct AST_Node_t *child) { PANIC("failed to allocate children array of AST node"); } + owner->location.col_end = max(owner->location.col_end, child->location.col_end); + owner->location.line_end = max(owner->location.line_end, child->location.line_end); + + owner->location.col_start = min(owner->location.col_start, child->location.col_start); + owner->location.line_start = min(owner->location.line_start, child->location.line_start); + assert(owner->children != NULL); owner->children[owner->child_count++] = child; diff --git a/src/ast/ast.h b/src/ast/ast.h index ff8297b..7edbe81 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -3,6 +3,7 @@ #define _AST_H_ #include +#include /** * @brief The type of a AST node @@ -94,6 +95,8 @@ struct AST_Node_t { // optional value: integer literal, string literal, ... const char* value; + TokenLocation location; + // number of child nodes ownd by this node // length of children array size_t child_count; @@ -133,7 +136,7 @@ const char* AST_node_to_string(const struct AST_Node_t* node); [[maybe_unused]] [[nodiscard("pointer must be freed")]] [[gnu::returns_nonnull]] -struct AST_Node_t *AST_new_node(enum AST_SyntaxElement_t kind, const char* value); +struct AST_Node_t *AST_new_node(TokenLocation location, enum AST_SyntaxElement_t kind, const char* value); /** * @brief Deallocate this node and all of its children. diff --git a/src/io/files.c b/src/io/files.c new file mode 100644 index 0000000..97daed1 --- /dev/null +++ b/src/io/files.c @@ -0,0 +1,224 @@ +// +// Created by servostar on 5/30/24. +// + +#include +#include +#include +#include + +ModuleFile *push_file(ModuleFileStack *stack, const char *path) { + assert(stack != NULL); + + // lazy init of heap stack + if (stack->files == NULL) { + stack->files = g_array_new(FALSE, FALSE, sizeof(ModuleFile)); + } + + ModuleFile new_file = { + .path = path, + .handle = NULL + }; + + g_array_append_val(stack->files, new_file); + + return ((ModuleFile *) stack->files->data) + stack->files->len - 1; +} + +void delete_files(ModuleFileStack *stack) { + for (size_t i = 0; i < stack->files->len; i++) { + ModuleFile *file = ((ModuleFile *) stack->files->data) + i; + + if (file->handle != NULL) { + DEBUG("closing file: %s", file->path); + fclose(file->handle); + } + + } + + g_array_free(stack->files, TRUE); + DEBUG("deleted module file stack"); +} + +#define SEEK_BUF_BYTES 256 + +static inline unsigned long int min(unsigned long int a, unsigned long int b) { + return a > b ? b : a; +} + +// behaves like fgets except that it has defined behavior when n == 1 +static void custom_fgets(char *buffer, size_t n, FILE *stream) { + if (n == 1) { + buffer[0] = (char) fgetc(stream); + buffer[1] = 0; + } else { + fgets(buffer, (int) n, stream); + } +} + +void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, const char *message) { + assert(file->handle != NULL); + assert(location != NULL); + assert(message != NULL); + + // reset to start + rewind(file->handle); + + char *buffer = alloca(SEEK_BUF_BYTES); + unsigned long int line_count = 1; + + // seek to first line + while (line_count < location->line_start && fgets(buffer, SEEK_BUF_BYTES, file->handle) != NULL) { + line_count += strchr(buffer, '\n') != NULL; + } + + const char *accent_color = RESET; + const char *kind_text = "unknown"; + switch (kind) { + case Info: + kind_text = "info"; + accent_color = CYAN; + file->statistics.info_count++; + break; + case Warning: + kind_text = "warning"; + accent_color = YELLOW; + file->statistics.warning_count++; + break; + case Error: + kind_text = "error"; + accent_color = RED; + file->statistics.error_count++; + break; + } + + char absolute_path[PATH_MAX]; + realpath(file->path, absolute_path); + + printf("%s%s:%ld:%s %s%s:%s %s\n", BOLD, absolute_path, location->line_start, RESET, accent_color, kind_text, RESET, + message); + + size_t lines = location->line_end - location->line_start + 1; + + for (size_t l = 0; l < lines; l++) { + printf(" %4ld | ", location->line_start + l); + + size_t limit; + size_t chars = 0; + + // print line before token group start + limit = min(location->col_start, SEEK_BUF_BYTES); + while (limit > 1) { + custom_fgets(buffer, (int) limit, file->handle); + chars += printf("%s", buffer); + limit = min(location->col_start - chars, SEEK_BUF_BYTES); + + if (strchr(buffer, '\n') != NULL) { + goto cont; + } + } + + printf("%s", accent_color); + + chars = 0; + limit = min(location->col_end - location->col_start + 1, SEEK_BUF_BYTES); + while (limit > 0) { + custom_fgets(buffer, (int) limit, file->handle); + chars += printf("%s", buffer); + limit = min(location->col_end - location->col_start + 1 - chars, SEEK_BUF_BYTES); + + if (strchr(buffer, '\n') != NULL) { + goto cont; + } + } + + printf("%s", RESET); + + // print rest of the line + do { + custom_fgets(buffer, SEEK_BUF_BYTES, file->handle); + printf("%s", buffer); + } while (strchr(buffer, '\n') == NULL); + + cont: + printf("%s", RESET); + } + + printf(" | "); + for (size_t i = 1; i < location->col_start; i++) { + printf(" "); + } + + printf("%s", accent_color); + printf("^"); + for (size_t i = 0; i < location->col_end - location->col_start; i++) { + printf("~"); + } + + printf("%s\n\n", RESET); +} + +TokenLocation new_location(unsigned long int line_start, unsigned long int col_start, unsigned long int line_end, + unsigned long int col_end) { + TokenLocation location; + + location.line_start = line_start; + location.line_end = line_end; + location.col_start = col_start; + location.col_end = col_end; + + return location; +} + +void print_file_statistics(ModuleFile *file) { + if (file->statistics.info_count + file->statistics.warning_count + file->statistics.error_count < 1) { + return; + } + + printf("File %s generated ", file->path); + + if (file->statistics.info_count > 0) { + printf("%ld notice(s) ", file->statistics.info_count); + } + + if (file->statistics.warning_count > 0) { + printf("%ld warning(s) ", file->statistics.warning_count); + } + + if (file->statistics.error_count > 0) { + printf("%ld error(s) ", file->statistics.error_count); + } + + printf("\n\n"); +} + +void print_unit_statistics(ModuleFileStack *file_stack) { + FileDiagnosticStatistics stats; + stats.info_count = 0; + stats.warning_count = 0; + stats.error_count = 0; + + for (size_t i = 0; i < file_stack->files->len; i++) { + ModuleFile *file = (ModuleFile *) file_stack->files->data; + + stats.info_count += file->statistics.warning_count; + stats.warning_count += file->statistics.warning_count; + stats.error_count += file->statistics.error_count; + } + + printf("%d files generated ", file_stack->files->len); + + if (stats.info_count > 0) { + printf("%ld notice(s) ", stats.info_count); + } + + if (stats.warning_count > 0) { + printf("%ld warning(s) ", stats.warning_count); + } + + if (stats.error_count > 0) { + printf("%ld error(s) ", stats.error_count); + } + + printf("\n\n"); +} diff --git a/src/io/files.h b/src/io/files.h new file mode 100644 index 0000000..5441805 --- /dev/null +++ b/src/io/files.h @@ -0,0 +1,77 @@ +// +// Created by servostar on 5/30/24. +// + +#ifndef GEMSTONE_FILES_H +#define GEMSTONE_FILES_H + +#include +#include + +typedef struct FileDiagnosticStatistics_t { + size_t error_count; + size_t warning_count; + size_t info_count; +} FileDiagnosticStatistics; + +typedef struct ModuleFile_t { + const char *path; + FILE *handle; + FileDiagnosticStatistics statistics; +} ModuleFile; + +typedef struct ModuleFileStack_t { + GArray *files; +} ModuleFileStack; + +typedef enum Message_t { + Info, + Warning, + Error +} Message; + +typedef struct TokenLocation_t { + unsigned long int line_start; + unsigned long int col_start; + unsigned long int line_end; + unsigned long int col_end; +} TokenLocation; + +/** + * @brief Add a new file to the file stack. + * @attention The file handle returned will be invalid + * @param stack + * @param path + * @return A new file module + */ +[[gnu::nonnull(1), gnu::nonnull(2)]] +ModuleFile *push_file(ModuleFileStack *stack, const char *path); + +/** + * @brief Delete all files in the stack and the stack itself + * @param stack + */ +[[gnu::nonnull(1)]] +void delete_files(ModuleFileStack *stack); + +/** + * Create a new token location + * @param line_start + * @param col_start + * @param line_end + * @param col_end + * @return + */ +TokenLocation new_location(unsigned long int line_start, unsigned long int col_start, unsigned long int line_end, + unsigned long int col_end); + +[[gnu::nonnull(1), gnu::nonnull(2)]] +void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, const char *message); + +[[gnu::nonnull(1)]] +void print_file_statistics(ModuleFile *file); + +[[gnu::nonnull(1)]] +void print_unit_statistics(ModuleFileStack *file_stack); + +#endif //GEMSTONE_FILES_H diff --git a/src/lex/util.c b/src/lex/util.c index b5b92ac..81f2855 100644 --- a/src/lex/util.c +++ b/src/lex/util.c @@ -25,6 +25,16 @@ void lex_init(void) { atexit(lex_deinit); } +void lex_reset(void) { + eof = 0; + nRow = 0; + nBuffer = 0; + lBuffer = 0; + nTokenStart = 0; + nTokenLength = 0; + nTokenNextStart = 0; +} + void beginToken(char *t) { nTokenStart = nTokenNextStart; nTokenLength = (int) strlen(t); @@ -41,7 +51,7 @@ int nextChar(char *dst) { if (eof) return 0; - + while (nBuffer >= lBuffer) { frc = getNextLine(); if (frc != 0) { @@ -57,7 +67,7 @@ int nextChar(char *dst) { int getNextLine(void) { char *p; - + nBuffer = 0; nTokenStart = -1; nTokenNextStart = 1; diff --git a/src/lex/util.h b/src/lex/util.h index 12e0837..6939526 100644 --- a/src/lex/util.h +++ b/src/lex/util.h @@ -16,6 +16,8 @@ extern char* buffer; */ void lex_init(void); +void lex_reset(void); + /** * @brief Begin counting a new token. This will fill the global struct yylloc. * @param t the text of the token. Must be null terminated diff --git a/src/main.c b/src/main.c index 27bca44..0b75508 100644 --- a/src/main.c +++ b/src/main.c @@ -4,11 +4,52 @@ #include #include #include +#include +#include -#define LOG_LEVEL LOG_LEVEL_DEBUG +extern void yyrestart(FILE *); -extern FILE *yyin; +[[maybe_unused]] AST_NODE_PTR root; +[[maybe_unused]] +ModuleFile *current_file; + +/** + * @brief Compile the specified file into AST + * @param ast + * @param file + * @return EXIT_SUCCESS in case the parsing was success full anything lese if not + */ +[[nodiscard("AST may be in invalid state")]] +[[gnu::nonnull(1), gnu::nonnull(1)]] +static size_t compile_file_to_ast(AST_NODE_PTR ast, ModuleFile *file) { + assert(file->path != NULL); + assert(ast != NULL); + + file->handle = fopen(file->path, "r"); + + if (file->handle == NULL) { + INFO("unable to open file: %s", file->path); + return 1; + } + + DEBUG("parsing file: %s", file->path); + // setup global state + root = ast; + current_file = file; + yyin = file->handle; + yyrestart(yyin); + lex_reset(); + + yyparse(); + + // clean up global state + // current_file = NULL; + root = NULL; + yyin = NULL; + + return 0; +} /** * @brief Log a debug message to inform about beginning exit procedures @@ -22,9 +63,9 @@ void notify_exit(void) { DEBUG("Exiting gemstone..."); } */ void close_file(void) { - if (NULL != yyin) { - fclose(yyin); - } + if (NULL != yyin) { + fclose(yyin); + } } /** @@ -32,52 +73,57 @@ void close_file(void) { * */ void setup(void) { - // setup preample + // setup preample - log_init(); - DEBUG("starting gemstone..."); + log_init(); + DEBUG("starting gemstone..."); #if LOG_LEVEL <= LOG_LEVEL_DEBUG - atexit(¬ify_exit); + atexit(¬ify_exit); #endif - // actual setup - AST_init(); + // actual setup + AST_init(); - col_init(); + col_init(); - lex_init(); + lex_init(); - DEBUG("finished starting up gemstone..."); + DEBUG("finished starting up gemstone..."); } int main(int argc, char *argv[]) { - setup(); - atexit(close_file); + setup(); + atexit(close_file); - // Check for file input as argument - if (2 != argc) { - INFO("Usage: %s \n", argv[0]); - PANIC("No File could be found"); - } + ModuleFileStack files; + files.files = NULL; - // filename as first argument - char *filename = argv[1]; + for (int i = 1; i < argc; i++) { + printf("Compiling file: %s\n\n", argv[i]); - FILE *file = fopen(filename, "r"); + TokenLocation location = { + .line_start = 0, + .line_end = 0, + .col_start = 0, + .col_end = 0 + }; + AST_NODE_PTR ast = AST_new_node(location, AST_Module, NULL); + ModuleFile *file = push_file(&files, argv[i]); - if (NULL == file) { - PANIC("File couldn't be opened!"); - } - yyin = file; + if (compile_file_to_ast(ast, file) == EXIT_SUCCESS) { + // TODO: parse AST to semantic values + // TODO: backend codegen + } - root = AST_new_node(AST_Module, NULL); - yyparse(); + AST_delete_node(ast); - FILE *output = fopen("test.txt", "w"); - AST_fprint_graphviz(output, root); - fclose(output); - AST_delete_node(root); - return 0; + print_file_statistics(file); + } + + print_unit_statistics(&files); + + delete_files(&files); + return 0; } diff --git a/src/sys/log.h b/src/sys/log.h index 6b8991d..50fded1 100644 --- a/src/sys/log.h +++ b/src/sys/log.h @@ -10,7 +10,7 @@ #define LOG_LEVEL_INFORMATION 1 #define LOG_LEVEL_DEBUG 0 -#define LOG_LEVEL LOG_LEVEL_DEBUG +#define LOG_LEVEL LOG_LEVEL_ERROR #define LOG_STRING_PANIC "Critical" #define LOG_STRING_FATAL "Fatal" diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 753c7bc..d599c8d 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -5,8 +5,9 @@ #include #include #include + #include extern int yylineno; - + extern ModuleFile* current_file; int yyerror(const char*); @@ -15,7 +16,8 @@ extern int yylex(); extern AST_NODE_PTR root; - + + #define new_loc() new_location(yylloc.first_line, yylloc.first_column, yylloc.last_line, yylloc.last_column) } %union { @@ -144,11 +146,11 @@ programbody: moduleimport {$$ = $1;} -expr: ValFloat {$$ = AST_new_node(AST_Float, $1);} - | ValInt {$$ = AST_new_node(AST_Int, $1);} - | ValMultistr {$$ = AST_new_node(AST_String, $1);} - | ValStr {$$ = AST_new_node(AST_String, $1);} - | Ident {$$ = AST_new_node(AST_Ident, $1);} +expr: ValFloat {$$ = AST_new_node(new_loc(), AST_Float, $1);} + | ValInt {$$ = AST_new_node(new_loc(), AST_Int, $1);} + | ValMultistr {$$ = AST_new_node(new_loc(), AST_String, $1);} + | ValStr {$$ = AST_new_node(new_loc(), AST_String, $1);} + | Ident {$$ = AST_new_node(new_loc(), AST_Ident, $1);} | operation {$$ = $1;} | boxaccess {$$ = $1;} | boxselfaccess{$$ = $1;} @@ -157,22 +159,22 @@ expr: ValFloat {$$ = AST_new_node(AST_Float, $1);} exprlist: expr ',' exprlist {AST_push_node($3, $1); $$ = $3;} - | expr {AST_NODE_PTR list = AST_new_node(AST_ExprList, NULL); + | expr {AST_NODE_PTR list = AST_new_node(new_loc(), AST_ExprList, NULL); AST_push_node(list, $1); $$ = list;}; argumentlist: argumentlist '(' exprlist ')' {AST_push_node($1, $3); $$ = $1;} - | '(' exprlist ')'{AST_NODE_PTR list = AST_new_node(AST_ArgList, NULL); + | '(' exprlist ')'{AST_NODE_PTR list = AST_new_node(new_loc(), AST_ArgList, NULL); AST_push_node(list, $2); $$ = list;} | argumentlist '(' ')' - | '(' ')'{AST_NODE_PTR list = AST_new_node(AST_ArgList, NULL); + | '(' ')'{AST_NODE_PTR list = AST_new_node(new_loc(), AST_ArgList, NULL); $$ = list;}; -fundef: KeyFun Ident paramlist '{' statementlist'}' {AST_NODE_PTR fun = AST_new_node(AST_Fun, NULL); - AST_NODE_PTR ident = AST_new_node(AST_Ident, $2); +fundef: KeyFun Ident paramlist '{' statementlist'}' {AST_NODE_PTR fun = AST_new_node(new_loc(), AST_Fun, NULL); + AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $2); AST_push_node(fun, ident); AST_push_node(fun, $3); AST_push_node(fun, $5); @@ -182,66 +184,66 @@ fundef: KeyFun Ident paramlist '{' statementlist'}' {AST_NODE_PTR fun = AST_new_ paramlist: paramlist '(' params ')' {AST_push_node($1, $3); $$ = $1;} | paramlist '(' ')'{$$ = $1;} - | '(' params ')' {AST_NODE_PTR list = AST_new_node(AST_List, NULL); + | '(' params ')' {AST_NODE_PTR list = AST_new_node(new_loc(), AST_List, NULL); AST_push_node(list, $2); $$ = list;} - | '(' ')' {$$ = AST_new_node(AST_List, NULL);}; + | '(' ')' {$$ = AST_new_node(new_loc(), AST_List, NULL);}; -params: IOqualifyier paramdecl ',' params {AST_NODE_PTR parameter = AST_new_node(AST_Parameter, NULL); +params: IOqualifyier paramdecl ',' params {AST_NODE_PTR parameter = AST_new_node(new_loc(), AST_Parameter, NULL); AST_push_node(parameter, $1); AST_push_node(parameter, $2); AST_push_node($4, parameter); $$ = $4;} - | IOqualifyier paramdecl {AST_NODE_PTR list = AST_new_node(AST_ParamList, NULL); - AST_NODE_PTR parameter = AST_new_node(AST_Parameter, NULL); + | IOqualifyier paramdecl {AST_NODE_PTR list = AST_new_node(new_loc(), AST_ParamList, NULL); + AST_NODE_PTR parameter = AST_new_node(new_loc(), AST_Parameter, NULL); AST_push_node(parameter, $1); AST_push_node(parameter, $2); AST_push_node(list, parameter); $$ = list;}; -IOqualifyier: KeyIn { AST_NODE_PTR in = AST_new_node(AST_Qualifyier, "in"); - AST_NODE_PTR list = AST_new_node(AST_List, NULL); +IOqualifyier: KeyIn { AST_NODE_PTR in = AST_new_node(new_loc(), AST_Qualifyier, "in"); + AST_NODE_PTR list = AST_new_node(new_loc(), AST_List, NULL); AST_push_node(list, in); $$ = list;} - | KeyOut{ AST_NODE_PTR out = AST_new_node(AST_Qualifyier, "out"); - AST_NODE_PTR list = AST_new_node(AST_List, NULL); + | KeyOut{ AST_NODE_PTR out = AST_new_node(new_loc(), AST_Qualifyier, "out"); + AST_NODE_PTR list = AST_new_node(new_loc(), AST_List, NULL); AST_push_node(list, out); $$ = list;} - | KeyIn KeyOut{ AST_NODE_PTR in = AST_new_node(AST_Qualifyier, "in"); - AST_NODE_PTR out = AST_new_node(AST_Qualifyier, "out"); - AST_NODE_PTR list = AST_new_node(AST_List, NULL); + | KeyIn KeyOut{ AST_NODE_PTR in = AST_new_node(new_loc(), AST_Qualifyier, "in"); + AST_NODE_PTR out = AST_new_node(new_loc(), AST_Qualifyier, "out"); + AST_NODE_PTR list = AST_new_node(new_loc(), AST_List, NULL); AST_push_node(list, in); AST_push_node(list, out); $$ = list;} - | KeyOut KeyIn{ AST_NODE_PTR in = AST_new_node(AST_Qualifyier, "in"); - AST_NODE_PTR out = AST_new_node(AST_Qualifyier, "out"); - AST_NODE_PTR list = AST_new_node(AST_List, NULL); + | KeyOut KeyIn{ AST_NODE_PTR in = AST_new_node(new_loc(), AST_Qualifyier, "in"); + AST_NODE_PTR out = AST_new_node(new_loc(), AST_Qualifyier, "out"); + AST_NODE_PTR list = AST_new_node(new_loc(), AST_List, NULL); AST_push_node(list, in); AST_push_node(list, out); $$ = list;} - | {$$ = AST_new_node(AST_List, NULL);}; + | {$$ = AST_new_node(new_loc(), AST_List, NULL);}; -paramdecl: type ':' Ident { AST_NODE_PTR paramdecl = AST_new_node(AST_ParamDecl, NULL); +paramdecl: type ':' Ident { AST_NODE_PTR paramdecl = AST_new_node(new_loc(), AST_ParamDecl, NULL); AST_push_node(paramdecl, $1); - AST_NODE_PTR ident = AST_new_node(AST_Ident, $3); + AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $3); AST_push_node(paramdecl, ident); $$ = paramdecl; DEBUG("Param-Declaration"); }; -box: KeyType KeyBox ':' Ident '{' boxbody '}' {AST_NODE_PTR box = AST_new_node(AST_Box, NULL); - AST_NODE_PTR ident = AST_new_node(AST_Ident, $4); +box: KeyType KeyBox ':' Ident '{' boxbody '}' {AST_NODE_PTR box = AST_new_node(new_loc(), AST_Box, NULL); + AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $4); AST_push_node(box, ident); AST_push_node(box, $6); $$ = box; DEBUG("Box"); } - | KeyType KeyBox ':' Ident '{' '}' {AST_NODE_PTR box = AST_new_node(AST_Box, NULL); - AST_NODE_PTR ident = AST_new_node(AST_Ident, $4); + | KeyType KeyBox ':' Ident '{' '}' {AST_NODE_PTR box = AST_new_node(new_loc(), AST_Box, NULL); + AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $4); AST_push_node(box, ident); $$ = box;}; boxbody: boxbody boxcontent {AST_push_node($1, $2); $$ = $1;} - | boxcontent {AST_NODE_PTR list = AST_new_node(AST_List, NULL); + | boxcontent {AST_NODE_PTR list = AST_new_node(new_loc(), AST_List, NULL); AST_push_node(list, $1); $$ = list;}; @@ -249,66 +251,66 @@ boxcontent: decl { $$ = $1;DEBUG("Box decl Content"); } | definition { $$ = $1;DEBUG("Box def Content"); } | fundef { $$ = $1;DEBUG("Box fun Content"); }; -boxselfaccess: KeySelf '.' Ident {AST_NODE_PTR boxselfaccess = AST_new_node(AST_List, NULL); - AST_NODE_PTR self = AST_new_node(AST_Ident, "self"); +boxselfaccess: KeySelf '.' Ident {AST_NODE_PTR boxselfaccess = AST_new_node(new_loc(), AST_List, NULL); + AST_NODE_PTR self = AST_new_node(new_loc(), AST_Ident, "self"); AST_push_node(boxselfaccess, self); - AST_NODE_PTR identlist = AST_new_node(AST_IdentList, NULL); - AST_NODE_PTR ident = AST_new_node(AST_Ident, $3); + AST_NODE_PTR identlist = AST_new_node(new_loc(), AST_IdentList, NULL); + AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $3); AST_push_node(identlist,ident); AST_push_node(boxselfaccess, identlist); $$ = boxselfaccess;} - | KeySelf '.' boxaccess {AST_NODE_PTR boxselfaccess = AST_new_node(AST_List, NULL); - AST_NODE_PTR self = AST_new_node(AST_Ident, "self"); + | KeySelf '.' boxaccess {AST_NODE_PTR boxselfaccess = AST_new_node(new_loc(), AST_List, NULL); + AST_NODE_PTR self = AST_new_node(new_loc(), AST_Ident, "self"); AST_push_node(boxselfaccess, self); AST_push_node(boxselfaccess, $3); $$ = boxselfaccess;}; -boxaccess: Ident '.' Ident {AST_NODE_PTR identlist = AST_new_node(AST_IdentList, NULL); - AST_NODE_PTR ident1 = AST_new_node(AST_Ident, $1); - AST_NODE_PTR ident2 = AST_new_node(AST_Ident, $3); +boxaccess: Ident '.' Ident {AST_NODE_PTR identlist = AST_new_node(new_loc(), AST_IdentList, NULL); + AST_NODE_PTR ident1 = AST_new_node(new_loc(), AST_Ident, $1); + AST_NODE_PTR ident2 = AST_new_node(new_loc(), AST_Ident, $3); AST_push_node(identlist,ident1); AST_push_node(identlist,ident2); $$ = identlist;} - | Ident '.' boxaccess {AST_NODE_PTR ident = AST_new_node(AST_Ident, $1); + | Ident '.' boxaccess {AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $1); AST_push_node($3,ident); $$ = $3;}; -boxcall: boxaccess argumentlist {AST_NODE_PTR boxcall = AST_new_node(AST_Call, NULL); +boxcall: boxaccess argumentlist {AST_NODE_PTR boxcall = AST_new_node(new_loc(), AST_Call, NULL); AST_push_node(boxcall, $1); AST_push_node(boxcall, $2); $$ = boxcall;} - | boxselfaccess argumentlist {AST_NODE_PTR boxcall = AST_new_node(AST_Call, NULL); + | boxselfaccess argumentlist {AST_NODE_PTR boxcall = AST_new_node(new_loc(), AST_Call, NULL); AST_push_node(boxcall, $1); AST_push_node(boxcall, $2); $$ = boxcall;}; -typecast: expr KeyAs type %prec KeyAs {AST_NODE_PTR cast = AST_new_node(AST_Typecast, NULL); +typecast: expr KeyAs type %prec KeyAs {AST_NODE_PTR cast = AST_new_node(new_loc(), AST_Typecast, NULL); AST_push_node(cast, $1); AST_push_node(cast, $3); $$ = cast; DEBUG("Type-Cast"); }; -reinterpretcast: '(' type ')' expr { AST_NODE_PTR cast = AST_new_node(AST_Transmute, NULL); +reinterpretcast: '(' type ')' expr { AST_NODE_PTR cast = AST_new_node(new_loc(), AST_Transmute, NULL); AST_push_node(cast, $4); AST_push_node(cast, $2); $$ = cast; DEBUG("Reinterpret-Cast"); }; -funcall: Ident argumentlist {AST_NODE_PTR funcall = AST_new_node(AST_Call, NULL); - AST_NODE_PTR ident = AST_new_node(AST_Ident, $1); +funcall: Ident argumentlist {AST_NODE_PTR funcall = AST_new_node(new_loc(), AST_Call, NULL); + AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $1); AST_push_node(funcall, ident); AST_push_node(funcall, $2); $$ = funcall; DEBUG("Function call"); }; -moduleimport: KeyImport ValStr {$$ = AST_new_node(AST_Import, $2); +moduleimport: KeyImport ValStr {$$ = AST_new_node(new_loc(), AST_Import, $2); DEBUG("Module-Import"); }; statementlist: statementlist statement {AST_push_node($1, $2); $$ = $1;} - | statement {AST_NODE_PTR list = AST_new_node(AST_StmtList, NULL); + | statement {AST_NODE_PTR list = AST_new_node(new_loc(), AST_StmtList, NULL); AST_push_node(list, $1); $$ = list;}; @@ -320,16 +322,16 @@ statement: assign {$$ = $1;} | funcall {$$ = $1;} | boxcall{$$ = $1;}; -branchif: KeyIf expr '{' statementlist '}' { AST_NODE_PTR branch = AST_new_node(AST_If, NULL); +branchif: KeyIf expr '{' statementlist '}' { AST_NODE_PTR branch = AST_new_node(new_loc(), AST_If, NULL); AST_push_node(branch, $2); AST_push_node(branch, $4); $$ = branch; }; -branchelse: KeyElse '{' statementlist '}' { AST_NODE_PTR branch = AST_new_node(AST_Else, NULL); +branchelse: KeyElse '{' statementlist '}' { AST_NODE_PTR branch = AST_new_node(new_loc(), AST_Else, NULL); AST_push_node(branch, $3); $$ = branch; }; -branchelseif: KeyElse KeyIf expr '{' statementlist '}' { AST_NODE_PTR branch = AST_new_node(AST_IfElse, NULL); +branchelseif: KeyElse KeyIf expr '{' statementlist '}' { AST_NODE_PTR branch = AST_new_node(new_loc(), AST_IfElse, NULL); AST_push_node(branch, $3); AST_push_node(branch, $5); $$ = branch; }; @@ -337,49 +339,49 @@ branchelseif: KeyElse KeyIf expr '{' statementlist '}' { AST_NODE_PTR branch = A branchfull: branchhalf { $$ = $1;}; |branchhalf branchelse { AST_push_node($1 , $2); $$ = $1; } -branchhalf: branchif { AST_NODE_PTR branch = AST_new_node(AST_Stmt, NULL); +branchhalf: branchif { AST_NODE_PTR branch = AST_new_node(new_loc(), AST_Stmt, NULL); AST_push_node(branch, $1); $$ = branch; } | branchhalf branchelseif { AST_push_node($1 , $2); $$ = $1; }; -while: KeyWhile expr '{' statementlist '}' {AST_NODE_PTR whilenode = AST_new_node(AST_While, NULL); +while: KeyWhile expr '{' statementlist '}' {AST_NODE_PTR whilenode = AST_new_node(new_loc(), AST_While, NULL); AST_push_node(whilenode, $2); AST_push_node(whilenode, $4); $$ = whilenode;}; -identlist: Ident ',' identlist {AST_NODE_PTR ident = AST_new_node(AST_Ident, $1); +identlist: Ident ',' identlist {AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $1); AST_push_node($3, ident); $$ = $3;} - | Ident {AST_NODE_PTR list = AST_new_node(AST_IdentList, NULL); - AST_NODE_PTR ident = AST_new_node(AST_Ident, $1); + | Ident {AST_NODE_PTR list = AST_new_node(new_loc(), AST_IdentList, NULL); + AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $1); AST_push_node(list, ident); $$ = list;}; -decl: type ':' identlist {AST_NODE_PTR decl = AST_new_node(AST_Decl, NULL); +decl: type ':' identlist {AST_NODE_PTR decl = AST_new_node(new_loc(), AST_Decl, NULL); AST_push_node(decl, $1); AST_push_node(decl, $3); $$ = decl;} - | storagequalifier type ':' identlist {AST_NODE_PTR decl = AST_new_node(AST_Decl, NULL); + | storagequalifier type ':' identlist {AST_NODE_PTR decl = AST_new_node(new_loc(), AST_Decl, NULL); AST_push_node(decl, $1); AST_push_node(decl, $2); AST_push_node(decl, $4); $$ = decl;} -definition: decl '=' expr { AST_NODE_PTR def = AST_new_node(AST_Def, NULL); +definition: decl '=' expr { AST_NODE_PTR def = AST_new_node(new_loc(), AST_Def, NULL); AST_push_node(def, $1); AST_push_node(def, $3); $$ = def; DEBUG("Definition"); }; -storagequalifier: KeyGlobal {$$ = AST_new_node(AST_Storage, "global");} - | KeyStatic {$$ = AST_new_node(AST_Storage, "static");} - | KeyLocal {$$ = AST_new_node(AST_Storage, "local");}; +storagequalifier: KeyGlobal {$$ = AST_new_node(new_loc(), AST_Storage, "global");} + | KeyStatic {$$ = AST_new_node(new_loc(), AST_Storage, "static");} + | KeyLocal {$$ = AST_new_node(new_loc(), AST_Storage, "local");}; -assign: Ident '=' expr { AST_NODE_PTR assign = AST_new_node(AST_Assign, NULL); - AST_NODE_PTR ident = AST_new_node(AST_Ident, $1); +assign: Ident '=' expr { AST_NODE_PTR assign = AST_new_node(new_loc(), AST_Assign, NULL); + AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $1); AST_push_node(assign, ident); AST_push_node(assign, $3); $$ = assign; @@ -388,60 +390,60 @@ assign: Ident '=' expr { AST_NODE_PTR assign = AST_new_node(AST_Assign, NULL); | boxaccess '=' expr | boxselfaccess '=' expr ; -sign: KeySigned {$$ = AST_new_node(AST_Sign, "signed");} - | KeyUnsigned{$$ = AST_new_node(AST_Sign, "unsigned");}; +sign: KeySigned {$$ = AST_new_node(new_loc(), AST_Sign, "signed");} + | KeyUnsigned{$$ = AST_new_node(new_loc(), AST_Sign, "unsigned");}; -typedef: KeyType type':' Ident {AST_NODE_PTR typeDef = AST_new_node(AST_Typedef, NULL); +typedef: KeyType type':' Ident {AST_NODE_PTR typeDef = AST_new_node(new_loc(), AST_Typedef, NULL); AST_push_node(typeDef, $2); - AST_NODE_PTR ident = AST_new_node(AST_Ident, $4); + AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $4); AST_push_node(typeDef, ident); $$ = typeDef;}; -scale: scale KeyShort {AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "short"); +scale: scale KeyShort {AST_NODE_PTR shortnode = AST_new_node(new_loc(), AST_Scale, "short"); AST_push_node($1, shortnode); $$ = $1;} - | scale KeyHalf {AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "half"); + | scale KeyHalf {AST_NODE_PTR shortnode = AST_new_node(new_loc(), AST_Scale, "half"); AST_push_node($1, shortnode); $$ = $1;} - | scale KeyLong {AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "long"); + | scale KeyLong {AST_NODE_PTR shortnode = AST_new_node(new_loc(), AST_Scale, "long"); AST_push_node($1, shortnode); $$ = $1;} - | scale KeyDouble {AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "double"); + | scale KeyDouble {AST_NODE_PTR shortnode = AST_new_node(new_loc(), AST_Scale, "double"); AST_push_node($1, shortnode); $$ = $1;} - | KeyShort {AST_NODE_PTR scale = AST_new_node(AST_List, NULL); - AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "short"); + | KeyShort {AST_NODE_PTR scale = AST_new_node(new_loc(), AST_List, NULL); + AST_NODE_PTR shortnode = AST_new_node(new_loc(), AST_Scale, "short"); AST_push_node(scale, shortnode); $$ = scale;} - | KeyHalf {AST_NODE_PTR scale = AST_new_node(AST_List, NULL); - AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "half"); + | KeyHalf {AST_NODE_PTR scale = AST_new_node(new_loc(), AST_List, NULL); + AST_NODE_PTR shortnode = AST_new_node(new_loc(), AST_Scale, "half"); AST_push_node(scale, shortnode); $$ = scale;} - | KeyLong {AST_NODE_PTR scale = AST_new_node(AST_List, NULL); - AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "long"); + | KeyLong {AST_NODE_PTR scale = AST_new_node(new_loc(), AST_List, NULL); + AST_NODE_PTR shortnode = AST_new_node(new_loc(), AST_Scale, "long"); AST_push_node(scale, shortnode); $$ = scale;} - | KeyDouble {AST_NODE_PTR scale = AST_new_node(AST_List, NULL); - AST_NODE_PTR shortnode = AST_new_node(AST_Scale, "double"); + | KeyDouble {AST_NODE_PTR scale = AST_new_node(new_loc(), AST_List, NULL); + AST_NODE_PTR shortnode = AST_new_node(new_loc(), AST_Scale, "double"); AST_push_node(scale, shortnode); $$ = scale;}; -typekind: Ident {$$ = AST_new_node(AST_Typekind, $1);} - | KeyInt {$$ = AST_new_node(AST_Typekind, "int");} - | KeyFloat {$$ = AST_new_node(AST_Typekind, "float");}; +typekind: Ident {$$ = AST_new_node(new_loc(), AST_Typekind, $1);} + | KeyInt {$$ = AST_new_node(new_loc(), AST_Typekind, "int");} + | KeyFloat {$$ = AST_new_node(new_loc(), AST_Typekind, "float");}; -type: typekind {AST_NODE_PTR type = AST_new_node(AST_Type, NULL); +type: typekind {AST_NODE_PTR type = AST_new_node(new_loc(), AST_Type, NULL); AST_push_node(type, $1); $$ = type;} - | scale typekind {AST_NODE_PTR type = AST_new_node(AST_Type, NULL); + | scale typekind {AST_NODE_PTR type = AST_new_node(new_loc(), AST_Type, NULL); AST_push_node(type, $1); AST_push_node(type, $2); $$ = type;} - | sign typekind {AST_NODE_PTR type = AST_new_node(AST_Type, NULL); + | sign typekind {AST_NODE_PTR type = AST_new_node(new_loc(), AST_Type, NULL); AST_push_node(type, $1); AST_push_node(type, $2); $$ = type;} - | sign scale typekind {AST_NODE_PTR type = AST_new_node(AST_Type, NULL); + | sign scale typekind {AST_NODE_PTR type = AST_new_node(new_loc(), AST_Type, NULL); AST_push_node(type, $1); AST_push_node(type, $2); AST_push_node(type, $3); @@ -452,136 +454,74 @@ operation: oparith {$$ = $1;} | opbool {$$ = $1;} | opbit {$$ = $1;}; -oparith: expr '+' expr {AST_NODE_PTR add = AST_new_node(AST_Add, NULL); +oparith: expr '+' expr {AST_NODE_PTR add = AST_new_node(new_loc(), AST_Add, NULL); AST_push_node(add, $1); AST_push_node(add, $3); $$ = add;} - | expr '-' expr {AST_NODE_PTR subtract = AST_new_node(AST_Sub, NULL); + | expr '-' expr {AST_NODE_PTR subtract = AST_new_node(new_loc(), AST_Sub, NULL); AST_push_node(subtract, $1); AST_push_node(subtract, $3); $$ = subtract;} - | expr '*' expr {AST_NODE_PTR mul = AST_new_node(AST_Mul, NULL); + | expr '*' expr {AST_NODE_PTR mul = AST_new_node(new_loc(), AST_Mul, NULL); AST_push_node(mul, $1); AST_push_node(mul, $3); $$ = mul;} - | expr '/' expr {AST_NODE_PTR div = AST_new_node(AST_Div, NULL); + | expr '/' expr {AST_NODE_PTR div = AST_new_node(new_loc(), AST_Div, NULL); AST_push_node(div, $1); AST_push_node(div, $3); $$ = div;} - | '-' expr %prec '*'{AST_NODE_PTR negator = AST_new_node(AST_Negate, NULL); + | '-' expr %prec '*'{AST_NODE_PTR negator = AST_new_node(new_loc(), AST_Negate, NULL); AST_push_node(negator, $2); $$ = negator;}; -oplogic: expr OpEquals expr {AST_NODE_PTR equals = AST_new_node(AST_Eq, NULL); +oplogic: expr OpEquals expr {AST_NODE_PTR equals = AST_new_node(new_loc(), AST_Eq, NULL); AST_push_node(equals, $1); AST_push_node(equals, $3); $$ = equals;} - | expr '<' expr {AST_NODE_PTR less = AST_new_node(AST_Less, NULL); + | expr '<' expr {AST_NODE_PTR less = AST_new_node(new_loc(), AST_Less, NULL); AST_push_node(less, $1); AST_push_node(less, $3); $$ = less;} - | expr '>' expr{AST_NODE_PTR greater = AST_new_node(AST_Greater, NULL); + | expr '>' expr{AST_NODE_PTR greater = AST_new_node(new_loc(), AST_Greater, NULL); AST_push_node(greater, $1); AST_push_node(greater, $3); $$ = greater;}; -opbool: expr OpAnd expr {AST_NODE_PTR and = AST_new_node(AST_BoolAnd, NULL); +opbool: expr OpAnd expr {AST_NODE_PTR and = AST_new_node(new_loc(), AST_BoolAnd, NULL); AST_push_node(and, $1); AST_push_node(and, $3); $$ = and;} - | expr OpOr expr{AST_NODE_PTR or = AST_new_node(AST_BoolOr, NULL); + | expr OpOr expr{AST_NODE_PTR or = AST_new_node(new_loc(), AST_BoolOr, NULL); AST_push_node(or, $1); AST_push_node(or, $3); $$ = or;} - | expr OpXor expr{AST_NODE_PTR xor = AST_new_node(AST_BoolXor, NULL); + | expr OpXor expr{AST_NODE_PTR xor = AST_new_node(new_loc(), AST_BoolXor, NULL); AST_push_node(xor, $1); AST_push_node(xor, $3); $$ = xor;} - | OpNot expr %prec OpAnd{AST_NODE_PTR not = AST_new_node(AST_BoolNot, NULL); + | OpNot expr %prec OpAnd{AST_NODE_PTR not = AST_new_node(new_loc(), AST_BoolNot, NULL); AST_push_node(not, $2); $$ = not;}; -opbit: expr OpBitand expr {AST_NODE_PTR and = AST_new_node(AST_BitAnd, NULL); +opbit: expr OpBitand expr {AST_NODE_PTR and = AST_new_node(new_loc(), AST_BitAnd, NULL); AST_push_node(and, $1); AST_push_node(and, $3); $$ = and;} - | expr OpBitor expr{AST_NODE_PTR or = AST_new_node(AST_BitOr, NULL); + | expr OpBitor expr{AST_NODE_PTR or = AST_new_node(new_loc(), AST_BitOr, NULL); AST_push_node(or, $1); AST_push_node(or, $3); $$ = or;} - | expr OpBitxor expr{AST_NODE_PTR xor = AST_new_node(AST_BitXor, NULL); + | expr OpBitxor expr{AST_NODE_PTR xor = AST_new_node(new_loc(), AST_BitXor, NULL); AST_push_node(xor, $1); AST_push_node(xor, $3); $$ = xor;} - | OpBitnot expr %prec OpBitand{AST_NODE_PTR not = AST_new_node(AST_BitNot, NULL); + | OpBitnot expr %prec OpBitand{AST_NODE_PTR not = AST_new_node(new_loc(), AST_BitNot, NULL); AST_push_node(not, $2); $$ = not;}; %% - -const char* ERROR = "error"; -const char* WARNING = "warning"; -const char* NOTE = "note"; - -int print_message(const char* kind, const char* message) { - // number of characters written - int char_count = 0; - // highlight to use - char* HIGHLIGHT = CYAN; - - // convert message kind into color - if (kind == ERROR) { - HIGHLIGHT = RED; - } else if (kind == WARNING) { - HIGHLIGHT = YELLOW; - } - - // print message - char_count += printf("%sfilename:%d:%d%s:%s%s %s: %s%s\n", BOLD, yylloc.first_line, yylloc.first_column, RESET, HIGHLIGHT, BOLD, kind, RESET, message); - - // print line in which error occurred - - char_count += printf(" %4d | ", yylloc.first_line); - - for (int i = 0; i < yylloc.first_column - 1; i++) { - if (buffer[i] == '\n') { - break; - } - printf("%c", buffer[i]); - } - - char_count += printf("%s%s", BOLD, HIGHLIGHT); - - for (int i = yylloc.first_column - 1; i < yylloc.last_column; i++) { - if (buffer[i] == '\n') { - break; - } - char_count += printf("%c", buffer[i]); - } - - char_count += printf("%s", RESET); - - for (int i = yylloc.last_column; buffer[i] != '\0' && buffer[i] != '\n'; i++) { - printf("%c", buffer[i]); - } - - char_count += printf("\n | "); - - for (int i = 0; i < yylloc.first_column - 1; i++) { - char_count += printf(" "); - } - - char_count += printf("%s^", HIGHLIGHT); - - for (int i = 0; i < yylloc.last_column - yylloc.first_column; i++) { - printf("~"); - } - - char_count += printf("%s\n\n", RESET); - - return char_count; -} - int yyerror(const char *s) { - return print_message(ERROR, s); + TokenLocation location = new_loc(); + print_diagnostic(current_file, &location, Error, s); + return 0; } \ No newline at end of file From cb8c7647bf859513ec815221b054fbd77cd1aba3 Mon Sep 17 00:00:00 2001 From: servostar Date: Thu, 30 May 2024 21:43:14 +0200 Subject: [PATCH 42/43] fixed: failing tests due to changes --- CMakeLists.txt | 2 +- src/io/files.c | 11 +++++++++++ src/io/files.h | 2 ++ src/sys/log.h | 2 +- tests/ast/CMakeLists.txt | 17 +++++++++++++++++ tests/ast/build_tree.c | 16 ++++++++-------- tests/ast/gen_graph.c | 12 ++++++------ tests/ast/print_graphviz.c | 16 ++++++++-------- tests/ast/print_node.c | 2 +- tests/logging/CMakeLists.txt | 11 +++++++++++ tests/logging/level.c | 2 ++ tests/logging/output.c | 2 ++ 12 files changed, 70 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b304447..cab901a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,7 @@ add_custom_command(OUTPUT ${YACC_GENERATED_SOURCE_FILE} find_package(PkgConfig REQUIRED) pkg_search_module(GLIB REQUIRED IMPORTED_TARGET glib-2.0) - + # ------------------------------------------------ # # Source # # ------------------------------------------------ # diff --git a/src/io/files.c b/src/io/files.c index 97daed1..2d4fda7 100644 --- a/src/io/files.c +++ b/src/io/files.c @@ -170,6 +170,17 @@ TokenLocation new_location(unsigned long int line_start, unsigned long int col_s return location; } +TokenLocation empty_location(void) { + TokenLocation location; + + location.line_start = 0; + location.line_end = 0; + location.col_start = 0; + location.col_end = 0; + + return location; +} + void print_file_statistics(ModuleFile *file) { if (file->statistics.info_count + file->statistics.warning_count + file->statistics.error_count < 1) { return; diff --git a/src/io/files.h b/src/io/files.h index 5441805..076b8d0 100644 --- a/src/io/files.h +++ b/src/io/files.h @@ -65,6 +65,8 @@ void delete_files(ModuleFileStack *stack); TokenLocation new_location(unsigned long int line_start, unsigned long int col_start, unsigned long int line_end, unsigned long int col_end); +TokenLocation empty_location(void); + [[gnu::nonnull(1), gnu::nonnull(2)]] void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, const char *message); diff --git a/src/sys/log.h b/src/sys/log.h index 50fded1..6b8991d 100644 --- a/src/sys/log.h +++ b/src/sys/log.h @@ -10,7 +10,7 @@ #define LOG_LEVEL_INFORMATION 1 #define LOG_LEVEL_DEBUG 0 -#define LOG_LEVEL LOG_LEVEL_ERROR +#define LOG_LEVEL LOG_LEVEL_DEBUG #define LOG_STRING_PANIC "Critical" #define LOG_STRING_FATAL "Fatal" diff --git a/tests/ast/CMakeLists.txt b/tests/ast/CMakeLists.txt index 455130b..88007e4 100644 --- a/tests/ast/CMakeLists.txt +++ b/tests/ast/CMakeLists.txt @@ -2,6 +2,14 @@ include(CTest) include_directories(${PROJECT_SOURCE_DIR}/src) +# ------------------------------------------------ # +# Setup Glib 2.0 # +# ------------------------------------------------ # + +find_package(PkgConfig REQUIRED) +pkg_search_module(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +include_directories(PRIVATE ${GLIB_INCLUDE_DIRS}) + # ------------------------------------------------------- # # CTEST 1 # test building the syntax tree @@ -9,11 +17,14 @@ include_directories(${PROJECT_SOURCE_DIR}/src) add_executable(ast_build_tree ${PROJECT_SOURCE_DIR}/src/ast/ast.c ${PROJECT_SOURCE_DIR}/src/sys/log.c + ${PROJECT_SOURCE_DIR}/src/io/files.c + ${PROJECT_SOURCE_DIR}/src/sys/col.c build_tree.c) set_target_properties(ast_build_tree PROPERTIES OUTPUT_NAME "build_tree" RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/tests/ast) +target_link_libraries(ast_build_tree PkgConfig::GLIB) add_test(NAME ast_build_tree WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND python ${GEMSTONE_TEST_DIR}/ast/test_ast.py check_build_tree) @@ -25,11 +36,14 @@ add_test(NAME ast_build_tree add_executable(ast_print_node ${PROJECT_SOURCE_DIR}/src/ast/ast.c ${PROJECT_SOURCE_DIR}/src/sys/log.c + ${PROJECT_SOURCE_DIR}/src/io/files.c + ${PROJECT_SOURCE_DIR}/src/sys/col.c print_node.c) set_target_properties(ast_print_node PROPERTIES OUTPUT_NAME "print_node" RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/tests/ast) +target_link_libraries(ast_print_node PkgConfig::GLIB) add_test(NAME ast_print_node WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND python ${GEMSTONE_TEST_DIR}/ast/test_ast.py check_print_node) @@ -41,11 +55,14 @@ add_test(NAME ast_print_node add_executable(ast_graphviz ${PROJECT_SOURCE_DIR}/src/ast/ast.c ${PROJECT_SOURCE_DIR}/src/sys/log.c + ${PROJECT_SOURCE_DIR}/src/io/files.c + ${PROJECT_SOURCE_DIR}/src/sys/col.c print_graphviz.c) set_target_properties(ast_graphviz PROPERTIES OUTPUT_NAME "print_graphviz" RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/tests/ast) +target_link_libraries(ast_graphviz PkgConfig::GLIB) add_test(NAME ast_graphviz WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND python ${GEMSTONE_TEST_DIR}/ast/test_ast.py check_print_graphviz) diff --git a/tests/ast/build_tree.c b/tests/ast/build_tree.c index dec7b85..2d2459b 100644 --- a/tests/ast/build_tree.c +++ b/tests/ast/build_tree.c @@ -6,22 +6,22 @@ #include void generate_statement(const AST_NODE_PTR stmt) { - const AST_NODE_PTR add = AST_new_node(AST_Add, NULL); + const AST_NODE_PTR add = AST_new_node(empty_location(), AST_Add, NULL); - AST_push_node(add, AST_new_node(AST_Int, "3")); - AST_push_node(add, AST_new_node(AST_Int, "6")); + AST_push_node(add, AST_new_node(empty_location(), AST_Int, "3")); + AST_push_node(add, AST_new_node(empty_location(), AST_Int, "6")); AST_push_node(stmt, add); } void generate_branch(const AST_NODE_PTR stmt) { - const AST_NODE_PTR branch = AST_new_node(AST_If, NULL); - const AST_NODE_PTR gt = AST_new_node(AST_Greater, NULL); + const AST_NODE_PTR branch = AST_new_node(empty_location(), AST_If, NULL); + const AST_NODE_PTR gt = AST_new_node(empty_location(), AST_Greater, NULL); AST_push_node(branch, gt); - AST_push_node(gt, AST_new_node(AST_Float, "2.3")); - AST_push_node(gt, AST_new_node(AST_Float, "0.79")); + AST_push_node(gt, AST_new_node(empty_location(), AST_Float, "2.3")); + AST_push_node(gt, AST_new_node(empty_location(), AST_Float, "0.79")); AST_push_node(stmt, branch); @@ -30,7 +30,7 @@ void generate_branch(const AST_NODE_PTR stmt) { int main(void) { - const AST_NODE_PTR root = AST_new_node(AST_Stmt, NULL); + const AST_NODE_PTR root = AST_new_node(empty_location(), AST_Stmt, NULL); generate_branch(root); diff --git a/tests/ast/gen_graph.c b/tests/ast/gen_graph.c index 186d571..c4e2f92 100644 --- a/tests/ast/gen_graph.c +++ b/tests/ast/gen_graph.c @@ -7,15 +7,15 @@ int main(void) { - struct AST_Node_t* node = AST_new_node(AST_If, NULL); + struct AST_Node_t* node = AST_new_node(empty_location(), AST_If, NULL); - struct AST_Node_t* child = AST_new_node(AST_Add, NULL); - AST_push_node(child, AST_new_node(AST_Int, "43")); - AST_push_node(child, AST_new_node(AST_Int, "9")); + struct AST_Node_t* child = AST_new_node(empty_location(), AST_Add, NULL); + AST_push_node(child, AST_new_node(empty_location(), AST_Int, "43")); + AST_push_node(child, AST_new_node(empty_location(), AST_Int, "9")); AST_push_node(node, child); - AST_push_node(node, AST_new_node(AST_Expr, NULL)); - AST_push_node(node, AST_new_node(AST_Expr, NULL)); + AST_push_node(node, AST_new_node(empty_location(), AST_Expr, NULL)); + AST_push_node(node, AST_new_node(empty_location(), AST_Expr, NULL)); FILE* out = fopen("ast.gv", "w+"); // convert this file ^^^^^^ diff --git a/tests/ast/print_graphviz.c b/tests/ast/print_graphviz.c index 6df64b4..c0f69af 100644 --- a/tests/ast/print_graphviz.c +++ b/tests/ast/print_graphviz.c @@ -6,22 +6,22 @@ #include void generate_statement(const AST_NODE_PTR stmt) { - const AST_NODE_PTR add = AST_new_node(AST_Add, NULL); + const AST_NODE_PTR add = AST_new_node(empty_location(), AST_Add, NULL); - AST_push_node(add, AST_new_node(AST_Int, "3")); - AST_push_node(add, AST_new_node(AST_Int, "6")); + AST_push_node(add, AST_new_node(empty_location(), AST_Int, "3")); + AST_push_node(add, AST_new_node(empty_location(), AST_Int, "6")); AST_push_node(stmt, add); } void generate_branch(const AST_NODE_PTR stmt) { - const AST_NODE_PTR branch = AST_new_node(AST_If, NULL); - const AST_NODE_PTR gt = AST_new_node(AST_Greater, NULL); + const AST_NODE_PTR branch = AST_new_node(empty_location(), AST_If, NULL); + const AST_NODE_PTR gt = AST_new_node(empty_location(), AST_Greater, NULL); AST_push_node(branch, gt); - AST_push_node(gt, AST_new_node(AST_Float, "2.3")); - AST_push_node(gt, AST_new_node(AST_Float, "0.79")); + AST_push_node(gt, AST_new_node(empty_location(), AST_Float, "2.3")); + AST_push_node(gt, AST_new_node(empty_location(), AST_Float, "0.79")); AST_push_node(stmt, branch); @@ -32,7 +32,7 @@ int main(void) { AST_init(); - const AST_NODE_PTR root = AST_new_node(AST_Stmt, NULL); + const AST_NODE_PTR root = AST_new_node(empty_location(), AST_Stmt, NULL); generate_branch(root); diff --git a/tests/ast/print_node.c b/tests/ast/print_node.c index 38e8a41..47db685 100644 --- a/tests/ast/print_node.c +++ b/tests/ast/print_node.c @@ -8,7 +8,7 @@ int main(void) { AST_init(); - const AST_NODE_PTR node = AST_new_node(0, "value"); + const AST_NODE_PTR node = AST_new_node(empty_location(), 0, "value"); for (size_t i = 0; i < AST_ELEMENT_COUNT; i++) { // set kind diff --git a/tests/logging/CMakeLists.txt b/tests/logging/CMakeLists.txt index 0f14079..d5abada 100644 --- a/tests/logging/CMakeLists.txt +++ b/tests/logging/CMakeLists.txt @@ -2,12 +2,20 @@ include(CTest) include_directories(${PROJECT_SOURCE_DIR}/src) +# ------------------------------------------------ # +# Setup Glib 2.0 # +# ------------------------------------------------ # + +find_package(PkgConfig REQUIRED) +pkg_search_module(GLIB REQUIRED IMPORTED_TARGET glib-2.0) + # ------------------------------------------------------- # # CTEST 1 # test the default output of the logger add_executable(logging_output ${PROJECT_SOURCE_DIR}/src/sys/log.c + ${PROJECT_SOURCE_DIR}/src/sys/col.c output.c) set_target_properties(logging_output PROPERTIES @@ -23,6 +31,7 @@ add_test(NAME logging_output add_executable(logging_panic ${PROJECT_SOURCE_DIR}/src/sys/log.c + ${PROJECT_SOURCE_DIR}/src/sys/col.c panic.c) set_target_properties(logging_panic PROPERTIES @@ -38,6 +47,7 @@ add_test(NAME logging_panic add_executable(logging_streams ${PROJECT_SOURCE_DIR}/src/sys/log.c + ${PROJECT_SOURCE_DIR}/src/sys/col.c streams.c) set_target_properties(logging_streams PROPERTIES @@ -53,6 +63,7 @@ add_test(NAME logging_streams add_executable(logging_level ${PROJECT_SOURCE_DIR}/src/sys/log.c + ${PROJECT_SOURCE_DIR}/src/sys/col.c level.c) set_target_properties(logging_level PROPERTIES diff --git a/tests/logging/level.c b/tests/logging/level.c index 6a4f055..fd37cc7 100644 --- a/tests/logging/level.c +++ b/tests/logging/level.c @@ -3,11 +3,13 @@ // #include "sys/log.h" +#include #define LOG_LEVEL LOG_LEVEL_WARNING int main(void) { log_init(); + col_init(); DEBUG("logging some debug..."); INFO("logging some info..."); diff --git a/tests/logging/output.c b/tests/logging/output.c index 7accfc5..dde7d90 100644 --- a/tests/logging/output.c +++ b/tests/logging/output.c @@ -3,9 +3,11 @@ // #include "sys/log.h" +#include int main(void) { log_init(); + col_init(); DEBUG("logging some debug..."); INFO("logging some info..."); From d60ebd6812495f0ee29f9f5713d43e3942109b62 Mon Sep 17 00:00:00 2001 From: servostar Date: Thu, 30 May 2024 21:46:44 +0200 Subject: [PATCH 43/43] fixed: return 1 if no input files specified --- src/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main.c b/src/main.c index 0b75508..4888ee5 100644 --- a/src/main.c +++ b/src/main.c @@ -122,6 +122,11 @@ int main(int argc, char *argv[]) { print_file_statistics(file); } + if (files.files == NULL) { + printf("No input files, nothing to do.\n\n"); + exit(1); + } + print_unit_statistics(&files); delete_files(&files);