More work. Doesn't compile at this point

This commit is contained in:
Nathan Braswell
2017-02-23 01:24:22 -05:00
parent cb8124afc0
commit 8a676a1b5b
3 changed files with 42 additions and 4 deletions

View File

@@ -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)

View File

@@ -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)
})
}

View File

@@ -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++;) {