more lowering

This commit is contained in:
Nathan Braswell
2017-04-08 16:10:57 -04:00
parent 9662197c21
commit a0c040da36
2 changed files with 36 additions and 37 deletions

View File

@@ -29,13 +29,15 @@ fun make_function_parent_block(function: *ast_node, parent: *ast_node, block: *a
fun function_value_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
var visited = hash_set<*ast_node>()
var lambdas = set<*ast_node>()
var function_types_needed_wo_lambdas = set<type>()
var all_types = set<*type>()
var function_value_creation_points = vector<function_parent_block>()
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) {
lambdas.add(syntax_ast_pair.second->translation_unit.lambdas)
})
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) {
var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
var t = get_ast_type(node)
if (t) all_types.add(t)
match(*node) {
ast_node::function(backing) {
var parent = parent_chain->top()
@@ -58,45 +60,37 @@ fun function_value_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node
parent_chain->item_from_top_satisfying(fun(i: *ast_node): bool return is_code_block(i);)))
}
if (backing.type->return_type->is_function())
function_types_needed_wo_lambdas.add(*backing.type->return_type)
for (var i = 0; i < backing.type->parameter_types.size; i++;)
if (backing.type->parameter_types[i]->is_function())
function_types_needed_wo_lambdas.add(*backing.type->parameter_types[i])
}
ast_node::identifier(backing) {
if (backing.type->is_function())
function_types_needed_wo_lambdas.add(*backing.type)
}
}
}
run_on_tree(helper_before, empty_pass_second_half, syntax_ast_pair.second, &visited)
})
var function_types_needed_for_lambdas = lambdas.map(fun(l: *ast_node): type { return *l->function.type; })
println(string("there are ") + function_value_creation_points.size + " function value creation points in the program.")
println(string("there are ") + function_types_needed_wo_lambdas.size() + " function types needed wo lambdas in the program.")
println(string("there are ") + function_types_needed_for_lambdas.size() + " function types needed for lambdas in the program.")
println(string("there are ") + (function_types_needed_wo_lambdas + function_types_needed_for_lambdas).size() + " total (set union, not addition) in the program.")
println(string("there are ") + all_types.size() + " all types in the program.")
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 all_type_values = all_types.map(fun(t: *type): type return *t;)
all_type_values.for_each(fun(t: type) {
if (t.is_function() && !t.is_raw) {
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)
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 new_type_def_name = t.to_string() + "_function_value_struct"
var new_type_def = ast_type_def_ptr(new_type_def_name)
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>()
@@ -132,5 +126,10 @@ fun function_value_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node
var func_call = ast_function_call_ptr(lambda_creation_funcs[p.function], vector<*ast_node>())
replace_with_in(p.function, func_call, p.parent)
})
lambdas.for_each(fun(l: *ast_node) l->function.type = l->function.type->clone();)
all_types.for_each(fun(t: *type) {
if (lambda_type_to_struct_type.contains_key(*t))
*t = *lambda_type_to_struct_type[*t]
})
}