Added copy_constructing retun values out and destructing them later, though for now the destruct is added to the defer stack and so doesn't happen until the end of the scope.
This commit is contained in:
@@ -545,9 +545,12 @@ obj interpreter (Object) {
|
|||||||
return make_pair(get_real_value(parameters[0]), control_flow::nor())
|
return make_pair(get_real_value(parameters[0]), control_flow::nor())
|
||||||
}
|
}
|
||||||
if (func_name == "&") {
|
if (func_name == "&") {
|
||||||
if (!is_variable(parameters[0]))
|
if (is_variable(parameters[0]))
|
||||||
error("Trying to take address of not a variable")
|
return make_pair(value::pointer(make_pair(parameters[0].variable.first, parameters[0].variable.second->clone_with_increased_indirection())), control_flow::nor())
|
||||||
return make_pair(value::pointer(make_pair(parameters[0].variable.first, parameters[0].variable.second->clone_with_increased_indirection())), control_flow::nor())
|
else if (is_object_like(parameters[0]))
|
||||||
|
return make_pair(value::pointer(make_pair(parameters[0].object_like.first, parameters[0].object_like.second->clone_with_increased_indirection())), control_flow::nor())
|
||||||
|
else
|
||||||
|
error("Trying to take address of not a variable or object_like")
|
||||||
}
|
}
|
||||||
// to dereference, we basically take the pointer's value (maybe going through a variable to get it)
|
// to dereference, we basically take the pointer's value (maybe going through a variable to get it)
|
||||||
// and re-wrap it up into a variable value (so it can be assigned to, etc)
|
// and re-wrap it up into a variable value (so it can be assigned to, etc)
|
||||||
@@ -578,11 +581,11 @@ obj interpreter (Object) {
|
|||||||
var func_name = func->function.name
|
var func_name = func->function.name
|
||||||
// do regular function
|
// do regular function
|
||||||
var new_var_stack = stack<map<string, value>>()
|
var new_var_stack = stack<map<string, value>>()
|
||||||
|
new_var_stack.push(map<string,value>())
|
||||||
// the new defer stack takes care of destructing parameters that were copy_constructed
|
// the new defer stack takes care of destructing parameters that were copy_constructed
|
||||||
var new_defer_stack = stack<*ast_node>()
|
var new_defer_stack = stack<*ast_node>()
|
||||||
// if this is a value based call, pull from parameters
|
// if this is a value based call, pull from parameters
|
||||||
if (parameter_sources.size == 0) {
|
if (parameter_sources.size == 0) {
|
||||||
new_var_stack.push(map<string,value>())
|
|
||||||
/*println(func_name + " being called with parameter values")*/
|
/*println(func_name + " being called with parameter values")*/
|
||||||
if (parameters.size != func->function.parameters.size)
|
if (parameters.size != func->function.parameters.size)
|
||||||
error(string("calling function ") + func->function.name + " with wrong number of parameters (values)")
|
error(string("calling function ") + func->function.name + " with wrong number of parameters (values)")
|
||||||
@@ -593,7 +596,7 @@ obj interpreter (Object) {
|
|||||||
store_into_variable(new_var_stack.top()[param_ident->identifier.name], get_real_value(parameters[i]))
|
store_into_variable(new_var_stack.top()[param_ident->identifier.name], get_real_value(parameters[i]))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// on this side we construct in the old var stack, then move it over to the new one so that references resolve correctly
|
// on this side we construct temps in the old var stack, then move it over to the new one so that references resolve correctly
|
||||||
var_stack->push(map<string,value>())
|
var_stack->push(map<string,value>())
|
||||||
/*println(func_name + " being called with parameter sources")*/
|
/*println(func_name + " being called with parameter sources")*/
|
||||||
// need to pull from parameter_sources instead
|
// need to pull from parameter_sources instead
|
||||||
@@ -602,22 +605,29 @@ obj interpreter (Object) {
|
|||||||
for (var i = 0; i < parameter_sources.size; i++;) {
|
for (var i = 0; i < parameter_sources.size; i++;) {
|
||||||
var param_type = get_ast_type(func)->parameter_types[i]
|
var param_type = get_ast_type(func)->parameter_types[i]
|
||||||
var param_ident = func->function.parameters[i]
|
var param_ident = func->function.parameters[i]
|
||||||
/*println(param_ident->identifier.name + " is the name of the identifier being added")*/
|
|
||||||
var_stack->top()[param_ident->identifier.name] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
|
|
||||||
if (param_type->indirection == 0 && (param_type->is_adt() || (param_type->is_object() && has_method(param_type->type_def, "copy_construct", vector(param_type->clone_with_increased_indirection()))))) {
|
if (param_type->indirection == 0 && (param_type->is_adt() || (param_type->is_object() && has_method(param_type->type_def, "copy_construct", vector(param_type->clone_with_increased_indirection()))))) {
|
||||||
interpret(ast_statement_ptr(make_method_call(param_ident, "copy_construct", vector(make_operator_call("&", vector(parameter_sources[i]))))), var_stack, enclosing_object, defer_stack)
|
var temp_ident = ast_identifier_ptr(string("temporary_param"), param_type, null<ast_node>())
|
||||||
|
var_stack->top()[temp_ident->identifier.name] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
|
||||||
|
interpret(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(parameter_sources[i]))))), var_stack, enclosing_object, defer_stack)
|
||||||
|
new_var_stack.top()[param_ident->identifier.name] = var_stack->top()[temp_ident->identifier.name]
|
||||||
new_defer_stack.push(ast_statement_ptr(make_method_call(param_ident, "destruct", vector<*ast_node>())))
|
new_defer_stack.push(ast_statement_ptr(make_method_call(param_ident, "destruct", vector<*ast_node>())))
|
||||||
} else {
|
} else {
|
||||||
store_into_variable(var_stack->top()[param_ident->identifier.name], get_real_value(interpret(parameter_sources[i], var_stack, enclosing_object, defer_stack).first))
|
new_var_stack.top()[param_ident->identifier.name] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
|
||||||
|
store_into_variable(new_var_stack.top()[param_ident->identifier.name], get_real_value(interpret(parameter_sources[i], var_stack, enclosing_object, defer_stack).first))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// swap the params over
|
// pop off the temporaries
|
||||||
new_var_stack.push(var_stack->pop())
|
var_stack->pop()
|
||||||
}
|
}
|
||||||
var to_ret = interpret(func->function.body_statement, &new_var_stack, enclosing_object, &new_defer_stack).first
|
var to_ret = interpret(func->function.body_statement, &new_var_stack, enclosing_object, &new_defer_stack).first
|
||||||
// handle destructing params
|
// handle destructing params
|
||||||
interpret_from_defer_stack(&new_defer_stack, &new_var_stack, enclosing_object)
|
interpret_from_defer_stack(&new_defer_stack, &new_var_stack, enclosing_object)
|
||||||
// need to handle copying out object before pop_and_free deletes them
|
var return_type = func->function.type->return_type
|
||||||
|
if (return_type->indirection == 0 && (return_type->is_adt() || (return_type->is_object() && has_method(return_type->type_def, "destruct", vector<*type>())))) {
|
||||||
|
var temp_ident = ast_identifier_ptr(string("temporary_return_to_be_destructed"), return_type, null<ast_node>())
|
||||||
|
var_stack->top()[temp_ident->identifier.name] = value::variable(make_pair(to_ret.object_like.first, to_ret.object_like.second))
|
||||||
|
defer_stack->push(ast_statement_ptr(make_method_call(temp_ident, "destruct", vector<*ast_node>())))
|
||||||
|
}
|
||||||
pop_and_free(&new_var_stack)
|
pop_and_free(&new_var_stack)
|
||||||
return to_ret
|
return to_ret
|
||||||
}
|
}
|
||||||
@@ -720,7 +730,23 @@ obj interpreter (Object) {
|
|||||||
interpret_from_defer_stack(&new_defer_stack, var_stack, enclosing_object)
|
interpret_from_defer_stack(&new_defer_stack, var_stack, enclosing_object)
|
||||||
}
|
}
|
||||||
fun interpret_return_statement(stmt: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
fun interpret_return_statement(stmt: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
||||||
return make_pair(get_real_value(interpret(stmt->return_statement.return_value, var_stack, enclosing_object, defer_stack).first), control_flow::ret())
|
if (stmt->return_statement.return_value == null<ast_node>())
|
||||||
|
return make_pair(value::void_nothing(), control_flow::ret())
|
||||||
|
var return_expression = stmt->return_statement.return_value
|
||||||
|
var return_type = get_ast_type(return_expression)
|
||||||
|
var to_ret: value
|
||||||
|
if (return_type->indirection == 0 && (return_type->is_adt() || (return_type->is_object() && has_method(return_type->type_def, "copy_construct", vector(return_type->clone_with_increased_indirection()))))) {
|
||||||
|
var_stack->push(map<string,value>())
|
||||||
|
var temp_ident = ast_identifier_ptr(string("temporary_return"), return_type, null<ast_node>())
|
||||||
|
var_stack->top()[temp_ident->identifier.name] = value::variable(make_pair(malloc(type_size(return_type)), return_type))
|
||||||
|
interpret(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(return_expression))))), var_stack, enclosing_object, defer_stack)
|
||||||
|
to_ret = var_stack->pop()[temp_ident->identifier.name]
|
||||||
|
} else {
|
||||||
|
to_ret = value::variable(make_pair(malloc(type_size(return_type)), return_type))
|
||||||
|
var ret_val = interpret(return_expression, var_stack, enclosing_object, defer_stack).first
|
||||||
|
store_into_variable(to_ret, get_real_value(ret_val))
|
||||||
|
}
|
||||||
|
return make_pair(get_real_value(to_ret), control_flow::ret())
|
||||||
}
|
}
|
||||||
fun interpret_declaration_statement(stmt: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
fun interpret_declaration_statement(stmt: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
||||||
var ident = stmt->declaration_statement.identifier
|
var ident = stmt->declaration_statement.identifier
|
||||||
|
|||||||
Reference in New Issue
Block a user