/* 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 ); }
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); } } }
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)); } } }
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 { //EM_error(a->pos, "undefined type %s", S_name(a->u.name)); return Ty_Int(); } } case A_recordTy: { Ty_ty ty,ty2; Ty_fieldList fields,tailptr; A_fieldList afields; if(a->u.record == NULL) { fields = NULL; ty = Ty_Record(fields); return ty; } else { fields = tailptr = NULL; afields = a->u.record; while(afields != NULL) { ty2 = S_look(tenv, afields->head->typ); if(ty2 != NULL) { if(fields == NULL) { fields = Ty_FieldList(Ty_Field(afields->head->name, ty2), NULL); tailptr = fields; } else { tailptr->tail = Ty_FieldList(Ty_Field(afields->head->name, ty2), NULL); tailptr = tailptr->tail; } } else { //EM_error(a->pos, "undefined field type"); return Ty_Int(); } afields = afields->tail; } ty = Ty_Record(fields); return ty; } } case A_arrayTy: { Ty_ty ty; ty = S_look(tenv, a->u.array); if(ty != NULL) { return Ty_Array(ty); } else { //EM_error(a->pos, "undefined type %s", S_name(a->u.array)); return Ty_Int(); } } default: { assert(0); } } }