//Refer to FIGURE 7.4 (P168) //struct {T_stm left, right;} SEQ; T_stm_ //struct {T_stm stm; T_exp exp;} ESEQ; T_exp_ void Tr_recordExp_app(Tr_exp te, Tr_exp init, bool last){ debug("Tr_recordExp_app %s", last==TRUE?"(LAST)":""); //1) Retrieve T_stm, which should be an ESEQ T_exp ex = unEx(te); //2) Prepare for iteration //The first sub-node for field initialization T_stm* right = &(ex->u.ESEQ.stm->u.SEQ.right); //The register saving the base addr of record var T_exp temp = ex->u.ESEQ.exp; //3) Iterate over the SEQs, until the rightmost node is found, which should be NULL int i = 0; while(*right!=NULL){ right = &((*right)->u.SEQ.right); i++; } //4) Create a new sub-node to initialize the next field T_stm move = T_Move(T_Mem(T_Binop(T_plus, temp, T_Const(i*F_wordSize))), unEx(init)); //5) Substitue the rightmode node if(!last){ *right = T_Seq(move, NULL); } else { *right = move; } }
T_exp F_Exp(F_access access, T_exp framePtr) { if (access->kind == inFrame) { return T_Mem(T_Binop(T_plus, framePtr, T_Const(access->u.offset))); } else { return T_Temp(access->u.reg); } }
Tr_exp Tr_nilExp(){ if(Tr_NIL==NULL){ Tr_NIL = Tr_Ex(T_Mem(T_Const(0))); } return Tr_NIL; }
Tr_exp Tr_arrayVar(Tr_exp base, Tr_exp offset_exp){ return Tr_Ex(T_Mem(T_Binop(T_plus, unEx(base), T_Binop(T_mul, unEx(offset_exp), T_Const(F_wordSize))))); }
Tr_exp Tr_fieldVar(Tr_exp base, int field_offset){ return Tr_Ex(T_Mem(T_Binop(T_plus, unEx(base), T_Const(field_offset * F_wordSize)))); }
T_exp F_Exp(F_access acc, T_exp framePtr) { if (acc->kind == inFrame) return T_Mem(T_Binop(T_plus, T_Const(acc->u.offset), framePtr)); else return T_Temp(acc->u.reg); }