Esempio n. 1
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));
}
Esempio n. 2
0
Tr_exp transDec_typeDec(Tr_level level, S_table venv, S_table tenv, A_dec d, Temp_label breakk) {
  for (A_nametyList decs = d->u.type; decs; decs = decs->tail) {
    S_symbol name = decs->head->name;

    for (A_nametyList ds = d->u.type; ds != decs; ds = ds->tail)
      if (ds->head->name == name)
        EM_error(d->pos,
                 "there are two types with the same name in the same batch of "
                 "mutually recursive types");

    S_enter(tenv, name, Ty_Name(name, NULL));
  }
  for (A_nametyList decs = d->u.type; decs; decs = decs->tail) {
    Ty_ty type = S_look(tenv, decs->head->name);
    type->u.name.ty = transTy(level, tenv, decs->head->ty);
  }
  for (A_nametyList decs = d->u.type; decs; decs = decs->tail) {
    Ty_ty type = S_look(tenv, decs->head->name);
    if (type->u.name.sym == actual_ty(type)->u.name.sym) {
      EM_error(decs->head->ty->pos, "mutually recursive types declaration");
      type->u.name.ty = Ty_Int();
    }
  }
  return Tr_noExp();
}
Esempio n. 3
0
Ty_ty transTy (S_table tenv, A_ty a)
{
  switch (a->kind) {
    case A_nameTy: {
        return Ty_Name (a->u.name, S_look (tenv, a->u.name));
      }

    case A_recordTy: {
        Ty_fieldList fieldList = NULL;
        A_fieldList a_fieldList = NULL;

        for (a_fieldList = a->u.record; a_fieldList; a_fieldList = a_fieldList->tail) {
          S_symbol name = a_fieldList->head->name;
          S_symbol typ = a_fieldList->head->typ;
          //printf("%s  ", S_name (name));
          //printf("%s\n", S_name (typ));
          Ty_ty ty = S_look (tenv, typ);

          //S_enter(tenv, name, ty);
          fieldList = Ty_FieldList (Ty_Field (name, ty), fieldList);
        }

        return Ty_Record (fieldList);
      }

    case A_arrayTy: {
        return Ty_Array (S_look (tenv, a->u.array));
      }
  }

  assert (0);
}
Esempio n. 4
0
Ty_ty transTy(Tr_level level, S_table tenv, A_ty a) {
  switch (a->kind) {
    case A_nameTy: {
      return Ty_Name(a->u.name, S_look(tenv, a->u.name));
    }
    case A_recordTy: {
      Ty_fieldList h = Ty_FieldList(NULL, NULL), p = h, fields;
      for (A_fieldList efields = a->u.record; efields;
           efields = efields->tail) {
        Ty_ty typ = S_look(tenv, efields->head->typ);
        if (!typ) {
          EM_error(efields->head->pos, "type '%s' undefined",
                   S_name(efields->head->name));
          typ = Ty_Int();
        }
        p->tail = Ty_FieldList(Ty_Field(efields->head->name, typ), NULL);
        p = p->tail;
      }
      fields = h->tail;
      free(h);

      return Ty_Record(fields);
    }
    case A_arrayTy: {
      return Ty_Array(S_look(tenv, a->u.array));
    }
  }
}
Esempio n. 5
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();
}
Esempio n. 6
0
/* translate A_ty in AST to real type representation
 */
Ty_ty transTy(S_table tenv, S_symbol ty_name, A_ty t)
{
  switch(t->kind) {
    case A_nameTy: {
      Ty_ty ty = S_look(tenv, t->u.name);
      if (ty)
        return Ty_Name(ty);
      else
        return NULL;
    }
    case A_recordTy: {
      A_fieldList a_record = NULL;
      A_field a_field = NULL;
      Ty_fieldList t_record = NULL;
      Ty_fieldList saved_t_record = NULL;
      Ty_ty ty = NULL;

      /* we only allow record field type to refer itself or already defined
       * type: type record = { id : record, id : other_defined_type }
       */
      for (a_record = t->u.record; a_record; a_record = a_record->tail) {
        a_field = a_record->head;
        ty = S_look(tenv, a_field->typ);
        if (ty_name == a_field->typ || ty) {
          if (t_record) {
            t_record->tail = Ty_FieldList(Ty_Field(a_field->name, ty), NULL);
            t_record = t_record->tail;
          } else {
            t_record = Ty_FieldList(Ty_Field(a_field->name, ty), NULL);
            saved_t_record = t_record;
          }
        } else {
          EM_error(a_field->pos, "undefined type %s", S_name(a_field->typ));
          return NULL;
        }
      }
      
      // fill the record's self-recursive reference
      Ty_ty new_record = Ty_Record(saved_t_record);
      Ty_fieldList tfl = NULL;
      for (tfl = t_record; tfl; tfl = tfl->tail) {
        if (!tfl->head->ty) {
          tfl->head->ty = new_record;
        }
      }
      return new_record;
    }
    case A_arrayTy: {
      Ty_ty ty = S_look(tenv, t->u.array);
      if (ty)
        return Ty_Array(ty);
      else
        return NULL;
    }
  }
}
Esempio n. 7
0
Ty_ty transTy(S_table tenv, A_ty a) {
	assert(a != NULL);
	switch (a->kind) {
		case A_nameTy: {
			Ty_ty ty = S_look(tenv, a->u.name);
			if (ty != NULL) {
				return ty;
			}
			else {
				return Ty_Int();
			}
		}
		case A_recordTy: {
			if (!a->u.record) {
				return Ty_Record(NULL);
			}
			Ty_fieldList tfl, tfl_p;
			tfl = tfl_p = NULL;
			A_fieldList fl;
			for (fl = a->u.record; fl; fl = fl->tail) {
				Ty_ty ty = S_look(tenv, fl->head->typ);
				if (!ty) {
					EM_error(a->pos, "undefined field type");
					return Ty_Int();
				}
				if (tfl) {
					tfl_p->tail = Ty_FieldList(Ty_Field(fl->head->name, ty), NULL);
					tfl_p = tfl_p->tail;
				}
				else {
					tfl = Ty_FieldList(Ty_Field(fl->head->name, ty), NULL);
					tfl_p = tfl;
				}
			}
			return Ty_Record(tfl);
		}
		case A_arrayTy: {
			Ty_ty ty;
			ty = S_look(tenv, a->u.array);
			if (ty != NULL) {
				return Ty_Array(ty);
			}
			else {
				return Ty_Int();
			}
		}
		default: {
			assert(0);
		}
	}
}
Esempio n. 8
0
//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 );
}
Esempio n. 9
0
Ty_tyList makeFormalTyList(S_table tenv, A_fieldList params) {
	A_fieldList ptr = params;
	Ty_tyList ret, ptr2;
	Ty_ty ty;

	ret = NULL; ptr2 = NULL;
	while(ptr != NULL) {
		ty = S_look(tenv, ptr->head->typ);
		if(ty != NULL) {
			if(ret == NULL) {
				ret = Ty_TyList(ty, NULL);
				ptr2 = ret;
			}
			else {
				ptr2->tail = Ty_TyList(ty, NULL);
				ptr2 = ptr2->tail;
			}
		}
		else {
			EM_error(ptr->head->pos, "undefined type %s", S_name(ptr->head->typ));
			exit(1);
		}
		ptr = ptr->tail;
	}
	return ret;
}
Esempio n. 10
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);
}
Esempio n. 11
0
Ty_tyList makeFormalTyList(S_table tenv, A_fieldList afields) {
  Ty_tyList head = Ty_TyList(NULL, NULL), slow = head;
  for (; afields; afields = afields->tail) {
    Ty_tyList fast = Ty_TyList(S_look(tenv, afields->head->typ), NULL);
    slow->tail = fast;
    slow = fast;
  }
  return head->tail;
}
Esempio n. 12
0
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);
	}
}
Esempio n. 13
0
Ty_tyList makeFormalTyList( S_table tenv, A_fieldList args)
{
  if( args == NULL )
    return NULL;
  A_field arg = args->head;
  Ty_ty ty = S_look( tenv, arg->typ );
  if( ty == NULL )
    EM_error( arg->pos, "wrong ty");
  return Ty_TyList( ty, makeFormalTyList( tenv, args->tail ) );
}
Esempio n. 14
0
A_exp A_StringExp(A_pos pos, S_table table, string s)
{A_exp p = checked_malloc(sizeof(*p));
 p->kind=A_stringExp;
 p->pos=pos;
 A_ty t=S_look(table,S_Symbol(s));
 if(t==NULL) p->dec_type=S_Symbol(s);
 else p->dec_type=t->dec_type;
 p->u.stringg=s;
 return p;
}
Esempio n. 15
0
struct expty transVar_simpleVar(Tr_level level, S_table venv, S_table tenv, A_var v, Temp_label breakk) {
  E_enventry x = S_look(venv, v->u.simple);

  if (!x || x->kind != E_varEntry) {
    EM_error(v->pos, "undeclared variable '%s'", S_name(v->u.simple));
    return expTy(NULL, Ty_Int());
  }

  return expTy(Tr_simpleVar(x->u.var.access, level),
               actual_ty(x->u.var.ty));
}
Esempio n. 16
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));
}
Esempio n. 17
0
Ty_tyList makeFormalTyList (S_table tenv, A_fieldList params)
{
  Ty_tyList tList = NULL;
  A_fieldList pList = NULL;

  for (pList = params; pList; pList = pList->tail) {
    Ty_ty ty = S_look (tenv, pList->head->typ);
    tList = Ty_TyList (ty, tList);
  }

  return tList;
}
Esempio n. 18
0
static Ty_fieldList dfsRecordTy( S_table tenv , A_fieldList records )
{
  if( records == NULL )
    return NULL ;
  A_field record = records->head ;
  Ty_ty type = S_look( tenv , record->typ );
  Ty_field field;
  if( type == NULL )
    field = Ty_Field( record->name , Ty_Name( record->typ , NULL ) );
  else field = Ty_Field( record->name , type );
  Ty_fieldList rest = dfsRecordTy( tenv , records->tail );
  return Ty_FieldList( field , rest );
}
Esempio n. 19
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);
		}
	}
}
Esempio n. 20
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);
	}
}
Esempio n. 21
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);
}
Esempio n. 22
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);
		}
	}
}
Esempio n. 23
0
// translate function call: check that arguments match the
// formal params
struct expty transCallExp(S_table venv, S_table tenv, A_exp e)
{
  E_enventry ee = S_look(venv, e->u.call.func);
  if (!ee) {
    EM_error(e->pos, "undefined function %s", S_name(e->u.call.func));
    return ExpTy(NULL, NULL);
  }

  Ty_tyList formals = ee->u.fun.formals;
  A_expList args = e->u.call.args;
  for (; formals && args; formals = formals->tail, args = args->tail) {
    if (!Ty_is_compatible(formals->head, transExp(venv, tenv, args->head).ty)) {
      EM_error(e->pos, "arguments type mismatch");
      return ExpTy(NULL, NULL);
    }
  }
  return ExpTy(NULL, ee->u.fun.result);
}
Esempio n. 24
0
struct expty transVar(S_table venv, S_table tenv, A_var v)
{

  switch( v->kind )
    {
    case A_simpleVar:
      {
	string varName = S_name( v->u.simple );
	E_entry var = (E_entry) S_look( venv , v->u.simple );
	if( var == NULL )
	  EM_error( v->pos , "can't find" , varName);
	if( var->kind != E_varEntry )
	  EM_error( v->pos , varName , " is not variable " );
	return _expTy( NULL , var->var );
      }
    case A_fieldVar:
      {
	struct expty var =  transVar( venv , tenv , v->u.field.var);
	Ty_ty varType = var.ty;
	string fieldName = S_name( v->u.field.sym );
	if( varType->kind != Ty_record )
	  EM_error( v->pos , " is not record " );
	Ty_fieldList fields = varType->u.record;
	for( ; fields != NULL ; fields = fields->tail )
	  {
	    Ty_field field = fields->head ;
	    if( field->name == v->u.field.sym )
	      return _expTy( NULL , field->ty );
	  }
	EM_error( v->pos , "can't find field " , S_name( v->u.field.sym ) );
      }
    case A_subscriptVar:
      {
	struct expty var = transVar( venv , tenv , v->u.subscript.var );
	struct expty subs = transExp( venv , tenv , v->u.subscript.exp );
	if( subs.ty->kind != Ty_int )
	  EM_error( v->pos , "array subs should be int" );
	return var;
      }
    default :
      assert(0);
    }
}
Esempio n. 25
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);
}
Esempio n. 26
0
Tr_exp transDec_varDec(Tr_level level, S_table venv, S_table tenv, A_dec d, Temp_label breakk) {
  struct expty init = transExp(level, venv, tenv, d->u.var.init, breakk);

  if (d->u.var.typ) {
    Ty_ty typ = S_look(tenv, d->u.var.typ);

    if (!has_same_ty(typ, init.ty))
      EM_error(d->u.var.init->pos,
               "cannot initialize a variable of type '%s' with an rvalue of "
               "type '%s'",
               type_msg(typ), type_msg(init.ty));
  } else if (init.ty->kind == Ty_nil)
    EM_error(d->u.var.init->pos,
             "cannot initialize a nil type without specified record type");

  Tr_access access = Tr_allocLocal(level, TRUE); // todo check escape = false
  S_enter(venv, d->u.var.var, E_VarEntry(access, init.ty));

  return Tr_assignExp(Tr_simpleVar(access, level), init.exp);
}
Esempio n. 27
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, x->u.var.ty);
      else {
        EM_error(v->pos, "undefined variable %s",
            S_name(v->u.simple));
        return ExpTy(NULL, NULL);
      }
    }

    case A_fieldVar: {
      struct expty et = transVar(venv, tenv, v->u.field.var);
      if (et.ty && et.ty->kind == Ty_record) {
        Ty_fieldList fl = et.ty->u.record;
        for(; fl; fl = fl->tail) {
          if (fl->head->name == v->u.field.sym) {
            return ExpTy(NULL, fl->head->ty);
          }
        }
      }
      // can NOT get the v's name, use field name instaed
      EM_error(v->pos, "undefined variable %s",
          S_name(v->u.field.sym));
      return ExpTy(NULL, NULL);
    }

    case A_subscriptVar: {
      struct expty et = transVar(venv, tenv, v->u.field.var);
      if (et.ty && et.ty->kind == Ty_array) {
        return ExpTy(NULL, et.ty->u.array);
      }
      // can NOT get v's name
      EM_error(v->pos, "undefined variable");
      return ExpTy(NULL, NULL);
    }
  }
}
Esempio n. 28
0
static Ty_ty dfsTypeDec( A_pos pos , S_table tenv ,
			 S_symbol s , S_symbol origin )
{
  if( s == origin )
    {
      EM_error( pos , " loop in definition " , S_name(s) );
      return NULL ;
    }

  Ty_ty ty = S_look( tenv , s );
  if( ty == NULL )
    EM_error( pos , " can't find " , s );

  if( ty->kind == Ty_name )
    {
      if( ty->u.name.ty == NULL )
	ty->u.name.ty = dfsTypeDec( pos , tenv , ty->u.name.sym , origin );
      return ty->u.name.ty;
    }
  return ty;
}
Esempio n. 29
0
/* translate function declaration
 * TODO
 * reduce the result type from the body and check that
 * it maps the specified result(including the void case
 * -it is a procedure)
 */
void transFuncDec(S_table venv, S_table tenv, A_dec d)
{
  // add the function itself
  Ty_ty resultTy;
  if (d->u.function.result)
    resultTy = S_look(tenv, d->u.function.result);
  else
    resultTy = Ty_Void();

  Ty_tyList formalTys = makeFormalTyList(tenv, d->u.function.params);
  S_enter(venv, d->u.function.name, E_FunEntry(formalTys, resultTy));

  // re-parse the formal params and add them as variable
  // binding for the body
  S_beginScope(venv);
  A_fieldList fl = d->u.function.params;
  Ty_tyList tl = formalTys;
  for (; fl; fl = fl->tail, tl = tl->tail) {
    S_enter(venv, fl->head->name, E_VarEntry(tl->head));
  }
  transExp(venv, tenv, d->u.function.body);
  S_endScope(venv);
}
Esempio n. 30
0
Ty_tyList makeFormalTyList(S_table tenv, A_fieldList fieldList)
{
  A_fieldList fl = fieldList;
  Ty_tyList tl = NULL;
  Ty_tyList ret = NULL;
  Ty_ty ty;

  // 从左到右构造参数
  for (; fl; fl = fl->tail) {
    ty = S_look(tenv, fl->head->typ);
    if (ty) {
      if (tl) {
        tl = tl->tail = Ty_TyList(ty, NULL);
      } else {
        ret = tl = Ty_TyList(ty, tl);
      }
    } else {
      EM_error(fl->head->pos, "undefined type %s", S_name(fl->head->typ));
    }
  }

  return ret;
}