Very limited HM-style type inference works! (Just var v = value, but still. The machinery is mostly in place)
This commit is contained in:
25
k.krak
25
k.krak
@@ -167,9 +167,28 @@ fun main(argc: int, argv: **char): int {
|
|||||||
|
|
||||||
// resolves all binding possibilities for one top level item
|
// resolves all binding possibilities for one top level item
|
||||||
passes[str("name_type_resolve")] = fun(item: *tree<ast>) {
|
passes[str("name_type_resolve")] = fun(item: *tree<ast>) {
|
||||||
println("Running name type resolver?")
|
if !pass_poset.done(make_pair(item, str("name_possibility_resolve"))) {
|
||||||
// just temp
|
pass_poset.add_open_dep(make_pair(item, str("name_type_resolve")), make_pair(item, str("name_possibility_resolve")))
|
||||||
pass_poset.add_close_dep(make_pair(item, str("name_type_resolve")), make_pair(item, str("name_possibility_resolve")))
|
return
|
||||||
|
}
|
||||||
|
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())
|
||||||
|
if (t1->bound_to->equality(t2->bound_to, false) || t1->bound_to->is_unknown())
|
||||||
|
t1->set(t2->bound_to)
|
||||||
|
else
|
||||||
|
t2->set(t1->bound_to)
|
||||||
|
}
|
||||||
|
var traverse_for_unify: fun(*tree<ast>): void = fun(t: *tree<ast>) {
|
||||||
|
t->children.for_each(traverse_for_unify)
|
||||||
|
match (t->data) {
|
||||||
|
ast::_declaration() if (t->children.size > 1)
|
||||||
|
unify(get_type(t->children[0]), get_type(t->children[1]))
|
||||||
|
/*ast::_assignment()*/
|
||||||
|
/*ast::_call()*/
|
||||||
|
/*ast::_return()*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
traverse_for_unify(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit C
|
// emit C
|
||||||
|
|||||||
@@ -32,6 +32,18 @@ adt ast {
|
|||||||
_cast: *binding<type>,
|
_cast: *binding<type>,
|
||||||
_value: pair<str, *binding<type>>
|
_value: pair<str, *binding<type>>
|
||||||
}
|
}
|
||||||
|
fun get_type(a: *tree<ast>): *binding<type> {
|
||||||
|
match(a->data) {
|
||||||
|
ast::_identifier(b) return b.second
|
||||||
|
ast::_binding(b) return get_type(b.second->bound_to)
|
||||||
|
ast::_function(b) return b.second
|
||||||
|
/*ast::_call() return get_type(a->children[0])->bound_to->base->_fun->second*/
|
||||||
|
/*ast::_compiler_intrinsic(b) return str("_compiler_intrinsic(") + b.first + ")"*/
|
||||||
|
ast::_cast(b) return b
|
||||||
|
ast::_value(b) return b.second
|
||||||
|
}
|
||||||
|
error("Trying to get type of node without one: " + to_string(a->data))
|
||||||
|
}
|
||||||
fun to_string(a: ref ast): str {
|
fun to_string(a: ref ast): str {
|
||||||
match(a) {
|
match(a) {
|
||||||
ast::_translation_unit(b) return str("_translation_unit(") + b + ")"
|
ast::_translation_unit(b) return str("_translation_unit(") + b + ")"
|
||||||
@@ -272,7 +284,7 @@ obj binding<T> (Object) {
|
|||||||
}
|
}
|
||||||
fun set(to: *T) {
|
fun set(to: *T) {
|
||||||
// don't set null, that will set all unbound ones
|
// don't set null, that will set all unbound ones
|
||||||
if (bound_to == null<tree<ast>>()) {
|
if (bound_to == null<T>()) {
|
||||||
bound_to = to
|
bound_to = to
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user