From 02424543fbf5b5027e49e039c92d0041bbb2a790 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Wed, 10 Oct 2018 00:39:04 -0400 Subject: [PATCH] Explicit template function instantiation working --- k.krak | 61 ++++++++++++++++++++++++++++++++++--------------- stdlib/ast.krak | 1 + 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/k.krak b/k.krak index ddc7621..c663714 100644 --- a/k.krak +++ b/k.krak @@ -473,26 +473,14 @@ fun main(argc: int, argv: **char): int { // has to be set instead of map<> as we need to use type's "equality" // function instead of type's adt's operator== var instantiated_map = map<*tree, set, *tree>>>() - passes[str("emit_C")] = fun(item: *tree) { + passes[str("depend_and_template_resolve")] = fun(item: *tree) { if !pass_poset.done(make_pair(item, str("name_type_resolve"))) { - pass_poset.add_open_dep(make_pair(item, str("emit_C")), make_pair(item, str("name_type_resolve"))) + pass_poset.add_open_dep(make_pair(item, str("depend_and_template_resolve")), make_pair(item, str("name_type_resolve"))) return } - println("Emitting C for:") - print_tree(item, 1) - - var emit_C: fun(*tree, int): void = fun(t: *tree, level: int) { - var idt = str("\t") * level + var resolve: fun(*tree): void = fun(t: *tree) { match (t->data) { - ast::_translation_unit(b) { - t->children.for_each(fun(c: *tree) { - emit_C(c, 0) - C_str += ";\n" - }) - } - ast::_import(b) { } - ast::_identifier(b) { C_str += idt + get_c_name(t); } - ast::_binding(b) { + ast::_binding(b) { var bound_to = get_ast_binding(t) if (is_top_level_item(bound_to)) { if (is_template(bound_to)) { @@ -501,9 +489,17 @@ fun main(argc: int, argv: **char): int { var binding_type = get_type(t) // grab inst types out of binding, or regen again from unify? Cache from first unify? - // regenning from unify - var inst_map = bound_to->data._template.second.associate(fun(k: str, v: *binding): pair<*binding, *binding> - return make_pair(v, binding_p(type::_unknown()));) + var inst_map = map<*binding, *binding>() + if (b.second.size > 0) { + for (var i = 0; i < b.second.size; i++;) { + inst_map[bound_to->data._template.second.values[i]] = b.second[i] + } + } else { + // regenning from unify + inst_map = bound_to->data._template.second.associate(fun(k: str, v: *binding): pair<*binding, *binding> + return make_pair(v, binding_p(type::_unknown()));) + } + // unify in both cases - we need it in the explicit case to make sure our explicit types propegate back unify(binding_type, inst_temp_type(get_type(bound_to->children[0]), inst_map)) // shouldn't cache by binding, but by all insted @@ -557,6 +553,33 @@ 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 + } + } + t->children.for_each(resolve) + } + resolve(item) + } + + passes[str("emit_C")] = fun(item: *tree) { + if !pass_poset.done(make_pair(item, str("depend_and_template_resolve"))) { + pass_poset.add_open_dep(make_pair(item, str("emit_C")), make_pair(item, str("depend_and_template_resolve"))) + return + } + println("Emitting C for:") + print_tree(item, 1) + + var emit_C: fun(*tree, int): void = fun(t: *tree, level: int) { + var idt = str("\t") * level + match (t->data) { + ast::_translation_unit(b) { + t->children.for_each(fun(c: *tree) { + emit_C(c, 0) + C_str += ";\n" + }) + } + ast::_import(b) { } + ast::_identifier(b) { C_str += idt + get_c_name(t); } + ast::_binding(b) { C_str += idt + get_c_name(get_ast_binding(t)) } ast::_type_def(b) { error("type_def gen unimplemented"); } diff --git a/stdlib/ast.krak b/stdlib/ast.krak index cd01560..5c010e4 100644 --- a/stdlib/ast.krak +++ b/stdlib/ast.krak @@ -15,6 +15,7 @@ adt ast { _type_def: str, _adt_def: str, _function: triple, bool>, + // needs to be a map that retains order _template: pair>>, _declaration, _block,