Some fixes and added in globals
This commit is contained in:
1 parent
593877eb84
commit
cf8656a538
8 files changed
+71
-102
No files matched your search
+64
-3
@@ -68,7 +68,7 @@ fun wrap_value(val: *ast_node): value {
|
|||||||
if (value_str[0] == '"') { // " // Comment hack for emacs now
|
if (value_str[0] == '"') { // " // Comment hack for emacs now
|
||||||
var to_ret = string()
|
var to_ret = string()
|
||||||
// triple quoted strings
|
// triple quoted strings
|
||||||
if (value_str[1] == '"' && value_str[2] == '"')
|
if (value_str[1] == '"' && value_str.length() > 2 && value_str[2] == '"')
|
||||||
value_str = value_str.slice(3,-4)
|
value_str = value_str.slice(3,-4)
|
||||||
else
|
else
|
||||||
value_str = value_str.slice(1,-2)
|
value_str = value_str.slice(1,-2)
|
||||||
@@ -483,11 +483,13 @@ fun pop_and_free(var_stack: *stack<map<string, value>>) {
|
|||||||
obj interpreter (Object) {
|
obj interpreter (Object) {
|
||||||
var ast_to_syntax: map<*ast_node, *tree<symbol>>
|
var ast_to_syntax: map<*ast_node, *tree<symbol>>
|
||||||
var name_ast_map: map<string, pair<*tree<symbol>,*ast_node>>
|
var name_ast_map: map<string, pair<*tree<symbol>,*ast_node>>
|
||||||
|
var globals: map<*ast_node, value>
|
||||||
var id_counter: int
|
var id_counter: int
|
||||||
fun get_id(): string return to_string(id_counter++);
|
fun get_id(): string return to_string(id_counter++);
|
||||||
fun construct(name_ast_map_in: map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax_in: map<*ast_node, *tree<symbol>>): *interpreter {
|
fun construct(name_ast_map_in: map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax_in: map<*ast_node, *tree<symbol>>): *interpreter {
|
||||||
name_ast_map.copy_construct(&name_ast_map_in)
|
name_ast_map.copy_construct(&name_ast_map_in)
|
||||||
ast_to_syntax.copy_construct(&ast_to_syntax_in)
|
ast_to_syntax.copy_construct(&ast_to_syntax_in)
|
||||||
|
globals.construct()
|
||||||
id_counter = 0
|
id_counter = 0
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@@ -498,11 +500,13 @@ obj interpreter (Object) {
|
|||||||
fun copy_construct(old: *interpreter) {
|
fun copy_construct(old: *interpreter) {
|
||||||
name_ast_map.copy_construct(&old->name_ast_map)
|
name_ast_map.copy_construct(&old->name_ast_map)
|
||||||
ast_to_syntax.copy_construct(&old->ast_to_syntax)
|
ast_to_syntax.copy_construct(&old->ast_to_syntax)
|
||||||
|
globals.copy_construct(&old->globals)
|
||||||
id_counter == old->id_counter
|
id_counter == old->id_counter
|
||||||
}
|
}
|
||||||
fun destruct() {
|
fun destruct() {
|
||||||
name_ast_map.destruct()
|
name_ast_map.destruct()
|
||||||
ast_to_syntax.destruct()
|
ast_to_syntax.destruct()
|
||||||
|
globals.destruct()
|
||||||
}
|
}
|
||||||
fun call_main() {
|
fun call_main() {
|
||||||
var results = vector<*ast_node>()
|
var results = vector<*ast_node>()
|
||||||
@@ -512,6 +516,10 @@ obj interpreter (Object) {
|
|||||||
if (results.size != 1)
|
if (results.size != 1)
|
||||||
error(string("wrong number of mains to call: ") + results.size)
|
error(string("wrong number of mains to call: ") + results.size)
|
||||||
printlnerr("=============")
|
printlnerr("=============")
|
||||||
|
printlnerr("setting up globals!")
|
||||||
|
printlnerr("=============")
|
||||||
|
setup_globals();
|
||||||
|
printlnerr("=============")
|
||||||
printlnerr("calling main!")
|
printlnerr("calling main!")
|
||||||
printlnerr("=============")
|
printlnerr("=============")
|
||||||
var var_stack = stack<map<string, value>>()
|
var var_stack = stack<map<string, value>>()
|
||||||
@@ -525,6 +533,30 @@ obj interpreter (Object) {
|
|||||||
interpret_from_defer_stack(&defer_stack, &var_stack, value::void_nothing(), null<ast_node>())
|
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() {
|
||||||
|
name_ast_map.for_each(fun(key: string, value: pair<*tree<symbol>,*ast_node>) {
|
||||||
|
value.second->translation_unit.children.for_each(fun(child: *ast_node) {
|
||||||
|
if (is_declaration_statement(child)) {
|
||||||
|
var declaration = child->declaration_statement
|
||||||
|
var identifier = declaration.identifier->identifier
|
||||||
|
if (declaration.is_extern) {
|
||||||
|
if (identifier.name == "stderr") {
|
||||||
|
var stderr_type = type_ptr(base_type::void_return(), 1)
|
||||||
|
var stderr_pointer = malloc(type_size(stderr_type))
|
||||||
|
*(stderr_pointer) cast **void = stderr;
|
||||||
|
globals[declaration.identifier] = value::variable(make_pair(stderr_pointer, stderr_type))
|
||||||
|
} else {
|
||||||
|
error(string("unknown extern: ") + identifier.name)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
globals[declaration.identifier] = value::variable(make_pair(calloc(type_size(identifier.type)), identifier.type))
|
||||||
|
if (declaration.expression)
|
||||||
|
store_into_variable(globals[declaration.identifier], get_real_value(interpret(declaration.expression, null<stack<map<string,value>>>(), value::void_nothing(), null<ast_node>(), null<stack<*ast_node>>()).first))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
fun interpret_function_call(func_call: *ast_node, var_stack: *stack<map<string, 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<string, value>>, enclosing_object: value, enclosing_func: *ast_node, 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
|
||||||
@@ -605,7 +637,7 @@ obj interpreter (Object) {
|
|||||||
return make_pair(value::variable(make_pair(get_real_value(dereference_val).pointer.first, dereference_val.pointer.second->clone_with_decreased_indirection())), control_flow::nor())
|
return make_pair(value::variable(make_pair(get_real_value(dereference_val).pointer.first, dereference_val.pointer.second->clone_with_decreased_indirection())), control_flow::nor())
|
||||||
}
|
}
|
||||||
// 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 == "snprintf" || func_name == "atan" || func_name == "atan2" || func_name == "acos" || func_name == "asin" || func_name == "tan" || func_name == "cos" || func_name == "sin")
|
if (func_name == "printf" || func_name == "malloc" || func_name == "free" || func_name == "fflush" || func_name == "snprintf" || func_name == "fopen" || func_name == "fclose" || func_name == "ftell" || func_name == "fseek" || func_name == "fread" || func_name == "fwrite" || func_name == "atan" || func_name == "atan2" || func_name == "acos" || func_name == "asin" || func_name == "tan" || func_name == "cos" || func_name == "sin")
|
||||||
return make_pair(call_built_in_extern(func_name, parameters), control_flow::nor())
|
return make_pair(call_built_in_extern(func_name, parameters), control_flow::nor())
|
||||||
if (!func_call_func->function.body_statement)
|
if (!func_call_func->function.body_statement)
|
||||||
error(string("trying to call unsupported extern function: ") + func_name)
|
error(string("trying to call unsupported extern function: ") + func_name)
|
||||||
@@ -714,6 +746,24 @@ obj interpreter (Object) {
|
|||||||
} else if (func_name == "snprintf") {
|
} else if (func_name == "snprintf") {
|
||||||
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")
|
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")
|
||||||
return value::integer(snprintf((parameters[0].pointer.first) cast *char, parameters[1].ulong_int, (parameters[2].pointer.first) cast *char, parameters[3].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 == "fopen") {
|
||||||
|
assert(parameters.size == 2 && is_pointer(parameters[0]) && is_pointer(parameters[1]), "Calling fopen with wrong params")
|
||||||
|
return value::pointer(make_pair(fopen((parameters[0].pointer.first) cast *char, (parameters[1].pointer.first) cast *char), type_ptr(base_type::void_return(), 1)))
|
||||||
|
} else if (func_name == "fclose") {
|
||||||
|
assert(parameters.size == 1 && is_pointer(parameters[0]), "Calling fclose with wrong params")
|
||||||
|
return value::integer(fclose((parameters[0].pointer.first) cast *void))
|
||||||
|
} else if (func_name == "ftell") {
|
||||||
|
assert(parameters.size == 1 && is_pointer(parameters[0]), "Calling ftell with wrong params")
|
||||||
|
return value::long_int(ftell((parameters[0].pointer.first) cast *void))
|
||||||
|
} else if (func_name == "fseek") {
|
||||||
|
assert(parameters.size == 3 && is_pointer(parameters[0]) && is_long_int(parameters[1]) && is_integer(parameters[2]), "Calling fseek with wrong params")
|
||||||
|
return value::integer(fseek((parameters[0].pointer.first) cast *void, parameters[1].long_int, parameters[2].integer))
|
||||||
|
} else if (func_name == "fread") {
|
||||||
|
assert(parameters.size == 4 && is_pointer(parameters[0]) && is_ulong_int(parameters[1]) && is_ulong_int(parameters[2]) && is_pointer(parameters[3]), "Calling fread with wrong params")
|
||||||
|
return value::ulong_int(fread((parameters[0].pointer.first) cast *void, parameters[1].ulong_int, parameters[2].ulong_int, parameters[3].pointer.first))
|
||||||
|
} else if (func_name == "fwrite") {
|
||||||
|
assert(parameters.size == 4 && is_pointer(parameters[0]) && is_ulong_int(parameters[1]) && is_ulong_int(parameters[2]) && is_pointer(parameters[3]), "Calling fwrite with wrong params")
|
||||||
|
return value::ulong_int(fwrite((parameters[0].pointer.first) cast *void, parameters[1].ulong_int, parameters[2].ulong_int, parameters[3].pointer.first))
|
||||||
} 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)
|
||||||
@@ -783,7 +833,7 @@ obj interpreter (Object) {
|
|||||||
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)
|
interpret(for_loop->for_loop.init, var_stack, enclosing_object, enclosing_func, &defer_stack)
|
||||||
while (truthy(interpret(for_loop->for_loop.condition, var_stack, enclosing_object, enclosing_func, &defer_stack).first)) {
|
while (going && truthy(interpret(for_loop->for_loop.condition, var_stack, enclosing_object, enclosing_func, &defer_stack).first)) {
|
||||||
value_from_inside = interpret(for_loop->for_loop.body, var_stack, enclosing_object, enclosing_func, &defer_stack)
|
value_from_inside = interpret(for_loop->for_loop.body, var_stack, enclosing_object, enclosing_func, &defer_stack)
|
||||||
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
|
||||||
@@ -800,6 +850,13 @@ obj interpreter (Object) {
|
|||||||
pop_and_free(var_stack)
|
pop_and_free(var_stack)
|
||||||
return value_from_inside
|
return value_from_inside
|
||||||
}
|
}
|
||||||
|
fun interpret_branching_statement(bstatement: *ast_node): pair<value, control_flow> {
|
||||||
|
match (bstatement->branching_statement.b_type) {
|
||||||
|
branching_type::break_stmt() return make_pair(value::void_nothing(), control_flow::bre())
|
||||||
|
branching_type::continue_stmt() return make_pair(value::void_nothing(), control_flow::con())
|
||||||
|
}
|
||||||
|
error("bad branch type")
|
||||||
|
}
|
||||||
fun interpret_code_block(block: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value, enclosing_func: *ast_node, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
fun interpret_code_block(block: *ast_node, var_stack: *stack<map<string, value>>, enclosing_object: value, enclosing_func: *ast_node, 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>()
|
var defer_stack = stack<*ast_node>()
|
||||||
@@ -913,6 +970,9 @@ obj interpreter (Object) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// check for global
|
||||||
|
if (globals.contains_key(ident))
|
||||||
|
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<string, 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<string, value>>, enclosing_object: value, enclosing_func: *ast_node, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
||||||
@@ -933,6 +993,7 @@ obj interpreter (Object) {
|
|||||||
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, defer_stack)
|
||||||
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, defer_stack)
|
||||||
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::code_block(backing) return interpret_code_block(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
ast_node::code_block(backing) return interpret_code_block(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, defer_stack)
|
ast_node::return_statement(backing) return interpret_return_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, defer_stack)
|
ast_node::declaration_statement(backing) return interpret_declaration_statement(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
||||||
|
|||||||
@@ -3,6 +3,13 @@ ext fun malloc(size: ulong): *void
|
|||||||
ext fun free(size: *void)
|
ext fun free(size: *void)
|
||||||
ext fun memmove(dest: *void, src: *void, size: ulong): *void
|
ext fun memmove(dest: *void, src: *void, size: ulong): *void
|
||||||
|
|
||||||
|
fun calloc(size: ulong): *void {
|
||||||
|
var to_ret = malloc(size)
|
||||||
|
for (var i = 0; i < size; i++;)
|
||||||
|
*((to_ret) cast *char + i) = 0
|
||||||
|
return to_ret
|
||||||
|
}
|
||||||
|
|
||||||
fun null<T>(): *T
|
fun null<T>(): *T
|
||||||
return (0) cast *T
|
return (0) cast *T
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
same_file: 5
|
|
||||||
diff_file: 7
|
|
||||||
diff_file: 13
|
|
||||||
diff_file: 1337
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import c_passthrough_diff
|
|
||||||
|
|
||||||
|
|
||||||
__if_comp__ __C__ simple_passthrough """
|
|
||||||
#include <stdio.h>
|
|
||||||
int same = 5;
|
|
||||||
"""
|
|
||||||
|
|
||||||
fun main(): int {
|
|
||||||
|
|
||||||
__if_comp__ __C__ simple_passthrough """
|
|
||||||
printf("same_file: %d\n", same);
|
|
||||||
"""
|
|
||||||
|
|
||||||
c_passthrough_diff::print_it();
|
|
||||||
var i: int = 7;
|
|
||||||
var j: int = 6;
|
|
||||||
__if_comp__ __C__ simple_passthrough(i = i, j = j : j = j:) """
|
|
||||||
j = i + j;
|
|
||||||
"""
|
|
||||||
c_passthrough_diff::print_it(j)
|
|
||||||
|
|
||||||
// test new shorthand for same name assignments
|
|
||||||
var r: int = 1000;
|
|
||||||
var s: int = 337;
|
|
||||||
__if_comp__ __C__ simple_passthrough(r, s : s:) """
|
|
||||||
s = r + s;
|
|
||||||
"""
|
|
||||||
c_passthrough_diff::print_it(s)
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
yeah new syntax: 7, 6
|
|
||||||
yeah new syntax: 8, 8.000000
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
|
|
||||||
fun withParams(a: int, b: float) : void {
|
|
||||||
simple_passthrough(a = a, b = b::) """
|
|
||||||
printf("yeah new syntax: %d, %f\n", a, b);
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun main() : int {
|
|
||||||
var i: int = 7;
|
|
||||||
var j: int = 6;
|
|
||||||
simple_passthrough(i = i, j = j::) """
|
|
||||||
printf("yeah new syntax: %d, %d\n", i, j);
|
|
||||||
"""
|
|
||||||
var a: int = 8
|
|
||||||
var b: float = 8
|
|
||||||
withParams(a,b)
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
yeah new syntax: 7, 6
|
|
||||||
yeah new syntax: 6, 7
|
|
||||||
yeah new syntax: 7, 6
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
obj Swapper<T> {
|
|
||||||
fun doit(a: *T, b: *T) : void {
|
|
||||||
var temp: T = *a;
|
|
||||||
*a = *b;
|
|
||||||
*b = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun swap<T>(a: *T, b: *T) : void {
|
|
||||||
var temp: T = *a
|
|
||||||
*a = *b
|
|
||||||
*b = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
fun print2int(a: int, b: int) : void {
|
|
||||||
simple_passthrough(a = a, b = b::) """
|
|
||||||
printf("yeah new syntax: %d, %d\n", a, b);
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun main() : int {
|
|
||||||
var i: int = 7;
|
|
||||||
var j: int = 6;
|
|
||||||
print2int(i,j)
|
|
||||||
swap<int>(&i, &j)
|
|
||||||
print2int(i,j)
|
|
||||||
var it: Swapper<int>
|
|
||||||
it.doit(&i,&j);
|
|
||||||
print2int(i,j)
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Reference in new issue
Block a user