From ed57d2b2a970fa97861c068875b474eabb3860c0 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sat, 29 Dec 2018 16:35:47 -0500 Subject: [PATCH] Added sizeof and fixed inferencing from explicitly instantiated template functions so that new and delete work! (though not traits yet...) --- k.krak | 49 ++++++++++++++++++++++++++++++++++++++++++----- stdlib/type2.krak | 10 ++++++++++ 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/k.krak b/k.krak index 1c244b0..ac3132b 100644 --- a/k.krak +++ b/k.krak @@ -323,13 +323,40 @@ fun main(argc: int, argv: **char): int { var binding_types = map<*tree, *binding>() var get_type: fun(*tree): *binding = fun(a: *tree): *binding { + var get_template_type: fun(*tree, vec<*binding>): *binding = fun(a: *tree, inst_with: vec<*binding>): *binding { + var i = 0 + return inst_temp_type(get_type(a->children[0]), a->data._template.second.associate(fun(k: str, v: *binding): pair<*binding, *binding> { + if (i < inst_with.size) + return make_pair(v, inst_with[i]) + else + return make_pair(v, binding_p(type::_unknown())) + })) + } match(a->data) { ast::_identifier(b) return b.second ast::_binding(b) if (binding_types.contains_key(a)) { + if ast_bound(a) && has_unknown(binding_types[a]) { + var t = null>() + var bound_to = get_ast_binding(a) + if (is_template(bound_to)) { + t = get_template_type(bound_to, b.second) + unify(binding_types[a], t) + } else { + t = get_type(bound_to) + unify(binding_types[a], t) + } + } return binding_types[a] } else { if (ast_bound(a)) { - var t = get_type(get_ast_binding(a)) + var t = null>() + var bound_to = get_ast_binding(a) + if (is_template(bound_to)) { + t = get_template_type(bound_to, b.second) + } else { + t = get_type(bound_to) + } + /*var t = get_type(get_ast_binding(a))*/ binding_types[a] = t return t } else { @@ -339,9 +366,7 @@ fun main(argc: int, argv: **char): int { } } ast::_function(b) return b.second - ast::_template(b) { - 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::_template(b) return get_template_type(a, vec<*binding>()) ast::_compiler_intrinsic(b) return b.second ast::_call(add_scope) { var t = get_type(a->children[0]) @@ -623,6 +648,8 @@ fun main(argc: int, argv: **char): int { if (filtered_options.size > 1) { println("Attempting to use our inferenced type " + to_string(binding_types[t]->bound_to) + " to decide what to bind " + to_string(t->data) + " to form options:") multiple_binding_options[t].for_each(fun(p: *tree) { println("\t" + to_string(p->data) + " of type " + to_string(get_type(p)->bound_to)); }) + println("current state of this:") + print_tree(item, 1) println("too many options remain after filtering overloads by type for " + to_string(t->data) + ", they were:") filtered_options.for_each(fun(p: *tree) { println("\t" + to_string(p->data) + " of type " + to_string(get_type(p)->bound_to)); }) error("cannot resolve") @@ -1159,7 +1186,13 @@ fun main(argc: int, argv: **char): int { C_str += ")" } } - ast::_compiler_intrinsic(b) { /* this can happen cuz of templated primitive ops and is_top_level_item includes parentless stuff...*/ } + ast::_compiler_intrinsic(b) { + if b.first == "sizeof" { + C_str += "sizeof(" + to_c_type(b.third[0]) + ")" + } else { + /* this can happen cuz of templated primitive ops and is_top_level_item includes parentless stuff...*/ + } + } ast::_cast(b) { C_str += idt + "((" + to_c_type(b) + ")" emit_C(t->children[0], 0) @@ -1513,6 +1546,12 @@ fun syntax_to_ast(file_name: str, syntax: *tree, import_paths: ref vecdata.name == "cast_expression") { return _cast(parse_type(get_node("type", syntax), declared_template_types), vec(syntax_to_ast_helper(syntax->children[0], declared_template_types))) + } else if (syntax->data.name == "compiler_intrinsic") { + var name = concat(get_node("identifier", syntax)) + if name != "sizeof" { + error("unknown compiler intrinsic " + name) + } + return _compiler_intrinsic(name, binding_p(type::_ulong()), vec(parse_type(get_node("type", syntax), declared_template_types))) } else if (syntax->data.name == "number") { var number_string = concat(syntax) if (number_string.contains('.')) diff --git a/stdlib/type2.krak b/stdlib/type2.krak index 8ffc5a5..c9763c5 100644 --- a/stdlib/type2.krak +++ b/stdlib/type2.krak @@ -40,6 +40,16 @@ adt type { _double } +fun has_unknown(t: *binding): bool { + match (*t->bound_to) { + type::_unknown() return true + type::_ptr(p) return has_unknown(p) + type::_obj(o) return o->data._binding.second.any_true(fun(inner_t: *binding): bool return has_unknown(inner_t);) + type::_fun(f) return has_unknown(f.first.second.second) || f.first.first.any_true(fun(p: pair>): bool return has_unknown(p.second);) + } + return false +} + 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)) {