Tr_exp Tr_whileExp(Tr_exp cond, Tr_exp body){ debug("Tr_whileExp"); T_stm st; struct Cx cx_cond = unCx(cond); Temp_label t = Temp_newlabel(); Temp_label f = LL_peek();//Get done label from the list, which should have been prepared before this function is called. Temp_label start = Temp_newlabel(); doPatch(cx_cond.trues, t); doPatch(cx_cond.falses, f); /* T_Label start cx_cond.stm (true->t, false->f) T_Label(t) body T_Jump start T_Label(f) */ st = T_Seq(T_Label(start), T_Seq(cx_cond.stm, T_Seq(T_Label(t), T_Seq(unNx(body), T_Seq( T_Jump( T_Name(start), Temp_LabelList(start, NULL) ), T_Label(f) ) ) ) ) ); //Pop the label as it's no longer used LL_pop(); return Tr_Nx(st); }
Tr_exp Tr_ifExp(Tr_exp cond, Tr_exp thenb, Tr_exp elseb){ T_exp ex; T_stm st; Tr_exp ret; struct Cx cx_cond = unCx(cond); Temp_label t = Temp_newlabel(); Temp_label f = Temp_newlabel(); Temp_label join = Temp_newlabel(); doPatch(cx_cond.trues, t); doPatch(cx_cond.falses, f); if(elseb==NULL){ //case 1: if-then debug("Tr_ifExp: if-then"); st = T_Seq(cx_cond.stm, T_Seq(T_Label(t), T_Seq(unNx(thenb), T_Label(f) ) ) ); ret = Tr_Nx(st); } else { //case 2: if-then-else if(thenb->kind==Tr_nx && elseb->kind==Tr_nx){ debug("Tr_ifExp: if-then-else (2 nx)"); //special case: two statements st = T_Seq(cx_cond.stm, T_Seq(T_Label(t), T_Seq(unNx(thenb), T_Seq( T_Jump( T_Name(join), Temp_LabelList(join, NULL) ), T_Seq(T_Label(f), T_Seq(unNx(elseb), T_Label(join) ) ) ) ) ) ); ret = Tr_Nx(st); //TODO: special case - two cx. } else { debug("Tr_ifExp: if-then-else"); Temp_temp r = Temp_newtemp(); ex = T_Eseq(cx_cond.stm, T_Eseq(T_Label(t), T_Eseq(T_Move(T_Temp(r), unEx(thenb)), T_Eseq( T_Jump( T_Name(join), Temp_LabelList(join, NULL) ), T_Eseq(T_Label(f), T_Eseq(T_Move(T_Temp(r), unEx(elseb)), T_Eseq(T_Label(join), T_Temp(r) ) ) ) ) ) ) ); ret = Tr_Ex(ex); } } return ret; }
//@@@ print Tr_exp void print(Tr_exp et, FILE * out) { if (et->kind == Tr_ex) printExp(unEx(et), out); if (et->kind == Tr_nx) printStm(unNx(et), out); if (et->kind == Tr_cx) printStm(unCx(et).stm, out); }
Cx::unEx() { Temp *tmp = gcnew(Temp, ()); tree::TEMP *r = _TEMP(tmp); tree::CONST *const_1 = _CONST(1); tree::CONST *const_0 = _CONST(0); tree::MOVE *r_1 = _MOVE(r, const_1); tree::MOVE *r_0 = _MOVE(r, const_0); Label *t = gcnew(Label, ()); Label *f = gcnew(Label, ()); tree::LABEL *l_T = _LABEL(t); tree::LABEL *l_F = _LABEL(f); tree::Stm *cmp = unCx(t, f); tree::SEQMaker sm; sm.add(r_1); sm.add(cmp); sm.add(l_F); sm.add(r_0); sm.add(l_T); tree::SEQ *seq = sm.make();//tree::makeSEQ(r_1, cmp, l_F, r_0, l_T); tree::ESEQ *eseq = _ESEQ(seq, r); return eseq; } tree::Stm * Cx::unNx() {