Tr_exp Tr_seqExp(Tr_exp* array, int size){ T_exp _pex = (T_exp)checked_malloc(sizeof(struct T_exp_)); T_exp *pex = &_pex;//Always point to the rightmost node in the tree during the spanning T_exp ex_head; int i = 0; int last = size - 1; while(i<size){ Tr_printTrExp(array[i]); if(i!=last){ //Not the last one: substitute the rightmost node by T_Eseq (stm-exp pair), //where stm is the Tr_exp *pex = T_Eseq(unNx(array[i]), NULL); } else { //Last one: substitute the rightmost node by Tr_exp itself *pex = unEx(array[i]); } //In case of first node, remember it if(i==0){ ex_head = *pex; } //Not the last one: let pex point to the rightmost node again if(i!=last){ pex = &((*pex)->u.ESEQ.exp); } i++; } //debug("Tr_seqExp done"); return Tr_Ex(ex_head); }
Tr_exp Tr_forExp(Tr_exp var, Tr_exp low, Tr_exp high, Tr_exp body){ debug("Tr_forExp"); T_stm st; T_exp v = unEx(var); 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(); T_stm cond = T_Cjump(T_le, v, unEx(high), t, f); /* T_Move var <- low T_Label start T_CJump var <= high, t, f T_Label(t) body T_Move var + 1 T_Jump start T_Label(f) */ st = T_Seq(T_Move(v, unEx(low)), T_Seq(T_Label(start), T_Seq(cond, T_Seq(T_Label(t), T_Seq(unNx(body), T_Seq(T_Move(v, T_Binop(T_plus, v, T_Const(1))), 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_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; }
void Tr_printTree(Tr_exp exp){ printStmList(stdout, T_StmList(unNx(exp), NULL)); }
//@@@ 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); }
T_stm public_unNx(Tr_exp e) { return unNx(e); }