From 2fb8dab08d0dd9e7ec74717a0d7ba4285cbd27d5 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Mon, 29 Feb 2016 19:18:22 -0500 Subject: [PATCH] Fix destructor stuff to fix destructor test and other bugs revealed --- stdlib/c_generator.krak | 45 ++++++++++++++++++++++------------------- stdlib/stack.krak | 6 ++++++ stdlib/vector.krak | 8 ++++++++ 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/stdlib/c_generator.krak b/stdlib/c_generator.krak index 4b8ffbf..3072ddb 100644 --- a/stdlib/c_generator.krak +++ b/stdlib/c_generator.krak @@ -383,23 +383,26 @@ obj c_generator (Object) { } fun generate_return_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node, defer_stack: *stack>>): code_triple { var return_value = node->return_statement.return_value - if (!return_value) - return code_triple("return") - var return_value_type = get_ast_type(return_value) var to_ret = code_triple() - // if we're returning an object, copy_construct a new one to return - if (return_value_type->is_object() && return_value_type->indirection == 0 && has_method(return_value_type->type_def, "copy_construct", vector(return_value_type->clone_with_indirection(1)))) { - var temp_ident = ast_identifier_ptr(string("temporary_return")+get_id(), return_value_type, null()) - var declaration = ast_declaration_statement_ptr(temp_ident, null()) - // have to pass false to the declaration generator, so can't do it through generate_statement - to_ret.pre = generate_declaration_statement(declaration, enclosing_object, enclosing_func, defer_stack, false).one_string() + ";\n" - to_ret.pre += generate_statement(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(return_value))))), enclosing_object, enclosing_func, defer_stack).one_string() - // make this new identifier the new return value - return_value = temp_ident + if (return_value) { + var return_value_type = get_ast_type(return_value) + // if we're returning an object, copy_construct a new one to return + if (return_value_type->is_object() && return_value_type->indirection == 0 && has_method(return_value_type->type_def, "copy_construct", vector(return_value_type->clone_with_indirection(1)))) { + var temp_ident = ast_identifier_ptr(string("temporary_return")+get_id(), return_value_type, null()) + var declaration = ast_declaration_statement_ptr(temp_ident, null()) + // have to pass false to the declaration generator, so can't do it through generate_statement + to_ret.pre = generate_declaration_statement(declaration, enclosing_object, enclosing_func, defer_stack, false).one_string() + ";\n" + to_ret.pre += generate_statement(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(return_value))))), enclosing_object, enclosing_func, defer_stack).one_string() + // make this new identifier the new return value + return_value = temp_ident + } } // generate all in stack by passing -1 - to_ret += generate_from_defer_stack(defer_stack, -1, enclosing_object, enclosing_func) - to_ret += code_triple("return ") + generate(return_value, enclosing_object, enclosing_func, null>>>()) + to_ret.pre += generate_from_defer_stack(defer_stack, -1, enclosing_object, enclosing_func).one_string() + to_ret += code_triple("return") + if (return_value) + to_ret += code_triple(" ") + generate(return_value, enclosing_object, enclosing_func, null>>>()) + return to_ret } fun generate_branching_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node, defer_stack: *stack>>): code_triple { @@ -423,7 +426,7 @@ obj c_generator (Object) { num++ } for (var i = 0; i < num; i++;) - defer_stack->from_top(i).second.for_each(fun(node: *ast_node) to_ret += generate(node, enclosing_object, enclosing_func, null>>>());) + defer_stack->from_top(i).second.for_each_reverse(fun(node: *ast_node) to_ret += generate(node, enclosing_object, enclosing_func, null>>>());) return to_ret } fun generate_defer_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node, defer_stack: *stack>>): code_triple { @@ -475,7 +478,7 @@ obj c_generator (Object) { return code_triple(get_name(node)) } fun generate_function_call(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): code_triple { - var func_name = generate_function(node->function_call.func, false).one_string() + var func_name = string() var call_string = code_triple() var func_return_type = get_ast_type(node) @@ -495,6 +498,9 @@ obj c_generator (Object) { if (node->function_call.func->function_call.func->function.name == ".") call_string += "&" call_string += generate_identifier(node->function_call.func->function_call.parameters[0], enclosing_object, enclosing_func) + } else if (is_identifier(node->function_call.func) || is_function(node->function_call.func)) { + // we handle the case when it's not this later, i.e. it's a lambda returned from another function or something + func_name = generate_function(node->function_call.func, false).one_string() } // handle method call from inside method of same object if (!dot_style_method_call && enclosing_object && enclosing_object->type_def.methods.contains(node->function_call.func)) @@ -532,9 +538,6 @@ obj c_generator (Object) { call_string.pre += generate_declaration_statement(declaration, enclosing_object, enclosing_func, null>>>(), false).one_string() + ";\n" call_string.pre += generate_statement(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(param))))), enclosing_object, enclosing_func, null>>>()).one_string() call_string += generate(temp_ident, enclosing_object, enclosing_func, null>>>()) - if (has_method(param_type->type_def, "destruct", vector<*type>())) { - call_string.post += generate_statement(ast_statement_ptr(make_method_call(temp_ident, "destruct", vector<*ast_node>())), enclosing_object, enclosing_func, null>>>()).one_string() - } } else { call_string += generate(param, enclosing_object, enclosing_func, null>>>()) } @@ -580,7 +583,7 @@ obj c_generator (Object) { } } if (pre_call != "") { - call_string.pre = pre_call + " = " + func_name + "(" + call_string.value + ")" + call_string.pre += pre_call + " = " + func_name + "(" + call_string.value + ");" call_string.value = pre_call } else { call_string.value = func_name + "(" + call_string.value + ")" @@ -702,7 +705,7 @@ obj c_generator (Object) { } } if (result == "impossible name") - println("HUGE PROBLEMS") + error("HUGE PROBLEMS") if (ast_name_map.contains_value(result)) result += get_id() ast_name_map.set(node, result) diff --git a/stdlib/stack.krak b/stdlib/stack.krak index e53c47a..1da8944 100644 --- a/stdlib/stack.krak +++ b/stdlib/stack.krak @@ -65,4 +65,10 @@ obj stack (Object, Serializable) { fun for_each(func: fun(T):void) { data.for_each(func) } + fun for_each_reverse(func: fun(ref T):void) { + data.for_each_reverse(func) + } + fun for_each_reverse(func: fun(T):void) { + data.for_each_reverse(func) + } } diff --git a/stdlib/vector.krak b/stdlib/vector.krak index f9ccc9c..eb00f01 100644 --- a/stdlib/vector.krak +++ b/stdlib/vector.krak @@ -225,6 +225,14 @@ obj vector (Object, Serializable) { for (var i = 0; i < size; i++;) func(data[i]) } + fun for_each_reverse(func: fun(ref T):void):void { + for (var i = size-1; i >= 0; i--;) + func(data[i]) + } + fun for_each_reverse(func: fun(T):void):void { + for (var i = size-1; i >= 0; i--;) + func(data[i]) + } fun in_place(func: fun(T):T):void { for (var i = 0; i < size; i++;) data[i] = func(data[i])