Пример #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));
}
Пример #2
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();
}
Пример #3
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());
}
Пример #4
0
basic_warning::basic_warning(const std::string& where_msg,
		const std::string& what_msg, type t) :
	my_where_msg(where_msg), my_what_msg(what_msg), my_type(t) {
	if (warning_stream) {
		std::string msg = what();
		if (msg != "") {
			// @todo This should be handled by passing the logger as
			// a stream (with some appropriate wrapper deriving from basic_ostream)
			// but for now this will have to do.
			if (is_active()) {
				// add warning to counter
				if (warning_count.find(t)==warning_count.end())
					warning_count[t]=1;
				else
					++warning_count[t];

				// output message
				if (warning_stream != logger::get_stream()) {
					*warning_stream << msg << std::endl;
				} else {
					// to avoid interleaving with logged messages, send
					// a logged message
					logger(logger_level::ALWAYS, where_msg,
							"WARNING (" + type_msg(t) + ") " + my_what_msg);
				}
			}
		}
	}
}
Пример #5
0
std::string basic_warning::prepare_msg() const {
	std::string msg = "WARNING " + type_msg(my_type);
	if (!my_where_msg.empty())
		msg += " in " + my_where_msg;
	if (!my_what_msg.empty())
		msg += ": " + my_what_msg;
	return msg;
}
Пример #6
0
struct expty transVar_subscriptVar(Tr_level level, S_table venv, S_table tenv, A_var v, Temp_label breakk) {
  struct expty var = transVar(level, venv, tenv, v->u.subscript.var, breakk);
  struct expty sub = transExp(level, venv, tenv, v->u.subscript.exp, breakk);

  if (var.ty->kind != Ty_array) {
    EM_error(v->u.subscript.var->pos, "variable type '%s' is not array",
             type_msg(var.ty));
    return expTy(NULL, Ty_Int());
  }
  if (sub.ty->kind != Ty_int) {
    EM_error(v->u.subscript.exp->pos, "invalid types '%s' for array subscript",
             type_msg(sub.ty));
    return expTy(NULL, Ty_Int());
  }

  return expTy(Tr_subscriptVar(var.exp, sub.exp, level),
               actual_ty(var.ty->u.array));
}
Пример #7
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);
}
Пример #8
0
string type_msg(Ty_ty ty) {
  string str = checked_malloc(200 * sizeof(char));
  switch (ty->kind) {
    case Ty_record:
      strcpy(str, "record{ ");
      Ty_fieldList fields = ty->u.record;
      if (!fields) {
        strcat(str, type_msg(fields->head->ty));
        fields = fields->tail;
      }
      for (; fields; fields = fields->tail) {
        strcat(str, ", ");
        strcat(str, type_msg(fields->head->ty));
      }
      strcat(str, " }");
      break;
    case Ty_nil:
      strcpy(str, "nil");
      break;
    case Ty_int:
      strcpy(str, "int");
      break;
    case Ty_string:
      strcpy(str, "string");
      break;
    case Ty_array:
      strcpy(str, "array of ");
      strcat(str, type_msg(ty->u.array));
      break;
    case Ty_name:
      if (ty->u.name.ty)
        strcpy(str, type_msg(actual_ty(ty)));
      else
        strcpy(str, S_name(ty->u.name.sym));
      break;
    case Ty_void:
      strcpy(str, "void");
      break;
  }
  return str;
}
Пример #9
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));
}
Пример #10
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());
}
Пример #11
0
struct expty transVar_fieldVar(Tr_level level, S_table venv, S_table tenv, A_var v, Temp_label breakk) {
  struct expty var = transVar(level, venv, tenv, v->u.field.var, breakk);

  if (var.ty->kind != Ty_record)
    EM_error(v->pos, "invalid types '%s' for record field", type_msg(var.ty));

  int index = 0;
  Ty_fieldList fields;
  for (fields = var.ty->u.record; fields != NULL; fields = fields->tail, index += 1)
    if (fields->head->name == v->u.field.sym) break;
  if (!fields) {
    EM_error(v->pos, "field '%s' not defined in record type", S_name(v->u.field.sym));
    return expTy(NULL, Ty_Int());
  }
  return expTy(Tr_fieldVar(var.exp, index, level),
               actual_ty(fields->head->ty));
}
Пример #12
0
void basic_warning::output_statistics() {
	if (!warning_count.empty()) {
		std::stringstream ss;
		ss << "ATTENTION: Warnings were issued." << std::endl;
		if (warning_stream != logger::get_stream()) {
			*warning_stream << ss;
		} else {
			logger(logger_level::ALWAYS, "Warning statistics",
					ss.str());
		}
	}
	for (std::map<basic_warning::type, unsigned int>::const_iterator it =
			warning_count.begin(); it != warning_count.end(); ++it) {
		std::stringstream ss;
		ss << "Warnings on " << type_msg(it->first) << ": " << it->second << std::endl;
		if (warning_stream != logger::get_stream()) {
			*warning_stream << ss;
		} else {
			logger(logger_level::ALWAYS, "Warning statistics",
					ss.str());
		}
	}
}