From 405ee70db8cf7c296baeea753139e0ff62271ce5 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Tue, 12 Jun 2018 23:29:39 -0400 Subject: [PATCH] Change ADTs to generate a copy_construct() that returns this, which should be our new default. Fix storing functions in vectors (lots of bugs here, with funciton types in templates, sizeof, returned by ref, etc. might have missed a few more, put in some warning comments --- stdlib/adt_lower.krak | 1 + stdlib/ast_transformation.krak | 2 +- stdlib/c_generator.krak | 2 +- stdlib/function_value_lower.krak | 32 +++++++++++++++++++++++++++----- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/stdlib/adt_lower.krak b/stdlib/adt_lower.krak index b7de80c..3c80f75 100644 --- a/stdlib/adt_lower.krak +++ b/stdlib/adt_lower.krak @@ -108,6 +108,7 @@ fun adt_lower(name_ast_map: *map,*ast_node>>, ast_to_syn if_stmt_inner->if_statement.then_part = assign_or_copy_construct_statement(our_option, their_option) block->code_block.children.add(if_stmt_inner) } + block->code_block.children.add(_return(func_this)) } else if (func->function.name == "operator=") { var other = func->function.parameters[0] block->code_block.children.add(make_method_call(func_this, "destruct", vec<*ast_node>())) diff --git a/stdlib/ast_transformation.krak b/stdlib/ast_transformation.krak index ab9bd32..4554b0e 100644 --- a/stdlib/ast_transformation.krak +++ b/stdlib/ast_transformation.krak @@ -198,7 +198,7 @@ obj ast_transformation (Object) { type_ptr(vec<*type>(), node->adt_def.self_type->clone_with_increased_indirection(), 0, false, false, true), vec<*ast_node>(), _ident("this", node->adt_def.self_type->clone_with_indirection(1), node), false, false)), make_pair("copy_construct", _function(str("copy_construct"), - type_ptr(vec(copy_construct_param->identifier.type), type_ptr(base_type::void_return()), 0, false, false, true), + type_ptr(vec(copy_construct_param->identifier.type), node->adt_def.self_type->clone_with_increased_indirection(), 0, false, false, true), vec(copy_construct_param), _ident("this", node->adt_def.self_type->clone_with_indirection(1), node), false, false)), make_pair("operator=", _function(str("operator="), type_ptr(vec(assign_param->identifier.type), type_ptr(base_type::void_return()), 0, false, false, true), diff --git a/stdlib/c_generator.krak b/stdlib/c_generator.krak index 6fcd888..29a3eb0 100644 --- a/stdlib/c_generator.krak +++ b/stdlib/c_generator.krak @@ -446,7 +446,7 @@ obj c_generator (Object) { return str("impossible type") + indirection } fun type_decoration(type: *type): str { - return cify_name(type_to_c(type)) + return cify_name(type->to_string()) } fun get_name(node: *ast_node): str { var maybe_it = ast_name_map.get_ptr_or_null(node); diff --git a/stdlib/function_value_lower.krak b/stdlib/function_value_lower.krak index efe50c1..26af279 100644 --- a/stdlib/function_value_lower.krak +++ b/stdlib/function_value_lower.krak @@ -109,6 +109,8 @@ fun function_value_lower(name_ast_map: *map,*ast_node>>, var t = get_ast_type(node) if (t) all_types.add(t) match(*node) { + // gotta get #sizeof + ast_node::compiler_intrinsic(c) c.type_parameters.for_each( fun(item: *type) all_types.add(item); ) ast_node::identifier(backing) { // see if this identifier use is a closed variable in a closure var enclosing_func = parent_chain->item_from_top_satisfying_or(fun(n: *ast_node): bool return is_function(n);, null()) @@ -146,10 +148,15 @@ fun function_value_lower(name_ast_map: *map,*ast_node>>, return from_vector(t->parameter_types + t->return_type) return set<*type>() }) - var all_type_values = all_types.map(fun(t: *type): type return *t;) + var all_type_values = all_types.map(fun(t: *type): type { + if (t->indirection != 0 || t->is_ref) + return *t->clone_with_indirection(0, false) + else + return *t + }) curr_time = split(curr_time, "\tall types/all type values") all_type_values.for_each(fun(t: type) { - if (t.is_function() && t.indirection == 0 && !t.is_raw && !lambda_type_to_struct_type_and_call_func.contains_key(t)) { + if (t.is_function() && t.indirection == 0 && !t.is_ref && !t.is_raw && !lambda_type_to_struct_type_and_call_func.contains_key(t)) { var cleaned = t.clone() cleaned->is_raw = true @@ -212,6 +219,7 @@ fun function_value_lower(name_ast_map: *map,*ast_node>>, var new_type_def_name = str("closure_struct_") + closure_id++ var new_type_def = _type_def(new_type_def_name) l->function.closed_variables.for_each(fun(v: *ast_node) { + // THIS MIGHT HAVE TO ACCOUNT FOR FUNC REFS var closed_var_type = v->identifier.type if (lambda_type_to_struct_type_and_call_func.contains_key(*closed_var_type)) closed_var_type = lambda_type_to_struct_type_and_call_func[*closed_var_type].first @@ -241,6 +249,7 @@ fun function_value_lower(name_ast_map: *map,*ast_node>>, body->code_block.children.add(_assign(access_expression(ident, "data"), closure_param)) l->function.closed_variables.for_each(fun(v: *ast_node) { // have to make sure to clean here as well + // THIS MIGHT HAVE TO ACCOUNT FOR FUNC REFS var closed_param_type = v->identifier.type if (lambda_type_to_struct_type_and_call_func.contains_key(*closed_param_type)) closed_param_type = lambda_type_to_struct_type_and_call_func[*closed_param_type].first @@ -259,7 +268,10 @@ fun function_value_lower(name_ast_map: *map,*ast_node>>, function_value_call_points.for_each(fun(p: function_parent_block) { // parent is the function call var function_struct = p.function - p.parent->function_call.func = lambda_type_to_struct_type_and_call_func[*get_ast_type(p.function)].second + var func_type = get_ast_type(p.function) + if (func_type->is_ref) + func_type = func_type->clone_without_ref() + p.parent->function_call.func = lambda_type_to_struct_type_and_call_func[*func_type].second p.parent->function_call.parameters.add(0, function_struct) }) curr_time = split(curr_time, "\tfunction_value_call_points.forEach") @@ -286,8 +298,18 @@ fun function_value_lower(name_ast_map: *map,*ast_node>>, curr_time = split(curr_time, "\tfunction_value_creation_points.forEach") 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_and_call_func.contains_key(*t)) - *t = *lambda_type_to_struct_type_and_call_func[*t].first + var t_nptr = t + if (t->indirection != 0 || t->is_ref) { + t_nptr = t->clone() + t_nptr->indirection = 0 + t_nptr->is_ref = false + } + if (lambda_type_to_struct_type_and_call_func.contains_key(*t_nptr)) { + if (t_nptr != t) + *t = *lambda_type_to_struct_type_and_call_func[*t_nptr].first->clone_with_indirection(t->indirection, t->is_ref) + else + *t = *lambda_type_to_struct_type_and_call_func[*t_nptr].first + } }) curr_time = split(curr_time, "\tlambdas.for_each") closed_over_uses.for_each(fun(p: pair<*ast_node, pair<*ast_node, *ast_node>>) {