コード例 #1
0
ファイル: semant.c プロジェクト: wingerted/Tiger-Complier
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);
}
コード例 #2
0
ファイル: semant.c プロジェクト: MaoKwen/tiger-compiler
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));
    }
  }
}
コード例 #3
0
ファイル: semant.c プロジェクト: MaoKwen/tiger-compiler
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();
}
コード例 #4
0
ファイル: semant.c プロジェクト: yangpeiyong/tiger
/* 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;
    }
  }
}
コード例 #5
0
ファイル: semant.c プロジェクト: Shenjiaqi/tiger
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 );
}
コード例 #6
0
ファイル: semant.c プロジェクト: wingerted/Tiger-Complier
void transDec (S_table venv, S_table tenv, A_dec d)
{
  switch (d->kind) {
    case A_varDec: {
        Ty_ty typ = NULL;
        if (d->u.var.typ) {
          typ = S_look(tenv, d->u.var.typ);
        }

        struct expty e = transExp (venv, tenv, d->u.var.init);
        if (!typ || typ->kind == e.ty->kind) {
          if (e.ty->kind == Ty_nil && (!typ || typ->kind != Ty_record)) {
            EM_error (d->u.var.init->pos, "nil should be constrained by record");
          }
          S_enter (venv, d->u.var.var, E_VarEntry (e.ty));
        } else {
          EM_error (d->u.var.init->pos, "var type should be same as init");
        }
        break;
      }

    case A_typeDec: {
        A_nametyList nList = NULL;

        for (nList = d->u.type; nList; nList = nList->tail) {
          bool flag;
          A_nametyList scanList = NULL;
          for (scanList = nList->tail; scanList; scanList = scanList->tail) {
            if (strcmp(S_name(nList->head->name), S_name(scanList->head->name)) == 0) {
              flag = TRUE;
              break;
            }
          }
          if (flag) {
            EM_error (d->pos, "type redefined error");
          }
          S_enter(tenv, nList->head->name, Ty_Name (nList->head->ty->u.name, NULL));
        }
        for (nList = d->u.type; nList; nList = nList->tail) {
          Ty_ty waitFill = S_look(tenv, nList->head->name);
          if (waitFill->kind == Ty_name) {
            waitFill->u.name.ty = transTy (tenv, nList->head->ty);
          }
          Ty_ty trueType = actual_ty(waitFill);
          if (trueType) {
            S_enter(tenv, nList->head->name, actual_ty(waitFill));
          } else {
            EM_error (d->pos, "recursive types should through record or array");
            break;
          }

        }

        break;
      }

    case A_functionDec: {
        A_fundecList funList = NULL;

        for (funList = d->u.function; funList; funList = funList->tail) {
           bool flag;
          A_fundecList scanList = NULL;
          for (scanList = funList->tail; scanList; scanList = scanList->tail) {
            if (strcmp(S_name(funList->head->name), S_name(scanList->head->name)) == 0) {
              flag = TRUE;
              break;
            }
          }
          if (flag) {
            EM_error (d->pos, "function redefined error");
          }
          A_fundec f = funList->head;
          if (!f->result) {
            f->result = S_Symbol("void");
          }
          Ty_ty resultTy = S_look (tenv, f->result);
          Ty_tyList formalTys = makeFormalTyList (tenv, f->params);
          S_enter (venv, f->name, E_FunEntry (formalTys, resultTy));
        }
        for (funList = d->u.function; funList; funList = funList->tail) {
          A_fundec f = funList->head;
          Ty_tyList formalTys = makeFormalTyList (tenv, f->params);

          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));
            }
          }
          Ty_ty returnTy = S_look (tenv, f->result);
          if (returnTy->kind != transExp (venv, tenv, f->body).ty->kind) {
            EM_error (f->body->pos, "return type wrong");
          }
          S_endScope (venv);

        }

        break;
      }
  }
}
コード例 #7
0
ファイル: semant.c プロジェクト: java66liu/mytiger
void transDec(S_table venv, S_table tenv, A_dec d) {
	if (!d) {
		return;
	}
	switch (d->kind) {
		case A_varDec: {
			struct expty e = transExp(venv, tenv, d->u.var.init);
			if (d->u.var.typ) {
				Ty_ty ty = (Ty_ty)S_look(tenv, d->u.var.typ);
				if (!ty) {
					EM_error(d->pos, "undefined type '%s'", S_name(d->u.var.typ));
					return;
				}
				ty = actual_ty(ty);
				if (!isSameTy(ty, e.ty)) {
					EM_error(d->pos, (string)"type mismatch");
					return;
				}
				S_enter(venv, d->u.var.var, E_VarEntry(ty));
				return;
			}
			if (e.ty->kind == Ty_nil) {
				EM_error(d->pos, "initializing nil expressions not constrained by record type");
				return;
			}
			S_enter(venv, d->u.var.var, E_VarEntry(e.ty));
			return;
		}
		case A_typeDec: {
			S_table tmp = S_empty();
			A_nametyList ntl;
			for (ntl = d->u.type; ntl; ntl = ntl->tail) {
				if (S_look(tmp, ntl->head->name)) {
					EM_error(d->pos, "type '%s' redefined", S_name(ntl->head->name));
					return;
				}
				S_enter(tmp, ntl->head->name, "-tmp-");
				S_enter(tenv, ntl->head->name, Ty_Name(ntl->head->name, NULL));
			}
			for (ntl = d->u.type; ntl; ntl = ntl->tail) {
				Ty_ty ty = (Ty_ty)S_look(tenv, ntl->head->name);
				ty->u.name.ty = transTy(tenv, ntl->head->ty);
			}
			for (ntl = d->u.type; ntl; ntl = ntl->tail) {
				Ty_ty ty = (Ty_ty)S_look(tenv, ntl->head->name);
				if (ty->u.name.ty->kind != Ty_name) {
					return;
				}
			}
			EM_error(d->pos, "infinite recursive");
			return;
		}
		case A_functionDec: {
			S_table tmp = S_empty();
			A_fundecList fdl;
			for (fdl = d->u.function; fdl; fdl = fdl->tail) {
				if (S_look(tmp, fdl->head->name)) {
					EM_error(d->pos, "function '%s' redefined", S_name(fdl->head->name));
					return;
				}
				S_enter(tmp, fdl->head->name, "-tmp-");
			}
			for (fdl = d->u.function; fdl; fdl = fdl->tail) {
				Ty_tyList formalTys = makeFormalTyList(tenv, fdl->head->params);
				if (fdl->head->result) {
					Ty_ty resultTy = S_look(tenv, fdl->head->result);
					S_enter(venv, fdl->head->name, E_FunEntry(formalTys, resultTy));
				}
				else {
					S_enter(venv, fdl->head->name, E_FunEntry(formalTys, NULL));
				}
			}
			for (fdl = d->u.function; fdl; fdl = fdl->tail) {
				Ty_tyList formalTys = makeFormalTyList(tenv, fdl->head->params);
				S_beginScope(venv);
				{
					A_fieldList l;
					Ty_tyList t;
					for (l = fdl->head->params, t = formalTys; l; l = l->tail, t = t->tail) {
						S_enter(venv, l->head->name, E_VarEntry(t->head));
					}
				}
				transExp(venv, tenv, fdl->head->body);
				S_endScope(venv);
			}
			break;
		}
		default: {
			assert(0);
		}
	}
}
コード例 #8
0
ファイル: semant.c プロジェクト: Shenjiaqi/tiger
struct expty transDec(S_table venv, S_table tenv, A_dec d)
{
  switch( d->kind )
    {
    case A_functionDec:
      {
	//whether already in funcdeclar
	if(InFunc())
	  EM_error( d->pos , "already in func declare");
	A_fundecList funcs = d->u.function;
	// for every fun declare in fundecList
	for( ; funcs != NULL ; funcs = funcs->tail )
	  {
	    A_fundec func = funcs->head;
	    // get ty of params and result
	    Ty_tyList funentry = makeFormalTyList( tenv , func->params );
	    Ty_ty res;
	    if( func->result == NULL )
	      res = Ty_Nil();
	    else
	      res = S_look( tenv , func->result );
	    if( res == NULL )
	      EM_error( func->pos , "no " , S_name( func->result ) , "type ");
	    //whether already defined
	    if( S_look( venv , func->name ) != NULL )
	      EM_error( func->pos , S_name( func->result ) ,
			"already defined" );
	    S_enter( venv ,  func->name , E_FunEntry( funentry , res ) );
	  }
	funcs = d->u.function;
	// for every fun in fundecList, call tranexp on its body
	for( ; funcs != NULL ; funcs = funcs->tail )
	  {
	    A_fundec func = funcs->head;
	    S_beginScope( venv );
	    A_fieldList args = func->params;
	    Ty_tyList funentries = ((E_entry)S_look( venv , func->name ))
	      ->fun.formalTys ;
	    for( ; args != NULL ; args = args->tail ,
		   funentries = funentries->tail)
	      {
		A_field arg = args->head;
		Ty_ty type = funentries->head;
		S_enter( venv , arg->name , type );
	      }
	    SetInFunc();
	    transExp( venv , tenv , func->body );
	    UsetInFunc();
	    S_endScope( venv );
	  }
	return _expTy( NULL , Ty_Void() );
      }
    case A_varDec:
      {
	Ty_ty type = S_look( tenv , d->u.var.typ );
	if( type == NULL )
	  EM_error( d->pos , S_name( d->u.var.typ ) , " not defined " );
	struct expty init = transExp( venv , tenv , d->u.var.init );
	if( init.ty->kind != Ty_nil && init.ty->kind != type->kind )
	  EM_error( d->pos , "Expect " , tyKindName( type->kind ) , " but " ,
		    tyKindName( init.ty->kind ) );
	if( S_look( venv , d->u.var.var ) != NULL )
	  EM_error( d->pos , S_name( d->u.var.var ) , " already defined " );
	S_enter( venv , d->u.var.var , type );
	return _expTy( NULL , Ty_Void() );
      }
    case A_typeDec:
      {
	A_nametyList tylist = d->u.type;
	for( ; tylist != NULL ; tylist = tylist->tail )
	  {
	    A_namety tydec = tylist->head;
	    if( S_look( tenv , tydec->name ) != NULL )
	      EM_error( tydec->ty->pos , S_name( tydec->name ) ,
			" already declared " );
	    A_ty ty = tydec->ty;
	    switch( ty->kind )
	      {
	      case A_nameTy:
		{
		  Ty_ty tyy = S_look( tenv , ty->u.name ) ;
		  if( tyy == NULL )
		    S_enter( tenv , tydec->name ,
			     Ty_Name( ty->u.name , NULL ) );
		  else
		    S_enter( tenv , tydec->name , tyy );
		}
	      case A_recordTy:
		{
		  A_fieldList records = ty->u.record;
		  Ty_fieldList types = dfsRecordTy( tenv , records );
		  S_enter( tenv , tydec->name , Ty_Record( types ) );
		}
	      case A_arrayTy:
	      default:
		assert(0);
	      }
	    S_enter( tenv , tydec->name , E_VarEntry( NULL ) );
	  }
	tylist = d->u.type;
	for( ; tylist != NULL ; tylist = tylist->tail )
	  {
	    A_namety tydec = tylist->head;
	    A_ty ty = tydec->ty;
	    switch( ty->kind )
	      {
	      case A_nameTy:
		{
		  Ty_ty tyy = S_look( tenv , ty->u.name );
		  if( tyy->u.name.ty == NULL )
		    tyy->u.name.ty = dfsTypeDec( ty->pos , tenv ,
						 tyy->u.name.sym ,
						 tydec->name );
		}
	      case A_recordTy:
	      case A_arrayTy:
	      default:
		assert(0);
	      }
	  }
      }
    default:
      assert(0);
    }
}