More work. Doesn't compile at this point
This commit is contained in:
@@ -797,6 +797,8 @@ obj ast_transformation (Object) {
|
||||
// don't bother with a full transform for parameters with their own function, just get the boolean expression and transform it
|
||||
var parameters = get_nodes("parameter", node).map(fun(child: *tree<symbol>): *ast_node return transform(get_node("boolean_expression", child), scope, template_replacements);)
|
||||
var parameter_types = parameters.map(fun(param: *ast_node): *type return get_ast_type(param);)
|
||||
if (parameter_types.any_true(fun(ptype: *type): bool return !ptype;))
|
||||
error(node, "One of the parameter types is null!")
|
||||
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
|
||||
var func_type = get_ast_type(func)
|
||||
|
||||
@@ -3,6 +3,7 @@ import tree:*
|
||||
import vector:*
|
||||
import map:*
|
||||
import util:*
|
||||
import type:*
|
||||
import string:*
|
||||
import mem:*
|
||||
import io:*
|
||||
@@ -79,19 +80,26 @@ fun function_value_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node
|
||||
|
||||
var void_ptr = type_ptr(base_type::void_return(), 1); // this most vexing parse actually causes a compiler segfault as it tries to call the result of type_ptr as a function....
|
||||
// AND IT STILL DOES EVEN WITH ALL MY CHEKCS
|
||||
var lambda_type_to_struct_type = map<type, *type>(); //freaking vexing parse moved
|
||||
(function_types_needed_wo_lambdas + function_types_needed_for_lambdas).for_each(fun(t: type) {
|
||||
var cleaned = t.clone()
|
||||
cleaned->is_raw = true
|
||||
|
||||
var new_type_def_name = t.to_string() + "_function_value_struct"
|
||||
var new_type_def = ast_type_def_ptr(new_type_def_name)
|
||||
new_type_def->type_def.variables.add(ast_declaration_statement_ptr(ast_identifier_ptr("func", cleaned, new_type_def), null<ast_node>()))
|
||||
new_type_def->type_def.variables.add(ast_declaration_statement_ptr(ast_identifier_ptr("data", void_ptr, new_type_def), null<ast_node>()))
|
||||
var func_ident = ast_identifier_ptr("func", cleaned, new_type_def)
|
||||
add_to_scope("func", func_ident, new_type_def)
|
||||
var data_ident = ast_identifier_ptr("data", void_ptr, new_type_def)
|
||||
add_to_scope("data", data_ident, new_type_def)
|
||||
new_type_def->type_def.variables.add(ast_declaration_statement_ptr(func_ident, null<ast_node>()))
|
||||
new_type_def->type_def.variables.add(ast_declaration_statement_ptr(data_ident, null<ast_node>()))
|
||||
add_to_scope("~enclosing_scope", name_ast_map->values.first().second, new_type_def)
|
||||
add_to_scope(new_type_def_name, new_type_def, name_ast_map->values.first().second)
|
||||
name_ast_map->values.first().second->translation_unit.children.add(new_type_def)
|
||||
lambda_type_to_struct_type[t] = type_ptr(new_type_def)
|
||||
})
|
||||
|
||||
var lambda_creation_funcs = map<*ast_node, *ast_node>()
|
||||
// create the closure type for each lambda
|
||||
var closure_id = 0
|
||||
lambdas.for_each(fun(l: *ast_node) {
|
||||
@@ -106,8 +114,23 @@ fun function_value_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node
|
||||
add_to_scope(new_type_def_name, new_type_def, name_ast_map->values.first().second)
|
||||
name_ast_map->values.first().second->translation_unit.children.add(new_type_def)
|
||||
}
|
||||
|
||||
var return_type = lambda_type_to_struct_type[*l->function.type]
|
||||
var creation_type = type_ptr(vector<*type>(), return_type, 0, false, false, true)
|
||||
lambda_creation_funcs[l] = ast_function_ptr(l->function.name + "_creation", creation_type, vector<*ast_node>(), false);
|
||||
var body = ast_code_block_ptr()
|
||||
var ident = ast_identifier_ptr("to_ret", return_type, body)
|
||||
body->code_block.children.add(ast_declaration_statement_ptr(ident, null<ast_node>()))
|
||||
body->code_block.children.add(ast_assignment_statement_ptr(access_expression(ident, "func"), l))
|
||||
body->code_block.children.add(ast_assignment_statement_ptr(access_expression(ident, "data"), ast_value_ptr(string("0"), type_ptr(base_type::void_return(), 1))))
|
||||
lambda_creation_funcs[l]->function.body_statement = body
|
||||
name_ast_map->values.first().second->translation_unit.children.add(lambda_creation_funcs[l])
|
||||
// after we use it's type to look up the new one...
|
||||
l->function.type->is_raw = true;
|
||||
})
|
||||
function_value_creation_points.for_each(fun(p: function_parent_block) {
|
||||
var func_call = ast_function_call_ptr(lambda_creation_funcs[p.function], vector<*ast_node>())
|
||||
replace_with_in(p.function, func_call, p.parent)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -49,9 +49,9 @@ fun is_dot_style_method_call(node: *ast_node): bool {
|
||||
fun function_satisfies_params(node: *ast_node, param_types: vector<*type>): bool {
|
||||
var func_type = get_ast_type(node)
|
||||
var func_param_types = func_type->parameter_types
|
||||
var param_string = string()
|
||||
param_types.for_each(fun(t: *type) param_string += t->to_string() + ", ";)
|
||||
if (!func_type->is_variadic && func_param_types.size != param_types.size) {
|
||||
var param_string = string()
|
||||
param_types.for_each(fun(t: *type) param_string += t->to_string() + ", ";)
|
||||
/*println(string("type sizes don't match ") + param_types.size + " with needed " + param_string)*/
|
||||
return false
|
||||
} else if (param_types.size < func_param_types.size) {
|
||||
@@ -70,6 +70,19 @@ fun function_satisfies_params(node: *ast_node, param_types: vector<*type>): bool
|
||||
}
|
||||
return true
|
||||
}
|
||||
fun access_expression(left: *ast_node, right: *char): *ast_node return access_expression(left, string(right))
|
||||
fun access_expression(left: *ast_node, right: ref string): *ast_node {
|
||||
var ltype = get_ast_type(left)
|
||||
if (!ltype->is_object())
|
||||
error("Trying to generate an access expression and the left side is not an object")
|
||||
var ident = identifier_lookup(right, ltype->type_def)
|
||||
if (!ident)
|
||||
error("Trying to generate an access expression, can't find right: " + right)
|
||||
|
||||
if (ltype->indirection)
|
||||
return make_operator_call("->", vector(left, ident))
|
||||
return make_operator_call(".", vector(left, ident))
|
||||
}
|
||||
fun function_lookup(name: string, scope: *ast_node, param_types: vector<*type>): *ast_node {
|
||||
var results = scope_lookup(name, scope)
|
||||
for (var i = 0; i < results.size; i++;) {
|
||||
|
||||
Reference in New Issue
Block a user