Added copy_constructing when returning
This commit is contained in:
@@ -351,17 +351,17 @@ fun make_method_call(object_ident: *ast_node, method: *ast_node, parameters: vec
|
|||||||
var method_access = ast_function_call_ptr(get_builtin_function(string("."), vector(get_ast_type(object_ident), get_ast_type(method))), vector(object_ident, method))
|
var method_access = ast_function_call_ptr(get_builtin_function(string("."), vector(get_ast_type(object_ident), get_ast_type(method))), vector(object_ident, method))
|
||||||
return ast_function_call_ptr(method_access, parameters)
|
return ast_function_call_ptr(method_access, parameters)
|
||||||
}
|
}
|
||||||
fun make_operator_call(left: *ast_node, func: *char, right: *ast_node): *ast_node return make_operator_call(left, string(func), right);
|
fun make_operator_call(func: *char, params: vector<*ast_node>): *ast_node return make_operator_call(string(func), params);
|
||||||
fun make_operator_call(left: *ast_node, func: string, right: *ast_node): *ast_node {
|
fun make_operator_call(func: string, params: vector<*ast_node>): *ast_node {
|
||||||
return ast_function_call_ptr(get_builtin_function(func, vector(get_ast_type(left), get_ast_type(right))), vector(left, right))
|
return ast_function_call_ptr(get_builtin_function(func, params.map(fun(p:*ast_node): *type return get_ast_type(p);)), params)
|
||||||
}
|
}
|
||||||
fun transform_assignment_statement(node: *tree<symbol>, scope: *ast_node): *ast_node {
|
fun transform_assignment_statement(node: *tree<symbol>, scope: *ast_node): *ast_node {
|
||||||
var assign_to = transform(get_node("factor", node), scope)
|
var assign_to = transform(get_node("factor", node), scope)
|
||||||
var to_assign = transform(get_node("boolean_expression", node), scope)
|
var to_assign = transform(get_node("boolean_expression", node), scope)
|
||||||
if (get_node("\"\\+=\"", node)) to_assign = make_operator_call(assign_to, "+", to_assign)
|
if (get_node("\"\\+=\"", node)) to_assign = make_operator_call("+", vector(to_assign, to_assign))
|
||||||
else if (get_node("\"-=\"", node)) to_assign = make_operator_call(assign_to, "-", to_assign)
|
else if (get_node("\"-=\"", node)) to_assign = make_operator_call("-", vector(to_assign, to_assign))
|
||||||
else if (get_node("\"\\*=\"", node)) to_assign = make_operator_call(assign_to, "*", to_assign)
|
else if (get_node("\"\\*=\"", node)) to_assign = make_operator_call("*", vector(to_assign, to_assign))
|
||||||
else if (get_node("\"/=\"", node)) to_assign = make_operator_call(assign_to, "/", to_assign)
|
else if (get_node("\"/=\"", node)) to_assign = make_operator_call("/", vector(to_assign, to_assign))
|
||||||
var assignment = ast_assignment_statement_ptr(assign_to, to_assign)
|
var assignment = ast_assignment_statement_ptr(assign_to, to_assign)
|
||||||
return assignment
|
return assignment
|
||||||
}
|
}
|
||||||
@@ -451,6 +451,10 @@ fun transform_expression(node: *tree<symbol>, scope: *ast_node, searching_for: s
|
|||||||
fun get_builtin_function(name: string, param_types: vector<*type>): *ast_node {
|
fun get_builtin_function(name: string, param_types: vector<*type>): *ast_node {
|
||||||
if (name == "." || name == "->")
|
if (name == "." || name == "->")
|
||||||
return ast_function_ptr(name, type_ptr(param_types, param_types[1]), vector<*ast_node>())
|
return ast_function_ptr(name, type_ptr(param_types, param_types[1]), vector<*ast_node>())
|
||||||
|
if (name == "&")
|
||||||
|
return ast_function_ptr(name, type_ptr(param_types, param_types[0]->clone_with_increased_indirection()), vector<*ast_node>())
|
||||||
|
if (name == "\\*")
|
||||||
|
return ast_function_ptr(name, type_ptr(param_types, param_types[0]->clone_with_decreased_indirection()), vector<*ast_node>())
|
||||||
return ast_function_ptr(name, type_ptr(param_types, param_types[0]), vector<*ast_node>())
|
return ast_function_ptr(name, type_ptr(param_types, param_types[0]), vector<*ast_node>())
|
||||||
}
|
}
|
||||||
fun function_lookup(name: string, scope: *ast_node, param_types: vector<*type>): *ast_node {
|
fun function_lookup(name: string, scope: *ast_node, param_types: vector<*type>): *ast_node {
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ obj c_generator (Object) {
|
|||||||
top_level_c_passthrough += generate_simple_passthrough(backing.statement->statement.child)
|
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::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) {
|
ast_node::function(backing) {
|
||||||
// make sure not a template
|
// make sure not a template
|
||||||
// or a passthrough
|
// or a passthrough
|
||||||
@@ -155,7 +155,7 @@ obj c_generator (Object) {
|
|||||||
type_poset.get_sorted().for_each(fun(vert: *ast_node) {
|
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"
|
plain_typedefs += string("typedef struct ") + vert->type_def.name + "_dummy " + vert->type_def.name + ";\n"
|
||||||
structs += string("struct ") + vert->type_def.name + "_dummy {\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"
|
structs += "};\n"
|
||||||
// generate the methods
|
// generate the methods
|
||||||
vert->type_def.methods.for_each(fun(method: *ast_node) generate_function_definition(method, vert);)
|
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
|
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_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
|
// add destruct to defer_stack
|
||||||
var identifier = node->declaration_statement.identifier
|
var identifier = node->declaration_statement.identifier
|
||||||
var ident_type = identifier->identifier.type
|
var ident_type = identifier->identifier.type
|
||||||
var to_ret = code_triple() + type_to_c(identifier->identifier.type) + " " + identifier->identifier.name
|
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.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 (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>())))
|
defer_stack->top().second.push(ast_statement_ptr(make_method_call(identifier, "destruct", vector<*ast_node>())))
|
||||||
return to_ret
|
return to_ret
|
||||||
}
|
}
|
||||||
@@ -220,9 +220,22 @@ obj c_generator (Object) {
|
|||||||
return code_triple(node->identifier.name)
|
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 {
|
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
|
// generate all in stack by passing -1
|
||||||
var to_ret = generate_from_defer_stack(defer_stack, -1, enclosing_object)
|
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 += code_triple("return ") + generate(return_value, enclosing_object, null<stack<pair<bool,stack<*ast_node>>>>())
|
||||||
return to_ret
|
return to_ret
|
||||||
}
|
}
|
||||||
fun generate_branching_statement(node: *ast_node, enclosing_object: *ast_node, defer_stack: *stack<pair<bool,stack<*ast_node>>>): code_triple {
|
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::if_comp(backing) return generate_if_comp(node)
|
||||||
ast_node::simple_passthrough(backing) return code_triple() + generate_simple_passthrough(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::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::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::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)
|
ast_node::while_loop(backing) return generate_while_loop(node, enclosing_object, defer_stack)
|
||||||
|
|||||||
@@ -115,6 +115,8 @@ obj type (Object) {
|
|||||||
}
|
}
|
||||||
return string("impossible type, indirection:") + indirection
|
return string("impossible type, indirection:") + indirection
|
||||||
}
|
}
|
||||||
|
fun clone_with_increased_indirection(): *type return clone_with_indirection(indirection+1);
|
||||||
|
fun clone_with_decreased_indirection(): *type return clone_with_indirection(indirection-1);
|
||||||
fun clone_with_indirection(ind: int): *type {
|
fun clone_with_indirection(ind: int): *type {
|
||||||
var to_ret = new<type>()
|
var to_ret = new<type>()
|
||||||
to_ret->copy_construct(this)
|
to_ret->copy_construct(this)
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import to_import: simple_print, simple_println, a, b, string_id
|
import to_import: simple_print, simple_println, a, b, string_id
|
||||||
|
|
||||||
|
fun something(param: int): Something {
|
||||||
|
var to_ret.construct_with_param(param): Something
|
||||||
|
return to_ret
|
||||||
|
}
|
||||||
obj Something (ObjectTrait) {
|
obj Something (ObjectTrait) {
|
||||||
var member: int
|
var member: int
|
||||||
fun construct(): *Something {
|
fun construct(): *Something {
|
||||||
@@ -35,6 +39,15 @@ fun some_other_function(in: bool): float {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
fun main(): int {
|
fun main(): int {
|
||||||
|
var test_methods = something(77)
|
||||||
|
var test_methods_param.construct_with_param(10090): Something
|
||||||
|
simple_println("Constructing an object and printint its member, copy-constructing it, and printing that out, then letting both be destructed")
|
||||||
|
simple_println(test_methods.member)
|
||||||
|
simple_println(test_methods_param.member)
|
||||||
|
var second_obj = test_methods
|
||||||
|
second_obj.member += 5
|
||||||
|
simple_println(second_obj.member)
|
||||||
|
return 0
|
||||||
/*
|
/*
|
||||||
var a_declaration:int
|
var a_declaration:int
|
||||||
simple_print(1 + 2)
|
simple_print(1 + 2)
|
||||||
@@ -99,16 +112,5 @@ fun main(): int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
var test_methods.construct(): Something
|
|
||||||
var test_methods_param.construct_with_param(10090): Something
|
|
||||||
/*var test_methods: Something*/
|
|
||||||
test_methods.member = 10
|
|
||||||
simple_println("Constructing an object and printint its member, copy-constructing it, and printing that out, then letting both be destructed")
|
|
||||||
simple_println(test_methods.member)
|
|
||||||
simple_println(test_methods_param.member)
|
|
||||||
var second_obj = test_methods
|
|
||||||
second_obj.member += 5
|
|
||||||
simple_println(second_obj.member)
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user