Finally, ref lowering! A little hacky, but not terrible...
This commit is contained in:
@@ -43,6 +43,14 @@ obj tree<T> (Object) {
|
||||
children.add(c)
|
||||
c->parent = this
|
||||
}
|
||||
fun set_child(i: int, c: *tree<T>) {
|
||||
children[i] = c
|
||||
c->parent = this
|
||||
}
|
||||
fun replace_child(old_c: *tree<T>, new_c: *tree<T>) {
|
||||
children[children.find(old_c)] = new_c
|
||||
new_c->parent = this
|
||||
}
|
||||
fun clone(): *tree<T> {
|
||||
return mem::new<tree<T>>()->construct(data, children.map(fun(c: *tree<T>): *tree<T> return c->clone();))
|
||||
}
|
||||
|
||||
@@ -6,6 +6,19 @@ import tree:*
|
||||
import ast:*
|
||||
import binding:*
|
||||
|
||||
adt ref_type {
|
||||
_unknown,
|
||||
_ref,
|
||||
_notref
|
||||
}
|
||||
fun to_string(r: ref_type): str {
|
||||
match (r) {
|
||||
ref_type::_unknown() return str("_ref/unknown")
|
||||
ref_type::_ref() return str("_ref/ref")
|
||||
ref_type::_notref() return str("_ref/notref")
|
||||
}
|
||||
}
|
||||
|
||||
adt type {
|
||||
_unknown,
|
||||
_void,
|
||||
@@ -13,7 +26,7 @@ adt type {
|
||||
_ptr: *binding<type>,
|
||||
_obj: *tree<ast>,
|
||||
// triple<pair<vec<pair<is_ref, param_type>>, pair<is_ref, return_type>>, is_variadic, is raw>
|
||||
_fun: triple<pair<vec<pair<bool, *binding<type>>>, pair<bool, *binding<type>>>, bool, bool>,
|
||||
_fun: triple<pair<vec<pair<ref_type, *binding<type>>>, pair<ref_type, *binding<type>>>, bool, bool>,
|
||||
_bool,
|
||||
_char,
|
||||
_uchar,
|
||||
@@ -37,8 +50,18 @@ fun unify(t1: *binding<type>, t2: *binding<type>) {
|
||||
if (shallow_equality(t1->bound_to, t2->bound_to)) {
|
||||
if (is_fun(t1->bound_to)) {
|
||||
unify(t1->bound_to->_fun.first.second.second, t2->bound_to->_fun.first.second.second)
|
||||
for (var i = 0; i < t1->bound_to->_fun.first.first.size; i++;)
|
||||
// unify ref_types
|
||||
if (t1->bound_to->_fun.first.second.first == ref_type::_unknown())
|
||||
t1->bound_to->_fun.first.second.first = t2->bound_to->_fun.first.second.first
|
||||
if (t2->bound_to->_fun.first.second.first == ref_type::_unknown())
|
||||
t2->bound_to->_fun.first.second.first = t1->bound_to->_fun.first.second.first
|
||||
for (var i = 0; i < t1->bound_to->_fun.first.first.size; i++;) {
|
||||
unify(t1->bound_to->_fun.first.first[i].second, t2->bound_to->_fun.first.first[i].second)
|
||||
if (t1->bound_to->_fun.first.first[i].first == ref_type::_unknown())
|
||||
t1->bound_to->_fun.first.first[i].first = t2->bound_to->_fun.first.first[i].first
|
||||
if (t2->bound_to->_fun.first.first[i].first == ref_type::_unknown())
|
||||
t2->bound_to->_fun.first.first[i].first = t1->bound_to->_fun.first.first[i].first
|
||||
}
|
||||
} else if (is_ptr(t1->bound_to)) {
|
||||
unify(t1->bound_to->_ptr, t2->bound_to->_ptr)
|
||||
} else if (is_obj(t1->bound_to)) {
|
||||
@@ -89,7 +112,7 @@ fun inst_temp_type(t: *binding<type>, replacements: ref map<*binding<type>, *bin
|
||||
type::_fun(b) {
|
||||
// triple<pair<param_types, return_type>, is_variadic, is raw>
|
||||
var rt = make_pair(b.first.second.first, inst_temp_type(b.first.second.second, replacements))
|
||||
var pts = b.first.first.map(fun(pt: pair<bool, *binding<type>>): pair<bool, *binding<type>> return make_pair(pt.first, inst_temp_type(pt.second, replacements));)
|
||||
var pts = b.first.first.map(fun(pt: pair<ref_type, *binding<type>>): pair<ref_type, *binding<type>> return make_pair(pt.first, inst_temp_type(pt.second, replacements));)
|
||||
if (rt.second != b.first.second.second)
|
||||
return binding_p(type::_fun(make_triple(make_pair(pts, rt), b.second, b.third)))
|
||||
for (var i = 0; i < pts.size; i++;)
|
||||
@@ -155,7 +178,7 @@ fun to_string(it: *type): str {
|
||||
to_ret += "_run("
|
||||
else
|
||||
to_ret += "_fun("
|
||||
to_ret += str(", ").join(b.first.first.map(fun(pt: pair<bool, *binding<type>>): str return to_string(pt.first) + to_string(pt.second->bound_to);))
|
||||
to_ret += str(", ").join(b.first.first.map(fun(pt: pair<ref_type, *binding<type>>): str return to_string(pt.first) + to_string(pt.second->bound_to);))
|
||||
if (b.third)
|
||||
to_ret += " ..."
|
||||
return to_ret + "): " + to_string(b.first.second.first) + to_string(b.first.second.second->bound_to)
|
||||
|
||||
Reference in New Issue
Block a user