Also regular overloading works now, by counting remaining unknowns as equal during overload filtering time (so that function calls as statements, which get an inferenced return type of _unknown can match a function with any return type

This commit is contained in:
Nathan Braswell
2018-09-24 00:21:39 -04:00
parent 2148577523
commit 4dcf102cb0
2 changed files with 10 additions and 8 deletions

4
k.krak
View File

@@ -213,7 +213,7 @@ fun main(argc: int, argv: **char): int {
var unify: fun(*binding<type>, *binding<type>): void = fun(t1: *binding<type>, t2: *binding<type>) { var unify: fun(*binding<type>, *binding<type>): void = fun(t1: *binding<type>, t2: *binding<type>) {
println("trying to unify " + t1->bound_to->to_string() + " and " + t2->bound_to->to_string()) println("trying to unify " + t1->bound_to->to_string() + " and " + t2->bound_to->to_string())
if (t1->bound_to->equality(t2->bound_to, false) || t1->bound_to->is_unknown()) if (t1->bound_to->equality(t2->bound_to, false, false) || t1->bound_to->is_unknown())
t1->set(t2->bound_to) t1->set(t2->bound_to)
else if (t2->bound_to->is_unknown()) else if (t2->bound_to->is_unknown())
t2->set(t1->bound_to) t2->set(t1->bound_to)
@@ -247,7 +247,7 @@ fun main(argc: int, argv: **char): int {
match (t->data) { match (t->data) {
ast::_binding(b) if (!t->data._binding.second->bound()) { ast::_binding(b) if (!t->data._binding.second->bound()) {
println("Attempting to use our inferenced type " + unbound_types[t]->bound_to->to_string() + " to decide what to bind " + to_string(t->data) + " to form options:") println("Attempting to use our inferenced type " + unbound_types[t]->bound_to->to_string() + " to decide what to bind " + to_string(t->data) + " to form options:")
var filtered_options = multiple_binding_options[t].filter(fun(p: *tree<ast>): bool return unbound_types[t]->bound_to->equality(get_type(p)->bound_to, false);) var filtered_options = multiple_binding_options[t].filter(fun(p: *tree<ast>): bool return unbound_types[t]->bound_to->equality(get_type(p)->bound_to, false, true);)
multiple_binding_options[t].for_each(fun(p: *tree<ast>) { multiple_binding_options[t].for_each(fun(p: *tree<ast>) {
println("\t" + to_string(p->data) + " of type " + get_type(p)->bound_to->to_string()) println("\t" + to_string(p->data) + " of type " + get_type(p)->bound_to->to_string())
}) })

View File

@@ -55,10 +55,12 @@ obj type (Object) {
fun destruct() { fun destruct() {
base.destruct() base.destruct()
} }
fun operator!=(other: ref type):bool return !equality(other, true); fun operator!=(other: ref type):bool return !equality(other, true, false);
fun operator==(other: ref type):bool return equality(other, true); fun operator==(other: ref type):bool return equality(other, true, false);
fun equality(other: *type, care_about_ref: bool):bool return equality(*other, care_about_ref); fun equality(other: *type, care_about_ref: bool, count_unknown_as_equal: bool):bool return equality(*other, care_about_ref, count_unknown_as_equal);
fun equality(other: ref type, care_about_ref: bool):bool { fun equality(other: ref type, care_about_ref: bool, count_unknown_as_equal: bool):bool {
if (count_unknown_as_equal && (is_unknown() || other.is_unknown()))
return true
if (care_about_ref && (is_ref != other.is_ref)) if (care_about_ref && (is_ref != other.is_ref))
return false return false
if (indirection != other.indirection) if (indirection != other.indirection)
@@ -67,12 +69,12 @@ obj type (Object) {
base_type::_fun(b) { base_type::_fun(b) {
if ( !(other.is_fun() && base._fun.second == other.base._fun.second && base._fun.third == other.base._fun.third) ) if ( !(other.is_fun() && base._fun.second == other.base._fun.second && base._fun.third == other.base._fun.third) )
return false return false
if ( !(base._fun.first.second->bound_to->equality(other.base._fun.first.second->bound_to, care_about_ref)) ) if ( !(base._fun.first.second->bound_to->equality(other.base._fun.first.second->bound_to, care_about_ref, count_unknown_as_equal)) )
return false return false
if ( !(base._fun.first.first.size == other.base._fun.first.first.size) ) if ( !(base._fun.first.first.size == other.base._fun.first.first.size) )
return false return false
for (var i = 0; i < base._fun.first.first.size; i++;) for (var i = 0; i < base._fun.first.first.size; i++;)
if ( !(base._fun.first.first[i]->bound_to->equality(other.base._fun.first.first[i]->bound_to, care_about_ref)) ) if ( !(base._fun.first.first[i]->bound_to->equality(other.base._fun.first.first[i]->bound_to, care_about_ref, count_unknown_as_equal)) )
return false return false
return true return true
} }