From 04b1d47de670135381e21b5942377706e3d1d0d2 Mon Sep 17 00:00:00 2001 From: CLAVEL JULIEN <julien.clavel@etu.unistra.fr> Date: Wed, 8 Jan 2025 18:58:22 +0100 Subject: [PATCH 1/7] that ternary statement is making me go crazy --- Codes_en_COREC/tests/test8.corec | 3 +- corec.y | 50 +++++++++--- lib.c | 127 +++++++++++++++++++++++++++++-- lib.h | 17 ++++- 4 files changed, 176 insertions(+), 21 deletions(-) diff --git a/Codes_en_COREC/tests/test8.corec b/Codes_en_COREC/tests/test8.corec index 5fc568f..57a6389 100644 --- a/Codes_en_COREC/tests/test8.corec +++ b/Codes_en_COREC/tests/test8.corec @@ -2,12 +2,13 @@ prog test8{ def Main { + Loc : a, b Rec : { a = 10; b = 2; printstr("a = 10 | b = 2"); - printstr("a<b ?"); + printstr("a>b ?"); a>b? { diff --git a/corec.y b/corec.y index 86af826..4799df8 100644 --- a/corec.y +++ b/corec.y @@ -60,7 +60,13 @@ void exit_safely(){ struct { uint8_t opnum; } opaff; -} + + struct { + struct symbol * lbl1; + struct symbol * lbl2; + } wardLabels; + +}; %token prog %token def @@ -123,8 +129,10 @@ void exit_safely(){ %type <ptrNameDim> DLIST ARRAY ELIST %type <ptrValE> E T F CALL %type <ptrArray> ARRAYREF -%type <opaff> OPAFF -%type <opaff> OPREL +%type <opaff> OPAFF OPREL +%type <wardLabels> INITBLOCK B + + %% @@ -363,13 +371,13 @@ REC : } ; BLOCKINST : // Bloc of instructions - left_curly_bracket LISTEI right_curly_bracket + left_curly_bracket LISTEI right_curly_bracket | I ; LISTEI : LISTEI semicolon I // Last instruction hasn't a semilocon after | I - | %empty // Error detection -> Rec section empty + | %empty // Error detection -> Rec TODO section empty Rec isn't the only BLOCK using LISTEI { fprintf(stderr, "Error at line %u in function '%s': Unexpected end of rec section (shouldn't be empty).\n",lineNumber,symb_scope_function->u.name); exit_safely(); @@ -941,17 +949,27 @@ COND : fprintf(stderr, "BUG\n"); break; } - name_t end_condition = snprintf(end_condition, sizeof(end_condition), "end_condition_%d", t->condition); - struct symbol * label = symtable_put_label(SYMTAB,end_condition); - name_t else_condition = snprintf(else_condition, sizeof(else_condition), "else_condition_%d", t->condition); - struct symbol * label = symtable_put_label(SYMTAB,else_condition); + + struct symbol* lbl_then = $5.lbl1; + struct symbol* lbl_else = $7.lbl2; + gencode(CODE,BRANCH_COND,boolean,lbl_then,lbl_else); - // TODO ahndle and gencode for if and else branches + // TODO handle and gencode for if and else branches } ; B : - BLOCKINST + INITBLOCK BLOCKINST + { + // end of the block (the corresponding label) used for jump got etc + gencode(CODE,LABEL_W,$1.lbl2,NULL,NULL); + $$.lbl1 = $1.lbl1; + $$.lbl2 = $1.lbl2; + } | %empty + { + $$.lbl1 = NULL; + $$.lbl2 = NULL; + } ; OPREL : inf @@ -980,6 +998,16 @@ ID : ID1 | ID2 +INITBLOCK: + %empty { + $$.lbl1 = symtable_put_label(SYMTAB, symb_scope_function); + $$.lbl2 = symtable_put_label(SYMTAB, symb_scope_function); + + gencode(CODE, GOTO_LABEL, $$.lbl2,NULL,NULL); + gencode(CODE, LABEL_W, $$.lbl1,NULL,NULL); + } +; + %% void yyerror(const char * s) diff --git a/lib.c b/lib.c index 1b2680c..0677df7 100644 --- a/lib.c +++ b/lib.c @@ -20,6 +20,7 @@ struct symtable * symtable_new() exit(1); } t->temporary = 0; + t->label = 0; t->size = 0; return t; } @@ -97,7 +98,7 @@ struct symbol* symtable_get(struct symtable * t, const char * id, struct symbol* return &(t->symbols[i]); } return NULL; - } + } return &(t->symbols[i]); } @@ -193,14 +194,16 @@ struct symbol *newtemp(struct symtable * t, enum var_type ty) return s; } -struct symbol* symtable_put_label(struct symtable * t, const char * label_name, struct symbol* func_id) +struct symbol* symtable_put_label(struct symtable * t, struct symbol* func_id) { if(t->size==t->capacity) symtable_grow(t); struct symbol *s = &(t->symbols[t->size]); s->kind = LABEL; - strcpy(s->u.name,label_name); + sprintf(s->u.name,"label%d",t->label); + strcpy(s->scope_function,func_id->u.name); ++ (t->size); + ++ (t->label); return s; } @@ -316,6 +319,7 @@ static void symbol_dump(struct symbol* s, FILE* fout) break; case LABEL: fprintf(fout,"%s",s->u.name); + break; default: fprintf(stderr,"BUG SYMBOL DUMP NOT RECOGNIZED\n"); break; @@ -412,6 +416,69 @@ static void quad_dump(struct quad * q, FILE* fout) symbol_dump(q->sym3,fout); fprintf(fout,"]"); break; + case OPREL_EQ: + symbol_dump(q->sym1,fout); + fprintf(fout," := "); + symbol_dump(q->sym2,fout); + fprintf(fout," == "); + symbol_dump(q->sym3,fout); + break; + case OPREL_GE: + symbol_dump(q->sym1,fout); + fprintf(fout," := "); + symbol_dump(q->sym2,fout); + fprintf(fout," >= "); + symbol_dump(q->sym3,fout); + break; + case OPREL_GT: + symbol_dump(q->sym1,fout); + fprintf(fout," := "); + symbol_dump(q->sym2,fout); + fprintf(fout," > "); + symbol_dump(q->sym3,fout); + break; + case OPREL_LE: + symbol_dump(q->sym1,fout); + fprintf(fout," := "); + symbol_dump(q->sym2,fout); + fprintf(fout," <= "); + symbol_dump(q->sym3,fout); + break; + case OPREL_LT: + symbol_dump(q->sym1,fout); + fprintf(fout," := "); + symbol_dump(q->sym2,fout); + fprintf(fout," < "); + symbol_dump(q->sym3,fout); + break; + case BRANCH_COND: + fprintf(fout,"if "); + symbol_dump(q->sym1,fout); + if(q->sym2!=NULL) + { + fprintf(fout," == 1 go to "); + symbol_dump(q->sym2,fout); + } + if(q->sym3!=NULL) + { + fprintf(fout," else go to "); + symbol_dump(q->sym3,fout); + } + break; + case LABEL_W: + if(q->sym1!=NULL) + { + symbol_dump(q->sym1,fout); + fprintf(fout," :"); + } + break; + case GOTO_LABEL: + if(q->sym1!=NULL) + { + fprintf(fout,"goto "); + symbol_dump(q->sym1,fout); + } + break; default: fprintf(stderr,"BUG quad_dump(...) : q->kind inconnu\n"); break; @@ -477,8 +544,8 @@ void code_mips_dump(struct symtable * t, struct code * c, FILE* fout){ // else if (t->symbols[i].kind == LABEL) { // fprintf(fout,"\t%s: .word 0\n",t->symbols[i].u.name); // } - else{ //NAME - fprintf(fout,"\ttemp%d: .word 0\n",i); + else{ // TODO check whether if in else shouldn't be printed or not ? + // fprintf(fout,"\ttemp%d: .word 0\n",i); } } @@ -534,6 +601,21 @@ void code_mips_dump(struct symtable * t, struct code * c, FILE* fout){ case COPY: print_copy(t,c,fout,i); break; + case OPREL_EQ: + print_EQ_check(t,c,fout,i); + break; + case OPREL_GT: + print_GT_check(t,c,fout,i); + break; + case OPREL_GE: + print_GE_check(t,c,fout,i); + break; + case OPREL_LT: + print_LT_check(t,c,fout,i); + break; + case OPREL_LE: + print_LE_check(t,c,fout,i); + break; default: fprintf(stderr,"#BUG %d\n",c->quads[i].kind); break; @@ -729,6 +811,40 @@ void print_uop_minus(struct code * c, struct symtable* t, FILE* fout,int i) #endif } +// -------- COMPARISONS / OPREL RELATED -------- + +void print_EQ_check(struct symtable* t, struct code * c, FILE* fout,int i) +{ + #ifdef LIBDEBUG + fprintf(fout,"%s# equality check\n",tabulation); + #endif +} + +void print_GT_check(struct symtable* t, struct code * c, FILE* fout,int i) +{ + #ifdef LIBDEBUG + fprintf(fout,"%s# Greater than check\n",tabulation); + #endif +} +void print_GE_check(struct symtable* t, struct code * c, FILE* fout,int i) +{ + #ifdef LIBDEBUG + fprintf(fout,"%s# Greater or equal check\n",tabulation); + #endif +} +void print_LT_check(struct symtable* t, struct code * c, FILE* fout,int i) +{ + #ifdef LIBDEBUG + fprintf(fout,"%s# Lesser than check\n",tabulation); + #endif +} +void print_LE_check(struct symtable* t, struct code * c, FILE* fout,int i) +{ + #ifdef LIBDEBUG + fprintf(fout,"%s# Lesser or equal check\n",tabulation); + #endif +} + // -------- PRINT RELATED -------- void print_print(struct symtable * t,struct code * c, FILE* fout,int i) @@ -1037,7 +1153,6 @@ void print_SPACE_macro(FILE* fout){ fprintf(fout,".end_macro\n"); } - // ETC FEEL FREE TO ADD MORE SECTIONS // -------- DEBUG RELATED -------- diff --git a/lib.h b/lib.h index 81097d9..eb91d1e 100644 --- a/lib.h +++ b/lib.h @@ -54,11 +54,13 @@ struct symbol { }; + + // Store the symbol table struct symtable { unsigned int capacity; unsigned int temporary; - unsigned int condition; // TODO find if necessary and how to name the different labels + unsigned int label; // TODO find if necessary and how to name the different labels unsigned int size; struct symbol* symbols; }; @@ -83,7 +85,7 @@ struct symbol* symtable_put_array(struct symtable * t, const char* var_name, uns // Add to the symtable a temporary function which is used to transform multiples addresses instruction to a group of 3 addresses instructions (uses NAME kind) struct symbol* newtemp(struct symtable * t,enum var_type ty); // Add to the symtable a label to branch different blocks of code -struct symbol* symtable_put_label(struct symtable * t, const char * label_name, struct symbol* func_id); +struct symbol* symtable_put_label(struct symtable * t, struct symbol* func_id); // Get a pointer of a symbol with attribut name in the symtable (if 's' isn't in the table, return NULL) // (func_id is used for the scope of function on the local variable) @@ -107,7 +109,7 @@ void symtable_free(struct symtable * t); * COPY_ARRAY -> tmp=sym1 array=sym2 element=sym3 -> tmp= array[element] */ struct quad { - enum quad_kind { BOP_PLUS, BOP_MINUS, BOP_MULT, BOP_DIV, BOP_MOD, UOP_MINUS, COPY, COPY_ARRAY, ALLOCATE_ARRAY, AFF_ARRAY, DEF_MAIN, DEF_FUNCTION, CALL_PRINT, CALL_PRINTSTR, CONDITION, OPREL_LT, OPREL_GT, OPREL_LE, OPREL_GE, OPREL_EQ} kind; + enum quad_kind { BOP_PLUS, BOP_MINUS, BOP_MULT, BOP_DIV, BOP_MOD, UOP_MINUS, COPY, COPY_ARRAY, ALLOCATE_ARRAY, AFF_ARRAY, DEF_MAIN, DEF_FUNCTION, CALL_PRINT, CALL_PRINTSTR, CONDITION, OPREL_LT, OPREL_GT, OPREL_LE, OPREL_GE, OPREL_EQ, BRANCH_COND, LABEL_W, GOTO_LABEL} kind; struct symbol* sym1; struct symbol* sym2; struct symbol* sym3; @@ -168,6 +170,15 @@ void print_bop_mod(struct code * c, struct symtable* t, FILE* fout,int i); // add the UOP minus arithmetic operation TODO explain in more details void print_uop_minus(struct code * c, struct symtable* t, FILE* fout,int i); +// -------- COMPARISONS / OPREL RELATED -------- + +void print_EQ_check(struct symtable* t, struct code * c, FILE* fout,int i); +void print_GT_check(struct symtable* t, struct code * c, FILE* fout,int i); +void print_GE_check(struct symtable* t, struct code * c, FILE* fout,int i); +void print_LT_check(struct symtable* t, struct code * c, FILE* fout,int i); +void print_LE_check(struct symtable* t, struct code * c, FILE* fout,int i); + + // -------- PRINT RELATED -------- // add the code to print the asked variable -- GitLab From fed571af46c4c3b77b2b32879b36fcc3dfb0c64a Mon Sep 17 00:00:00 2001 From: CLAVEL JULIEN <julien.clavel@etu.unistra.fr> Date: Thu, 9 Jan 2025 18:34:02 +0100 Subject: [PATCH 2/7] intermediary commit to chck upon a bug on another branch --- Codes_en_COREC/tests/test8.corec | 56 +++++++++++++- Makefile | 3 + corec.y | 123 +++++++++++++++++-------------- corecDev.l | 22 ++++-- lib.c | 80 ++++++++++++++++---- lib.h | 39 +++++++++- 6 files changed, 240 insertions(+), 83 deletions(-) diff --git a/Codes_en_COREC/tests/test8.corec b/Codes_en_COREC/tests/test8.corec index 57a6389..1b52b5a 100644 --- a/Codes_en_COREC/tests/test8.corec +++ b/Codes_en_COREC/tests/test8.corec @@ -2,25 +2,73 @@ prog test8{ def Main { - Loc : a, b + Loc : a, b, c Rec : { a = 10; b = 2; + c = 17; printstr("a = 10 | b = 2"); printstr("a>b ?"); a>b? { - printstr("oui") + printstr("oui\n") } - :printstr("non"); + :printstr("non\n"); printstr("b egal a 2 ?"); b==2? { - printstr("oui") + printstr("oui\n") }: + + printstr("advanced test"); + c>10?{ + c>=15?{ + c<19? { + c<=16? { + c==15?printstr("c == 15"):printstr("c == 16") + } : { + c==17?printstr("c == 17"):printstr("c == 18") + } + } : { + c==20?printstr("c == 20 "): { + c==19?printstr("c == 19 "):printstr("c must be <=20 (and >=0)") + } + } + } : { + c>12? { + c==13?printstr("c == 13"):printstr("c == 14") + } : { + c==12?printstr("c == 12"):printstr("c == 11") + } + } + } : { + c<1? { + c==0?printstr("c == 0"):printstr("c must be >=0 (and <=20)") + } : { + c<=1?printstr("c == 1"): { + c>=10?printstr("c == 10"): { + c>2? { + c<4?printstr("c == 3"): { + c==5?printstr("c == 5"):{ + c>6?{ + c==7?printstr("c == 7"): { + c==8?printstr("c == 8"): { + c<8?printstr("c == 6"):printstr("c == 9") + } + } + }:{ + c==6?printstr("c == 6"):printstr("c == 4") + } + } + } + }:printstr("c == 2") + } + } + } + } } } } diff --git a/Makefile b/Makefile index 0d4f308..d0ee398 100644 --- a/Makefile +++ b/Makefile @@ -48,6 +48,9 @@ test_corec: all ./$(Compilateur_COREC) -tos < $(DIR_IN)/SystTriang.corec > $(DIR_OUT)/output7.asm test: all # Change to allDev if u want to display the lex tokens + ./$(Compilateur_COREC) -tos -o $(DIR_OUT)/output$(num).asm < $(DIR_IN)/tests/test$(num).corec + +testDev: allDev # Change to allDev if u want to display the lex tokens ./$(Compilateur_COREC) -tos -o $(DIR_OUT)/output$(num).asm < $(DIR_IN)/tests/test$(num).corec testTo: all diff --git a/corec.y b/corec.y index 4799df8..b25f20a 100644 --- a/corec.y +++ b/corec.y @@ -11,6 +11,9 @@ struct symbol* symb_scope_function; // Boolean if we are in a print call uint8_t isPrintCall = 0; +// stack of the IF ELSE calls +struct labelStack * condition_stack; + // Store the dimension or indexes when we call or declare an array struct symbol** tabArrayDim = NULL; // Store the length of the array @@ -35,6 +38,7 @@ void exit_safely(){ long int intval; float floatval; name_t strval; + wardLabels label; struct { struct symbol* ptr; @@ -61,11 +65,6 @@ void exit_safely(){ uint8_t opnum; } opaff; - struct { - struct symbol * lbl1; - struct symbol * lbl2; - } wardLabels; - }; %token prog @@ -130,7 +129,6 @@ void exit_safely(){ %type <ptrValE> E T F CALL %type <ptrArray> ARRAYREF %type <opaff> OPAFF OPREL -%type <wardLabels> INITBLOCK B @@ -920,57 +918,21 @@ F : ; COND : - E OPREL E ternary_then B ternary_else B + CONDCHECK THEN B ELSE B { - struct symbol * boolean = newtemp(SYMTAB,INTEGER); - - switch($2.opnum){ - case 1: - gencode(CODE,OPREL_LT,boolean,$1.ptr,$3.ptr); - break; - - case 2: - gencode(CODE,OPREL_GT,boolean,$1.ptr,$3.ptr); - break; - - case 3: - gencode(CODE,OPREL_LE,boolean,$1.ptr,$3.ptr); - break; - - case 4: - gencode(CODE,OPREL_GE,boolean,$1.ptr,$3.ptr); - break; - - case 5: - gencode(CODE,OPREL_EQ,boolean,$1.ptr,$3.ptr); - break; - - default: - fprintf(stderr, "BUG\n"); - break; - } - - struct symbol* lbl_then = $5.lbl1; - struct symbol* lbl_else = $7.lbl2; - gencode(CODE,BRANCH_COND,boolean,lbl_then,lbl_else); + // label du ENDIF + gencode(CODE,LABEL_W,condition_stack->elt.lbl2,NULL,NULL); + pop_stack(&condition_stack); // on dépile les labels de cette condition // TODO handle and gencode for if and else branches } ; B : - INITBLOCK BLOCKINST - { - // end of the block (the corresponding label) used for jump got etc - gencode(CODE,LABEL_W,$1.lbl2,NULL,NULL); - $$.lbl1 = $1.lbl1; - $$.lbl2 = $1.lbl2; - } + BLOCKINST | %empty - { - $$.lbl1 = NULL; - $$.lbl2 = NULL; - } ; + + OPREL : inf { @@ -997,17 +959,66 @@ OPREL : ID : ID1 | ID2 + ; + +CONDCHECK: + E OPREL E { -INITBLOCK: - %empty { - $$.lbl1 = symtable_put_label(SYMTAB, symb_scope_function); - $$.lbl2 = symtable_put_label(SYMTAB, symb_scope_function); - gencode(CODE, GOTO_LABEL, $$.lbl2,NULL,NULL); - gencode(CODE, LABEL_W, $$.lbl1,NULL,NULL); + wardLabels tmp; + tmp.cond_number = SYMTAB->condition; + tmp.lbl1 = symtable_put_label(SYMTAB, "else", tmp.cond_number, symb_scope_function); + tmp.lbl2 = symtable_put_label(SYMTAB, "endif", tmp.cond_number, symb_scope_function); + switch($2.opnum){ + case 1: + gencode(CODE,OPREL_LT,tmp.lbl1,$1.ptr,$3.ptr); + break; + + case 2: + gencode(CODE,OPREL_GT,tmp.lbl1,$1.ptr,$3.ptr); + break; + + case 3: + gencode(CODE,OPREL_LE,tmp.lbl1,$1.ptr,$3.ptr); + break; + + case 4: + gencode(CODE,OPREL_GE,tmp.lbl1,$1.ptr,$3.ptr); + break; + + case 5: + gencode(CODE,OPREL_EQ,tmp.lbl1,$1.ptr,$3.ptr); + break; + + default: + fprintf(stderr, "BUG\n"); + break; + } + push_stack(&condition_stack,tmp); + (SYMTAB->condition) ++; + // go to else si la condition est fausse + + } + ; + +THEN : + ternary_then + { + struct symbol * if_label = symtable_put_label(SYMTAB, "if", condition_stack->elt.cond_number, symb_scope_function); + // lavel de la sectrion IF + gencode(CODE, LABEL_W, if_label, NULL, NULL); } -; + ; +ELSE : + ternary_else + { + // goto endif juste après le code du IF + gencode(CODE, GOTO_LABEL, condition_stack->elt.lbl2, NULL, NULL); + // label de la section ELSE + gencode(CODE, LABEL_W, condition_stack->elt.lbl1, NULL, NULL); + } + ; %% void yyerror(const char * s) diff --git a/corecDev.l b/corecDev.l index 3e0143e..25e59e2 100644 --- a/corecDev.l +++ b/corecDev.l @@ -63,14 +63,20 @@ in {printf("in_dom"); return in_dom;} "/" {printf("divide"); return divide;} "%" {printf("mod"); return mod;} -([0-9]*[[:alpha:]]+|[[:alpha:]])[[:alnum:]]* { - printf("ID"); - if ( yyleng > 63 ) - fprintf(stderr,"Error at line %u: Identifier '%s' too long (> 31), truncated.\n",lineNumber,yytext); - strncpy(yylval.strval,yytext,63); - yylval.strval[64] = '\0'; - return ID; - } +[[:alpha:]][[:alnum:]]* { + if ( yyleng > 63 ) + fprintf(stderr,"Error at line %u: Identifier '%s' too long (> 63), truncated.\n",lineNumber,yytext); + strncpy(yylval.strval,yytext,63); + yylval.strval[64] = '\0'; + return ID1; + } +[0-9]*[[:alpha:]]+[[:alnum:]]* { + if ( yyleng > 63 ) + fprintf(stderr,"Error at line %u: Identifier '%s' too long (> 63), truncated.\n",lineNumber,yytext); + strncpy(yylval.strval,yytext,63); + yylval.strval[64] = '\0'; + return ID2; + } ["]([^"]|[\\]["])*["] { printf("chaine"); if ( yyleng > 1023 ) diff --git a/lib.c b/lib.c index 0677df7..edc0667 100644 --- a/lib.c +++ b/lib.c @@ -20,7 +20,7 @@ struct symtable * symtable_new() exit(1); } t->temporary = 0; - t->label = 0; + t->condition = 0; t->size = 0; return t; } @@ -194,16 +194,15 @@ struct symbol *newtemp(struct symtable * t, enum var_type ty) return s; } -struct symbol* symtable_put_label(struct symtable * t, struct symbol* func_id) +struct symbol* symtable_put_label(struct symtable * t, const char* var_name, int cond_id, struct symbol* func_id) { if(t->size==t->capacity) symtable_grow(t); struct symbol *s = &(t->symbols[t->size]); s->kind = LABEL; - sprintf(s->u.name,"label%d",t->label); + sprintf(s->u.name,"%s_%d",var_name,cond_id); strcpy(s->scope_function,func_id->u.name); ++ (t->size); - ++ (t->label); return s; } @@ -456,14 +455,9 @@ static void quad_dump(struct quad * q, FILE* fout) symbol_dump(q->sym1,fout); if(q->sym2!=NULL) { - fprintf(fout," == 1 go to "); + fprintf(fout," == 0 go to "); symbol_dump(q->sym2,fout); } - if(q->sym3!=NULL) - { - fprintf(fout," else go to "); - symbol_dump(q->sym3,fout); - } break; case LABEL_W: if(q->sym1!=NULL) @@ -844,7 +838,34 @@ void print_LE_check(struct symtable* t, struct code * c, FILE* fout,int i) fprintf(fout,"%s# Lesser or equal check\n",tabulation); #endif } +// -------- COMPARISONS / OPREL RELATED -------- + +void print_EQ_check(struct symtable* t, struct code * c, FILE* fout,int i) +{ + if(c->quads[i].sym1->kind!=LABEL) + { + fprintf(stdout,"error gave a non label symbol exiting\n"); + } + if(ISFLOAT(c->quads[i].sym2)|| ISFLOAT(c->quads[i].sym3)) +} +void print_GT_check(struct symtable* t, struct code * c, FILE* fout,int i) +{ +} +void print_GE_check(struct symtable* t, struct code * c, FILE* fout,int i) +{ + +} +void print_LT_check(struct symtable* t, struct code * c, FILE* fout,int i) +{ + +} +void print_LE_check(struct symtable* t, struct code * c, FILE* fout,int i) +{ + +} + +// -------- BRANCHING RELATED -------- // -------- PRINT RELATED -------- void print_print(struct symtable * t,struct code * c, FILE* fout,int i) @@ -938,7 +959,7 @@ void print_copy_array(struct symtable * t, struct code * c, FILE* fout,int i) #endif if(c->quads[i].sym2->kind != ARRAY){ fprintf(stdout,"Tried to do an Var = tab[index] operation but right part isn't an array should address this issue in the corec.y file\n"); - exit(1); + free_exit(1,c,t,fout); } // adress of the array element we want to copy load_tab_addr_macro("$t0", "$t1", "$t2", c->quads[i].sym2,c->quads[i].sym3,t,fout); @@ -961,7 +982,7 @@ void print_allocate_array(struct symtable * t, struct code * c, FILE* fout,int i #endif if(c->quads[i].sym1->kind != ARRAY){ fprintf(stdout,"Tried to don an tab[index] = Var operation but left part isn't an array should address this issue in the corec.y file\n"); - exit(1); + free_exit(1,c,t,fout); } // number for the sbrk primitive call fprintf(fout,"%sli $v0, 9\n",tabulation); @@ -984,7 +1005,7 @@ void print_aff_array(struct symtable * t, struct code * c, FILE* fout,int i) #endif if(c->quads[i].sym1->kind != ARRAY){ fprintf(stdout,"Tried to do an tab[index] = Var operation but left part isn't an array should address this issue in the corec.y file\n"); - exit(1); + free_exit(1,c,t,fout); } // V alternative, effectue directement le*4 en calcul vu qu'on devrait passer par un load immediate dans tout les cas // fprintf(fout,"%sla $t0, %s\n",tabulation,c->quads[i].sym1->u.name); @@ -1208,6 +1229,39 @@ void debug_register_strings_declaration(FILE * fout){ } #endif +// -------- ERROR CHECK -------- + +void push_stack(labelStack ** stack, wardLabels new_elt) +{ + labelStack * new; + CHK( new = malloc(sizeof(labelStack)) , NULL ); + new->elt.cond_number = new_elt.cond_number; + new->elt.lbl1 = new_elt.lbl1; + new->elt.lbl2 = new_elt.lbl2; + new->previous = (*stack); + (*stack) = new; +} + +void pop_stack(labelStack ** stack) +{ + if((*stack) == NULL) + { + fprintf(stdout,"Trying to pop an empty stack \n"); + return; + } + labelStack * tmp = (*stack); + (*stack) = tmp->previous; + free(tmp); +} + +void raler(int err, const char *msg, ...) +{ + if (err == 1) + perror (""); + + exit(EXIT_FAILURE); + +} /************************* NAME TO DEFINE FUNCTIONS *************************/ diff --git a/lib.h b/lib.h index eb91d1e..39c7946 100644 --- a/lib.h +++ b/lib.h @@ -11,6 +11,9 @@ extern struct symbol* symb_scope_function; #define LIBDEBUG #define ISFLOAT(X) ( X->kind == CONSTANT_FLOAT || X->kind == ARRAY || X->kind == NAME_FLOAT ) + + + /* TABLE DES SYMBOLES */ typedef char name_t[64]; @@ -39,6 +42,7 @@ enum kind{ LABEL // -> use the name attribut in the union u }; + // Struct symbol -> store a symbol struct symbol { enum kind kind; // attribut kind : the type of symbol; @@ -60,7 +64,7 @@ struct symbol { struct symtable { unsigned int capacity; unsigned int temporary; - unsigned int label; // TODO find if necessary and how to name the different labels + unsigned int condition; unsigned int size; struct symbol* symbols; }; @@ -85,7 +89,7 @@ struct symbol* symtable_put_array(struct symtable * t, const char* var_name, uns // Add to the symtable a temporary function which is used to transform multiples addresses instruction to a group of 3 addresses instructions (uses NAME kind) struct symbol* newtemp(struct symtable * t,enum var_type ty); // Add to the symtable a label to branch different blocks of code -struct symbol* symtable_put_label(struct symtable * t, struct symbol* func_id); +struct symbol* symtable_put_label(struct symtable * t, const char* var_name, int cond_id, struct symbol* func_id); // Get a pointer of a symbol with attribut name in the symtable (if 's' isn't in the table, return NULL) // (func_id is used for the scope of function on the local variable) @@ -178,6 +182,7 @@ void print_GE_check(struct symtable* t, struct code * c, FILE* fout,int i); void print_LT_check(struct symtable* t, struct code * c, FILE* fout,int i); void print_LE_check(struct symtable* t, struct code * c, FILE* fout,int i); +// -------- BRANCHING RELATED -------- // -------- PRINT RELATED -------- @@ -271,6 +276,36 @@ void debug_print_start(FILE * fout); void debug_print_end(FILE * fout); void debug_register_strings_declaration(FILE * fout); #endif + +// -------- STACK RELATED -------- +typedef struct { + int cond_number; + struct symbol * lbl1; + struct symbol * lbl2; +} wardLabels; + +typedef struct labelStack{ + wardLabels elt; + struct labelStack * previous; +} labelStack; + +extern labelStack * condition_stack; + +/** @brief add an element on top of the stack + */ +void push_stack(labelStack ** stack, wardLabels new_elt); + +/** @brief pop the top element of the stack + */ +void pop_stack(labelStack ** stack); + +// -------- ERROR CHECK -------- + +#define CHK(op,x) do { if ((op) == (x)) raler (1, #op); } while (0) + +void raler(int err, const char *msg, ...); + + // ETC FEEL FREE TO ADD MORE SECTIONS /************************* NAME TO DEFINE FUNCTIONS *************************/ -- GitLab From 8051eca6dfb01d282367ca5352b092b8d0094e8f Mon Sep 17 00:00:00 2001 From: CLAVEL JULIEN <julien.clavel@etu.unistra.fr> Date: Thu, 9 Jan 2025 20:35:59 +0100 Subject: [PATCH 3/7] =?UTF-8?q?test=208=20implement=C3=A9=20et=20fonctionn?= =?UTF-8?q?el,=20branchements=20conditionnels=20op=C3=A9rationnels=20(non?= =?UTF-8?q?=20test=C3=A9s=20sur=20les=20float,=20objet=20du=20test=209)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Codes_en_COREC/tests/test8.corec | 23 ++++- README.md | 5 +- corec.y | 9 ++ lib.c | 163 ++++++++++++++++++++++++------- lib.h | 32 ++++-- 5 files changed, 186 insertions(+), 46 deletions(-) diff --git a/Codes_en_COREC/tests/test8.corec b/Codes_en_COREC/tests/test8.corec index 1b52b5a..901bfa9 100644 --- a/Codes_en_COREC/tests/test8.corec +++ b/Codes_en_COREC/tests/test8.corec @@ -23,43 +23,64 @@ prog test8{ printstr("oui\n") }: - printstr("advanced test"); + printstr("advanced test, modify c if you want to test other branchings, c=17 shouldn\'t work if one of the conditions isn't well implemented\n"); c>10?{ + printstr("c > 10\n"); c>=15?{ + printstr("c >= 15\n"); c<19? { + printstr("c < 19\n"); c<=16? { + printstr("c <= 16\n"); c==15?printstr("c == 15"):printstr("c == 16") } : { + printstr("c > 16\n"); c==17?printstr("c == 17"):printstr("c == 18") } } : { c==20?printstr("c == 20 "): { + printstr("c >= 19\n"); c==19?printstr("c == 19 "):printstr("c must be <=20 (and >=0)") } } } : { + printstr("c < 15\n"); c>12? { + printstr("c > 12\n"); c==13?printstr("c == 13"):printstr("c == 14") } : { + printstr("c <= 12\n"); c==12?printstr("c == 12"):printstr("c == 11") } } } : { + printstr("c <= 10\n"); c<1? { + printstr("c < 1\n"); c==0?printstr("c == 0"):printstr("c must be >=0 (and <=20)") } : { + printstr("c >= 1\n"); c<=1?printstr("c == 1"): { + printstr("c > 1\n"); c>=10?printstr("c == 10"): { + printstr("c < 10\n"); c>2? { + printstr("c > 2\n"); c<4?printstr("c == 3"): { + printstr("c >= 4\n"); c==5?printstr("c == 5"):{ + printstr("c != 5\n"); c>6?{ + printstr("c > 6\n"); c==7?printstr("c == 7"): { + printstr("c != 7\n"); c==8?printstr("c == 8"): { + printstr("c != 8\n"); c<8?printstr("c == 6"):printstr("c == 9") } } }:{ + printstr("c <= 6\n"); c==6?printstr("c == 6"):printstr("c == 4") } } diff --git a/README.md b/README.md index 931fa20..d71ca48 100644 --- a/README.md +++ b/README.md @@ -52,9 +52,10 @@ sudo apt install bison - float value as singleton array. - Cast integer in float if integer affectation to arrays or multiplication of a float and an integer. (Implicit) ### 6. branch test6 -- Affectation multi dimensional array. **(TO DO :TRANSLATE IN MIPS)** +- Affectation multi dimensional array. ### 7. branch test7 -- Operations on multi dimensional array. **(TO DO :TRANSLATE IN MIPS)** +- Operations on multi dimensional array. +### 8. branch test8 See in the [test report](./docs/tests.md) file the report on COREC tests features and error detection. diff --git a/corec.y b/corec.y index b25f20a..5d64be6 100644 --- a/corec.y +++ b/corec.y @@ -14,6 +14,9 @@ uint8_t isPrintCall = 0; // stack of the IF ELSE calls struct labelStack * condition_stack; +int indent; +char tabulation[INDENT_BUF]; + // Store the dimension or indexes when we call or declare an array struct symbol** tabArrayDim = NULL; // Store the length of the array @@ -921,7 +924,9 @@ COND : CONDCHECK THEN B ELSE B { // label du ENDIF + gencode(CODE,RM_INDENT,NULL,NULL,NULL); gencode(CODE,LABEL_W,condition_stack->elt.lbl2,NULL,NULL); + pop_stack(&condition_stack); // on dépile les labels de cette condition // TODO handle and gencode for if and else branches @@ -1004,9 +1009,11 @@ CONDCHECK: THEN : ternary_then { + struct symbol * if_label = symtable_put_label(SYMTAB, "if", condition_stack->elt.cond_number, symb_scope_function); // lavel de la sectrion IF gencode(CODE, LABEL_W, if_label, NULL, NULL); + gencode(CODE,ADD_INDENT,NULL,NULL,NULL); } ; @@ -1015,8 +1022,10 @@ ELSE : { // goto endif juste après le code du IF gencode(CODE, GOTO_LABEL, condition_stack->elt.lbl2, NULL, NULL); + gencode(CODE,RM_INDENT,NULL,NULL,NULL); // label de la section ELSE gencode(CODE, LABEL_W, condition_stack->elt.lbl1, NULL, NULL); + gencode(CODE,ADD_INDENT,NULL,NULL,NULL); } ; %% diff --git a/lib.c b/lib.c index edc0667..21a67c5 100644 --- a/lib.c +++ b/lib.c @@ -1,9 +1,7 @@ #include "lib.h" -// TODO make it in a cleaner way -int indent = 0; -char tabulation[INDENT_BUF] = ""; + #define INDENT_MAKER struct symtable * symtable_new() @@ -22,6 +20,7 @@ struct symtable * symtable_new() t->temporary = 0; t->condition = 0; t->size = 0; + init_indent(); return t; } @@ -450,15 +449,6 @@ static void quad_dump(struct quad * q, FILE* fout) fprintf(fout," < "); symbol_dump(q->sym3,fout); break; - case BRANCH_COND: - fprintf(fout,"if "); - symbol_dump(q->sym1,fout); - if(q->sym2!=NULL) - { - fprintf(fout," == 0 go to "); - symbol_dump(q->sym2,fout); - } - break; case LABEL_W: if(q->sym1!=NULL) { @@ -473,6 +463,10 @@ static void quad_dump(struct quad * q, FILE* fout) symbol_dump(q->sym1,fout); } break; + case ADD_INDENT: + break; + case RM_INDENT: + break; default: fprintf(stderr,"BUG quad_dump(...) : q->kind inconnu\n"); break; @@ -584,7 +578,7 @@ void code_mips_dump(struct symtable * t, struct code * c, FILE* fout){ break; case DEF_MAIN: print_main_def(fout); - add_indent(1,c,t,fout); + add_indent(c,t,fout); break; case CALL_PRINT: print_print(t,c,fout,i); @@ -610,6 +604,18 @@ void code_mips_dump(struct symtable * t, struct code * c, FILE* fout){ case OPREL_LE: print_LE_check(t,c,fout,i); break; + case LABEL_W: + print_label_w(t,c,fout,i); + break; + case GOTO_LABEL: + print_goto(t,c,fout,i); + break; + case ADD_INDENT: + add_indent(c,t,fout); + break; + case RM_INDENT: + remove_indent(); + break; default: fprintf(stderr,"#BUG %d\n",c->quads[i].kind); break; @@ -780,7 +786,7 @@ void print_uop_minus(struct code * c, struct symtable* t, FILE* fout,int i) #endif if(ISFLOAT(c->quads[i].sym2)) { // float uop minus - if(!ISFLOAT(c->quads[i].sym2)) + if(!ISFLOAT(c->quads[i].sym2)) { // if sym2 is an integer convert it to a float and store it in $f0 convert_int_to_float("$f0","$t0",c->quads[i].sym2,t,fout); } else { // store it in $f0 @@ -812,6 +818,22 @@ void print_EQ_check(struct symtable* t, struct code * c, FILE* fout,int i) #ifdef LIBDEBUG fprintf(fout,"%s# equality check\n",tabulation); #endif + if(c->quads[i].sym1->kind!=LABEL) + { + fprintf(stdout,"error gave a non label symbol, exiting\n"); + free_exit(1,c,t,fout); + } + if(ISFLOAT(c->quads[i].sym2)|| ISFLOAT(c->quads[i].sym3)) + { + load_float_bop_macro("$f0","$f1","$t0",c->quads[i].sym2,c->quads[i].sym3,t,fout); + fprintf(fout,"%sc.beq.s $f0, $f1\n",tabulation); + fprintf(fout,"%sbc1f %s\n",tabulation,c->quads[i].sym1->u.name); + } else { + // Check if we have variable names or just integers for sym2 and sym3 + print_nameOrInteger(c,fout,i,0b110); + // we wanna branch to the else when condition is false s owe do the opposite test == => != + fprintf(fout,"%sbne $t0, $t1, %s\n",tabulation,c->quads[i].sym1->u.name); + } } void print_GT_check(struct symtable* t, struct code * c, FILE* fout,int i) @@ -819,53 +841,115 @@ void print_GT_check(struct symtable* t, struct code * c, FILE* fout,int i) #ifdef LIBDEBUG fprintf(fout,"%s# Greater than check\n",tabulation); #endif + if(c->quads[i].sym1->kind!=LABEL) + { + fprintf(stdout,"error gave a non label symbol, exiting\n"); + free_exit(1,c,t,fout); + } + if(ISFLOAT(c->quads[i].sym2)|| ISFLOAT(c->quads[i].sym3)) + { + load_float_bop_macro("$f0","$f1","$t0",c->quads[i].sym2,c->quads[i].sym3,t,fout); + // we go to else if lesser or equal is true since it's the oposite of greater than + fprintf(fout,"%sc.le.s $f0, $f1\n",tabulation); + fprintf(fout,"%sbc1t %s\n",tabulation,c->quads[i].sym1->u.name); + } else { + // Check if we have variable names or just integers for sym2 and sym3 + print_nameOrInteger(c,fout,i,0b110); + // we go to else if lesser or equal is true since it's the oposite of greater than + fprintf(fout,"%sble $t0, $t1, %s\n",tabulation,c->quads[i].sym1->u.name); + } } void print_GE_check(struct symtable* t, struct code * c, FILE* fout,int i) { #ifdef LIBDEBUG fprintf(fout,"%s# Greater or equal check\n",tabulation); #endif + if(c->quads[i].sym1->kind!=LABEL) + { + fprintf(stdout,"error gave a non label symbol, exiting\n"); + free_exit(1,c,t,fout); + } + if(ISFLOAT(c->quads[i].sym2)|| ISFLOAT(c->quads[i].sym3)) + { + load_float_bop_macro("$f0","$f1","$t0",c->quads[i].sym2,c->quads[i].sym3,t,fout); + // we go to else if lesser than is true since it's the oposite of greater or equal + fprintf(fout,"%sc.lt.s $f0, $f1\n",tabulation); + fprintf(fout,"%sbc1t %s\n",tabulation,c->quads[i].sym1->u.name); + } else { + // Check if we have variable names or just integers for sym2 and sym3 + print_nameOrInteger(c,fout,i,0b110); + // we go to else if lesser than is true since it's the oposite of greater or equal + fprintf(fout,"%sblt $t0, $t1, %s\n",tabulation,c->quads[i].sym1->u.name); + } } void print_LT_check(struct symtable* t, struct code * c, FILE* fout,int i) { #ifdef LIBDEBUG fprintf(fout,"%s# Lesser than check\n",tabulation); #endif + if(c->quads[i].sym1->kind!=LABEL) + { + fprintf(stdout,"error gave a non label symbol, exiting\n"); + free_exit(1,c,t,fout); + } + if(ISFLOAT(c->quads[i].sym2)|| ISFLOAT(c->quads[i].sym3)) + { + load_float_bop_macro("$f0","$f1","$t0",c->quads[i].sym2,c->quads[i].sym3,t,fout); + // we go to else if lesser than is false + fprintf(fout,"%sc.lt.s $f0, $f1\n",tabulation); + fprintf(fout,"%sbc1f %s\n",tabulation,c->quads[i].sym1->u.name); + } else { + // Check if we have variable names or just integers for sym2 and sym3 + print_nameOrInteger(c,fout,i,0b110); + // we go to else if greater or equal is true since it's the oposite of lesser than + fprintf(fout,"%sbge $t0, $t1, %s\n",tabulation,c->quads[i].sym1->u.name); + } } void print_LE_check(struct symtable* t, struct code * c, FILE* fout,int i) { #ifdef LIBDEBUG fprintf(fout,"%s# Lesser or equal check\n",tabulation); #endif -} -// -------- COMPARISONS / OPREL RELATED -------- - -void print_EQ_check(struct symtable* t, struct code * c, FILE* fout,int i) -{ if(c->quads[i].sym1->kind!=LABEL) { - fprintf(stdout,"error gave a non label symbol exiting\n"); + fprintf(stdout,"error gave a non label symbol, exiting\n"); + free_exit(1,c,t,fout); } if(ISFLOAT(c->quads[i].sym2)|| ISFLOAT(c->quads[i].sym3)) + { + load_float_bop_macro("$f0","$f1","$t0",c->quads[i].sym2,c->quads[i].sym3,t,fout); + // we go to else if lesser or equal is false + fprintf(fout,"%sc.le.s $f0, $f1\n",tabulation); + fprintf(fout,"%sbc1f %s\n",tabulation,c->quads[i].sym1->u.name); + } else { + // Check if we have variable names or just integers for sym2 and sym3 + print_nameOrInteger(c,fout,i,0b110); + // we go to else if greater than is true since it's the oposite of lesser or equal + fprintf(fout,"%sbgt $t0, $t1, %s\n",tabulation,c->quads[i].sym1->u.name); + } } -void print_GT_check(struct symtable* t, struct code * c, FILE* fout,int i) -{ -} -void print_GE_check(struct symtable* t, struct code * c, FILE* fout,int i) -{ +// -------- BRANCHING RELATED -------- -} -void print_LT_check(struct symtable* t, struct code * c, FILE* fout,int i) +void print_label_w(struct symtable* t, struct code * c, FILE* fout,int i) { - + if(c->quads[i].sym1->kind!=LABEL) + { + fprintf(stdout,"error gave a non label symbol, exiting\n"); + free_exit(1,c,t,fout); + } + fprintf(fout,"%s%s:\n",tabulation,c->quads[i].sym1->u.name); } -void print_LE_check(struct symtable* t, struct code * c, FILE* fout,int i) -{ +void print_goto(struct symtable* t, struct code * c, FILE* fout,int i) +{ + if(c->quads[i].sym1->kind!=LABEL) + { + fprintf(stdout,"error gave a non label symbol, exiting\n"); + free_exit(1,c,t,fout); + } + fprintf(fout,"%sj %s\n",tabulation,c->quads[i].sym1->u.name); } - -// -------- BRANCHING RELATED -------- // -------- PRINT RELATED -------- void print_print(struct symtable * t,struct code * c, FILE* fout,int i) @@ -885,7 +969,7 @@ void print_print(struct symtable * t,struct code * c, FILE* fout,int i) // we avoid having 2 identical labels by putting the quad index at the end of it // /!\ start of the loop /!\ -- fprintf(fout,"%sprint_array_loop%d:\n",tabulation,i); - add_indent(1,c,t,fout); + add_indent(c,t,fout); // bge by security to avoid miss matching (which shouldn't be happening) fprintf(fout,"%sbge $t2, $t0, end_array_loop%d\n",tabulation,i); @@ -1254,11 +1338,10 @@ void pop_stack(labelStack ** stack) free(tmp); } -void raler(int err, const char *msg, ...) +void raler(int err) { if (err == 1) perror (""); - exit(EXIT_FAILURE); } @@ -1267,11 +1350,11 @@ void raler(int err, const char *msg, ...) -void add_indent(int code, struct code* c, struct symtable* t, FILE* fname){ +void add_indent(struct code* c, struct symtable* t, FILE* fname){ if(indent >= 1022) { printf("more than 1023 indentations ! write better code.\n"); - free_exit(code,c,t,fname); + free_exit(1,c,t,fname); } tabulation[indent] = '\t'; indent++; @@ -1287,4 +1370,10 @@ int remove_indent(){ indent--; tabulation[indent] = '\0'; return 0; +} + +void init_indent() +{ + indent=0; + tabulation[indent]='\0'; } \ No newline at end of file diff --git a/lib.h b/lib.h index 39c7946..eb0b868 100644 --- a/lib.h +++ b/lib.h @@ -113,7 +113,7 @@ void symtable_free(struct symtable * t); * COPY_ARRAY -> tmp=sym1 array=sym2 element=sym3 -> tmp= array[element] */ struct quad { - enum quad_kind { BOP_PLUS, BOP_MINUS, BOP_MULT, BOP_DIV, BOP_MOD, UOP_MINUS, COPY, COPY_ARRAY, ALLOCATE_ARRAY, AFF_ARRAY, DEF_MAIN, DEF_FUNCTION, CALL_PRINT, CALL_PRINTSTR, CONDITION, OPREL_LT, OPREL_GT, OPREL_LE, OPREL_GE, OPREL_EQ, BRANCH_COND, LABEL_W, GOTO_LABEL} kind; + enum quad_kind { BOP_PLUS, BOP_MINUS, BOP_MULT, BOP_DIV, BOP_MOD, UOP_MINUS, COPY, COPY_ARRAY, ALLOCATE_ARRAY, AFF_ARRAY, DEF_MAIN, DEF_FUNCTION, CALL_PRINT, CALL_PRINTSTR, CONDITION, OPREL_LT, OPREL_GT, OPREL_LE, OPREL_GE, OPREL_EQ, LABEL_W, GOTO_LABEL, ADD_INDENT, RM_INDENT} kind; struct symbol* sym1; struct symbol* sym2; struct symbol* sym3; @@ -175,15 +175,29 @@ void print_bop_mod(struct code * c, struct symtable* t, FILE* fout,int i); void print_uop_minus(struct code * c, struct symtable* t, FILE* fout,int i); // -------- COMPARISONS / OPREL RELATED -------- - +/** @brief add the code to branch to symbol1 label if symbol2 and symbol3 aren't equal + */ void print_EQ_check(struct symtable* t, struct code * c, FILE* fout,int i); +/** @brief add the code to branch to symbol1 label if symbol2 isn't > symbol3 + */ void print_GT_check(struct symtable* t, struct code * c, FILE* fout,int i); +/** @brief add the code to branch to symbol1 label if symbol2 isn't >= symbol3 + */ void print_GE_check(struct symtable* t, struct code * c, FILE* fout,int i); +/** @brief add the code to branch to symbol1 label if symbol2 isn't < symbol3 + */ void print_LT_check(struct symtable* t, struct code * c, FILE* fout,int i); +/** @brief add the code to branch to symbol1 label if symbol2 isn't <= symbol3 + */ void print_LE_check(struct symtable* t, struct code * c, FILE* fout,int i); // -------- BRANCHING RELATED -------- - +/** @brief add the code to put the sym1 label into the mips code + */ +void print_label_w(struct symtable* t, struct code * c, FILE* fout,int i); +/** @brief add the code to go to sym1 label + */ +void print_goto(struct symtable* t, struct code * c, FILE* fout,int i); // -------- PRINT RELATED -------- // add the code to print the asked variable @@ -301,17 +315,23 @@ void pop_stack(labelStack ** stack); // -------- ERROR CHECK -------- -#define CHK(op,x) do { if ((op) == (x)) raler (1, #op); } while (0) +#define CHK(op,x) do { if ((op) == (x)) raler (1); } while (0) -void raler(int err, const char *msg, ...); +void raler(int err); // ETC FEEL FREE TO ADD MORE SECTIONS /************************* NAME TO DEFINE FUNCTIONS *************************/ +// TODO make it in a cleaner way +extern int indent; +extern char tabulation[INDENT_BUF]; + // add a tabulation to the indentation string -void add_indent(int code, struct code* c, struct symtable* t, FILE* fname); +void add_indent(struct code* c, struct symtable* t, FILE* fname); // remove a tabulation from the indentation string int remove_indent(); +// init the indentation tab +void init_indent(); -- GitLab From 81ea8d724c922f24e18c7a7be681b056a1414c51 Mon Sep 17 00:00:00 2001 From: CLAVEL JULIEN <julien.clavel@etu.unistra.fr> Date: Fri, 10 Jan 2025 14:29:38 +0100 Subject: [PATCH 4/7] tested and corrected floating operands comparisons now working and ready to merge --- Codes_en_COREC/tests/test8.corec | 20 +++++++++++++++++--- lib.c | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Codes_en_COREC/tests/test8.corec b/Codes_en_COREC/tests/test8.corec index 901bfa9..1d7ef3f 100644 --- a/Codes_en_COREC/tests/test8.corec +++ b/Codes_en_COREC/tests/test8.corec @@ -2,11 +2,12 @@ prog test8{ def Main { - Loc : a, b, c + Loc : a, b, c, (array,3) Rec : { a = 10; b = 2; c = 17; + array = 0.12; printstr("a = 10 | b = 2"); printstr("a>b ?"); @@ -23,7 +24,8 @@ prog test8{ printstr("oui\n") }: - printstr("advanced test, modify c if you want to test other branchings, c=17 shouldn\'t work if one of the conditions isn't well implemented\n"); + printstr("advanced test, modify c if you want to test other branchings,\n"); + printstr("c=17 shouldn\'t work if one of the conditions isn't well implemented\n"); c>10?{ printstr("c > 10\n"); c>=15?{ @@ -89,7 +91,19 @@ prog test8{ } } } - } + }; + + printstr("\ntest conditions on float :\nIs 0.12 [array] greater than 0.1 : "); + array>0.1?printstr("YES\n"):printstr("NO\n"); + printstr("Is 0.12 [array] greater or equal to 0.12 : "); + array>=0.12?printstr("YES\n"):printstr("NO\n"); + printstr("Is 0.24 [array*2] equal to 0.24 : "); + array*2==0.24?printstr("YES\n"):printstr("NO\n"); + printstr("Is 0.11 [array-0.1] lesser than 0.12 [array] : "); + array-0.1<array?printstr("YES\n"):printstr("NO\n"); + printstr("Is 0.06 [array/2] lesser or equal to 0.06 [array-0.06] : "); + array/2<=array-0.06?printstr("YES\n"):printstr("NO\n") + } } } diff --git a/lib.c b/lib.c index 21a67c5..f1a1c7c 100644 --- a/lib.c +++ b/lib.c @@ -826,7 +826,7 @@ void print_EQ_check(struct symtable* t, struct code * c, FILE* fout,int i) if(ISFLOAT(c->quads[i].sym2)|| ISFLOAT(c->quads[i].sym3)) { load_float_bop_macro("$f0","$f1","$t0",c->quads[i].sym2,c->quads[i].sym3,t,fout); - fprintf(fout,"%sc.beq.s $f0, $f1\n",tabulation); + fprintf(fout,"%sc.eq.s $f0, $f1\n",tabulation); fprintf(fout,"%sbc1f %s\n",tabulation,c->quads[i].sym1->u.name); } else { // Check if we have variable names or just integers for sym2 and sym3 -- GitLab From 485733350b53e618a316d65d4f364b06f3625225 Mon Sep 17 00:00:00 2001 From: CLAVEL JULIEN <julien.clavel@etu.unistra.fr> Date: Fri, 10 Jan 2025 14:34:39 +0100 Subject: [PATCH 5/7] verified that all tests until 8 passed, can be safely merged --- Codes_en_COREC/tests/test7.corec | 34 ++++++++++++++++---------------- Codes_en_COREC/tests/test8.corec | 15 ++++++-------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/Codes_en_COREC/tests/test7.corec b/Codes_en_COREC/tests/test7.corec index c87a950..ace050d 100644 --- a/Codes_en_COREC/tests/test7.corec +++ b/Codes_en_COREC/tests/test7.corec @@ -2,27 +2,27 @@ prog Test7{ def Main{ - Loc : a=2, (2Darray,3,3), (3Darray,a,a,a)//, 3Darray[0,0,0] = 0 //BUG HERE + Loc : a=2, (array2D,3,3), (array3D,a,a,a)//, array3D[0,0,0] = 0 //BUG HERE Rec : { - 2Darray[0,0] = 0; - 2Darray[0,1] = 1; - 2Darray[0,2] = a; - 2Darray[1,0] = 3.0; - 2Darray[1,1] = 4.5; - 2Darray[1,2] = 5; + array2D[0,0] = 0; + array2D[0,1] = 1; + array2D[0,2] = a; + array2D[1,0] = 3.0; + array2D[1,1] = 4.5; + array2D[1,2] = 5; - print(2Darray); + print(array2D); - 3Darray[0,0,0] = 0; - 3Darray[0,0,1] = 1; - 3Darray[0,1,0] = a; - 3Darray[0,1,1] = 2Darray[1,2]; - 3Darray[1,0,0] = 2Darray[0,2]*2Darray[0,2]+2Darray[0,2]-2Darray[0,1]*2; - 3Darray[1,0,1] = 5; - 3Darray[1,1,0] = 2Darray[1,2]+2Darray[0,1]; - 3Darray[1,1,1] = 7; + array3D[0,0,0] = 0; + array3D[0,0,1] = 1; + array3D[0,1,0] = a; + array3D[0,1,1] = array2D[1,2]; + array3D[1,0,0] = array2D[0,2]*array2D[0,2]+array2D[0,2]-array2D[0,1]*2; + array3D[1,0,1] = 5; + array3D[1,1,0] = array2D[1,2]+array2D[0,1]; + array3D[1,1,1] = 7; - print(3Darray); + print(array3D); printstr("Fini") } } diff --git a/Codes_en_COREC/tests/test8.corec b/Codes_en_COREC/tests/test8.corec index 1d7ef3f..5d5baad 100644 --- a/Codes_en_COREC/tests/test8.corec +++ b/Codes_en_COREC/tests/test8.corec @@ -10,19 +10,16 @@ prog test8{ array = 0.12; printstr("a = 10 | b = 2"); - printstr("a>b ?"); + printstr("a>b ? "); a>b? { - printstr("oui\n") + printstr("YES\n") } - :printstr("non\n"); + :printstr("NO\n"); - printstr("b egal a 2 ?"); - b==2? - { - printstr("oui\n") - }: + printstr("b equal 2 ? "); + b==2?printstr("YES\n"):printstr("NO\n"); printstr("advanced test, modify c if you want to test other branchings,\n"); printstr("c=17 shouldn\'t work if one of the conditions isn't well implemented\n"); @@ -93,7 +90,7 @@ prog test8{ } }; - printstr("\ntest conditions on float :\nIs 0.12 [array] greater than 0.1 : "); + printstr("\n\ntest conditions on float :\nIs 0.12 [array] greater than 0.1 : "); array>0.1?printstr("YES\n"):printstr("NO\n"); printstr("Is 0.12 [array] greater or equal to 0.12 : "); array>=0.12?printstr("YES\n"):printstr("NO\n"); -- GitLab From 51a15c44a5d4526b85ffeb532fa9d7eeaa67ec2e Mon Sep 17 00:00:00 2001 From: CLAVEL JULIEN <julien.clavel@etu.unistra.fr> Date: Fri, 10 Jan 2025 14:40:58 +0100 Subject: [PATCH 6/7] Tweaks to update the documentation --- README.md | 1 + corec.y | 6 ++---- docs/tests.md | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d71ca48..716a59d 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ sudo apt install bison ### 7. branch test7 - Operations on multi dimensional array. ### 8. branch test8 +- conditional code execution See in the [test report](./docs/tests.md) file the report on COREC tests features and error detection. diff --git a/corec.y b/corec.y index 5d64be6..aed7d23 100644 --- a/corec.y +++ b/corec.y @@ -923,13 +923,11 @@ F : COND : CONDCHECK THEN B ELSE B { - // label du ENDIF + // ENDIF label gencode(CODE,RM_INDENT,NULL,NULL,NULL); gencode(CODE,LABEL_W,condition_stack->elt.lbl2,NULL,NULL); - pop_stack(&condition_stack); // on dépile les labels de cette condition - - // TODO handle and gencode for if and else branches + pop_stack(&condition_stack); // we pop the current condition's labels since the condition is now over } ; B : diff --git a/docs/tests.md b/docs/tests.md index 0c3b096..b41fc74 100644 --- a/docs/tests.md +++ b/docs/tests.md @@ -8,7 +8,7 @@ 5. Operation with float. 6. Declaration of local ND arrays and assignement of values. 7. Operation with ND arrays. -8. +8. if else and condition checks 9. ## Error detection -- GitLab From 78f93950b427a115aa4bf6e7cec0ed416d85d9cc Mon Sep 17 00:00:00 2001 From: CLAVEL JULIEN <julien.clavel@etu.unistra.fr> Date: Fri, 10 Jan 2025 15:11:46 +0100 Subject: [PATCH 7/7] made all tests in english ready to merge witch conflicts solved --- Codes_en_COREC/tests/test1.corec | 6 +++--- Codes_en_COREC/tests/test2.corec | 22 ++++++++++++---------- Codes_en_COREC/tests/test3.corec | 2 +- Codes_en_COREC/tests/test4.corec | 6 +++--- Codes_en_COREC/tests/test5.corec | 6 +++--- Codes_en_COREC/tests/test9.corec | 4 ++-- 6 files changed, 24 insertions(+), 22 deletions(-) diff --git a/Codes_en_COREC/tests/test1.corec b/Codes_en_COREC/tests/test1.corec index d8c7220..3e2bcc8 100644 --- a/Codes_en_COREC/tests/test1.corec +++ b/Codes_en_COREC/tests/test1.corec @@ -7,12 +7,12 @@ prog Test1 { a = 10; b = 2; - printstr("Affichage de variables, a: "); + printstr("Printing variable, a: "); print(a); - printstr("Affichage de variables, b: "); + printstr("Printing variable, b: "); print(b); - printstr("Affichage de variables, c: "); + printstr("Printing variable, c: "); print(c) } } diff --git a/Codes_en_COREC/tests/test2.corec b/Codes_en_COREC/tests/test2.corec index 1cbbcef..a3a442a 100644 --- a/Codes_en_COREC/tests/test2.corec +++ b/Codes_en_COREC/tests/test2.corec @@ -7,44 +7,46 @@ prog Test2{ a = 10; b = 2; + printstr("a = 10, b = 2\n"); + c = a+b; - printstr("Addition, attendu 12: "); + printstr("a+b, expect 12 : "); print(c); c = a-b; - printstr("Substraction, attendu 8: "); + printstr("a-b, expect 8: "); print(c); c = a*b; - printstr("Multiplication, attendu 20: "); + printstr("a*b, expect 20: "); print(c); c = a/b; - printstr("Division, attendu 5: "); + printstr("a/b, expect 5: "); print(c); a += b; - printstr("Addition aff, attendu 12: "); + printstr("a += b aff, expect 12: "); print(a); a *= b; - printstr("Addition mult, attendu 24: "); + printstr("a *= b (a=12*2), expect 24: "); print(a); a /= b; - printstr("Addition mult, attendu 12: "); + printstr("a /= b (a=24/2), expect 12: "); print(a); a -= 4; - printstr("Addition mult, attendu 8: "); + printstr("a -= 4 (a=12-4), expect 8: "); print(a); c = a*a+2+b*b; - printstr("Addition mult, attendu 70: "); + printstr("a*a + 2 + b*b (8*8 + 2 + 2*2), expect 70: "); print(c); c= a*(a+b)-c/2; - printstr("Addition mult, attendu 45: "); + printstr(" a*(a+b)-c/2 (8*(8+2)-70/2), expect 45: "); print(c) } } diff --git a/Codes_en_COREC/tests/test3.corec b/Codes_en_COREC/tests/test3.corec index 93c55f2..21ad140 100644 --- a/Codes_en_COREC/tests/test3.corec +++ b/Codes_en_COREC/tests/test3.corec @@ -16,7 +16,7 @@ prog Test3 { f[0] = 1.0; // Implicit array of dim 1 length 1 -> f[0] array1[2] = f; - printstr("Expected result : 2.0 1.15 1.0 5.0 2.0 \nObtained Result : "); + printstr("Expected result : 2.00 1.15 1.00 5.00 2.00 \nObtained Result : "); print(array1) // contain all the values exchanges here if the code is correct } } diff --git a/Codes_en_COREC/tests/test4.corec b/Codes_en_COREC/tests/test4.corec index 1985bf0..e98a493 100644 --- a/Codes_en_COREC/tests/test4.corec +++ b/Codes_en_COREC/tests/test4.corec @@ -13,21 +13,21 @@ prog Test4 { array[1] -= 2; array[2] /= 2; array[3] *= 2; - printstr("Expected : 4.0 0.0 1.0 4.0 0.0 0.0 \nObtained : "); + printstr("Expected : 4.00 0.00 1.00 4.00 0.00 0.00 \nObtained : "); print(array); array[1] = array[0] + float; array[2] = array[2] - float; array[3] = array[0] / float; array[4] = array[0] * float; - printstr("Expected : 4.0 7.0 -2.0 1.3333334 12.0 0.0 \nObtained : "); + printstr("Expected : 4.00 7.00 -2.00 1.33 12.00 0.00 \nObtained : "); print(array); array[2] = array[0] + array[1]; array[3] = array[0] - array[1]; array[4] = array[0] / array[1]; array[5] = array[0] * array[1]; - printstr("Expected : 4.0 7.0 11.0 -3.0 0.5714286 28.0 \nObtained : "); + printstr("Expected : 4.00 7.00 11.00 -3.00 0.57 28.00 \nObtained : "); print(array) } } diff --git a/Codes_en_COREC/tests/test5.corec b/Codes_en_COREC/tests/test5.corec index f293225..881dcd4 100644 --- a/Codes_en_COREC/tests/test5.corec +++ b/Codes_en_COREC/tests/test5.corec @@ -8,15 +8,15 @@ prog Test6 { f2 = 1.3; f1 += f2*2; - printstr("Expected : 1.2 + 1.3 * 2 = 3.8\nObtained : 1.2 + 1.3 * 2 = "); + printstr("Expected : 1.2 + 1.3 * 2 = 3.80\nObtained : 1.2 + 1.3 * 2 = "); print(f1); f2 = f2*2; - printstr("Expected : 1.3 * 2 = 2.6\nObtained : "); + printstr("Expected : 1.3 * 2 = 2.60\nObtained : "); print(f2); f1 /= f2+f2*4; - printstr("Expected : 3.8 / (2.6 + 2.6 * 4) = 0.29230767\nObtained : "); + printstr("Expected : 3.8 / (2.6 + 2.6 * 4) = 0.29\nObtained : "); print(f1) } } diff --git a/Codes_en_COREC/tests/test9.corec b/Codes_en_COREC/tests/test9.corec index 562894d..72bbfd1 100644 --- a/Codes_en_COREC/tests/test9.corec +++ b/Codes_en_COREC/tests/test9.corec @@ -4,10 +4,10 @@ prog test9 { def Main { Loc: (f,1), saisie Rec : { - printstr("Saisie clavier :"); + printstr("Integer input asked:"); read(saisie); print(saisie); - printstr("Saisie float clavier:"); + printstr("Float input asked:"); read(f); print(f) } -- GitLab