117 lines
2.6 KiB
Plaintext
117 lines
2.6 KiB
Plaintext
#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)); |