let rec genParam (plist: aexp list) (dect: dec_table) (proct: proc_table) (ic: intermediateCode): unit = match plist with
        []      ->  ()
      | a::ae   ->  genParam ae dect proct ic; ic#addInstr (PARAM, (genArithmetical a dect proct ic), NullNull)

(** Creates the instruction for the arithmetical expressions @param a The arithmetical expression to analize @param dect The declarations table @param proct The procedures table @param ic The intermediateCode class instance @return An element, which can be a Value, an Offset or a temporary register *)

and genArithmetical (a:aexp) (dect: dec_table) (proct: proc_table) (ic: intermediateCode): element = match a with
          N(n)              ->  Val(I(n))
    | R(n)              ->  Val(F(n))
        | Var(i)            ->  (
                             if(isVarDeclared i dect) then (
                                let (_,_,stackoff) = getVarDeclaration i dect in stackoff
                             ) else raise (NON_DECLARED_VARIABLE "ERROR: Undeclared variable\n")
                            )
    | Vec(i,x)          ->  (
                             if(isVarDeclared i dect) then (
                                let xRes = genArithmetical x dect proct ic and
                                v = ic#getReg and
                                (_, _, stackoff) = getVecDeclaration i 0 (-1) dect in (
                                    ic#addInstr (AGET, stackoff, xRes, (Reg(v,DInt)));
                                    (Reg(v,DInt))
                                )
                             ) else raise (NON_DECLARED_VARIABLE "ERROR: Undeclared variable\n")
                            )
    | Mat(i,x,y)        ->  (
                             if(isVarDeclared i dect) then (
                                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 (AGET, stackoff, (Reg(r2,DInt)), (Reg(r3,DInt)));
                                    (Reg(r3,DInt))
                                )
                             ) else raise (NON_DECLARED_VARIABLE "ERROR: Undeclared variable\n")
                            )
        | Sum(ex1,ex2)      ->  (
                             let reg = (ic#getReg) in (
                                ic#addInstr(ADD,(genArithmetical ex1 dect proct ic),(genArithmetical ex2 dect proct ic),(Reg(reg,DInt)));
                                (Reg(reg,DInt))
                             )
                            )
    | Sub(ex1,ex2)      ->  (
                             let reg = (ic#getReg) in (
                                ic#addInstr(SUB,(genArithmetical ex1 dect proct ic),(genArithmetical ex2 dect proct ic),(Reg(reg,DInt)));
                                (Reg(reg,DInt))

                             )
                            )
        | Mul(ex1,ex2)      ->  (
                             let reg = (ic#getReg) in (
                                ic#addInstr(MUL,(genArithmetical ex1 dect proct ic),(genArithmetical ex2 dect proct ic),(Reg(reg,DInt)));
                                (Reg(reg,DInt))
                             )
                            )
        | Div(ex1,ex2)      ->  (
                             let reg = (ic#getReg) in (
                                ic#addInstr(DIV,(genArithmetical ex1 dect proct ic),(genArithmetical ex2 dect proct ic),(Reg(reg,DInt)));
                                (Reg(reg,DInt))
                             )
                            )
    | FCall(Ide(i),plist)   ->  (
                                 let pten = (Hashtbl.find proct (Ide(i))) in match pten with
                                     Building(t, _)     ->  (
                                                                 let reg = (ic#getReg) in (
                                                                 (genParam plist dect proct ic);
                                                                 match t with 
                                                                    SRet(Int)   ->  ic#addInstr (CALLSubr(i), NullReg(reg,DInt));
                                                                                    Reg(reg,DInt)
                                                                  | SRet(Float->  ic#addInstr (CALLSubr(i), NullReg(reg,DFloat));
                                                                                    Reg(reg,DFloat)
                                                                  | Void        ->  raise (SEMANTIC_ERROR "Void function")
                                                                 )
                                                                )
                                   | Subroutine(t,_,_,_)    ->  (
                                                                 let reg = (ic#getReg) in (
                                                                 (genParam plist dect proct ic);
                                                                 match t with 
                                                                    SRet(Int)   ->  ic#addInstr (CALLSubr(i), NullReg(reg,DInt));
                                                                                    Reg(reg,DInt)
                                                                  | SRet(Float->  ic#addInstr (CALLSubr(i), NullReg(reg,DFloat));
                                                                                    Reg(reg,DFloat)
                                                                  | Void        ->  raise (SEMANTIC_ERROR "Void function")
                                                                 )
                                                                )
                                )