From 2bc9ce497b58396cd61c28b25b90283a0232f0bb Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sat, 13 Jul 2019 18:01:04 -0400 Subject: [PATCH] FINALLY FIXED THE PROBLEM - was using set instead of set_single, so it set it's child as well, causing the type loop. Also, the binding replace child evaluated the parameters first, changing t's parent before t->parent->replace_child happened --- .gitignore | 3 + k.krak | 159 ++++++++++++++++++++++++++++++++------------ stdlib/ast.krak | 28 ++++++-- stdlib/binding.krak | 5 ++ stdlib/tree.krak | 2 + stdlib/type2.krak | 31 +++++---- 6 files changed, 166 insertions(+), 62 deletions(-) diff --git a/.gitignore b/.gitignore index 7b5bbd2..f69c238 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,9 @@ stats *.swn *.swo *.swl +*.swi +*.swj +*.swk *.png *krakout* kraklist.txt diff --git a/k.krak b/k.krak index b29b9a7..7a46f02 100644 --- a/k.krak +++ b/k.krak @@ -299,7 +299,7 @@ fun main(argc: int, argv: **char): int { // 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(), binding_epoch::pre_ref()));) var new_ident_type = inst_temp_type(ident->data._identifier.second, name_map_pair.second.associate(fun(n: str, t: *binding): pair<*binding, *binding> - return make_pair(t, new_template_type_map[n]);), binding_epoch::pre_ref()) + return make_pair(t, new_template_type_map[n]);), binding_epoch::pre_ref(), binding_epoch::pre_ref()) var type_def_binding = make_ast_binding(name, new_template_type_map.values) // do we need to set the binding to the template? @@ -331,7 +331,7 @@ fun main(argc: int, argv: **char): int { return make_pair(v, inst_with[i]) else return make_pair(v, binding_p(type::_unknown(), epoch)) - }), binding_epoch::pre_ref()) + }), binding_epoch::pre_ref(), binding_epoch::pre_ref()) } match(a->data) { ast::_identifier(b) return b.second @@ -674,22 +674,53 @@ fun main(argc: int, argv: **char): int { pass_poset.add_open_dep(make_pair(item, str("ref_lower")), make_pair(item, str("name_type_resolve"))) return } - var parameter_update_map = map<*tree, *tree>() + /*var parameter_update_map = map<*tree, *tree>()*/ + var parameter_update_set = set<*tree>() var traverse_for_ref: fun(*tree): void = fun(t: *tree) { match (t->data) { ast::_function(name_type_ext) { var fun_type = get_type(t, binding_epoch::pre_ref()) + var need_fun_type_replacement = false + println("very before, function is " + to_string(t->data)) for (var i = 0; i < fun_type->get_bound_to(binding_epoch::pre_ref())->_fun.first.first.size; i++;) { if fun_type->get_bound_to(binding_epoch::pre_ref())->_fun.first.first[i].first == ref_type::_ref() { var old_param = t->children[i] - println("function definition has refs - " + old_param->data._identifier.first) - var new_param = _identifier(old_param->data._identifier.first, binding_p(type::_ptr(old_param->data._identifier.second), binding_epoch::pre_ref())) - parameter_update_map[old_param] = new_param - t->set_child(i, new_param) + /*get_type(old_param, binding_epoch::post_ref())->set(type::_ptr(binding(get_type(old_param, binding_epoch::post_ref())->get_bound_to(binding_epoch::pre_ref()), binding_epoch::post_ref())), binding_epoch::post_ref())*/ + /*get_type(old_param, binding_epoch::post_ref())->set(type::_ptr(binding(get_type(old_param, binding_epoch::pre_ref())->get_bound_to(binding_epoch::pre_ref()), binding_epoch::post_ref())), binding_epoch::post_ref())*/ + /*get_type(old_param, binding_epoch::post_ref())->set(type::_ptr(binding(get_type(old_param, binding_epoch::post_ref())->get_bound_to(binding_epoch::post_ref()), binding_epoch::post_ref())), binding_epoch::post_ref())*/ + var old_type = get_type(old_param, binding_epoch::post_ref()) + var new_type = type::_ptr(binding(get_type(old_param, binding_epoch::post_ref())->get_bound_to(binding_epoch::post_ref()), binding_epoch::all())) + println("for a param " + to_string(old_param->data) + " setting old_type " + binding_deref_to_string(old_type) + " to " + to_string(&new_type)) + /*old_type->set(new_type, binding_epoch::post_ref())*/ + old_type->set_single(new_type, binding_epoch::post_ref()) + parameter_update_set.add(old_param) + /*println("ok, all together now, old_param is " + to_string(old_param->data))*/ + /*println("note now the type: " + binding_deref_to_string(get_type(old_param, binding_epoch::post_ref())))*/ + /*println("note now the type: " + to_string(get_type(old_param, binding_epoch::post_ref())))*/ + need_fun_type_replacement = true } } + /*println("after params, function is " + to_string(t->data))*/ + /*if fun_type->get_bound_to(binding_epoch::pre_ref())->_fun.first.second.first == ref_type::_ref() {*/ + /*fun_type->get_bound_to(binding_epoch::pre_ref())->_fun.first.second.second->set(*/ + /*type::_ptr(binding(fun_type->get_bound_to(binding_epoch::pre_ref())->_fun.first.second.second->get_bound_to(binding_epoch::pre_ref()), binding_epoch::post_ref())),*/ + /*binding_epoch::post_ref())*/ + /*need_fun_type_replacement = true*/ + /*}*/ + println("about to after return") + println("after return, function is " + to_string(t->data)) + if need_fun_type_replacement { + println("before, function is " + to_string(t->data)) + var new_fun_type = type::_fun(fun_type->get_bound_to(binding_epoch::pre_ref())->_fun) + for (var i = 0; i < new_fun_type._fun.first.first.size; i++;) + new_fun_type._fun.first.first[i].first = ref_type::_notref() + new_fun_type._fun.first.second.first = ref_type::_notref() + get_type(t, binding_epoch::post_ref())->set(new_fun_type, binding_epoch::post_ref()) + println("finally, function is " + to_string(t->data)) + } } ast::_call(add_scope) { + t->children.for_each(traverse_for_ref) println("traverse_for_ref call - " + to_string(t->data)) // we call get type to make sure if it is unknown it is transformed into a function version var fun_type = get_type(t->children[0], binding_epoch::pre_ref())->get_bound_to(binding_epoch::pre_ref()) @@ -698,44 +729,62 @@ fun main(argc: int, argv: **char): int { if fun_type->_fun.first.first[i-1].first == ref_type::_ref() { println(str("\t\tparam ") + i + " is reffed") var addr_of_binding = make_ast_binding("op&") - set_single_ast_binding(addr_of_binding, primitive_ops[str("op&")].last(), binding_epoch::pre_ref()) - unify(get_type(addr_of_binding, binding_epoch::pre_ref())->get_bound_to(binding_epoch::pre_ref())->_fun.first.first[0].second, get_type(t->children[i], binding_epoch::pre_ref()), binding_epoch::pre_ref()) + set_single_ast_binding(addr_of_binding, primitive_ops[str("op&")].last(), binding_epoch::post_ref()) + unify(get_type(addr_of_binding, binding_epoch::post_ref())->get_bound_to(binding_epoch::post_ref())->_fun.first.first[0].second, get_type(t->children[i], binding_epoch::post_ref()), binding_epoch::post_ref()) t->set_child(i, _call(false, vec(addr_of_binding, t->children[i]))) } } if fun_type->_fun.first.second.first == ref_type::_ref() { println("call's return is reffed!") var addr_of_binding = make_ast_binding("op*") - set_single_ast_binding(addr_of_binding, primitive_ops[str("op*")].last(), binding_epoch::pre_ref()) - unify(get_type(addr_of_binding, binding_epoch::pre_ref())->get_bound_to(binding_epoch::pre_ref())->_fun.first.first[0].second, binding_p(type::_ptr(fun_type->_fun.first.second.second), binding_epoch::pre_ref()), binding_epoch::pre_ref()) + set_single_ast_binding(addr_of_binding, primitive_ops[str("op*")].last(), binding_epoch::post_ref()) + /*unify(get_type(addr_of_binding, binding_epoch::pre_ref())->get_bound_to(binding_epoch::pre_ref())->_fun.first.first[0].second, binding_p(type::_ptr(fun_type->_fun.first.second.second), binding_epoch::pre_ref()), binding_epoch::pre_ref())*/ + + + // one intentional pre_ref - we don't know that the function's already had the transformation happen + unify(get_type(addr_of_binding, binding_epoch::post_ref())->get_bound_to(binding_epoch::post_ref())->_fun.first.first[0].second, + binding_p(type::_ptr(binding(fun_type->_fun.first.second.second->get_bound_to(binding_epoch::pre_ref()), binding_epoch::post_ref())), binding_epoch::post_ref()), + binding_epoch::post_ref()) // BUG IN kraken compiler, or weird part of kraken itself - evaluation order isn't guarenteed, so evaling a param could change lhs /*t->parent->replace_child(t, _call(false, vec(addr_of_binding, t)))*/ var parent = t->parent parent->replace_child(t, _call(false, vec(addr_of_binding, t))) } + return; } ast::_binding(b) { var bound_to = get_ast_binding(t, binding_epoch::pre_ref()) - if parameter_update_map.contains_key(bound_to) { + if parameter_update_set.contains(bound_to) { println("param binding is reffed") - var new_param = parameter_update_map[bound_to] + println("bound to is " + to_string(bound_to->data)) + println("other bound to is " + to_string(get_ast_binding(t, binding_epoch::post_ref())->data)) var addr_of_binding = make_ast_binding("op*") - set_single_ast_binding(addr_of_binding, primitive_ops[str("op*")].last(), binding_epoch::pre_ref()) - unify(get_type(addr_of_binding, binding_epoch::pre_ref())->get_bound_to(binding_epoch::pre_ref())->_fun.first.first[0].second, get_type(new_param, binding_epoch::pre_ref()), binding_epoch::pre_ref()) - t->parent->replace_child(t, _call(false, vec(addr_of_binding, new_param))) + set_single_ast_binding(addr_of_binding, primitive_ops[str("op*")].last(), binding_epoch::post_ref()) + unify( + get_type(addr_of_binding, binding_epoch::post_ref())->get_bound_to(binding_epoch::post_ref())->_fun.first.first[0].second, + get_type(bound_to, binding_epoch::post_ref()), + binding_epoch::post_ref()) + println("param binding is reffed - parent tree is ") + var t_parent = t->parent; + /*t->parent->replace_child(t, _call(false, vec(addr_of_binding, t)))*/ + t_parent->replace_child(t, _call(false, vec(addr_of_binding, t))) } } ast::_return() { + t->children.for_each(traverse_for_ref) if (t->children.size > 0) { var ret_is_ref = get_type(get_ancestor_satisfying(t, fun(t: *tree): bool return is_function(t);), binding_epoch::pre_ref())->get_bound_to(binding_epoch::pre_ref())->_fun.first.second.first == ref_type::_ref() if ret_is_ref { println("return is reffed") + println("tree is") + print_tree(t, 1) var addr_of_binding = make_ast_binding("op&") - set_single_ast_binding(addr_of_binding, primitive_ops[str("op&")].last(), binding_epoch::pre_ref()) - unify(get_type(addr_of_binding, binding_epoch::pre_ref())->get_bound_to(binding_epoch::pre_ref())->_fun.first.first[0].second, get_type(t->children[0], binding_epoch::pre_ref()), binding_epoch::pre_ref()) + set_single_ast_binding(addr_of_binding, primitive_ops[str("op&")].last(), binding_epoch::post_ref()) + unify(get_type(addr_of_binding, binding_epoch::post_ref())->get_bound_to(binding_epoch::post_ref())->_fun.first.first[0].second, get_type(t->children[0], binding_epoch::post_ref()), binding_epoch::post_ref()) t->set_child(0, _call(false, vec(addr_of_binding, t->children[0]))) } } + return; } } t->children.for_each(traverse_for_ref) @@ -761,7 +810,8 @@ fun main(argc: int, argv: **char): int { var resolve: fun(*tree): void = fun(t: *tree) { var resolve_type: fun(*binding): void = fun(t: *binding) { match (*t->get_bound_to(binding_epoch::pre_ref())) { - type::_unknown() error("unknown in resolve_type") + /*type::_unknown() error("unknown in resolve_type")*/ + type::_unknown() { /* this can happen because we use templates for builtins that we insert in later passes */ } type::_template_placeholder() error("template_placeholder in resolve_type") type::_ptr(p) resolve_type(p) type::_obj(o) { @@ -776,7 +826,7 @@ fun main(argc: int, argv: **char): int { } match (t->data) { ast::_binding(b) { - var bound_to = get_ast_binding(t, binding_epoch::pre_ref()) + var bound_to = get_ast_binding(t, binding_epoch::post_ref()) if (is_top_level_item(bound_to)) { if (is_template(bound_to)) { if (!instantiated_map.contains_key(bound_to)) { @@ -799,15 +849,18 @@ fun main(argc: int, argv: **char): int { var binding_type = null>() 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, binding_epoch::pre_ref()) - unify(binding_type, inst_temp_type(get_type(bound_to->children[0], binding_epoch::pre_ref()), inst_map, binding_epoch::pre_ref()), binding_epoch::pre_ref()) + /*binding_type = get_type(t, binding_epoch::pre_ref())*/ + /*unify(binding_type, inst_temp_type(get_type(bound_to->children[0], binding_epoch::pre_ref()), inst_map, binding_epoch::pre_ref()), binding_epoch::pre_ref())*/ + binding_type = get_type(t, binding_epoch::post_ref()) + unify(binding_type, inst_temp_type(get_type(bound_to->children[0], binding_epoch::post_ref()), inst_map, binding_epoch::post_ref(), binding_epoch::pre_ref()), binding_epoch::post_ref()) } else { binding_type = binding_p(type::_obj(t), binding_epoch::pre_ref()) } // shouldn't cache by binding, but by all insted println("checking for prior instantiations of " + to_string(bound_to->data)) - var already_inst = instantiated_map[bound_to].filter(fun(p: pair<*binding, *tree>): bool return equality(binding_type->get_bound_to(binding_epoch::pre_ref()), p.first->get_bound_to(binding_epoch::pre_ref()), false, binding_epoch::pre_ref());) + /*var already_inst = instantiated_map[bound_to].filter(fun(p: pair<*binding, *tree>): bool return equality(binding_type->get_bound_to(binding_epoch::pre_ref()), p.first->get_bound_to(binding_epoch::pre_ref()), false, binding_epoch::pre_ref());)*/ + var already_inst = instantiated_map[bound_to].filter(fun(p: pair<*binding, *tree>): bool return equality(binding_type->get_bound_to(binding_epoch::post_ref()), p.first->get_bound_to(binding_epoch::post_ref()), false, binding_epoch::post_ref());) if (already_inst.size() > 1) { error("already inst > 1, should be impossible") } else if (already_inst.size() == 1) { @@ -816,26 +869,35 @@ fun main(argc: int, argv: **char): int { println("cached to:") print_tree(already_inst.single().second, 1) 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, binding_epoch::pre_ref()) + /*set_single_ast_binding(t, already_inst.single().second, binding_epoch::pre_ref())*/ + set_single_ast_binding(t, already_inst.single().second, binding_epoch::all()) } else { println("Copying tree to instantiate template!" + to_string(bound_to->data)) println("using inst map:") inst_map.for_each(fun(k: *binding, v: *binding) { - println("\t" + to_string(k->get_bound_to(binding_epoch::pre_ref())) + " -> " + to_string(v->get_bound_to(binding_epoch::pre_ref()))) + /*println("\t" + to_string(k->get_bound_to(binding_epoch::pre_ref())) + " -> " + to_string(v->get_bound_to(binding_epoch::pre_ref())))*/ + println("\t" + to_string(k->get_bound_to(binding_epoch::post_ref())) + " -> " + to_string(v->get_bound_to(binding_epoch::post_ref()))) }) 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, binding_epoch::pre_ref()))) + /*ast::_identifier(b) return ast::_identifier(make_pair(b.first, inst_temp_type(b.second, inst_map, binding_epoch::pre_ref())))*/ + ast::_identifier(b) return ast::_identifier(make_pair(b.first, inst_temp_type(b.second, inst_map, binding_epoch::post_ref(), binding_epoch::pre_ref()))) 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_epoch::pre_ref());), + /*b.second.map(fun(bd: *binding): *binding return inst_temp_type(bd, inst_map, binding_epoch::pre_ref());),*/ + b.second.map(fun(bd: *binding): *binding return inst_temp_type(bd, inst_map, binding_epoch::post_ref(), binding_epoch::pre_ref());), binding>())) - ast::_function(b) return ast::_function(make_triple(b.first, inst_temp_type(b.second, inst_map, binding_epoch::pre_ref()), b.third)) + /*ast::_function(b) return ast::_function(make_triple(b.first, inst_temp_type(b.second, inst_map, binding_epoch::pre_ref()), b.third))*/ + ast::_function(b) return ast::_function(make_triple(b.first, inst_temp_type(b.second, inst_map, binding_epoch::post_ref(), binding_epoch::pre_ref()), b.third)) ast::_compiler_intrinsic(b) return ast::_compiler_intrinsic(make_triple( b.first, - inst_temp_type(b.second, inst_map, binding_epoch::pre_ref()), - b.third.map(fun(bd: *binding): *binding return inst_temp_type(bd, inst_map, binding_epoch::pre_ref());))) - ast::_cast(b) return ast::ast::_cast(inst_temp_type(b, inst_map, binding_epoch::pre_ref())) - ast::_value(b) return ast::_value(make_pair(b.first, inst_temp_type(b.second, inst_map, binding_epoch::pre_ref()))) + /*inst_temp_type(b.second, inst_map, binding_epoch::pre_ref()),*/ + inst_temp_type(b.second, inst_map, binding_epoch::post_ref(), binding_epoch::pre_ref()), + /*b.third.map(fun(bd: *binding): *binding return inst_temp_type(bd, inst_map, binding_epoch::pre_ref());)))*/ + b.third.map(fun(bd: *binding): *binding return inst_temp_type(bd, inst_map, binding_epoch::post_ref(), binding_epoch::pre_ref());))) + /*ast::_cast(b) return ast::ast::_cast(inst_temp_type(b, inst_map, binding_epoch::pre_ref()))*/ + ast::_cast(b) return ast::ast::_cast(inst_temp_type(b, inst_map, binding_epoch::post_ref(), binding_epoch::pre_ref())) + /*ast::_value(b) return ast::_value(make_pair(b.first, inst_temp_type(b.second, inst_map, binding_epoch::pre_ref())))*/ + ast::_value(b) return ast::_value(make_pair(b.first, inst_temp_type(b.second, inst_map, binding_epoch::post_ref(), binding_epoch::pre_ref()))) /*_template: pair>>,*/ } return a @@ -850,14 +912,18 @@ fun main(argc: int, argv: **char): int { // save it in our insted map so we don't instantate more than once per types if is_function(bound_to->children[0]) || is_compiler_intrinsic(bound_to->children[0]) { - var binding_type2 = get_type(clone_ast_binding(t), binding_epoch::pre_ref()) - unify(binding_type2, inst_temp_type(get_type(bound_to->children[0], binding_epoch::pre_ref()), inst_map, binding_epoch::pre_ref()), binding_epoch::pre_ref()) + /*var binding_type2 = get_type(clone_ast_binding(t), binding_epoch::pre_ref())*/ + var binding_type2 = get_type(clone_ast_binding(t), binding_epoch::post_ref()) + /*unify(binding_type2, inst_temp_type(get_type(bound_to->children[0], binding_epoch::pre_ref()), inst_map, binding_epoch::pre_ref()), binding_epoch::pre_ref())*/ + unify(binding_type2, inst_temp_type(get_type(bound_to->children[0], binding_epoch::post_ref()), inst_map, binding_epoch::post_ref(), binding_epoch::pre_ref()), binding_epoch::post_ref()) instantiated_map[bound_to].add(make_pair(binding_type2, inst_copy)) } else { - instantiated_map[bound_to].add(make_pair(binding_p(type::_obj(clone_ast_binding(t)), binding_epoch::pre_ref()), inst_copy)) + /*instantiated_map[bound_to].add(make_pair(binding_p(type::_obj(clone_ast_binding(t)), binding_epoch::pre_ref()), inst_copy))*/ + instantiated_map[bound_to].add(make_pair(binding_p(type::_obj(clone_ast_binding(t)), binding_epoch::post_ref()), 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, binding_epoch::pre_ref()) + /*set_single_ast_binding(t, inst_copy, binding_epoch::pre_ref())*/ + set_single_ast_binding(t, inst_copy, binding_epoch::all()) } } else { pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(bound_to, str("emit_C"))) @@ -868,8 +934,10 @@ fun main(argc: int, argv: **char): int { } // bound_to might have changed from binding } - ast::_identifier(p) resolve_type(get_type(t, binding_epoch::pre_ref())) - ast::_function(p) resolve_type(get_type(t, binding_epoch::pre_ref())) + /*ast::_identifier(p) resolve_type(get_type(t, binding_epoch::pre_ref()))*/ + ast::_identifier(p) resolve_type(get_type(t, binding_epoch::post_ref())) + /*ast::_function(p) resolve_type(get_type(t, binding_epoch::pre_ref()))*/ + ast::_function(p) resolve_type(get_type(t, binding_epoch::post_ref())) ast::_compiler_intrinsic(p) { resolve_type(p.second) p.third.for_each(resolve_type) @@ -881,6 +949,9 @@ fun main(argc: int, argv: **char): int { t->children.for_each(resolve) } resolve(item) + + println("post depend_and_template_resolve") + print_tree(item, 1) } passes[str("defer_lower")] = fun(item: *tree) { @@ -1093,7 +1164,7 @@ fun main(argc: int, argv: **char): int { 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, binding_epoch::pre_ref())) + C_str += idt + get_c_name(get_ast_binding(t, binding_epoch::post_ref())) } ast::_type_def(b) { C_type_forward_declaration_str += "typedef struct " + get_c_name(t) + " " + get_c_name(t) + ";\n" @@ -1101,7 +1172,7 @@ fun main(argc: int, argv: **char): int { C_type_declaration_poset.add_job(t) t->children.for_each(fun(c: *tree) { C_type_declaration_str_map[t] += "\t" + to_c_type(c->children[0]->data._identifier.second) + " " + get_c_name(c->children[0]) + ";\n" - if is_obj(c->children[0]->data._identifier.second->get_bound_to(binding_epoch::pre_ref())) { + if is_obj(c->children[0]->data._identifier.second->get_bound_to(binding_epoch::post_ref())) { C_type_declaration_poset.add_open_dep(t, get_ast_binding(c->children[0]->data._identifier.second->get_bound_to(binding_epoch::post_ref())->_obj, binding_epoch::post_ref())) } }) @@ -1124,8 +1195,8 @@ fun main(argc: int, argv: **char): int { // type to remove ref and add ptr (though we do change the parameters type, // as that all happens inside the function) var beginning_str = to_c_type(return_type.second) - if (return_type.first == ref_type::_ref()) - beginning_str += "*" + /*if (return_type.first == ref_type::_ref())*/ + /*beginning_str += "*"*/ beginning_str += " " + fun_name + "(" if (!is_just_dec) C_str += beginning_str @@ -1138,8 +1209,8 @@ fun main(argc: int, argv: **char): int { } // TODO ditto about ref stuff above var parameter_type_str = to_c_type(parameter_types[i].second) - if (parameter_types[i].first == ref_type::_ref()) - parameter_type_str += "*" + /*if (parameter_types[i].first == ref_type::_ref())*/ + /*parameter_type_str += "*"*/ if (!is_just_dec) C_str += parameter_type_str + " " C_declaration_str += parameter_type_str diff --git a/stdlib/ast.krak b/stdlib/ast.krak index f880d24..5845f76 100644 --- a/stdlib/ast.krak +++ b/stdlib/ast.krak @@ -43,15 +43,33 @@ fun deref_to_string(in: *T, ts: fun(*T): str): str return str("null") else return ts(in) +fun binding_deref_to_string(b: *binding): str { + var pre = b->get_bound_to(binding_epoch::pre_ref()) + var post = b->get_bound_to(binding_epoch::post_ref()) + if pre == post { + return deref_to_string(pre) + } else { + return "pre_ref:" + deref_to_string(pre) + "/post_ref:" + deref_to_string(post) + } +} +fun binding_deref_to_string(b: *binding, ts: fun(*T): str): str { + var pre = b->get_bound_to(binding_epoch::pre_ref()) + var post = b->get_bound_to(binding_epoch::post_ref()) + if pre == post { + return deref_to_string(pre, ts) + } else { + return "pre_ref:" + deref_to_string(pre, ts) + "/post_ref:" + deref_to_string(post, ts) + } +} fun to_string(a: ref ast): str { match(a) { ast::_translation_unit(b) return str("_translation_unit(") + b + ")" ast::_import(b) return str("_import(") + to_string(b.first->data) + ")[" + str(",").join(b.second.data) + "]" - ast::_identifier(b) return str("_identifier(") + b.first + ": " + "pre_ref:" + deref_to_string(b.second->get_bound_to(binding_epoch::pre_ref())) + "/post_ref:" + deref_to_string(b.second->get_bound_to(binding_epoch::post_ref())) + ")" - ast::_binding(b) return str("_binding(") + b.first + "[" + str(",").join(b.second.map(fun(x:*binding): str { return "pre_ref:" + deref_to_string(x->get_bound_to(binding_epoch::pre_ref())) + "/post_ref:" + deref_to_string(x->get_bound_to(binding_epoch::post_ref())); })) + "]" + "-> pre_ref:" + deref_to_string(b.third->get_bound_to(binding_epoch::pre_ref()), fun(t: *tree): str return to_string(t->data);) + " /post_ref:" + deref_to_string(b.third->get_bound_to(binding_epoch::post_ref()), fun(t: *tree): str return to_string(t->data);)+ ")" + ast::_identifier(b) return str("_identifier(") + b.first + ": " + binding_deref_to_string(b.second) + ")" + ast::_binding(b) return str("_binding(") + b.first + "[" + str(",").join(b.second.map(fun(x:*binding): str { return binding_deref_to_string(x); })) + "]" + "-> " + binding_deref_to_string(b.third, fun(t: *tree): str return to_string(t->data);) + ")" ast::_type_def(b) return str("_type_def(") + b + ")" ast::_adt_def(b) return str("_adt_def(") + b + ")" - ast::_function(b) return str("_function(") + b.first + ": " + "pre_ref:" + deref_to_string(b.second->get_bound_to(binding_epoch::pre_ref())) + "/post_ref:" + deref_to_string(b.second->get_bound_to(binding_epoch::post_ref())) + ", ext?:" + to_string(b.third) + ")" + ast::_function(b) return str("_function(") + b.first + ": " + binding_deref_to_string(b.second) + ", ext?:" + to_string(b.third) + ")" ast::_template(b) return str("_template(") + b.first + "[" + str(",").join(b.second.keys) + "])" ast::_declaration() return str("_declaration") ast::_block() return str("_block") @@ -65,9 +83,9 @@ fun to_string(a: ref ast): str { ast::_continue() return str("_continue") ast::_defer() return str("_defer") ast::_call(b) return "_call(add_scope: " + to_string(b) + ")" - ast::_compiler_intrinsic(b) return str("_compiler_intrinsic(") + b.first + ": " + "pre_ref:" + deref_to_string(b.second->get_bound_to(binding_epoch::pre_ref())) + "/post_ref:" + deref_to_string(b.second->get_bound_to(binding_epoch::post_ref())) + ")" + ast::_compiler_intrinsic(b) return str("_compiler_intrinsic(") + b.first + ": " + binding_deref_to_string(b.second) + ")" ast::_cast(b) return str("_cast") - ast::_value(b) return str("_value(") + b.first + ": " + "pre_ref:" + deref_to_string(b.second->get_bound_to(binding_epoch::pre_ref())) + "/post_ref:" + deref_to_string(b.second->get_bound_to(binding_epoch::post_ref())) + ")" + ast::_value(b) return str("_value(") + b.first + ": " + binding_deref_to_string(b.second) + ")" } } fun _translation_unit(p: str): *tree { diff --git a/stdlib/binding.krak b/stdlib/binding.krak index 0203a91..c141c72 100644 --- a/stdlib/binding.krak +++ b/stdlib/binding.krak @@ -81,6 +81,11 @@ obj binding (Object) { } } } + fun set_single(to: T, epoch: binding_epoch) { + var p = new() + p->copy_construct(&to) + set_single(p, epoch) + } fun set_single(to: *T, epoch: binding_epoch) { match (epoch) { binding_epoch::pre_ref() { bound_to_pre_ref = to; } diff --git a/stdlib/tree.krak b/stdlib/tree.krak index 76af518..e33a289 100644 --- a/stdlib/tree.krak +++ b/stdlib/tree.krak @@ -1,5 +1,7 @@ import mem import vec +import io:* +import str:* obj tree (Object) { var data: T diff --git a/stdlib/type2.krak b/stdlib/type2.krak index 23bb166..e9e2b99 100644 --- a/stdlib/type2.krak +++ b/stdlib/type2.krak @@ -103,32 +103,32 @@ fun shallow_equality(a: *type, b: *type, epoch: binding_epoch):bool { return *a == *b } -fun inst_temp_type(t: *binding, replacements: ref map<*binding, *binding>, epoch: binding_epoch): *binding { - match (*t->get_bound_to(epoch)) { +fun inst_temp_type(t: *binding, replacements: ref map<*binding, *binding>, read_epoch: binding_epoch, write_epoch: binding_epoch): *binding { + match (*t->get_bound_to(read_epoch)) { 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, epoch);) + var binding_types = o->data._binding.second.map(fun(b: *binding): *binding return inst_temp_type(b, replacements, read_epoch, write_epoch);) 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)), epoch) + return binding_p(type::_obj(_binding(o->data._binding.first, binding_types, o->data._binding.third)), write_epoch) } } type::_ptr(p) { - var cp = inst_temp_type(p, replacements, epoch) + var cp = inst_temp_type(p, replacements, read_epoch, write_epoch) if (cp == p) return t else - return binding_p(type::_ptr(cp), epoch) + return binding_p(type::_ptr(cp), write_epoch) } type::_fun(b) { // triple, is_variadic, is raw> - var rt = make_pair(b.first.second.first, inst_temp_type(b.first.second.second, replacements, epoch)) - var pts = b.first.first.map(fun(pt: pair>): pair> return make_pair(pt.first, inst_temp_type(pt.second, replacements, epoch));) + var rt = make_pair(b.first.second.first, inst_temp_type(b.first.second.second, replacements, read_epoch, write_epoch)) + var pts = b.first.first.map(fun(pt: pair>): pair> return make_pair(pt.first, inst_temp_type(pt.second, replacements, read_epoch, write_epoch));) if (rt.second != b.first.second.second) - return binding_p(type::_fun(make_triple(make_pair(pts, rt), b.second, b.third)), epoch) + return binding_p(type::_fun(make_triple(make_pair(pts, rt), b.second, b.third)), write_epoch) for (var i = 0; i < pts.size; i++;) if (pts[i].second != b.first.first[i].second) - return binding_p(type::_fun(make_triple(make_pair(pts, rt), b.second, b.third)), epoch) + return binding_p(type::_fun(make_triple(make_pair(pts, rt), b.second, b.third)), write_epoch) return t } type::_template_placeholder() return replacements[t] @@ -174,11 +174,16 @@ fun equality(a: *type, b: *type, count_unknown_as_equal: bool, epoch: binding_ep } return *a == *b } +fun deref_to_string(in: *T): str + if (in == mem::null()) + return str("null") + else + return to_string(in) fun to_string(it: *type): str { match (*it) { type::_unknown() return str("_unknown") type::_void() return str("_void") - type::_ptr(p) return "* pre_ref:" + to_string(p->get_bound_to(binding_epoch::pre_ref())) + "/post_ref" + to_string(p->get_bound_to(binding_epoch::post_ref())) + type::_ptr(p) return "*(pre_ref:" + deref_to_string(p->get_bound_to(binding_epoch::pre_ref())) + "/post_ref" + deref_to_string(p->get_bound_to(binding_epoch::post_ref())) + ")" type::_obj(b) { return "_obj(" + to_string(b->data) + ")" } @@ -189,10 +194,10 @@ fun to_string(it: *type): str { to_ret += "_run(" else to_ret += "_fun(" - to_ret += str(", ").join(b.first.first.map(fun(pt: pair>): str return to_string(pt.first) + "pre_ref:" + to_string(pt.second->get_bound_to(binding_epoch::pre_ref())) + "/post_ref" + to_string(pt.second->get_bound_to(binding_epoch::post_ref()));)) + to_ret += str(", ").join(b.first.first.map(fun(pt: pair>): str return to_string(pt.first) + "(pre_ref:" + deref_to_string(pt.second->get_bound_to(binding_epoch::pre_ref())) + "/post_ref" + deref_to_string(pt.second->get_bound_to(binding_epoch::post_ref())) + ")";)) if (b.third) to_ret += " ..." - return to_ret + "): " + to_string(b.first.second.first) + "* pre_ref:" + to_string(b.first.second.second->get_bound_to(binding_epoch::pre_ref())) + "/post_ref:" + to_string(b.first.second.second->get_bound_to(binding_epoch::post_ref())) + return to_ret + "): " + to_string(b.first.second.first) + ": (pre_ref:" + deref_to_string(b.first.second.second->get_bound_to(binding_epoch::pre_ref())) + "/post_ref:" + deref_to_string(b.first.second.second->get_bound_to(binding_epoch::post_ref())) + ")" } type::_template_placeholder() return str("_template_placeholder") type::_bool() return str("_bool")