diff --git a/Codes_en_COREC/tests/test10.corec b/Codes_en_COREC/tests/test10.corec
index 0c8d007c1353a0a44cf90a9fb05f46b8204837ac..c576aa63f3efd6105588fac4f0f941af001e7bff 100644
--- a/Codes_en_COREC/tests/test10.corec
+++ b/Codes_en_COREC/tests/test10.corec
@@ -1 +1,24 @@
 // For with Dom
+
+
+
+prog Test10 {
+    def Main{
+        Loc: c, a=15331, NP=10
+        Dom: i in [0..NP-1], j in [0..NP-1], k in [0..NP-1], l in [0..NP-1], m in [0..NP-1]
+        Rec: {
+            c = 10000*i + 1000*j + 100*k + 10*l + m +1;
+
+            c%a==0?{
+                print(c)
+            }:
+            c==100000?{
+                print(c);
+                printstr("counting from 1 to 100000 (5 imbricated loop going from 0 to 9)\n");
+                printstr("change a value in the test to print every time the count is");
+                printstr(" a multiple of a or when reaching 100000\nonly print every : ");
+                print(a)
+            }:
+        }
+    }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 32880ef3d082d075bda597a00dfd618a89574586..d6f7dcc53d835684275f4a989da30a76218f5c45 100644
--- a/README.md
+++ b/README.md
@@ -60,6 +60,8 @@ sudo apt install bison
 ### 9.branch test9
 - Read an int into an int variable
 - Read a float into a float variable
+### 10.branch test10
+- implemented DOM for main and functions
 
 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 3212409829d15e8fae7d43f1fe4c10e716706c7c..db288670d11266b49fec5deb44575ada513dfa01 100644
--- a/corec.y
+++ b/corec.y
@@ -13,6 +13,9 @@ uint8_t isPrintCall = 0;
 
 // stack of the IF ELSE calls
 struct labelStack *  condition_stack;
+// stacks of the DOM
+struct domStack * dom_stack;
+
 
 int indent;
 char tabulation[INDENT_BUF];
@@ -28,6 +31,8 @@ void exit_safely(){
         free(tabArrayDim);
     }
     yylex_destroy(); 
+    free_stack((void**)condition_stack,LBLSTACK);
+    free_stack((void**)dom_stack,DOMSTACK);
     free_exit(1,CODE,SYMTAB,fname);
 }
 
@@ -362,10 +367,62 @@ DOMLIST :
     ;
 D : 
     ID1 in_dom left_bracket E double_period E right_bracket
+    {
+        struct symbol * id = symtable_get(SYMTAB,$1,symb_scope_function);
+        struct symbol * loop_start, * loop_end;
+        
+        if(id == NULL || strcmp(id->scope_function,symb_scope_function->u.name) != 0 )
+        {
+            id = symtable_put_loc(SYMTAB,$1,symb_scope_function);
+        } else {
+            fprintf(stderr, "Error at line %u in function '%s': DOM var shouldn't exist yet.\n",lineNumber,symb_scope_function->u.name);
+            exit_safely();
+        }
+        
+        loop_start = symtable_put_label(SYMTAB,"loop_start",SYMTAB->dom,symb_scope_function);
+        loop_end = symtable_put_label(SYMTAB,"loop_end",SYMTAB->dom,symb_scope_function);
+        ++(SYMTAB->dom);
+        domQuad * to_push;
+        CHK(to_push = malloc(sizeof(domQuad)),NULL);
+        to_push->dom_var=id;
+        to_push->lbl1=loop_start;
+        to_push->lbl2=loop_end;
+        // copy the start val into the dom var
+        gencode(CODE,COPY,id,$4.ptr,NULL);
+        // put the start loop label
+        gencode(CODE,LABEL_W,loop_start,NULL,NULL);
+        // we add an indent level since we enter a new label
+        gencode(CODE, ADD_INDENT,NULL,NULL,NULL);
+        // branch to end of loop if dom var (i,j,k or anything it's named) is greater than the end value of the loop (if lesser or equal is false)
+        gencode(CODE,OPREL_LE,loop_end,id,$6.ptr);
+        // now the start of the loop is initialized we just put the infos needed for the end in the stack
+        push_stack((void*)(&dom_stack),to_push,DOMSTACK);
+        
+    }
     ;
 
 REC : 
     rec BLOCKINST
+    {
+        // once the rec block is over we have to add the end of the different dom loops
+        while(dom_stack != NULL)
+        {
+            // we get the head of the stack which should be the first elt since DOMLIST access the doms from right to left if wrongjust reverse it
+            domQuad * tmp = head_stack((void**)(&dom_stack), DOMSTACK);
+            // we can now gen the END LOOP code
+            struct symbol * one = symtable_const_int(SYMTAB,1);
+            // add one to the loop index
+            gencode(CODE,BOP_PLUS,tmp->dom_var,tmp->dom_var,one);
+            // jump to start of loop
+            gencode(CODE,GOTO_LABEL,tmp->lbl1,NULL,NULL);
+            // end of this loop
+            gencode(CODE,RM_INDENT,NULL,NULL,NULL);
+            // put the end loop label
+            gencode(CODE,LABEL_W,tmp->lbl2,NULL,NULL);
+            // no longer of use we delete it with it's elt
+            pop_stack((void**)(&dom_stack), DOMSTACK, 1);
+        }
+    }
     | %empty // Error dectection -> Function without a rec section
         {
             fprintf(stderr, "Error at line %u in function '%s': Unexpected end of function (shouldn't be empty).\n",lineNumber,symb_scope_function->u.name);
@@ -931,9 +988,9 @@ COND :
         {
             // ENDIF label
             gencode(CODE,RM_INDENT,NULL,NULL,NULL);
-            gencode(CODE,LABEL_W,condition_stack->elt.lbl2,NULL,NULL);
+            gencode(CODE,LABEL_W,condition_stack->elt->lbl2,NULL,NULL);
             
-            pop_stack(&condition_stack); // we pop the current condition's labels since the condition is now over
+            pop_stack((void**)(&condition_stack),LBLSTACK,1); // we pop the current condition's labels since the condition is now over
         }
     ;
 B : 
@@ -974,36 +1031,37 @@ CONDCHECK:
     E OPREL E  {
 
         
-        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);
+        wardLabels * tmp;
+        CHK(tmp = malloc(sizeof(wardLabels)),NULL); 
+        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);
+                gencode(CODE,OPREL_LT,tmp->lbl1,$1.ptr,$3.ptr);
                 break;
 
             case 2:
-                gencode(CODE,OPREL_GT,tmp.lbl1,$1.ptr,$3.ptr);
+                gencode(CODE,OPREL_GT,tmp->lbl1,$1.ptr,$3.ptr);
                 break;
 
             case 3:
-                gencode(CODE,OPREL_LE,tmp.lbl1,$1.ptr,$3.ptr);
+                gencode(CODE,OPREL_LE,tmp->lbl1,$1.ptr,$3.ptr);
                 break;
 
             case 4:
-                gencode(CODE,OPREL_GE,tmp.lbl1,$1.ptr,$3.ptr);
+                gencode(CODE,OPREL_GE,tmp->lbl1,$1.ptr,$3.ptr);
                 break;
 
             case 5:
-                gencode(CODE,OPREL_EQ,tmp.lbl1,$1.ptr,$3.ptr);
+                gencode(CODE,OPREL_EQ,tmp->lbl1,$1.ptr,$3.ptr);
                 break;
 
             default:
                 fprintf(stderr, "BUG\n");
                 break;
         }
-        push_stack(&condition_stack,tmp);
+        push_stack((void**)(&condition_stack),(void*)tmp,LBLSTACK);
         (SYMTAB->condition) ++;
         // go to else si la condition est fausse
 
@@ -1014,7 +1072,7 @@ THEN :
     ternary_then
     {
         
-        struct symbol * if_label = symtable_put_label(SYMTAB, "if", condition_stack->elt.cond_number, symb_scope_function);
+        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);
@@ -1025,10 +1083,10 @@ ELSE :
     ternary_else
     {
         // goto endif juste après le code du IF
-        gencode(CODE, GOTO_LABEL, condition_stack->elt.lbl2, NULL, NULL);
+        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, LABEL_W, condition_stack->elt->lbl1, NULL, NULL);
         gencode(CODE,ADD_INDENT,NULL,NULL,NULL);
     }
     ;
diff --git a/lib.c b/lib.c
index 960b2decdc9c8d8c2b8b5a6528d8c46c32af6720..369288f3c3884ebc33be1589ab17437c7631f224 100644
--- a/lib.c
+++ b/lib.c
@@ -17,8 +17,14 @@ struct symtable * symtable_new()
         fprintf(stderr,"Bug memory allocation failed\n");
         exit(1);
     }
+    // make the stack point to null at start
+    condition_stack = NULL;
+    dom_stack = NULL;
+
+    // init the different counters 
     t->temporary = 0;
     t->condition = 0;
+    t->dom = 0;
     t->size = 0;
     init_indent();
     return t;
@@ -87,23 +93,32 @@ struct symbol* symtable_const_double(struct symtable * t, float v)
     }
 }
 
+// for a given name return either a local symbol with the right scope or a non local symbol 
 struct symbol* symtable_get(struct symtable * t, const char * id, struct symbol* func_id) 
 {
+    //should
     unsigned int i;
-    for ( i=0 ; i<t->size && strcmp(t->symbols[i].u.name,id) != 0; i++ );
-    if(i<t->size){
-        if(t->symbols[i].kind == NAME_LOC || t->symbols[i].kind == ARRAY){
-            if(strcmp(func_id->u.name,t->symbols[i].scope_function) == 0){
-                return &(t->symbols[i]);
+    struct symbol * best_fit = NULL;
+    for ( i=0 ; i<t->size; i++ )
+    {
+        if(strcmp(t->symbols[i].u.name,id) == 0)
+        {
+            if(t->symbols[i].kind == NAME_LOC || t->symbols[i].kind == ARRAY)
+            { // these names are only unique whithin a function_scope
+                // if the scope function is the same it's the right symbol
+                if(strcmp(func_id->u.name,t->symbols[i].scope_function) == 0)
+                    return &(t->symbols[i]);
+            } 
+            else if ((t->symbols[i].kind == NAME || t->symbols[i].kind == NAME_FLOAT || t->symbols[i].kind == LABEL) )  
+            { // these names are supposed to be unique so no overwrite of best_fit should be happening
+                best_fit = &(t->symbols[i]);
             }
-            return NULL;
-        } 
-        return &(t->symbols[i]);
+        }
     }
-      
-    return NULL;
+    return best_fit;
 }
 
+
 struct symbol* symtable_put_name(struct symtable * t, const char * id) 
 {
     if(t->size==t->capacity)
@@ -419,36 +434,41 @@ static void quad_dump(struct quad * q, FILE* fout)
             fprintf(fout,"]");
             break;
         case OPREL_EQ:
+            fprintf(fout,"go to  ");
             symbol_dump(q->sym1,fout);
-            fprintf(fout," := ");
+            fprintf(fout," if ");
             symbol_dump(q->sym2,fout);
             fprintf(fout," == ");
             symbol_dump(q->sym3,fout);
             break;
         case OPREL_GE:
+            fprintf(fout,"go to  ");
             symbol_dump(q->sym1,fout);
-            fprintf(fout," := ");
+            fprintf(fout," if ");
             symbol_dump(q->sym2,fout);
             fprintf(fout," >= ");
             symbol_dump(q->sym3,fout);
             break;
         case OPREL_GT:
+            fprintf(fout,"go to  ");
             symbol_dump(q->sym1,fout);
-            fprintf(fout," := ");
+            fprintf(fout," if ");
             symbol_dump(q->sym2,fout);
             fprintf(fout," > ");
             symbol_dump(q->sym3,fout);
             break;
         case OPREL_LE:
+            fprintf(fout,"go to  ");
             symbol_dump(q->sym1,fout);
-            fprintf(fout," := ");
+            fprintf(fout," if ");
             symbol_dump(q->sym2,fout);
             fprintf(fout," <= ");
             symbol_dump(q->sym3,fout);
             break;
         case OPREL_LT:
+            fprintf(fout,"go to  ");
             symbol_dump(q->sym1,fout);
-            fprintf(fout," := ");
+            fprintf(fout," if ");
             symbol_dump(q->sym2,fout);
             fprintf(fout," < ");
             symbol_dump(q->sym3,fout);
@@ -1429,31 +1449,127 @@ 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;
+// -------- STACK RELATED --------
+
+
+
+void push_stack(void** stack, void* new_elt, enum stacktype type) {
+    switch (type) {
+        case LBLSTACK: {
+            labelStack* new_l;
+            CHK(new_l = malloc(sizeof(labelStack)), NULL);
+            labelStack** curr_stack_l = (labelStack**)stack;
+            // setup the new head of stack
+            new_l->previous = *curr_stack_l;
+            new_l->elt = (wardLabels*)new_elt;
+            // update the ptr to the head of the stack
+            *curr_stack_l = new_l;
+            break;
+        }
+        case DOMSTACK: {
+            domStack* new_d;
+            CHK(new_d = malloc(sizeof(domStack)), NULL);
+            domStack** curr_stack_d = (domStack**)stack;
+            // setup the new head of stack
+            new_d->previous = *curr_stack_d;
+            new_d->elt = (domQuad*)new_elt;
+            // update the ptr to the head of the stack
+            *curr_stack_d = new_d;
+            break;
+        }
+        default:
+            fprintf(stderr, "Error during push stack, this stack type doesn't exist.\n");
+            break;
+    }
+}
+
+
+
+void pop_stack(void** stack, enum stacktype type, int del_elt) {
+    if (*stack == NULL) {
+        fprintf(stdout, "Trying to pop an empty stack\n");
+        return;
+    }
+
+    switch (type) {
+        case LBLSTACK: {
+            labelStack** curr_stack_l = (labelStack**)stack;
+
+            // Free elt if we don't need it ( del_elt !=0 )
+            if (del_elt && (*curr_stack_l)->elt != NULL) {
+                free((*curr_stack_l)->elt);
+                (*curr_stack_l)->elt = NULL;
+            }
+            labelStack* tmp_l = *curr_stack_l;
+            *curr_stack_l = (*curr_stack_l)->previous;
+            free(tmp_l);
+            tmp_l = NULL;
+            break;
+        }
+
+        case DOMSTACK: {
+            domStack** curr_stack_d = (domStack**)stack;
+            // Free elt if we don't need it ( del_elt !=0 )
+            if (del_elt && (*curr_stack_d)->elt != NULL) {
+                free((*curr_stack_d)->elt);
+                (*curr_stack_d)->elt = NULL;
+            }
+            domStack* tmp_d = *curr_stack_d;
+            *curr_stack_d = (*curr_stack_d)->previous;
+            free(tmp_d);
+            tmp_d = NULL;
+            break;
+        }
+
+        default:
+            fprintf(stderr, "Error during pop stack, this stack type doesn't exist.\n");
+            break;
+    }
 }
 
-void pop_stack(labelStack ** stack)
+void * head_stack(void ** stack, enum stacktype type)
 {
     if((*stack) == NULL)
     {
-        fprintf(stdout,"Trying to pop an empty stack \n");
-        return;
+        fprintf(stdout,"Trying to get the head of an empty stack, shouldn't happen\n");
+        return NULL;
+    }
+    switch(type)
+    {
+        case LBLSTACK:
+            return (void*) ((*(labelStack **)stack)->elt);
+        case DOMSTACK:
+            return (void*) ((*(domStack **)stack)->elt);
+        default:
+            fprintf(stderr, "Error during head return stack, this stack type doesn't exist.\n");
+            return NULL;
     }
-    labelStack * tmp = (*stack);
-    (*stack) = tmp->previous;
-    free(tmp);
 }
 
+void free_stack(void ** stack, enum stacktype type)
+{
+    switch(type)
+    {
+        case LBLSTACK:
+            labelStack ** curr_stack_l = (labelStack **) stack;
+            while(*curr_stack_l != NULL)
+                pop_stack((void**)curr_stack_l,LBLSTACK,1);
+            break;
+        case DOMSTACK:
+            domStack ** curr_stack_d = (domStack **) stack;
+            while(*curr_stack_d != NULL)
+                pop_stack((void**)curr_stack_d,DOMSTACK,1);
+            break;
+        default:
+            fprintf(stderr, "Error during free stack, this stack type doesn't exist.\n");
+            break;
+    }
+}
+
+
+// -------- ERROR CHECK --------
+
 void raler(int err)
 {
     if (err == 1)
diff --git a/lib.h b/lib.h
index c0b24fd69963d59da11dfc45f9904d0c64bfb23f..b92cf2d02178197995671a9a8cde7b3451c4132f 100644
--- a/lib.h
+++ b/lib.h
@@ -65,6 +65,7 @@ struct symtable {
     unsigned int capacity;
     unsigned int temporary; 
     unsigned int condition;
+    unsigned int dom; // TODO could make a name based on the local var and the functon, for the moment don't wan't to handle names being too loong
     unsigned int size;
     struct symbol* symbols;
 };
@@ -306,6 +307,12 @@ void debug_register_strings_declaration(FILE * fout);
 #endif
 
 // -------- STACK RELATED --------
+
+enum stacktype {
+    LBLSTACK,
+    DOMSTACK,
+};
+
 typedef struct {
     int cond_number;
     struct symbol * lbl1;
@@ -313,19 +320,41 @@ typedef struct {
 } wardLabels;
 
 typedef struct labelStack{
-    wardLabels elt;
+    wardLabels * elt;
     struct labelStack * previous;
 } labelStack;
 
+typedef struct {
+    struct symbol * dom_var;
+    struct symbol * lbl1;
+    struct symbol * lbl2;
+} domQuad;
+
+typedef struct domStack{
+    domQuad * elt;
+    struct domStack * previous;
+} domStack;
+
 extern labelStack *  condition_stack;
+extern domStack *  dom_stack;
+
+
 
 /** @brief add an element on top of the stack
  */
-void push_stack(labelStack ** stack, wardLabels new_elt);
+void push_stack(void ** stack, void * new_elt, enum stacktype types);
 
 /** @brief pop the top element of the stack
+ * if del_elt != 0, free the elt inside of the stack struct
  */
-void pop_stack(labelStack ** stack);
+void pop_stack(void ** stack, enum stacktype type, int del_elt);
+
+void * head_stack(void ** stack, enum stacktype type);
+
+/** @brief free a whole stack
+ */
+void free_stack(void ** stack, enum stacktype type);
+
 
 // -------- ERROR CHECK --------