Lambdas and function values starting to work - using the parameters or return value crashes
This commit is contained in:
@@ -971,7 +971,7 @@ obj ast_transformation (Object) {
|
||||
var possible_overload_call = find_and_make_any_operator_overload_call(func_name, parameters, scope, template_replacements)
|
||||
if (possible_overload_call)
|
||||
return possible_overload_call
|
||||
return ast_function_call_ptr(get_builtin_function(func_name, parameter_types), parameters)
|
||||
return ast_function_call_ptr(get_builtin_function(func_name, parameter_types, node), parameters)
|
||||
}
|
||||
fun find_and_make_any_operator_overload_call(func_name: string, parameters: vector<*ast_node>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node {
|
||||
var parameter_types = parameters.map(fun(param: *ast_node): *type return get_ast_type(param);)
|
||||
@@ -1131,22 +1131,24 @@ fun make_operator_call(func: *char, params: vector<*ast_node>): *ast_node return
|
||||
fun make_operator_call(func: string, params: vector<*ast_node>): *ast_node {
|
||||
return ast_function_call_ptr(get_builtin_function(func, params.map(fun(p:*ast_node): *type return get_ast_type(p);)), params)
|
||||
}
|
||||
fun get_builtin_function(name: string, param_types: vector<*type>): *ast_node {
|
||||
fun get_builtin_function(name: string, param_types: vector<*type>): *ast_node
|
||||
return get_builtin_function(name, param_types, null<tree<symbol>>())
|
||||
fun get_builtin_function(name: string, param_types: vector<*type>, syntax: *tree<symbol>): *ast_node {
|
||||
// none of the builtin functions should take in references
|
||||
param_types = param_types.map(fun(t: *type): *type return t->clone_without_ref();)
|
||||
if (name == "==" || name == "!=" || name == ">" || name == "<" || name == "<=" || name == ">" || name == ">=" || name == "&&" || name == "||" || name == "!")
|
||||
return ast_function_ptr(name, type_ptr(param_types, type_ptr(base_type::boolean())), vector<*ast_node>(), false)
|
||||
if (name == "." || name == "->") {
|
||||
if (name == "->" && param_types[0]->indirection == 0)
|
||||
error(string("drereferencing not a pointer: ") + name)
|
||||
error(syntax, string("drereferencing not a pointer: ") + name)
|
||||
else if (name == "." && param_types[0]->indirection != 0)
|
||||
error(string("dot operator on a pointer: ") + name)
|
||||
error(syntax, string("dot operator on a pointer: ") + name)
|
||||
else
|
||||
return ast_function_ptr(name, type_ptr(param_types, param_types[1]), vector<*ast_node>(), false)
|
||||
}
|
||||
if (name == "[]") {
|
||||
if (param_types[0]->indirection == 0)
|
||||
error(string("drereferencing not a pointer: ") + name)
|
||||
error(syntax, string("drereferencing not a pointer: ") + name)
|
||||
else
|
||||
return ast_function_ptr(name, type_ptr(param_types, param_types[0]->clone_with_decreased_indirection()), vector<*ast_node>(), false)
|
||||
}
|
||||
@@ -1154,7 +1156,7 @@ fun get_builtin_function(name: string, param_types: vector<*type>): *ast_node {
|
||||
return ast_function_ptr(name, type_ptr(param_types, param_types[0]->clone_with_increased_indirection()), vector<*ast_node>(), false)
|
||||
if (name == "\*" && param_types.size == 1) {
|
||||
if (param_types[0]->indirection == 0)
|
||||
error(string("drereferencing not a pointer: ") + name)
|
||||
error(syntax, string("drereferencing not a pointer: ") + name)
|
||||
else
|
||||
return ast_function_ptr(name, type_ptr(param_types, param_types[0]->clone_with_decreased_indirection()), vector<*ast_node>(), false)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ adt value {
|
||||
void_nothing,
|
||||
pointer: pair<*void,*type>,
|
||||
object_like: pair<*void,*type>,
|
||||
variable: pair<*void,*type>
|
||||
variable: pair<*void,*type>,
|
||||
function: pair<*ast_node,map<*ast_node,value>>
|
||||
}
|
||||
adt control_flow {
|
||||
nor,
|
||||
@@ -132,6 +133,7 @@ fun is_void_nothing(it: value): bool { match(it) { value::void_nothing() return
|
||||
fun is_pointer(it: value): bool { match(it) { value::pointer(var) return true; } return false; }
|
||||
fun is_object_like(it: value): bool { match(it) { value::object_like(var) return true; } return false; }
|
||||
fun is_variable(it: value): bool { match(it) { value::variable(var) return true; } return false; }
|
||||
fun is_function(it: value): bool { match(it) { value::function(var) return true; } return false; }
|
||||
|
||||
fun print_value(v: ref value) {
|
||||
match (get_real_value(v)) {
|
||||
@@ -150,6 +152,7 @@ fun print_value(v: ref value) {
|
||||
value::pointer(var) println("pointer")
|
||||
value::object_like(var) println("object_like")
|
||||
value::variable(var) println("variable")
|
||||
value::function(var) println("function")
|
||||
}
|
||||
}
|
||||
fun truthy(v: ref value):bool {
|
||||
@@ -286,7 +289,7 @@ fun store_into_variable(to: value, from: value) {
|
||||
match (variable.second->base) {
|
||||
base_type::object() { assert(is_object_like(from), "mismatching assignemnt types - from is not object"); memmove(variable.first, from.object_like.first, type_size(from.object_like.second)); }
|
||||
base_type::adt() error(string("trying to store into an adt: ") + variable.second->to_string())
|
||||
base_type::function() error(string("trying to store into a function: ") + variable.second->to_string())
|
||||
base_type::function() { assert(is_function(from), "mismatching assignemnt types - from is not function"); *(variable.first) cast *pair<*ast_node, map<*ast_node,value>> = from.function; }
|
||||
base_type::boolean() { assert(is_boolean(from), "mismatching assignemnt types - from is not boolean"); *(variable.first) cast *bool = from.boolean; }
|
||||
base_type::character() { assert(is_character(from), "mismatching assignemnt types - from is not character"); *(variable.first) cast *char = from.character; }
|
||||
base_type::ucharacter() { assert(is_ucharacter(from), "mismatching assignemnt types - from is not ucharacter"); *(variable.first) cast *uchar = from.ucharacter; }
|
||||
@@ -298,6 +301,7 @@ fun store_into_variable(to: value, from: value) {
|
||||
base_type::ulong_int() { assert(is_ulong_int(from), "mismatching assignemnt types - from is not ulong_int"); *(variable.first) cast *ulong = from.ulong_int; }
|
||||
base_type::floating() { assert(is_floating(from), "mismatching assignemnt types - from is not floating"); *(variable.first) cast *float = from.floating; }
|
||||
base_type::double_precision() { assert(is_double_precision(from), "mismatching assignemnt types - from is not double"); *(variable.first) cast *double = from.double_precision; }
|
||||
base_type::function() { assert(is_function(from), "mismatching assignemnt types - from is not function"); *(variable.first) cast *pair<*ast_node,map<*ast_node,value>> = from.function; }
|
||||
}
|
||||
}
|
||||
fun get_real_value(v: value): value {
|
||||
@@ -322,6 +326,7 @@ fun get_real_value(v: value): value {
|
||||
base_type::ulong_int() return value::ulong_int(*(variable.first) cast *ulong)
|
||||
base_type::floating() return value::floating(*(variable.first) cast *float)
|
||||
base_type::double_precision() return value::double_precision(*(variable.first) cast *double)
|
||||
base_type::function() return value::function(*(variable.first) cast *pair<*ast_node,map<*ast_node,value>>)
|
||||
}
|
||||
error(string("Cannot get real value from variable: ") + variable.second->to_string())
|
||||
}
|
||||
@@ -332,7 +337,10 @@ fun wrap_into_variable(v: value): value {
|
||||
return value::variable(make_pair(v.object_like.first, v.object_like.second))
|
||||
var variable_type = get_type_from_primitive_value(v)
|
||||
var to_ret = value::variable(make_pair(malloc(type_size(variable_type)), variable_type))
|
||||
store_into_variable(to_ret, v)
|
||||
if (is_function(v))
|
||||
(to_ret.variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->copy_construct(&v.function)
|
||||
else
|
||||
store_into_variable(to_ret, v)
|
||||
return to_ret
|
||||
}
|
||||
fun get_type_from_primitive_value(v: value): *type {
|
||||
@@ -350,6 +358,7 @@ fun get_type_from_primitive_value(v: value): *type {
|
||||
value::double_precision(data) return type_ptr(base_type::double_precision())
|
||||
value::pointer(data) return data.second
|
||||
value::void_nothing() return type_ptr(base_type::void_return())
|
||||
value::function(data) return data.first->function.type
|
||||
}
|
||||
println("Bad get_type_from_primitive_value!")
|
||||
print_value(v)
|
||||
@@ -446,7 +455,7 @@ fun type_size(t: *type): ulong {
|
||||
return size
|
||||
}
|
||||
/*base_type::adt() return #sizeof<>*/
|
||||
/*base_type::function() return #sizeof<>*/
|
||||
base_type::function() return #sizeof<pair<*ast_node,map<*ast_node,value>>>
|
||||
base_type::boolean() return #sizeof<bool>
|
||||
base_type::character() return #sizeof<char>
|
||||
base_type::ucharacter() return #sizeof<uchar>
|
||||
@@ -474,6 +483,8 @@ fun pop_and_free(var_stack: *stack<map<*ast_node, value>>) {
|
||||
var_stack->pop().for_each(fun(k: *ast_node, v: value) {
|
||||
match(v) {
|
||||
value::variable(backing) {
|
||||
/*if (backing.second->is_function())*/
|
||||
/*(backing.first) cast *pair<*ast_node,map<*ast_node,value>> ->destruct()*/
|
||||
free(backing.first)
|
||||
}
|
||||
}
|
||||
@@ -561,8 +572,16 @@ obj interpreter (Object) {
|
||||
var func_call_parameters = func_call->function_call.parameters
|
||||
var func_call_func = func_call->function_call.func
|
||||
var new_enclosing_object = value::void_nothing()
|
||||
var dot_style_method_call = is_dot_style_method_call(func_call)
|
||||
// test for function value
|
||||
if (!dot_style_method_call && !is_function(func_call_func)) {
|
||||
/*error("func_call_func is not a function")*/
|
||||
println(string("func_call_func is not a function: ") + get_ast_name(func_call_func))
|
||||
func_call_func = get_real_value(interpret(func_call_func, var_stack, enclosing_object, enclosing_func, defer_stack).first).function.first
|
||||
println(string("calling func we got from interpreting: ") + get_ast_name(func_call_func))
|
||||
}
|
||||
// note here also that this is likely not a foolproof method
|
||||
if (is_dot_style_method_call(func_call)) {
|
||||
if (dot_style_method_call) {
|
||||
new_enclosing_object = get_real_value(interpret(func_call_func->function_call.parameters[0], var_stack, enclosing_object, enclosing_func, defer_stack).first)
|
||||
// do a dereference
|
||||
if (is_pointer(new_enclosing_object))
|
||||
@@ -676,6 +695,8 @@ obj interpreter (Object) {
|
||||
new_var_stack.top()[param_ident] = wrap_into_variable(parameters[i])
|
||||
} else {
|
||||
new_var_stack.top()[param_ident] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
|
||||
//HERE
|
||||
(new_var_stack.top()[param_ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
|
||||
store_into_variable(new_var_stack.top()[param_ident], get_real_value(parameters[i]))
|
||||
}
|
||||
}
|
||||
@@ -698,12 +719,16 @@ obj interpreter (Object) {
|
||||
} else 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()))))) {
|
||||
var temp_ident = ast_identifier_ptr(string("temporary_param") + get_id(), param_type, null<ast_node>())
|
||||
var_stack->top()[temp_ident] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
|
||||
//HERE
|
||||
(var_stack->top()[temp_ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
|
||||
interpret(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(parameter_sources[i]))))), var_stack, enclosing_object, enclosing_func, ¶m_defer_stack)
|
||||
new_var_stack.top()[param_ident] = var_stack->top()[temp_ident]
|
||||
// note that we destruct the temp version because that's the one in the var_stack
|
||||
param_defer_stack.push(ast_statement_ptr(make_method_call(temp_ident, "destruct", vector<*ast_node>())))
|
||||
} else {
|
||||
new_var_stack.top()[param_ident] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
|
||||
//HERE
|
||||
(new_var_stack.top()[param_ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
|
||||
store_into_variable(new_var_stack.top()[param_ident], get_real_value(interpret(parameter_sources[i], var_stack, enclosing_object, enclosing_func, ¶m_defer_stack).first))
|
||||
}
|
||||
}
|
||||
@@ -727,7 +752,6 @@ obj interpreter (Object) {
|
||||
return to_ret
|
||||
}
|
||||
fun call_built_in_extern(func_name: string, parameters: vector<value>): value {
|
||||
/*println(string("calling func: ") + func_name)*/
|
||||
for (var i = 0; i < parameters.size; i++;)
|
||||
parameters[i] = get_real_value(parameters[i])
|
||||
if (func_name == "printf") {
|
||||
@@ -793,6 +817,9 @@ obj interpreter (Object) {
|
||||
}
|
||||
return value::void_nothing()
|
||||
}
|
||||
fun interpret_function(function: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
||||
return make_pair(value::function(make_pair(function, map<*ast_node,value>())), control_flow::nor())
|
||||
}
|
||||
fun interpret_statement(stmt: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
||||
return interpret(stmt->statement.child, var_stack, enclosing_object, enclosing_func, defer_stack)
|
||||
}
|
||||
@@ -898,7 +925,7 @@ obj interpreter (Object) {
|
||||
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
|
||||
var to_ret.construct(): value
|
||||
if (get_ast_type(enclosing_func)->return_type->is_ref) {
|
||||
to_ret = interpret(return_expression, var_stack, enclosing_object, enclosing_func, defer_stack).first
|
||||
} else 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()))))) {
|
||||
@@ -914,6 +941,8 @@ obj interpreter (Object) {
|
||||
/*pop_and_free(var_stack)*/
|
||||
} else {
|
||||
to_ret = value::variable(make_pair(malloc(type_size(return_type)), return_type))
|
||||
//HERE
|
||||
(to_ret.variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
|
||||
var ret_val = interpret(return_expression, var_stack, enclosing_object, enclosing_func, defer_stack).first
|
||||
store_into_variable(to_ret, get_real_value(ret_val))
|
||||
}
|
||||
@@ -923,6 +952,8 @@ obj interpreter (Object) {
|
||||
var ident = stmt->declaration_statement.identifier
|
||||
var ident_type = ident->identifier.type
|
||||
var_stack->top()[ident] = value::variable(make_pair(malloc(type_size(ident_type)),ident_type))
|
||||
//HERE
|
||||
(var_stack->top()[ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
|
||||
if (stmt->declaration_statement.expression) {
|
||||
if (ident_type->indirection == 0 && (ident_type->is_adt() || (ident_type->is_object() && has_method(ident_type->type_def, "copy_construct", vector(get_ast_type(stmt->declaration_statement.expression)->clone_with_increased_indirection())))))
|
||||
interpret(ast_statement_ptr(make_method_call(ident, "copy_construct", vector(make_operator_call("&", vector(stmt->declaration_statement.expression))))), var_stack, enclosing_object, enclosing_func, defer_stack)
|
||||
@@ -988,6 +1019,7 @@ obj interpreter (Object) {
|
||||
fun interpret(node: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
||||
match (*node) {
|
||||
ast_node::function_call(backing) return interpret_function_call(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
||||
ast_node::function(backing) return interpret_function(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
||||
ast_node::statement(backing) return interpret_statement(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
||||
ast_node::if_statement(backing) return interpret_if_statement(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
||||
ast_node::while_loop(backing) return interpret_while_loop(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
||||
|
||||
Reference in New Issue
Block a user