Exp transDec(Absyn.TypeDec d) { // 1st pass - handles the type headers // Using a local hashtable, check if there are two types // with the same name in the same (consecutive) batch // of mutually recursive types. See test38.tig! Hashtable hash = new Hashtable(); for (Absyn.TypeDec type = d; type != null; type = type.next) { if (hash.put(type.name, type.name) != null) error(type.pos, "type redeclared"); type.entry = new Types.NAME(type.name); env.tenv.put(type.name, type.entry); } // 2nd pass - handles the type bodies for (Absyn.TypeDec type = d; type != null; type = type.next) { Types.NAME name = (Types.NAME) type.entry; name.bind(transTy(type.ty)); } // check for illegal cycle in type declarations for (Absyn.TypeDec type = d; type != null; type = type.next) { Types.NAME name = (Types.NAME) type.entry; if (name.isLoop()) error(type.pos, "illegal type cycle"); } return translate.TypeDec(); }
ExpTy transExp(Absyn.RecordExp e) { Types.NAME name = (Types.NAME) env.tenv.get(e.typ); if (name != null) { Type actual = name.actual(); if (actual instanceof Types.RECORD) { Types.RECORD r = (Types.RECORD) actual; return new ExpTy(translate.RecordExp(transFields(e.pos, r, e.fields)), name); } error(e.pos, "record type required"); } else error(e.pos, "undeclared type: " + e.typ); return new ExpTy(translate.Error(), VOID); }
ExpTy transExp(Absyn.ArrayExp e) { Types.NAME name = (Types.NAME) env.tenv.get(e.typ); ExpTy size = transExp(e.size); ExpTy init = transExp(e.init); checkInt(size, e.size.pos); if (name != null) { Type actual = name.actual(); if (actual instanceof Types.ARRAY) { Types.ARRAY array = (Types.ARRAY) actual; if (!init.ty.coerceTo(array.element)) error(e.init.pos, "element type mismatch"); return new ExpTy(translate.ArrayExp(size.exp, init.exp), name); } else error(e.pos, "array type required"); } else error(e.pos, "undeclared type: " + e.typ); return new ExpTy(translate.Error(), VOID); }