diff --git a/k.krak b/k.krak index 339fa3b..01660d4 100644 --- a/k.krak +++ b/k.krak @@ -175,17 +175,28 @@ fun main(argc: int, argv: **char): int { println("trying to unify " + t1->bound_to->to_string() + " and " + t2->bound_to->to_string()) if (t1->bound_to->equality(t2->bound_to, false) || t1->bound_to->is_unknown()) t1->set(t2->bound_to) - else + else if (t2->bound_to->is_unknown()) t2->set(t1->bound_to) + else + error("Doesn't typecheck! Attempted to unify " + t1->bound_to->to_string() + " and " + t2->bound_to->to_string()) } var traverse_for_unify: fun(*tree): void = fun(t: *tree) { t->children.for_each(traverse_for_unify) match (t->data) { ast::_declaration() if (t->children.size > 1) unify(get_type(t->children[0]), get_type(t->children[1])) - /*ast::_assignment()*/ - /*ast::_call()*/ - /*ast::_return()*/ + /*ast::_assignment() unify(get_type(t->children[0]), get_type(t->children[1]))*/ + ast::_call() { + var fun_type = get_type(t->children[0])->bound_to + if (!fun_type->is_fun()) + error("trying to call not a function type: " + fun_type->to_string()) + if (fun_type->base._fun.first.first.size != (t->children.size - 1)) + error("trying to call function with type wrong number of params (" + to_string(fun_type->base._fun.first.first.size) + " vs " + to_string(t->children.size - 1) + "): " + fun_type->to_string()) + for (var i = 1; i < t->children.size; i++;) + unify(fun_type->base._fun.first.first[i-1], get_type(t->children[i])) + } + ast::_return() if (t->children.size > 0) + unify(get_type(get_ancestor_satisfying(t, fun(t: *tree): bool return is_function(t);))->bound_to->base._fun.first.second, get_type(t->children[0])) } } traverse_for_unify(item) @@ -590,9 +601,13 @@ fun syntax_to_ast(file_name: str, syntax: *tree, import_paths: ref vecchildren[0]), syntax_to_ast_helper(syntax->children[2]))) } - } else if (syntax->data.name == "number") - return _value(concat(syntax), binding(type(base_type::_int(), 0, false))) - else if (syntax->data.name == "bool") + } else if (syntax->data.name == "number") { + var number_string = concat(syntax) + if (number_string.contains('.')) + return _value(number_string, binding(type(base_type::_double(), 0, false))) + else + return _value(number_string, binding(type(base_type::_int(), 0, false))) + } else if (syntax->data.name == "bool") return _value(concat(syntax), binding(type(base_type::_bool(), 0, false))) else if (syntax->data.name == "scoped_identifier" || syntax->data.name == "identifier") return make_ast_binding(concat(syntax)) diff --git a/stdlib/ast.krak b/stdlib/ast.krak index e7d02c4..f078fad 100644 --- a/stdlib/ast.krak +++ b/stdlib/ast.krak @@ -37,7 +37,7 @@ fun get_type(a: *tree): *binding { ast::_identifier(b) return b.second ast::_binding(b) return get_type(b.second->bound_to) ast::_function(b) return b.second - /*ast::_call() return get_type(a->children[0])->bound_to->base->_fun->second*/ + ast::_call() return get_type(a->children[0])->bound_to->base._fun.first.second /*ast::_compiler_intrinsic(b) return str("_compiler_intrinsic(") + b.first + ")"*/ ast::_cast(b) return b ast::_value(b) return b.second @@ -249,6 +249,13 @@ fun is_value(i: *tree): bool { match(i->data) { ast::_value(b) return true; fun is_top_level_item(i: *tree): bool { return i->parent != null>() && is_translation_unit(i->parent); } +fun get_ancestor_satisfying(t: *tree, p: fun(*tree): bool): *tree { + t = t->parent + while (t != null>() && !p(t)) + t = t->parent + return t +} + var bindings: *vec<*void> diff --git a/stdlib/str.krak b/stdlib/str.krak index 20278d4..16fd3a2 100644 --- a/stdlib/str.krak +++ b/stdlib/str.krak @@ -309,5 +309,8 @@ obj str (Object, Serializable, Hashable) { fun for_each(func: fun(char):void) { data.for_each(func) } + fun contains(c: char): bool { + return data.contains(c) + } };