let rec genCommand (c: cmd) (dect: dec_table) (proct: proc_table) (ic: intermediateCode): unit = match c with
      
      (** Assuming that the types between Left and Right of assignment are correct, first is generated the code for the right part, then the code for the left part. *)

      Ass(l,a)                  ->  (
                                     let rop = genArithmetical a dect proct ic in
                                     match l with
                                        LVar(i)     ->  let (_, _, stackoff) = getVarDeclaration i dect in
                                                        ic#addInstr (CPY, rop, Null, stackoff) 
                                                             (** If the left part is a variable, only copy the value *)

                                      | LVec(i,x)   ->  let xRes = genArithmetical x dect proct ic and
                                                        (_, _, stackoff) = getVecDeclaration i 0 (-1) dect in
                                                        ic#addInstr (ASET, stackoff, xRes, rop) 
                                                             (** If is a vector, use the instruction ASET with xRes *)

                                      | LMat(i,x,y) ->  let xRes = genArithmetical x dect proct ic and
                                                        yRes = genArithmetical y dect proct ic and
                                                        r1,r2,r3 = (ic#getReg),(ic#getReg),(ic#getReg) and
                                                        (_, dim, stackoff) = getVecDeclaration i 0 0 dect in (
                                                            ic#addInstr (MUL, (Val(I(dim))), xRes, (Reg(r1,DInt)));
                                                            ic#addInstr (ADD, (Reg(r1,DInt)), yRes, (Reg(r2,DInt)));
                                                            ic#addInstr (ASET, stackoff, (Reg(r2,DInt)), rop); 
                                                            
                                                            (** Position into the memory of a matrix is (dim_of_line * number_of_lines) + number_of_columns this value is used into the ASET instruction *)

                                                        )
                                    )
      
      (** A block is a list of commands, so when there is something into the list the genCommand is invoked on the element and then on the remaining list; when the list is empty is added a No-Operation Instruction *)

    | Blk(cmdl)                 ->  (
                                     match cmdl with
                                         []      ->  let newinstr = (NOPNullNullNullin
                                                     ic#addInstr newinstr
                                       | x::xs   ->  genCommand x dect proct ic; genCommand (Blk(xs)) dect proct ic
                                    )
      
      (** The write operation is converted into an OUT instruction *)

    | Write(ex)                 ->  (
                                     let newinstr = (OUT, (genArithmetical ex dect proct ic), NullNullin
                                     ic#addInstr newinstr
                                    )
      
      (** First are generated the labels for the start and the end of the while: the start is setted at the current point, then is generated the boolean condition and the register where the result of the compare is saved. After this the command of the while is generated, the GOTO instruction is added and finally is setted the end Label *)

    | While(b,c)                ->  (
                                     let startwhile,endwhile = ic#getLabel,ic#getLabel in
                                        (
                                         ic#addLabel startwhile (ic#getIc);
                                         let result = (genBoolean b dect proct ic) in
                                         ic#addInstr (JNE, result, Val(I(1)), endwhile);
                                         (genCommand c dect proct ic);
                                         ic#addInstr (GOTO, startwhile, NullNull);
                                         ic#addLabel endwhile (ic#getIc);
                                        )
                                    )
    
    (** Same as the "While", but first of all an execution of the command is added *)

    | Repeat(c,b)               ->  (
                                     genCommand c dect proct ic;
                                     genCommand (While(b,c)) dect proct ic
                                    )
    
    (** Here are generated 2 labels, one for the else RAMO and one for the end of the if; the code for the boolean compare is generated, then the code of c1 (if the condition is true) with a GOTO to the end of the if command and finally the code of c2 (if the condition is false) *)

    | Ite(b,c1,c2)              ->  (
                                     let elseif, endif = ic#getLabel,ic#getLabel in 
                                        (
                                         let result = (genBoolean b dect proct ic) in
                                         ic#addInstr (JNE, result, Val(I(0)), elseif);
                                         (genCommand c1 dect proct ic);
                                         ic#addInstr (GOTO, endif, NullNull);
                                         ic#addLabel elseif (ic#getIc);
                                         (genCommand c2 dect proct ic);
                                         ic#addLabel endif (ic#getIc);
                                        )
                                    )
    
    (** First is generated the values for the start and end conditions, then the start value is copied into the cycle variable position and the start label is setted. After this there is the compare instruction, the command generation and the assignment of the incremented value into the cycle variable. Finally there is the GOT start label instruction and the end label is setted *)

    | For(id,start,finish,c)    ->  (
                                     let startfor,endfor = ic#getLabel,ic#getLabel in
                                     (
                                      let init,ending = (genArithmetical start dect proct ic),(genArithmetical finish dect proct ic) and
                                      increg, tmpreg = (genArithmetical (Var(id)) dect proct ic), ic#getReg in
                                      ic#addInstr (CPY, init, Null, increg);
                                      ic#addLabel startfor (ic#getIc);
                                      ic#addInstr (CG, increg, ending, (Reg(tmpreg,DInt)));
                                      ic#addInstr (JNE, (Reg(tmpreg,DInt)), Val(I(0)), endfor);
                                      (genCommand c dect proct ic);
                                      (genCommand (Ass(LVar(id),Sum(Var(id), N(1)))) dect proct ic);
                                      ic#addInstr (GOTO, startfor, NullNull);
                                      ic#addLabel endfor (ic#getIc);
                                     )
                                    )
    
    (** Here are generated the code for the list of parameters and then the code for the function call *)

    | PCall(Ide(id),plist)      ->  (
                                     (genParam plist dect proct ic);
                                     ic#addInstr (CALLSubr(id), NullNull);
                                    )