示例#1
0
/* exp op exp, rules:
 * 1. +,-,*,/ only apply to integer operands
 * 2. =,<>,>,<,>=,<= apply to:
 *  integers
 *  record or array of the same type: compare pointers
 *  strings: compare contents
 */
struct expty transOpExp(S_table venv, S_table tenv, A_exp e)
{
  struct expty left = transExp(venv, tenv, e->u.op.left);
  struct expty right = transExp(venv, tenv, e->u.op.right);

  switch (e->u.op.oper) {
    case A_plusOp:
    case A_minusOp:
    case A_timesOp:
    case A_divideOp:
      if (left.ty->kind != Ty_int) {
        EM_error(e->u.op.left->pos, "integer required");
      }
      if (right.ty->kind != Ty_int) {
        EM_error(e->u.op.right->pos, "integer required");
      }
      return ExpTy(NULL, Ty_Int());

    case A_eqOp:
    case A_neqOp:
    case A_ltOp:
    case A_leOp:
    case A_gtOp:
    case A_geOp:
      if (!Ty_is_compatible(left.ty, right.ty)) {
        EM_error(e->pos, "operands type mismatch");
      }
      return ExpTy(NULL, Ty_Int());
  }

  assert(0);
}
示例#2
0
// evaluate the exp list from left to right, use the last
// exp's result as the result of the whole list
struct expty transSeqExp(S_table venv, S_table tenv, A_expList el)
{
  while (el->tail) {
    transExp(venv, tenv, el->head);
    el = el->tail;
  }

  return transExp(venv, tenv, el->head);
}
示例#3
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());
}
示例#4
0
/* while exp1 do exp2
 * 1. exp1's type is integer
 * 2. exp2 produces no value
 */
struct expty transWhileExp(S_table venv, S_table tenv, A_exp e)
{
  struct expty test = transExp(venv, tenv, e->u.whilee.test);
  struct expty body = transExp(venv, tenv, e->u.whilee.body);
  if (test.ty != Ty_Int()) {
    EM_error(e->pos, "test type of while is not integer");
  }

  if (body.ty != Ty_Void()) {
    EM_error(e->pos, "body's type of while must be void");
  }

  return ExpTy(NULL, Ty_Void());
}
示例#5
0
struct expty transExp_seqExp(Tr_level level, S_table venv, S_table tenv, A_exp a, Temp_label breakk) {
  A_expList seq = a->u.seq;
  if (!seq || !seq->head) return expTy(Tr_noExp(), Ty_Void());

  Tr_expList head = Tr_ExpList(NULL, NULL), p = head;
  for (; seq && seq->tail; seq = seq->tail) {
    struct expty s = transExp(level, venv, tenv, seq->head, breakk);
    p->tail = Tr_ExpList(s.exp, NULL);
    p = p->tail;
  }
  struct expty last = transExp(level, venv, tenv, seq->head, breakk);
  head->head = last.exp;
  
  return expTy(Tr_eseqExp(head), last.ty);
}
示例#6
0
void SEM_transProg(A_exp exp) {
  S_table tenv = E_base_tenv();
  S_table venv = E_base_venv();
  Tr_level level = Tr_outermost();
  struct expty et = transExp(level, venv, tenv, exp, NULL);
  Tr_printTree(et.exp);
}
示例#7
0
struct expty transExp_recordExp(Tr_level level, S_table venv, S_table tenv, A_exp a, Temp_label breakk) {
  Ty_ty typ = actual_ty(S_look(tenv, a->u.record.typ));
  A_pos pos = a->pos;

  // check record type
  if (!typ || typ->kind != Ty_record) {
    EM_error(pos, "record type '%s' mismatched", S_name(a->u.record.typ));
    return expTy(NULL, Ty_Void());
  }

  // check exp field type
  A_efieldList efields = a->u.record.fields;
  Ty_fieldList fields = typ->u.record;
  Tr_expList expl_h = Tr_ExpList(NULL, NULL), expl_p = expl_h;
  int size = 0;
  while (efields && fields) {
    struct expty efield = transExp(level, venv, tenv, efields->head->exp, breakk);
    pos = efields->head->exp->pos;
    if (!has_same_ty(fields->head->ty, efield.ty)) {
      EM_error(pos, "record field type mismatched: '%s' and '%s'",
               type_msg(fields->head->ty), type_msg(efield.ty));
      break;
    }
    efields = efields->tail;
    fields = fields->tail;
    expl_p->tail = Tr_ExpList(efield.exp, NULL);
    expl_p = expl_p->tail;
    size += 1;
  }
  if (efields || fields) EM_error(pos, "record type mismatched");

  expl_p = expl_h->tail;
  free(expl_h);
  return expTy(Tr_recordExp(expl_p, size), S_look(tenv, a->u.record.typ));
}
示例#8
0
文件: semant.c 项目: Shenjiaqi/tiger
//check function call exp
static struct expty transExpCall( S_table venv, S_table tenv, A_exp e)
{
  //make sure e is funcall, just in case
  assertKind( e->pos, e->kind, A_callExp , "function call" );

  //find function type in tenv
  E_entry funentry = (E_entry)S_look( venv, e->u.call.func );
  //may be not a function name or can't find at all
  if( funentry == NULL)
    EM_error( e->pos , S_name( e->u.call.func ) , "not defined" );
  if( funentry->kind != E_funEntry )
    EM_error( e->pos , S_name( e->u.call.func ) , "is not function name" );
  //traverse all arguments 
  Ty_tyList params = funentry->fun.formalTys;
  A_expList args = e->u.call.args;
  for( ; args!=NULL && params!=NULL ; 
       args = args->tail, params = params->tail )
    {
      Ty_ty param = params->head;
      //evaluate argument exp first
      A_exp arg = args->head;
      struct expty exp = transExp( venv, tenv, arg );
      assertKind( arg->pos, exp.ty->kind , param->kind ,
		  tyKindName(param->kind) );
    }
  //if argument number satisfy argument list in function
  if( args != NULL )
    EM_error( e->pos, "Too much arguments" );
  else if( params != NULL )
    EM_error( e->pos, "Expect more arguments" );
  return _expTy( NULL, funentry->fun.resultTy );
}
示例#9
0
文件: parse.c 项目: java66liu/mytiger
int main(int argc, char **argv) {
 if (argc!=2) {fprintf(stderr,"usage: a.out filename\n"); exit(1);}
	S_table tenv = E_base_tenv();
	S_table venv = E_base_venv();
 transExp(venv, tenv, parse(argv[1]));
 return 0;
}
示例#10
0
void SEM_transProg(A_exp exp){
	struct expty et;
	S_table t = E_base_tenv();
	S_table v = E_base_venv();
	et = transExp(Tr_outermost(), v, t, exp);
	printf("this exp return: %d\n", et.ty->kind); /* check the return result (use Ty_ty->kind stand) */
}
示例#11
0
/* type-id { id = exp {, id = exp}} or type-id {}
 * the field names and types of the record exp must match
 * those of the named type, in the order given
 */
struct expty transRecordExp(S_table venv, S_table tenv, A_exp e)
{
  Ty_ty recordType = S_look(tenv, e->u.record.typ);
  if (!recordType) {
    EM_error(e->pos, "undefined record type %s",
        S_name(e->u.record.typ));
    return ExpTy(NULL, NULL);
  }

  A_efieldList efl = e->u.record.fields;
  Ty_fieldList tfl = recordType->u.record;

  while (efl && tfl) {
    if (efl->head->name != tfl->head->name) {
      EM_error(e->pos, "field name error %s", S_name(efl->head->name));
    }
    if (transExp(venv, tenv, efl->head->exp).ty != tfl->head->ty) {
      EM_error(e->pos, "field type error %s", S_name(efl->head->name));
    }

    efl = efl->tail;
    tfl = tfl->tail;
  }
  return ExpTy(NULL, recordType);
}
示例#12
0
struct expty transExp_opExp(Tr_level level, S_table venv, S_table tenv, A_exp a, Temp_label breakk) {
  A_oper oper = a->u.op.oper;
  struct expty left =  transExp(level, venv, tenv, a->u.op.left , breakk);
  struct expty right = transExp(level, venv, tenv, a->u.op.right, breakk);

  if (oper == A_plusOp || oper == A_minusOp || oper == A_timesOp ||
      oper == A_divideOp || oper == A_ltOp || oper == A_leOp ||
      oper == A_gtOp || oper == A_geOp) {
    if (left.ty->kind != Ty_int)
      EM_error(a->u.op.left->pos, "operate of incompatible types");
    if (right.ty->kind != Ty_int)
      EM_error(a->u.op.right->pos, "operate of incompatible types");
  }

  if (oper == A_eqOp || oper == A_neqOp) {
    if (left.ty->kind != right.ty->kind &&
        !(left.ty->kind == Ty_nil && right.ty->kind == Ty_record) &&
        !(left.ty->kind == Ty_record && right.ty->kind == Ty_nil))
      EM_error(a->u.op.right->pos, "same type required");
  }

  Tr_exp op_exp;

  switch (oper) {
    case A_plusOp:    op_exp = Tr_addOpExp(   left.exp, right.exp); break;
    case A_minusOp:   op_exp = Tr_minusOpExp( left.exp, right.exp); break;
    case A_timesOp:   op_exp = Tr_timesOpExp( left.exp, right.exp); break;
    case A_divideOp:  op_exp = Tr_divideOpExp(left.exp, right.exp); break;
    case A_ltOp:      op_exp = Tr_ltOpExp(    left.exp, right.exp); break;
    case A_leOp:      op_exp = Tr_leOpExp(    left.exp, right.exp); break;
    case A_gtOp:      op_exp = Tr_gtOpExp(    left.exp, right.exp); break;
    case A_geOp:      op_exp = Tr_geOpExp(    left.exp, right.exp); break;
    case A_eqOp:
      if (left.ty->kind == Ty_string)
                      op_exp = Tr_stringEqExp(left.exp, right.exp);
      else            op_exp = Tr_eqExp(      left.exp, right.exp);break;
    case A_neqOp:
      if (left.ty->kind == Ty_string)
                      op_exp = Tr_stringNeExp(left.exp, right.exp);
      else            op_exp = Tr_neqExp(     left.exp, right.exp); break;
  }
  

  return expTy(op_exp, Ty_Int());
}
示例#13
0
文件: semant.c 项目: JackWyj/Tiger
static struct expty transVar(Tr_level level, Tr_exp breakk, S_table venv, S_table tenv, A_var v) {
	if (!v) {return expTy(Tr_noExp(), Ty_Void());}
    /*!those several var is ugly*/
	E_enventry x;
	struct expty et,et2;
	Ty_fieldList fl;
	Tr_exp trans;

	switch (v->kind) {
	case A_simpleVar:/* var id (a)*/
		x = S_look(venv, v->u.simple); 
		trans = Tr_noExp();
		if (x && x->kind == E_varEntry) {
			trans = Tr_simpleVar(x->u.var.access, level);
			return expTy(trans, actual_ty(x->u.var.ty));
		} else {
			EM_error(v->pos, "undefined var %s", S_name(v->u.simple));
			return expTy(trans, Ty_Int());
		}
		break;
	case A_fieldVar:/* var record (a.b)*/
		et = transVar(level, breakk, venv, tenv, v->u.field.var);
		trans = Tr_noExp();
		if (et.ty->kind != Ty_record) {
			EM_error(v->pos, "not a record type");
		} else {
			int i = 0;
			for (fl = et.ty->u.record; fl; fl = fl->tail, i++) { /*fl is Ty_fieldList*/
				if (fl->head->name == v->u.field.sym) {
					trans = Tr_fieldVar(et.exp, i);
					return expTy(trans, actual_ty(fl->head->ty));
				}
			}
			EM_error(v->pos, "no such field in record %s", S_name(v->u.field.sym));
		}
		return expTy(trans, Ty_Int());
		break;
	case A_subscriptVar: /*var array (a[b])*/ 
		et  = transVar(level, breakk, venv, tenv, v->u.subscript.var);
		trans = Tr_noExp();
		if (et.ty->kind != Ty_array) {
			EM_error(v->pos, "not a array type");
		} else {
			et2 = transExp(level, breakk, venv, tenv, v->u.subscript.exp);
			if (et2.ty->kind != Ty_int) {
				EM_error(v->pos, "int required");
			} else {
				trans = Tr_subscriptVar(et.exp, et2.exp);
				return expTy(trans, actual_ty(et.ty->u.array));
			}
		}
		return expTy(trans, Ty_Int());
	default:
		assert(0);
	}
}
示例#14
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();
}
示例#15
0
/* lvalue := exp
 * evaluates lvalue, then exp; set the contents of the lvalue
 * to the result of exp; check that the types of lvalue and
 * the exp are the same, but the whole assignment exp produce
 * no value, so (a := b) + c is illegal
 */
struct expty transAssignExp(S_table venv, S_table tenv, A_exp e)
{
  struct expty lv = transVar(venv, tenv, e->u.assign.var);
  struct expty exp = transExp(venv, tenv, e->u.assign.exp);
  if (!Ty_is_compatible(lv.ty, exp.ty)) {
    EM_error(e->pos, "assignment types mismatch");
  }

  return ExpTy(NULL, Ty_Void());
}
示例#16
0
文件: semant.c 项目: 0XCC1/tiger
F_fragList SEM_transProg(A_exp exp){
	struct expty et;

	S_table t = E_base_tenv();
	S_table v = E_base_venv();
	et = transExp(Tr_outermost(),NULL,v, t, exp);
	printf("@this expr return:\n"); /* check the return result (use Ty_ty->kind stand) */
	F_fragList resl = Tr_getResult();
	return resl;
}
示例#17
0
/* type-id[exp1] of exp2
 * 1. type-id is array
 * 2. exp1 is integer
 */
struct expty transArrayExp(S_table venv, S_table tenv, A_exp e)
{
  struct expty size = transExp(venv, tenv, e->u.array.size);
  struct expty init = transExp(venv, tenv, e->u.array.init);
  Ty_ty typ = S_look(tenv, e->u.array.typ);

  if (size.ty != Ty_Int()) {
    EM_error(e->pos, "type of array size is not integer");
  }

  if (typ->kind != Ty_array) {
    EM_error(e->pos, "%s is not a array", S_name(e->u.array.typ));
  }

  if (init.ty != typ->u.array) {
    EM_error(e->pos, "type of element of array mismatch");
  }

  return ExpTy(NULL, typ);
}
示例#18
0
struct expty transExp_assignExp(Tr_level level, S_table venv, S_table tenv, A_exp a, Temp_label breakk) {
  struct expty lvar = transVar(level, venv, tenv, a->u.assign.var, breakk);
  struct expty rvar = transExp(level, venv, tenv, a->u.assign.exp, breakk);

  if (!has_same_ty(lvar.ty, rvar.ty))
    EM_error(
        a->u.assign.exp->pos,
        "cannot initialize a variable of type '%s' with an rvalue of type '%s'",
        type_msg(lvar.ty), type_msg(rvar.ty));

  return expTy(Tr_assignExp(lvar.exp, rvar.exp), Ty_Void());
}
示例#19
0
struct expty transExp_arrayExp(Tr_level level, S_table venv, S_table tenv, A_exp a, Temp_label breakk) {
  Ty_ty typ = actual_ty(S_look(tenv, a->u.array.typ));
  struct expty size = transExp(level, venv, tenv, a->u.array.size, breakk);
  struct expty init = transExp(level, venv, tenv, a->u.array.init, breakk);

  if (!typ || typ->kind != Ty_array) {
    EM_error(a->pos, "array type '%s' mismatched", S_name(a->u.array.typ));
    return expTy(NULL, Ty_Void());
  }

  if (size.ty->kind != Ty_int)
    EM_error(a->u.array.size->pos, "integer type required");

  if (!has_same_ty(init.ty, typ->u.array))
    EM_error(
        a->u.array.init->pos,
        "cannot initialize a variable of type '%s' with an rvalue of type '%s'",
        type_msg(typ), type_msg(init.ty));

  return expTy(Tr_arrayExp(size.exp, init.exp), S_look(tenv, a->u.array.typ));
}
示例#20
0
/* if exp1 then exp2 [else exp3]
 * 1. exp1 is integer type
 * 2. exp2 and exp3 are the same type if exp3 exists
 * 3. exp2 produce no value if exp3 does not exists
 */
struct expty transIfExp(S_table venv, S_table tenv, A_exp e)
{
  struct expty test = transExp(venv, tenv, e->u.iff.test);
  struct expty then = transExp(venv, tenv, e->u.iff.then);

  if (test.ty != Ty_Int()) {
    EM_error(e->pos, "test exp of if is not integer");
  }

  if (e->u.iff.elsee) {
    struct expty elsee = transExp(venv, tenv, e->u.iff.elsee);
    if (!Ty_is_compatible(then.ty, elsee.ty)) {
      EM_error(e->pos, "then and elsee type of if mismatch");
    }
    return ExpTy(NULL, elsee.ty);
  } else {
    if (then.ty != Ty_Void()) {
      EM_error(e->pos, "then type of if is NOT void");
    }
    return ExpTy(NULL, Ty_Void());
  }
}
示例#21
0
/* for id := exp1 to exp2 do exp3
 * 1. both exp1 and exp2 are integer type
 * 2. exp3 is void type
 * 3. id is a new variable implicitly declared by the for 
 * statement, whose scope covers only exp3
 */
struct expty transForExp(S_table venv, S_table tenv, A_exp e)
{
  struct expty lo = transExp(venv, tenv, e->u.forr.lo);
  struct expty hi = transExp(venv, tenv, e->u.forr.hi);
  struct expty body;

  if (lo.ty != Ty_Int() || hi.ty != Ty_Int()) {
    EM_error(e->pos, "low or high range type is not integer");
  }

  S_beginScope(venv);
  transDec(venv, tenv, 
      A_VarDec(e->pos,
        e->u.forr.var,
        S_Symbol("int"),
        e->u.forr.lo));
  body = transExp(venv, tenv, e->u.forr.body);
  if (body.ty != Ty_Void()) {
    EM_error(e->pos, "body of for is not void");
  }
  S_endScope(venv);
  return ExpTy(NULL, Ty_Void());
}
示例#22
0
struct expty transExp_ifExp(Tr_level level, S_table venv, S_table tenv, A_exp a, Temp_label breakk) {
  struct expty test = transExp(level, venv, tenv, a->u.iff.test, breakk);
  struct expty then = transExp(level, venv, tenv, a->u.iff.then, breakk);

  if (test.ty->kind != Ty_int)
    EM_error(a->u.iff.test->pos, "integer type required");

  if (a->u.iff.elsee) {
    struct expty elsee = transExp(level, venv, tenv, a->u.iff.elsee, breakk);
    if (!has_same_ty(then.ty, elsee.ty))
      EM_error(a->u.iff.elsee->pos, "types of then - else differ ('%s' and '%s')",
               type_msg(then.ty), type_msg(elsee.ty));
    if (then.ty == Ty_Void())
       return expTy(Tr_ifExp_noValue(test.exp, then.exp, elsee.exp), Ty_Void());
    return expTy(Tr_ifExp(test.exp, then.exp, elsee.exp), then.ty);
  }

  if (then.ty->kind != Ty_void)
    EM_error(a->u.iff.then->pos, "if-then returns non unit");

  return expTy(Tr_ifExp_noValue(test.exp, then.exp, NULL), then.ty);
  return expTy(NULL, Ty_Void());
}
示例#23
0
struct expty transVar(S_table venv, S_table tenv, A_var v) {
	switch (v->kind) {
		case A_simpleVar: {
			E_enventry x = S_look(venv, v->u.simple);
			if (x && x->kind == E_varEntry)
				return expTy(NULL, actual_ty(x->u.var.ty));
			else {
				//EM_error(v->pos, "undefined variable %s", S_name(v->u.simple));
				return expTy(NULL, Ty_Int());
			}
		}
		case A_fieldVar: {
			struct expty res = transVar(venv, tenv, v->u.field.var);
			Ty_ty ty = res.ty;
			if (ty->kind == Ty_record) {
				Ty_fieldList fieldList = ty->u.record;
				while (fieldList != NULL) {
					if (fieldList->head->name == v->u.field.sym) {
						return expTy(NULL, actual_ty(fieldList->head->ty));
					}
					else {
						fieldList = fieldList->tail;
					}
				}
				//EM_error(v->pos, "undefined field %s", S_name(v->u.field.sym));
				return expTy(NULL, Ty_Int());
			}
			else {
				//EM_error(v->pos, "undefined field %s", S_name(v->u.field.sym));
				return expTy(NULL, Ty_Int());
			}
		}
		case A_subscriptVar: {
			struct expty res = transVar(venv, tenv, v->u.subscript.var);
			struct expty index = transExp(venv, tenv, v->u.subscript.exp);
			Ty_ty ty = res.ty;
			if (ty->kind == Ty_array && index.ty->kind == Ty_int) {
				return expTy(NULL, actual_ty(ty->u.array));
			}
			else {
				EM_error(v->pos, "array index error");
				return expTy(NULL, Ty_Int());
			}
		}
		default: {
			assert(0);
		}
	}
}
示例#24
0
void transDec(S_table venv, S_table tenv, A_dec d) {
	if(d == NULL) {
		return;
	}
	switch(d->kind) {
	case A_varDec: {
		struct expty e = transExp(venv, tenv, d->u.var.init);
		S_enter(venv, d->u.var.var, E_VarEntry(e.ty));
		break;
	}
	case A_typeDec: {
		S_enter(venv, d->u.type->head->name, transTy(tenv, d->u.type->head->ty));
		break;
	}
	case A_functionDec: {
		A_fundec f = d->u.function->head;
		Ty_ty resultTy = S_look(tenv, f->result);
		Ty_tyList formalTys = makeFormalTyList(tenv, f->params);
		S_enter(venv,  f->name, E_FunEntry(formalTys, resultTy));
		S_beginScope(venv);
		{
			A_fieldList l;
			Ty_tyList t;
			for (l = f->params, t = formalTys; l; l = l->tail, t = t->tail) {
				S_enter(venv, l->head->name, E_VarEntry(t->head));
			}
		}
		transExp(venv, tenv, d->u.function->head->body);
		S_endScope(venv);
		break;
	}
	default: {
		assert(0);
			 }
	}
}
示例#25
0
struct expty transExp_forExp(Tr_level level, S_table venv, S_table tenv, A_exp a, Temp_label breakk) {
  struct expty lo = transExp(level, venv, tenv, a->u.forr.lo, breakk);
  struct expty hi = transExp(level, venv, tenv, a->u.forr.hi, breakk);

  if (lo.ty->kind != Ty_int || hi.ty->kind != Ty_int)
    EM_error(a->u.forr.lo->pos, "lo or hi expr is not int");

  /*
   * LET VAR i := lo
   *     VAR lmt := hi
   * IN
   *    IF lo < hi THEN
   *      WHILE i <= lmt DO
   *        (body;
   *         i := i+1)
   */
  A_pos pos1 = a->pos;
  A_pos pos2 = a->u.forr.body->pos;
  S_symbol var = a->u.forr.var;
  S_symbol lmt = S_Symbol("limit");
  A_exp ebody = a->u.forr.body;
  A_exp transformed = A_LetExp(pos1,
      A_DecList(A_VarDec(pos1, var, S_Symbol("int"), a->u.forr.lo),
      A_DecList(A_VarDec(pos1, lmt, S_Symbol("int"), a->u.forr.hi), NULL)),
          A_IfExp(pos1,
              A_OpExp(pos1, A_ltOp, a->u.forr.lo, a->u.forr.hi),
              A_WhileExp(pos1,
                  A_OpExp(pos1, A_leOp, A_VarExp(pos1, A_SimpleVar(pos1, var)), A_VarExp(pos1, A_SimpleVar(pos1, lmt))),
                  A_SeqExp(pos2, A_ExpList(ebody, 
                                 A_ExpList(A_OpExp(pos1, A_plusOp, A_VarExp(pos1, A_SimpleVar(pos1, var)), A_IntExp(pos1, 1)),
                                 A_ExpList(A_SeqExp(pos2, NULL), // return no value
                                 NULL))))),
              NULL)
  );
  return transExp(level, venv, tenv, transformed, breakk);
}
示例#26
0
struct expty transExp_letExp(Tr_level level, S_table venv, S_table tenv, A_exp a, Temp_label breakk) {
  S_beginScope(venv);
  S_beginScope(tenv);
  Tr_expList h = Tr_ExpList(NULL, NULL), p = h;
  for (A_decList d = a->u.let.decs; d; d = d->tail) {
    p->tail = Tr_ExpList(transDec(level, venv, tenv, d->head, breakk), NULL);
    p = p->tail;
  }
  p = h->tail;
  free(h);
  struct expty body = transExp(level, venv, tenv, a->u.let.body, breakk);
  S_endScope(venv);
  S_endScope(tenv);

  return expTy(Tr_LetExp(p, body.exp), body.ty);
}
示例#27
0
static struct expty transVar(Tr_level level, S_table venv, S_table tenv, A_var v) {
	E_enventry x;
	struct expty et,et2;
	Ty_fieldList fl;

	switch (v->kind) {
	case A_simpleVar:/* var id (a)*/
		x = S_look(venv, v->u.simple);
		if (x && x->kind == E_varEntry) {
			return expTy(NULL, actual_ty(x->u.var.ty));
		} else {
			EM_error(v->pos, "undefined var %s", S_name(v->u.simple));
			return expTy(NULL, Ty_Int());
		}
		break;
	case A_fieldVar:/* var record (a.b)*/
		et = transVar(level, venv, tenv, v->u.field.var);
		if (et.ty->kind != Ty_record) {
			EM_error(v->pos, "not a record type");
			return expTy(NULL, Ty_Record(NULL));
		} else {
			for (fl = et.ty->u.record; fl; fl = fl->tail) {
				if (fl->head->name == v->u.field.sym) {
					return expTy(NULL, actual_ty(fl->head->ty));
				}
			}
			EM_error(v->pos, "no such field in record %s", S_name(v->u.field.sym));
		}
		return expTy(NULL, Ty_Record(NULL));
		break;
	case A_subscriptVar:/*var array (a[b])*/ 
		et  = transVar(level, venv, tenv, v->u.subscript.var);
		if (et.ty->kind != Ty_array) {
			EM_error(v->pos, "not a array type");
		} else {
			et2 = transExp(level, venv, tenv, v->u.subscript.exp);
			if (et2.ty->kind != Ty_int) {
				EM_error(v->pos, "int required");
			} else {
				return expTy(NULL, actual_ty(et.ty->u.array));
			}
		}
		return expTy(NULL, Ty_Array(NULL));
	default:
		assert(0);
	}
}
示例#28
0
文件: semant.c 项目: JackWyj/Tiger
F_fragList SEM_transProg(A_exp exp){
	struct expty et;
	S_table t = E_base_tenv();
	S_table v = E_base_venv();
	//puts("@before trans:");
	et = transExp(Tr_outermost(), NULL, v, t, exp);
	//puts("@end trans, begin pr-main:");
	//if(!anyErrors) print(et.exp); else printf("@error cant pr");
	//puts("\n@end pr-main, begin ref:");
	//printf("this exp return: %d\n", et.ty->kind); 
	//puts("@end ref, begin pr-frag");
	//puts("@@@@@@@@@@@@@@@@@@@@@@@");
	F_fragList resl = Tr_getResult();
	//print_frag(resl);
	//puts("\n@end pr-falg");
	return resl;
}
示例#29
0
struct expty transVar (S_table venv, S_table tenv, A_var v)
{
  switch (v->kind) {
    case A_simpleVar: {
        E_enventry x = S_look (venv, v->u.simple);

        if (x && x->kind == E_varEntry) {
          return expTy (NULL, actual_ty (x->u.var.ty));
        } else {
          EM_error (v->pos, "undefined variable %s", S_name (v->u.simple));
          return expTy (NULL, Ty_Int());
        }
      }

    case A_fieldVar: {
        struct expty var = transVar (venv, tenv, v->u.field.var);

        Ty_fieldList fList = var.ty->u.record;

        while (fList && fList->head->name != v->u.field.sym) {
          fList = fList->tail;
        }

        if (!fList) {
          EM_error (v->pos, "undefined subName %s", S_name (v->u.field.sym));
          return expTy (NULL, Ty_Int());
        } else {
          return expTy (NULL, actual_ty (fList->head->ty));
        }
      }

    case A_subscriptVar: {
        struct expty var = transVar (venv, tenv, v->u.subscript.var);
        struct expty exp = transExp (venv, tenv, v->u.subscript.exp);

        if (exp.ty->kind != Ty_int) {
          EM_error (v->pos, "subscript should be int");
          return expTy (NULL, Ty_Int());
        } else {
          return expTy (NULL, actual_ty (var.ty->u.array));
        }
      }
  }

  assert (0);
}
示例#30
0
struct expty transVar(S_table venv, S_table tenv, A_var v) {
	switch (v->kind) {
		case A_simpleVar: {
			E_enventry x = S_look(venv, v->u.simple);
			if (x && x->kind == E_varEntry) {
				return expTy(NULL, actual_ty(x->u.var.ty));
			}
			EM_error(v->pos, (string)"undeclared variable '%s'", S_name(v->u.simple));
			return expTy(NULL, Ty_Int());
		}
		case A_fieldVar: {
			struct expty res = transVar(venv, tenv, v->u.field.var);
			Ty_ty ty = res.ty;
			if (ty->kind == Ty_record) {
				Ty_fieldList tfl = ty->u.record;
				for (tfl = ty->u.record; tfl; tfl = tfl->tail) {
					if (tfl->head->name == v->u.field.sym) {
						return expTy(NULL, actual_ty(tfl->head->ty));
					}
				}
				EM_error(v->pos, "field '%s' not in record type", S_name(v->u.field.sym));
				return expTy(NULL, Ty_Int());
			}
			EM_error(v->pos, "variable not record");
			return expTy(NULL, Ty_Int());
		}
		case A_subscriptVar: {
			struct expty res = transVar(venv, tenv, v->u.subscript.var);
			struct expty index = transExp(venv, tenv, v->u.subscript.exp);
			Ty_ty ty = res.ty;
			if (ty->kind != Ty_array) {
				EM_error(v->pos, "variable not array");
				return expTy(NULL, Ty_Int());
			}
			if (index.ty->kind != Ty_int) {
				EM_error(v->pos, "array index error");
				return expTy(NULL, Ty_Int());
			}
			return expTy(NULL, actual_ty(ty->u.array));
		}
		default: {
			assert(0);
		}
	}
}