Fixed up interpreter, ADT is close to working but something's weird about what match statements are translated into
This commit is contained in:
@@ -151,11 +151,7 @@ fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
|||||||
var value = backing.value
|
var value = backing.value
|
||||||
var holder = ast_identifier_ptr(string("holder"), get_ast_type(value)->clone_with_increased_indirection(), block)
|
var holder = ast_identifier_ptr(string("holder"), get_ast_type(value)->clone_with_increased_indirection(), block)
|
||||||
block->code_block.children.add(ast_statement_ptr(ast_declaration_statement_ptr(holder, null<ast_node>(), false)))
|
block->code_block.children.add(ast_statement_ptr(ast_declaration_statement_ptr(holder, null<ast_node>(), false)))
|
||||||
// dirty hack
|
block->code_block.children.add(ast_statement_ptr(ast_assignment_statement_ptr(holder, make_operator_call("&", vector(value)))))
|
||||||
var if_hack = ast_if_statement_ptr(ast_assignment_statement_ptr(holder, make_operator_call("&", vector(value))))
|
|
||||||
block->code_block.children.add(if_hack)
|
|
||||||
var if_block = ast_code_block_ptr()
|
|
||||||
if_hack->if_statement.then_part = if_block
|
|
||||||
backing.cases.for_each(fun(case_stmt: *ast_node) {
|
backing.cases.for_each(fun(case_stmt: *ast_node) {
|
||||||
var option = case_stmt->case_statement.option
|
var option = case_stmt->case_statement.option
|
||||||
var flag = get_from_scope(get_ast_type(value)->type_def, "flag")
|
var flag = get_from_scope(get_ast_type(value)->type_def, "flag")
|
||||||
@@ -178,7 +174,7 @@ fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
|||||||
}
|
}
|
||||||
inner_block->code_block.children.add(case_stmt->case_statement.statement)
|
inner_block->code_block.children.add(case_stmt->case_statement.statement)
|
||||||
if_stmt->if_statement.then_part = inner_block
|
if_stmt->if_statement.then_part = inner_block
|
||||||
if_block->code_block.children.add(if_stmt)
|
block->code_block.children.add(if_stmt)
|
||||||
})
|
})
|
||||||
*node = *block
|
*node = *block
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ import tree:*
|
|||||||
import symbol:*
|
import symbol:*
|
||||||
import ast_nodes:*
|
import ast_nodes:*
|
||||||
import poset:*
|
import poset:*
|
||||||
// we import ast_transformation for its make_method_call function
|
|
||||||
import ast_transformation:*
|
|
||||||
|
|
||||||
fun code_triple(): code_triple return code_triple(string(), string(), string());
|
fun code_triple(): code_triple return code_triple(string(), string(), string());
|
||||||
fun code_triple(only: *char): code_triple return code_triple(string(), string(only), string());
|
fun code_triple(only: *char): code_triple return code_triple(string(), string(only), string());
|
||||||
|
|||||||
@@ -280,11 +280,14 @@ fun store_into_variable(to: value, from: value) {
|
|||||||
assert(is_variable(to), "trying to store into not variable")
|
assert(is_variable(to), "trying to store into not variable")
|
||||||
var variable = to.variable
|
var variable = to.variable
|
||||||
// check for indirection
|
// check for indirection
|
||||||
if (variable.second->indirection) {
|
// we have a special case here - we allow assigning to a ref from a pointer, as this is used in adt_lower
|
||||||
|
if (variable.second->indirection || (variable.second->is_ref && is_pointer(from))) {
|
||||||
assert(is_pointer(from), "mismatching assignemnt types - from is not pointer")
|
assert(is_pointer(from), "mismatching assignemnt types - from is not pointer")
|
||||||
*(variable.first) cast **void = from.pointer.first
|
*(variable.first) cast **void = from.pointer.first
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (variable.second->is_ref && is_pointer(from)) {
|
||||||
|
}
|
||||||
// TODO - check to make sure that we don't have to cast pre assign (perhaps alwyas send through the cast?)
|
// TODO - check to make sure that we don't have to cast pre assign (perhaps alwyas send through the cast?)
|
||||||
match (variable.second->base) {
|
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::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)); }
|
||||||
@@ -484,7 +487,7 @@ fun pop_and_free(var_stack: *stack<map<*ast_node, value>>) {
|
|||||||
value::variable(backing) {
|
value::variable(backing) {
|
||||||
/*if (backing.second->is_function())*/
|
/*if (backing.second->is_function())*/
|
||||||
/*(backing.first) cast *pair<*ast_node,map<*ast_node,value>> ->destruct()*/
|
/*(backing.first) cast *pair<*ast_node,map<*ast_node,value>> ->destruct()*/
|
||||||
free(backing.first)
|
/*free(backing.first)*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -534,13 +537,10 @@ obj interpreter (Object) {
|
|||||||
printlnerr("=============")
|
printlnerr("=============")
|
||||||
var var_stack = stack<map<*ast_node, value>>()
|
var var_stack = stack<map<*ast_node, value>>()
|
||||||
var_stack.push(map<*ast_node,value>())
|
var_stack.push(map<*ast_node,value>())
|
||||||
var defer_stack = stack<*ast_node>()
|
var result = call_function(results[0], vector<value>(), vector<*ast_node>(), &var_stack, value::void_nothing(), value::void_nothing(), null<ast_node>())
|
||||||
var result = call_function(results[0], vector<value>(), vector<*ast_node>(), &var_stack, &defer_stack, value::void_nothing(), value::void_nothing(), null<ast_node>())
|
|
||||||
printlnerr("=============")
|
printlnerr("=============")
|
||||||
printlnerr("Done!")
|
printlnerr("Done!")
|
||||||
printlnerr("=============")
|
printlnerr("=============")
|
||||||
|
|
||||||
interpret_from_defer_stack(&defer_stack, &var_stack, value::void_nothing(), null<ast_node>())
|
|
||||||
pop_and_free(&var_stack)
|
pop_and_free(&var_stack)
|
||||||
}
|
}
|
||||||
fun setup_globals() {
|
fun setup_globals() {
|
||||||
@@ -561,13 +561,13 @@ obj interpreter (Object) {
|
|||||||
} else {
|
} else {
|
||||||
globals[declaration.identifier] = value::variable(make_pair(calloc(type_size(identifier.type)), identifier.type))
|
globals[declaration.identifier] = value::variable(make_pair(calloc(type_size(identifier.type)), identifier.type))
|
||||||
if (declaration.expression)
|
if (declaration.expression)
|
||||||
store_into_variable(globals[declaration.identifier], get_real_value(interpret(declaration.expression, null<stack<map<*ast_node,value>>>(), value::void_nothing(), null<ast_node>(), null<stack<*ast_node>>()).first))
|
store_into_variable(globals[declaration.identifier], get_real_value(interpret(declaration.expression, null<stack<map<*ast_node,value>>>(), value::void_nothing(), null<ast_node>()).first))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fun interpret_function_call(func_call: *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> {
|
fun interpret_function_call(func_call: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
||||||
var func_call_parameters = func_call->function_call.parameters
|
var func_call_parameters = func_call->function_call.parameters
|
||||||
var func_call_func = func_call->function_call.func
|
var func_call_func = func_call->function_call.func
|
||||||
var new_enclosing_object = value::void_nothing()
|
var new_enclosing_object = value::void_nothing()
|
||||||
@@ -575,13 +575,13 @@ obj interpreter (Object) {
|
|||||||
// test for function value
|
// test for function value
|
||||||
if (!dot_style_method_call && !is_function(func_call_func)) {
|
if (!dot_style_method_call && !is_function(func_call_func)) {
|
||||||
/*error("func_call_func is not a function")*/
|
/*error("func_call_func is not a function")*/
|
||||||
println(string("func_call_func is not a function: ") + get_ast_name(func_call_func))
|
/*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
|
func_call_func = get_real_value(interpret(func_call_func, var_stack, enclosing_object, enclosing_func).first).function.first
|
||||||
println(string("calling func we got from interpreting: ") + get_ast_name(func_call_func))
|
/*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
|
// note here also that this is likely not a foolproof method
|
||||||
if (dot_style_method_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)
|
new_enclosing_object = get_real_value(interpret(func_call_func->function_call.parameters[0], var_stack, enclosing_object, enclosing_func).first)
|
||||||
// do a dereference
|
// do a dereference
|
||||||
if (is_pointer(new_enclosing_object))
|
if (is_pointer(new_enclosing_object))
|
||||||
new_enclosing_object = get_real_value(value::variable(make_pair(new_enclosing_object.pointer.first, new_enclosing_object.pointer.second->clone_with_decreased_indirection())))
|
new_enclosing_object = get_real_value(value::variable(make_pair(new_enclosing_object.pointer.first, new_enclosing_object.pointer.second->clone_with_decreased_indirection())))
|
||||||
@@ -596,12 +596,9 @@ obj interpreter (Object) {
|
|||||||
var func_name = func_call_func->function.name
|
var func_name = func_call_func->function.name
|
||||||
// some of these have to be done before parameters are evaluated (&&, ||, ., ->)
|
// some of these have to be done before parameters are evaluated (&&, ||, ., ->)
|
||||||
if (func_name == "&&" || func_name == "||") {
|
if (func_name == "&&" || func_name == "||") {
|
||||||
var p1true = truthy(get_real_value(interpret(func_call_parameters[0], var_stack, enclosing_object, enclosing_func, defer_stack).first))
|
error("short circuit still in interpreter")
|
||||||
if ( (func_name == "&&" && !p1true) || (func_name == "||" && p1true) )
|
|
||||||
return make_pair(value::boolean(p1true), control_flow::nor())
|
|
||||||
return make_pair(value::boolean(truthy(get_real_value(interpret(func_call_parameters[1], var_stack, enclosing_object, enclosing_func, defer_stack).first))), control_flow::nor())
|
|
||||||
} else if (func_name == "." || func_name == "->") {
|
} else if (func_name == "." || func_name == "->") {
|
||||||
var left_side = get_real_value(interpret(func_call_parameters[0], var_stack, enclosing_object, enclosing_func, defer_stack).first)
|
var left_side = get_real_value(interpret(func_call_parameters[0], var_stack, enclosing_object, enclosing_func).first)
|
||||||
var ret_ptr = null<void>()
|
var ret_ptr = null<void>()
|
||||||
if (func_name == "->")
|
if (func_name == "->")
|
||||||
ret_ptr = ((left_side.pointer.first) cast *char + offset_into_struct(left_side.pointer.second->clone_with_decreased_indirection(), func_call_parameters[1])) cast *void
|
ret_ptr = ((left_side.pointer.first) cast *char + offset_into_struct(left_side.pointer.second->clone_with_decreased_indirection(), func_call_parameters[1])) cast *void
|
||||||
@@ -615,7 +612,7 @@ obj interpreter (Object) {
|
|||||||
var parameter_sources = vector<*ast_node>()
|
var parameter_sources = vector<*ast_node>()
|
||||||
// if we don't have to copy_construct params (is an operator, or has no object params)
|
// if we don't have to copy_construct params (is an operator, or has no object params)
|
||||||
if (func_name == "&" || !func_call_parameters.any_true(fun(p: *ast_node): bool return get_ast_type(p)->is_object() && get_ast_type(p)->indirection == 0;)) {
|
if (func_name == "&" || !func_call_parameters.any_true(fun(p: *ast_node): bool return get_ast_type(p)->is_object() && get_ast_type(p)->indirection == 0;)) {
|
||||||
parameters = func_call_parameters.map(fun(p: *ast_node): value return interpret(p, var_stack, enclosing_object, enclosing_func, defer_stack).first;)
|
parameters = func_call_parameters.map(fun(p: *ast_node): value return interpret(p, var_stack, enclosing_object, enclosing_func).first;)
|
||||||
if ( parameters.size == 2 && (func_name == "+" || func_name == "-" || func_name == "*" || func_name == "/"
|
if ( parameters.size == 2 && (func_name == "+" || func_name == "-" || func_name == "*" || func_name == "/"
|
||||||
|| func_name == "<" || func_name == ">" || func_name == "<=" || func_name == ">="
|
|| func_name == "<" || func_name == ">" || func_name == "<=" || func_name == ">="
|
||||||
|| func_name == "==" || func_name == "!=" || func_name == "%" || func_name == "^"
|
|| func_name == "==" || func_name == "!=" || func_name == "%" || func_name == "^"
|
||||||
@@ -663,12 +660,12 @@ obj interpreter (Object) {
|
|||||||
// not the operator & and at least one object like parameter
|
// not the operator & and at least one object like parameter
|
||||||
parameter_sources = func_call_parameters
|
parameter_sources = func_call_parameters
|
||||||
}
|
}
|
||||||
return make_pair(call_function(func_call_func, parameters, parameter_sources, var_stack, defer_stack, enclosing_object, new_enclosing_object, enclosing_func), control_flow::nor())
|
return make_pair(call_function(func_call_func, parameters, parameter_sources, var_stack, enclosing_object, new_enclosing_object, enclosing_func), control_flow::nor())
|
||||||
}
|
}
|
||||||
// call_function can be called with either parameter values in parameters or ast expressions in parameter_sources
|
// call_function can be called with either parameter values in parameters or ast expressions in parameter_sources
|
||||||
// this is to allow easy function calling if we already have the values (for main, say, or to make our job if it's not
|
// this is to allow easy function calling if we already have the values (for main, say, or to make our job if it's not
|
||||||
// an operator easier), but we need to be able to be called with ast_expressions too so we can properly copy_construct once
|
// an operator easier), but we need to be able to be called with ast_expressions too so we can properly copy_construct once
|
||||||
fun call_function(func: *ast_node, parameters: vector<value>, parameter_sources: vector<*ast_node>, var_stack: *stack<map<*ast_node, value>>, defer_stack: *stack<*ast_node>, enclosing_object: value, new_enclosing_object: value, enclosing_func: *ast_node): value {
|
fun call_function(func: *ast_node, parameters: vector<value>, parameter_sources: vector<*ast_node>, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, new_enclosing_object: value, enclosing_func: *ast_node): value {
|
||||||
// will need adjustment
|
// will need adjustment
|
||||||
if (!is_function(func))
|
if (!is_function(func))
|
||||||
error("Can't handle not function function calls (can do regular method, is this chained or something?)")
|
error("Can't handle not function function calls (can do regular method, is this chained or something?)")
|
||||||
@@ -676,9 +673,6 @@ obj interpreter (Object) {
|
|||||||
// do regular function
|
// do regular function
|
||||||
var new_var_stack = stack<map<*ast_node, value>>()
|
var new_var_stack = stack<map<*ast_node, value>>()
|
||||||
new_var_stack.push(map<*ast_node,value>())
|
new_var_stack.push(map<*ast_node,value>())
|
||||||
var new_defer_stack = stack<*ast_node>()
|
|
||||||
// the param defer stack takes care of destructing parameters that were copy_constructed
|
|
||||||
var param_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) {
|
||||||
/*println(func_name + " being called with parameter values")*/
|
/*println(func_name + " being called with parameter values")*/
|
||||||
@@ -695,7 +689,8 @@ obj interpreter (Object) {
|
|||||||
} else {
|
} else {
|
||||||
new_var_stack.top()[param_ident] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
|
new_var_stack.top()[param_ident] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
|
||||||
//HERE
|
//HERE
|
||||||
(new_var_stack.top()[param_ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
|
if (param_type->indirection == 0 && param_type->is_function())
|
||||||
|
(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]))
|
store_into_variable(new_var_stack.top()[param_ident], get_real_value(parameters[i]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -710,44 +705,27 @@ obj interpreter (Object) {
|
|||||||
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]
|
||||||
if (param_type->is_ref) {
|
if (param_type->is_ref) {
|
||||||
var param = interpret(parameter_sources[i], var_stack, enclosing_object, enclosing_func, ¶m_defer_stack).first
|
var param = interpret(parameter_sources[i], var_stack, enclosing_object, enclosing_func).first
|
||||||
if (is_variable(param))
|
if (is_variable(param))
|
||||||
new_var_stack.top()[param_ident] = param
|
new_var_stack.top()[param_ident] = param
|
||||||
else
|
else
|
||||||
new_var_stack.top()[param_ident] = wrap_into_variable(param)
|
new_var_stack.top()[param_ident] = wrap_into_variable(param)
|
||||||
} else if (param_type->indirection == 0 && (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 {
|
} else {
|
||||||
new_var_stack.top()[param_ident] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
|
new_var_stack.top()[param_ident] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
|
||||||
//HERE
|
//HERE
|
||||||
(new_var_stack.top()[param_ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
|
if (param_type->indirection == 0 && param_type->is_function())
|
||||||
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))
|
(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).first))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var to_ret = interpret(func->function.body_statement, &new_var_stack, new_enclosing_object, func, &new_defer_stack).first
|
var to_ret = interpret(func->function.body_statement, &new_var_stack, new_enclosing_object, func).first
|
||||||
// handle destructing params
|
|
||||||
interpret_from_defer_stack(&new_defer_stack, &new_var_stack, enclosing_object, enclosing_func)
|
|
||||||
// to_ret is on the new_var_stack, likely
|
// to_ret is on the new_var_stack, likely
|
||||||
/*pop_and_free(&new_var_stack)*/
|
/*pop_and_free(&new_var_stack)*/
|
||||||
if (parameter_sources.size) {
|
if (parameter_sources.size) {
|
||||||
// pop off the temporaries if we needed to, but only after destructing any params we needed to
|
// pop off the temporaries if we needed to, but only after destructing any params we needed to
|
||||||
interpret_from_defer_stack(¶m_defer_stack, var_stack, enclosing_object, enclosing_func)
|
|
||||||
pop_and_free(var_stack)
|
pop_and_free(var_stack)
|
||||||
}
|
}
|
||||||
var return_type = func->function.type->return_type
|
|
||||||
if (!return_type->is_ref && return_type->indirection == 0 && (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") + get_id(), return_type, null<ast_node>())
|
|
||||||
var_stack->top()[temp_ident] = 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>())))
|
|
||||||
}
|
|
||||||
return to_ret
|
return to_ret
|
||||||
}
|
}
|
||||||
fun call_built_in_extern(func_name: string, parameters: vector<value>): value {
|
fun call_built_in_extern(func_name: string, parameters: vector<value>): value {
|
||||||
@@ -819,63 +797,54 @@ obj interpreter (Object) {
|
|||||||
}
|
}
|
||||||
return value::void_nothing()
|
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> {
|
fun interpret_function(function: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
||||||
return make_pair(value::function(make_pair(function, map<*ast_node,value>())), control_flow::nor())
|
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> {
|
fun interpret_statement(stmt: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
||||||
return interpret(stmt->statement.child, var_stack, enclosing_object, enclosing_func, defer_stack)
|
return interpret(stmt->statement.child, var_stack, enclosing_object, enclosing_func)
|
||||||
}
|
}
|
||||||
fun interpret_if_statement(if_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> {
|
fun interpret_if_statement(if_stmt: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
||||||
var_stack->push(map<*ast_node,value>())
|
var_stack->push(map<*ast_node,value>())
|
||||||
var inner_defer_stack = stack<*ast_node>()
|
|
||||||
var value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
|
var value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
|
||||||
if (truthy(interpret(if_stmt->if_statement.condition, var_stack, enclosing_object, enclosing_func, &inner_defer_stack).first)) {
|
if (truthy(interpret(if_stmt->if_statement.condition, var_stack, enclosing_object, enclosing_func).first)) {
|
||||||
value_from_inside = interpret(if_stmt->if_statement.then_part, var_stack, enclosing_object, enclosing_func, &inner_defer_stack)
|
value_from_inside = interpret(if_stmt->if_statement.then_part, var_stack, enclosing_object, enclosing_func)
|
||||||
} else if (if_stmt->if_statement.else_part) {
|
} else if (if_stmt->if_statement.else_part) {
|
||||||
value_from_inside = interpret(if_stmt->if_statement.else_part, var_stack, enclosing_object, enclosing_func, &inner_defer_stack)
|
value_from_inside = interpret(if_stmt->if_statement.else_part, var_stack, enclosing_object, enclosing_func)
|
||||||
}
|
}
|
||||||
interpret_from_defer_stack(&inner_defer_stack, var_stack, value::void_nothing(), enclosing_func)
|
|
||||||
pop_and_free(var_stack)
|
pop_and_free(var_stack)
|
||||||
return value_from_inside
|
return value_from_inside
|
||||||
}
|
}
|
||||||
fun interpret_while_loop(while_loop: *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> {
|
fun interpret_while_loop(while_loop: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
||||||
var_stack->push(map<*ast_node,value>())
|
var_stack->push(map<*ast_node,value>())
|
||||||
var inner_defer_stack = stack<*ast_node>()
|
|
||||||
var value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
|
var value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
|
||||||
var going = true
|
var going = true
|
||||||
while (going && truthy(interpret(while_loop->while_loop.condition, var_stack, enclosing_object, enclosing_func, &inner_defer_stack).first)) {
|
while (going && truthy(interpret(while_loop->while_loop.condition, var_stack, enclosing_object, enclosing_func).first)) {
|
||||||
value_from_inside = interpret(while_loop->while_loop.statement, var_stack, enclosing_object, enclosing_func, &inner_defer_stack)
|
value_from_inside = interpret(while_loop->while_loop.statement, var_stack, enclosing_object, enclosing_func)
|
||||||
interpret_from_defer_stack(&inner_defer_stack, var_stack, value::void_nothing(), enclosing_func)
|
|
||||||
inner_defer_stack.clear()
|
|
||||||
if (value_from_inside.second == control_flow::ret() || value_from_inside.second == control_flow::bre())
|
if (value_from_inside.second == control_flow::ret() || value_from_inside.second == control_flow::bre())
|
||||||
going = false
|
going = false
|
||||||
if (value_from_inside.second == control_flow::bre() || value_from_inside.second == control_flow::con())
|
if (value_from_inside.second == control_flow::bre() || value_from_inside.second == control_flow::con())
|
||||||
value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
|
value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
|
||||||
}
|
}
|
||||||
interpret_from_defer_stack(&inner_defer_stack, var_stack, value::void_nothing(), enclosing_func)
|
|
||||||
pop_and_free(var_stack)
|
pop_and_free(var_stack)
|
||||||
return value_from_inside
|
return value_from_inside
|
||||||
}
|
}
|
||||||
fun interpret_for_loop(for_loop: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
fun interpret_for_loop(for_loop: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
||||||
var defer_stack = stack<*ast_node>()
|
|
||||||
var_stack->push(map<*ast_node,value>())
|
var_stack->push(map<*ast_node,value>())
|
||||||
var value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
|
var value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
|
||||||
var going = true
|
var going = true
|
||||||
interpret(for_loop->for_loop.init, var_stack, enclosing_object, enclosing_func, &defer_stack)
|
if (for_loop->for_loop.init)
|
||||||
while (going && truthy(interpret(for_loop->for_loop.condition, var_stack, enclosing_object, enclosing_func, &defer_stack).first)) {
|
interpret(for_loop->for_loop.init, var_stack, enclosing_object, enclosing_func)
|
||||||
value_from_inside = interpret(for_loop->for_loop.body, var_stack, enclosing_object, enclosing_func, &defer_stack)
|
while (going && (!for_loop->for_loop.condition || truthy(interpret(for_loop->for_loop.condition, var_stack, enclosing_object, enclosing_func).first))) {
|
||||||
|
value_from_inside = interpret(for_loop->for_loop.body, var_stack, enclosing_object, enclosing_func)
|
||||||
if (value_from_inside.second == control_flow::ret() || value_from_inside.second == control_flow::bre())
|
if (value_from_inside.second == control_flow::ret() || value_from_inside.second == control_flow::bre())
|
||||||
going = false
|
going = false
|
||||||
if (value_from_inside.second == control_flow::bre() || value_from_inside.second == control_flow::con())
|
if (value_from_inside.second == control_flow::bre() || value_from_inside.second == control_flow::con())
|
||||||
value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
|
value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
|
||||||
|
|
||||||
// only run update if we're not breaking or continuing
|
// only run update if we're not breaking or continuing
|
||||||
if (going)
|
if (going && for_loop->for_loop.update)
|
||||||
interpret(for_loop->for_loop.update, var_stack, enclosing_object, enclosing_func, &defer_stack)
|
interpret(for_loop->for_loop.update, var_stack, enclosing_object, enclosing_func)
|
||||||
interpret_from_defer_stack(&defer_stack, var_stack, enclosing_object, enclosing_func)
|
|
||||||
defer_stack.clear()
|
|
||||||
}
|
}
|
||||||
interpret_from_defer_stack(&defer_stack, var_stack, enclosing_object, enclosing_func)
|
|
||||||
pop_and_free(var_stack)
|
pop_and_free(var_stack)
|
||||||
return value_from_inside
|
return value_from_inside
|
||||||
}
|
}
|
||||||
@@ -888,90 +857,62 @@ obj interpreter (Object) {
|
|||||||
}
|
}
|
||||||
fun interpret_code_block(block: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
fun interpret_code_block(block: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
||||||
var_stack->push(map<*ast_node,value>())
|
var_stack->push(map<*ast_node,value>())
|
||||||
var defer_stack = stack<*ast_node>()
|
|
||||||
for (var i = 0; i < block->code_block.children.size; i++;) {
|
for (var i = 0; i < block->code_block.children.size; i++;) {
|
||||||
var statement = interpret(block->code_block.children[i], var_stack, enclosing_object, enclosing_func, &defer_stack)
|
var statement = interpret(block->code_block.children[i], var_stack, enclosing_object, enclosing_func)
|
||||||
match (statement.second) {
|
match (statement.second) {
|
||||||
control_flow::con() {
|
control_flow::con() {
|
||||||
interpret_from_defer_stack(&defer_stack, var_stack, enclosing_object, enclosing_func)
|
|
||||||
pop_and_free(var_stack)
|
pop_and_free(var_stack)
|
||||||
return make_pair(value::void_nothing(), control_flow::con())
|
return make_pair(value::void_nothing(), control_flow::con())
|
||||||
}
|
}
|
||||||
control_flow::bre() {
|
control_flow::bre() {
|
||||||
interpret_from_defer_stack(&defer_stack, var_stack, enclosing_object, enclosing_func)
|
|
||||||
pop_and_free(var_stack)
|
pop_and_free(var_stack)
|
||||||
return make_pair(value::void_nothing(), control_flow::bre())
|
return make_pair(value::void_nothing(), control_flow::bre())
|
||||||
}
|
}
|
||||||
control_flow::ret() {
|
control_flow::ret() {
|
||||||
interpret_from_defer_stack(&defer_stack, var_stack, enclosing_object, enclosing_func)
|
|
||||||
pop_and_free(var_stack)
|
pop_and_free(var_stack)
|
||||||
return statement
|
return statement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if nor, continue on
|
// if nor, continue on
|
||||||
}
|
}
|
||||||
interpret_from_defer_stack(&defer_stack, var_stack, enclosing_object, enclosing_func)
|
|
||||||
pop_and_free(var_stack)
|
pop_and_free(var_stack)
|
||||||
return make_pair(value::void_nothing(), control_flow::nor())
|
return make_pair(value::void_nothing(), control_flow::nor())
|
||||||
}
|
}
|
||||||
fun interpret_from_defer_stack(defer_stack: *stack<*ast_node>, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node) {
|
fun interpret_return_statement(stmt: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
||||||
var new_defer_stack = stack<*ast_node>()
|
|
||||||
defer_stack->for_each_reverse(fun(i: *ast_node) {
|
|
||||||
interpret(i, var_stack, enclosing_object, enclosing_func, &new_defer_stack)
|
|
||||||
})
|
|
||||||
if (new_defer_stack.size())
|
|
||||||
interpret_from_defer_stack(&new_defer_stack, var_stack, enclosing_object, enclosing_func)
|
|
||||||
}
|
|
||||||
fun interpret_return_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> {
|
|
||||||
if (stmt->return_statement.return_value == null<ast_node>())
|
if (stmt->return_statement.return_value == null<ast_node>())
|
||||||
return make_pair(value::void_nothing(), control_flow::ret())
|
return make_pair(value::void_nothing(), control_flow::ret())
|
||||||
var return_expression = stmt->return_statement.return_value
|
var return_expression = stmt->return_statement.return_value
|
||||||
var return_type = get_ast_type(return_expression)
|
var return_type = get_ast_type(return_expression)
|
||||||
var to_ret.construct(): value
|
var to_ret.construct(): value
|
||||||
if (get_ast_type(enclosing_func)->return_type->is_ref) {
|
if (get_ast_type(enclosing_func)->return_type->is_ref) {
|
||||||
to_ret = interpret(return_expression, var_stack, enclosing_object, enclosing_func, defer_stack).first
|
to_ret = interpret(return_expression, var_stack, enclosing_object, enclosing_func).first
|
||||||
} else if (return_type->indirection == 0 && (return_type->is_object() && has_method(return_type->type_def, "copy_construct", vector(return_type->clone_with_increased_indirection())))) {
|
|
||||||
var_stack->push(map<*ast_node,value>())
|
|
||||||
var inner_defer_stack = stack<*ast_node>()
|
|
||||||
var temp_ident = ast_identifier_ptr(string("temporary_return"), return_type, null<ast_node>())
|
|
||||||
var_stack->top()[temp_ident] = 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, enclosing_func, &inner_defer_stack)
|
|
||||||
to_ret = var_stack->top()[temp_ident]
|
|
||||||
interpret_from_defer_stack(&inner_defer_stack, var_stack, enclosing_object, enclosing_func)
|
|
||||||
// don't want to free our to_ret
|
|
||||||
var_stack->pop()
|
|
||||||
/*pop_and_free(var_stack)*/
|
|
||||||
} else {
|
} else {
|
||||||
to_ret = value::variable(make_pair(malloc(type_size(return_type)), return_type))
|
to_ret = value::variable(make_pair(malloc(type_size(return_type)), return_type))
|
||||||
//HERE
|
//HERE
|
||||||
(to_ret.variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
|
if (return_type->indirection == 0 && return_type->is_function())
|
||||||
var ret_val = interpret(return_expression, var_stack, enclosing_object, enclosing_func, defer_stack).first
|
(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).first
|
||||||
store_into_variable(to_ret, get_real_value(ret_val))
|
store_into_variable(to_ret, get_real_value(ret_val))
|
||||||
}
|
}
|
||||||
return make_pair(get_real_value(to_ret), control_flow::ret())
|
return make_pair(get_real_value(to_ret), control_flow::ret())
|
||||||
}
|
}
|
||||||
fun interpret_declaration_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> {
|
fun interpret_declaration_statement(stmt: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
||||||
var ident = stmt->declaration_statement.identifier
|
var ident = stmt->declaration_statement.identifier
|
||||||
var ident_type = ident->identifier.type
|
var ident_type = ident->identifier.type
|
||||||
var_stack->top()[ident] = value::variable(make_pair(malloc(type_size(ident_type)),ident_type))
|
var_stack->top()[ident] = value::variable(make_pair(malloc(type_size(ident_type)),ident_type))
|
||||||
//HERE
|
//HERE
|
||||||
(var_stack->top()[ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
|
if (ident_type->indirection == 0 && ident_type->is_function())
|
||||||
|
(var_stack->top()[ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
|
||||||
if (stmt->declaration_statement.expression) {
|
if (stmt->declaration_statement.expression) {
|
||||||
if (ident_type->indirection == 0 && (ident_type->is_object() && has_method(ident_type->type_def, "copy_construct", vector(get_ast_type(stmt->declaration_statement.expression)->clone_with_increased_indirection()))))
|
store_into_variable(var_stack->top()[ident], get_real_value(interpret(stmt->declaration_statement.expression, var_stack, enclosing_object, enclosing_func).first))
|
||||||
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)
|
|
||||||
else
|
|
||||||
store_into_variable(var_stack->top()[ident], get_real_value(interpret(stmt->declaration_statement.expression, var_stack, enclosing_object, enclosing_func, defer_stack).first))
|
|
||||||
} else if (stmt->declaration_statement.init_method_call) {
|
} else if (stmt->declaration_statement.init_method_call) {
|
||||||
interpret(stmt->declaration_statement.init_method_call, var_stack, enclosing_object, enclosing_func, defer_stack)
|
interpret(stmt->declaration_statement.init_method_call, var_stack, enclosing_object, enclosing_func)
|
||||||
}
|
}
|
||||||
// defering destructs
|
|
||||||
if (ident_type->indirection == 0 && (ident_type->is_object() && has_method(ident_type->type_def, "destruct", vector<*type>())))
|
|
||||||
defer_stack->push(ast_statement_ptr(make_method_call(ident, "destruct", vector<*ast_node>())))
|
|
||||||
return make_pair(value::void_nothing(), control_flow::nor())
|
return make_pair(value::void_nothing(), control_flow::nor())
|
||||||
}
|
}
|
||||||
fun interpret_assignment_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> {
|
fun interpret_assignment_statement(stmt: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
||||||
var to = interpret(stmt->assignment_statement.to, var_stack, enclosing_object, enclosing_func, defer_stack).first
|
var to = interpret(stmt->assignment_statement.to, var_stack, enclosing_object, enclosing_func).first
|
||||||
var from = interpret(stmt->assignment_statement.from, var_stack, enclosing_object, enclosing_func, defer_stack).first
|
var from = interpret(stmt->assignment_statement.from, var_stack, enclosing_object, enclosing_func).first
|
||||||
assert(is_variable(to), "assigning into not a variable")
|
assert(is_variable(to), "assigning into not a variable")
|
||||||
// always do cast now to make our best effort at assignment (assign into a double from a float, etc)
|
// always do cast now to make our best effort at assignment (assign into a double from a float, etc)
|
||||||
// unless it's an object
|
// unless it's an object
|
||||||
@@ -982,10 +923,6 @@ obj interpreter (Object) {
|
|||||||
store_into_variable(to, cast_value(from_real, to.variable.second))
|
store_into_variable(to, cast_value(from_real, to.variable.second))
|
||||||
return make_pair(value::void_nothing(), control_flow::nor())
|
return make_pair(value::void_nothing(), control_flow::nor())
|
||||||
}
|
}
|
||||||
fun interpret_defer_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> {
|
|
||||||
defer_stack->push(stmt->defer_statement.statement)
|
|
||||||
return make_pair(value::void_nothing(), control_flow::nor())
|
|
||||||
}
|
|
||||||
fun interpret_identifier(ident: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
fun interpret_identifier(ident: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
||||||
for (var i = 0; i < var_stack->size(); i++;)
|
for (var i = 0; i < var_stack->size(); i++;)
|
||||||
if (var_stack->from_top(i).contains_key(ident))
|
if (var_stack->from_top(i).contains_key(ident))
|
||||||
@@ -1007,8 +944,8 @@ obj interpreter (Object) {
|
|||||||
return make_pair(globals[ident], control_flow::nor())
|
return make_pair(globals[ident], control_flow::nor())
|
||||||
error(string("Cannot find variable: ") + ident->identifier.name)
|
error(string("Cannot find variable: ") + ident->identifier.name)
|
||||||
}
|
}
|
||||||
fun interpret_cast(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> {
|
fun interpret_cast(node: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
||||||
return make_pair(cast_value(interpret(node->cast.value, var_stack, enclosing_object, enclosing_func, defer_stack).first, node->cast.to_type), control_flow::nor())
|
return make_pair(cast_value(interpret(node->cast.value, var_stack, enclosing_object, enclosing_func).first, node->cast.to_type), control_flow::nor())
|
||||||
}
|
}
|
||||||
fun interpret_compiler_intrinsic(node: *ast_node, var_stack: *stack<map<*ast_node, value>>): pair<value, control_flow> {
|
fun interpret_compiler_intrinsic(node: *ast_node, var_stack: *stack<map<*ast_node, value>>): pair<value, control_flow> {
|
||||||
var intrinsic_name = node->compiler_intrinsic.intrinsic
|
var intrinsic_name = node->compiler_intrinsic.intrinsic
|
||||||
@@ -1018,22 +955,22 @@ obj interpreter (Object) {
|
|||||||
}
|
}
|
||||||
fun interpret_value(val: *ast_node): pair<value, control_flow>
|
fun interpret_value(val: *ast_node): pair<value, control_flow>
|
||||||
return make_pair(wrap_value(val), control_flow::nor())
|
return make_pair(wrap_value(val), control_flow::nor())
|
||||||
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> {
|
fun interpret(node: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
||||||
|
if (!node) error("cannot interpret null node!")
|
||||||
match (*node) {
|
match (*node) {
|
||||||
ast_node::function_call(backing) return interpret_function_call(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
ast_node::function_call(backing) return interpret_function_call(node, var_stack, enclosing_object, enclosing_func)
|
||||||
ast_node::function(backing) return interpret_function(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
ast_node::function(backing) return interpret_function(node, var_stack, enclosing_object, enclosing_func)
|
||||||
ast_node::statement(backing) return interpret_statement(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
ast_node::statement(backing) return interpret_statement(node, var_stack, enclosing_object, enclosing_func)
|
||||||
ast_node::if_statement(backing) return interpret_if_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)
|
||||||
ast_node::while_loop(backing) return interpret_while_loop(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)
|
||||||
ast_node::for_loop(backing) return interpret_for_loop(node, var_stack, enclosing_object, enclosing_func)
|
ast_node::for_loop(backing) return interpret_for_loop(node, var_stack, enclosing_object, enclosing_func)
|
||||||
ast_node::branching_statement(backing) return interpret_branching_statement(node)
|
ast_node::branching_statement(backing) return interpret_branching_statement(node)
|
||||||
ast_node::code_block(backing) return interpret_code_block(node, var_stack, enclosing_object, enclosing_func)
|
ast_node::code_block(backing) return interpret_code_block(node, var_stack, enclosing_object, enclosing_func)
|
||||||
ast_node::return_statement(backing) return interpret_return_statement(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
ast_node::return_statement(backing) return interpret_return_statement(node, var_stack, enclosing_object, enclosing_func)
|
||||||
ast_node::declaration_statement(backing) return interpret_declaration_statement(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
ast_node::declaration_statement(backing) return interpret_declaration_statement(node, var_stack, enclosing_object, enclosing_func)
|
||||||
ast_node::assignment_statement(backing) return interpret_assignment_statement(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
ast_node::assignment_statement(backing) return interpret_assignment_statement(node, var_stack, enclosing_object, enclosing_func)
|
||||||
ast_node::defer_statement(backing) return interpret_defer_statement(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
|
||||||
ast_node::identifier(backing) return interpret_identifier(node, var_stack, enclosing_object, enclosing_func)
|
ast_node::identifier(backing) return interpret_identifier(node, var_stack, enclosing_object, enclosing_func)
|
||||||
ast_node::cast(backing) return interpret_cast(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
ast_node::cast(backing) return interpret_cast(node, var_stack, enclosing_object, enclosing_func)
|
||||||
ast_node::compiler_intrinsic(backing) return interpret_compiler_intrinsic(node, var_stack)
|
ast_node::compiler_intrinsic(backing) return interpret_compiler_intrinsic(node, var_stack)
|
||||||
ast_node::value(backing) return interpret_value(node)
|
ast_node::value(backing) return interpret_value(node)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user