diff --git a/k.krak b/k.krak index 55893f8..31fa8b6 100644 --- a/k.krak +++ b/k.krak @@ -280,7 +280,7 @@ fun main(argc: int, argv: **char): int { 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 - ast::_call() { + ast::_call(add_scope) { var t = get_type(a->children[0]) if (is_fun(t->bound_to)) return t->bound_to->_fun.first.second @@ -365,33 +365,57 @@ fun main(argc: int, argv: **char): int { to_ret += primitive_ops[name] return OptionVecAst::Some(to_ret) } - var try_to_find_binding_possibilities = fun(binding: *tree, start_scope: *tree, type_binding: bool) { + var try_to_find_binding_possibilities = fun(binding: *tree, start_scope: *tree, additional_scope: *tree, type_binding: bool): bool { if !ast_bound(binding) && !multiple_binding_options.contains_key(binding) { + var all_options = vec<*tree>() match (scope_lookup(start_scope, ast_binding_str(binding), type_binding)) { OptionVecAst::None() { println("OptionVecAst::None for " + ast_binding_str(binding) + " lookup, returning") - return; + return false; } OptionVecAst::Some(options) { println("OptionVecAst::Some for " + ast_binding_str(binding) + " lookup, continuing!") - if (options.size == 0) - error("Could not find any options for scope lookup of " + ast_binding_str(binding)) - else if (options.size == 1) - set_ast_binding(binding, options[0]) - else - multiple_binding_options[binding] = options + all_options += options } } + if additional_scope != null>() { + println("Additionally looking at scope " + to_string(additional_scope->data) + " for try_to_find_binding_possibilities " + ast_binding_str(binding)) + match (scope_lookup(additional_scope, ast_binding_str(binding), type_binding)) { + OptionVecAst::None() { + println("OptionVecAst::None for " + ast_binding_str(binding) + " lookup, returning") + return false; + } + OptionVecAst::Some(options) { + println("OptionVecAst::Some for " + ast_binding_str(binding) + " lookup, continuing!") + all_options.add_all_unique(options) + } + } + } + if (all_options.size == 0) { + error("Could not find any options for scope lookup of " + ast_binding_str(binding)) + } else if (all_options.size == 1) { + println(ast_binding_str(binding) + " resolved to a single!") + set_ast_binding(binding, all_options[0]) + } else { + println(ast_binding_str(binding) + " found to have " + all_options.size + " options!") + for (var i = 0; i < all_options.size; i++;) + println("\t" + to_string(all_options[i]->data)) + multiple_binding_options[binding] = all_options + } + return true; } } - var handle_type_binding_possibilities: fun(*binding, *tree): void = fun(t: *binding, n: *tree) { + var handle_type_binding_possibilities: fun(*binding, *tree): bool = fun(t: *binding, n: *tree): bool { match(*t->bound_to) { - type::_obj(b) try_to_find_binding_possibilities(b, n, true) + type::_obj(b) return try_to_find_binding_possibilities(b, n, null>(), true) type::_fun(b) { - b.first.first.for_each(fun(it: *binding) { - handle_type_binding_possibilities(it, n) - }) - handle_type_binding_possibilities(b.first.second, n) + /*b.first.first.for_each(fun(it: *binding) {*/ + /*handle_type_binding_possibilities(it, n)*/ + /*})*/ + for (var i = 0; i < b.first.first.size; i++;) + if (!handle_type_binding_possibilities(b.first.first[i], n)) + return false + return handle_type_binding_possibilities(b.first.second, n) } } } @@ -401,7 +425,7 @@ fun main(argc: int, argv: **char): int { match (t->data) { ast::_declaration() if (t->children.size > 1) unify(get_type(t->children[0]), get_type(t->children[1])) - ast::_call() { + ast::_call(add_scope) { 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) @@ -424,40 +448,72 @@ fun main(argc: int, argv: **char): int { var more_to_do = true while (more_to_do) { + println("RESOLVE LOOP BEGIN") more_to_do = false var work_done = false var traverse_for_select: fun(*tree): bool = fun(t: *tree): bool { + var children_start_index = 0 match (t->data) { - - ast::_identifier(b) handle_type_binding_possibilities(b.second, t) + ast::_identifier(b) if (!handle_type_binding_possibilities(b.second, t)) + return false; /*_binding: triple, *tree>,*/ - ast::_function(b) handle_type_binding_possibilities(b.second, t) + ast::_function(b) if (!handle_type_binding_possibilities(b.second, t)) + return false; ast::_compiler_intrinsic(b) { - handle_type_binding_possibilities(b.second, t) - b.third.for_each(fun(tb: *binding) { - handle_type_binding_possibilities(tb, t) - }) + if (!handle_type_binding_possibilities(b.second, t)) + return false; + for (var i = 0; i < b.third.size; i++;) + if (!handle_type_binding_possibilities(b.third[i], t)) + return false; + /*b.third.for_each(fun(tb: *binding) {*/ + /*handle_type_binding_possibilities(tb, t)*/ + /*})*/ + } + ast::_cast(b) if (!handle_type_binding_possibilities(b, t)) + return false + ast::_call(add_scope) { + println("call of " + to_string(t->children[0]) + ", that is " + to_string(t->children[0]->data) + " has type " + to_string(get_type(t)->bound_to) + ", and the function has type " + to_string(get_type(t->children[0])->bound_to)) + /*get_type(t)*/ + if add_scope && is_binding(t->children[0]) && !ast_bound(t->children[0]) && !multiple_binding_options.contains_key(t->children[0]) { + var first_param_type = get_type(t->children[1]) + if !is_unknown(first_param_type->bound_to) && (!is_obj(first_param_type->bound_to) || ast_bound(first_param_type->bound_to->_obj)) { + if is_obj(first_param_type->bound_to) { + if (!try_to_find_binding_possibilities(t->children[0], t->children[0], get_ast_binding(first_param_type->bound_to->_obj)->parent, false)) + return false; + } else { + if (!try_to_find_binding_possibilities(t->children[0], t->children[0], null>(), false)) + return false + } + work_done = true + println("wok done! generic add posibilities (or down to one) for " + to_string(t->children[0]->data)) + if ast_bound(t->children[0]) { + unify(binding_types[t->children[0]], get_type(get_ast_binding(t->children[0]))) + } + } else { + children_start_index = 1 + more_to_do = true + } + } } - ast::_cast(b) handle_type_binding_possibilities(b, t) ast::_binding(b) if (!ast_bound(t)) { println(to_string(t->data) + " - not bound!") if !multiple_binding_options.contains_key(t) { - try_to_find_binding_possibilities(t, t, false) + if (!try_to_find_binding_possibilities(t, t, null>(), false)) + return false } if ast_bound(t) { unify(binding_types[t], get_type(get_ast_binding(t))) + work_done = true + println("wok done! set " + to_string(t->data)) } else { - if !multiple_binding_options.contains_key(t) { - println(" must have added a pass! going around the horn again... before") - return false; - } var filtered_options = multiple_binding_options[t].filter(fun(p: *tree): bool return equality(binding_types[t]->bound_to, get_type(p)->bound_to, true);) if (filtered_options.size == 0) { println("Attempting to use our inferenced type " + to_string(binding_types[t]->bound_to) + " to decide what to bind " + to_string(t->data) + " to from 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)); }) error("no options remain after filtering overloads by type for " + to_string(t->data)) } else if (filtered_options.size > 1) { + println("inferenced type " + to_string(binding_types[t]->bound_to) + " HAD MULTIPLE OPTIONS AFTER FILTER for " + to_string(t) + ", that is "+ to_string(t->data)) more_to_do = true } else { set_ast_binding(t, filtered_options[0]) @@ -468,7 +524,7 @@ fun main(argc: int, argv: **char): int { } } } - for (var i = 0; i < t->children.size; i++;) { + for (var i = children_start_index; i < t->children.size; i++;) { if !traverse_for_select(t->children[i]) { return false } @@ -483,6 +539,7 @@ fun main(argc: int, argv: **char): int { var traverse_for_error: fun(*tree): void = fun(t: *tree) { match (t->data) { ast::_binding(b) if (!ast_bound(t)) { + println("Trying to error out because we made no progress") var filtered_options = multiple_binding_options[t].filter(fun(p: *tree): bool return equality(binding_types[t]->bound_to, get_type(p)->bound_to, true);) 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:") @@ -883,7 +940,7 @@ fun main(argc: int, argv: **char): int { ast::_break() { C_str += idt + "break"; } ast::_continue() { C_str += idt + "continue"; } ast::_defer() { error("no defer should remain at C emit"); } - ast::_call() { + ast::_call(add_scope) { if (is_compiler_intrinsic(get_ast_binding(t->children[0]))) { if (t->children.size == 2) { var intrinsic_name = get_ast_binding(t->children[0])->data._compiler_intrinsic.first @@ -940,7 +997,7 @@ fun main(argc: int, argv: **char): int { true, vec( _identifier(str("argc"), binding_p(type::_int())), _identifier(str("argv"), binding_p(type::_ptr(binding_p(type::_ptr(binding_p(type::_char())))))), - _return(vec(_call(vec(make_ast_binding("fmain"), make_ast_binding("argc"), make_ast_binding("argv"))))) + _return(vec(_call(false, vec(make_ast_binding("fmain"), make_ast_binding("argc"), make_ast_binding("argv"))))) ) ) var top_unit = _translation_unit(str(), vec( @@ -1175,27 +1232,28 @@ fun syntax_to_ast(file_name: str, syntax: *tree, import_paths: ref vec): *tree return syntax_to_ast_helper(x, declared_template_types);) return _declaration(children) } else if (syntax->data.name == "assignment_statement") { - return _call(vec(make_ast_binding("op" + concat(syntax->children[1])), + return _call(false, vec(make_ast_binding("op" + concat(syntax->children[1])), syntax_to_ast_helper(syntax->children[0], declared_template_types), syntax_to_ast_helper(syntax->children[2], declared_template_types))) } else if (syntax->data.name == "function_call") { // if method, pull out if syntax->children[0]->data.name == "unarad" && syntax->children[0]->children[0]->data.name == "access_operation" { println("doing a method call!") - return _call(vec(syntax_to_ast_helper(syntax->children[0]->children[0]->children[2], declared_template_types)) + syntax_to_ast_helper(syntax->children[0]->children[0]->children[0], declared_template_types) + get_nodes("parameter", syntax).map(fun(s: *tree): *tree { + /*return _call(vec(syntax_to_ast_helper(syntax->children[0]->children[0]->children[2], declared_template_types)) + syntax_to_ast_helper(syntax->children[0]->children[0]->children[0], declared_template_types) + get_nodes("parameter", syntax).map(fun(s: *tree): *tree {*/ + return _call(true, vec(make_ast_binding(concat(syntax->children[0]->children[0]->children[2]))) + syntax_to_ast_helper(syntax->children[0]->children[0]->children[0], declared_template_types) + get_nodes("parameter", syntax).map(fun(s: *tree): *tree { return syntax_to_ast_helper(s->children[0], declared_template_types) })) } else { println("NOT doing a method call! - is " + syntax->children[0]->data.name + " not unrad, or") println(syntax->children[0]->children[0]->data.name + " not access_operation") - return _call(vec(syntax_to_ast_helper(syntax->children[0], declared_template_types)) + get_nodes("parameter", syntax).map(fun(s: *tree): *tree { + return _call(false, vec(syntax_to_ast_helper(syntax->children[0], declared_template_types)) + get_nodes("parameter", syntax).map(fun(s: *tree): *tree { return syntax_to_ast_helper(s->children[0], declared_template_types) })) } } else if (syntax->data.name == "access_operation") { // somehow note / do the crazier scope lookup // also handle . vs -> - return _call(vec(make_ast_binding(concat(syntax->children[2])), syntax_to_ast_helper(syntax->children[0], declared_template_types))) + return _call(true, vec(make_ast_binding(concat(syntax->children[2])), syntax_to_ast_helper(syntax->children[0], declared_template_types))) } else if (syntax->data.name == "boolean_expression" || syntax->data.name == "and_boolean_expression" || syntax->data.name == "bitwise_or" || @@ -1218,14 +1276,14 @@ fun syntax_to_ast(file_name: str, syntax: *tree, import_paths: ref vecchildren[0]->data.terminal) { - return _call(vec(make_ast_binding("op" + concat(syntax->children[0])), + return _call(true, vec(make_ast_binding("op" + concat(syntax->children[0])), syntax_to_ast_helper(syntax->children[1], declared_template_types))) } else { - return _call(vec(make_ast_binding("op" + concat(syntax->children[1])), + return _call(true, vec(make_ast_binding("op" + concat(syntax->children[1])), syntax_to_ast_helper(syntax->children[0], declared_template_types))) } } else { - return _call(vec(make_ast_binding("op" + concat(syntax->children[1])), + return _call(true, vec(make_ast_binding("op" + concat(syntax->children[1])), syntax_to_ast_helper(syntax->children[0], declared_template_types), syntax_to_ast_helper(syntax->children[2], declared_template_types))) } diff --git a/stdlib/ast.krak b/stdlib/ast.krak index a4c1bf1..467f983 100644 --- a/stdlib/ast.krak +++ b/stdlib/ast.krak @@ -28,7 +28,7 @@ adt ast { _break, _continue, _defer, - _call, + _call: bool, _compiler_intrinsic: triple, vec<*binding>>, _cast: *binding, _value: pair> @@ -64,7 +64,7 @@ fun to_string(a: ref ast): str { ast::_break() return str("_break") ast::_continue() return str("_continue") ast::_defer() return str("_defer") - ast::_call() return str("_call") + ast::_call(b) return "_call(add_scope: " + to_string(b) + ")" ast::_compiler_intrinsic(b) return str("_compiler_intrinsic(") + b.first + ": " + deref_to_string(b.second->bound_to) + ")" ast::_cast(b) return str("_cast") ast::_value(b) return str("_value(") + b.first + ": " + deref_to_string(b.second->bound_to) + ")" @@ -136,8 +136,8 @@ fun _continue(): *tree { fun _defer(): *tree { return new>()->construct(ast::_defer()) } -fun _call(): *tree { - return new>()->construct(ast::_call()) +fun _call(add_scope: bool): *tree { + return new>()->construct(ast::_call(add_scope)) } @@ -202,8 +202,8 @@ fun _return(c: ref vec<*tree>): *tree { fun _defer(c: ref vec<*tree>): *tree { return new>()->construct(ast::_defer(), c) } -fun _call(c: ref vec<*tree>): *tree { - return new>()->construct(ast::_call(), c) +fun _call(add_scope: bool, c: ref vec<*tree>): *tree { + return new>()->construct(ast::_call(add_scope), c) } @@ -227,7 +227,7 @@ fun is_return(i: *tree): bool { match(i->data) { ast::_return() return true fun is_break(i: *tree): bool { match(i->data) { ast::_break() return true; } return false; } fun is_continue(i: *tree): bool { match(i->data) { ast::_continue() return true; } return false; } fun is_defer(i: *tree): bool { match(i->data) { ast::_defer() return true; } return false; } -fun is_call(i: *tree): bool { match(i->data) { ast::_call() return true; } return false; } +fun is_call(i: *tree): bool { match(i->data) { ast::_call(b) return true; } return false; } fun is_compiler_intrinsic(i: *tree): bool { match(i->data) { ast::_compiler_intrinsic(b) return true; } return false; } fun is_cast(i: *tree): bool { match(i->data) { ast::_cast(b) return true; } return false; } fun is_value(i: *tree): bool { match(i->data) { ast::_value(b) return true; } return false; } diff --git a/stdlib/type2.krak b/stdlib/type2.krak index e20ccd4..a07b202 100644 --- a/stdlib/type2.krak +++ b/stdlib/type2.krak @@ -111,7 +111,7 @@ 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)) + /*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) { diff --git a/stdlib/vec.krak b/stdlib/vec.krak index 28a6e24..443c2a9 100644 --- a/stdlib/vec.krak +++ b/stdlib/vec.krak @@ -217,6 +217,10 @@ obj vec (Object, Serializable) { for (var i = 0; i < dataIn.size; i++;) addEnd(dataIn[i]); } + fun add_all_unique(dataIn: ref vec): void { + for (var i = 0; i < dataIn.size; i++;) + add_unique(dataIn[i]); + } // same darn trick fun add_unique(dataIn: ref U): void { if (!contains(dataIn))