From adc50362130d1e888ac5152ade4bbf2d578c4201 Mon Sep 17 00:00:00 2001 From: CLAVEL JULIEN <julien.clavel@etu.unistra.fr> Date: Mon, 30 Dec 2024 19:16:34 +0100 Subject: [PATCH 1/3] =?UTF-8?q?COPY=20ARRAY=20transform=C3=A9=20en=20code?= =?UTF-8?q?=20MIPS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- corec.y | 2 +- lib.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- lib.h | 20 ++++++++++++++------ 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/corec.y b/corec.y index daa7503..997990c 100644 --- a/corec.y +++ b/corec.y @@ -539,7 +539,7 @@ AFFECTATION : else{ t = $3.ptr; } - + // id index E gencode(CODE,AFF_ARRAY,$1.ptr1,$1.ptr2,t); } | ID aff E // Affectation of A to ID diff --git a/lib.c b/lib.c index 951755b..53afe37 100644 --- a/lib.c +++ b/lib.c @@ -418,7 +418,7 @@ void code_mips_dump(struct symtable * t, struct code * c, FILE* fout){ fprintf(fout,"\ttemp%d: .word %ld\n",i,t->symbols[i].u.value_int); } else if(t->symbols[i].kind == CONSTANT_FLOAT){ //FLOAT CONSTANT - fprintf(fout,"\ttemp%d: .word %0.2f\n",i,t->symbols[i].u.value_float); + fprintf(fout,"\ttemp%d: .float %0.2f\n",i,t->symbols[i].u.value_float); } else if(t->symbols[i].kind == CHAIN){ //CHAIN fprintf(fout,"\ttemp%d: .asciiz %s\n",i,t->symbols[i].u.chaine); @@ -428,6 +428,10 @@ void code_mips_dump(struct symtable * t, struct code * c, FILE* fout){ } else if(t->symbols[i].kind == NAME){ fprintf(fout,"\t%s: .word 0\n",t->symbols[i].u.name); + } + // this prevent the declaration fo some temp necessary but is also necessary to allocat the memory tab TODO resolve this issue + else if (t->symbols[i].kind == ARRAY){ + fprintf(fout,"\t%s: .word 0\n",t->symbols[i].u.name); } else{ //NAME fprintf(fout,"\ttemp%d: .word 0\n",i); @@ -460,6 +464,12 @@ void code_mips_dump(struct symtable * t, struct code * c, FILE* fout){ case UOP_MINUS: print_uop_minus(c,fout,i); break; + case COPY_ARRAY: + print_copy_array(t,c,fout,i); + break; + case ALLOCATE_ARRAY: + print_allocate_array(t,c,fout,i); + break; case DEF_MAIN: print_main_def(fout); break; @@ -574,6 +584,7 @@ void print_print(struct code * c, FILE* fout,int i) { fprintf(fout,"%slw $t0, %s\n",tabulation,c->quads[i].sym1->u.name); fprintf(fout,"%smove $a0, $t0\n",tabulation); + // ne marche que pour print ls int pas pour les float fprintf(fout,"%sli $v0, 1\n",tabulation); fprintf(fout,"%ssyscall\n",tabulation); //Return to line @@ -589,6 +600,38 @@ void print_printstr(struct symtable * t, struct code * c, FILE* fout,int i) // -------- FUNCTIONS RELATED -------- + +// -------- ARRAY RELATED -------- + +void print_copy_array(struct symtable * t, struct code * c, FILE* fout,int i) +{ + #ifdef LIBDEBUG + fprintf(fout,"%s# copy_array section\n",tabulation); + #endif + // get the array adress in $t0 + if(c->quads[i].sym2->kind == NAME || c->quads[i].sym2->kind == NAME_LOC || c->quads[i].sym2->kind == ARRAY) + fprintf(fout,"%sla $t0, %s\n",tabulation,c->quads[i].sym2->u.name); + else + fprintf(fout,"%sla $t0, temp%d\n",tabulation,indice_temp(t,c->quads[i].sym2)); + fprintf(fout,"%sli $t1, %ld\n",tabulation,c->quads[i].sym3->u.value_int); + // each INT/FLOATS are 4bytes to get the right adress $t1 must be multiple by 4 equal to 2 left bit shifts + fprintf(fout,"%ssll $t1, $t1, 2\n",tabulation); + // add the index adresses to the starting adress of the array to get the adress of the nth element + fprintf(fout,"%sadd $t2, $t0, $t1\n",tabulation); + // load the nth element into $t3 + fprintf(fout,"%slw $t3, 0($t2)\n",tabulation); + // put it into the destination register + fprintf(fout,"%ssw $t3, %s\n",tabulation,c->quads[i].sym1->u.name); + #ifdef LIBDEBUG + fprintf(fout,"%s# end of copy_array section\n",tabulation); + #endif +} +void print_allocate_array(struct symtable * t, struct code * c, FILE* fout,int i) +{ + +} + + // -------- MISCELLANEOUS -------- void print_copy(struct symtable * t, struct code * c, FILE* fout,int i) diff --git a/lib.h b/lib.h index 6a89439..d3ceadc 100644 --- a/lib.h +++ b/lib.h @@ -7,6 +7,8 @@ extern unsigned int lineNumber; extern struct symbol* symb_scope_function; #define INDENT_BUF 1024 +// make each section of MIPS code more clear comment to disable +// #define LIBDEBUG /* TABLE DES SYMBOLES */ @@ -133,22 +135,22 @@ void print_main_def(FILE* fout); // -------- ARITHMETIC RELATED -------- -// add the BOP plus arithmetic operation TODO explain in more details i don't know what BOP stand for (Binary operator ?) +// add the BOP plus arithmetic operation TODO explain in more details void print_bop_plus(struct code * c, FILE* fout,int i); -// add the BOP minus arithmetic operation TODO explain in more details i don't know what BOP stand for (Binary operator ?) +// add the BOP minus arithmetic operation TODO explain in more details void print_bop_minus(struct code * c, FILE* fout,int i); -// add the BOP mult arithmetic operation TODO explain in more details i don't know what BOP stand for (Binary operator ?) +// add the BOP mult arithmetic operation TODO explain in more details void print_bop_mult(struct code * c, FILE* fout,int i); -// add the BOP div arithmetic operation TODO explain in more details i don't know what BOP stand for (Binary operator ?) +// add the BOP div arithmetic operation TODO explain in more details void print_bop_div(struct code * c, FILE* fout,int i); -// add the BOP modulo arithmetic operation TODO explain in more details i don't know what BOP stand for (Binary operator ?) +// add the BOP modulo arithmetic operation TODO explain in more details void print_bop_mod(struct code * c, FILE* fout,int i); -// add the UOP minus arithmetic operation TODO explain in more details i don't know what UOP stand for (Unary operator ?) +// add the UOP minus arithmetic operation TODO explain in more details void print_uop_minus(struct code * c, FILE* fout,int i); // -------- PRINT RELATED -------- @@ -161,6 +163,12 @@ void print_printstr(struct symtable * t, struct code * c, FILE* fout,int i); // -------- FUNCTIONS RELATED -------- +// -------- ARRAY RELATED -------- + +void print_copy_array(struct symtable * t, struct code * c, FILE* fout,int i); + +void print_allocate_array(struct symtable * t, struct code * c, FILE* fout,int i); + // -------- MISCELLANEOUS -------- -- GitLab From 52f93f0139cb373d271424dbd826d663673ee704 Mon Sep 17 00:00:00 2001 From: CLAVEL JULIEN <julien.clavel@etu.unistra.fr> Date: Thu, 2 Jan 2025 21:33:55 +0100 Subject: [PATCH 2/3] COPY ALLOCATE and PRINT working for arrays but didn't resolve YET COPY_ARRAY malfunctionning --- Codes_en_COREC/tests/test3.corec | 5 +- Codes_en_COREC/testsErrors/test20Err.corec | 8 + lib.c | 271 ++++++++++++++++++--- lib.h | 65 +++-- 4 files changed, 300 insertions(+), 49 deletions(-) create mode 100644 Codes_en_COREC/testsErrors/test20Err.corec diff --git a/Codes_en_COREC/tests/test3.corec b/Codes_en_COREC/tests/test3.corec index a3fd3f7..236481d 100644 --- a/Codes_en_COREC/tests/test3.corec +++ b/Codes_en_COREC/tests/test3.corec @@ -2,16 +2,17 @@ prog Test3 { def Main{ - Loc : (array1,5), (array2,2+4/2), (f,1) + Loc : (array1,5), (array2,2*4/2), (f,1) Rec : { array1 = 2.0; // Implicitement array1[0] array1[4] = 2; f = 1.15; // Implicit array of dim 1 length 1 -> f[0] + print(f); // to delete test purpose only array2[0] = f; array2[1] = 5; - + print(array2); // to delete test purpose only array1[3] = array2[1]; f[0] = 1.0; // Implicit array of dim 1 length 1 -> f[0] diff --git a/Codes_en_COREC/testsErrors/test20Err.corec b/Codes_en_COREC/testsErrors/test20Err.corec new file mode 100644 index 0000000..4b44783 --- /dev/null +++ b/Codes_en_COREC/testsErrors/test20Err.corec @@ -0,0 +1,8 @@ +prog test20Err{ + def Main{ + Loc: a, (f,a) + Rec:{ + printstr("TestErr allocation 1D array with a var not initialized") + } + } +} \ No newline at end of file diff --git a/lib.c b/lib.c index 53afe37..ab80a22 100644 --- a/lib.c +++ b/lib.c @@ -409,7 +409,7 @@ int indice_temp(struct symtable* t, struct symbol* s){ void code_mips_dump(struct symtable * t, struct code * c, FILE* fout){ fprintf(fout,".data\n"); fprintf(fout,"\tlf: .asciiz \"\\n\"\n"); - + fprintf(fout,"\tspace: .asciiz \" \"\n"); if(t==NULL){fprintf(stderr,"Code mips dump: symtable null\n"); exit(1);} unsigned int i =0; @@ -437,6 +437,10 @@ void code_mips_dump(struct symtable * t, struct code * c, FILE* fout){ fprintf(fout,"\ttemp%d: .word 0\n",i); } } + + #ifdef LIBDEBUG + debug_register_strings_declaration(fout); + #endif print_macros(fout); @@ -470,11 +474,14 @@ void code_mips_dump(struct symtable * t, struct code * c, FILE* fout){ case ALLOCATE_ARRAY: print_allocate_array(t,c,fout,i); break; + case AFF_ARRAY: + print_aff_array(t,c,fout,i); + break; case DEF_MAIN: print_main_def(fout); break; case CALL_PRINT: - print_print(c,fout,i); + print_print(t,c,fout,i); break; case CALL_PRINTSTR: print_printstr(t,c,fout,i); @@ -580,15 +587,57 @@ void print_uop_minus(struct code * c, FILE* fout,int i) } // -------- PRINT RELATED -------- -void print_print(struct code * c, FILE* fout,int i) + +void print_print(struct symtable * t,struct code * c, FILE* fout,int i) { - fprintf(fout,"%slw $t0, %s\n",tabulation,c->quads[i].sym1->u.name); - fprintf(fout,"%smove $a0, $t0\n",tabulation); - // ne marche que pour print ls int pas pour les float - fprintf(fout,"%sli $v0, 1\n",tabulation); - fprintf(fout,"%ssyscall\n",tabulation); - //Return to line - fprintf(fout,"%sLF\n",tabulation); + switch(c->quads[i].sym1->kind){ + case ARRAY: + // TODO + WIP solution temporaire, quand les fonctions seront implémentés à remplacer par une fonction pour éviter le code spaghetti + // putting the array size in $t2 + load_symbol_macro("$t2",c->quads[i].sym1->u.arr.dim1size,t,fout); + // to avoid doing a mult at each iterations we multiply the size by 4 (each elements need a 4 bytes incrementation) + fprintf(fout,"%smul $t0, $t2, 4\n",tabulation); + // putting array address in $t1 + load_symbol_macro("$t1",c->quads[i].sym1,t,fout); + fprintf(fout,"%sli $t2, 0\n",tabulation); + + + // 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(); + // bge by security to avoid miss matching (which shouldn't be happening) + fprintf(fout,"%sbge $t2, $t0, end_array_loop%d\n",tabulation,i); + + // put the address of the current element to be printed in $t3 + fprintf(fout,"%sadd $t3, $t2, $t1\n",tabulation); + // load the current float element in the + fprintf(fout,"%slwc1 $f0, ($t3)\n",tabulation); + // function that print the asked register + print_reg("f0",fout,1); + // macro that print a space + fprintf(fout,"%sSPACE\n",tabulation); + // increment to next address + fprintf(fout,"%saddi $t2, $t2, 4\n",tabulation); + + // jump to the start of the loop + fprintf(fout,"%sj print_array_loop%d\n",tabulation,i); + // /!\ end of the loop /!\ -- + remove_indent(); + fprintf(fout,"%send_array_loop%d:\n",tabulation,i); + fprintf(fout,"%sLF\n",tabulation); + break; + default: + fprintf(fout,"%slw $t0, %s\n",tabulation,c->quads[i].sym1->u.name); + fprintf(fout,"%smove $a0, $t0\n",tabulation); + // ne marche que pour print ls int pas pour les float + fprintf(fout,"%sli $v0, 1\n",tabulation); + fprintf(fout,"%ssyscall\n",tabulation); + //Return to line + fprintf(fout,"%sLF\n",tabulation); + break; + } + } void print_printstr(struct symtable * t, struct code * c, FILE* fout,int i) @@ -598,6 +647,26 @@ void print_printstr(struct symtable * t, struct code * c, FILE* fout,int i) fprintf(fout,"%ssyscall\n",tabulation); } + +void print_reg(char * reg,FILE * fout, int type){ + switch(type) { + case 0: + fprintf(fout,"%smove $a0, $%s\n",tabulation,reg); + fprintf(fout,"%sli $v0, 1\n",tabulation); + break; + case 1: + fprintf(fout,"%smov.s $f12, $%s\n",tabulation,reg); + fprintf(fout,"%sli $v0, 2\n",tabulation); + break; + default: + // we suppose value is int + fprintf(fout,"%smove $a0, $%s\n",tabulation,reg); + fprintf(fout,"%sli $v0, 1\n",tabulation); + break; + } + fprintf(fout,"%ssyscall\n",tabulation); +} + // -------- FUNCTIONS RELATED -------- @@ -608,29 +677,66 @@ void print_copy_array(struct symtable * t, struct code * c, FILE* fout,int i) #ifdef LIBDEBUG fprintf(fout,"%s# copy_array section\n",tabulation); #endif - // get the array adress in $t0 - if(c->quads[i].sym2->kind == NAME || c->quads[i].sym2->kind == NAME_LOC || c->quads[i].sym2->kind == ARRAY) - fprintf(fout,"%sla $t0, %s\n",tabulation,c->quads[i].sym2->u.name); - else - fprintf(fout,"%sla $t0, temp%d\n",tabulation,indice_temp(t,c->quads[i].sym2)); - fprintf(fout,"%sli $t1, %ld\n",tabulation,c->quads[i].sym3->u.value_int); - // each INT/FLOATS are 4bytes to get the right adress $t1 must be multiple by 4 equal to 2 left bit shifts - fprintf(fout,"%ssll $t1, $t1, 2\n",tabulation); - // add the index adresses to the starting adress of the array to get the adress of the nth element - fprintf(fout,"%sadd $t2, $t0, $t1\n",tabulation); - // load the nth element into $t3 - fprintf(fout,"%slw $t3, 0($t2)\n",tabulation); - // put it into the destination register - fprintf(fout,"%ssw $t3, %s\n",tabulation,c->quads[i].sym1->u.name); + 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); + } + + get_tab_addr_macro("$t0", 1, 2, c->quads[i].sym2,c->quads[i].sym3,t,fout); + + load_symbol_macro("$t1",c->quads[i].sym1,t,fout); + + fprintf(fout,"%ssw $t1, ($t0)\n",tabulation); + #ifdef LIBDEBUG fprintf(fout,"%s# end of copy_array section\n",tabulation); #endif } + void print_allocate_array(struct symtable * t, struct code * c, FILE* fout,int i) { - + #ifdef LIBDEBUG + fprintf(fout,"%s# allocate_array section\n",tabulation); + #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); + } + // number for the sbrk primitive call + fprintf(fout,"%sli $v0, 9\n",tabulation); + // based on the type of the var indicating the size of the array we do different operations to end up with the nb of bytes we should allocate is $a0 + load_symbol_alloc_macro("$a0",0,c->quads[i].sym1->u.arr.dim1size,t,fout); + // call sbrk + fprintf(fout,"%ssyscall\n",tabulation); + // save the allocated array ptr returned in $v0 by syscall in the assigned .data var + fprintf(fout,"%sla $t0, %s\n",tabulation,c->quads[i].sym1->u.name); + fprintf(fout,"%ssw $v0, ($t0)\n",tabulation); + #ifdef LIBDEBUG + fprintf(fout,"%s# end of allocate_array section\n",tabulation); + #endif } +void print_aff_array(struct symtable * t, struct code * c, FILE* fout,int i) +{ + #ifdef LIBDEBUG + fprintf(fout,"%s# aff_array section\n",tabulation); + #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); + } + // 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); + get_tab_addr_macro("$t0", 1, 2, c->quads[i].sym1,c->quads[i].sym2,t,fout); + load_symbol_macro("$t1",c->quads[i].sym3,t,fout); + fprintf(fout,"%ssw $t1, ($t0)\n",tabulation); + #ifdef LIBDEBUG + fprintf(fout,"%s# end of aff_array section\n",tabulation); + #endif +} + + + // -------- MISCELLANEOUS -------- @@ -653,15 +759,13 @@ void print_copy(struct symtable * t, struct code * c, FILE* fout,int i) void print_nameOrInteger(struct code * c, FILE* fout,int i,int sym) { - if(sym & 0b10) - { + if(sym & 0b10) { if(c->quads[i].sym2->kind == NAME || c->quads[i].sym2->kind == NAME_LOC) fprintf(fout,"%slw $t0, %s\n",tabulation,c->quads[i].sym2->u.name); else if(c->quads[i].sym2->kind == CONSTANT_INT) fprintf(fout,"%sli $t0, %ld\n",tabulation,c->quads[i].sym2->u.value_int); } - if( sym & 0b100) - { + if( sym & 0b100) { if(c->quads[i].sym3->kind == NAME || c->quads[i].sym3->kind == NAME_LOC) fprintf(fout,"%slw $t1, %s\n",tabulation,c->quads[i].sym3->u.name); else if(c->quads[i].sym3->kind == CONSTANT_INT) @@ -670,12 +774,59 @@ void print_nameOrInteger(struct code * c, FILE* fout,int i,int sym) } +// -------- MACROS -------- +void load_symbol_alloc_macro(char * dest, int tmp_used, struct symbol * sym, struct symtable * t, FILE* fout){ + if(sym->kind == CONSTANT_INT) // var = 3 + // in this case the value is a constant int we can do a load immediate in $a0 with value*4 + fprintf(fout,"%sli %s, %ld\n",tabulation,dest,(sym->u.value_int)*4); + // in other cases we need to load the value from the label of the corresponding symbol + else if( sym->kind == NAME || sym->kind == NAME_LOC ) { // var = 4*3 + fprintf(fout,"%slw $t%d, %s\n",tabulation,tmp_used,(sym->u.name)); + } else { // array[4] = array[5]+3*4 + fprintf(fout,"%slw $t%d, temp%d\n",tabulation,tmp_used,indice_temp(t,sym)); + } + // if we don't have a CONST INT we loaded the nb of int/floats we want to stock in the array, in this case + if(sym->kind != CONSTANT_INT) + fprintf(fout,"%ssll %s, $t%d, 2\n",tabulation,dest,tmp_used); +} + +void load_symbol_macro(char * dest, struct symbol * sym, struct symtable * t, FILE* fout){ + if(sym->kind == CONSTANT_INT) // var = 3 + // in this case the value is a constant int we can do a load immediate in $a0 with value*4 + fprintf(fout,"%sli %s, %ld\n",tabulation,dest,(sym->u.value_int)); + // in other cases we need to load the value from the label of the corresponding symbol + else if( sym->kind == NAME || sym->kind == NAME_LOC || sym->kind == ARRAY) { // var = 4*3 + fprintf(fout,"%slw %s, %s\n",tabulation,dest,(sym->u.name)); + } else { // array[4] = array[5]+3*4 + fprintf(fout,"%slw %s, temp%d\n",tabulation,dest,indice_temp(t,sym)); + } +} + + +void get_tab_addr_macro(char * dest,int tmp_used1, int tmp_used2, struct symbol * sym_addr, struct symbol * sym_index, struct symtable * t, FILE* fout){ + fprintf(fout,"%slw $t%d, %s\n",tabulation,tmp_used2,sym_addr->u.name); + if(sym_index->kind == CONSTANT_INT) + // put into dest the addr of array[index] element + fprintf(fout,"%saddi %s, $t%d, %ld\n",tabulation,dest,tmp_used2,(sym_index->u.value_int)*4); + // in other cases we need to load the value from the label of the corresponding symbol + else if( sym_index->kind == NAME || sym_index->kind == NAME_LOC) { + fprintf(fout,"%slw $t%d, %s\n",tabulation,tmp_used1,(sym_index->u.name)); + } else { + fprintf(fout,"%slw $t%d, temp%d\n",tabulation,tmp_used1,indice_temp(t,sym_index)); + } + if (sym_index->kind != CONSTANT_INT){ + fprintf(fout,"%ssll $t%d, $t%d, 2\n",tabulation,tmp_used1,tmp_used1); + fprintf(fout,"%sadd %s, $t%d, $t%d\n",tabulation,dest,tmp_used2,tmp_used1); + } +} + /** Macro printer * only print the LF macro for the moment */ void print_macros(FILE* fout){ fprintf(fout,"\n# MACROS definition\n\n"); print_LF_macro(fout); + print_SPACE_macro(fout); fprintf(fout,"# End of MACROS definition\n"); } @@ -686,8 +837,70 @@ void print_LF_macro(FILE* fout){ fprintf(fout,"\tsyscall\n"); fprintf(fout,".end_macro\n"); } + +void print_SPACE_macro(FILE* fout){ + fprintf(fout,".macro SPACE\n"); + fprintf(fout,"\tli $v0, 4\n"); + fprintf(fout,"\tla $a0, space\n"); + fprintf(fout,"\tsyscall\n"); + fprintf(fout,".end_macro\n"); +} // ETC FEEL FREE TO ADD MORE SECTIONS +// -------- DEBUG RELATED -------- + +#ifdef LIBDEBUG +void debug_print_reg(char * reg,FILE * fout, int type){ + fprintf(fout,"%sli $v0, 4\n",tabulation); + fprintf(fout,"%sla $a0, print%s\n",tabulation,reg); + fprintf(fout,"%ssyscall\n",tabulation); + + fprintf(fout,"%smove $a0, $%s\n",tabulation,reg); + switch(type) { + case 0: + fprintf(fout,"%sli $v0, 1\n",tabulation); + break; + case 1: + fprintf(fout,"%sli $v0, 4\n",tabulation); + break; + default: + // we suppose value is int + fprintf(fout,"%sli $v0, 1\n",tabulation); + break; + } + fprintf(fout,"%ssyscall\n",tabulation); + //Return to line + fprintf(fout,"%sLF\n",tabulation); + +} + +void debug_print_start(FILE * fout){ + fprintf(fout,"%sli $v0, 4\n",tabulation); + fprintf(fout,"%sla $a0, startfct\n",tabulation); + fprintf(fout,"%ssyscall\n",tabulation); + fprintf(fout,"%sLF\n",tabulation); +} + +void debug_print_end(FILE * fout){ + fprintf(fout,"%sli $v0, 4\n",tabulation); + fprintf(fout,"%sla $a0, endfct\n",tabulation); + fprintf(fout,"%ssyscall\n",tabulation); + fprintf(fout,"%sLF\n",tabulation); +} + +void debug_register_strings_declaration(FILE * fout){ + for(int i = 0; i < 10; i++) + fprintf(fout,"\tprintt%d: .asciiz \"$t%d : \"\n",i,i); + for(int i = 0; i < 4; i++) + fprintf(fout,"\tprinta%d: .asciiz \"$a%d : \"\n",i,i); + for(int i = 0; i < 3; i++) + fprintf(fout,"\tprintv%d: .asciiz \"$v%d : \"\n",i,i); + fprintf(fout,"\tstartfct: .asciiz \"START \"\n" ); + fprintf(fout,"\tendfct: .asciiz \"END \"\n" ); + +} +#endif + /************************* NAME TO DEFINE FUNCTIONS *************************/ diff --git a/lib.h b/lib.h index d3ceadc..2108325 100644 --- a/lib.h +++ b/lib.h @@ -8,7 +8,7 @@ extern struct symbol* symb_scope_function; #define INDENT_BUF 1024 // make each section of MIPS code more clear comment to disable -// #define LIBDEBUG +#define LIBDEBUG /* TABLE DES SYMBOLES */ @@ -16,21 +16,24 @@ typedef char name_t[64]; typedef char name_64_t[1024]; struct array { - name_t name; - struct symbol** size; - unsigned int dim; - struct symbol* dim1size; + name_t name; + struct symbol** size; + unsigned int dim; + struct symbol* dim1size; }; -// Struct symbol -> store a symbol -struct symbol { - enum { NAME, // -> use the name attribut in the union u +enum kind{ + NAME, // -> use the name attribut in the union u CONSTANT_INT, // -> use the value_int attribut in the union u CONSTANT_FLOAT, // -> use the value_float attribut in the union u CHAIN, // -> use the chaine attribut in the union u NAME_LOC, // -> use the name attribut, the symbol is just defined ARRAY // -> use the name attribut in the union u - } kind; // attribut kind : the type of symbol; +}; + +// Struct symbol -> store a symbol +struct symbol { + enum kind kind; // attribut kind : the type of symbol; union { name_t name; name_64_t chaine; @@ -38,8 +41,7 @@ struct symbol { float value_float; struct array arr; } u; - - // * (! only sets with variable kind : NAME_LOC, ARRAY) + // * (! only sets with variable kind : NAME_LOC, ARRAY) name_t scope_function; // -> Name of the function where locals variables (NAME_LOC, ARRAY) are defined. }; @@ -89,10 +91,10 @@ 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} kind; - struct symbol* sym1; - struct symbol* sym2; - struct symbol* sym3; + 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} kind; + struct symbol* sym1; + struct symbol* sym2; + struct symbol* sym3; }; // Struct code -> store the intermediate code @@ -156,11 +158,17 @@ void print_uop_minus(struct code * c, FILE* fout,int i); // -------- PRINT RELATED -------- // add the code to print the asked variable -void print_print(struct code * c, FILE* fout,int i); +void print_print(struct symtable * t, struct code * c, FILE* fout,int i); // add the code to print the asked string void print_printstr(struct symtable * t, struct code * c, FILE* fout,int i); +/** print the register's value, no LF and no SPACE + * only the register's value type = 0 => int | type = 1 => float everything else is considered as an int TODO update this + * TODO think about deleting type and just checking if the first reg character is an f if no other cases than int and floats + */ +void print_reg(char * reg,FILE * fout, int type); + // -------- FUNCTIONS RELATED -------- // -------- ARRAY RELATED -------- @@ -169,6 +177,8 @@ void print_copy_array(struct symtable * t, struct code * c, FILE* fout,int i); void print_allocate_array(struct symtable * t, struct code * c, FILE* fout,int i); +void print_aff_array(struct symtable * t, struct code * c, FILE* fout,int i); + // -------- MISCELLANEOUS -------- @@ -178,17 +188,36 @@ void print_copy(struct symtable * t, struct code * c, FILE* fout,int i); // load whether a named var or a constant TODO find a better name ! void print_nameOrInteger(struct code * c, FILE* fout,int i,int sym); +// -------- MACROS -------- +void load_symbol_alloc_macro(char * dest, int tmp_used, struct symbol * sym, struct symtable * t, FILE* fout); + +void load_symbol_macro(char * dest, struct symbol * sym, struct symtable * t, FILE* fout); + +void get_tab_addr_macro(char * dest, int tmp_used1, int tmp_used2, struct symbol * sym_addr, struct symbol * sym_index, struct symtable * t, FILE* fout); + /** Macro printer * only print the LF macro for the moment * should becalled between .data and .text segments */ void print_macros(FILE* fout); -/** Add a macro to print a LF in MIPS +/** Add a macro to print a LF in MIPS code */ void print_LF_macro(FILE* fout); -// ETC FEEL FREE TO ADD MORE SECTIONS +/** Add a macro to print a SPCE in MIPS code + */ +void print_SPACE_macro(FILE* fout); + +// -------- DEBUG RELATED -------- + +#ifdef LIBDEBUG +void debug_print_reg(char * reg,FILE * fout, int type); +void debug_print_start(FILE * fout); +void debug_print_end(FILE * fout); +void debug_register_strings_declaration(FILE * fout); +#endif +// ETC FEEL FREE TO ADD MORE SECTIONS /************************* NAME TO DEFINE FUNCTIONS *************************/ // add a tabulation to the indentation string -- GitLab From c397d0bbcf26cb8abd829a91d87303635e9790e2 Mon Sep 17 00:00:00 2001 From: CLAVEL JULIEN <julien.clavel@etu.unistra.fr> Date: Fri, 3 Jan 2025 12:04:33 +0100 Subject: [PATCH 3/3] test3 finalized and ready to merge --- Codes_en_COREC/tests/test3.corec | 12 ++++----- lib.c | 42 ++++++++++++++++++++------------ lib.h | 37 ++++++++++++++++++++-------- 3 files changed, 59 insertions(+), 32 deletions(-) diff --git a/Codes_en_COREC/tests/test3.corec b/Codes_en_COREC/tests/test3.corec index 236481d..93c55f2 100644 --- a/Codes_en_COREC/tests/test3.corec +++ b/Codes_en_COREC/tests/test3.corec @@ -9,16 +9,16 @@ prog Test3 { array1[4] = 2; f = 1.15; // Implicit array of dim 1 length 1 -> f[0] - print(f); // to delete test purpose only - array2[0] = f; + array1[1] = f; array2[1] = 5; - print(array2); // to delete test purpose only array1[3] = array2[1]; - + f[0] = 1.0; // Implicit array of dim 1 length 1 -> f[0] + array1[2] = f; - - print(array1) + printstr("Expected result : 2.0 1.15 1.0 5.0 2.0 \nObtained Result : "); + print(array1) // contain all the values exchanges here if the code is correct } } } + diff --git a/lib.c b/lib.c index ab80a22..77f9b64 100644 --- a/lib.c +++ b/lib.c @@ -479,6 +479,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); break; case CALL_PRINT: print_print(t,c,fout,i); @@ -521,7 +522,6 @@ void free_exit(int code, struct code* c, struct symtable* t, FILE* fname){ void print_main_def(FILE* fout){ fprintf(fout,".globl start\n\n"); fprintf(fout,"start:\n"); - add_indent(); } // -------- ARITHMETIC RELATED -------- @@ -605,7 +605,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(); + add_indent(1,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); @@ -681,12 +681,14 @@ void print_copy_array(struct symtable * t, struct code * c, FILE* fout,int i) 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); } - - get_tab_addr_macro("$t0", 1, 2, c->quads[i].sym2,c->quads[i].sym3,t,fout); - - load_symbol_macro("$t1",c->quads[i].sym1,t,fout); - - fprintf(fout,"%ssw $t1, ($t0)\n",tabulation); + // adress of the array element we want to copy + load_tab_addr_macro("$t0", 1, 2, c->quads[i].sym2,c->quads[i].sym3,t,fout); + // adress of the place we want to copy the array element in + load_addr_macro("$t1",c->quads[i].sym1,t,fout); + // load in $t2 what's inside the array element + fprintf(fout,"%slw $t2, ($t0)\n",tabulation); + // store it in the destination + fprintf(fout,"%ssw $t2, ($t1)\n",tabulation); #ifdef LIBDEBUG fprintf(fout,"%s# end of copy_array section\n",tabulation); @@ -727,7 +729,7 @@ void print_aff_array(struct symtable * t, struct code * c, FILE* fout,int i) } // 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); - get_tab_addr_macro("$t0", 1, 2, c->quads[i].sym1,c->quads[i].sym2,t,fout); + load_tab_addr_macro("$t0", 1, 2, c->quads[i].sym1,c->quads[i].sym2,t,fout); load_symbol_macro("$t1",c->quads[i].sym3,t,fout); fprintf(fout,"%ssw $t1, ($t0)\n",tabulation); #ifdef LIBDEBUG @@ -803,26 +805,34 @@ void load_symbol_macro(char * dest, struct symbol * sym, struct symtable * t, FI } -void get_tab_addr_macro(char * dest,int tmp_used1, int tmp_used2, struct symbol * sym_addr, struct symbol * sym_index, struct symtable * t, FILE* fout){ +void load_tab_addr_macro(char * dest,int tmp_used1, int tmp_used2, struct symbol * sym_addr, struct symbol * sym_index, struct symtable * t, FILE* fout){ fprintf(fout,"%slw $t%d, %s\n",tabulation,tmp_used2,sym_addr->u.name); if(sym_index->kind == CONSTANT_INT) // put into dest the addr of array[index] element fprintf(fout,"%saddi %s, $t%d, %ld\n",tabulation,dest,tmp_used2,(sym_index->u.value_int)*4); // in other cases we need to load the value from the label of the corresponding symbol - else if( sym_index->kind == NAME || sym_index->kind == NAME_LOC) { + else if( sym_index->kind == NAME || sym_index->kind == NAME_LOC || sym_index->kind == ARRAY) { fprintf(fout,"%slw $t%d, %s\n",tabulation,tmp_used1,(sym_index->u.name)); } else { fprintf(fout,"%slw $t%d, temp%d\n",tabulation,tmp_used1,indice_temp(t,sym_index)); } if (sym_index->kind != CONSTANT_INT){ + // if not CONSTANT_INT wasn't yet multiplied by 4 fprintf(fout,"%ssll $t%d, $t%d, 2\n",tabulation,tmp_used1,tmp_used1); fprintf(fout,"%sadd %s, $t%d, $t%d\n",tabulation,dest,tmp_used2,tmp_used1); } } -/** Macro printer - * only print the LF macro for the moment - */ +void load_addr_macro(char * dest, struct symbol * sym, struct symtable * t, FILE* fout) +{ + if( sym->kind == NAME || sym->kind == NAME_LOC || sym->kind == ARRAY){ + fprintf(fout,"%sla %s, %s\n",tabulation,dest,sym->u.name); + } else + fprintf(fout,"%sla %s, temp%d\n",tabulation,dest,indice_temp(t,sym)); + +} + + void print_macros(FILE* fout){ fprintf(fout,"\n# MACROS definition\n\n"); print_LF_macro(fout); @@ -905,11 +915,11 @@ void debug_register_strings_declaration(FILE * fout){ -void add_indent(){ +void add_indent(int code, struct code* c, struct symtable* t, FILE* fname){ if(indent >= 1022) { printf("more than 1023 indentations ! write better code.\n"); - exit(-1); + free_exit(code,c,t,fname); } tabulation[indent] = '\t'; indent++; diff --git a/lib.h b/lib.h index 2108325..a9426d9 100644 --- a/lib.h +++ b/lib.h @@ -160,10 +160,10 @@ void print_uop_minus(struct code * c, FILE* fout,int i); // add the code to print the asked variable void print_print(struct symtable * t, struct code * c, FILE* fout,int i); -// add the code to print the asked string +// add the code to print the asked string void print_printstr(struct symtable * t, struct code * c, FILE* fout,int i); -/** print the register's value, no LF and no SPACE +/** @brief print_reg make MIPS code to print the register's value, no LF and no SPACE * only the register's value type = 0 => int | type = 1 => float everything else is considered as an int TODO update this * TODO think about deleting type and just checking if the first reg character is an f if no other cases than int and floats */ @@ -173,39 +173,56 @@ void print_reg(char * reg,FILE * fout, int type); // -------- ARRAY RELATED -------- +/** @brief print_copy_array make MIPS code that copy to a temp the value in an array at a given index X <= array[i] + */ void print_copy_array(struct symtable * t, struct code * c, FILE* fout,int i); +/** @brief print_allocate_array make MIPS code to allocate the memory of a given array + */ void print_allocate_array(struct symtable * t, struct code * c, FILE* fout,int i); +/** @brief print_aff_array make MIPS code to affect a value in an array at a given index array[i]= X + */ void print_aff_array(struct symtable * t, struct code * c, FILE* fout,int i); // -------- MISCELLANEOUS -------- -// make a copy of a var TODO make a real comment +// make a copy of a var TODO make a real comment void print_copy(struct symtable * t, struct code * c, FILE* fout,int i); // load whether a named var or a constant TODO find a better name ! void print_nameOrInteger(struct code * c, FILE* fout,int i,int sym); // -------- MACROS -------- + +/** @brief load_symbol_alloc_macro load a symbol used for an sbrk allocation ( multiply it's value by 4) + */ void load_symbol_alloc_macro(char * dest, int tmp_used, struct symbol * sym, struct symtable * t, FILE* fout); +/** @brief load_symbol_macro load a symbol value into the dest register + */ void load_symbol_macro(char * dest, struct symbol * sym, struct symtable * t, FILE* fout); -void get_tab_addr_macro(char * dest, int tmp_used1, int tmp_used2, struct symbol * sym_addr, struct symbol * sym_index, struct symtable * t, FILE* fout); +/** @brief load_tab_addr_macro given a symbol adress and a symbol index put the addr of array[n] element in dest + * tmp_used1 and tmp_used2 won't be saved so ensure nothing that should be saved is in + */ +void load_tab_addr_macro(char * dest, int tmp_used1, int tmp_used2, struct symbol * sym_addr, struct symbol * sym_index, struct symtable * t, FILE* fout); + +/** @brief load_addr_macro put the memory adress of sym into the dest register + */ +void load_addr_macro(char * dest, struct symbol * sym, struct symtable * t, FILE* fout); -/** Macro printer - * only print the LF macro for the moment - * should becalled between .data and .text segments +/** @brief Macro printer only print the LF and SPACE macros for the moment + * should be called between .data and .text segments */ void print_macros(FILE* fout); -/** Add a macro to print a LF in MIPS code +/** @brief print_LF_macro add a macro to print a LF in MIPS code */ void print_LF_macro(FILE* fout); -/** Add a macro to print a SPCE in MIPS code +/** @brief print_SPACE_macro add a macro to print a SPCE in MIPS code */ void print_SPACE_macro(FILE* fout); @@ -221,7 +238,7 @@ void debug_register_strings_declaration(FILE * fout); /************************* NAME TO DEFINE FUNCTIONS *************************/ // add a tabulation to the indentation string -void add_indent(); +void add_indent(int code, struct code* c, struct symtable* t, FILE* fname); // remove a tabulation from the indentation string int remove_indent(); -- GitLab