diff --git a/k.krak b/k.krak index d63a3de..746ea9d 100644 --- a/k.krak +++ b/k.krak @@ -236,41 +236,6 @@ fun main(argc: int, argv: **char): int { traverse_for_bindings(item) } - var inst_temp_type: fun(*binding, map<*binding, *binding>): *binding = fun(t: *binding, replacements: ref map<*binding, *binding>): *binding { - println("Insting type!") - - match (*t->bound_to) { - type::_unknown() error("Unknown in temp type") - type::_ptr(p) { - var cp = inst_temp_type(p, replacements) - if (cp == p) - return t - else - return binding_p(type::_ptr(cp)) - } - type::_ref(r) { - var cr = inst_temp_type(r, replacements) - if (cr == r) - return t - else - return binding_p(type::_ref(cr)) - } - type::_fun(b) { - // triple, is_variadic, is raw> - var rt = inst_temp_type(b.first.second, replacements) - var pts = b.first.first.map(fun(pt: *binding): *binding return inst_temp_type(pt, replacements);) - if (rt != b.first.second) - return binding_p(type::_fun(make_triple(make_pair(pts, rt), b.second, b.third))) - for (var i = 0; i < pts.size; i++;) - if (pts[i] != b.first.first[i]) - return binding_p(type::_fun(make_triple(make_pair(pts, rt), b.second, b.third))) - return t - } - type::_template_placeholder() return replacements[t] - } - return t - } - var binding_types = map<*tree, *binding>() var get_type: fun(*tree): *binding = fun(a: *tree): *binding { match(a->data) { @@ -319,6 +284,8 @@ fun main(argc: int, argv: **char): int { pass_poset.add_open_dep(make_pair(item, str("name_type_resolve")), make_pair(item, str("name_possibility_resolve"))) return } + println("name_type resolve for:") + print_tree(item, 1) var traverse_for_unify: fun(*tree): void = fun(t: *tree) { t->children.for_each(traverse_for_unify) @@ -523,11 +490,11 @@ fun main(argc: int, argv: **char): int { }) } ast::_import(b) { } - ast::_identifier(b) { C_str += idt + b.first; } + ast::_identifier(b) { C_str += idt + get_c_name(t); } ast::_binding(b) { var bound_to = get_ast_binding(t) if (is_top_level_item(bound_to)) { - if (is_template(bound_to) { + if (is_template(bound_to)) { if (!instantiated_map.contains_key(bound_to)) instantiated_map[bound_to] = set, *tree>>() var binding_type = get_type(t) @@ -539,22 +506,43 @@ fun main(argc: int, argv: **char): int { unify(binding_type, inst_temp_type(get_type(bound_to->children[0]), inst_map)) // shouldn't cache by binding, but by all insted - var already_inst = instantiated_map[bound_to].filter(fun(p: pair<*binding, *tree>): bool return equality(binding_type, p.first, false);) + var already_inst = instantiated_map[bound_to].filter(fun(p: pair<*binding, *tree>): bool return equality(binding_type->bound_to, p.first->bound_to, false);) if (already_inst.size() > 1) { error("already inst > 1, should be impossible") } else if (already_inst.size() == 1) { - pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(already_inst.single(), str("emit_C"))) + pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(already_inst.single().second, str("emit_C"))) + set_single_ast_binding(t, already_inst.single().second) } else { - var inst_copy = copy_ast(bound_to->children[0], TYPE_INSTING_LAMBDA?) + println("Copying tree to instantiate template!") + var inst_copy = bound_to->children[0]->clone(fun(a: ref ast): ast { + match (a) { + ast::_identifier(b) return ast::_identifier(make_pair(b.first, inst_temp_type(b.second, inst_map))) + ast::_binding(b) return ast::_binding(make_triple(b.first, + b.second.map(fun(bd: *binding): *binding return inst_temp_type(bd, inst_map);), + binding>())) + ast::_function(b) return ast::_function(make_triple(b.first, inst_temp_type(b.second, inst_map), b.third)) + ast::_compiler_intrinsic(b) return ast::_compiler_intrinsic(make_triple( + b.first, + inst_temp_type(b.second, inst_map), + b.third.map(fun(bd: *binding): *binding return inst_temp_type(bd, inst_map);))) + ast::_cast(b) return ast::ast::_cast(inst_temp_type(b, inst_map)) + ast::_value(b) return ast::_value(make_pair(b.first, inst_temp_type(b.second, inst_map))) + /*_template: pair>>,*/ + } + return a + }) // add inst copy as a child of template? + bound_to->add_child(inst_copy) - - // unify copy'd types with inst types - + println("inst from:") + print_tree(bound_to->children[0], 1) + println("inst to:") + print_tree(inst_copy, 1) // save it in our insted map so we don't instantate more than once per types instantiated_map[bound_to].add(make_pair(binding_type, inst_copy)) pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(inst_copy, str("emit_C"))) + set_single_ast_binding(t, inst_copy) } } else { pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(bound_to, str("emit_C"))) @@ -563,7 +551,8 @@ fun main(argc: int, argv: **char): int { } else if (is_identifier(bound_to) && is_declaration(bound_to->parent) && is_top_level_item(bound_to->parent)) { pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(bound_to->parent, str("emit_C"))) } - C_str += idt + get_c_name(bound_to) + // bound_to might have changed from binding + C_str += idt + get_c_name(get_ast_binding(t)) } ast::_type_def(b) { error("type_def gen unimplemented"); } ast::_adt_def(b) { error("no adt_def should remain at C emit"); } diff --git a/stdlib/ast.krak b/stdlib/ast.krak index d9277e5..cd01560 100644 --- a/stdlib/ast.krak +++ b/stdlib/ast.krak @@ -274,6 +274,15 @@ fun set_ast_binding(binding: *tree, to: *tree) { } error("trying to set binding on not a binding") } +fun set_single_ast_binding(binding: *tree, to: *tree) { + match(binding->data) { + ast::_binding(b) { + b.third->set_single(to) + return + } + } + error("trying to set binding on not a binding") +} fun ast_bound(binding: *tree): bool { match(binding->data) { ast::_binding(b) return b.third->bound() diff --git a/stdlib/binding.krak b/stdlib/binding.krak index 4be57a9..41dab92 100644 --- a/stdlib/binding.krak +++ b/stdlib/binding.krak @@ -58,6 +58,9 @@ obj binding (Object) { if ( ((bindings->get(i)) cast *binding)->bound_to == from) ((bindings->get(i)) cast *binding)->bound_to = to } + fun set_single(to: *T) { + bound_to = to + } fun to_string(): str { /*return "binding(" + to_string(bound_to) + ")"*/ return "binding(" + deref_to_string(bound_to) + ")" diff --git a/stdlib/set.krak b/stdlib/set.krak index dbde7ba..64739d5 100644 --- a/stdlib/set.krak +++ b/stdlib/set.krak @@ -57,7 +57,7 @@ obj set (Object, Serializable) { return data.size } fun single(): T { - if (size() != 1)k + if (size() != 1) util::error("trying to single with size != 1") return data[0] } diff --git a/stdlib/tree.krak b/stdlib/tree.krak index 58a85dd..e4bdf39 100644 --- a/stdlib/tree.krak +++ b/stdlib/tree.krak @@ -5,13 +5,13 @@ obj tree (Object) { var data: T var parent: *tree var children: vec::vec<*tree> - fun construct(dataIn: T): *tree { + fun construct(dataIn: ref T): *tree { mem::maybe_copy_construct(&data, &dataIn) parent = mem::null>() children.construct() return this } - fun construct(dataIn: T, c: ref vec::vec<*tree>): *tree { + fun construct(dataIn: ref T, c: ref vec::vec<*tree>): *tree { mem::maybe_copy_construct(&data, &dataIn) parent = mem::null>() children.copy_construct(&c) @@ -39,5 +39,15 @@ obj tree (Object) { mem::maybe_destruct(&data) children.destruct() } + fun add_child(c: *tree) { + children.add(c) + c->parent = this + } + fun clone(): *tree { + return mem::new>()->construct(data, children.map(fun(c: *tree): *tree return c->clone();)) + } + fun clone(f: fun(ref T): T): *tree { + return mem::new>()->construct(f(data), children.map(fun(c: *tree): *tree return c->clone(f);)) + } } diff --git a/stdlib/type2.krak b/stdlib/type2.krak index 84fc615..3c2ce69 100644 --- a/stdlib/type2.krak +++ b/stdlib/type2.krak @@ -46,6 +46,39 @@ fun unify(t1: *binding, t2: *binding) { } } +fun inst_temp_type(t: *binding, replacements: ref map<*binding, *binding>): *binding { + match (*t->bound_to) { + type::_unknown() error("Unknown in temp type") + type::_ptr(p) { + var cp = inst_temp_type(p, replacements) + if (cp == p) + return t + else + return binding_p(type::_ptr(cp)) + } + type::_ref(r) { + var cr = inst_temp_type(r, replacements) + if (cr == r) + return t + else + return binding_p(type::_ref(cr)) + } + type::_fun(b) { + // triple, is_variadic, is raw> + var rt = inst_temp_type(b.first.second, replacements) + var pts = b.first.first.map(fun(pt: *binding): *binding return inst_temp_type(pt, replacements);) + if (rt != b.first.second) + return binding_p(type::_fun(make_triple(make_pair(pts, rt), b.second, b.third))) + for (var i = 0; i < pts.size; i++;) + if (pts[i] != b.first.first[i]) + return binding_p(type::_fun(make_triple(make_pair(pts, rt), b.second, b.third))) + return t + } + type::_template_placeholder() return replacements[t] + } + return t +} + fun equality(a: *type, b: *type, count_unknown_as_equal: bool): bool { if (count_unknown_as_equal && (is_unknown(a) || is_unknown(b))) return true