|
|
|
|
@@ -208,8 +208,8 @@ obj ast_transformation (Object) {
|
|
|
|
|
template_types.add(concat_symbol_tree(get_node("identifier", template_param)))
|
|
|
|
|
template_type_replacements.set(template_types.last(), type_ptr(transform_traits(get_node("traits", template_param))))
|
|
|
|
|
})
|
|
|
|
|
template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)
|
|
|
|
|
println("MAP DONE")
|
|
|
|
|
/*template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)*/
|
|
|
|
|
/*println("MAP DONE")*/
|
|
|
|
|
var template = ast_template_ptr(function_name, node, template_types, template_type_replacements, true)
|
|
|
|
|
add_to_scope(function_name, template, scope)
|
|
|
|
|
add_to_scope("~enclosing_scope", scope, template)
|
|
|
|
|
@@ -296,7 +296,7 @@ obj ast_transformation (Object) {
|
|
|
|
|
var template_inst = get_node("template_inst", real_node)
|
|
|
|
|
if (template_inst) {
|
|
|
|
|
var name = concat_symbol_tree(get_node("scoped_identifier", real_node))
|
|
|
|
|
println(string("trying to instantiate a template object: ") + name)
|
|
|
|
|
/*println(string("trying to instantiate a template object: ") + name)*/
|
|
|
|
|
var real_types = get_nodes("type", template_inst).map(fun(t: *tree<symbol>): *type return transform_type(t, scope, template_replacements);)
|
|
|
|
|
var real_types_deref = real_types.map(fun(t:*type):type return *t;)
|
|
|
|
|
var results = scope_lookup(name, scope)
|
|
|
|
|
@@ -305,7 +305,7 @@ obj ast_transformation (Object) {
|
|
|
|
|
for (var i = 0; i < results.size; i++;) {
|
|
|
|
|
if (!is_template(results[i]) || results[i]->template.is_function)
|
|
|
|
|
continue
|
|
|
|
|
println(to_string(i) + " is an object template!")
|
|
|
|
|
/*println(to_string(i) + " is an object template!")*/
|
|
|
|
|
var template_types = results[i]->template.template_types
|
|
|
|
|
var template_type_replacements = results[i]->template.template_type_replacements
|
|
|
|
|
if (template_types.size != real_types.size)
|
|
|
|
|
@@ -314,47 +314,47 @@ obj ast_transformation (Object) {
|
|
|
|
|
var num_satisfied_traits = 0
|
|
|
|
|
var satisfied_traits = true
|
|
|
|
|
template_type_replacements.for_each(fun(key: string, value: *type) num_satisfied_traits += value->traits.size();)
|
|
|
|
|
println("FOR FIND OR INSTATINTATE PREEEE")
|
|
|
|
|
template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)
|
|
|
|
|
println("MAP DONE")
|
|
|
|
|
/*println("FOR FIND OR INSTATINTATE PREEEE")*/
|
|
|
|
|
/*template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)*/
|
|
|
|
|
/*println("MAP DONE")*/
|
|
|
|
|
for (var j = 0; j < template_types.size; j++;) {
|
|
|
|
|
satisfied_traits = satisfied_traits && real_types[j]->traits.contains(template_type_replacements[template_types[j]]->traits) &&
|
|
|
|
|
(real_types[j]->indirection == 0 || template_type_replacements[template_types[j]]->traits.size() == 0)
|
|
|
|
|
template_type_replacements[template_types[j]] = real_types[j]
|
|
|
|
|
println("Just made")
|
|
|
|
|
println(template_types[j])
|
|
|
|
|
println("equal to")
|
|
|
|
|
println(real_types[j]->to_string())
|
|
|
|
|
/*println("Just made")*/
|
|
|
|
|
/*println(template_types[j])*/
|
|
|
|
|
/*println("equal to")*/
|
|
|
|
|
/*println(real_types[j]->to_string())*/
|
|
|
|
|
}
|
|
|
|
|
if (!satisfied_traits) {
|
|
|
|
|
println(name + " did not satisfy traits!")
|
|
|
|
|
/*println(name + " did not satisfy traits!")*/
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
println("FOR FIND OR INSTATINTATE")
|
|
|
|
|
template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)
|
|
|
|
|
println("MAP DONE")
|
|
|
|
|
/*println("FOR FIND OR INSTATINTATE")*/
|
|
|
|
|
/*template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)*/
|
|
|
|
|
/*println("MAP DONE")*/
|
|
|
|
|
|
|
|
|
|
var inst_type = null<ast_node>()
|
|
|
|
|
// check if already instantiated
|
|
|
|
|
if (results[i]->template.instantiated_map.contains_key(real_types_deref)) {
|
|
|
|
|
println("USING CACHED TEMPLATE OBJECT")
|
|
|
|
|
/*println("USING CACHED TEMPLATE OBJECT")*/
|
|
|
|
|
inst_type = results[i]->template.instantiated_map[real_types_deref]
|
|
|
|
|
} else {
|
|
|
|
|
print("Not using cached template - was looking for:\n\t\t")
|
|
|
|
|
/*print("Not using cached template - was looking for:\n\t\t")*/
|
|
|
|
|
var typeStr = string()
|
|
|
|
|
real_types_deref.for_each(fun(t: type) typeStr += t.to_string(false) + " ";)
|
|
|
|
|
print(typeStr)
|
|
|
|
|
println("\ninstead, only had:")
|
|
|
|
|
/*print(typeStr)*/
|
|
|
|
|
/*println("\ninstead, only had:")*/
|
|
|
|
|
results[i]->template.instantiated_map.for_each(fun(key: vector<type>, value: *ast_node) {
|
|
|
|
|
print("\t\t")
|
|
|
|
|
/*print("\t\t")*/
|
|
|
|
|
var hasTypStr = string()
|
|
|
|
|
key.for_each(fun(t: type) hasTypStr += t.to_string(false) + " ";)
|
|
|
|
|
print(hasTypStr)
|
|
|
|
|
/*print(hasTypStr)*/
|
|
|
|
|
if (typeStr == hasTypStr)
|
|
|
|
|
error("they're equal but really shouldnt be")
|
|
|
|
|
println()
|
|
|
|
|
/*println()*/
|
|
|
|
|
})
|
|
|
|
|
println("donr")
|
|
|
|
|
/*println("donr")*/
|
|
|
|
|
if (real_types.any_true(fun(t: *type): bool return t->is_none() || t ->is_template_type();)) {
|
|
|
|
|
error("Instantiating types for templated object are not all real types!")
|
|
|
|
|
}
|
|
|
|
|
@@ -378,11 +378,11 @@ obj ast_transformation (Object) {
|
|
|
|
|
return fitting_types.max(fun(a: pair<*ast_node, int>, b: pair<*ast_node, int>): bool return a.second < b.second;).first->type_def.self_type->clone_with_indirection(indirection, is_ref)
|
|
|
|
|
}
|
|
|
|
|
var type_syntax_str = concat_symbol_tree(real_node)
|
|
|
|
|
println(type_syntax_str + " *************************")
|
|
|
|
|
/*println(type_syntax_str + " *************************")*/
|
|
|
|
|
if (template_replacements.contains_key(type_syntax_str)) {
|
|
|
|
|
print("Is in template_replacements, returning: ")
|
|
|
|
|
/*print("Is in template_replacements, returning: ")*/
|
|
|
|
|
var to_ret = template_replacements[type_syntax_str]->clone_with_increased_indirection(indirection, is_ref)
|
|
|
|
|
println(to_ret->to_string())
|
|
|
|
|
/*println(to_ret->to_string())*/
|
|
|
|
|
return to_ret
|
|
|
|
|
}
|
|
|
|
|
// should take into account references...
|
|
|
|
|
@@ -404,7 +404,7 @@ obj ast_transformation (Object) {
|
|
|
|
|
} else {
|
|
|
|
|
// do lookup for objects, ADTs, templates, etc
|
|
|
|
|
var possibilities = scope_lookup(type_syntax_str, scope)
|
|
|
|
|
print("There are "); print(possibilities.size); println(" possibilites for this object type lookup")
|
|
|
|
|
/*print("There are "); print(possibilities.size); println(" possibilites for this object type lookup")*/
|
|
|
|
|
for (var i = 0; i < possibilities.size; i++;) {
|
|
|
|
|
match(*possibilities[i]) {
|
|
|
|
|
ast_node::type_def(backing) return backing.self_type->clone_with_indirection(indirection, is_ref)
|
|
|
|
|
@@ -412,7 +412,7 @@ obj ast_transformation (Object) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// error("no types found for " + type_syntax_str)
|
|
|
|
|
println("no types found for " + type_syntax_str)
|
|
|
|
|
/*println("no types found for " + type_syntax_str)*/
|
|
|
|
|
return type_ptr(base_type::none(), indirection, is_ref)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -462,7 +462,7 @@ obj ast_transformation (Object) {
|
|
|
|
|
} else if (name == "bool" || name == "string"
|
|
|
|
|
|| name == "character" || name == "number"
|
|
|
|
|
) {
|
|
|
|
|
println(string("transforming value: ") + name)
|
|
|
|
|
/*println(string("transforming value: ") + name)*/
|
|
|
|
|
return transform_value(node, scope)
|
|
|
|
|
}
|
|
|
|
|
print("FAILED TO TRANSFORM: "); print(name + ": "); println(concat_symbol_tree(node))
|
|
|
|
|
@@ -496,13 +496,13 @@ obj ast_transformation (Object) {
|
|
|
|
|
var possible_obj_type = get_ast_type(possible_obj)
|
|
|
|
|
// note operator() has had it's () stripped out...
|
|
|
|
|
if (possible_obj_type->is_object() && has_method(possible_obj_type->type_def, "operator", type_vec)) {
|
|
|
|
|
println("Has the operator()!")
|
|
|
|
|
/*println("Has the operator()!")*/
|
|
|
|
|
return possible_obj
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
println("FAILED SEARCH FOR")
|
|
|
|
|
/*println("FAILED SEARCH FOR")*/
|
|
|
|
|
return null<ast_node>()
|
|
|
|
|
}
|
|
|
|
|
fun transform_value(node: *tree<symbol>, scope: *ast_node): *ast_node {
|
|
|
|
|
@@ -607,55 +607,55 @@ obj ast_transformation (Object) {
|
|
|
|
|
var to_assign = transform(get_node("boolean_expression", node), scope, template_replacements)
|
|
|
|
|
// for []= overloading
|
|
|
|
|
if (get_node("\"=\"", node)) {
|
|
|
|
|
println("Regular Assignment!")
|
|
|
|
|
/*println("Regular Assignment!")*/
|
|
|
|
|
var factor_part = get_node("factor", node)
|
|
|
|
|
if (factor_part->children.size == 1) {
|
|
|
|
|
println("Factor has only one child!")
|
|
|
|
|
/*println("Factor has only one child!")*/
|
|
|
|
|
var inner_unarad = get_node("unarad", factor_part)
|
|
|
|
|
if (get_node("\"[\"", inner_unarad)) {
|
|
|
|
|
println("Inner Unarad has [!")
|
|
|
|
|
/*println("Inner Unarad has [!")*/
|
|
|
|
|
var assign_to = transform(get_node("unarad", inner_unarad), scope, template_replacements)
|
|
|
|
|
var assign_idx = transform(get_node("expression", inner_unarad), scope, template_replacements)
|
|
|
|
|
var possible_bracket_assign = find_and_make_any_operator_overload_call(string("[]="), vector(assign_to, assign_idx, to_assign), scope, template_replacements)
|
|
|
|
|
if (possible_bracket_assign) {
|
|
|
|
|
println("Computed and returning []=!")
|
|
|
|
|
/*println("Computed and returning []=!")*/
|
|
|
|
|
return possible_bracket_assign
|
|
|
|
|
} else println("Could not Compute and return []=!")
|
|
|
|
|
} else println("Inner Unarad does not have [!")
|
|
|
|
|
} else println("Factor not 1 child")
|
|
|
|
|
} else println("Not regular assignment")
|
|
|
|
|
} // else println("Could not Compute and return []=!")
|
|
|
|
|
} // else println("Inner Unarad does not have [!")
|
|
|
|
|
} // else println("Factor not 1 child")
|
|
|
|
|
} // else println("Not regular assignment")
|
|
|
|
|
var assign_to = transform(get_node("factor", node), scope, template_replacements)
|
|
|
|
|
if (get_node("\"=\"", node)) {
|
|
|
|
|
var possible_assign = find_and_make_any_operator_overload_call(string("="), vector(assign_to, to_assign), scope, template_replacements)
|
|
|
|
|
if (possible_assign) {
|
|
|
|
|
println("Computed and returning operator=")
|
|
|
|
|
/*println("Computed and returning operator=")*/
|
|
|
|
|
return possible_assign
|
|
|
|
|
}
|
|
|
|
|
} else if (get_node("\"\\+=\"", node)) {
|
|
|
|
|
var possible_assign = find_and_make_any_operator_overload_call(string("+="), vector(assign_to, to_assign), scope, template_replacements)
|
|
|
|
|
if (possible_assign) {
|
|
|
|
|
print("Computed and returning operator+=")
|
|
|
|
|
/*print("Computed and returning operator+=")*/
|
|
|
|
|
return possible_assign
|
|
|
|
|
}
|
|
|
|
|
to_assign = make_operator_call("+", vector(assign_to, to_assign))
|
|
|
|
|
} else if (get_node("\"-=\"", node)) {
|
|
|
|
|
var possible_assign = find_and_make_any_operator_overload_call(string("-="), vector(assign_to, to_assign), scope, template_replacements)
|
|
|
|
|
if (possible_assign) {
|
|
|
|
|
print("Computed and returning operator-=")
|
|
|
|
|
/*print("Computed and returning operator-=")*/
|
|
|
|
|
return possible_assign
|
|
|
|
|
}
|
|
|
|
|
to_assign = make_operator_call("-", vector(assign_to, to_assign))
|
|
|
|
|
} else if (get_node("\"\\*=\"", node)) {
|
|
|
|
|
var possible_assign = find_and_make_any_operator_overload_call(string("*="), vector(assign_to, to_assign), scope, template_replacements)
|
|
|
|
|
if (possible_assign) {
|
|
|
|
|
print("Computed and returning operator*=")
|
|
|
|
|
/*print("Computed and returning operator*=")*/
|
|
|
|
|
return possible_assign
|
|
|
|
|
}
|
|
|
|
|
to_assign = make_operator_call("*", vector(assign_to, to_assign))
|
|
|
|
|
} else if (get_node("\"/=\"", node)){
|
|
|
|
|
var possible_assign = find_and_make_any_operator_overload_call(string("/="), vector(assign_to, to_assign), scope, template_replacements)
|
|
|
|
|
if (possible_assign) {
|
|
|
|
|
print("Computed and returning operator/=")
|
|
|
|
|
/*print("Computed and returning operator/=")*/
|
|
|
|
|
return possible_assign
|
|
|
|
|
}
|
|
|
|
|
to_assign = make_operator_call("/", vector(assign_to, to_assign))
|
|
|
|
|
@@ -736,21 +736,21 @@ obj ast_transformation (Object) {
|
|
|
|
|
var func = transform(get_node("unarad", node), scope, search_type::function(parameter_types), template_replacements)
|
|
|
|
|
// may return an identifier of type object if doing operator() - but the () have been stripped out by importer
|
|
|
|
|
if (get_ast_type(func)->is_object()) {
|
|
|
|
|
println("Making an operator() method call!")
|
|
|
|
|
/*println("Making an operator() method call!")*/
|
|
|
|
|
return make_method_call(func, "operator", parameters)
|
|
|
|
|
}
|
|
|
|
|
var f = ast_function_call_ptr(func, parameters)
|
|
|
|
|
print("function call function ")
|
|
|
|
|
println(f->function_call.func)
|
|
|
|
|
print("function call parameters ")
|
|
|
|
|
f->function_call.parameters.for_each(fun(param: *ast_node) print(param);)
|
|
|
|
|
/*print("function call function ")*/
|
|
|
|
|
/*println(f->function_call.func)*/
|
|
|
|
|
/*print("function call parameters ")*/
|
|
|
|
|
/*f->function_call.parameters.for_each(fun(param: *ast_node) print(param);)*/
|
|
|
|
|
return f
|
|
|
|
|
}
|
|
|
|
|
fun transform_lambda(node: *tree<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node {
|
|
|
|
|
var function_node = second_pass_function(node, scope, template_replacements, false)
|
|
|
|
|
function_node->function.body_statement = transform_statement(get_node("statement", node), function_node, template_replacements)
|
|
|
|
|
function_node->function.closed_variables = find_closed_variables(function_node, function_node->function.body_statement)
|
|
|
|
|
println(string("Found ") + function_node->function.closed_variables.size() + " closed variables!")
|
|
|
|
|
/*println(string("Found ") + function_node->function.closed_variables.size() + " closed variables!")*/
|
|
|
|
|
while (!is_translation_unit(scope)) scope = get_ast_scope(scope)->get(string("~enclosing_scope"))[0]
|
|
|
|
|
scope->translation_unit.lambdas.add(function_node)
|
|
|
|
|
return function_node
|
|
|
|
|
@@ -759,24 +759,18 @@ obj ast_transformation (Object) {
|
|
|
|
|
if (!node) return set<*ast_node>()
|
|
|
|
|
match (*node) {
|
|
|
|
|
ast_node::identifier(backing) {
|
|
|
|
|
println("found an identifier")
|
|
|
|
|
println(backing.name)
|
|
|
|
|
if (!in_scope_chain(backing.enclosing_scope, func))
|
|
|
|
|
return set(node);
|
|
|
|
|
}
|
|
|
|
|
ast_node::statement(backing) {
|
|
|
|
|
println("found an statement")
|
|
|
|
|
return find_closed_variables(func, backing.child)
|
|
|
|
|
}
|
|
|
|
|
ast_node::code_block(backing) {
|
|
|
|
|
println("found an code_block")
|
|
|
|
|
var to_ret = set<*ast_node>()
|
|
|
|
|
backing.children.for_each(fun(n: *ast_node) to_ret += find_closed_variables(func, n);)
|
|
|
|
|
return to_ret
|
|
|
|
|
}
|
|
|
|
|
ast_node::function_call(backing) {
|
|
|
|
|
println("found an function_call")
|
|
|
|
|
// XXX should special case . and ->, I think
|
|
|
|
|
if (is_function(backing.func) && (backing.func->function.name == "." || backing.func->function.name == "->"))
|
|
|
|
|
return find_closed_variables(func, backing.parameters.first())
|
|
|
|
|
var to_ret = find_closed_variables(func, backing.func)
|
|
|
|
|
@@ -801,50 +795,39 @@ obj ast_transformation (Object) {
|
|
|
|
|
return to_ret
|
|
|
|
|
}
|
|
|
|
|
ast_node::return_statement(backing) {
|
|
|
|
|
println("found an return_statement")
|
|
|
|
|
return find_closed_variables(func, backing.return_value)
|
|
|
|
|
}
|
|
|
|
|
ast_node::if_statement(backing) {
|
|
|
|
|
println("found an if statement")
|
|
|
|
|
return find_closed_variables(func, backing.condition) + find_closed_variables(func, backing.then_part) + find_closed_variables(func, backing.else_part)
|
|
|
|
|
}
|
|
|
|
|
ast_node::match_statement(backing) {
|
|
|
|
|
println("found an match_statement")
|
|
|
|
|
var to_ret = set<*ast_node>()
|
|
|
|
|
backing.cases.for_each(fun(n: *ast_node) to_ret += find_closed_variables(func, n);)
|
|
|
|
|
return to_ret
|
|
|
|
|
}
|
|
|
|
|
ast_node::case_statement(backing) {
|
|
|
|
|
println("found a case_statement")
|
|
|
|
|
return find_closed_variables(func, backing.statement)
|
|
|
|
|
}
|
|
|
|
|
ast_node::while_loop(backing) {
|
|
|
|
|
println("found an while loop")
|
|
|
|
|
return find_closed_variables(func, backing.condition) + find_closed_variables(func, backing.statement)
|
|
|
|
|
}
|
|
|
|
|
ast_node::for_loop(backing) {
|
|
|
|
|
println("found an for loop")
|
|
|
|
|
return find_closed_variables(func, backing.init) + find_closed_variables(func, backing.condition) +
|
|
|
|
|
find_closed_variables(func, backing.update) + find_closed_variables(func, backing.body)
|
|
|
|
|
}
|
|
|
|
|
ast_node::return_statement(backing) {
|
|
|
|
|
println("found a return_statement")
|
|
|
|
|
return find_closed_variables(func, backing.return_value)
|
|
|
|
|
}
|
|
|
|
|
ast_node::defer_statement(backing) {
|
|
|
|
|
println("found a defer_statement")
|
|
|
|
|
return find_closed_variables(func, backing.statement)
|
|
|
|
|
}
|
|
|
|
|
ast_node::assignment_statement(backing) {
|
|
|
|
|
println("found an assignment_statement")
|
|
|
|
|
return find_closed_variables(func, backing.to) + find_closed_variables(func, backing.from)
|
|
|
|
|
}
|
|
|
|
|
ast_node::declaration_statement(backing) {
|
|
|
|
|
println("found an declaration_statement")
|
|
|
|
|
return find_closed_variables(func, backing.expression) + find_closed_variables(func, backing.init_method_call)
|
|
|
|
|
}
|
|
|
|
|
ast_node::if_comp(backing) {
|
|
|
|
|
println("found an if_comp")
|
|
|
|
|
return find_closed_variables(func, backing.statement)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -899,7 +882,7 @@ obj ast_transformation (Object) {
|
|
|
|
|
var first_param = transform(node->children[0], scope, template_replacements)
|
|
|
|
|
var second_param = null<ast_node>()
|
|
|
|
|
if (func_name == "." || func_name == "->") {
|
|
|
|
|
println("PRE VANILLA TRY FOR SECOND PARAM")
|
|
|
|
|
/*println("PRE VANILLA TRY FOR SECOND PARAM")*/
|
|
|
|
|
second_param = transform(node->children[2], get_ast_type(first_param)->type_def, searching_for, template_replacements)
|
|
|
|
|
// template member functions
|
|
|
|
|
// XXX add in template inst if it exists
|
|
|
|
|
@@ -909,14 +892,14 @@ obj ast_transformation (Object) {
|
|
|
|
|
var inherited_replacements = map<string, *type>()
|
|
|
|
|
var parent = get_ast_scope(get_ast_type(first_param)->type_def)->get(string("~enclosing_scope"))[0]
|
|
|
|
|
if (is_template(parent)) {
|
|
|
|
|
println("TEMPLATE type PARENT IS TEMPLATE")
|
|
|
|
|
/*println("TEMPLATE type PARENT IS TEMPLATE")*/
|
|
|
|
|
for (var i = 0; i < parent->template.template_types.size; i++;)
|
|
|
|
|
inherited_replacements[parent->template.template_types[i]] = parent->template.instantiated_map.reverse_get(get_ast_type(first_param)->type_def)[i].clone()
|
|
|
|
|
} else {
|
|
|
|
|
println("TEMPLATE type PARENT IS NOT TEMPLATE")
|
|
|
|
|
/*println("TEMPLATE type PARENT IS NOT TEMPLATE")*/
|
|
|
|
|
}
|
|
|
|
|
var method_name = concat_symbol_tree(node->children[2])
|
|
|
|
|
println("PRE TEMPLATE TRY FOR SECOND PARAM")
|
|
|
|
|
/*println("PRE TEMPLATE TRY FOR SECOND PARAM")*/
|
|
|
|
|
second_param = find_or_instantiate_template_function(method_name, template_inst, get_ast_type(first_param)->type_def, type_vec, template_replacements, inherited_replacements);
|
|
|
|
|
if (!second_param) {
|
|
|
|
|
error("Could not find method " + method_name + " on the right side of (. or ->) " + concat_symbol_tree(node->children[0]) +
|
|
|
|
|
@@ -945,11 +928,11 @@ obj ast_transformation (Object) {
|
|
|
|
|
var inherited_replacements = map<string, *type>()
|
|
|
|
|
var parent = get_ast_scope(parameter_types.first()->type_def)->get(string("~enclosing_scope"))[0]
|
|
|
|
|
if (is_template(parent)) {
|
|
|
|
|
println("TEMPLATE type PARENT IS TEMPLATE")
|
|
|
|
|
/*println("TEMPLATE type PARENT IS TEMPLATE")*/
|
|
|
|
|
for (var i = 0; i < parent->template.template_types.size; i++;)
|
|
|
|
|
inherited_replacements[parent->template.template_types[i]] = parent->template.instantiated_map.reverse_get(parameter_types.first()->type_def)[i].clone()
|
|
|
|
|
} else {
|
|
|
|
|
println("TEMPLATE type PARENT IS NOT TEMPLATE")
|
|
|
|
|
/*println("TEMPLATE type PARENT IS NOT TEMPLATE")*/
|
|
|
|
|
}
|
|
|
|
|
possible_overload = find_or_instantiate_template_function(string("operator")+func_name, null<tree<symbol>>(), parameter_types.first()->type_def, parameter_types.slice(1,-1), template_replacements, inherited_replacements)
|
|
|
|
|
}
|
|
|
|
|
@@ -965,7 +948,7 @@ obj ast_transformation (Object) {
|
|
|
|
|
}
|
|
|
|
|
fun find_or_instantiate_template_function(name: string, template_inst: *tree<symbol>, scope: *ast_node, param_types: vector<*type>, template_replacements: map<string, *type>, replacements_base: map<string, *type>): *ast_node {
|
|
|
|
|
// replacments base is for templated methods starting off with the replacements of their parent (possibly templated) object
|
|
|
|
|
println(string("trying to instantiate a template function: ") + name)
|
|
|
|
|
/*println(string("trying to instantiate a template function: ") + name)*/
|
|
|
|
|
var results = scope_lookup(name, scope)
|
|
|
|
|
var real_types = vector<*type>()
|
|
|
|
|
var real_types_deref = vector<type>()
|
|
|
|
|
@@ -978,7 +961,7 @@ obj ast_transformation (Object) {
|
|
|
|
|
var fitting_functions = vector<pair<*ast_node, int>>()
|
|
|
|
|
for (var i = 0; i < results.size; i++;) {
|
|
|
|
|
if (is_template(results[i]) && results[i]->template.is_function) {
|
|
|
|
|
println(string() + i + " is a template!")
|
|
|
|
|
/*println(string() + i + " is a template!")*/
|
|
|
|
|
var template_types = results[i]->template.template_types
|
|
|
|
|
var template_type_replacements = results[i]->template.template_type_replacements
|
|
|
|
|
if (!had_real_types) {
|
|
|
|
|
@@ -992,7 +975,7 @@ obj ast_transformation (Object) {
|
|
|
|
|
continue
|
|
|
|
|
for (var j = 0; j < typed_params.size; j++;)
|
|
|
|
|
unify_type(typed_params[j], param_types[j], &unify_template_type_replacements, template_replacements)
|
|
|
|
|
for (var j = 0; j < typed_params.size; j++;) {
|
|
|
|
|
for (var j = 0; j < template_types.size; j++;) {
|
|
|
|
|
var t = unify_template_type_replacements[template_types[j]];
|
|
|
|
|
real_types.add(t)
|
|
|
|
|
real_types_deref.add(*t)
|
|
|
|
|
@@ -1004,47 +987,47 @@ obj ast_transformation (Object) {
|
|
|
|
|
template_type_replacements.for_each(fun(key: string, value: *type) num_satisfied_traits += value->traits.size();)
|
|
|
|
|
// check if already instantiated
|
|
|
|
|
var inst_func = null<ast_node>()
|
|
|
|
|
println(string("FOR TEMPLATE FUNCTION ") + name)
|
|
|
|
|
println("FOR FIND OR INSTATINTATE PREEEE")
|
|
|
|
|
template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)
|
|
|
|
|
println("MAP DONE")
|
|
|
|
|
/*println(string("FOR TEMPLATE FUNCTION ") + name)*/
|
|
|
|
|
/*println("FOR FIND OR INSTATINTATE PREEEE")*/
|
|
|
|
|
/*template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)*/
|
|
|
|
|
/*println("MAP DONE")*/
|
|
|
|
|
for (var j = 0; j < template_types.size; j++;) {
|
|
|
|
|
print("NEW TRAITS IN ALREADY: ")
|
|
|
|
|
template_type_replacements[template_types[j]]->traits.for_each(fun (t: string) print(t + " ");)
|
|
|
|
|
println()
|
|
|
|
|
print("NEW TRAITS PASSED IN: ")
|
|
|
|
|
real_types[j]->traits.for_each(fun (t: string) print(t + " ");)
|
|
|
|
|
println()
|
|
|
|
|
/*print("NEW TRAITS IN ALREADY: ")*/
|
|
|
|
|
/*template_type_replacements[template_types[j]]->traits.for_each(fun (t: string) print(t + " ");)*/
|
|
|
|
|
/*println()*/
|
|
|
|
|
/*print("NEW TRAITS PASSED IN: ")*/
|
|
|
|
|
/*real_types[j]->traits.for_each(fun (t: string) print(t + " ");)*/
|
|
|
|
|
/*println()*/
|
|
|
|
|
satisfied_traits = satisfied_traits && real_types[j]->traits.contains(template_type_replacements[template_types[j]]->traits) &&
|
|
|
|
|
(real_types[j]->indirection == 0 || template_type_replacements[template_types[j]]->traits.size() == 0)
|
|
|
|
|
template_type_replacements[template_types[j]] = real_types[j]
|
|
|
|
|
println("Just made")
|
|
|
|
|
println(template_types[j])
|
|
|
|
|
println("equal to")
|
|
|
|
|
println(real_types[j]->to_string())
|
|
|
|
|
/*println("Just made")*/
|
|
|
|
|
/*println(template_types[j])*/
|
|
|
|
|
/*println("equal to")*/
|
|
|
|
|
/*println(real_types[j]->to_string())*/
|
|
|
|
|
}
|
|
|
|
|
replacements_base.for_each(fun(key: string, value: *type) {
|
|
|
|
|
template_type_replacements[key] = value
|
|
|
|
|
println("Just Inherited")
|
|
|
|
|
println(key)
|
|
|
|
|
println("equal to")
|
|
|
|
|
println(value->to_string())
|
|
|
|
|
/*println("Just Inherited")*/
|
|
|
|
|
/*println(key)*/
|
|
|
|
|
/*println("equal to")*/
|
|
|
|
|
/*println(value->to_string())*/
|
|
|
|
|
})
|
|
|
|
|
println("FOR FIND OR INSTATINTATE")
|
|
|
|
|
template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)
|
|
|
|
|
println("MAP DONE")
|
|
|
|
|
/*println("FOR FIND OR INSTATINTATE")*/
|
|
|
|
|
/*template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)*/
|
|
|
|
|
/*println("MAP DONE")*/
|
|
|
|
|
|
|
|
|
|
if (!satisfied_traits) {
|
|
|
|
|
println("Did not satisfy traits!")
|
|
|
|
|
/*println("Did not satisfy traits!")*/
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if (real_types.any_true(fun(t: *type): bool return t->is_none() || t ->is_template_type();)) {
|
|
|
|
|
println("Instantiating types not all real types!")
|
|
|
|
|
/*println("Instantiating types not all real types!")*/
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (results[i]->template.instantiated_map.contains_key(real_types_deref)) {
|
|
|
|
|
println("USING CACHED TEMPLATE FUNCITON")
|
|
|
|
|
/*println("USING CACHED TEMPLATE FUNCITON")*/
|
|
|
|
|
inst_func = results[i]->template.instantiated_map[real_types_deref]
|
|
|
|
|
} else {
|
|
|
|
|
inst_func = second_pass_function(results[i]->template.syntax_node, results[i], template_type_replacements, false)
|
|
|
|
|
@@ -1057,12 +1040,12 @@ obj ast_transformation (Object) {
|
|
|
|
|
}
|
|
|
|
|
if (function_satisfies_params(inst_func, param_types))
|
|
|
|
|
fitting_functions.add(make_pair(inst_func, num_satisfied_traits))
|
|
|
|
|
else
|
|
|
|
|
println(string("this paticular ") + name + " did not satisfy params")
|
|
|
|
|
/*else*/
|
|
|
|
|
/*println(string("this paticular ") + name + " did not satisfy params")*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (fitting_functions.size == 0) {
|
|
|
|
|
println("no working templated method found")
|
|
|
|
|
/*println("no working templated method found")*/
|
|
|
|
|
return null<ast_node>()
|
|
|
|
|
}
|
|
|
|
|
return fitting_functions.max(fun(a: pair<*ast_node, int>, b: pair<*ast_node, int>): bool return a.second < b.second;).first
|
|
|
|
|
@@ -1070,23 +1053,23 @@ obj ast_transformation (Object) {
|
|
|
|
|
}
|
|
|
|
|
fun has_method(object: *ast_node, name: *char, parameter_types: vector<*type>): bool return has_method(object, string(name), parameter_types);
|
|
|
|
|
fun has_method(object: *ast_node, name: string, parameter_types: vector<*type>): bool {
|
|
|
|
|
println("HAS METHOD:")
|
|
|
|
|
/*println("HAS METHOD:")*/
|
|
|
|
|
var to_ret = function_lookup(name, object, parameter_types) || false
|
|
|
|
|
println("HAS METHOD result:")
|
|
|
|
|
println(to_ret)
|
|
|
|
|
/*println("HAS METHOD result:")*/
|
|
|
|
|
/*println(to_ret)*/
|
|
|
|
|
return to_ret
|
|
|
|
|
}
|
|
|
|
|
fun make_method_call(object_ident: *ast_node, name: *char, parameters: vector<*ast_node>): *ast_node return make_method_call(object_ident, string(name), parameters);
|
|
|
|
|
fun make_method_call(object_ident: *ast_node, name: string, parameters: vector<*ast_node>): *ast_node {
|
|
|
|
|
println("MAKE METHOD CALL OUT:")
|
|
|
|
|
/*println("MAKE METHOD CALL OUT:")*/
|
|
|
|
|
// note that this type_def is the adt_def if this is an adt type
|
|
|
|
|
var method = function_lookup(name, get_ast_type(object_ident)->type_def, parameters.map(fun(param: *ast_node): *type return get_ast_type(param);))
|
|
|
|
|
print("Here is the Method: ")
|
|
|
|
|
println(method)
|
|
|
|
|
/*print("Here is the Method: ")*/
|
|
|
|
|
/*println(method)*/
|
|
|
|
|
return make_method_call(object_ident, method, parameters)
|
|
|
|
|
}
|
|
|
|
|
fun make_method_call(object_ident: *ast_node, method: *ast_node, parameters: vector<*ast_node>): *ast_node {
|
|
|
|
|
println("MAKE METHOD CALL IN:")
|
|
|
|
|
/*println("MAKE METHOD CALL IN:")*/
|
|
|
|
|
var method_access = ast_function_call_ptr(get_builtin_function(string("."), vector(get_ast_type(object_ident), get_ast_type(method))), vector(object_ident, method))
|
|
|
|
|
return ast_function_call_ptr(method_access, parameters)
|
|
|
|
|
}
|
|
|
|
|
@@ -1112,7 +1095,7 @@ fun get_builtin_function(name: string, param_types: vector<*type>): *ast_node {
|
|
|
|
|
return ast_function_ptr(name, type_ptr(param_types, param_types[0]), vector<*ast_node>())
|
|
|
|
|
}
|
|
|
|
|
fun unify_type(template_type: *tree<symbol>, param_type: *type, new_map: *map<string, *type>, template_replacements: map<string, *type>) {
|
|
|
|
|
println(string("Unifying type: ") + concat_symbol_tree(template_type))
|
|
|
|
|
/*println(string("Unifying type: ") + concat_symbol_tree(template_type))*/
|
|
|
|
|
// first get rid of the reference if we have it - we don't care for unification
|
|
|
|
|
if (get_node("pre_reffed", template_type))
|
|
|
|
|
template_type = get_node("pre_reffed", template_type)
|
|
|
|
|
@@ -1126,20 +1109,20 @@ fun unify_type(template_type: *tree<symbol>, param_type: *type, new_map: *map<st
|
|
|
|
|
// to object templates at all ;)
|
|
|
|
|
if (template_type->children.size == 1) {
|
|
|
|
|
if (get_node("function_type", template_type)) {
|
|
|
|
|
println("UNIFYING FUNCTION")
|
|
|
|
|
/*println("UNIFYING FUNCTION")*/
|
|
|
|
|
var template_function_types = get_nodes("type", get_node("function_type", template_type))
|
|
|
|
|
if (!param_type->is_function() || template_function_types.size -1 != param_type->parameter_types.size) {
|
|
|
|
|
println("not combining function because:")
|
|
|
|
|
println(param_type->is_function())
|
|
|
|
|
println(template_function_types.size-1)
|
|
|
|
|
println(param_type->parameter_types.size)
|
|
|
|
|
/*println("not combining function because:")*/
|
|
|
|
|
/*println(param_type->is_function())*/
|
|
|
|
|
/*println(template_function_types.size-1)*/
|
|
|
|
|
/*println(param_type->parameter_types.size)*/
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
for (var i = 0; i < template_function_types.size-1; i++;)
|
|
|
|
|
unify_type(template_function_types[i], param_type->parameter_types[i], new_map, template_replacements)
|
|
|
|
|
unify_type(template_function_types.last(), param_type->return_type, new_map, template_replacements)
|
|
|
|
|
} else {
|
|
|
|
|
println(string("setting ") + concat_symbol_tree(template_type) + " equal to " + param_type->to_string())
|
|
|
|
|
/*println(string("setting ") + concat_symbol_tree(template_type) + " equal to " + param_type->to_string())*/
|
|
|
|
|
new_map->set(concat_symbol_tree(template_type), param_type)
|
|
|
|
|
}
|
|
|
|
|
} else if (get_node("\"\\*\"", template_type)) {
|
|
|
|
|
@@ -1151,19 +1134,19 @@ fun unify_type(template_type: *tree<symbol>, param_type: *type, new_map: *map<st
|
|
|
|
|
var inst_params = enclosing_template->template.instantiated_map.reverse_get(param_type->type_def)
|
|
|
|
|
var template_params = get_nodes("type", get_node("template_inst", template_type))
|
|
|
|
|
if (inst_params.size == template_params.size) {
|
|
|
|
|
println("TEMPLATE inference should be successful")
|
|
|
|
|
/*println("TEMPLATE inference should be successful")*/
|
|
|
|
|
for (var i = 0; i < inst_params.size; i++;)
|
|
|
|
|
unify_type(template_params[i], inst_params[i].clone(), new_map, template_replacements)
|
|
|
|
|
} else {
|
|
|
|
|
println("TEMPLATE inference hit different sizes")
|
|
|
|
|
/*println("TEMPLATE inference hit different sizes")*/
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// error("TEMPLATE inference hit non parent template")
|
|
|
|
|
println("TEMPLATE inference hit non parent template")
|
|
|
|
|
/*println("TEMPLATE inference hit non parent template")*/
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// error("TEMPLATE inference hit non object")
|
|
|
|
|
println("TEMPLATE inference hit non object")
|
|
|
|
|
/*println("TEMPLATE inference hit non object")*/
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
println(template_type->children[0]->data.name)
|
|
|
|
|
@@ -1176,13 +1159,13 @@ fun function_satisfies_params(node: *ast_node, param_types: vector<*type>): bool
|
|
|
|
|
var param_string = string()
|
|
|
|
|
param_types.for_each(fun(t: *type) param_string += t->to_string() + ", ";)
|
|
|
|
|
if (func_param_types.size != param_types.size) {
|
|
|
|
|
println(string("type sizes don't match ") + param_types.size + " with needed " + param_string)
|
|
|
|
|
/*println(string("type sizes don't match ") + param_types.size + " with needed " + param_string)*/
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
for (var j = 0; j < param_types.size; j++;) {
|
|
|
|
|
// don't care about references
|
|
|
|
|
if (!func_param_types[j]->equality(param_types[j], false)) {
|
|
|
|
|
println(string("types don't match ") + func_param_types[j]->to_string() + " with needed " + param_types[j]->to_string())
|
|
|
|
|
/*println(string("types don't match ") + func_param_types[j]->to_string() + " with needed " + param_types[j]->to_string())*/
|
|
|
|
|
if (func_param_types[j]->to_string() == param_types[j]->to_string())
|
|
|
|
|
error("types aren't equal, but their string rep is (and ref doesn't even matter)")
|
|
|
|
|
return false
|
|
|
|
|
@@ -1191,22 +1174,22 @@ fun function_satisfies_params(node: *ast_node, param_types: vector<*type>): bool
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
fun function_lookup(name: string, scope: *ast_node, param_types: vector<*type>): *ast_node {
|
|
|
|
|
println(string("doing function lookup for: ") + name)
|
|
|
|
|
/*println(string("doing function lookup for: ") + name)*/
|
|
|
|
|
var results = scope_lookup(name, scope)
|
|
|
|
|
print(results.size); println(" number of results")
|
|
|
|
|
/*print(results.size); println(" number of results")*/
|
|
|
|
|
for (var i = 0; i < results.size; i++;) {
|
|
|
|
|
if ((is_function(results[i]) || (is_identifier(results[i]) && get_ast_type(results[i])->is_function())) && function_satisfies_params(results[i], param_types)) {
|
|
|
|
|
return results[i]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
println(string("function lookup failed for ") + name)
|
|
|
|
|
/*println(string("function lookup failed for ") + name)*/
|
|
|
|
|
return null<ast_node>()
|
|
|
|
|
}
|
|
|
|
|
fun identifier_lookup(name: string, scope: *ast_node): *ast_node {
|
|
|
|
|
println(string("doing identifier lookup for: ") + name)
|
|
|
|
|
/*println(string("doing identifier lookup for: ") + name)*/
|
|
|
|
|
var results = scope_lookup(name, scope)
|
|
|
|
|
if (!results.size) {
|
|
|
|
|
println(string("identifier lookup failed for ") + name)
|
|
|
|
|
/*println(string("identifier lookup failed for ") + name)*/
|
|
|
|
|
return null<ast_node>()
|
|
|
|
|
}
|
|
|
|
|
return results[0]
|
|
|
|
|
@@ -1280,7 +1263,7 @@ fun get_node(lookup: *char, parent: *tree<symbol>): *tree<symbol> {
|
|
|
|
|
fun get_node(lookup: string, parent: *tree<symbol>): *tree<symbol> {
|
|
|
|
|
var results = get_nodes(lookup, parent)
|
|
|
|
|
if (results.size > 1)
|
|
|
|
|
println("too many results!")
|
|
|
|
|
error("get node too many results!")
|
|
|
|
|
if (results.size)
|
|
|
|
|
return results[0]
|
|
|
|
|
return null<tree<symbol>>()
|
|
|
|
|
|