diff --git a/k.krak b/k.krak index 6fa3036..cf606d7 100644 --- a/k.krak +++ b/k.krak @@ -202,7 +202,6 @@ fun main(argc: int, argv: **char): int { } for (var i = 0; i < item->children.size; i++;) { var child = item->children[i] - if is_type_def(child) match (child->data) { ast::_type_def(name) { println("Found a type_def! - " + name) @@ -210,25 +209,64 @@ fun main(argc: int, argv: **char): int { var grandchild = child->children[j]; if is_declaration(grandchild) { var ident = grandchild->children[0] + var ident_name = ident->data._identifier.first + var ident_type = ident->data._identifier.second var type_def_binding = make_ast_binding(name) set_ast_binding(type_def_binding, child) - item->add_child(_compiler_intrinsic(ident->data._identifier.first, binding_p(type::_fun(make_triple(make_pair(vec( + item->add_child(_compiler_intrinsic(ident_name, binding_p(type::_fun(make_triple(make_pair(vec( binding_p(type::_obj(type_def_binding)) ), - ident->data._identifier.second + ident_type ), false, false))), vec<*binding>())) - println("adding compiler intrinsic to do " + name + "." + ident->data._identifier.first) + println("adding compiler intrinsic to do " + name + "." + ident_name) + } + } + } + ast::_template(name_map_pair) { + if is_type_def(child->children[0]) { + var name = child->children[0]->data._type_def + println("Found a templated type_def! - " + name) + for (var j = 0; j < child->children[0]->children.size; j++;) { + var great_grandchild = child->children[0]->children[j]; + if is_declaration(great_grandchild) { + var ident = great_grandchild->children[0] + var ident_name = ident->data._identifier.first + + // inst type? + var ident_type = ident->data._identifier.second + + + // the map retains the order + var new_template_type_map = name_map_pair.second.associate(fun(n: str, t: *binding): pair> return make_pair(n, binding_p(type::_template_placeholder()));) + var new_ident_type = inst_temp_type(ident_type, name_map_pair.second.associate(fun(n: str, t: *binding): pair<*binding, *binding> + return make_pair(t, new_template_type_map[n]);)) + + var type_def_binding = make_ast_binding(name, new_template_type_map.values) + // do we need to set the binding to the template? + /*set_ast_binding(type_def_binding, child)*/ + + item->add_child(_template(ident_name, new_template_type_map, vec(_compiler_intrinsic(ident_name, binding_p(type::_fun(make_triple(make_pair(vec( + binding_p(type::_obj(type_def_binding)) + ), + ident_type + ), false, false))), vec<*binding>())))) + println("adding compiler intrinsic to do " + name + "." + ident_name) + } } } } } } + + println("post generative") + print_tree(item, 1) } // resolves all binding possibilities for one top level item passes[str("name_possibility_resolve")] = fun(item: *tree) { println("Running name possibility resolver?") var scope_lookup: fun(*tree, str, bool): OptionVecAst = fun(scope: *tree, name: str, is_type: bool): OptionVecAst { + /*println("doing a scope lookup for " + name + " starting from " + to_string(scope->data))*/ var to_ret = vec<*tree>() for (var i = 0; i < scope->children.size; i++;) { match(scope->children[i]->data) { @@ -267,6 +305,7 @@ fun main(argc: int, argv: **char): int { ast::_compiler_intrinsic(b) if (!is_type && b.first == name) to_ret += scope->children[i] ast::_template(b) if (((!is_type && is_function(scope->children[i]->children[0])) + || (!is_type && is_compiler_intrinsic(scope->children[i]->children[0])) || ( is_type && is_type_def(scope->children[i]->children[0])) || ( is_type && is_adt_def( scope->children[i]->children[0]))) && b.first == name) to_ret += scope->children[i] @@ -319,7 +358,7 @@ fun main(argc: int, argv: **char): int { /*_binding: triple, *tree>,*/ ast::_function(b) handle_type(b.second, t) ast::_compiler_intrinsic(b) { - /*handle_type(b.second, t)*/ + handle_type(b.second, t) b.third.for_each(fun(tb: *binding) { handle_type(tb, t) }) @@ -352,6 +391,10 @@ fun main(argc: int, argv: **char): int { } ast::_function(b) return b.second ast::_template(b) { + println("insting temp type in get_type with map") + b.second.for_each(fun(k: str, v: *binding) { + println("\t" + k + ": " + to_string(v->bound_to)) + }) return inst_temp_type(get_type(a->children[0]), b.second.associate(fun(k: str, v: *binding): pair<*binding, *binding> return make_pair(v, binding_p(type::_unknown()));)) } ast::_compiler_intrinsic(b) return b.second @@ -375,7 +418,7 @@ fun main(argc: int, argv: **char): int { error("Trying to get type of node without one: " + to_string(a->data)) } - // resolves all binding possibilities for one top level item + // resolves all binding possibilities to a single one for one top level item passes[str("name_type_resolve")] = fun(item: *tree) { if !pass_poset.done(make_pair(item, str("name_possibility_resolve"))) { pass_poset.add_open_dep(make_pair(item, str("name_type_resolve")), make_pair(item, str("name_possibility_resolve"))) @@ -390,13 +433,17 @@ fun main(argc: int, argv: **char): int { ast::_declaration() if (t->children.size > 1) unify(get_type(t->children[0]), get_type(t->children[1])) ast::_call() { + println("traverse_for_unify call - " + to_string(t->data)) // we call get type to make sure if it is unknown it is transformed into a function version get_type(t) + println("\tpast first get_type") var fun_type = get_type(t->children[0])->bound_to + println("\tpast second get_type") if (!is_fun(fun_type)) error("trying to call not a function type: " + to_string(fun_type)) if (fun_type->_fun.first.first.size != (t->children.size - 1)) error("trying to call function with type wrong number of params (" + to_string(fun_type->_fun.first.first.size) + " vs " + to_string(t->children.size - 1) + "): " + to_string(fun_type)) + println("\titerating through children, matching their type with the param type") for (var i = 1; i < t->children.size; i++;) unify(fun_type->_fun.first.first[i-1], get_type(t->children[i])) } @@ -527,7 +574,8 @@ fun main(argc: int, argv: **char): int { return taken_names[x] var possible = str() match(x->data) { - ast::_identifier(b) { possible = b.first; } + /*ast::_identifier(b) { possible = b.first; }*/ + ast::_identifier(b) { return b.first; } ast::_type_def(b) { possible = b; } ast::_function(b) { possible = b.first; } } @@ -612,7 +660,7 @@ fun main(argc: int, argv: **char): int { // but not in the case where this is a templated type instead of a function - that doesn't make any sense var binding_type = null>() - if is_function(bound_to->children[0]) { + if is_function(bound_to->children[0]) || is_compiler_intrinsic(bound_to->children[0]) { // unify in both cases - we need it in the explicit case to make sure our explicit types propegate back binding_type = get_type(t) unify(binding_type, inst_temp_type(get_type(bound_to->children[0]), inst_map)) @@ -675,9 +723,9 @@ fun main(argc: int, argv: **char): int { pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(bound_to->parent, str("emit_C"))) } // bound_to might have changed from binding - if !is_type_def(get_ast_binding(t)) { - resolve_type(get_type(t)) - } + /*if !is_type_def(get_ast_binding(t)) {*/ + /*resolve_type(get_type(t))*/ + /*}*/ } ast::_identifier(p) resolve_type(get_type(t)) ast::_function(p) resolve_type(get_type(t)) diff --git a/stdlib/type2.krak b/stdlib/type2.krak index c7463f9..9f7907b 100644 --- a/stdlib/type2.krak +++ b/stdlib/type2.krak @@ -29,6 +29,7 @@ adt type { } fun unify(t1: *binding, t2: *binding) { + println("attempting to unify " + to_string(t1->bound_to) + " and " + to_string(t2->bound_to)) if (is_unknown(t1->bound_to)) { t1->set(t2->bound_to) } else if (is_unknown(t2->bound_to)) { @@ -41,16 +42,45 @@ fun unify(t1: *binding, t2: *binding) { unify(t1->bound_to->_fun.first.first[i], t2->bound_to->_fun.first.first[i]) } else if (is_ptr(t1->bound_to)) { unify(t1->bound_to->_ptr, t2->bound_to->_ptr) + } else if (is_obj(t1->bound_to)) { + for (var i = 0; i < t1->bound_to->_obj->data._binding.second.size; i++;) { + unify(t1->bound_to->_obj->data._binding.second[i], t2->bound_to->_obj->data._binding.second[i]) + } } } else { error("Doesn't typecheck! Attempted to unify " + to_string(t1->bound_to) + " and " + to_string(t2->bound_to)) } } } +fun shallow_equality(a: *type, b: *type):bool { + if (is_ptr(a) != is_ptr(b)) + return false + if (is_ptr(a) && is_ptr(b)) + return true + match(*a) { + type::_fun(x) { + return is_fun(b) && a->_fun.third == b->_fun.third + } + type::_obj(x) { + return is_obj(b) && (get_ast_binding(x) == get_ast_binding(b->_obj) || ((!ast_bound(x) || !ast_bound(b->_obj)) + && x->data._binding.second.size == b->_obj->data._binding.second.size + && x->data._binding.first == b->_obj->data._binding.first)) + } + } + return *a == *b +} fun inst_temp_type(t: *binding, replacements: ref map<*binding, *binding>): *binding { + println("inst_temp_type " + to_string(t->bound_to)) match (*t->bound_to) { type::_unknown() error("Unknown in temp type") + type::_obj(o) { + var binding_types = o->data._binding.second.map(fun(b: *binding): *binding return inst_temp_type(b, replacements);) + for (var i = 0; i < o->data._binding.second.size; i++;) { + if (o->data._binding.second[i] != binding_types[i]) + return binding_p(type::_obj(_binding(o->data._binding.first, binding_types, o->data._binding.third))) + } + } type::_ptr(p) { var cp = inst_temp_type(p, replacements) if (cp == p) @@ -82,9 +112,23 @@ fun inst_temp_type(t: *binding, replacements: ref map<*binding, *bin } fun equality(a: *type, b: *type, count_unknown_as_equal: bool): bool { + println("equality of " + to_string(a) + " and " + to_string(b)) if (count_unknown_as_equal && (is_unknown(a) || is_unknown(b))) return true match(*a) { + type::_obj(x) { + if (!is_obj(b)) + return false + if (get_ast_binding(x) == get_ast_binding(b->_obj)) + return true + if (!count_unknown_as_equal || (ast_bound(x) && ast_bound(b->_obj)) || x->data._binding.first != b->_obj->data._binding.first || x->data._binding.second.size != b->_obj->data._binding.second.size) + return false + for (var i = 0; i < x->data._binding.second.size; i++;) { + if (!equality(x->data._binding.second[i]->bound_to, b->_obj->data._binding.second[i]->bound_to, count_unknown_as_equal)) + return false + } + return true + } type::_ptr(p) { if (!is_ptr(b)) return false @@ -110,21 +154,6 @@ fun equality(a: *type, b: *type, count_unknown_as_equal: bool): bool { } return *a == *b } -fun shallow_equality(a: *type, b: *type):bool { - if (is_ptr(a) != is_ptr(b)) - return false - if (is_ptr(a) && is_ptr(b)) - return true - match(*a) { - type::_fun(x) { - return is_fun(b) && a->_fun.third == b->_fun.third - } - type::_obj(x) { - return is_obj(b) && get_ast_binding(x) == get_ast_binding(b->_obj) - } - } - return *a == *b -} fun to_string(it: *type): str { match (*it) { type::_unknown() return str("_unknown")