예제 #1
0
//Extractors
static T_exp unEx(Tr_exp e){
	Temp_temp r;
	Temp_label t,f;
	T_exp ex;

	switch(e->kind){
	case Tr_ex:
		ex = e->u.ex;
		break;
	case Tr_cx:
		r = Temp_newtemp();
		t = Temp_newlabel();
		f = Temp_newlabel();
		doPatch(e->u.cx.trues, t);
		doPatch(e->u.cx.falses, f);
		ex = T_Eseq(T_Move(T_Temp(r), T_Const(1)),
				T_Eseq(e->u.cx.stm,
					T_Eseq(T_Label(f),
						T_Eseq(T_Move(T_Temp(r), T_Const(0)),
							T_Eseq(T_Label(t),
								T_Temp(r)
							)
						)
					)
				)
			);
		break;
	case Tr_nx:
		ex = T_Eseq(e->u.nx, T_Const(0));
		break;
	}

	return ex;
}
예제 #2
0
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);
}
예제 #3
0
Tr_exp transDec_functionDec(Tr_level level, S_table venv, S_table tenv, A_dec d, Temp_label breakk) {
  for (A_fundecList fundecs = d->u.function; fundecs; fundecs = fundecs->tail) {
    S_symbol name = fundecs->head->name;
    Ty_tyList formals = makeFormalTyList(tenv, fundecs->head->params);

    for (A_fundecList f = d->u.function; f != fundecs; f = f->tail)
      if (f->head->name == name)
        EM_error(f->head->pos,
                 "there are two functions with the same name in the same batch "
                 "of mutually recursive functions");

    Ty_ty result = (fundecs->head->result)? S_look(tenv, fundecs->head->result) : Ty_Void();
    Temp_label label = Temp_newlabel();
    U_boolList escapeList = NULL;
    for (A_fieldList l = fundecs->head->params; l; l = l->tail)
      // todo: handle no escape
      escapeList = U_BoolList(TRUE, escapeList);

    S_enter(venv, name,
            E_FunEntry(Tr_newLevel(level, label, escapeList), label, formals,
                      result));
  }

  for (A_fundecList fundecs = d->u.function; fundecs; fundecs = fundecs->tail) {
    S_symbol name = fundecs->head->name;
    E_enventry x = S_look(venv, name);
    Ty_tyList formals = x->u.fun.formals;
    Ty_ty result = x->u.fun.result;
    Tr_level lev = x->u.fun.level;

    S_beginScope(venv);
    {
      A_fieldList l;
      Ty_tyList t;
      Tr_accessList a;
      for (l = fundecs->head->params, t = formals, a = Tr_formals(lev);
           l;
           l = l->tail, t = t->tail, a = a->tail)
        S_enter(venv, l->head->name, E_VarEntry(a->head, t->head));

      // check return type
      struct expty body = transExp(lev, venv, tenv, fundecs->head->body, breakk);
      if (!has_same_ty(result, body.ty)) {
        if (has_same_ty(result, Ty_Void()))
          EM_error(fundecs->head->pos, "procedure returns value '%s'",
                  type_msg(body.ty));
        else
          EM_error(fundecs->head->pos, "return type mismatched '%s' and '%s')",
                  type_msg(result), type_msg(body.ty));
      }
      Tr_procEntryExit(lev, body.exp, a);
    }
    S_endScope(venv);
  }
  return Tr_noExp();
}
예제 #4
0
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);
}
예제 #5
0
static T_stm unNx(Tr_exp e){
	Temp_label t,f;
	T_stm st;

	switch(e->kind){
	case Tr_ex:
		st = T_Exp(e->u.ex);
		break;
	case Tr_cx:
		t = Temp_newlabel();
		f = Temp_newlabel();
		doPatch(e->u.cx.trues, t);
		doPatch(e->u.cx.falses, f);
		st = T_Seq(e->u.cx.stm, T_Seq(T_Label(t), T_Label(f)));
		break;
	case Tr_nx:
		st = e->u.nx;
		break;
	}
	return st;
}
예제 #6
0
struct expty transExp_whileExp(Tr_level level, S_table venv, S_table tenv, A_exp a, Temp_label breakk) {
  struct expty test = transExp(level, venv, tenv, a->u.whilee.test, breakk);
  struct expty body = transExp(level, venv, tenv, a->u.whilee.body, breakk);

  if (test.ty->kind != Ty_int)
    EM_error(a->u.whilee.test->pos, "expected unqualified-id");
  if (body.ty->kind != Ty_void)
    EM_error(a->u.whilee.test->pos, "body of while not unit");

  Temp_label newbreak = Temp_newlabel();

  return expTy(Tr_whileExp(test.exp, body.exp, newbreak), Ty_Void());
}
예제 #7
0
Tr_exp Tr_stringExp(string str_val){
	Temp_label tl = Temp_newlabel();
	F_String(tl, str_val);
	return Tr_Ex(T_Name(tl));
}
예제 #8
0
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;
}
예제 #9
0
void Tr_genLoopDoneLabel(){
	//Put a new label into the label list
	Temp_label f = Temp_newlabel();
	LL_push(f);
debug("new loop done label generated");
}
예제 #10
0
파일: translate.c 프로젝트: JackWyj/Tiger
Tr_level Tr_outermost(void) {
	if (!outer) outer = Tr_newLevel(NULL, Temp_newlabel(), NULL);
	return outer;
}