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), Null, Null)
(** 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 (CALL, Subr(i), Null, Reg(reg,DInt));
Reg(reg,DInt)
| SRet(Float) -> ic#addInstr (CALL, Subr(i), Null, Reg(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 (CALL, Subr(i), Null, Reg(reg,DInt));
Reg(reg,DInt)
| SRet(Float) -> ic#addInstr (CALL, Subr(i), Null, Reg(reg,DFloat));
Reg(reg,DFloat)
| Void -> raise (SEMANTIC_ERROR "Void function")
)
)
)