diff --git a/Codes_en_COREC/tests/test2.corec b/Codes_en_COREC/tests/test2.corec
index aef0f5d090e98b81fc019a0dc926e32c83af8804..1cbbcefab7b8f55633225918062c09ad436fbb07 100644
--- a/Codes_en_COREC/tests/test2.corec
+++ b/Codes_en_COREC/tests/test2.corec
@@ -8,41 +8,44 @@ prog Test2{
             b = 2;
 
             c = a+b;
-            printstr("Addition, attendu 12");
+            printstr("Addition, attendu 12: ");
             print(c);
 
             c = a-b;
-            printstr("Substraction, attendu 8");
+            printstr("Substraction, attendu 8: ");
             print(c);
 
             c = a*b;
-            printstr("Multiplication, attendu 20");
+            printstr("Multiplication, attendu 20: ");
             print(c);
 
             c = a/b;
-            printstr("Division, attendu 5");
+            printstr("Division, attendu 5: ");
             print(c);
 
             a += b;
-            printstr("Addition aff, attendu 12");
-            print(c);
+            printstr("Addition aff, attendu 12: ");
+            print(a);
 
             a *= b;
-            printstr("Addition mult, attendu 24");
-            print(c);
+            printstr("Addition mult, attendu 24: ");
+            print(a);
 
             a /= b;
-            printstr("Addition mult, attendu 12");
-            print(c);
+            printstr("Addition mult, attendu 12: ");
+            print(a);
 
             a -= 4;
-            printstr("Addition mult, attendu 8");
-            print(c);
+            printstr("Addition mult, attendu 8: ");
+            print(a);
 
             c = a*a+2+b*b;
+            printstr("Addition mult, attendu 70: ");
             print(c);
 
-            c= a*(a+b)-c/2
+            c= a*(a+b)-c/2;
+            printstr("Addition mult, attendu 45: ");
+            print(c)
         }
     }
 }
diff --git a/corec.y b/corec.y
index 32dfb04e05f9b29f60c3835f593aed74f014deba..daa750362ef8c7cfcf3fab07aba74660285447c6 100644
--- a/corec.y
+++ b/corec.y
@@ -139,7 +139,7 @@ PROG :
             }
             id = symtable_put_name(SYMTAB,"Main");
             symb_scope_function = id;
-            gencode(CODE,DEF_FUNCTION,id,NULL,NULL);
+            gencode(CODE,DEF_MAIN,id,NULL,NULL);
         }
     left_curly_bracket LOC DOM REC right_curly_bracket right_curly_bracket
     ;
diff --git a/lib.c b/lib.c
index 997d1010ce21b9614e771150258d46ef1167b231..951755b5eab75c04b5bee6e42097d70a10399313 100644
--- a/lib.c
+++ b/lib.c
@@ -1,6 +1,11 @@
 
 #include "lib.h"
 
+// TODO make it in a cleaner way
+int indent = 0;
+char tabulation[INDENT_BUF] = "";
+
+#define INDENT_MAKER
 struct symtable * symtable_new()
 {
     struct symtable * t = malloc(sizeof(struct symtable));
@@ -325,6 +330,10 @@ static void quad_dump(struct quad * q, FILE* fout)
             fprintf(fout,"- ");
             symbol_dump(q->sym2,fout);
             break;
+        case DEF_MAIN:
+            symbol_dump(q->sym1,fout);
+            fprintf(fout,":");
+            break;
         case DEF_FUNCTION:
             symbol_dump(q->sym1,fout);
             fprintf(fout,":");
@@ -417,40 +426,51 @@ void code_mips_dump(struct symtable * t, struct code * c, FILE* fout){
         else if(t->symbols[i].kind == NAME_LOC){
             fprintf(fout,"\t%s: .word 0\n",t->symbols[i].u.name);
         }
+        else if(t->symbols[i].kind == NAME){
+            fprintf(fout,"\t%s: .word 0\n",t->symbols[i].u.name);
+        }
         else{ //NAME
             fprintf(fout,"\ttemp%d: .word 0\n",i);
         }
     }
 
-    //Macro for new line print
-    fprintf(fout,".macro LF\n");
-    fprintf(fout,"\tli $v0, 4\n");
-    fprintf(fout,"\tla $a0, lf\n");
-    fprintf(fout,"\tsyscall\n");
-    fprintf(fout,".end_macro\n");
-    fprintf(fout,"\n\n.text\n  main:\n");
-
-
+    print_macros(fout);
+    
+    // start of the .text segment
+    fprintf(fout,"\n\n.text\n");
 
     for(i = 0; i<c->nextquad; i++){
         switch (c->quads[i].kind)
         {
+            case BOP_PLUS:
+                print_bop_plus(c,fout,i);
+                break;
+            case BOP_MINUS:
+                print_bop_minus(c,fout,i);
+                break;
+            case BOP_MULT:
+                print_bop_mult(c,fout,i);
+                break;
+            case BOP_DIV:
+                print_bop_div(c,fout,i);
+                break;
+            case BOP_MOD:
+                print_bop_mod(c,fout,i);
+                break;
+            case UOP_MINUS:
+                print_uop_minus(c,fout,i);
+                break;
+            case DEF_MAIN:
+                print_main_def(fout);
+                break;
             case CALL_PRINT:
-                fprintf(fout,"\tlw $t0, %s\n",c->quads[i].sym1->u.name);
-                fprintf(fout,"\tmove $a0, $t0\n");
-                fprintf(fout,"\tli $v0, 1\n");
-                fprintf(fout,"\tsyscall\n");
-                //Return to line
-                fprintf(fout,"\tLF\n");
+                print_print(c,fout,i);
                 break;
             case CALL_PRINTSTR:
-                fprintf(fout,"\tli $v0, 4\n");
-                fprintf(fout,"\tla $a0, temp%d\n",indice_temp(t,c->quads[i].sym1));
-                fprintf(fout,"\tsyscall\n");
+                print_printstr(t,c,fout,i);
                 break;
             case COPY:
-                fprintf(fout,"\tlw $t0, temp%d\n",indice_temp(t,c->quads[i].sym2));
-                fprintf(fout,"\tsw $t0, %s\n",c->quads[i].sym1->u.name);
+                print_copy(t,c,fout,i);
                 break;
             default:
                 fprintf(stderr,"#BUG %d\n",c->quads[i].kind);
@@ -475,3 +495,178 @@ void free_exit(int code, struct code* c, struct symtable* t, FILE* fname){
     if(fname!=NULL){fclose(fname);}
     exit(code);
 }
+
+
+/************************* MIPS CODE GEN FUNCTIONS *************************/
+
+// -------- MAIN RELATED --------
+
+void print_main_def(FILE* fout){
+    fprintf(fout,".globl start\n\n");
+    fprintf(fout,"start:\n");
+    add_indent();
+}
+
+// -------- ARITHMETIC RELATED --------
+
+void print_bop_plus(struct code * c, FILE* fout,int i)
+{
+    //Check if we have variable names or just integers for sym2 and sym3
+    print_nameOrInteger(c,fout,i,0b110);
+    //Do the operation and save result in wanted variable
+    fprintf(fout,"\tadd $t0, $t0, $t1\n");
+    fprintf(fout,"\tsw $t0, %s\n",c->quads[i].sym1->u.name);
+}
+
+void print_bop_minus(struct code * c, FILE* fout,int i)
+{
+    //Check if we have variable names or just integers
+    print_nameOrInteger(c,fout,i,0b110);
+    //Do the operation and save result in wanted variable
+    fprintf(fout,"\tsub $t0, $t0, $t1\n");
+    fprintf(fout,"\tsw $t0, %s\n",c->quads[i].sym1->u.name);
+}
+
+void print_bop_mult(struct code * c, FILE* fout,int i)
+{
+    //Check if we have variable names or just integers for sym2 and sym3
+    print_nameOrInteger(c,fout,i,0b110);
+    //Do the operation and save result in wanted variable
+    fprintf(fout,"%smul $t0, $t0, $t1\n",tabulation);
+    fprintf(fout,"%ssw $t0, %s\n",tabulation,c->quads[i].sym1->u.name);
+}
+
+void print_bop_div(struct code * c, FILE* fout,int i)
+{
+    //Check if we have variable names or just integers for sym2 and sym3
+    print_nameOrInteger(c,fout,i,0b110);
+    //Do the operation and save result in wanted variable
+    fprintf(fout,"%sdiv $t0, $t0, $t1\n",tabulation);
+    fprintf(fout,"%ssw $t0, %s\n",tabulation,c->quads[i].sym1->u.name);
+}
+
+void print_bop_mod(struct code * c, FILE* fout,int i)
+{
+    //Check if we have variable names or just integers for sym2 and sym3
+    print_nameOrInteger(c,fout,i,0b110);
+    //Do the operation and save result in wanted variable
+    fprintf(fout,"%sdiv $t0, $t0, $t1\n",tabulation);
+    fprintf(fout,"%smfhi $t0\n",tabulation);
+    fprintf(fout,"%ssw $t0, %s\n",tabulation,c->quads[i].sym1->u.name);
+}
+
+void print_uop_minus(struct code * c, FILE* fout,int i)
+{
+    fprintf(fout,"%slw $t0, %s\n",tabulation,c->quads[i].sym1->u.name);
+    //Check if we have variable names or just integers
+    if(c->quads[i].sym2->kind == NAME || c->quads[i].sym2->kind == NAME_LOC)
+        fprintf(fout,"%slw $t1, %s\n",tabulation,c->quads[i].sym2->u.name);
+    else if(c->quads[i].sym2->kind == CONSTANT_INT)
+        fprintf(fout,"%sli $t1, %ld\n",tabulation,c->quads[i].sym2->u.value_int);
+
+    //Do the operation and save result in wanted variable
+    fprintf(fout,"%ssub $t0, $t0, $t1\n",tabulation);
+    fprintf(fout,"%ssw $t0, %s\n",tabulation,c->quads[i].sym1->u.name);
+}
+
+// -------- PRINT RELATED --------
+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);
+    fprintf(fout,"%sli $v0, 1\n",tabulation);
+    fprintf(fout,"%ssyscall\n",tabulation);
+    //Return to line
+    fprintf(fout,"%sLF\n",tabulation);
+}
+
+void print_printstr(struct symtable * t, struct code * c, FILE* fout,int i)
+{
+    fprintf(fout,"%sli $v0, 4\n",tabulation);
+    fprintf(fout,"%sla $a0, temp%d\n",tabulation,indice_temp(t,c->quads[i].sym1));
+    fprintf(fout,"%ssyscall\n",tabulation);
+}
+
+// -------- FUNCTIONS RELATED --------
+
+// -------- MISCELLANEOUS --------
+
+void print_copy(struct symtable * t, struct code * c, FILE* fout,int i)
+{
+    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
+        fprintf(fout,"%slw $t0, temp%d\n",tabulation,indice_temp(t,c->quads[i].sym2));
+    fprintf(fout,"%ssw $t0, %s\n",tabulation,c->quads[i].sym1->u.name);
+}
+
+/***    do the right thing based on whether we have an named var or a constant TODO finde a better name !
+ *      if on sym 1 sym = 0b1 do on sym1 (not implmented should never be of use)
+ *      if on sym 2 sym = 0b10 etc
+ *      if on sym 2 and 3 but not 1 simultaneously sym = 0b110
+ *      to use only on BOP operations PLUS MINUS MUL DIV MOD
+ *      TODO sym may be useless and may be removed later
+ */ 
+
+void print_nameOrInteger(struct code * c, FILE* fout,int i,int sym)
+{
+    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(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)
+            fprintf(fout,"%sli $t1, %ld\n",tabulation,c->quads[i].sym3->u.value_int);
+    }
+}
+
+
+/** 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);
+    fprintf(fout,"# End of MACROS definition\n");
+}
+
+void print_LF_macro(FILE* fout){
+    fprintf(fout,".macro LF\n");
+    fprintf(fout,"\tli $v0, 4\n");
+    fprintf(fout,"\tla $a0, lf\n");
+    fprintf(fout,"\tsyscall\n");
+    fprintf(fout,".end_macro\n");
+}
+// ETC FEEL FREE TO ADD MORE SECTIONS
+
+/************************* NAME TO DEFINE FUNCTIONS *************************/
+
+
+
+void add_indent(){
+    if(indent >= 1022)
+    {
+        printf("more than 1023 indentations ! write better code.\n");
+        exit(-1);
+    }
+    tabulation[indent] = '\t';
+    indent++;
+    tabulation[indent] = '\0';
+}
+
+int remove_indent(){
+    if(indent == 0)
+    {
+        printf("shouldn't be removing a tab since there are none, resuming \n");
+        return -1;
+    }
+    indent--;
+    tabulation[indent] = '\0';
+    return 0;
+}
\ No newline at end of file
diff --git a/lib.h b/lib.h
index d8c32da2eeb48851e97a16d824344c0a9826f87c..6a894396021f1a11abffa021779a0d26742bf1c1 100644
--- a/lib.h
+++ b/lib.h
@@ -6,6 +6,8 @@
 extern unsigned int lineNumber;
 extern struct symbol* symb_scope_function;
 
+#define INDENT_BUF 1024
+
 /* TABLE DES SYMBOLES */
 
 typedef char name_t[64];
@@ -85,7 +87,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_FUNCTION, CALL_PRINT, CALL_PRINTSTR} 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} kind;
   struct symbol* sym1;
   struct symbol* sym2;
   struct symbol* sym3;
@@ -122,3 +124,68 @@ void code_free(struct code * c);
 void free_exit(int code, struct code* c, struct symtable* t, FILE* fname);
 
 
+/************************* MIPS CODE GEN FUNCTIONS *************************/
+
+// -------- MAIN RELATED --------
+
+// print the starting flag so MIPS code know where he should start reading code from
+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 ?)
+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 ?)
+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 ?)
+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 ?)
+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 ?)
+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 ?)
+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);
+
+// add the code to  print the asked string
+void print_printstr(struct symtable * t, struct code * c, FILE* fout,int i);
+
+// -------- FUNCTIONS RELATED --------
+
+// -------- MISCELLANEOUS --------
+
+
+// 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);
+
+/** 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 
+ */
+void print_LF_macro(FILE* fout);
+// ETC FEEL FREE TO ADD MORE SECTIONS
+
+/************************* NAME TO DEFINE FUNCTIONS *************************/
+
+// add a tabulation to the indentation string
+void add_indent();
+
+// remove a tabulation from the indentation string
+int remove_indent();
+