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); }
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)); } } }
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(); }
/* 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; } } }
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 ); }
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; } } }
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); } } }
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); } }