Added a lot to the interpreter, but some odd problem where snprintf seems to print the wrong thing something like a 10th of the time. Debugged it for a while over two days, and I've narrowed it down to the actual snprintf call. It seems to happen under some different circumstances for compiled versions too, so I'm just going to keep it like this for now.
This commit is contained in:
+1
-1
@@ -87,7 +87,7 @@ fun main(argc: int, argv: **char):int {
|
|||||||
var kraken_c_output_name = kraken_file_name + ".c"
|
var kraken_c_output_name = kraken_file_name + ".c"
|
||||||
write_file(kraken_c_output_name, c_output_pair.first)
|
write_file(kraken_c_output_name, c_output_pair.first)
|
||||||
/*println(string("linker string: ") + c_output_pair.second)*/
|
/*println(string("linker string: ") + c_output_pair.second)*/
|
||||||
var compile_string = "cc -g -O3 -std=c99 " + c_output_pair.second + " " + kraken_c_output_name + " -o " + executable_name
|
var compile_string = "cc -g -O3 -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -std=c99 " + c_output_pair.second + " " + kraken_c_output_name + " -o " + executable_name
|
||||||
println(compile_string)
|
println(compile_string)
|
||||||
system(compile_string)
|
system(compile_string)
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-9
@@ -84,6 +84,15 @@ fun is_dot_style_method_call(node: *ast_node): bool {
|
|||||||
is_adt_def(get_ast_scope(node->function_call.func->function_call.parameters[1])->get(string("~enclosing_scope"))[0]))
|
is_adt_def(get_ast_scope(node->function_call.func->function_call.parameters[1])->get(string("~enclosing_scope"))[0]))
|
||||||
// should get uglier when we have to figure out if it's just an inside lambda
|
// should get uglier when we have to figure out if it's just an inside lambda
|
||||||
}
|
}
|
||||||
|
fun method_in_object(method: *ast_node, enclosing_object: *ast_node): bool {
|
||||||
|
var methods = enclosing_object->type_def.methods
|
||||||
|
for (var i = 0; i < methods.size; i++;) {
|
||||||
|
if (methods[i] == method || (is_template(methods[i]) && methods[i]->template.instantiated.contains(method))) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
obj c_generator (Object) {
|
obj c_generator (Object) {
|
||||||
var id_counter: int
|
var id_counter: int
|
||||||
var ast_to_syntax: map<*ast_node, *tree<symbol>>
|
var ast_to_syntax: map<*ast_node, *tree<symbol>>
|
||||||
@@ -789,15 +798,11 @@ obj c_generator (Object) {
|
|||||||
}
|
}
|
||||||
// handle method call from inside method of same object
|
// handle method call from inside method of same object
|
||||||
if (!dot_style_method_call && enclosing_object) {
|
if (!dot_style_method_call && enclosing_object) {
|
||||||
var methods = enclosing_object->type_def.methods
|
if (method_in_object(node->function_call.func, enclosing_object)) {
|
||||||
for (var i = 0; i < methods.size; i++;) {
|
if (enclosing_func && enclosing_func->function.closed_variables.size())
|
||||||
if (methods[i] == node->function_call.func || (is_template(methods[i]) && methods[i]->template.instantiated.contains(node->function_call.func))) {
|
call_string += "(*(closure_data->this))";
|
||||||
if (enclosing_func && enclosing_func->function.closed_variables.size())
|
else
|
||||||
call_string += "(*(closure_data->this))";
|
call_string += "this";
|
||||||
else
|
|
||||||
call_string += "this";
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+96
-51
@@ -81,6 +81,9 @@ fun wrap_value(val: *ast_node): value {
|
|||||||
to_ret += value_str[i]
|
to_ret += value_str[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// if there was only one character
|
||||||
|
if (value_str.length() == 1)
|
||||||
|
to_ret = value_str
|
||||||
return value::pointer(make_pair((to_ret.toCharArray()) cast *void, get_ast_type(val)))
|
return value::pointer(make_pair((to_ret.toCharArray()) cast *void, get_ast_type(val)))
|
||||||
} else if (value_str[0] == '\'') //'// lol, comment hack for vim syntax highlighting (my fault, of course)
|
} else if (value_str[0] == '\'') //'// lol, comment hack for vim syntax highlighting (my fault, of course)
|
||||||
return value::character(value_str[1])
|
return value::character(value_str[1])
|
||||||
@@ -435,7 +438,9 @@ fun offset_into_struct(struct_type: *type, ident: *ast_node): ulong {
|
|||||||
fun pop_and_free(var_stack: *stack<map<string, value>>) {
|
fun pop_and_free(var_stack: *stack<map<string, value>>) {
|
||||||
var_stack->pop().for_each(fun(k: string, v: value) {
|
var_stack->pop().for_each(fun(k: string, v: value) {
|
||||||
match(v) {
|
match(v) {
|
||||||
value::variable(backing) free(backing.first)
|
value::variable(backing) {
|
||||||
|
free(backing.first)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -477,30 +482,35 @@ obj interpreter (Object) {
|
|||||||
print_value(result)
|
print_value(result)
|
||||||
println("=============")
|
println("=============")
|
||||||
}
|
}
|
||||||
fun interpret_function_call(func_call: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value): pair<value, control_flow> {
|
fun interpret_function_call(func_call: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value, defer_stack: *stack<*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()
|
||||||
// note here also that this is likely not a foolproof method
|
// note here also that this is likely not a foolproof method
|
||||||
if (is_dot_style_method_call(func_call)) {
|
if (is_dot_style_method_call(func_call)) {
|
||||||
println("DOT STYLE METHOD CALL")
|
new_enclosing_object = get_real_value(interpret(func_call_func->function_call.parameters[0], var_stack, enclosing_object, defer_stack).first)
|
||||||
new_enclosing_object = get_real_value(interpret(func_call_func->function_call.parameters[0], var_stack, enclosing_object).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())))
|
||||||
func_call_func = func_call_func->function_call.parameters[1]
|
func_call_func = func_call_func->function_call.parameters[1]
|
||||||
|
} else if (!is_void_nothing(enclosing_object)) {
|
||||||
|
if (method_in_object(func_call_func, enclosing_object.object_like.second->type_def)) {
|
||||||
|
// should maybe do something special for closure here
|
||||||
|
// copy over old enclosing object
|
||||||
|
new_enclosing_object = enclosing_object
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// check if it's a same method method call and do the right new_enclosing_object
|
// check if it's a same method method call and do the right new_enclosing_object
|
||||||
// new_enclosing_object = enclosing_object
|
// new_enclosing_object = enclosing_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).first))
|
var p1true = truthy(get_real_value(interpret(func_call_parameters[0], var_stack, enclosing_object, defer_stack).first))
|
||||||
if ( (func_name == "&&" && !p1true) || (func_name == "||" && p1true) )
|
if ( (func_name == "&&" && !p1true) || (func_name == "||" && p1true) )
|
||||||
return make_pair(value::boolean(p1true), control_flow::nor())
|
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).first))), control_flow::nor())
|
return make_pair(value::boolean(truthy(get_real_value(interpret(func_call_parameters[1], var_stack, enclosing_object, 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).first)
|
var left_side = get_real_value(interpret(func_call_parameters[0], var_stack, enclosing_object, defer_stack).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
|
||||||
@@ -508,7 +518,7 @@ obj interpreter (Object) {
|
|||||||
ret_ptr = ((left_side.object_like.first) cast *char + offset_into_struct(left_side.object_like.second, func_call_parameters[1])) cast *void
|
ret_ptr = ((left_side.object_like.first) cast *char + offset_into_struct(left_side.object_like.second, func_call_parameters[1])) cast *void
|
||||||
return make_pair(value::variable(make_pair(ret_ptr, func_call_parameters[1]->identifier.type)), control_flow::nor())
|
return make_pair(value::variable(make_pair(ret_ptr, func_call_parameters[1]->identifier.type)), control_flow::nor())
|
||||||
}
|
}
|
||||||
var parameters = func_call_parameters.map(fun(p: *ast_node): value return interpret(p, var_stack, enclosing_object).first;)
|
var parameters = func_call_parameters.map(fun(p: *ast_node): value return interpret(p, var_stack, enclosing_object, defer_stack).first;)
|
||||||
return make_pair(call_function(func_call_func, parameters, var_stack, new_enclosing_object), control_flow::nor())
|
return make_pair(call_function(func_call_func, parameters, var_stack, new_enclosing_object), control_flow::nor())
|
||||||
}
|
}
|
||||||
fun call_function(func: *ast_node, parameters: vector<value>, var_stack: *stack<map<string, value>>, enclosing_object: value): value {
|
fun call_function(func: *ast_node, parameters: vector<value>, var_stack: *stack<map<string, value>>, enclosing_object: value): value {
|
||||||
@@ -548,7 +558,7 @@ obj interpreter (Object) {
|
|||||||
return value::variable(make_pair(get_real_value(dereference_val).pointer.first, dereference_val.pointer.second->clone_with_decreased_indirection()))
|
return value::variable(make_pair(get_real_value(dereference_val).pointer.first, dereference_val.pointer.second->clone_with_decreased_indirection()))
|
||||||
}
|
}
|
||||||
// check for built-in-ish externs (everything the standard library needs)
|
// check for built-in-ish externs (everything the standard library needs)
|
||||||
if (func_name == "printf" || func_name == "malloc" || func_name == "free" || func_name == "fflush" || func_name == "sprintf")
|
if (func_name == "printf" || func_name == "malloc" || func_name == "free" || func_name == "fflush" || func_name == "snprintf")
|
||||||
return call_built_in_extern(func_name, parameters)
|
return call_built_in_extern(func_name, parameters)
|
||||||
if (!func->function.body_statement)
|
if (!func->function.body_statement)
|
||||||
error(string("trying to call unsupported extern function: ") + func_name)
|
error(string("trying to call unsupported extern function: ") + func_name)
|
||||||
@@ -562,7 +572,9 @@ obj interpreter (Object) {
|
|||||||
new_var_stack.top()[func->function.parameters[i]->identifier.name] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
|
new_var_stack.top()[func->function.parameters[i]->identifier.name] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
|
||||||
store_into_variable(new_var_stack.top()[func->function.parameters[i]->identifier.name], get_real_value(parameters[i]))
|
store_into_variable(new_var_stack.top()[func->function.parameters[i]->identifier.name], get_real_value(parameters[i]))
|
||||||
}
|
}
|
||||||
var to_ret = interpret(func->function.body_statement, &new_var_stack, enclosing_object).first
|
// our defer stack to keep track of what needs to be evaluated later at runtime
|
||||||
|
var defer_stack = stack<*ast_node>()
|
||||||
|
var to_ret = interpret(func->function.body_statement, &new_var_stack, enclosing_object, &defer_stack).first
|
||||||
// need to handle copying out object before pop_and_free deletes them
|
// need to handle copying out object before pop_and_free deletes them
|
||||||
pop_and_free(&new_var_stack)
|
pop_and_free(&new_var_stack)
|
||||||
return to_ret
|
return to_ret
|
||||||
@@ -584,9 +596,9 @@ obj interpreter (Object) {
|
|||||||
} else if (func_name == "fflush") {
|
} else if (func_name == "fflush") {
|
||||||
assert(parameters.size == 1 && is_integer(parameters[0]), "Calling fflush with wrong params")
|
assert(parameters.size == 1 && is_integer(parameters[0]), "Calling fflush with wrong params")
|
||||||
fflush(parameters[0].integer)
|
fflush(parameters[0].integer)
|
||||||
} else if (func_name == "sprintf") {
|
} else if (func_name == "snprintf") {
|
||||||
assert(parameters.size == 3 && is_pointer(parameters[0]) && is_pointer(parameters[1]) && is_double_precision(parameters[2]), "Calling fflush with wrong params")
|
assert(parameters.size == 4 && is_pointer(parameters[0]) && is_ulong_int(parameters[1]) && is_pointer(parameters[2]) && is_double_precision(parameters[3]), "Calling snprintf with wrong params")
|
||||||
sprintf((parameters[0].pointer.first) cast *char, (parameters[1].pointer.first) cast *char, parameters[2].double_precision)
|
return value::integer(snprintf((parameters[0].pointer.first) cast *char, parameters[1].ulong_int, (parameters[2].pointer.first) cast *char, parameters[3].double_precision))
|
||||||
} else if (func_name == "exit") {
|
} else if (func_name == "exit") {
|
||||||
assert(parameters.size == 1 && is_integer(parameters[0]), "Calling exit with wrong params")
|
assert(parameters.size == 1 && is_integer(parameters[0]), "Calling exit with wrong params")
|
||||||
exit(parameters[0].integer)
|
exit(parameters[0].integer)
|
||||||
@@ -595,86 +607,118 @@ obj interpreter (Object) {
|
|||||||
}
|
}
|
||||||
return value::void_nothing()
|
return value::void_nothing()
|
||||||
}
|
}
|
||||||
fun interpret_statement(stmt: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value): pair<value, control_flow> {
|
fun interpret_statement(stmt: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
||||||
return interpret(stmt->statement.child, var_stack, enclosing_object)
|
return interpret(stmt->statement.child, var_stack, enclosing_object, defer_stack)
|
||||||
}
|
}
|
||||||
fun interpret_if_statement(if_stmt: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value): pair<value, control_flow> {
|
fun interpret_if_statement(if_stmt: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
||||||
var_stack->push(map<string,value>())
|
var_stack->push(map<string,value>())
|
||||||
if (truthy(interpret(if_stmt->if_statement.condition, var_stack, enclosing_object).first)) {
|
if (truthy(interpret(if_stmt->if_statement.condition, var_stack, enclosing_object, defer_stack).first)) {
|
||||||
interpret(if_stmt->if_statement.then_part, var_stack, enclosing_object)
|
interpret(if_stmt->if_statement.then_part, var_stack, enclosing_object, defer_stack)
|
||||||
} else if (if_stmt->if_statement.else_part) {
|
} else if (if_stmt->if_statement.else_part) {
|
||||||
interpret(if_stmt->if_statement.else_part, var_stack, enclosing_object)
|
interpret(if_stmt->if_statement.else_part, var_stack, enclosing_object, defer_stack)
|
||||||
}
|
}
|
||||||
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_while_loop(while_loop: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value): pair<value, control_flow> {
|
fun interpret_while_loop(while_loop: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
||||||
var_stack->push(map<string,value>())
|
var_stack->push(map<string,value>())
|
||||||
while (truthy(interpret(while_loop->while_loop.condition, var_stack, enclosing_object).first)) {
|
while (truthy(interpret(while_loop->while_loop.condition, var_stack, enclosing_object, defer_stack).first)) {
|
||||||
interpret(while_loop->while_loop.statement, var_stack, enclosing_object)
|
interpret(while_loop->while_loop.statement, var_stack, enclosing_object, defer_stack)
|
||||||
}
|
}
|
||||||
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_for_loop(for_loop: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value): pair<value, control_flow> {
|
fun interpret_for_loop(for_loop: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value): pair<value, control_flow> {
|
||||||
|
var defer_stack = stack<*ast_node>()
|
||||||
var_stack->push(map<string,value>())
|
var_stack->push(map<string,value>())
|
||||||
interpret(for_loop->for_loop.init, var_stack, enclosing_object)
|
interpret(for_loop->for_loop.init, var_stack, enclosing_object, &defer_stack)
|
||||||
while (truthy(interpret(for_loop->for_loop.condition, var_stack, enclosing_object).first)) {
|
while (truthy(interpret(for_loop->for_loop.condition, var_stack, enclosing_object, &defer_stack).first)) {
|
||||||
interpret(for_loop->for_loop.body, var_stack, enclosing_object)
|
var inner_defer_stack = stack<*ast_node>()
|
||||||
interpret(for_loop->for_loop.update, var_stack, enclosing_object)
|
interpret(for_loop->for_loop.body, var_stack, enclosing_object, &inner_defer_stack)
|
||||||
|
interpret(for_loop->for_loop.update, var_stack, enclosing_object, &inner_defer_stack)
|
||||||
|
interpret_from_defer_stack(&defer_stack, var_stack, enclosing_object)
|
||||||
}
|
}
|
||||||
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_code_block(block: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value): pair<value, control_flow> {
|
fun interpret_code_block(block: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
||||||
var_stack->push(map<string,value>())
|
var_stack->push(map<string,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)
|
var statement = interpret(block->code_block.children[i], var_stack, enclosing_object, &defer_stack)
|
||||||
match (statement.second) {
|
match (statement.second) {
|
||||||
control_flow::con() {
|
control_flow::con() {
|
||||||
|
interpret_from_defer_stack(&defer_stack, var_stack, enclosing_object)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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_return_statement(stmt: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value): pair<value, control_flow> {
|
fun interpret_from_defer_stack(defer_stack: *stack<*ast_node>, var_stack: *stack<map<string, value>>, enclosing_object: value) {
|
||||||
return make_pair(get_real_value(interpret(stmt->return_statement.return_value, var_stack, enclosing_object).first), control_flow::ret())
|
var new_defer_stack = stack<*ast_node>()
|
||||||
|
defer_stack->for_each_reverse(fun(i: *ast_node) {
|
||||||
|
interpret(i, var_stack, enclosing_object, &new_defer_stack)
|
||||||
|
})
|
||||||
|
if (new_defer_stack.size())
|
||||||
|
interpret_from_defer_stack(&new_defer_stack, var_stack, enclosing_object)
|
||||||
}
|
}
|
||||||
fun interpret_declaration_statement(stmt: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value): 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> {
|
||||||
var ident_type = stmt->declaration_statement.identifier->identifier.type
|
return make_pair(get_real_value(interpret(stmt->return_statement.return_value, var_stack, enclosing_object, defer_stack).first), control_flow::ret())
|
||||||
var ident_name = stmt->declaration_statement.identifier->identifier.name
|
}
|
||||||
|
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_type = ident->identifier.type
|
||||||
|
var ident_name = ident->identifier.name
|
||||||
var_stack->top()[ident_name] = value::variable(make_pair(malloc(type_size(ident_type)),ident_type))
|
var_stack->top()[ident_name] = value::variable(make_pair(malloc(type_size(ident_type)),ident_type))
|
||||||
if (stmt->declaration_statement.expression)
|
if (stmt->declaration_statement.expression) {
|
||||||
store_into_variable(var_stack->top()[ident_name], get_real_value(interpret(stmt->declaration_statement.expression, var_stack, enclosing_object).first))
|
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, defer_stack)
|
||||||
|
else
|
||||||
|
store_into_variable(var_stack->top()[ident_name], get_real_value(interpret(stmt->declaration_statement.expression, var_stack, enclosing_object, defer_stack).first))
|
||||||
|
} else if (stmt->declaration_statement.init_method_call) {
|
||||||
|
interpret(stmt->declaration_statement.init_method_call, var_stack, enclosing_object, defer_stack)
|
||||||
|
}
|
||||||
|
// defering destructs
|
||||||
|
if (ident_type->indirection == 0 && (ident_type->is_adt() || (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<string, value>>, enclosing_object: value): pair<value, control_flow> {
|
fun interpret_assignment_statement(stmt: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
||||||
var to = interpret(stmt->assignment_statement.to, var_stack, enclosing_object).first
|
var to = interpret(stmt->assignment_statement.to, var_stack, enclosing_object, defer_stack).first
|
||||||
var from = interpret(stmt->assignment_statement.from, var_stack, enclosing_object).first
|
var from = interpret(stmt->assignment_statement.from, var_stack, enclosing_object, defer_stack).first
|
||||||
assert(is_variable(to), "assigning into not a variable")
|
assert(is_variable(to), "assigning into not a variable")
|
||||||
// first, we have to see if this is an object
|
// first, we have to see if this is an object
|
||||||
// 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)
|
||||||
store_into_variable(to, cast_value(get_real_value(from), to.variable.second))
|
store_into_variable(to, cast_value(get_real_value(from), 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<string, value>>, enclosing_object: value, 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<string, value>>, enclosing_object: value): pair<value, control_flow> {
|
fun interpret_identifier(ident: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value): 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->identifier.name))
|
if (var_stack->from_top(i).contains_key(ident->identifier.name))
|
||||||
return make_pair(var_stack->from_top(i)[ident->identifier.name], control_flow::nor())
|
return make_pair(var_stack->from_top(i)[ident->identifier.name], control_flow::nor())
|
||||||
// check for object member
|
// check for object member / this
|
||||||
if (is_object_like(enclosing_object)) {
|
if (is_object_like(enclosing_object)) {
|
||||||
|
if (ident->identifier.name == "this")
|
||||||
|
return make_pair(value::pointer(make_pair(enclosing_object.object_like.first, enclosing_object.object_like.second->clone_with_increased_indirection())), control_flow::nor())
|
||||||
var object_def = enclosing_object.object_like.second->type_def
|
var object_def = enclosing_object.object_like.second->type_def
|
||||||
for (var i = 0; i < object_def->type_def.variables.size; i++;) {
|
for (var i = 0; i < object_def->type_def.variables.size; i++;) {
|
||||||
if (object_def->type_def.variables[i]->declaration_statement.identifier == ident) {
|
if (object_def->type_def.variables[i]->declaration_statement.identifier == ident) {
|
||||||
@@ -685,8 +729,8 @@ obj interpreter (Object) {
|
|||||||
}
|
}
|
||||||
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<string, value>>, enclosing_object: value): pair<value, control_flow> {
|
fun interpret_cast(node: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
||||||
return make_pair(cast_value(interpret(node->cast.value, var_stack, enclosing_object).first, node->cast.to_type), control_flow::nor())
|
return make_pair(cast_value(interpret(node->cast.value, var_stack, enclosing_object, defer_stack).first, node->cast.to_type), control_flow::nor())
|
||||||
}
|
}
|
||||||
fun interpret_compiler_intrinsic(node: *ast_node, var_stack: *stack<map<string, value>>): pair<value, control_flow> {
|
fun interpret_compiler_intrinsic(node: *ast_node, var_stack: *stack<map<string, value>>): pair<value, control_flow> {
|
||||||
var intrinsic_name = node->compiler_intrinsic.intrinsic
|
var intrinsic_name = node->compiler_intrinsic.intrinsic
|
||||||
@@ -696,19 +740,20 @@ 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<string, value>>, enclosing_object: value): pair<value, control_flow> {
|
fun interpret(node: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
||||||
match (*node) {
|
match (*node) {
|
||||||
ast_node::function_call(backing) return interpret_function_call(node, var_stack, enclosing_object)
|
ast_node::function_call(backing) return interpret_function_call(node, var_stack, enclosing_object, defer_stack)
|
||||||
ast_node::statement(backing) return interpret_statement(node, var_stack, enclosing_object)
|
ast_node::statement(backing) return interpret_statement(node, var_stack, enclosing_object, defer_stack)
|
||||||
ast_node::if_statement(backing) return interpret_if_statement(node, var_stack, enclosing_object)
|
ast_node::if_statement(backing) return interpret_if_statement(node, var_stack, enclosing_object, defer_stack)
|
||||||
ast_node::while_loop(backing) return interpret_while_loop(node, var_stack, enclosing_object)
|
ast_node::while_loop(backing) return interpret_while_loop(node, var_stack, enclosing_object, defer_stack)
|
||||||
ast_node::for_loop(backing) return interpret_for_loop(node, var_stack, enclosing_object)
|
ast_node::for_loop(backing) return interpret_for_loop(node, var_stack, enclosing_object)
|
||||||
ast_node::code_block(backing) return interpret_code_block(node, var_stack, enclosing_object)
|
ast_node::code_block(backing) return interpret_code_block(node, var_stack, enclosing_object, defer_stack)
|
||||||
ast_node::return_statement(backing) return interpret_return_statement(node, var_stack, enclosing_object)
|
ast_node::return_statement(backing) return interpret_return_statement(node, var_stack, enclosing_object, defer_stack)
|
||||||
ast_node::declaration_statement(backing) return interpret_declaration_statement(node, var_stack, enclosing_object)
|
ast_node::declaration_statement(backing) return interpret_declaration_statement(node, var_stack, enclosing_object, defer_stack)
|
||||||
ast_node::assignment_statement(backing) return interpret_assignment_statement(node, var_stack, enclosing_object)
|
ast_node::assignment_statement(backing) return interpret_assignment_statement(node, var_stack, enclosing_object, defer_stack)
|
||||||
|
ast_node::defer_statement(backing) return interpret_defer_statement(node, var_stack, enclosing_object, defer_stack)
|
||||||
ast_node::identifier(backing) return interpret_identifier(node, var_stack, enclosing_object)
|
ast_node::identifier(backing) return interpret_identifier(node, var_stack, enclosing_object)
|
||||||
ast_node::cast(backing) return interpret_cast(node, var_stack, enclosing_object)
|
ast_node::cast(backing) return interpret_cast(node, var_stack, enclosing_object, defer_stack)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -38,13 +38,14 @@ fun print(toPrint: bool): void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ext fun sprintf(to_str: *char, format: *char, d: double)
|
ext fun snprintf(to_str: *char, num: ulong, format: *char, d: double): int
|
||||||
fun print(toPrint: float)
|
fun print(toPrint: float)
|
||||||
print((toPrint) cast double)
|
print((toPrint) cast double)
|
||||||
|
|
||||||
fun print(toPrint: double) {
|
fun print(toPrint: double) {
|
||||||
var int_str = new<char>((#sizeof<double>) cast int)
|
var how_much = snprintf(null<char>(), (0) cast ulong, "%f", toPrint)
|
||||||
sprintf(int_str, "%f", toPrint)
|
var int_str = new<char>(how_much+2)
|
||||||
|
snprintf(int_str, (how_much+1) cast ulong, "%f", toPrint)
|
||||||
print(int_str)
|
print(int_str)
|
||||||
delete(int_str)
|
delete(int_str)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user