#define freshTypes ///freshTypes(block) /** * freshTypes :: Block -> () * * Refreshes the anchor types of this block. * * @param block the block to refresh */ var block = argument0; assertInstanceof(block, Block); with (block) { for (var i = 0; i < ds_list_size(self.children); i++) if (instanceof(self.children[|i], Anchor)) { var anchor = self.children[|i]; if (!ds_list_empty(anchor.children)) delete(anchor.children[|0]); } var tmap = ds_map_create(); var vmap = ds_map_create(); for (var i = 0; i < ds_list_size(children); i++) if (instanceof(self.children[|i], Anchor)) { var anchor = self.children[|i]; if (anchor.currentType != noone) { if (!instanceof(anchor.currentType, TypeCon1Link)) removeType(anchor.currentType); anchor.currentType = noone; } anchor.currentType = copyFreshCon(tmap, vmap, anchor.freshType); addChild(anchor, createTypeInstance(anchor.currentType.to[|0])); } ds_map_destroy(tmap); ds_map_destroy(vmap); } #define copyFreshCon ///copyFreshCon(cmap, vmap, id) /** * copyFreshCon :: Map TypeConLink TypeConLink -> Map FreeType FreeType -> TypeConLink -> TypeConLink * * Returns a deep copy of the given type structure with fresh type variables. * * @param cmap a map of old cons to fresh ones * @param vmap a map of old free types to fresh ones * @param id the type to copy */ var cmap = argument0; var vmap = argument1; var con = argument2; assertInstanceof(con, TypeConLink); if (!ds_map_exists(cmap, con)) { if (instanceof(con, TypeCon1Link)) { if (instanceof(con.type, FreeType)) with (new(TypeCon1Link)) { self.type = copyFreshType(vmap, con.type); cmap[?con] = id; } else return con; } else if (instanceof(con, TypeConLink)) with (new(TypeConLink)) { for (var i = 0; i < ds_list_size(con.to); i++) addLink(id, copyFreshCon(cmap, vmap, con.to[|i])); cmap[?con] = id; } } return cmap[?con]; #define copyFreshType ///copyFreshType(vmap, id) /** * copyFreshType :: Map FreeType FreeType -> Type -> Type * * Returns a copy of the given type with a fresh type variable (if applicable). * * @param vmap a map of old free types to fresh ones * @param id the type to copy */ var vmap = argument0; var type = argument1; assertInstanceof(type, Type); if (instanceof(type, ConcreteType)) return type; if (instanceof(type, FreeType)) { if (!ds_map_exists(vmap, type)) with (new(FreeType)) { ds_set_add_all(self.traits, type.traits); vmap[?type] = id; } return vmap[?type]; } assert(false, "Unknown type "+getInstObjName(type));