diff --git a/src/CGenerator.cpp b/src/CGenerator.cpp index 745f94f..174436b 100644 --- a/src/CGenerator.cpp +++ b/src/CGenerator.cpp @@ -510,8 +510,13 @@ CCodeTriple CGenerator::generate(NodeTree* from, NodeTree* enc throw "Error: this used in non-object scope"; } //If we're in an object method, and our enclosing scope is that object, we're a member of the object and should use the this reference. - if (enclosingObject && enclosingObject->getDataRef()->scope.find(data.symbol.getName()) != enclosingObject->getDataRef()->scope.end()) - preName = "(" + preName + "this)->"; // incase this is a closed over this that is referencing another thing (I think this happens for a.b when a is supposed to be closed over but isn't) + //if (enclosingObject && enclosingObject->getDataRef()->scope.find(data.symbol.getName()) != enclosingObject->getDataRef()->scope.end()) + // the old one would actually activate if the object even had one of the same name + if (enclosingObject) { + auto containing = enclosingObject->getDataRef()->scope.find(data.symbol.getName()); + if (containing != enclosingObject->getDataRef()->scope.end() && std::find(containing->second.begin(), containing->second.end(), from) != containing->second.end()) + preName = "(" + preName + "this)->"; // incase this is a closed over this that is referencing another thing (I think this happens for a.b when a is supposed to be closed over but isn't) + } // dereference references, but only if inside a function and not if this is a closed over variable if (enclosingFunction && data.valueType->is_reference && !closed) { preName += "(*"; diff --git a/stdlib/ast_transformation.krak b/stdlib/ast_transformation.krak index 125984e..205dad6 100644 --- a/stdlib/ast_transformation.krak +++ b/stdlib/ast_transformation.krak @@ -451,9 +451,15 @@ fun transform_expression(node: *tree, scope: *ast_node, searching_for: s // ignore everything and do a passthrough var func_name = string() var parameters = vector<*ast_node>() - if (node->children.size == 1) - return transform(node->children[0], scope, searching_for, template_replacements) - else if (node->children.size == 2) { + if (node->children.size == 1) { + var possible_func = transform(node->children[0], scope, searching_for, template_replacements) + if (!possible_func) match (searching_for) { + search_type::function(type_vec) possible_func = find_or_instantiate_function_template(node->children[0], null>(), scope, type_vec, template_replacements); + } + if (!possible_func) + println(concat_symbol_tree(node) + ": HAS NO POSSIBLE FUNCTION OR FUNCTION TEMPLATE SOLUTIONS") + return possible_func + } else if (node->children.size == 2) { var template_inst = get_node("template_inst", node) if (template_inst) { var identifier = get_node("scoped_identifier", node) @@ -503,17 +509,36 @@ fun get_builtin_function(name: string, param_types: vector<*type>): *ast_node { return ast_function_ptr(name, type_ptr(param_types, param_types[1]), vector<*ast_node>()) return ast_function_ptr(name, type_ptr(param_types, param_types[0]), vector<*ast_node>()) } +fun unify_type(template_type: *tree, param_type: *type, new_map: *map, template_replacements: map) { + println(string("Unifying type: ") + concat_symbol_tree(template_type)) +} fun find_or_instantiate_function_template(identifier: *tree, template_inst: *tree, scope: *ast_node, param_types: vector<*type>, template_replacements: map): *ast_node { var name = concat_symbol_tree(identifier) println(string("trying to instantiate a template function: ") + name) var results = scope_lookup(name, scope) - var real_types = get_nodes("type", template_inst).map(fun(t: *tree): *type return transform_type(t, scope, template_replacements);) - var real_types_deref = real_types.map(fun(t:*type):type return *t;) + var real_types = vector<*type>() + var real_types_deref = vector() + if (template_inst) { + real_types = get_nodes("type", template_inst).map(fun(t: *tree): *type return transform_type(t, scope, template_replacements);) + real_types_deref = real_types.map(fun(t:*type):type return *t;) + } for (var i = 0; i < results.size; i++;) { if (is_function_template(results[i])) { var template_types = results[i]->function_template.template_types var template_type_replacements = results[i]->function_template.template_type_replacements - if (template_types.size != real_types.size) + if (!real_types.size) { + // Template Function Instance Inference time + var typed_params = get_nodes("typed_parameter", results[i]->function_template.syntax_node).map(fun(t: *tree): *tree return get_node("type",t);) + if (param_types.size != typed_params.size) + continue + for (var j = 0; j < typed_params.size; j++;) + unify_type(typed_params[j], param_types[j], &template_type_replacements, template_replacements) + for (var j = 0; j < typed_params.size; j++;) { + var t = template_type_replacements[template_types[j]]; + real_types.add(t) + real_types_deref.add(*t) + } + } else if (template_types.size != real_types.size) continue // check if already instantiated var inst_func = null() diff --git a/stdlib/c_generator.krak b/stdlib/c_generator.krak index fce1590..080da20 100644 --- a/stdlib/c_generator.krak +++ b/stdlib/c_generator.krak @@ -243,7 +243,7 @@ obj c_generator (Object) { return to_ret } fun generate_identifier(node: *ast_node, enclosing_object: *ast_node): code_triple { - if (enclosing_object && get_ast_scope(enclosing_object)->contains_key(node->identifier.name)) + if (enclosing_object && get_ast_scope(enclosing_object)->contains_key(node->identifier.name) && get_ast_scope(enclosing_object)->get(node->identifier.name).contains(node)) return code_triple("(this->") + node->identifier.name + ")" return code_triple(node->identifier.name) } diff --git a/tests/to_parse.krak b/tests/to_parse.krak index bff3883..e69673a 100644 --- a/tests/to_parse.krak +++ b/tests/to_parse.krak @@ -52,13 +52,14 @@ fun some_other_function(in: bool): float { } */ fun main(): int { - var a = id(7) - println(a) - var b = id(8) + println(id("Wooo function template inference")) + /*var a = id(7)*/ + /*println(a)*/ + /*var b = id(8)*/ /*var b = id<*char>("Double down time")*/ /*println(b)*/ - println(id("Double down time")) - println(other_id<*char>("Triple down time")) + /*println(id("Double down time"))*/ + /*println(other_id<*char>("Triple down time"))*/