Added copy_constructing when returning
This commit is contained in:
@@ -139,7 +139,7 @@ obj c_generator (Object) {
|
||||
top_level_c_passthrough += generate_simple_passthrough(backing.statement->statement.child)
|
||||
}
|
||||
ast_node::simple_passthrough(backing) top_level_c_passthrough += generate_simple_passthrough(child)
|
||||
ast_node::declaration_statement(backing) variable_declarations += generate_declaration_statement(child, null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>()).one_string() + ";\n"
|
||||
ast_node::declaration_statement(backing) variable_declarations += generate_declaration_statement(child, null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), true).one_string() + ";\n"
|
||||
ast_node::function(backing) {
|
||||
// make sure not a template
|
||||
// or a passthrough
|
||||
@@ -155,7 +155,7 @@ obj c_generator (Object) {
|
||||
type_poset.get_sorted().for_each(fun(vert: *ast_node) {
|
||||
plain_typedefs += string("typedef struct ") + vert->type_def.name + "_dummy " + vert->type_def.name + ";\n"
|
||||
structs += string("struct ") + vert->type_def.name + "_dummy {\n"
|
||||
vert->type_def.variables.for_each(fun(variable_declaration: *ast_node) structs += generate_declaration_statement(variable_declaration, null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>()).one_string() + ";\n";)
|
||||
vert->type_def.variables.for_each(fun(variable_declaration: *ast_node) structs += generate_declaration_statement(variable_declaration, null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), true).one_string() + ";\n";)
|
||||
structs += "};\n"
|
||||
// generate the methods
|
||||
vert->type_def.methods.for_each(fun(method: *ast_node) generate_function_definition(method, vert);)
|
||||
@@ -173,14 +173,14 @@ obj c_generator (Object) {
|
||||
return node->simple_passthrough.passthrough_str
|
||||
}
|
||||
fun generate_statement(node: *ast_node, enclosing_object: *ast_node, defer_stack: *stack<pair<bool,stack<*ast_node>>>): code_triple return generate(node->statement.child, enclosing_object, defer_stack) + ";\n";
|
||||
fun generate_declaration_statement(node: *ast_node, enclosing_object: *ast_node, defer_stack: *stack<pair<bool,stack<*ast_node>>>): code_triple {
|
||||
fun generate_declaration_statement(node: *ast_node, enclosing_object: *ast_node, defer_stack: *stack<pair<bool,stack<*ast_node>>>, add_to_defer: bool): code_triple {
|
||||
// add destruct to defer_stack
|
||||
var identifier = node->declaration_statement.identifier
|
||||
var ident_type = identifier->identifier.type
|
||||
var to_ret = code_triple() + type_to_c(identifier->identifier.type) + " " + identifier->identifier.name
|
||||
if (node->declaration_statement.expression) to_ret += code_triple(" = ") + generate(node->declaration_statement.expression, enclosing_object, null<stack<pair<bool,stack<*ast_node>>>>())
|
||||
if (node->declaration_statement.init_method_call) to_ret += code_triple(";\n") + generate(node->declaration_statement.init_method_call, enclosing_object, null<stack<pair<bool,stack<*ast_node>>>>())
|
||||
if (ident_type->is_object() && has_method(ident_type->type_def, "destruct", vector<*type>()))
|
||||
if (add_to_defer && ident_type->is_object() && has_method(ident_type->type_def, "destruct", vector<*type>()))
|
||||
defer_stack->top().second.push(ast_statement_ptr(make_method_call(identifier, "destruct", vector<*ast_node>())))
|
||||
return to_ret
|
||||
}
|
||||
@@ -220,9 +220,22 @@ obj c_generator (Object) {
|
||||
return code_triple(node->identifier.name)
|
||||
}
|
||||
fun generate_return_statement(node: *ast_node, enclosing_object: *ast_node, defer_stack: *stack<pair<bool,stack<*ast_node>>>): code_triple {
|
||||
var return_value = node->return_statement.return_value
|
||||
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_value_type)
|
||||
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>())
|
||||
// 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, 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, defer_stack).one_string()
|
||||
// make this new identifier the new return value
|
||||
return_value = temp_ident
|
||||
}
|
||||
// generate all in stack by passing -1
|
||||
var to_ret = generate_from_defer_stack(defer_stack, -1, enclosing_object)
|
||||
to_ret += code_triple("return ") + generate(node->return_statement.return_value, enclosing_object, null<stack<pair<bool,stack<*ast_node>>>>())
|
||||
to_ret += generate_from_defer_stack(defer_stack, -1, enclosing_object)
|
||||
to_ret += code_triple("return ") + generate(return_value, enclosing_object, null<stack<pair<bool,stack<*ast_node>>>>())
|
||||
return to_ret
|
||||
}
|
||||
fun generate_branching_statement(node: *ast_node, enclosing_object: *ast_node, defer_stack: *stack<pair<bool,stack<*ast_node>>>): code_triple {
|
||||
@@ -323,7 +336,7 @@ obj c_generator (Object) {
|
||||
ast_node::if_comp(backing) return generate_if_comp(node)
|
||||
ast_node::simple_passthrough(backing) return code_triple() + generate_simple_passthrough(node)
|
||||
ast_node::statement(backing) return generate_statement(node, enclosing_object, defer_stack)
|
||||
ast_node::declaration_statement(backing) return generate_declaration_statement(node, enclosing_object, defer_stack)
|
||||
ast_node::declaration_statement(backing) return generate_declaration_statement(node, enclosing_object, defer_stack, true)
|
||||
ast_node::assignment_statement(backing) return generate_assignment_statement(node, enclosing_object)
|
||||
ast_node::if_statement(backing) return generate_if_statement(node, enclosing_object, defer_stack)
|
||||
ast_node::while_loop(backing) return generate_while_loop(node, enclosing_object, defer_stack)
|
||||
|
||||
Reference in New Issue
Block a user