work on k
This commit is contained in:
70
k.krak
70
k.krak
@@ -202,7 +202,6 @@ fun main(argc: int, argv: **char): int {
|
|||||||
}
|
}
|
||||||
for (var i = 0; i < item->children.size; i++;) {
|
for (var i = 0; i < item->children.size; i++;) {
|
||||||
var child = item->children[i]
|
var child = item->children[i]
|
||||||
if is_type_def(child)
|
|
||||||
match (child->data) {
|
match (child->data) {
|
||||||
ast::_type_def(name) {
|
ast::_type_def(name) {
|
||||||
println("Found a type_def! - " + name)
|
println("Found a type_def! - " + name)
|
||||||
@@ -210,25 +209,64 @@ fun main(argc: int, argv: **char): int {
|
|||||||
var grandchild = child->children[j];
|
var grandchild = child->children[j];
|
||||||
if is_declaration(grandchild) {
|
if is_declaration(grandchild) {
|
||||||
var ident = grandchild->children[0]
|
var ident = grandchild->children[0]
|
||||||
|
var ident_name = ident->data._identifier.first
|
||||||
|
var ident_type = ident->data._identifier.second
|
||||||
var type_def_binding = make_ast_binding(name)
|
var type_def_binding = make_ast_binding(name)
|
||||||
set_ast_binding(type_def_binding, child)
|
set_ast_binding(type_def_binding, child)
|
||||||
item->add_child(_compiler_intrinsic(ident->data._identifier.first, binding_p(type::_fun(make_triple(make_pair(vec(
|
item->add_child(_compiler_intrinsic(ident_name, binding_p(type::_fun(make_triple(make_pair(vec(
|
||||||
binding_p(type::_obj(type_def_binding))
|
binding_p(type::_obj(type_def_binding))
|
||||||
),
|
),
|
||||||
ident->data._identifier.second
|
ident_type
|
||||||
), false, false))), vec<*binding<type>>()))
|
), false, false))), vec<*binding<type>>()))
|
||||||
println("adding compiler intrinsic to do " + name + "." + ident->data._identifier.first)
|
println("adding compiler intrinsic to do " + name + "." + ident_name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast::_template(name_map_pair) {
|
||||||
|
if is_type_def(child->children[0]) {
|
||||||
|
var name = child->children[0]->data._type_def
|
||||||
|
println("Found a templated type_def! - " + name)
|
||||||
|
for (var j = 0; j < child->children[0]->children.size; j++;) {
|
||||||
|
var great_grandchild = child->children[0]->children[j];
|
||||||
|
if is_declaration(great_grandchild) {
|
||||||
|
var ident = great_grandchild->children[0]
|
||||||
|
var ident_name = ident->data._identifier.first
|
||||||
|
|
||||||
|
// inst type?
|
||||||
|
var ident_type = ident->data._identifier.second
|
||||||
|
|
||||||
|
|
||||||
|
// the map retains the order
|
||||||
|
var new_template_type_map = name_map_pair.second.associate(fun(n: str, t: *binding<type>): pair<str, *binding<type>> return make_pair(n, binding_p(type::_template_placeholder()));)
|
||||||
|
var new_ident_type = inst_temp_type(ident_type, name_map_pair.second.associate(fun(n: str, t: *binding<type>): pair<*binding<type>, *binding<type>>
|
||||||
|
return make_pair(t, new_template_type_map[n]);))
|
||||||
|
|
||||||
|
var type_def_binding = make_ast_binding(name, new_template_type_map.values)
|
||||||
|
// do we need to set the binding to the template?
|
||||||
|
/*set_ast_binding(type_def_binding, child)*/
|
||||||
|
|
||||||
|
item->add_child(_template(ident_name, new_template_type_map, vec(_compiler_intrinsic(ident_name, binding_p(type::_fun(make_triple(make_pair(vec(
|
||||||
|
binding_p(type::_obj(type_def_binding))
|
||||||
|
),
|
||||||
|
ident_type
|
||||||
|
), false, false))), vec<*binding<type>>()))))
|
||||||
|
println("adding compiler intrinsic to do " + name + "." + ident_name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println("post generative")
|
||||||
|
print_tree(item, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolves all binding possibilities for one top level item
|
// resolves all binding possibilities for one top level item
|
||||||
passes[str("name_possibility_resolve")] = fun(item: *tree<ast>) {
|
passes[str("name_possibility_resolve")] = fun(item: *tree<ast>) {
|
||||||
println("Running name possibility resolver?")
|
println("Running name possibility resolver?")
|
||||||
var scope_lookup: fun(*tree<ast>, str, bool): OptionVecAst = fun(scope: *tree<ast>, name: str, is_type: bool): OptionVecAst {
|
var scope_lookup: fun(*tree<ast>, str, bool): OptionVecAst = fun(scope: *tree<ast>, name: str, is_type: bool): OptionVecAst {
|
||||||
|
/*println("doing a scope lookup for " + name + " starting from " + to_string(scope->data))*/
|
||||||
var to_ret = vec<*tree<ast>>()
|
var to_ret = vec<*tree<ast>>()
|
||||||
for (var i = 0; i < scope->children.size; i++;) {
|
for (var i = 0; i < scope->children.size; i++;) {
|
||||||
match(scope->children[i]->data) {
|
match(scope->children[i]->data) {
|
||||||
@@ -267,6 +305,7 @@ fun main(argc: int, argv: **char): int {
|
|||||||
ast::_compiler_intrinsic(b) if (!is_type && b.first == name)
|
ast::_compiler_intrinsic(b) if (!is_type && b.first == name)
|
||||||
to_ret += scope->children[i]
|
to_ret += scope->children[i]
|
||||||
ast::_template(b) if (((!is_type && is_function(scope->children[i]->children[0]))
|
ast::_template(b) if (((!is_type && is_function(scope->children[i]->children[0]))
|
||||||
|
|| (!is_type && is_compiler_intrinsic(scope->children[i]->children[0]))
|
||||||
|| ( is_type && is_type_def(scope->children[i]->children[0]))
|
|| ( is_type && is_type_def(scope->children[i]->children[0]))
|
||||||
|| ( is_type && is_adt_def( scope->children[i]->children[0]))) && b.first == name)
|
|| ( is_type && is_adt_def( scope->children[i]->children[0]))) && b.first == name)
|
||||||
to_ret += scope->children[i]
|
to_ret += scope->children[i]
|
||||||
@@ -319,7 +358,7 @@ fun main(argc: int, argv: **char): int {
|
|||||||
/*_binding: triple<str, vec<*type>, *tree<ast>>,*/
|
/*_binding: triple<str, vec<*type>, *tree<ast>>,*/
|
||||||
ast::_function(b) handle_type(b.second, t)
|
ast::_function(b) handle_type(b.second, t)
|
||||||
ast::_compiler_intrinsic(b) {
|
ast::_compiler_intrinsic(b) {
|
||||||
/*handle_type(b.second, t)*/
|
handle_type(b.second, t)
|
||||||
b.third.for_each(fun(tb: *binding<type>) {
|
b.third.for_each(fun(tb: *binding<type>) {
|
||||||
handle_type(tb, t)
|
handle_type(tb, t)
|
||||||
})
|
})
|
||||||
@@ -352,6 +391,10 @@ fun main(argc: int, argv: **char): int {
|
|||||||
}
|
}
|
||||||
ast::_function(b) return b.second
|
ast::_function(b) return b.second
|
||||||
ast::_template(b) {
|
ast::_template(b) {
|
||||||
|
println("insting temp type in get_type with map")
|
||||||
|
b.second.for_each(fun(k: str, v: *binding<type>) {
|
||||||
|
println("\t" + k + ": " + to_string(v->bound_to))
|
||||||
|
})
|
||||||
return inst_temp_type(get_type(a->children[0]), b.second.associate(fun(k: str, v: *binding<type>): pair<*binding<type>, *binding<type>> return make_pair(v, binding_p(type::_unknown()));))
|
return inst_temp_type(get_type(a->children[0]), b.second.associate(fun(k: str, v: *binding<type>): pair<*binding<type>, *binding<type>> return make_pair(v, binding_p(type::_unknown()));))
|
||||||
}
|
}
|
||||||
ast::_compiler_intrinsic(b) return b.second
|
ast::_compiler_intrinsic(b) return b.second
|
||||||
@@ -375,7 +418,7 @@ fun main(argc: int, argv: **char): int {
|
|||||||
error("Trying to get type of node without one: " + to_string(a->data))
|
error("Trying to get type of node without one: " + to_string(a->data))
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolves all binding possibilities for one top level item
|
// resolves all binding possibilities to a single one for one top level item
|
||||||
passes[str("name_type_resolve")] = fun(item: *tree<ast>) {
|
passes[str("name_type_resolve")] = fun(item: *tree<ast>) {
|
||||||
if !pass_poset.done(make_pair(item, str("name_possibility_resolve"))) {
|
if !pass_poset.done(make_pair(item, str("name_possibility_resolve"))) {
|
||||||
pass_poset.add_open_dep(make_pair(item, str("name_type_resolve")), make_pair(item, str("name_possibility_resolve")))
|
pass_poset.add_open_dep(make_pair(item, str("name_type_resolve")), make_pair(item, str("name_possibility_resolve")))
|
||||||
@@ -390,13 +433,17 @@ fun main(argc: int, argv: **char): int {
|
|||||||
ast::_declaration() if (t->children.size > 1)
|
ast::_declaration() if (t->children.size > 1)
|
||||||
unify(get_type(t->children[0]), get_type(t->children[1]))
|
unify(get_type(t->children[0]), get_type(t->children[1]))
|
||||||
ast::_call() {
|
ast::_call() {
|
||||||
|
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
|
// we call get type to make sure if it is unknown it is transformed into a function version
|
||||||
get_type(t)
|
get_type(t)
|
||||||
|
println("\tpast first get_type")
|
||||||
var fun_type = get_type(t->children[0])->bound_to
|
var fun_type = get_type(t->children[0])->bound_to
|
||||||
|
println("\tpast second get_type")
|
||||||
if (!is_fun(fun_type))
|
if (!is_fun(fun_type))
|
||||||
error("trying to call not a function type: " + to_string(fun_type))
|
error("trying to call not a function type: " + to_string(fun_type))
|
||||||
if (fun_type->_fun.first.first.size != (t->children.size - 1))
|
if (fun_type->_fun.first.first.size != (t->children.size - 1))
|
||||||
error("trying to call function with type wrong number of params (" + to_string(fun_type->_fun.first.first.size) + " vs " + to_string(t->children.size - 1) + "): " + to_string(fun_type))
|
error("trying to call function with type wrong number of params (" + to_string(fun_type->_fun.first.first.size) + " vs " + to_string(t->children.size - 1) + "): " + to_string(fun_type))
|
||||||
|
println("\titerating through children, matching their type with the param type")
|
||||||
for (var i = 1; i < t->children.size; i++;)
|
for (var i = 1; i < t->children.size; i++;)
|
||||||
unify(fun_type->_fun.first.first[i-1], get_type(t->children[i]))
|
unify(fun_type->_fun.first.first[i-1], get_type(t->children[i]))
|
||||||
}
|
}
|
||||||
@@ -527,7 +574,8 @@ fun main(argc: int, argv: **char): int {
|
|||||||
return taken_names[x]
|
return taken_names[x]
|
||||||
var possible = str()
|
var possible = str()
|
||||||
match(x->data) {
|
match(x->data) {
|
||||||
ast::_identifier(b) { possible = b.first; }
|
/*ast::_identifier(b) { possible = b.first; }*/
|
||||||
|
ast::_identifier(b) { return b.first; }
|
||||||
ast::_type_def(b) { possible = b; }
|
ast::_type_def(b) { possible = b; }
|
||||||
ast::_function(b) { possible = b.first; }
|
ast::_function(b) { possible = b.first; }
|
||||||
}
|
}
|
||||||
@@ -612,7 +660,7 @@ fun main(argc: int, argv: **char): int {
|
|||||||
|
|
||||||
// but not in the case where this is a templated type instead of a function - that doesn't make any sense
|
// but not in the case where this is a templated type instead of a function - that doesn't make any sense
|
||||||
var binding_type = null<binding<type>>()
|
var binding_type = null<binding<type>>()
|
||||||
if is_function(bound_to->children[0]) {
|
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
|
// 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_type = get_type(t)
|
||||||
unify(binding_type, inst_temp_type(get_type(bound_to->children[0]), inst_map))
|
unify(binding_type, inst_temp_type(get_type(bound_to->children[0]), inst_map))
|
||||||
@@ -675,9 +723,9 @@ 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")))
|
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
|
// bound_to might have changed from binding
|
||||||
if !is_type_def(get_ast_binding(t)) {
|
/*if !is_type_def(get_ast_binding(t)) {*/
|
||||||
resolve_type(get_type(t))
|
/*resolve_type(get_type(t))*/
|
||||||
}
|
/*}*/
|
||||||
}
|
}
|
||||||
ast::_identifier(p) resolve_type(get_type(t))
|
ast::_identifier(p) resolve_type(get_type(t))
|
||||||
ast::_function(p) resolve_type(get_type(t))
|
ast::_function(p) resolve_type(get_type(t))
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ adt type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun unify(t1: *binding<type>, t2: *binding<type>) {
|
fun unify(t1: *binding<type>, t2: *binding<type>) {
|
||||||
|
println("attempting to unify " + to_string(t1->bound_to) + " and " + to_string(t2->bound_to))
|
||||||
if (is_unknown(t1->bound_to)) {
|
if (is_unknown(t1->bound_to)) {
|
||||||
t1->set(t2->bound_to)
|
t1->set(t2->bound_to)
|
||||||
} else if (is_unknown(t2->bound_to)) {
|
} else if (is_unknown(t2->bound_to)) {
|
||||||
@@ -41,16 +42,45 @@ fun unify(t1: *binding<type>, t2: *binding<type>) {
|
|||||||
unify(t1->bound_to->_fun.first.first[i], t2->bound_to->_fun.first.first[i])
|
unify(t1->bound_to->_fun.first.first[i], t2->bound_to->_fun.first.first[i])
|
||||||
} else if (is_ptr(t1->bound_to)) {
|
} else if (is_ptr(t1->bound_to)) {
|
||||||
unify(t1->bound_to->_ptr, t2->bound_to->_ptr)
|
unify(t1->bound_to->_ptr, t2->bound_to->_ptr)
|
||||||
|
} else if (is_obj(t1->bound_to)) {
|
||||||
|
for (var i = 0; i < t1->bound_to->_obj->data._binding.second.size; i++;) {
|
||||||
|
unify(t1->bound_to->_obj->data._binding.second[i], t2->bound_to->_obj->data._binding.second[i])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error("Doesn't typecheck! Attempted to unify " + to_string(t1->bound_to) + " and " + to_string(t2->bound_to))
|
error("Doesn't typecheck! Attempted to unify " + to_string(t1->bound_to) + " and " + to_string(t2->bound_to))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun shallow_equality(a: *type, b: *type):bool {
|
||||||
|
if (is_ptr(a) != is_ptr(b))
|
||||||
|
return false
|
||||||
|
if (is_ptr(a) && is_ptr(b))
|
||||||
|
return true
|
||||||
|
match(*a) {
|
||||||
|
type::_fun(x) {
|
||||||
|
return is_fun(b) && a->_fun.third == b->_fun.third
|
||||||
|
}
|
||||||
|
type::_obj(x) {
|
||||||
|
return is_obj(b) && (get_ast_binding(x) == get_ast_binding(b->_obj) || ((!ast_bound(x) || !ast_bound(b->_obj))
|
||||||
|
&& x->data._binding.second.size == b->_obj->data._binding.second.size
|
||||||
|
&& x->data._binding.first == b->_obj->data._binding.first))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *a == *b
|
||||||
|
}
|
||||||
|
|
||||||
fun inst_temp_type(t: *binding<type>, replacements: ref map<*binding<type>, *binding<type>>): *binding<type> {
|
fun inst_temp_type(t: *binding<type>, replacements: ref map<*binding<type>, *binding<type>>): *binding<type> {
|
||||||
|
println("inst_temp_type " + to_string(t->bound_to))
|
||||||
match (*t->bound_to) {
|
match (*t->bound_to) {
|
||||||
type::_unknown() error("Unknown in temp type")
|
type::_unknown() error("Unknown in temp type")
|
||||||
|
type::_obj(o) {
|
||||||
|
var binding_types = o->data._binding.second.map(fun(b: *binding<type>): *binding<type> return inst_temp_type(b, replacements);)
|
||||||
|
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)))
|
||||||
|
}
|
||||||
|
}
|
||||||
type::_ptr(p) {
|
type::_ptr(p) {
|
||||||
var cp = inst_temp_type(p, replacements)
|
var cp = inst_temp_type(p, replacements)
|
||||||
if (cp == p)
|
if (cp == p)
|
||||||
@@ -82,9 +112,23 @@ fun inst_temp_type(t: *binding<type>, replacements: ref map<*binding<type>, *bin
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun equality(a: *type, b: *type, count_unknown_as_equal: bool): bool {
|
fun equality(a: *type, b: *type, count_unknown_as_equal: bool): bool {
|
||||||
|
println("equality of " + to_string(a) + " and " + to_string(b))
|
||||||
if (count_unknown_as_equal && (is_unknown(a) || is_unknown(b)))
|
if (count_unknown_as_equal && (is_unknown(a) || is_unknown(b)))
|
||||||
return true
|
return true
|
||||||
match(*a) {
|
match(*a) {
|
||||||
|
type::_obj(x) {
|
||||||
|
if (!is_obj(b))
|
||||||
|
return false
|
||||||
|
if (get_ast_binding(x) == get_ast_binding(b->_obj))
|
||||||
|
return true
|
||||||
|
if (!count_unknown_as_equal || (ast_bound(x) && ast_bound(b->_obj)) || x->data._binding.first != b->_obj->data._binding.first || x->data._binding.second.size != b->_obj->data._binding.second.size)
|
||||||
|
return false
|
||||||
|
for (var i = 0; i < x->data._binding.second.size; i++;) {
|
||||||
|
if (!equality(x->data._binding.second[i]->bound_to, b->_obj->data._binding.second[i]->bound_to, count_unknown_as_equal))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
type::_ptr(p) {
|
type::_ptr(p) {
|
||||||
if (!is_ptr(b))
|
if (!is_ptr(b))
|
||||||
return false
|
return false
|
||||||
@@ -110,21 +154,6 @@ fun equality(a: *type, b: *type, count_unknown_as_equal: bool): bool {
|
|||||||
}
|
}
|
||||||
return *a == *b
|
return *a == *b
|
||||||
}
|
}
|
||||||
fun shallow_equality(a: *type, b: *type):bool {
|
|
||||||
if (is_ptr(a) != is_ptr(b))
|
|
||||||
return false
|
|
||||||
if (is_ptr(a) && is_ptr(b))
|
|
||||||
return true
|
|
||||||
match(*a) {
|
|
||||||
type::_fun(x) {
|
|
||||||
return is_fun(b) && a->_fun.third == b->_fun.third
|
|
||||||
}
|
|
||||||
type::_obj(x) {
|
|
||||||
return is_obj(b) && get_ast_binding(x) == get_ast_binding(b->_obj)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return *a == *b
|
|
||||||
}
|
|
||||||
fun to_string(it: *type): str {
|
fun to_string(it: *type): str {
|
||||||
match (*it) {
|
match (*it) {
|
||||||
type::_unknown() return str("_unknown")
|
type::_unknown() return str("_unknown")
|
||||||
|
|||||||
Reference in New Issue
Block a user