diff --git a/stdlib/ast_transformation.krak b/stdlib/ast_transformation.krak index 1e37b88..fc6ddf1 100644 --- a/stdlib/ast_transformation.krak +++ b/stdlib/ast_transformation.krak @@ -172,9 +172,9 @@ obj ast_transformation (Object) { var function_node = null() if (type_syntax) { var identifier_param = ast_identifier_ptr(option_name, ident_type, node) - function_node = ast_function_ptr(option_name, type_ptr(vector(get_ast_type(identifier_param)), node->adt_def.self_type, 0, false, false, false), vector(identifier_param), false) + function_node = ast_function_ptr(option_name, type_ptr(vector(get_ast_type(identifier_param)), node->adt_def.self_type, 0, false, false, true), vector(identifier_param), false) } else { - function_node = ast_function_ptr(option_name, type_ptr(vector<*type>(), node->adt_def.self_type, 0, false, false, false), vector<*ast_node>(), false) + function_node = ast_function_ptr(option_name, type_ptr(vector<*type>(), node->adt_def.self_type, 0, false, false, true), vector<*ast_node>(), false) } add_to_scope(option_name, function_node, node) add_to_scope("~enclosing_scope", node, function_node) @@ -190,11 +190,11 @@ obj ast_transformation (Object) { var assign_param = ast_identifier_ptr(string("in"), node->adt_def.self_type->clone_with_indirection(0,true), node) vector( make_pair("operator==", ast_function_ptr(string("operator=="), type_ptr(vector(equals_param->identifier.type), type_ptr(base_type::boolean()), 0, false, false, false), vector(equals_param), false)), - make_pair("operator!=", ast_function_ptr(string("operator!="), type_ptr(vector(nequals_param->identifier.type), type_ptr(base_type::boolean()), 0, false, false, false), vector(nequals_param), false)), - make_pair("construct", ast_function_ptr(string("construct"), type_ptr(vector<*type>(), node->adt_def.self_type->clone_with_increased_indirection(), 0, false, false, false), vector<*ast_node>(), false)), - make_pair("copy_construct", ast_function_ptr(string("copy_construct"), type_ptr(vector(copy_construct_param->identifier.type), type_ptr(base_type::void_return()), 0, false, false, false), vector(copy_construct_param), false)), - make_pair("operator=", ast_function_ptr(string("operator="), type_ptr(vector(assign_param->identifier.type), type_ptr(base_type::void_return()), 0, false, false, false), vector(assign_param), false)), - make_pair("destruct", ast_function_ptr(string("destruct"), type_ptr(vector<*type>(), type_ptr(base_type::void_return()), 0, false, false, false), vector<*ast_node>(), false)) + make_pair("operator!=", ast_function_ptr(string("operator!="), type_ptr(vector(nequals_param->identifier.type), type_ptr(base_type::boolean()), 0, false, false, true), vector(nequals_param), false)), + make_pair("construct", ast_function_ptr(string("construct"), type_ptr(vector<*type>(), node->adt_def.self_type->clone_with_increased_indirection(), 0, false, false, true), vector<*ast_node>(), false)), + make_pair("copy_construct", ast_function_ptr(string("copy_construct"), type_ptr(vector(copy_construct_param->identifier.type), type_ptr(base_type::void_return()), 0, false, false, true), vector(copy_construct_param), false)), + make_pair("operator=", ast_function_ptr(string("operator="), type_ptr(vector(assign_param->identifier.type), type_ptr(base_type::void_return()), 0, false, false, true), vector(assign_param), false)), + make_pair("destruct", ast_function_ptr(string("destruct"), type_ptr(vector<*type>(), type_ptr(base_type::void_return()), 0, false, false, true), vector<*ast_node>(), false)) ).for_each(fun(func_pair: pair<*char, *ast_node>) { node->adt_def.regular_funcs.add(func_pair.second) add_to_scope(string(func_pair.first), func_pair.second, node) @@ -240,7 +240,7 @@ obj ast_transformation (Object) { parameters.add(ast_identifier_ptr(concat_symbol_tree(get_node("identifier", child)), param_type, null())) }) var is_variadic = get_node("\"...\"", node) != null>() - var is_raw = false + var is_raw = function_name != "__compiler_lambda__" // figure out function type and make function_node var function_node = ast_function_ptr(function_name, type_ptr(parameters.map(fun(parameter: *ast_node): *type return parameter->identifier.type;), diff --git a/stdlib/function_value_lower.krak b/stdlib/function_value_lower.krak index 2e9a1a7..ac6a548 100644 --- a/stdlib/function_value_lower.krak +++ b/stdlib/function_value_lower.krak @@ -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,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree>) { var visited = hash_set<*ast_node>() var lambdas = set<*ast_node>() - var function_types_needed_wo_lambdas = set() + var all_types = set<*type>() var function_value_creation_points = vector() name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree,*ast_node>) { lambdas.add(syntax_ast_pair.second->translation_unit.lambdas) }) name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree,*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,*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(); //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())) - new_type_def->type_def.variables.add(ast_declaration_statement_ptr(data_ident, null())) - 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())) + new_type_def->type_def.variables.add(ast_declaration_statement_ptr(data_ident, null())) + 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,*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] + }) }