Almost have scoped . working, in fact it is, but having objects with member names has problems (like o.o) if the member function is in scope. (it thinks maybe you're trying to call o on itself...)
This commit is contained in:
136
k.krak
136
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<type>): pair<*binding<type>, *binding<type>> 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<ast>, start_scope: *tree<ast>, type_binding: bool) {
|
||||
var try_to_find_binding_possibilities = fun(binding: *tree<ast>, start_scope: *tree<ast>, additional_scope: *tree<ast>, type_binding: bool): bool {
|
||||
if !ast_bound(binding) && !multiple_binding_options.contains_key(binding) {
|
||||
var all_options = vec<*tree<ast>>()
|
||||
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<tree<ast>>() {
|
||||
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<type>, *tree<ast>): void = fun(t: *binding<type>, n: *tree<ast>) {
|
||||
var handle_type_binding_possibilities: fun(*binding<type>, *tree<ast>): bool = fun(t: *binding<type>, n: *tree<ast>): 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<tree<ast>>(), true)
|
||||
type::_fun(b) {
|
||||
b.first.first.for_each(fun(it: *binding<type>) {
|
||||
handle_type_binding_possibilities(it, n)
|
||||
})
|
||||
handle_type_binding_possibilities(b.first.second, n)
|
||||
/*b.first.first.for_each(fun(it: *binding<type>) {*/
|
||||
/*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<ast>): bool = fun(t: *tree<ast>): 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<str, vec<*type>, *tree<ast>>,*/
|
||||
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<type>) {
|
||||
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<type>) {*/
|
||||
/*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<tree<ast>>(), 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<tree<ast>>(), 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<ast>): 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<ast>) { 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<ast>): void = fun(t: *tree<ast>) {
|
||||
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<ast>): 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<symbol>, import_paths: ref vec<s
|
||||
children += get_nodes("boolean_expression", syntax).map(fun(x: *tree<symbol>): *tree<ast> 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<symbol>): *tree<ast> {
|
||||
/*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<symbol>): *tree<ast> {*/
|
||||
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<symbol>): *tree<ast> {
|
||||
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<symbol>): *tree<ast> {
|
||||
return _call(false, vec(syntax_to_ast_helper(syntax->children[0], declared_template_types)) + get_nodes("parameter", syntax).map(fun(s: *tree<symbol>): *tree<ast> {
|
||||
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<symbol>, import_paths: ref vec<s
|
||||
return parse_type(s, declared_template_types);
|
||||
}))
|
||||
} else if (syntax->children[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)))
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ adt ast {
|
||||
_break,
|
||||
_continue,
|
||||
_defer,
|
||||
_call,
|
||||
_call: bool,
|
||||
_compiler_intrinsic: triple<str, *binding<type>, vec<*binding<type>>>,
|
||||
_cast: *binding<type>,
|
||||
_value: pair<str, *binding<type>>
|
||||
@@ -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<ast> {
|
||||
fun _defer(): *tree<ast> {
|
||||
return new<tree<ast>>()->construct(ast::_defer())
|
||||
}
|
||||
fun _call(): *tree<ast> {
|
||||
return new<tree<ast>>()->construct(ast::_call())
|
||||
fun _call(add_scope: bool): *tree<ast> {
|
||||
return new<tree<ast>>()->construct(ast::_call(add_scope))
|
||||
}
|
||||
|
||||
|
||||
@@ -202,8 +202,8 @@ fun _return(c: ref vec<*tree<ast>>): *tree<ast> {
|
||||
fun _defer(c: ref vec<*tree<ast>>): *tree<ast> {
|
||||
return new<tree<ast>>()->construct(ast::_defer(), c)
|
||||
}
|
||||
fun _call(c: ref vec<*tree<ast>>): *tree<ast> {
|
||||
return new<tree<ast>>()->construct(ast::_call(), c)
|
||||
fun _call(add_scope: bool, c: ref vec<*tree<ast>>): *tree<ast> {
|
||||
return new<tree<ast>>()->construct(ast::_call(add_scope), c)
|
||||
}
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ fun is_return(i: *tree<ast>): bool { match(i->data) { ast::_return() return true
|
||||
fun is_break(i: *tree<ast>): bool { match(i->data) { ast::_break() return true; } return false; }
|
||||
fun is_continue(i: *tree<ast>): bool { match(i->data) { ast::_continue() return true; } return false; }
|
||||
fun is_defer(i: *tree<ast>): bool { match(i->data) { ast::_defer() return true; } return false; }
|
||||
fun is_call(i: *tree<ast>): bool { match(i->data) { ast::_call() return true; } return false; }
|
||||
fun is_call(i: *tree<ast>): bool { match(i->data) { ast::_call(b) return true; } return false; }
|
||||
fun is_compiler_intrinsic(i: *tree<ast>): bool { match(i->data) { ast::_compiler_intrinsic(b) return true; } return false; }
|
||||
fun is_cast(i: *tree<ast>): bool { match(i->data) { ast::_cast(b) return true; } return false; }
|
||||
fun is_value(i: *tree<ast>): bool { match(i->data) { ast::_value(b) return true; } return false; }
|
||||
|
||||
@@ -111,7 +111,7 @@ 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 {
|
||||
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) {
|
||||
|
||||
@@ -217,6 +217,10 @@ obj vec<T> (Object, Serializable) {
|
||||
for (var i = 0; i < dataIn.size; i++;)
|
||||
addEnd(dataIn[i]);
|
||||
}
|
||||
fun add_all_unique<U>(dataIn: ref vec<U>): void {
|
||||
for (var i = 0; i < dataIn.size; i++;)
|
||||
add_unique(dataIn[i]);
|
||||
}
|
||||
// same darn trick
|
||||
fun add_unique<U>(dataIn: ref U): void {
|
||||
if (!contains(dataIn))
|
||||
|
||||
Reference in New Issue
Block a user