85 lines
2.0 KiB
Plaintext
85 lines
2.0 KiB
Plaintext
|
#define unify
|
||
|
///unify(a, b)
|
||
|
/**
|
||
|
* unify :: TypeConLink -> TypeConLink -> ()
|
||
|
*
|
||
|
* Unifies types `a` and `b`.
|
||
|
*
|
||
|
* @param a the first type con
|
||
|
* @param b the second type con
|
||
|
*/
|
||
|
var a = argument0;
|
||
|
var b = argument1;
|
||
|
|
||
|
assertInstanceof(a, TypeConLink);
|
||
|
assertInstanceof(b, TypeConLink);
|
||
|
|
||
|
if (instanceof(a, TypeCon1Link) && instanceof(b, TypeCon1Link))
|
||
|
unifyType(a, b);
|
||
|
else if (instanceof(a, TypeCon1Link) && !instanceof(b, TypeCon1Link))
|
||
|
unify(b, a);
|
||
|
else if (!instanceof(a, TypeCon1Link) && instanceof(b, TypeCon1Link)) {
|
||
|
while (!ds_set_empty(b.from))
|
||
|
replaceLink(ds_set_first(b.from), b, a);
|
||
|
|
||
|
delete(b.type);
|
||
|
delete(b);
|
||
|
exit;
|
||
|
|
||
|
}
|
||
|
else if (!instanceof(a, TypeCon1Link) && !instanceof(b, TypeCon1Link)) {
|
||
|
for (var i = 0; i < ds_list_size(a.to); i++)
|
||
|
unify(a.to[|i], b.to[|i]);
|
||
|
}
|
||
|
|
||
|
|
||
|
#define unifyType
|
||
|
///unifyType(a, b)
|
||
|
/**
|
||
|
* unifyType :: TypeConLink -> TypeConLink -> ()
|
||
|
*
|
||
|
* Unifies types `a` and `b`.
|
||
|
*
|
||
|
* @param a the first type con
|
||
|
* @param b the second type con
|
||
|
*/
|
||
|
var a = argument0;
|
||
|
var b = argument1;
|
||
|
|
||
|
assertInstanceof(a, TypeCon1Link);
|
||
|
assertInstanceof(b, TypeCon1Link);
|
||
|
assertInstanceof(a.type, Type);
|
||
|
assertInstanceof(b.type, Type);
|
||
|
|
||
|
if (a == b)
|
||
|
exit;
|
||
|
|
||
|
//unify free types by taking the union of their traits and destroying the second type
|
||
|
if (instanceof(a.type, FreeType) && instanceof(b.type, FreeType)) {
|
||
|
ds_set_add_all(a.type.traits, b.type.traits);
|
||
|
for (var trait = ds_set_first(b.type.traits); ds_set_exists(b.type.traits, trait); trait = ds_set_next(b.type.traits, trait))
|
||
|
ds_set_add(a.type.traits, trait);
|
||
|
|
||
|
while (!ds_set_empty(b.from))
|
||
|
replaceLink(ds_set_first(b.from), b, a);
|
||
|
|
||
|
delete(b.type);
|
||
|
delete(b);
|
||
|
exit;
|
||
|
}
|
||
|
|
||
|
|
||
|
//unify free type with concrete type by replacing all occurrences with the concrete type
|
||
|
if (instanceof(a.type, FreeType) && !instanceof(b.type, FreeType)) {
|
||
|
unify(b, a);
|
||
|
exit;
|
||
|
}
|
||
|
|
||
|
if (!instanceof(a.type, FreeType) && instanceof(b.type, FreeType)) {
|
||
|
while (!ds_set_empty(b.from))
|
||
|
replaceLink(ds_set_first(b.from), b, a);
|
||
|
|
||
|
delete(b.type);
|
||
|
delete(b);
|
||
|
exit;
|
||
|
}
|