Interpreter up to 71/73 tests passing, the only ones that don't yet are the future ones. Struct size is still wrong though
This commit is contained in:
@@ -7,6 +7,8 @@ import util:*
|
|||||||
import tree:*
|
import tree:*
|
||||||
import symbol:*
|
import symbol:*
|
||||||
import ast_nodes:*
|
import ast_nodes:*
|
||||||
|
// for error with syntax tree
|
||||||
|
import ast_transformation:*
|
||||||
import poset:*
|
import poset:*
|
||||||
|
|
||||||
fun code_triple(): code_triple return code_triple(string(), string(), string());
|
fun code_triple(): code_triple return code_triple(string(), string(), string());
|
||||||
@@ -464,6 +466,9 @@ obj c_generator (Object) {
|
|||||||
var function_return_type = get_ast_type(enclosing_func)->return_type
|
var function_return_type = get_ast_type(enclosing_func)->return_type
|
||||||
var to_ret = code_triple()
|
var to_ret = code_triple()
|
||||||
|
|
||||||
|
if (!function_return_type->is_void() && !function_return_type->equality(get_ast_type(return_value), false))
|
||||||
|
error(ast_to_syntax[node], "return value type does not match function return type")
|
||||||
|
|
||||||
to_ret += "return"
|
to_ret += "return"
|
||||||
var refamp = string()
|
var refamp = string()
|
||||||
if (function_return_type->is_ref)
|
if (function_return_type->is_ref)
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ fun wrap_value(val: *ast_node): value {
|
|||||||
} else if (value_str[i] == '\\' && value_str[i+1] == 't') {
|
} else if (value_str[i] == '\\' && value_str[i+1] == 't') {
|
||||||
to_ret += '\t'
|
to_ret += '\t'
|
||||||
i++
|
i++
|
||||||
|
} else if (value_str[i] == '\\' && value_str[i+1] == '\\') {
|
||||||
|
to_ret += '\\'
|
||||||
|
i++
|
||||||
} else if (i == value_str.length()-2) {
|
} else if (i == value_str.length()-2) {
|
||||||
to_ret += value_str[i]
|
to_ret += value_str[i]
|
||||||
to_ret += value_str[i+1]
|
to_ret += value_str[i+1]
|
||||||
@@ -189,6 +192,15 @@ fun do_basic_op(func_name: string, a: value, b: value): value {
|
|||||||
value::floating(av) return do_basic_floating_op_second_half(func_name, av, b, null<type>())
|
value::floating(av) return do_basic_floating_op_second_half(func_name, av, b, null<type>())
|
||||||
value::double_precision(av) return do_basic_floating_op_second_half(func_name, av, b, null<type>())
|
value::double_precision(av) return do_basic_floating_op_second_half(func_name, av, b, null<type>())
|
||||||
value::pointer(av) {
|
value::pointer(av) {
|
||||||
|
var real_b = get_real_value(b)
|
||||||
|
if (func_name == "==") {
|
||||||
|
if (!is_pointer(real_b)) {
|
||||||
|
print("equality between pointer and not pointer: ")
|
||||||
|
print_value(real_b)
|
||||||
|
error(":/")
|
||||||
|
}
|
||||||
|
return value::boolean(av.first == real_b.pointer.first)
|
||||||
|
}
|
||||||
var inc_in_bytes = cast_value(b, type_ptr(base_type::ulong_int())).ulong_int * type_size(av.second->clone_with_decreased_indirection())
|
var inc_in_bytes = cast_value(b, type_ptr(base_type::ulong_int())).ulong_int * type_size(av.second->clone_with_decreased_indirection())
|
||||||
var ptr = null<void>()
|
var ptr = null<void>()
|
||||||
if (func_name == "+") {
|
if (func_name == "+") {
|
||||||
@@ -196,7 +208,9 @@ fun do_basic_op(func_name: string, a: value, b: value): value {
|
|||||||
} else if (func_name == "-") {
|
} else if (func_name == "-") {
|
||||||
ptr = ((av.first) cast *char - inc_in_bytes) cast *void
|
ptr = ((av.first) cast *char - inc_in_bytes) cast *void
|
||||||
} else {
|
} else {
|
||||||
error("pointer arithmatic is not + or -")
|
println(string("pointer arithmatic is not + or -: ") + func_name + ", b is: ")
|
||||||
|
print_value(b)
|
||||||
|
error(string("pointer arithmatic is not + or -: ") + func_name)
|
||||||
}
|
}
|
||||||
return value::pointer(make_pair(ptr, av.second))
|
return value::pointer(make_pair(ptr, av.second))
|
||||||
}
|
}
|
||||||
@@ -486,9 +500,9 @@ fun type_size(t: *type): ulong {
|
|||||||
error(string("Invalid type for type_size: ") + t->to_string())
|
error(string("Invalid type for type_size: ") + t->to_string())
|
||||||
}
|
}
|
||||||
fun offset_into_struct(struct_type: *type, ident: *ast_node): ulong {
|
fun offset_into_struct(struct_type: *type, ident: *ast_node): ulong {
|
||||||
if (struct_type->type_def->type_def.is_union)
|
|
||||||
return 0
|
|
||||||
var size: ulong = 0
|
var size: ulong = 0
|
||||||
|
if (struct_type->type_def->type_def.is_union)
|
||||||
|
return size
|
||||||
for (var i = 0; i < struct_type->type_def->type_def.variables.size; i++;)
|
for (var i = 0; i < struct_type->type_def->type_def.variables.size; i++;)
|
||||||
if (struct_type->type_def->type_def.variables[i]->declaration_statement.identifier == ident)
|
if (struct_type->type_def->type_def.variables[i]->declaration_statement.identifier == ident)
|
||||||
break
|
break
|
||||||
@@ -496,6 +510,8 @@ fun offset_into_struct(struct_type: *type, ident: *ast_node): ulong {
|
|||||||
size += type_size(struct_type->type_def->type_def.variables[i]->declaration_statement.identifier->identifier.type)
|
size += type_size(struct_type->type_def->type_def.variables[i]->declaration_statement.identifier->identifier.type)
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
fun dereference_pointer_into_variable(dereference_val: value): value
|
||||||
|
return value::variable(make_pair(get_real_value(dereference_val).pointer.first, dereference_val.pointer.second->clone_with_decreased_indirection()))
|
||||||
fun pop_and_free(var_stack: *stack<map<*ast_node, value>>) {
|
fun pop_and_free(var_stack: *stack<map<*ast_node, value>>) {
|
||||||
var_stack->pop().for_each(fun(k: *ast_node, v: value) {
|
var_stack->pop().for_each(fun(k: *ast_node, v: value) {
|
||||||
match(v) {
|
match(v) {
|
||||||
@@ -595,6 +611,12 @@ obj interpreter (Object) {
|
|||||||
var func_value = get_real_value(interpret(func_call_func, var_stack, enclosing_object, enclosing_func).first)
|
var func_value = get_real_value(interpret(func_call_func, var_stack, enclosing_object, enclosing_func).first)
|
||||||
func_call_func = func_value.function.first
|
func_call_func = func_value.function.first
|
||||||
possible_closure_map = *func_value.function.second
|
possible_closure_map = *func_value.function.second
|
||||||
|
// if the closure closes over this, put it as the enclosing object inside the closure
|
||||||
|
possible_closure_map.for_each(fun(key: *ast_node, v: value) {
|
||||||
|
if (key->identifier.name == "this") {
|
||||||
|
new_enclosing_object = get_real_value(dereference_pointer_into_variable(v))
|
||||||
|
}
|
||||||
|
})
|
||||||
/*println("possible_closure_map is")*/
|
/*println("possible_closure_map is")*/
|
||||||
/*possible_closure_map.for_each(fun(key: *ast_node, v: value) print(get_ast_name(key) + " ");)*/
|
/*possible_closure_map.for_each(fun(key: *ast_node, v: value) print(get_ast_name(key) + " ");)*/
|
||||||
/*println()*/
|
/*println()*/
|
||||||
@@ -674,7 +696,7 @@ obj interpreter (Object) {
|
|||||||
dereference_val = do_basic_op(string("+"), parameters[0], parameters[1])
|
dereference_val = do_basic_op(string("+"), parameters[0], parameters[1])
|
||||||
if (!is_pointer(get_real_value(parameters[0])))
|
if (!is_pointer(get_real_value(parameters[0])))
|
||||||
error("Trying to take dereference not a pointer")
|
error("Trying to take dereference not a pointer")
|
||||||
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(dereference_pointer_into_variable(dereference_val), 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 == "memmove" || 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")
|
if (func_name == "printf" || func_name == "malloc" || func_name == "free" || func_name == "memmove" || 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")
|
||||||
@@ -981,12 +1003,22 @@ obj interpreter (Object) {
|
|||||||
// check for global
|
// check for global
|
||||||
if (globals.contains_key(ident))
|
if (globals.contains_key(ident))
|
||||||
return make_pair(globals[ident], control_flow::nor())
|
return make_pair(globals[ident], control_flow::nor())
|
||||||
println("couldn't find it in interpret identifier")
|
println("couldn't find it in interpret identifier, scope:")
|
||||||
for (var i = 0; i < var_stack->size(); i++;) {
|
for (var i = 0; i < var_stack->size(); i++;) {
|
||||||
println(string("level: ") + i)
|
println(string("level: ") + i)
|
||||||
var_stack->from_top(i).for_each(fun(key: *ast_node, v: value) print(get_ast_name(key) + " ");)
|
var_stack->from_top(i).for_each(fun(key: *ast_node, v: value) print(get_ast_name(key) + " ");)
|
||||||
println()
|
println()
|
||||||
}
|
}
|
||||||
|
if (is_object_like(enclosing_object)) {
|
||||||
|
println("object scope:")
|
||||||
|
var object_def = enclosing_object.object_like.second->type_def
|
||||||
|
for (var i = 0; i < object_def->type_def.variables.size; i++;) {
|
||||||
|
print(get_ast_name(object_def->type_def.variables[i]) + " ")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print("no object scope: ")
|
||||||
|
print_value(enclosing_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<*ast_node, value>>, enclosing_object: value, enclosing_func: *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> {
|
||||||
|
|||||||
@@ -170,7 +170,12 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
|||||||
return;
|
return;
|
||||||
if (!ident_type->is_ref && ident_type->indirection == 0 && ident_type->is_object()) {
|
if (!ident_type->is_ref && ident_type->indirection == 0 && ident_type->is_object()) {
|
||||||
if (backing.expression && has_method(ident_type->type_def, "copy_construct", vector(get_ast_type(backing.expression)->clone_with_increased_indirection()))) {
|
if (backing.expression && has_method(ident_type->type_def, "copy_construct", vector(get_ast_type(backing.expression)->clone_with_increased_indirection()))) {
|
||||||
add_after_in(ast_statement_ptr(make_method_call(backing.identifier, "copy_construct", vector(make_operator_call("&", vector(backing.expression))))),
|
var temp_cpy_ctst = ast_identifier_ptr("temp_declaration_copy_construct", get_ast_type(backing.expression)->clone_without_ref(), null<ast_node>())
|
||||||
|
var declaration = ast_statement_ptr(ast_declaration_statement_ptr(temp_cpy_ctst, backing.expression, false))
|
||||||
|
add_after_in(ast_statement_ptr(make_method_call(backing.identifier, "copy_construct", vector(make_operator_call("&", vector(temp_cpy_ctst))))),
|
||||||
|
parent_chain->top(), parent_chain->from_top(1))
|
||||||
|
// do second so the order's right
|
||||||
|
add_after_in(declaration,
|
||||||
parent_chain->top(), parent_chain->from_top(1))
|
parent_chain->top(), parent_chain->from_top(1))
|
||||||
backing.expression = null<ast_node>()
|
backing.expression = null<ast_node>()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import io
|
import io
|
||||||
import string
|
import string
|
||||||
import ast_transformation
|
import util
|
||||||
import vector
|
import vector
|
||||||
import string
|
import string
|
||||||
import mem
|
import mem
|
||||||
@@ -151,7 +151,7 @@ obj regex (Object, Serializable) {
|
|||||||
var perenEnd = i + 1
|
var perenEnd = i + 1
|
||||||
for (var depth = 1; depth > 0; perenEnd++;) {
|
for (var depth = 1; depth > 0; perenEnd++;) {
|
||||||
if (perenEnd >= regex_string.length())
|
if (perenEnd >= regex_string.length())
|
||||||
ast_transformation::error(string::string("can't find matching peren in: ") + regex_string)
|
util::error(string::string("can't find matching peren in: ") + regex_string)
|
||||||
// be careful, this isn't quite right yet
|
// be careful, this isn't quite right yet
|
||||||
/*var not_non_special = perenEnd == 0 || (regex_string[perenEnd-1] != '\\' && regex_string[perenEnd-1] != '[' && (perenEnd+1 >= regex_string.length() || regex_string[perenEnd+1] != ']'))*/
|
/*var not_non_special = perenEnd == 0 || (regex_string[perenEnd-1] != '\\' && regex_string[perenEnd-1] != '[' && (perenEnd+1 >= regex_string.length() || regex_string[perenEnd+1] != ']'))*/
|
||||||
var not_non_special = perenEnd == 0 || (regex_string[perenEnd-1] != '[' && (perenEnd+1 >= regex_string.length() || regex_string[perenEnd+1] != ']'))
|
var not_non_special = perenEnd == 0 || (regex_string[perenEnd-1] != '[' && (perenEnd+1 >= regex_string.length() || regex_string[perenEnd+1] != ']'))
|
||||||
|
|||||||
@@ -41,18 +41,18 @@ fun min<T>(a: T, b: T): T {
|
|||||||
|
|
||||||
fun hash<T(Hashable)>(item: T): ulong return item.hash()
|
fun hash<T(Hashable)>(item: T): ulong return item.hash()
|
||||||
fun hash<T>(item: *T): ulong return (item) cast ulong
|
fun hash<T>(item: *T): ulong return (item) cast ulong
|
||||||
fun hash(item: char): ulong return item
|
fun hash(item: char): ulong return (item) cast ulong
|
||||||
fun hash(item: uchar): ulong return item
|
fun hash(item: uchar): ulong return (item) cast ulong
|
||||||
fun hash(item: short): ulong return item
|
fun hash(item: short): ulong return (item) cast ulong
|
||||||
fun hash(item: ushort): ulong return item
|
fun hash(item: ushort): ulong return (item) cast ulong
|
||||||
fun hash(item: int): ulong return item
|
fun hash(item: int): ulong return (item) cast ulong
|
||||||
fun hash(item: uint): ulong return item
|
fun hash(item: uint): ulong return (item) cast ulong
|
||||||
fun hash(item: long): ulong return item
|
fun hash(item: long): ulong return (item) cast ulong
|
||||||
fun hash(item: ulong): ulong return item
|
fun hash(item: ulong): ulong return (item) cast ulong
|
||||||
// default hash
|
// default hash
|
||||||
fun hash<T>(item: T): ulong {
|
fun hash<T>(item: T): ulong {
|
||||||
io::println("using empty hash - please do not do!")
|
io::println("using empty hash - please do not do!")
|
||||||
return 0
|
return (0) cast ulong
|
||||||
}
|
}
|
||||||
|
|
||||||
fun make_pair<T,U>(first: T, second: U): pair<T,U> {
|
fun make_pair<T,U>(first: T, second: U): pair<T,U> {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
Test linear map:
|
||||||
3
|
3
|
||||||
2
|
2
|
||||||
1
|
1
|
||||||
@@ -10,6 +11,7 @@ Lookie, a map!
|
|||||||
What I get for not testing different types
|
What I get for not testing different types
|
||||||
key: 7, value: Lookie, a map!
|
key: 7, value: Lookie, a map!
|
||||||
key: 30, value: we'll look for for_each too
|
key: 30, value: we'll look for for_each too
|
||||||
|
Test hash map:
|
||||||
3
|
3
|
||||||
2
|
2
|
||||||
1
|
1
|
||||||
|
|||||||
@@ -24,9 +24,11 @@ fun test_map<T,V>(m: ref T, mapEx: ref V) {
|
|||||||
mapEx.for_each(fun(key:int, value:*char) { print("key: "); print(key); print(", value: "); println(value); })
|
mapEx.for_each(fun(key:int, value:*char) { print("key: "); print(key); print(", value: "); println(value); })
|
||||||
}
|
}
|
||||||
fun main(): int {
|
fun main(): int {
|
||||||
|
println("Test linear map:")
|
||||||
var m1 = map(3,1)
|
var m1 = map(3,1)
|
||||||
var mapEx1 = map(7, "Lookie, a map!")
|
var mapEx1 = map(7, "Lookie, a map!")
|
||||||
test_map(m1, mapEx1)
|
test_map(m1, mapEx1)
|
||||||
|
println("Test hash map:")
|
||||||
var m2 = hash_map(3,1)
|
var m2 = hash_map(3,1)
|
||||||
var mapEx2 = hash_map(7, "Lookie, a map!")
|
var mapEx2 = hash_map(7, "Lookie, a map!")
|
||||||
test_map(m2, mapEx2)
|
test_map(m2, mapEx2)
|
||||||
|
|||||||
Reference in New Issue
Block a user