From c25fa2f6f39fd87d59d2a11f0b3cf44db4985db2 Mon Sep 17 00:00:00 2001 From: Victorious3 Date: Wed, 30 Nov 2022 10:36:15 +0100 Subject: [PATCH] Finish the test suite --- build.py | 6 +- src/compiler.pr | 4 +- src/debug.pr | 407 ++++----- src/errors.pr | 2 +- src/main.pr | 15 + src/parser.pr | 7 +- src/scope.pr | 5 +- src/test/main.pr | 18 - src/test/test_compiler.pr | 837 ------------------- src/test/test_ctfe.pr | 70 -- src/test/test_expr_eval.pr | 53 -- src/test/test_json.pr | 208 ----- src/test/test_lexer.pr | 291 ------- src/test/test_parser.pr | 761 ----------------- src/test/test_runtime.pr | 572 ------------- src/test/test_typechecking.pr | 711 ---------------- src/test/testsuite.pr | 374 --------- src/testrunner.pr | 2 +- src/toolchain.pr | 39 +- src/typechecking.pr | 4 + src/util.pr | 51 -- {src => std}/getopt.pr | 3 +- std/std.pr | 51 ++ test/common.pr | 61 +- {src/test => test/runtime}/module/a.pr | 0 {src/test => test/runtime}/module/b.pr | 0 test/runtime/test_imports | Bin 0 -> 251336 bytes test/runtime/test_imports.pr | 14 + test/runtime/test_reflection | Bin 0 -> 253816 bytes test/runtime/test_reflection.pr | 43 + test/runtime/test_vector | Bin 0 -> 261360 bytes {src/test => test/runtime}/test_vector.pr | 21 +- test/test_compiler.pr | 970 ++++++++++++++++++++++ test/test_ctfe.pr | 102 +++ {src/test => test}/test_getopt.pr | 44 +- test/test_json.pr | 1 + test/test_lexer.pr | 3 +- test/test_map.pr | 71 ++ test/test_parser.pr | 3 +- test/test_runtime.pr | 729 ++++++++++++++++ travis.py | 15 +- version | 2 +- 42 files changed, 2353 insertions(+), 4217 deletions(-) delete mode 100644 src/test/main.pr delete mode 100644 src/test/test_compiler.pr delete mode 100644 src/test/test_ctfe.pr delete mode 100644 src/test/test_expr_eval.pr delete mode 100644 src/test/test_json.pr delete mode 100644 src/test/test_lexer.pr delete mode 100644 src/test/test_parser.pr delete mode 100644 src/test/test_runtime.pr delete mode 100644 src/test/test_typechecking.pr delete mode 100644 src/test/testsuite.pr rename {src => std}/getopt.pr (99%) rename {src/test => test/runtime}/module/a.pr (100%) rename {src/test => test/runtime}/module/b.pr (100%) create mode 100644 test/runtime/test_imports create mode 100644 test/runtime/test_imports.pr create mode 100644 test/runtime/test_reflection create mode 100644 test/runtime/test_reflection.pr create mode 100644 test/runtime/test_vector rename {src/test => test/runtime}/test_vector.pr (78%) create mode 100644 test/test_compiler.pr create mode 100644 test/test_ctfe.pr rename {src/test => test}/test_getopt.pr (77%) create mode 100644 test/test_map.pr create mode 100644 test/test_runtime.pr diff --git a/build.py b/build.py index 7df8d87c..ac9337ad 100644 --- a/build.py +++ b/build.py @@ -32,7 +32,7 @@ def release(): build([]) print("Second compilation step") - subprocess.check_call([exe_file("bin/princess2"), "-d", "-Isrc", "--buildfolder=build", "--outfile", exe_file("bin/princess3"), "src/main.pr"]) + subprocess.check_call([exe_file("bin/princess2"), "--no-incremental", "-d", "-Isrc", "--buildfolder=build", "--outfile", exe_file("bin/princess3"), "src/main.pr"]) print("Creating archive") FOLDER.mkdir(exist_ok=True) @@ -74,7 +74,7 @@ def release(): shutil.rmtree(FOLDER) def testrunner(extra): - args = [exe_file("bin/princess"), "--outfile", exe_file("bin/testrunner"), "src/testrunner.pr"] + args = [exe_file("bin/princess"), "--no-incremental", "--outfile", exe_file("bin/testrunner"), "src/testrunner.pr"] if sys.platform == "win32": args += WIN_ARGS subprocess.check_call(args + extra) @@ -108,7 +108,7 @@ def download(): Path(archive).unlink() def build(extra): - args = [exe_file("bin/princess"), "-d", "-Isrc", "--buildfolder=build", "--outfile", exe_file("bin/princess2"), "src/main.pr"] + args = [exe_file("bin/princess"), "--no-incremental", "-d", "-Isrc", "--buildfolder=build", "--outfile", exe_file("bin/princess2"), "src/main.pr"] if sys.platform == "win32": args += WIN_ARGS subprocess.check_call(args + extra) diff --git a/src/compiler.pr b/src/compiler.pr index 99187f7f..02d70b51 100644 --- a/src/compiler.pr +++ b/src/compiler.pr @@ -8498,10 +8498,10 @@ export def compile(state: &State, is_main: bool, no_cleanup: bool = false) { var globals: &Value = null // Create compilation unit and file if toolchain::debug_sym { - var dirname = util::dirname(state.module.filename) + var dirname = dirname(state.module.filename) if length(dirname) == 0 { dirname = "." } let abspath = absolute_path(dirname) - let file = util::basename(state.module.filename) + let file = basename(state.module.filename) let dvalues1 = allocate_ref(DebugParam, 2) dvalues1[0] = { diff --git a/src/debug.pr b/src/debug.pr index 230301d2..889c4f59 100644 --- a/src/debug.pr +++ b/src/debug.pr @@ -8,100 +8,100 @@ import json import linux } -def bin_op_to_json(str: &string, node: &parser::Node) -> &Json { +def bin_op_to_json(str: &string, node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = str - res["left"] = node_to_json(node.value.bin_op.left) - res["right"] = node_to_json(node.value.bin_op.right) + res["left"] = node_to_json(node.value.bin_op.left, types) + res["right"] = node_to_json(node.value.bin_op.right, types) return res } -def un_op_to_json(str: &string, node: &parser::Node) -> &Json { +def un_op_to_json(str: &string, node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = str - res["expr"] = node_to_json(node.value.expr) + res["expr"] = node_to_json(node.value.expr, types) return res } -def node_vec_to_json(vec: &Vector(&parser::Node)) -> &Json { +def node_vec_to_json(vec: &Vector(&parser::Node), types: bool) -> &Json { if not vec { return json::make_null() } else { let res = json::make_array() for var i in 0..vector::length(vec) { - res.push(node_to_json(vec[i])) + res.push(node_to_json(vec[i], types)) } return res } } -def func_call_to_json(node: &parser::Node) -> &Json { +def func_call_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "FuncCall" - res["left"] = node_to_json(node.value.func_call.left) - res["args"] = node_vec_to_json(node.value.func_call.args) - res["kwargs"] = node_vec_to_json(node.value.func_call.kwargs) + res["left"] = node_to_json(node.value.func_call.left, types) + res["args"] = node_vec_to_json(node.value.func_call.args, types) + res["kwargs"] = node_vec_to_json(node.value.func_call.kwargs, types) return res } -def var_decl_to_json(node: &parser::Node) -> &Json { +def var_decl_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "VarDecl" res["share"] = to_string(node.value.var_decl.share) res["kw"] = to_string(node.value.var_decl.kw) - res["left"] = node_vec_to_json(node.value.var_decl.left) - res["right"] = node_vec_to_json(node.value.var_decl.right) + res["left"] = node_vec_to_json(node.value.var_decl.left, types) + res["right"] = node_vec_to_json(node.value.var_decl.right, types) return res } -def id_decl_to_json(node: &parser::Node) -> &Json { +def id_decl_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "IdDecl" - res["value"] = node_to_json(node.value.id_decl.value) - res["tpe"] = node_to_json(node.value.id_decl.tpe) + res["value"] = node_to_json(node.value.id_decl.value, types) + res["tpe"] = node_to_json(node.value.id_decl.tpe, types) return res } -def id_decl_struct_to_json(node: &parser::Node) -> &Json { +def id_decl_struct_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "IdDeclStruct" - res["ident"] = node_to_json(node.value.id_decl_struct.ident) - res["tpe"] = node_to_json(node.value.id_decl_struct.tpe) + res["ident"] = node_to_json(node.value.id_decl_struct.ident, types) + res["tpe"] = node_to_json(node.value.id_decl_struct.tpe, types) return res } -def id_decl_enum_to_json(node: &parser::Node) -> &Json { +def id_decl_enum_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "IdDeclEnum" - res["ident"] = node_to_json(node.value.id_decl_enum.ident) - res["value"] = node_to_json(node.value.id_decl_enum.value) + res["ident"] = node_to_json(node.value.id_decl_enum.ident, types) + res["value"] = node_to_json(node.value.id_decl_enum.value, types) return res } -def enum_to_json(node: &parser::Node) -> &Json { +def enum_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "Enum" - res["tpe"] = node_to_json(node.value.t_enum.tpe) - res["body"] = node_vec_to_json(node.value.t_enum.body) + res["tpe"] = node_to_json(node.value.t_enum.tpe, types) + res["body"] = node_vec_to_json(node.value.t_enum.body, types) return res } -def id_assign_to_json(node: &parser::Node) -> &Json { +def id_assign_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "IdAssign" - res["value"] = node_to_json(node.value.expr) + res["value"] = node_to_json(node.value.expr, types) return res } -def named_arg_to_json(node: &parser::Node) -> &Json { +def named_arg_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "NamedArg" - res["name"] = node_to_json(node.value.named_arg.name) - res["value"] = node_to_json(node.value.named_arg.value) + res["name"] = node_to_json(node.value.named_arg.name, types) + res["value"] = node_to_json(node.value.named_arg.value, types) return res } -def identifier_to_json(node: &parser::Node) -> &Json { +def identifier_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "Identifier" let path = json::make_array() @@ -110,215 +110,215 @@ def identifier_to_json(node: &parser::Node) -> &Json { } res["path"] = path res["prefixed"] = node.value.identifier.prefixed - res["args"] = node_vec_to_json(node.value.identifier.args) + res["args"] = node_vec_to_json(node.value.identifier.args, types) return res } -def function_t_to_json(node: &parser::Node) -> &Json { +def function_t_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "FunctionT" - res["args"] = node_vec_to_json(node.value.t_func.args) - res["ret"] = node_vec_to_json(node.value.t_func.ret) + res["args"] = node_vec_to_json(node.value.t_func.args, types) + res["ret"] = node_vec_to_json(node.value.t_func.ret, types) return res } -def ptrarray_to_json(str: &string, node: &parser::Node) -> &Json { +def ptrarray_to_json(str: &string, node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = str res["kw"] = to_string(node.value.t_parr.kw) - res["tpe"] = node_to_json(node.value.t_parr.tpe) + res["tpe"] = node_to_json(node.value.t_parr.tpe, types) return res } -def array_static_to_json(node: &parser::Node) -> &Json { +def array_static_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "ArrayStaticT" - res["n"] = node_to_json(node.value.t_arrs.n) + res["n"] = node_to_json(node.value.t_arrs.n, types) res["kw"] = to_string(node.value.t_arrs.kw) - res["tpe"] = node_to_json(node.value.t_arrs.tpe) + res["tpe"] = node_to_json(node.value.t_arrs.tpe, types) return res } -def assign_to_json(node: &parser::Node) -> &Json { +def assign_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "Assign" - res["left"] = node_vec_to_json(node.value.assign.left) - res["right"] = node_vec_to_json(node.value.assign.right) + res["left"] = node_vec_to_json(node.value.assign.left, types) + res["right"] = node_vec_to_json(node.value.assign.right, types) return res } -def unsigned_to_json(node: &parser::Node) -> &Json { +def unsigned_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "Unsigned" - res["expr"] = node_to_json(node.value.expr) + res["expr"] = node_to_json(node.value.expr, types) return res } -def switch_to_json(node: &parser::Node) -> &Json { +def switch_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "Switch" - res["expr"] = node_to_json(node.value.switch_.expr) - res["body"] = node_vec_to_json(node.value.switch_.body) + res["expr"] = node_to_json(node.value.switch_.expr, types) + res["body"] = node_vec_to_json(node.value.switch_.body, types) return res } -def case_to_json(node: &parser::Node) -> &Json { +def case_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "Case" - res["expr"] = node_vec_to_json(node.value.case_.expr) - res["body"] = node_vec_to_json(node.value.case_.body) + res["expr"] = node_vec_to_json(node.value.case_.expr, types) + res["body"] = node_vec_to_json(node.value.case_.body, types) return res } -def if_expr_to_json(node: &parser::Node) -> &Json { +def if_expr_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "IfExpr" - res["cond"] = node_to_json(node.value.if_expr.cond) - res["if_true"] = node_to_json(node.value.if_expr.if_true) - res["if_false"] = node_to_json(node.value.if_expr.if_false) + res["cond"] = node_to_json(node.value.if_expr.cond, types) + res["if_true"] = node_to_json(node.value.if_expr.if_true, types) + res["if_false"] = node_to_json(node.value.if_expr.if_false, types) return res } -def if_to_json(node: &parser::Node, static_if: bool) -> &Json { +def if_to_json(node: &parser::Node, static_if: bool, types: bool) -> &Json { let res = json::make_object() if static_if { res["kind"] = "StaticIf" } else { res["kind"] = "If" } - res["cond"] = node_to_json(node.value.if_.cond) - res["body"] = node_vec_to_json(node.value.if_.body) - res["else_if"] = node_vec_to_json(node.value.if_.else_if) - res["else_"] = node_to_json(node.value.if_.else_) + res["cond"] = node_to_json(node.value.if_.cond, types) + res["body"] = node_vec_to_json(node.value.if_.body, types) + res["else_if"] = node_vec_to_json(node.value.if_.else_if, types) + res["else_"] = node_to_json(node.value.if_.else_, types) return res } -def else_if_to_json(node: &parser::Node) -> &Json { +def else_if_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "ElseIf" - res["cond"] = node_to_json(node.value.if_.cond) - res["body"] = node_vec_to_json(node.value.if_.body) + res["cond"] = node_to_json(node.value.if_.cond, types) + res["body"] = node_vec_to_json(node.value.if_.body, types) return res } -def else_to_json(node: &parser::Node) -> &Json { +def else_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "Else" - res["body"] = node_vec_to_json(node.value.body) + res["body"] = node_vec_to_json(node.value.body, types) return res } -def type_decl_to_json(node: &parser::Node) -> &Json { +def type_decl_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "TypeDecl" res["share"] = to_string(node.value.type_decl.share) - res["left"] = node_vec_to_json(node.value.type_decl.left) - res["right"] = node_vec_to_json(node.value.type_decl.right) + res["left"] = node_vec_to_json(node.value.type_decl.left, types) + res["right"] = node_vec_to_json(node.value.type_decl.right, types) return res } -def loop_to_json(node: &parser::Node) -> &Json { +def loop_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "Loop" - res["body"] = node_vec_to_json(node.value.body) + res["body"] = node_vec_to_json(node.value.body, types) return res } -def for_to_json(node: &parser::Node) -> &Json { +def for_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "For" - res["iddecl"] = node_to_json(node.value.for_loop.iddecl) - res["expr"] = node_to_json(node.value.for_loop.expr) - res["body"] = node_vec_to_json(node.value.for_loop.body) + res["iddecl"] = node_to_json(node.value.for_loop.iddecl, types) + res["expr"] = node_to_json(node.value.for_loop.expr, types) + res["body"] = node_vec_to_json(node.value.for_loop.body, types) return res } -def for_id_decl_to_json(node: &parser::Node) -> &Json { +def for_id_decl_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "ForIdDecl" res["kw"] = to_string(node.value.for_id_decl.kw) - res["ident"] = node_to_json(node.value.for_id_decl.ident) + res["ident"] = node_to_json(node.value.for_id_decl.ident, types) return res } -def while_to_json(node: &parser::Node) -> &Json { +def while_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "While" - res["expr"] = node_to_json(node.value.while_loop.expr) - res["body"] = node_vec_to_json(node.value.while_loop.body) + res["expr"] = node_to_json(node.value.while_loop.expr, types) + res["body"] = node_vec_to_json(node.value.while_loop.body, types) return res } -def import_module_to_json(node: &parser::Node) -> &Json { +def import_module_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "ImportModule" - res["name"] = node_to_json(node.value.import_module.name) - res["alias"] = node_to_json(node.value.import_module.alias) + res["name"] = node_to_json(node.value.import_module.name, types) + res["alias"] = node_to_json(node.value.import_module.alias, types) return res } -def def_to_json(node: &parser::Node) -> &Json { +def def_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "Def" res["share"] = to_string(node.value.def_.share) - res["name"] = node_to_json(node.value.def_.name) - res["params"] = node_vec_to_json(node.value.def_.params) - res["returns"] = node_vec_to_json(node.value.def_.returns) - res["body"] = node_vec_to_json(node.value.def_.body) + res["name"] = node_to_json(node.value.def_.name, types) + res["params"] = node_vec_to_json(node.value.def_.params, types) + res["returns"] = node_vec_to_json(node.value.def_.returns, types) + res["body"] = node_vec_to_json(node.value.def_.body, types) return res } -def parameter_to_json(node: &parser::Node) -> &Json { +def parameter_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "Parameter" res["kw"] = to_string(node.value.param.kw) - res["name"] = node_to_json(node.value.param.name) - res["tpe"] = node_to_json(node.value.param.tpe) - res["value"] = node_to_json(node.value.param.value) + res["name"] = node_to_json(node.value.param.name, types) + res["tpe"] = node_to_json(node.value.param.tpe, types) + res["value"] = node_to_json(node.value.param.value, types) return res } -def struct_lit_to_json(node: &parser::Node) -> &Json { +def struct_lit_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "StructLit" - res["args"] = node_vec_to_json(node.value.struct_lit.args) - res["kwargs"] = node_vec_to_json(node.value.struct_lit.kwargs) + res["args"] = node_vec_to_json(node.value.struct_lit.args, types) + res["kwargs"] = node_vec_to_json(node.value.struct_lit.kwargs, types) return res } -def assert_to_json(node: &parser::Node) -> &Json { +def assert_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "Assert" - res["cond"] = node_to_json(node.value.assert_.cond) - res["message"] = node_to_json(node.value.assert_.message) + res["cond"] = node_to_json(node.value.assert_.cond, types) + res["message"] = node_to_json(node.value.assert_.message, types) return res } -def structural_member_to_json(node: &parser::Node) -> &Json { +def structural_member_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "StructuralMember" - res["name"] = node_to_json(node.value.structural_member.name) - res["params"] = node_vec_to_json(node.value.structural_member.params) - res["returns"] = node_vec_to_json(node.value.structural_member.returns) + res["name"] = node_to_json(node.value.structural_member.name, types) + res["params"] = node_vec_to_json(node.value.structural_member.params, types) + res["returns"] = node_vec_to_json(node.value.structural_member.returns, types) return res } -def type_constructor_to_json(node: &parser::Node) -> &Json { +def type_constructor_to_json(node: &parser::Node, types: bool) -> &Json { let res = json::make_object() res["kind"] = "TypeConstructor" - res["name"] = node_to_json(node.value.type_constructor.name) - res["args"] = node_vec_to_json(node.value.type_constructor.args) + res["name"] = node_to_json(node.value.type_constructor.name, types) + res["args"] = node_vec_to_json(node.value.type_constructor.args, types) return res } -export def node_to_json(node: &parser::Node) -> &Json { +export def node_to_json(node: &parser::Node, types: bool = false) -> &Json { if not node { return json::make_null() } var res: &Json switch (@node).kind !int { case parser::NodeKind::PROGRAM: res = json::make_object() res["kind"] = "Program" - res["body"] = node_vec_to_json(node.body) + res["body"] = node_vec_to_json(node.body, types) case parser::NodeKind::INTEGER: res = json::make_object() res["kind"] = "Integer" @@ -340,11 +340,11 @@ export def node_to_json(node: &parser::Node) -> &Json { res["kind"] = "Boolean" res["value"] = node.value.i !bool case parser::NodeKind::IDENTIFIER: - res = identifier_to_json(node) + res = identifier_to_json(node, types) case parser::NodeKind::DEFINED: - res = un_op_to_json("Defined", node) + res = un_op_to_json("Defined", node, types) case parser::NodeKind::ERROR: - res = un_op_to_json("Error", node) + res = un_op_to_json("Error", node, types) case parser::NodeKind::NULL: res = json::make_object() res["kind"] = "Null" @@ -352,135 +352,135 @@ export def node_to_json(node: &parser::Node) -> &Json { res = json::make_object() res["kind"] = "Undef" case parser::NodeKind::RANGE: - res = bin_op_to_json("Range", node) + res = bin_op_to_json("Range", node, types) case parser::NodeKind::RANGE_INC: - res = bin_op_to_json("RangeInc", node) + res = bin_op_to_json("RangeInc", node, types) case parser::NodeKind::ARRAY_LIT: res = json::make_object() res["kind"] = "ArrayLit" - res["body"] = node_vec_to_json(node.value.body) + res["body"] = node_vec_to_json(node.value.body, types) case parser::NodeKind::STRUCT_LIT: - res = struct_lit_to_json(node) + res = struct_lit_to_json(node, types) case parser::NodeKind::MEMBER_ACCESS: - res = bin_op_to_json("MemberAccess", node) + res = bin_op_to_json("MemberAccess", node, types) case parser::NodeKind::CAST: - res = bin_op_to_json("Cast", node) + res = bin_op_to_json("Cast", node, types) case parser::NodeKind::SIZE_OF: - res = un_op_to_json("SizeOf", node) + res = un_op_to_json("SizeOf", node, types) case parser::NodeKind::ALIGN_OF: - res = un_op_to_json("AlignOf", node) + res = un_op_to_json("AlignOf", node, types) case parser::NodeKind::TYPE_OF_T: - res = un_op_to_json("TypeOf", node) + res = un_op_to_json("TypeOf", node, types) case parser::NodeKind::ADD: - res = bin_op_to_json("Add", node) + res = bin_op_to_json("Add", node, types) case parser::NodeKind::SUB: - res = bin_op_to_json("Sub", node) + res = bin_op_to_json("Sub", node, types) case parser::NodeKind::MUL: - res = bin_op_to_json("Mul", node) + res = bin_op_to_json("Mul", node, types) case parser::NodeKind::DIV: - res = bin_op_to_json("Div", node) + res = bin_op_to_json("Div", node, types) case parser::NodeKind::MOD: - res = bin_op_to_json("Mod", node) + res = bin_op_to_json("Mod", node, types) case parser::NodeKind::AND: - res = bin_op_to_json("And", node) + res = bin_op_to_json("And", node, types) case parser::NodeKind::OR: - res = bin_op_to_json("Or", node) + res = bin_op_to_json("Or", node, types) case parser::NodeKind::UADD: - res = un_op_to_json("UAdd", node) + res = un_op_to_json("UAdd", node, types) case parser::NodeKind::USUB: - res = un_op_to_json("USub", node) + res = un_op_to_json("USub", node, types) case parser::NodeKind::PTR: - res = un_op_to_json("Ptr", node) + res = un_op_to_json("Ptr", node, types) case parser::NodeKind::DEREF: - res = un_op_to_json("Deref", node) + res = un_op_to_json("Deref", node, types) case parser::NodeKind::BNOT: - res = un_op_to_json("BNot", node) + res = un_op_to_json("BNot", node, types) case parser::NodeKind::NOT: - res = un_op_to_json("Not", node) + res = un_op_to_json("Not", node, types) case parser::NodeKind::BAND: - res = bin_op_to_json("BAnd", node) + res = bin_op_to_json("BAnd", node, types) case parser::NodeKind::BOR: - res = bin_op_to_json("BOr", node) + res = bin_op_to_json("BOr", node, types) case parser::NodeKind::BXOR: - res = bin_op_to_json("BXor", node) + res = bin_op_to_json("BXor", node, types) case parser::NodeKind::SHL: - res = bin_op_to_json("Shl", node) + res = bin_op_to_json("Shl", node, types) case parser::NodeKind::SHR: - res = bin_op_to_json("Shr", node) + res = bin_op_to_json("Shr", node, types) case parser::NodeKind::PADD: - res = bin_op_to_json("PAdd", node) + res = bin_op_to_json("PAdd", node, types) case parser::NodeKind::PSUB: - res = bin_op_to_json("PSub", node) + res = bin_op_to_json("PSub", node, types) case parser::NodeKind::EQ: - res = bin_op_to_json("Eq", node) + res = bin_op_to_json("Eq", node, types) case parser::NodeKind::NEQ: - res = bin_op_to_json("NEq", node) + res = bin_op_to_json("NEq", node, types) case parser::NodeKind::GT: - res = bin_op_to_json("Gt", node) + res = bin_op_to_json("Gt", node, types) case parser::NodeKind::LT: - res = bin_op_to_json("Lt", node) + res = bin_op_to_json("Lt", node, types) case parser::NodeKind::GEQ: - res = bin_op_to_json("GEq", node) + res = bin_op_to_json("GEq", node, types) case parser::NodeKind::LEQ: - res = bin_op_to_json("LEq", node) + res = bin_op_to_json("LEq", node, types) case parser::NodeKind::PADD_EQ: - res = bin_op_to_json("PAddEq", node) + res = bin_op_to_json("PAddEq", node, types) case parser::NodeKind::PSUB_EQ: - res = bin_op_to_json("PSubEq", node) + res = bin_op_to_json("PSubEq", node, types) case parser::NodeKind::ADD_EQ: - res = bin_op_to_json("AddEq", node) + res = bin_op_to_json("AddEq", node, types) case parser::NodeKind::SUB_EQ: - res = bin_op_to_json("SubEq", node) + res = bin_op_to_json("SubEq", node, types) case parser::NodeKind::MUL_EQ: - res = bin_op_to_json("MulEq", node) + res = bin_op_to_json("MulEq", node, types) case parser::NodeKind::DIV_EQ: - res = bin_op_to_json("DivEq", node) + res = bin_op_to_json("DivEq", node, types) case parser::NodeKind::MOD_EQ: - res = bin_op_to_json("ModEq", node) + res = bin_op_to_json("ModEq", node, types) case parser::NodeKind::AND_EQ: - res = bin_op_to_json("AndEq", node) + res = bin_op_to_json("AndEq", node, types) case parser::NodeKind::OR_EQ: - res = bin_op_to_json("OrEq", node) + res = bin_op_to_json("OrEq", node, types) case parser::NodeKind::XOR_EQ: - res = bin_op_to_json("XorEq", node) + res = bin_op_to_json("XorEq", node, types) case parser::NodeKind::SHL_EQ: - res = bin_op_to_json("ShlEq", node) + res = bin_op_to_json("ShlEq", node, types) case parser::NodeKind::SHR_EQ: - res = bin_op_to_json("ShrEq", node) + res = bin_op_to_json("ShrEq", node, types) case parser::NodeKind::IMPORT: res = json::make_object() res["kind"] = "Import" - res["body"] = node_vec_to_json(node.value.body) + res["body"] = node_vec_to_json(node.value.body, types) case parser::NodeKind::IMPORT_MODULE: - res = import_module_to_json(node) + res = import_module_to_json(node, types) case parser::NodeKind::ASSIGN: - res = assign_to_json(node) + res = assign_to_json(node, types) case parser::NodeKind::DEF: - res = def_to_json(node) + res = def_to_json(node, types) case parser::NodeKind::PARAMETER: - res = parameter_to_json(node) + res = parameter_to_json(node, types) case parser::NodeKind::SWITCH: - res = switch_to_json(node) + res = switch_to_json(node, types) case parser::NodeKind::CASE: - res = case_to_json(node) + res = case_to_json(node, types) case parser::NodeKind::IF_EXPR: - res = if_expr_to_json(node) + res = if_expr_to_json(node, types) case parser::NodeKind::IF: - res = if_to_json(node, false) + res = if_to_json(node, false, types) case parser::NodeKind::STATIC_IF: - res = if_to_json(node, true) + res = if_to_json(node, true, types) case parser::NodeKind::ELSE_IF: - res = else_if_to_json(node) + res = else_if_to_json(node, types) case parser::NodeKind::ELSE: - res = else_to_json(node) + res = else_to_json(node, types) case parser::NodeKind::LOOP: - res = loop_to_json(node) + res = loop_to_json(node, types) case parser::NodeKind::WHILE: - res = while_to_json(node) + res = while_to_json(node, types) case parser::NodeKind::FOR: - res = for_to_json(node) + res = for_to_json(node, types) case parser::NodeKind::FOR_ID_DECL: - res = for_id_decl_to_json(node) + res = for_id_decl_to_json(node, types) case parser::NodeKind::BREAK: res = json::make_object() res["kind"] = "Break" @@ -490,78 +490,85 @@ export def node_to_json(node: &parser::Node) -> &Json { case parser::NodeKind::RETURN: res = json::make_object() res["kind"] = "Return" - res["body"] = node_vec_to_json(node.value.body) + res["body"] = node_vec_to_json(node.value.body, types) case parser::NodeKind::YIELD: res = json::make_object() res["kind"] = "Yield" - res["body"] = node_vec_to_json(node.value.body) + res["body"] = node_vec_to_json(node.value.body, types) case parser::NodeKind::DEFER: res = json::make_object() res["kind"] = "Defer" - res["body"] = node_vec_to_json(node.value.body) + res["body"] = node_vec_to_json(node.value.body, types) case parser::NodeKind::ASSERT: - res = assert_to_json(node) + res = assert_to_json(node, types) case parser::NodeKind::ARRAY_SUBSCRIPT: - res = bin_op_to_json("ArraySubscript", node) + res = bin_op_to_json("ArraySubscript", node, types) case parser::NodeKind::FUNC_CALL: - res = func_call_to_json(node) + res = func_call_to_json(node, types) case parser::NodeKind::TYPE_DECL: - res = type_decl_to_json(node) + res = type_decl_to_json(node, types) case parser::NodeKind::VAR_DECL: - res = var_decl_to_json(node) + res = var_decl_to_json(node, types) case parser::NodeKind::ID_DECL: - res = id_decl_to_json(node) + res = id_decl_to_json(node, types) case parser::NodeKind::ID_ASSIGN: - res = id_assign_to_json(node) + res = id_assign_to_json(node, types) case parser::NodeKind::NAMED_ARG: - res = named_arg_to_json(node) + res = named_arg_to_json(node, types) case parser::NodeKind::ID_DECL_STRUCT: - res = id_decl_struct_to_json(node) + res = id_decl_struct_to_json(node, types) case parser::NodeKind::ID_DECL_ENUM: - res = id_decl_enum_to_json(node) + res = id_decl_enum_to_json(node, types) case parser::NodeKind::ENUM_T: - res = enum_to_json(node) + res = enum_to_json(node, types) case parser::NodeKind::STRUCT_T: res = json::make_object() res["kind"] = "Struct" - res["body"] = node_vec_to_json(node.value.body) + res["body"] = node_vec_to_json(node.value.body, types) case parser::NodeKind::UNION_T: res = json::make_object() res["kind"] = "Union" - res["body"] = node_vec_to_json(node.value.body) + res["body"] = node_vec_to_json(node.value.body, types) case parser::NodeKind::FUNCTION_T, parser::NodeKind::CLOSURE_T: - res = function_t_to_json(node) + res = function_t_to_json(node, types) case parser::NodeKind::UNSIGNED_T: - res = unsigned_to_json(node) + res = unsigned_to_json(node, types) case parser::NodeKind::PTR_T: - res = ptrarray_to_json("PtrT", node) + res = ptrarray_to_json("PtrT", node, types) case parser::NodeKind::REF_T: - res = ptrarray_to_json("RefT", node) + res = ptrarray_to_json("RefT", node, types) case parser::NodeKind::ARRAY_T: - res = ptrarray_to_json("ArrayT", node) + res = ptrarray_to_json("ArrayT", node, types) case parser::NodeKind::WEAK_REF_T: - res = ptrarray_to_json("WeakRefT", node) + res = ptrarray_to_json("WeakRefT", node, types) case parser::NodeKind::WORD_T: res = json::make_object() res["kind"] = "Word" res["size"] = node.value.i !double case parser::NodeKind::ARRAY_STATIC_T: - res = array_static_to_json(node) + res = array_static_to_json(node, types) case parser::NodeKind::TYPE_T: - res = un_op_to_json("TypeT", node) + res = un_op_to_json("TypeT", node, types) case parser::NodeKind::STRUCTURAL_T: res = json::make_object() res["kind"] = "StructuralT" - res["body"] = node_vec_to_json(node.value.body) + res["body"] = node_vec_to_json(node.value.body, types) case parser::NodeKind::STRUCTURAL_T_MEMBER: - res = structural_member_to_json(node) + res = structural_member_to_json(node, types) case parser::NodeKind::TYPE_CONSTRUCTOR: - res = type_constructor_to_json(node) + res = type_constructor_to_json(node, types) case: error(node.kind, "\n") assert } + if types and node.tpe { + let info = json::make_object() + info["name"] = type_to_str(node.tpe) + info["size"] = node.tpe.size + info["align"] = node.tpe.align + res["type_tag"] = info + } return res } diff --git a/src/errors.pr b/src/errors.pr index 853ceaa0..60c76464 100644 --- a/src/errors.pr +++ b/src/errors.pr @@ -88,7 +88,7 @@ export def errorn(node: &parser::Node, msg: &string...) { if suppress_errors { return } if not node { assert(false) } - let filename = (@node).loc.filename + let filename = (@node).loc.display_name let line = (@node).loc.line let column = (@node).loc.column let end_line = node.loc.end_line diff --git a/src/main.pr b/src/main.pr index 96bdc322..c086bc91 100644 --- a/src/main.pr +++ b/src/main.pr @@ -15,6 +15,10 @@ let options = [ .set_help("Print the ast when compiling")), (option("--tokens", false) .set_help("Print the tokens when compiling")), + (option("--typed-ast", false) + .set_help("Print AST with type information")), + (option("--continue-on-output", false) + .set_help("Continue after printing the AST/Tokens")), (option_repeat('I', "--include") .set_help("Include directory") .set_metavar("DIR")), @@ -55,6 +59,8 @@ let options = [ .set_help("Set up language server to use stdio")), (option("--no-incremental", false) .set_help("Starts compiling non incrementally, all caches are invalidated")), + (option("--name", "") + .set_help("Set name for the main file")), (option("compile", "") .set_help("File to compile") .set_metavar("FILE")) @@ -65,6 +71,8 @@ if not res { exit(1) } let print_ast = parser.get_value("--ast").b let print_tokens = parser.get_value("--tokens").b +let print_typed_ast = parser.get_value("--typed-ast").b +let continue_on_output = parser.get_value("--continue-on-output").b let includes = parser.get_value("--include") let defines = parser.get_value("--define") let link_directories = parser.get_value("--link-directory") @@ -80,6 +88,7 @@ let print_version = parser.get_value("--version").b let verbose = parser.get_value("--verbose").b let language_server = parser.get_value("--language-server").b let no_incremental = parser.get_value("--no-incremental").b +let name = parser.get_value("--name").str let filename = parser.get_value("compile").str if print_version { @@ -120,8 +129,14 @@ while define { debug::verbose = verbose +if name.length > 0 { + toolchain::main_file_name = name +} + toolchain::print_ast = print_ast toolchain::print_tokens = print_tokens +toolchain::print_typed_ast = print_typed_ast +toolchain::continue_on_output = continue_on_output toolchain::debug_sym = debug_sym toolchain::time_report = time_report toolchain::dependency_graph = dependency_graph diff --git a/src/parser.pr b/src/parser.pr index f0df83b4..0a5d72ab 100644 --- a/src/parser.pr +++ b/src/parser.pr @@ -368,6 +368,7 @@ export type NodeValue = struct #union { export type SourceLoc = struct { filename: &string + display_name: &string module: &string line: int column: int @@ -1131,6 +1132,7 @@ export def find(node: &Node, line: int, column: int) -> &Node { export type ParseState = struct { filename: &string + display_name: &string module: &string has_error: bool lines: &[&string] @@ -1350,6 +1352,7 @@ def make_node(kind: NodeKind, line: int, column: int, state: &ParseState) -> &No kind = kind, loc = { state.filename, + state.display_name, state.module, line, column, @@ -2385,6 +2388,7 @@ def parse_term(parse_state: &ParseState) -> &Node { node.scope = null node.loc = { parse_state.filename, + parse_state.display_name, parse_state.module, token.line, token.column, @@ -3899,12 +3903,13 @@ def parse_block(parse_state: &ParseState, vec: &Vector(&Node)) { export var time_spent: int64 = 0 -export def parse(list: *lexer::TokenList, lines: &[&string], filename: &string, module: &string) -> &Node { +export def parse(list: *lexer::TokenList, lines: &[&string], filename: &string, module: &string, display_name: &string = null) -> &Node { debug::trace("Parsing ", module) let start = util::millis() var parse_state = { filename = filename, + display_name = display_name, module = module, lines = lines, tokens = list diff --git a/src/scope.pr b/src/scope.pr index 3daaa825..feb0bc83 100644 --- a/src/scope.pr +++ b/src/scope.pr @@ -119,6 +119,7 @@ export def loc(value: &Value) -> parser::SourceLoc { if value.tpe and value.tpe.kind == typechecking::TypeKind::NAMESPACE { let module = value._module.module return { + module.filename, module.filename, module.module, 0, 0, 0, 0 @@ -185,7 +186,9 @@ export def create_dependency_on_type(this: &Value, node: &parser::Node) { // TODO We need to check for type here for some reason, without this enums from other files get caught // Figure out why instead of working around the problem if node.kind == parser::NodeKind::IDENTIFIER and (not node.tpe or node.tpe.kind == typechecking::TypeKind::STUB) { - errors::errorn(node, "Unknown type") + if node.tpe and node.tpe.kind == typechecking::TypeKind::STUB { + errors::errorn(node, "Unknown type") + } create_dependency(this, make_ident(parser::identifier_to_str(node))) } return diff --git a/src/test/main.pr b/src/test/main.pr deleted file mode 100644 index caafaaa7..00000000 --- a/src/test/main.pr +++ /dev/null @@ -1,18 +0,0 @@ -import getopt -import test::testsuite - -let options = [ - option('f', "--filter", "*").set_help("Filter test cases, wildcards * and ? are allowed"), - option("--no-fork", false).set_help("If specified runs the test on the same process instead of creating a fork"), - option("--no-capture", false).set_help("Specifies if stdout and stderr should be captured") -] - -let parser = *getopt::make_parser(options, "Princess Testsuite") -let res = parser.parse(args) -if not res { exit(1) } - -test::testsuite::match_string = parser.get_value("--filter").str -test::testsuite::fork_process = not parser.get_value("--no-fork").b -test::testsuite::capture_stdout = not parser.get_value("--no-capture").b - -test::testsuite::run_test_suite() \ No newline at end of file diff --git a/src/test/test_compiler.pr b/src/test/test_compiler.pr deleted file mode 100644 index 786ec8d9..00000000 --- a/src/test/test_compiler.pr +++ /dev/null @@ -1,837 +0,0 @@ -import vector -import map -import codegen -import lexer -import util -import parser -import scope -import typechecking -import compiler -import toolchain -import builtins -import consteval -import errors - -import test::testsuite - -export var print_ll = false - -def compile(s: &string) -> &toolchain::Module { - toolchain::outfolder = "./build" - errors::error_count = 0 - toolchain::clear_temporaries_in_runtime_module() - - let main = "main" - let tokens = lexer::lex(s) - let lines = util::split_lines(s) - let node = parser::parse(tokens, lines, main, main) - let module = toolchain::make_module( - text = s, - lines = lines, - filename = main, - modulename = main, - node = node, - scpe = scope::enter_function_scope(builtins::builtins, null) - ) - module.scope.module = module - toolchain::modules[main] = module - - consteval::consteval(module) - typechecking::typecheck(module) - - toolchain::load_file_type() - toolchain::reset_types() - - compiler::compile(module) - codegen::gen(module) - - let fh = open("./build/main.ll", "r") - let buf = read_all(fh) - close(fh) - - #if defined WIN32 { - let llc = system("llc.exe build/main.ll") - } else { - let llc = system("llc-13 build/main.ll") - } - - if llc { - error("LLC compilation failed!\n") - } - - if print_ll or llc { - print("\n") - print(s) - print("\n") - print(buf) - } - - if llc { - exit(1) - } - - return module -} - -def test_arithmetic { - var str = " - 10 + 10 + 10 - " - var res = compile(str) - - str = " - 10 * 2 + 5 / 4 - 5 % 3 - " - res = compile(str) - - str = " - 10.5 / 4.0 - " - res = compile(str) - - str = " - 10 << 1 + 10 >> 2 - " - res = compile(str) - - str = " - -10 - -10.5 - " - res = compile(str) -} - -def test_call { - var str = " - def add(a: int, b: int) -> int { - return a + b - } - add(10, 10) - " - var res = compile(str) - - // Overloaded function - str = " - def add(a: int, b: int) -> int { - return a + b - } - def add(a: double, b: double) -> double { - return a + b - } - add(10, 10) - add(10.0, 10.5) - " - res = compile(str) -} - -def test_if { - var str = " - def foo {} - if true { - foo() - } - foo() - " - var res = compile(str) - - str = " - def foo -> int { return 0 } - if true { - let x = foo() - } else if false { - let x = foo() - } else if true { - let x = foo() - } - let x = foo() - " - res = compile(str) - - str = " - def foo - if true { - foo() - } else { - foo() - } - foo() - " - res = compile(str) - - // Nested - str = " - def foo - if true { - foo() - if true { - foo() - } else { - foo() - } - } else { - foo() - if true { - foo() - } else if true { - foo() - } else { - foo() - } - } - foo() - " - res = compile(str) -} - -def test_loop { - var str = " - def foo - loop { - foo() - continue - foo() - break - foo() - } - " - var res = compile(str) - - str = " - loop { - if true { - break - } else { - continue - } - break - } - " - res = compile(str) - - str = " - loop { - continue - loop { - continue - break - } - break - } - " - res = compile(str) -} - -def test_while { - var str = " - var i = 0 - while i < 10 { - i += 1 - } - " - var res = compile(str) -} - -def test_for { - var str = " - for var i in 0..10 { - print(i) - } - " - var res = compile(str) - - str = " - var i = 0 - for i in 0..=10 { - print(i) - } - " - res = compile(str) -} - -def test_vardecl { - var str = " - def foo { - var a: int, b: int - } - " - var res = compile(str) - - // Test scoping - str = " - def foo { - var a: int - if false { - var a: int - } - } - " - res = compile(str) -} - -def test_globals { - var str = " - var global: int - " - var res = compile(str) - - str = " - let global = 20 - " - res = compile(str) - - str = " - let a, b = 10, 20 - " - res = compile(str) - - str = " - def foo -> int, int { - return 10, 20 - } - let a, b = foo() - " - res = compile(str) - - str = " - def foo -> int, int { - return 10, 20 - } - var a: int - let (a), b = foo() - " - res = compile(str) - - str = " - def foo -> int { - return 10 - } - var a: int - var b: int - a = b = foo() - " - res = compile(str) -} - -def test_ptr { - var str = " - let a = 20 - let pa = *a - @pa = 40 - " - var res = compile(str) - - str = " - let a = 20 - let pa = *a - let ppa = *pa - @@ppa = 40 - let b = @@ppa - " - res = compile(str) -} - -def test_ref { - var str = " - var a: &int - var b: & - b = a - " - var res = compile(str) - - str = " - var a: &int = 20 - var b = a - " - res = compile(str) - - str = " - var a: &int = 20 - var b = @a - " - res = compile(str) - - str = " - var a: &int = 20 - var b = a !&float - var c = a !*int - " - res = compile(str) -} - -def test_convert { - var str = " - let a = 10 !float - let b = a !int - " - var res = compile(str) - - str = " - let a = 10!float + 20 - let b = 10!uint + 20 - " - res = compile(str) - - str = " - let a = 200!bool - let b = 1.5!bool - let c: *int = null - let d = c!bool - " - res = compile(str) - - str = " - let a: int64 = 20 - let b: int16 = 20 - - def foo(a: int64) - foo(10) - " - res = compile(str) -} - -def test_member_access { - var str = " - type S = struct { - value: int - } - type T = struct { - a: int - b: S - } - - var t: T - let a = t.a - let b = t.b.value - - t.b.value = 20 - t.a = 40 - " - var res = compile(str) -} - -def test_array_subscript { - var str = " - var a: [int] - var b: *int - var c: [3; int] - - let d = a[2] - let e = b[2] - let f = c[2] - - a[2] = 5 - b[2] = 10 - c[2] = 15 - " - var res = compile(str) -} - -def test_struct_lit { - var str = " - type T = struct { - a: int - b: int - } - let a = {10, 20} !T - " - var res = compile(str) - - str = " - type T = struct { - a: int - b: int - } - let a = 20 - let b = 50 - let c = {a = a, b = b} !T - " - res = compile(str) - - str = " - type A = struct { - a: int - } - type B = struct { - b: A - c: int - } - let a = 20 - let b = 50 - let v = {{a} !A, b} !B - " - res = compile(str) - - str = " - type A = struct { - value: int - } - - def ret_a -> A { - return {10} - } - - let a: A = {10} - var b: A - b = {10} - " - res = compile(str) - - str = " - type A = struct { - a: int - b: int - c: int - } - let a = {a = 10} !A - " - res = compile(str) -} - -def test_size_of { - var str = " - type T = struct { - a: int - b: int - } - - let a = size_of T - let b = size_of int - let c = size_of type * - let d = size_of type_of a - let e = size_of type_of a + b - " - var res = compile(str) -} - -def test_align_of { - var str = " - type T = struct { - a: int - b: int - } - - let a = align_of T - let b = align_of int - let c = align_of type * - let d = align_of type_of a - let e = align_of type_of a + b - " - var res = compile(str) -} - -def test_type_of { - var str = " - let a = 20 - let b: (type_of a) = 30 - - def some_function(type T) {} - - some_function(type_of a) - " - var res = compile(str) -} - -def test_array_lit { - var str = " - let a = [1, 2, 3, 4] - " - var res = compile(str) - - str = " - let a: [int] = [1, 2, 3, 4] - let b: [?; int] = [1, 2, 3, 4] - " - res = compile(str) - - str = " - let a = 10 - let b = [a, 20] - let c: [int] = b - " - res = compile(str) -} - -def test_compare { - var str = " - let a = 10 == 20 - let b = 10 > 20 - let c = 10 < 20 - - let d = 5 - let e = 1 < d < 10 - " - var res = compile(str) -} - -def test_pointer_arithmetic { - var str = " - let a = 20 - let b = *a - let c = b ++ 20 -- 5 - " - var res = compile(str) - - str = " - var a: *int - @(a ++ 10) = 20 - " - res = compile(str) -} - -def test_assign_eq { - var str = " - var a = 10 - a += 20 - a <<= 1 - a >>= 2 - a *= 5 - a /= 10 - " - var res = compile(str) -} - -def test_import { - var str = " - import test::module::a - import test::module::b - - let a, b = return_multiple() - " - var res = compile(str) -} - -def test_array_size_and_value { - var str = " - var a: [4; int] - var b: [int] - - let c = a.size - let d = a.value - let e = b.size - let f = b.value - - b.size = 20 - b.value = null - " - var res = compile(str) -} - -def test_string_literal { - // Conversion between static and dynamic arrays - var str = " - def function -> [4; char] {} - - var a: [char] = \"abc\" - var b: [char] = function() - - def two_returns -> [4; char], [5; char] {} - var c: [char], d: [char] = two_returns() - " - var res = compile(str) -} - -def test_boolean_op { - var str = " - let a = true - let b = false - let c = a and b - let d = a or b - let e = not d - " - var res = compile(str) -} - -def test_builtins { - var str = " - var a = 10 - assert(a == 15) - print(a, 10, 10.5, \"string\") - let b = allocate(int) - let c = allocate(size_of int) !*int - reallocate(c, 10 * (size_of int)) - let d = allocate(int, 10) - free(b) - free(c) - free(d) - " - var res = compile(str) - - str = " - let fp: File = open(\"build/test\", \"wb+\") - - write(fp, \"some string\") - let i = 20 - write(fp, *i) - - rewind(fp) - - var str: [12; char] - read(fp, str) - - var i2: int - read(fp, *i2) - - close(fp) - " - res = compile(str) - - str = " - let fp: File = open(\"build/test_file_io_text\", \"w+\") - - fprint(fp, \"This is a test\\n\", 10) - - seek(fp, 0, SEEK_SET) // Same as rewind - - var buffer: [20; char] - read_line(fp, buffer) - var num: int - cstd::fscanf(fp, \"%d\".value, *num) - - close(fp) - - " - res = compile(str) -} - -def test_switch { - var str = " - let a = 20 - switch a { - case 10: print(1) - case 11..=19: print(2) - case 20, 25: print(3) - case: print(4) - } - " - var res = compile(str) - - str = " - let a = 20 - switch a { - case 0..=100: print(1) - case 101, 102, 103: print(2) - case 104..200, 205: print(3) - case: print(4) - } - " - res = compile(str) -} - -def test_function_pointers { - var str = " - def some_function -> int { return 20 } - let a = *some_function - let b = a() - " - var res = compile(str) -} - -def test_if_expression { - var str = " - let a = 10 if 10 > 20 else 5 - var b: int - var c: int - @(*b if 10 > 20 else *c) = 10 - " - var res = compile(str) -} - -def test_return_multiple { - var str = " - type T = struct { - a: int - b: int - } - - def return_multiple -> T, T { - let a = { 0, 0 } !T - let b = { 1, 1 } !T - return a, b - } - " - var res = compile(str) -} - -def test_assert { - var str = " - assert - assert 1 == 2 - assert 1 == 2, \"What is this\" - " - var res = compile(str) -} - -def test_yield { - var str = " - def some_function -> int { - yield 20 - yield 30 - } - let gen = some_function() - for var i in gen { - print(i) - } - " - var res = compile(str) -} - -def test_closure { - var str = " - def some_function -> int { - var a = 20 - var b = 30 - def inner -> int { - let capture = *b - let res = a + @capture - @capture += 10 - return res - } - inner() - return inner() - } - " - var res = compile(str) -} - -export def run_tests { - toolchain::no_incremental = true // TODO Temporary - toolchain::no_dependency_tracking = true - toolchain::include_path.push("src") - - toolchain::prepare_preload() - toolchain::create_types_main() - - print("Running tests on Compiler...\n") - run_test("test_arithmetic", *test_arithmetic) - run_test("test_call", *test_call) - run_test("test_if", *test_if) - run_test("test_loop", *test_loop) - run_test("test_while", *test_while) - run_test("test_for", *test_for) - run_test("test_vardecl", *test_vardecl) - run_test("test_globals", *test_globals) - run_test("test_ptr", *test_ptr) - run_test("test_ref", *test_ref) - run_test("test_convert", *test_convert) - run_test("test_member_access", *test_member_access) - run_test("test_array_subscript", *test_array_subscript) - run_test("test_struct_lit", *test_struct_lit) - run_test("test_size_of", *test_size_of) - run_test("test_align_of", *test_align_of) - run_test("test_type_of", *test_type_of) - run_test("test_array_lit", *test_array_lit) - run_test("test_compare", *test_compare) - run_test("test_pointer_arithmetic", *test_pointer_arithmetic) - run_test("test_assign_eq", *test_assign_eq) - run_test("test_import", *test_import) - run_test("test_array_size_and_value", *test_array_size_and_value) - run_test("test_string_literal", *test_string_literal) - run_test("test_builtins", *test_builtins) - run_test("test_switch", *test_switch) - run_test("test_function_pointers", *test_function_pointers) - run_test("test_if_expression", *test_if_expression) - run_test("test_return_multiple", *test_return_multiple) - run_test("test_assert", *test_assert) - run_test("test_yield", *test_yield) - run_test("test_closure", *test_closure) -} \ No newline at end of file diff --git a/src/test/test_ctfe.pr b/src/test/test_ctfe.pr deleted file mode 100644 index df47b8e1..00000000 --- a/src/test/test_ctfe.pr +++ /dev/null @@ -1,70 +0,0 @@ -import test::testsuite - -def test_constants { - // We can't use pointers here - const c = 4 - tassert(c == 4) -} - -def sum(a: int, b: int) -> int { - return a + b -} - -def test_func_call { - // TODO Varargs don't work for some reason - const sum = sum(10, 20) - tassert(sum == 30) -} - -def test_static_if { - const s = sum(10, 20) - #if s > 10 { - var a: int = 10 - } else { - var a: int = 20 - } - tassert(a == 10) -} - -def return_random_number -> long { - cstd::srand(100) - return cstd::rand() -} - -def test_c_functions { - const ac = return_random_number() - let al = return_random_number() - - tassert(ac == al) -} - -def append_str(a: string, b: string) -> string { - let res = a + b - return @res -} - -const hello_world = append_str("Hello ", "World!") - -def test_strings { - tassert(hello_world == "Hello World!") -} - -def test_bug_1_ -> bool { - return true == (true == true) -} - -def test_bug_1 { - const ac = test_bug_1_() - let al = test_bug_1_() - tassert(ac == al == true) -} - -export def run_tests { - print("Running tests on compile time functions... \n") - run_test("test_constants", *test_constants) - run_test("test_func_call", *test_func_call) - run_test("test_static_if", *test_static_if) - run_test("test_c_functions", *test_c_functions) - run_test("test_strings", *test_strings) - run_test("test_bug_1", *test_bug_1) -} \ No newline at end of file diff --git a/src/test/test_expr_eval.pr b/src/test/test_expr_eval.pr deleted file mode 100644 index 098ca8c7..00000000 --- a/src/test/test_expr_eval.pr +++ /dev/null @@ -1,53 +0,0 @@ -import test::testsuite - -type Node = interface { - def walk() -> int -} - -type Add = struct { - left: &Node - right: &Node -} - -def walk(add: &Add) -> int { - return add.left.walk() + add.right.walk() -} - -type Sub = struct { - left: &Node - right: &Node -} - -def walk(sub: &Sub) -> int { - return sub.left.walk() - sub.right.walk() -} - -type Value = struct { - value: int -} - -def walk(value: &Value) -> int { - return value.value -} - -def test_expr { - // 10 + (40 - 20) + 40 - let expr = { - { - {10} !&Value, - { - {40} !&Value, - {20} !&Value - } !&Sub - } !&Add, - {40} !&Value - } !&Add - - let result = walk(expr) - tassert(result == 70) -} - -export def run_tests { - print("Running expression test... \n") - run_test("test_expr", *test_expr) -} \ No newline at end of file diff --git a/src/test/test_json.pr b/src/test/test_json.pr deleted file mode 100644 index ca0f9cd8..00000000 --- a/src/test/test_json.pr +++ /dev/null @@ -1,208 +0,0 @@ -import test::testsuite -import json -import optional -import util - -def test_numbers { - let data = """ - { - "key_a": 10, - "key_b": -10, - "key_c": 10.5, - "key_d": 10E2, - "key_e": 10e2, - "key_f": 10e+2, - "key_g": 10e-2, - "key_h": 0 - } - """ - let obj = json::parse(data) - tassert(obj["key_a"].as_double() == 10) - tassert(obj["key_b"].as_double() == -10) - tassert(obj["key_c"].as_double() == 10.5) - tassert(obj["key_d"].as_double() == 10E2) - tassert(obj["key_e"].as_double() == 10e2) - tassert(obj["key_f"].as_double() == 10e+2) - tassert(obj["key_g"].as_double() == 10e-2) - tassert(obj["key_h"].as_double() == 0) -} - -def test_arrays { - let data = """ - { - "key_a": [1, 2, 3], - "key_b": ["a", "b", "c"], - "key_c": [ - {"1": 1}, - {"2": 2}, - {"3": 3} - ] - } - """ - let obj = json::parse(data) - let key_a = obj["key_a"] - tassert(key_a[0].as_double() == 1 and key_a[1].as_double() == 2 and key_a[2].as_double() == 3) - let key_b = obj["key_b"] - tassert(key_b[0].as_string() == "a" and key_b[1].as_string() == "b" and key_b[2].as_string() == "c") - let key_c = obj["key_c"] - tassert(key_c[0]["1"].as_double() == 1 and key_c[1]["2"].as_double() == 2 and key_c[2]["3"].as_double() == 3) -} - -def test_objects { - let data = """ - { - "key_a": { - "1": 1, - "2": 2 - }, - "key_b": { - "1": 1, - "2": 2 - } - } - """ - let obj = json::parse(data) - let key_a = obj["key_a"] - tassert(key_a["1"].as_double() == 1 and key_a["2"].as_double() == 2) - let key_b = obj["key_b"] - tassert(key_b["1"].as_double() == 1 and key_b["2"].as_double() == 2) -} - -def test_values { - let data = """ - { - "key_a": null, - "key_b": true, - "key_c": false - } - """ - let obj = json::parse(data) - tassert(obj["key_a"].is_null()) - tassert(obj["key_b"].as_bool() == true) - tassert(obj["key_c"].as_bool() == false) -} - -def test_strings { - let data = """ - { - "key_a": "some string", - "key_b": "\\" \\\\ \\b \\f \\n \\r \\t", - "key_c": "\\uAABB" - } - """ - let obj = json::parse(data) - tassert(obj["key_a"].as_string() == "some string") - tassert(obj["key_b"].as_string() == "\" \\ \b \f \n \r \t") - tassert(obj["key_c"].as_string() == "\uAABB") -} - -type A = struct { - a: int - b: double - c: B - d: [5; int] -} -type B = struct { - a: int - s: &string -} - -def test_serialization { - let value = { a = 10, b = 20.5, c = { a = 20, s = "some string" } !B, d = [1, 2, 3, 4, 5] } !A - let obj = json::serialize(*value) - print(obj) - - let value2 = json::deserialize(obj, A).get() - tassert(value2.a == value.a) - tassert(value2.b == value.b) - tassert(value2.c.a == value.c.a) - for var i in 0..value2.d.size { - tassert(value2.d[i] == value.d[i]) - } -} - -def test_equality { - let data1 = """ - { - "key_1": 0, - "key_2": 1 - } - """ - let data2 = """ - { - "key_2": 1, - "key_1": 0 - } - """ - let data3 = """ - { - "key_1": 0 - } - """ - - tassert(json::parse(data1) == json::parse(data2)) - tassert(json::parse(data1) != json::parse(data3)) -} - -def test_generation { - let data = """ - { - "key_1": 0, - "key_2": true, - "key_3": "some_string", - "key_4": null, - "key_5": { - "foo": 10, - "bar": 20 - }, - "key_6": [ - 10, 20, 30, 40 - ] - } - """ - let obj = json::parse(data) - let obj2 = json::make_object() - obj2["key_1"] = 0 - obj2["key_2"] = true - obj2["key_3"] = "some_string" - obj2["key_4"] = json::make_null() - let obj3 = json::make_object() - obj3["foo"] = 10 - obj3["bar"] = 20 - obj2["key_5"] = obj3 - let array = json::make_array() - array.push(10) - array.push(20) - array.push(30) - array.push(40) - obj2["key_6"] = array - - tassert(obj == obj2) -} - -export def run_tests { - print("Running json tests... \n") - run_test("test_numbers", *test_numbers) - run_test("test_arrays", *test_arrays) - run_test("test_objects", *test_objects) - run_test("test_values", *test_values) - run_test("test_strings", *test_strings) - run_test("test_serialization", *test_serialization, strip_margin("""\ - |{ - | "a": 10.00000, - | "b": 20.50000, - | "c": { - | "a": 20.00000, - | "s": "some string" - | }, - | "d": [ - | 1.00000, - | 2.00000, - | 3.00000, - | 4.00000, - | 5.00000 - | ] - |}"""), "") - run_test("test_equality", *test_equality) - run_test("test_generation", *test_generation) -} \ No newline at end of file diff --git a/src/test/test_lexer.pr b/src/test/test_lexer.pr deleted file mode 100644 index 7f26d3c9..00000000 --- a/src/test/test_lexer.pr +++ /dev/null @@ -1,291 +0,0 @@ -import lexer -import test::testsuite - -def next_value(list: **lexer::TokenList, tpe: lexer::TokenType) -> lexer::Token { - let value = (@list).value - if value.tpe == lexer::TokenType::ERROR { - error("Error: ", value.value.str, "\n") - exit(2) - } - tassert(value.tpe == tpe) - @list = (@list).next - return value -} - -def next_char(list: **lexer::TokenList) -> char { - return next_value(list, lexer::TokenType::CHAR).value.ch -} - -def next_long(list: **lexer::TokenList) -> uint64 { - return next_value(list, lexer::TokenType::INTEGER).value.i -} - -def next_double(list: **lexer::TokenList) -> double { - return next_value(list, lexer::TokenType::FLOAT).value.f -} - -def next_string(list: **lexer::TokenList) -> &string { - return next_value(list, lexer::TokenType::STRING).value.str -} - -def next_identifier(list: **lexer::TokenList) -> &string { - return next_value(list, lexer::TokenType::IDENTIFIER).value.str -} - -def next_comment(list: **lexer::TokenList) -> &string { - return next_value(list, lexer::TokenType::COMMENT).value.str -} - -def next_pragma(list: **lexer::TokenList) -> &string { - return next_value(list, lexer::TokenType::PRAGMA).value.str -} - -def next_error(list: **lexer::TokenList) -> &string { - let value = (@@list).value - if value.tpe != lexer::TokenType::ERROR { - error("Error: Invalid token type: ", value.tpe, "\n") - exit(2) - } - let s = value.value.str - @list = (@@list).next - return s -} - -def test_float_literal { - var str = "10.5" - var result = lexer::lex(str) - tassert(next_double(*result) == 10.5) - - str = ".5" - result = lexer::lex(str) - tassert(next_double(*result) == .5) - - str = "10." - result = lexer::lex(str) - tassert(next_double(*result) == 10.) - - str = "10E10" - result = lexer::lex(str) - tassert(next_double(*result) == 10E10) - - str = "10.e10" - result = lexer::lex(str) - tassert(next_double(*result) == 10.e10) - - /*str = "10E-4" - result = lexer::lex(str) - tassert(next_double(*result) == 10E-4)*/ // TODO This doesnt work - - str = "10E+10" - result = lexer::lex(str) - tassert(next_double(*result) == 10E+10) -} - -def test_int_literal { - var str = "156" - var result = lexer::lex(str) - tassert(next_long(*result) == 156) - - str = "0b100100" - result = lexer::lex(str) - tassert(next_long(*result) == 0b100100) - - str = "0xDEADBABE" - result = lexer::lex(str) - tassert(next_long(*result) == 0xDEADBABE) - - str = "0o172" - result = lexer::lex(str) - tassert(next_long(*result) == 0o172) -} - -def test_char_literal { - var str = "'A'" - var result = lexer::lex(str) - tassert(next_char(*result) == 'A') - - str = "'A' 'B'" - result = lexer::lex(str) - tassert(next_char(*result) == 'A') - next_value(*result, lexer::TokenType::WHITESPACE) - tassert(next_char(*result) == 'B') - - str = "'\\a'" - result = lexer::lex(str) - tassert(next_char(*result) == '\a') - - str = "'\\xFF'" - result = lexer::lex(str) - tassert(next_char(*result) == '\xFF') - -} - -def test_char_literal_error { - var str = "'A" - var result = lexer::lex(str) - tassert(next_error(*result) == "Unexpected end of file while parsing character") - - str = "'\\d'" - result = lexer::lex(str) - tassert(next_error(*result) == "Invalid escape sequence") - - str = "'\\x" - result = lexer::lex(str) - tassert(next_error(*result) == "Invalid escape sequence") - - //TODO Test more corner cases -} - -def test_string_literal { - var str = "\"this is a test\"" - var result = lexer::lex(str) - tassert(next_string(*result) == "this is a test") - - str = "\"test\" \"more\"" - result = lexer::lex(str) - tassert(next_string(*result) == "test") - next_value(*result, lexer::TokenType::WHITESPACE) - tassert(next_string(*result) == "more") - - str = "\"\\a\\b\\f\\n\\r\\t\\v\\'\\\"\\\\\"" - result = lexer::lex(str) - tassert(next_string(*result) == "\a\b\f\n\r\t\v\'\"\\") - - str = "\"\\xFF\"" - result = lexer::lex(str) - tassert(next_string(*result) == "\xFF") - - str = "\"\\u01FF\"" - result = lexer::lex(str) - tassert(next_string(*result) == "\u01FF") - - str = "\"\\u88AA\"" - result = lexer::lex(str) - tassert(next_string(*result) == "\u88AA") - - str = "\"\\U0010FFFF\"" - result = lexer::lex(str) - tassert(next_string(*result) == "\U0010FFFF") - - str = "\"\n\n\"" - result = lexer::lex(str) - tassert(next_string(*result) == "\n\n") -} - -def test_string_literal_error { - var str = "\"this is a test" - var result = lexer::lex(str) - tassert(next_error(*result) == "Unexpected end of file while parsing string literal") - - str = "\"test \\d \"" - result = lexer::lex(str) - tassert(next_error(*result) == "Invalid escape sequence") - - str = "\"\\UGHRR\"" - result = lexer::lex(str) - tassert(next_error(*result) == "Invalid escape sequence") - - str = "\"\\UFF0000FF\"" - result = lexer::lex(str) - tassert(next_error(*result) == "Invalid unicode sequence") -} - -def test_identifier { - var str = "foo_bar" - var result = lexer::lex(str) - tassert(next_identifier(*result) == "foo_bar") - - str = "foo bar" - result = lexer::lex(str) - tassert(next_identifier(*result) == "foo") - next_value(*result, lexer::TokenType::WHITESPACE) - tassert(next_identifier(*result) == "bar") - - str = "def foo" - result = lexer::lex(str) - next_value(*result, lexer::TokenType::K_DEF) - next_value(*result, lexer::TokenType::WHITESPACE) - tassert(next_identifier(*result) == "foo") -} - -def test_pragma { - var str = "#union" - var result = lexer::lex(str) - tassert(next_pragma(*result) == "#union") - - str = "##compiler_dep" - result = lexer::lex(str) - tassert(next_pragma(*result) == "##compiler_dep") -} - -def test_comment { - var str = "//This is a test" - var result = lexer::lex(str) - tassert(next_comment(*result) == "//This is a test") - - str = "//This - //Test - " - result = lexer::lex(str) - tassert(next_comment(*result) == "//This") - next_value(*result, lexer::TokenType::NEW_LINE) - next_value(*result, lexer::TokenType::WHITESPACE) - tassert(next_comment(*result) == "//Test") - - str = "/*This*/" - result = lexer::lex(str) - tassert(next_comment(*result) == "/*This*/") - - str = "/*Nested/*Comment*/*/" - result = lexer::lex(str) - tassert(next_comment(*result) == "/*Nested/*Comment*/*/") -} - -def test_symbols { - var str = "foo+bar" - var result = lexer::lex(str) - tassert(next_identifier(*result) == "foo") - next_value(*result, lexer::TokenType::OP_ADD) - tassert(next_identifier(*result) == "bar") - - str = "1..2" - result = lexer::lex(str) - tassert(next_long(*result) == 1) - next_value(*result, lexer::TokenType::OP_RANGE) - tassert(next_long(*result) == 2) - - // TODO add more tests -} - -def test_complex { - var str = " - type T = struct { - a: int - b: string - } - - def main(a: int, b: unsigned word) -> T { - print(\"A: \", a, \" B: \", b) - var t: T = { - a = 0, b = \"Test string\" - } !T - } - " - var result = lexer::lex(str) - //lexer::print_token_list(result) -} - -export def run_tests { - print("Running tests on Lexer...\n") - run_test("test_string_literal", *test_string_literal) - run_test("test_string_literal_error", *test_string_literal_error) - run_test("test_char_literal", *test_char_literal) - run_test("test_char_literal_error", *test_char_literal_error) - run_test("test_int_literal", *test_int_literal) - run_test("test_float_literal", *test_float_literal) - run_test("test_identifier", *test_identifier) - run_test("test_pragma", *test_pragma) - run_test("test_comment", *test_comment) - run_test("test_symbols", *test_symbols) - run_test("test_complex", *test_complex) -} \ No newline at end of file diff --git a/src/test/test_parser.pr b/src/test/test_parser.pr deleted file mode 100644 index 26ffcafe..00000000 --- a/src/test/test_parser.pr +++ /dev/null @@ -1,761 +0,0 @@ -import parser -import lexer -import vector -import util -import debug - -import test::testsuite - -export var print_ast = false - -def parse(s: &string) -> &parser::Node { - let tokens = lexer::lex(s) - let lines = util::split_lines(s) - let node = parser::parse(tokens, lines, "main", "main") - - if print_ast { - print("\n") - print(s) - print("\n") - debug::print_node(node) - } - - return node -} - -def test_identifiers { - var str = "foo" - var res = parse(str) - - str = "foo::bar::baz" - res = parse(str) - - str = "foo::bar::" - res = parse(str) - - str = "foo::bar::()" - res = parse(str) - - str = "foo::bar::(int)" - res = parse(str) - - str = "foo::bar::(int, () -> ())" - res = parse(str) -} - -def test_operators { - var str = "1 + 2" - var res = parse(str) - tassert((@res).kind == parser::NodeKind::PROGRAM) - var val = @((@res).body[0]) - tassert(val.kind == parser::NodeKind::ADD) - var left = @val.value.bin_op.left - var right = @val.value.bin_op.right - tassert(left.kind == parser::NodeKind::INTEGER) - tassert(right.kind == parser::NodeKind::INTEGER) - tassert(left.value.i == 1) - tassert(right.value.i == 2) - - str = "1 + 2 * 3 - 5" - res = parse(str) - - str = "1 << 5 + 0xFF >> 1" - res = parse(str) - - str = "0 and 2 or 5" - res = parse(str) - - str = "a == 5 and b != 6 or c <= 10 and d >= 5" - res = parse(str) - - str = "10 > a > 5" - res = parse(str) - - str = "not true" - res = parse(str) - - str = "not not true" - res = parse(str) - - str = "*foo and @bar and ~foo" - res = parse(str) - - str = "+foo and -foo" - res = parse(str) - - str = "5 !int" - res = parse(str) - - str = "5 * 5 !int" - res = parse(str) - - str = "foo[1 + 5][1]" - res = parse(str) - - str = "foo.bar.baz" - res = parse(str) - - str = "a..b" - res = parse(str) - - str = "a..=b..c" - res = parse(str) - - str = "size_of foo" - res = parse(str) - - str = "size_of type *Foo" - res = parse(str) - - str = "align_of foo" - res = parse(str) - - str = "align_of type *Foo" - res = parse(str) - - str = "type_of a" - res = parse(str) - - str = "(type type_of a)" - res = parse(str) -} - -def test_vardecl { - var str = "var foo = 5" - var res = parse(str) - - str = "const foo = 5" - res = parse(str) - - str = "var foo, bar = 1, 2" - res = parse(str) - - str = "let foo, (bar) = 1, 2" - res = parse(str) - - str = "export var foo" - res = parse(str) - - str = "export import var bar" - res = parse(str) - - str = "var foo: int, bar: int" - res = parse(str) - - str = "export let foo: int = 5" - res = parse(str) -} - -def test_typedecl { - var str = "type A" - var res = parse(str) - - str = "export type A, B" - res = parse(str) - - str = "type A = Foo" - res = parse(str) - - str = "type A = unsigned word(16)" - res = parse(str) - - str = "type A, B = int, float" - res = parse(str) -} - -def test_simple_types { - var str = "(type int)" - var res = parse(str) - - str = "(type word(16))" - res = parse(str) - - str = "(type unsigned word(32))" - res = parse(str) -} - -def test_function_types { - var str = "(type T -> F)" - var res = parse(str) - - str = "(type ->)" - res = parse(str) - - str = "(type (->))" - res = parse(str) - - str = "(type A -> B -> C)" - res = parse(str) - - str = "(type () -> ())" - res = parse(str) - - str = "(type (A, B) -> (C, D))" - res = parse(str) -} - -def test_pointer_types { - var str = "(type *A)" - var res = parse(str) - - str = "(type **A)" - res = parse(str) - - str = "(type &A)" - res = parse(str) - - str = "(type &&**A)" - res = parse(str) - - str = "(type *)" - res = parse(str) - - str = "(type &*)" - res = parse(str) - - str = "(type *let A)" - res = parse(str) - - str = "(type *var A)" - res = parse(str) - - str = "(type &let A)" - res = parse(str) - - str = "(type &var A)" - res = parse(str) - - str = "(type weak_ref)" - res = parse(str) - - str = "(type weak_ref(T))" - res = parse(str) - - str = "(type weak_ref(var T))" - res = parse(str) - - str = "(type weak_ref(let *T))" - res = parse(str) - - str = "(type weak_ref())" - res = parse(str) - - str = "(type weak_ref(let))" - res = parse(str) - - str = "(type weak_ref(var))" - res = parse(str) -} - -def test_array_types { - var str = "(type [T])" - var res = parse(str) - - str = "(type [5; T])" - res = parse(str) - - str = "(type [?; T])" - res = parse(str) - - str = "(type [let T])" - res = parse(str) - - str = "(type [5; var T])" - res = parse(str) - - str = "(type [5; [T]])" - res = parse(str) - - str = "(type [5; var [let T]])" - res = parse(str) -} - -def test_func_call { - var str = "really::long::path::foo()" - var res = parse(str) - - str = "foo(bar, baz)" - res = parse(str) - - str = "foo(bar, baz = 20)" - res = parse(str) - - str = "foo(0)(1)" - res = parse(str) -} - -def test_assign_op { - var str = "a = b" - var res = parse(str) - - str = "a, b = c, d" - res = parse(str) - - str = "a, b = c, d = e, f" - res = parse(str) - - str = "a += 2" - res = parse(str) - - str = "a *= 2 %= 3" - res = parse(str) - - str = "a ++= 2 = b += 2" - res = parse(str) -} - -def test_statements { - var str = " - var foo = 20 - foo += 10 - print(foo) - " - var res = parse(str) - - str = " - #if foo { - // Do something - } else if bar { - // Do something else - } else { - // Do more - } - " - res = parse(str) - - str = " - if foo == null { - print(\"Hello World\") - } - end - " - res = parse(str) - - str = " - if true { - // Do something - } else { - // Do something else - } - end - " - res = parse(str) - - str = " - if true { - print(0) - } else if false { - print(0) - print(1) - } else if true { - // Do more - } else { - // Or else...! - } - end - " - res = parse(str) - - str = " - if true { - print(0) - } else if false { - print(1) - } - end - " - res = parse(str) - - str = " - if must { - if go { - if deeper { - - } - } - } - end - " - res = parse(str) - - str = " - if false - { - // on new line - } - else - { - // Very ugly - } - end - " - res = parse(str) - - str = " - loop { - nop() - break - continue - } - end - " - res = parse(str) - - str = " - for var i in 0..10 { - nop() - } - end - " - res = parse(str) - - str = " - var i = 0 - for i in 0..10 { - nop() - } - end - " - res = parse(str) - - str = " - while true { - nop() - } - end - " - res = parse(str) - - str = "return" - res = parse(str) - - str = " - return 1, 2, 3 - " - res = parse(str) - - str = " - return 1, - 2 - " - res = parse(str) -} - -def test_yield { - var str = " - yield - " - var res = parse(str) - - str = " - yield 10 - " - res = parse(str) - - str = " - yield 10, - 20 - " - res = parse(str) -} - -def test_struct { - var str = " - type T = struct { - a: int - } - " - var res = parse(str) - - str = " - type T = struct { - a: int - b: struct { - a: int - } - } - " - res = parse(str) - - str = " - type T = struct #union { - a: int - b: long - } - " - res = parse(str) - - str = " - type T = struct { - a: int - struct #union { - a: int - b: long - } - } - " - res = parse(str) -} - -def test_import { - var str = "import module" - var res = parse(str) - - str = "import module as mod" - res = parse(str) - - str = "import a as foo, bar" - res = parse(str) - - str = " - import - Module as mod, - foo, - bar as baz - " - res = parse(str) -} - -def test_enum { - var str = " - type T = enum { - FOO - BAR - BAZ - } - " - var res = parse(str) - - str = " - type T = enum { - FOO = 10 - BAR - } - " - res = parse(str) - - str = " - type T = enum: long { - FOO; BAR - } - " - res = parse(str) -} - -def test_switch_stmt { - var str = " - switch value {} - " - var res = parse(str) - - str = " - switch value { - case 1: one - case 2: two - case: default - } - " - res = parse(str) - - str = " - switch value { - case 1: - print(foo) - print(bar) - case 2: - print(bar) - print(foo) - } - " - res = parse(str) - - str = " - switch value { - case 1..10: - print(foo) - case 11..20: - print(bar) - } - " - res = parse(str) - - str = " - switch value { - case 10, 20: - one - case 20..30, 30..40: - two - } - " - res = parse(str) -} - -def test_def { - var str = " - def test - " - var res = parse(str) - - str = " - def test(a: int) - " - res = parse(str) - - str = " - def test(type T, var a: int, let b: int) - " - res = parse(str) - - str = " - def test -> int, float - " - res = parse(str) - - str = " - def test() { - return - } - " - res = parse(str) - - str = " - def test(var a: int) -> int { - return a - } - " - res = parse(str) - - str = " - def test(type T = *int, a: int = 0) - " - res = parse(str) - - str = " - def test(a: type T) -> T - " - res = parse(str) - - str = " - def test(a: type [T]) -> T - " - res = parse(str) - - str = " - def test(a: type [type T]) -> T - " - res = parse(str) -} - -def test_array_literal { - var str = " - [1, 2, 3] - " - var res = parse(str) - - str = " - [ - 1, - 2, - 3 - ] - " - res = parse(str) -} - -def test_struct_literal { - var str = " - {foo, bar} !Struct - " - var res = parse(str) - - str = " - {foo, bar = 20, baz = 40} !Struct - " - res = parse(str) - - str = " - { - foo, - bar = 20, - baz = 40 - } !Struct - " - res = parse(str) -} - -def test_if_expression { - var str = " - let a = 10 if 10 > 20 else 20 - " - var res = parse(str) - - str = " - let a = 10 if 10 > 20 else 20 if 20 > 30 else 40 - " - res = parse(str) - - str = " - foo(10 if true else 20) - " - res = parse(str) -} - -def test_closures { - var str = " - def fun { - def fun { - def fun { - def fun { - - } - } - } - } - " - var res = parse(str) -} - -def test_bug_1 { - var str = " - type T = struct { - a: int - // New line here - } - type E = struct { } - " - var res = parse(str) -} - -def test_bug_2 { - var str = " - var a = 20; a += 10 - " - var res = parse(str) -} - -export def run_tests { - print("Running tests on Parser...\n") - run_test("test_identifiers", *test_identifiers) - run_test("test_operators", *test_operators) - run_test("test_simple_types", *test_simple_types) - run_test("test_function_types", *test_function_types) - run_test("test_pointer_types", *test_pointer_types) - run_test("test_array_types", *test_array_types) - run_test("test_vardecl", *test_vardecl) - run_test("test_typedecl", *test_typedecl) - run_test("test_func_call", *test_func_call) - run_test("test_assign_op", *test_assign_op) - run_test("test_statements", *test_statements) - run_test("test_yield", *test_yield) - run_test("test_struct", *test_struct) - run_test("test_import", *test_import) - run_test("test_enum", *test_enum) - run_test("test_switch_stmt", *test_switch_stmt) - run_test("test_def", *test_def) - run_test("test_array_literal", *test_array_literal) - run_test("test_struct_literal", *test_struct_literal) - run_test("test_if_expression", *test_if_expression) - run_test("test_closures", *test_closures) - run_test("test_bug_1", *test_bug_1) - run_test("test_bug_2", *test_bug_2) -} \ No newline at end of file diff --git a/src/test/test_runtime.pr b/src/test/test_runtime.pr deleted file mode 100644 index 85b43b9e..00000000 --- a/src/test/test_runtime.pr +++ /dev/null @@ -1,572 +0,0 @@ -import util -import test::testsuite - -import runtime - -def test_loop { - var cnt = 0 - while cnt < 10 { - print(cnt) - cnt += 1 - } - print("\n") - - for var i in 0..10 { - print(i) - } - print("\n") - - let foo: *int = null - while foo != null { - @foo = 10 - } - - for var i in 0..10 { - if i == 5 { continue } - print(i) - } - print("\n") -} - -type Point = struct { - x: int - y: int -} - -def test_print { - let a = 20 - let b = 0xDEADBABE !* - print("Hello World ", 1, " ", 'x', " ", 10.5, " ", b, "\n") - error("Hello World ", 1, " ", 'x', " ", 10.5, " ", b, "\n") - - let point: Point = {10, 20} - print(point, "\n") - - let array = [1, 2, 3, 4] - print(array, "\n") -} - -def pass_dynamic_array(a: string) { - print(a) -} - -def function(a: int, b: double) -> double { return a * b } -def function(b: double, a: int) -> double { return a * b } -def function -> int { return 10 } - -def test_function_calls { - pass_dynamic_array("Some string\n") - pass_dynamic_array(a = "Named parameter\n") - - function(2, 1.5) - function(1.5, 2) - function(2, b = 1.5) - function(1.5, a = 2) - // function(a = 1, b = 1.5) # Ambiguous reference - - tassert(function == 10) -} - -def test_length { - let a = "Some string" - tassert(length(a) == 11) -} - -def test_allocate { - let a = allocate(size_of int) !*int - @a = 10 - tassert(@a == 10) - free(a) - - let b = allocate(int) - @b = 20 - tassert(@b == 20) - free(b) - - let c = allocate(int, 10) - c[0] = 10 - c[9] = 20 - tassert(c[0] == 10) - tassert(c[9] == 20) - free(c) -} - -def test_file_binary { - let fp = open("tmp/test_file_io_binary", "wb+") - - let str = "Some text" - write(fp, str) - let i = 10 - write(fp, *i) - - rewind(fp) - - var str2: [10; char] - read(fp, str2) - print(str2, "\n") - - var i2: int - read(fp, *i2) - print(i2, "\n") - - close(fp) -} - -def test_file_text { - let fp = open("tmp/test_file_io_text", "w+") - - fprint(fp, "This is a test\n", 10) - - seek(fp, 0, SEEK_SET) // Same as rewind - - var buffer: [20; char] - read_line(fp, buffer) - print(buffer) - var num: int - cstd::fscanf(fp, "%d".value, *num) - print(num, "\n") - - close(fp) -} - -def test_operators { - - let g = true and false - let h = true and true - let i = false and true - tassert(not g) - tassert(h) - tassert(not i) -} - -type Enum = enum { - A = 10; - B; C; D -} - -type Enum2 = enum { - A = 10 - B = A - C -} - -def pass_enum(a: Enum) {} - -def test_enum { - tassert(Enum::A == 10) - tassert(Enum::B == 11) - pass_enum(Enum::A) - let a = Enum::A !int - let b = 10 !Enum - pass_enum(b) - - print(to_string(Enum::A), "\n") - print(Enum::B, "\n") -} - -def some_function { - print("Hello\n") -} - -def test_function_pointers { - let function = *some_function - function() -} - -type Struct = struct { - a: string - b: int - c: char -} - -def test_structs { - let s = { - c = 10 - } !Struct -} - -type Union = struct #union { - a: string - b: long - c: int -} - -def test_unions { - let u = { - "some string" - } !Union - print(u, "\n") - - let u2 = { - b = 20 - } !Union - u2.b = 120 - print(u2.c, "\n") - - let u3 = {} !Union -} - -def test_strings { - let stra = "Some value" - tassert(stra == "Some value") - tassert(stra != "Other value") -} - -def test_if_stmts { - if false { - print("false\n") - } else if starts_with("foo", "f") { - print("true\n") - } else { - print("false\n") - } -} - -def fact(n: int) -> int { - if n <= 1 { return 1 } - else { - return n * fact(n - 1) - } -} - -def test_recursion { - tassert(fact(10) == 3628800) -} - -def test_scoping { - var a = 10 - if true { - a = 10 - var a = 20 - } -} - -def pass_array(a: [int]) { - for var i in 0..a.size { - print(a[i], " ") - } - print("\n") -} - -def test_arrays { - let a = [10, 20, 30] - let b = [] ![int] - pass_array(a) - pass_array(b) -} - -type Struct2 = struct { - a: int - t: *Struct2 -} - -def test_deref { - let s = allocate(Struct2) - s.a = 10 - s.t = allocate(Struct2) - s.t.a = 20 - print(s.a, " ", s.t.a, "\n") -} - -def function(s: Struct2) -> int { return s.a } -def function(s: Struct2, a: int) -> int { return s.a + a } -def inc(a: int) -> int { return a + 1} - -def test_ucs { - let s: Struct2 = { 10, null } - - tassert(s.function() == 10) - tassert(s.function.inc == 11) - tassert(s.function(10).inc() == 21) -} - -type Struct3 = struct { - a: int - b: struct { - c: int - d: int - } - struct #union { - e: int64 - f: double - } -} - -def test_anonymous { - var s: Struct3 - s = {10, {20, 30}} - s.a = 10 - s.b = {20, 30} - s.e = 0x4034800000000000 - - print(s.f, "\n") -} - -def sum(args: int...) -> int { - var sum = 0 - for var i in 0..args.size { - sum += args[i] - } - return sum -} - -def my_print(args: string...) { - for var i in 0..args.size { - print(args[i], " ") - } - print("\n") -} - -def test_varargs { - tassert(sum(1, 2, 3) == 6) - tassert(sum([1, 2, 3]) == 6) - my_print("foo", "bar", "baz") -} - -def test_if_expression { - // TODO I've seen these fail but I can't quite pin down what's wrong with them - var a = 10 if 10 > 20 else 20 - tassert(a == 20) - var b: int - @(*a if 10 > 20 else *b) = 30 - tassert(b == 30) - - let c = { c = 10 } !Struct - let d = { c = 0 } !Struct if 10 > 20 else c - tassert(d.c == 10) -} - -import module::a as A -import module::b - -def test_imports { - tassert(A::multiply_by_2(10) == 20) - let a, b = return_multiple() - tassert(a == 10) - tassert(b == 20) - print(A::Enum::SOME_ENUM_VALUE, "\n") - - let c = {10, 10} !A::Point - let d = module::b::some_value -} - -def takes_default_param(a: int = 0, b: string = "some value") { - print(a, " ", b, "\n") -} - -def test_default_parameters { - takes_default_param() - takes_default_param(10) - takes_default_param(20, "Hello world!") -} - -def test_function_overloads { - let f1 = *function::() - let f2 = *function::(int, double) - let f3 = *function::(double, int) - - tassert(f1() == 10) - tassert(f2(10, 10.5) == 105) - tassert(f3(10.5, 10) == 105) -} - -def test_underscore { - let _, _ = 10, 20 - tassert(_ == 20) - _ = "Hello World!" - tassert(_ == "Hello World!") -} - -def function(type T) -> size_t { - return T.size -} - -def add(a: type T, b: T) -> T { - return a + b -} - -def test_def_polymorph { - tassert(function(int) == 4) - tassert(function(Struct) == 24) - - tassert(add(10, 10) == 20) - tassert(add(10.5, 20.5) == 31.0) -} - -def test_type_of { - let a = 20 - let b: (type_of a) = 30 - type T = type_of a - - tassert(T == int) - tassert((type_of b) == int) -} - -type Struct4 = struct { a: int; b: float } -type Interface = interface { - def function(a: int) -> int -} - -def function(s: Struct4, a: int) -> int { - return s.a + a -} - -def test_reflection { - type T = int - tassert(T.kind == runtime::TypeKind::WORD) - tassert(T.name == "int32") - tassert(T.unsig == false) - - tassert(Struct4.kind == runtime::TypeKind::STRUCT) - tassert(Struct4.fields.size == 2) - tassert(Struct4.fields[0].tpe == int) - tassert(Struct4.fields[0].name == "a") - tassert(Struct4.fields[1].tpe == float) - tassert(Struct4.fields[1].name == "b") - - tassert(Struct4.type_members.size == 1) - let member = Struct4.type_members[0] - tassert(member.name == "test_runtime::function::(test_runtime::Struct4, int32)") - tassert(member.parameter_t.size == 2) - tassert(member.parameter_t[0] == Struct4) - tassert(member.parameter_t[1] == int) - tassert(member.return_t.size == 1) - tassert(member.return_t[0] == int) - - tassert(Interface.kind == runtime::TypeKind::STRUCTURAL) - tassert(Interface.structural_members.size == 1) - let smember = Interface.structural_members[0] - tassert(smember.name == "function") - tassert(smember.parameter_t.size == 1) - tassert(smember.parameter_t[0] == int) - tassert(smember.return_t.size == 1) - tassert(smember.return_t[0] == int) - - tassert(runtime::implements(Struct4, Interface)) -} - -def range_for(a: int, b: int) -> int { - for var i in a..b { - yield i - } -} - -def range_while(a: int, b: int) -> int { - var i = a - while i < b { - yield i - i = i + 1 - } -} - -def test_yield { - for var i in range_for(0, 10) { - print(i, " ") - } - print("\n") - - for var i in range_while(0, 10) { - print(i, " ") - } - print("\n") -} - -type Struct5 = struct { - a: int; b: int; c: int -} - -def iterate(s: *Struct5) -> int { - yield s.a - yield s.b - yield s.c -} - -def test_generators { - let s = { 10, 20, 30 } !Struct5 - - for var i in *s { - print(i, " ") - } - print("\n") -} - -def test_closures { - def inner(a: int) -> int { - def inner -> int { - return a - } - return inner() - } - tassert(inner(10) == 10) - - var a = 20 - var b = 30 - def capture { - tassert(a == 20) - let local = *b - @local = 40 - tassert(@local == 40) - } - capture() - tassert(b == 40) -} - -export def run_tests { - print("Running tests on runtime... \n") - run_test("test_imports", *test_imports, "0\n", "") - run_test("test_loop", *test_loop, strip_margin("\ - |0123456789 - |0123456789 - |012346789\n"), "") - run_test("test_print", *test_print, strip_margin("\ - |Hello World 1 x 10.500000 0xdeadbabe - |{x = 10, y = 20} !test_runtime::Point - |[1, 2, 3, 4]\n"), - strip_margin("\ - |Hello World 1 x 10.500000 0xdeadbabe\n")) - run_test("test_function_calls", *test_function_calls, strip_margin("\ - |Some string - |Named parameter\n"), "") - run_test("test_length", *test_length) - run_test("test_allocate", *test_allocate) - run_test("test_file_binary", *test_file_binary, strip_margin("\ - |Some text - |10\n"), "") - run_test("test_file_text", *test_file_text, strip_margin("\ - |This is a test - |10\n"), "") - run_test("test_operators", *test_operators) - run_test("test_enum", *test_enum, strip_margin("\ - |A - |11\n"), "") - run_test("test_function_pointers", *test_function_pointers, "Hello\n", "") - run_test("test_structs", *test_structs) - run_test("test_unions", *test_unions, strip_margin("\ - |{a = some string, b = 12, c = 12} !test_runtime::Union - |120\n"), "") - run_test("test_strings", *test_strings) - run_test("test_if_stmts", *test_if_stmts, "true\n", "") - run_test("test_recursion", *test_recursion) - run_test("test_scoping", *test_scoping) - run_test("test_arrays", *test_arrays, "10 20 30 \n\n", "") - run_test("test_deref", *test_deref, "10 20\n", "") - run_test("test_ucs", *test_ucs) - run_test("test_anonymous", *test_anonymous, "20.500000\n", "") - run_test("test_varargs", *test_varargs, "foo bar baz \n", "") - run_test("test_if_expression", *test_if_expression) - run_test("test_default_parameters", *test_default_parameters, strip_margin("\ - |0 some value - |10 some value - |20 Hello world!\n"), "") - run_test("test_function_overloads", *test_function_overloads) - run_test("test_underscore", *test_underscore) - run_test("test_def_polymorph", *test_def_polymorph) - run_test("test_type_of", *test_type_of) - run_test("test_reflection", *test_reflection) - run_test("test_yield", *test_yield, strip_margin("\ - |0 1 2 3 4 5 6 7 8 9 - |0 1 2 3 4 5 6 7 8 9 \n"), "") - run_test("test_generators", *test_generators, strip_margin("\ - |10 20 30 \n"), "") - run_test("test_closures", *test_closures) -} diff --git a/src/test/test_typechecking.pr b/src/test/test_typechecking.pr deleted file mode 100644 index b5be90ba..00000000 --- a/src/test/test_typechecking.pr +++ /dev/null @@ -1,711 +0,0 @@ -import vector -import map -import util -import lexer -import parser -import typechecking -import compiler -import scope -import builtins -import debug -import codegen -import toolchain -import consteval -import errors - -import test::testsuite - -type Result = struct { - module: &toolchain::Module - node: &parser::Node -} - -def typecheck(s: &string) -> Result { - toolchain::outfolder = "./build" - errors::error_count = 0 - - let main = "main" - let tokens = lexer::lex(s) - let lines = util::split_lines(s) - let node = parser::parse(tokens, lines, main, main) - let module = toolchain::make_module( - text = s, - lines = lines, - filename = main, - modulename = main, - node = node, - scpe = scope::enter_function_scope(builtins::builtins, null) - ) - toolchain::modules[main] = module - module.scope.module = module - consteval::consteval(module) - typechecking::typecheck(module) - - toolchain::load_file_type() - // TODO This is a bit besides the point of testing typechecking seperately - compiler::compile(module) - - return { module, node } !Result -} - -def test_vardecl { - var str = " - var foo: byte = 5 - " - var res = typecheck(str) - let v1 = (@scope::get(res.module.scope, parser::make_identifier("foo"))).tpe - tassert(v1 == builtins::byte_) - - str = " - var bar: long - let foo, (bar) = 0, 1 - " - res = typecheck(str) - let v2 = (@scope::get(res.module.scope, parser::make_identifier("bar"))).tpe - let v3 = (@scope::get(res.module.scope, parser::make_identifier("foo"))).tpe - tassert(v2 == builtins::long_) - tassert(v3 == builtins::int_) -} - -def test_vardecl_fail { - var str = " - const a, b = 20 - var c, d = 10, 20, 30 - var c = 10 - var e, (c) = 10 - var f: int = \"string\" - " - var res = typecheck(str) -} - -def test_var_let { - var str = " - let a: *let int = null - a = null - @a = 20 - " - var res = typecheck(str) - - str = " - var a: [let int] - a[0] = 20 - " - res = typecheck(str) - - str = " - var a: [4; let int] - a[0] = 20 - " - res = typecheck(str) -} - -def test_literals { - var str = " - let v1 = \"string\" - let v2 = 'c' - let v3 = 0.0 - let v4 = 0xFF - let v5 = false - " - - var res = typecheck(str) - let v1 = (@scope::get(res.module.scope, parser::make_identifier("v1"))).tpe - let v2 = (@scope::get(res.module.scope, parser::make_identifier("v2"))).tpe - let v3 = (@scope::get(res.module.scope, parser::make_identifier("v3"))).tpe - let v4 = (@scope::get(res.module.scope, parser::make_identifier("v4"))).tpe - let v5 = (@scope::get(res.module.scope, parser::make_identifier("v5"))).tpe - - tassert((@v1).kind == typechecking::TypeKind::ARRAY) - tassert((@v1).tpe == builtins::char_) - tassert(v2 == builtins::char_) - tassert(v3 == builtins::double_) - tassert(v4 == builtins::int_) - tassert(v5 == builtins::bool_) -} - -def test_assign { - var str = " - var foo = 5 - var bar = 10 - - foo, bar = 10, 20 - - def function -> int, int { - return 0, 0 - } - foo, bar = function() - " - typecheck(str) -} - -def test_assign_fail { - var str = " - var v - let foo = 20 - foo = 40 - var bar: int - bar = \"string\" - " - var res = typecheck(str) -} - -def test_operators { - var str = " - let foo = 0 - let bar = -foo - let baz = +50 - " - - // TODO This doesnt really test anything, we need to inspect the nodes - var res = typecheck(str) - let v1 = (@scope::get(res.module.scope, parser::make_identifier("foo"))).tpe - let v2 = (@scope::get(res.module.scope, parser::make_identifier("baz"))).tpe - tassert(v1 == builtins::int_) - tassert(v2 == builtins::int_) - - str = " - let v3 = 10 + 20 - let v4 = v3 + 0 !short - let v5 = 0 !long - 0 !int - let v6 = 0 !long & 0 !int - " - res = typecheck(str) - let v3 = (@scope::get(res.module.scope, parser::make_identifier("v3"))).tpe - let v4 = (@scope::get(res.module.scope, parser::make_identifier("v4"))).tpe - let v5 = (@scope::get(res.module.scope, parser::make_identifier("v5"))).tpe - let v6 = (@scope::get(res.module.scope, parser::make_identifier("v6"))).tpe - tassert(v3 == builtins::int_) - tassert(v4 == builtins::int_) - tassert(v5 == builtins::long_) - tassert(v6 == builtins::long_) -} - -def test_operators_fail { - var str = " - var a = 0 !float - var b = 1 - var c = a & b - var d = \"string\" - var e = not d - " - var res = typecheck(str) -} - -def test_def { - var str = " - def foo {} - " - var res = typecheck(str) - - str = " - def foo - def foo {} - " - res = typecheck(str) - - str = " - def foo {} - def foo(a: float) {} - " - res = typecheck(str) -} - -def test_def_fail { - var str = " - def foo {} - def foo {} - " - var res = typecheck(str) - - str = " - def foo { - export var foo: int - export def nested_function {} - } - " - res = typecheck(str) -} - -def test_def_polymorph { - var str = " - def function(type T) -> T { - var t: T - return t - } - function(int) - " - var res = typecheck(str) - - str = " - def function(a: type T) -> T { - return a - } - function(10) - " - res = typecheck(str) -} - -def test_typedecl { - var str = " - type A = int - type B = A - - var a: B = 0 - " - var res = typecheck(str) - - str = " - type A - type A = int - //type module::A - //type module::A = int // No longer allowed - " - res = typecheck(str) -} - -def test_typedecl_fail { - var str = " - type A = int - type A = float - var B = 0 - type B = int - " - var res = typecheck(str) -} - -def test_struct { - var str = " - type A = struct { - a: int32 - b: int64 - c: int16 - d: int8 - } - type B = struct { - a: int8 - b: int16 - } - type C = struct { - a: int16 - b: int8 - c: int32 - } - " - var res = typecheck(str) - var s1 = scope::get_type(res.module.scope, parser::make_identifier("A")) - tassert((@s1).size == 24) - tassert((@s1).align == 8) - var s2 = scope::get_type(res.module.scope, parser::make_identifier("B")) - tassert((@s2).size == 4) - tassert((@s2).align == 2) - var s3 = scope::get_type(res.module.scope, parser::make_identifier("C")) - tassert((@s3).size == 8) - tassert((@s3).align == 4) - - str = " - type A = struct #union { - a: int8 - b: int32 - c: int64 - } - " - res = typecheck(str) - var s4 = scope::get_type(res.module.scope, parser::make_identifier("A")) - tassert((@s4).size == 8) - tassert((@s4).align == 8) -} - -def test_import { - var str = " - import test::module::a - test::module::a::multiply_by_2(4) - multiply_by_2(10) - multiply_by_2(10.5) - " - var res = typecheck(str) - - str = " - import test::module::a - def multiply_by_2(a: int) -> int { - return a * 2 - } - multiply_by_2(10) - test::module::a::multiply_by_2(10) - multiply_by_2(10.5) // module::a - " - res = typecheck(str) -} - -def test_import_fail { - // TODO Fix this - // We print too many errors - /*var str = " - import test::a - import test::b - multiply_by_2(10) - multiply_by_2(10.5) - " - var res = typecheck(str)*/ -} - -def test_return { - var str = " - def foo -> int { - return 0 - } - " - var res = typecheck(str) - - str = " - def foo -> int, bool { - return 0, true - } - def bar -> int, bool { - return foo() - } - " - res = typecheck(str) -} - -def test_return_fail { - var str = " - def foo -> int, bool { - return false, 'c' - } - " - var res = typecheck(str) -} - -def test_pointers { - var str = " - let a = 10 - let b = *a - let c = @b - " - var res = typecheck(str) - let a = (@scope::get(res.module.scope, parser::make_identifier("a"))).tpe - let b = (@scope::get(res.module.scope, parser::make_identifier("b"))).tpe - let c = (@scope::get(res.module.scope, parser::make_identifier("c"))).tpe - tassert(a == builtins::int_) - tassert(typechecking::equals(b, typechecking::pointer(builtins::int_))) - tassert(c == builtins::int_) -} - -def test_pointers_fail { - var str = " - let a = 10 - let b = @a - " - var res = typecheck(str) -} - -def test_member_access { - var str = " - type T = struct { - a: int - b: double - } - var foo: T - let a = foo.a - let b = foo.b - " - var res = typecheck(str) - let a = (@scope::get(res.module.scope, parser::make_identifier("a"))).tpe - let b = (@scope::get(res.module.scope, parser::make_identifier("b"))).tpe - tassert(a == builtins::int_) - tassert(b == builtins::double_) - - // TODO Test error messages -} - -def test_array_subscript { - var str = " - var a: [4; int] - let b = a[2] - - var c = 10 - var d = *c - let e = d[2] - " - var res = typecheck(str) - let b = (@scope::get(res.module.scope, parser::make_identifier("b"))).tpe - let e = (@scope::get(res.module.scope, parser::make_identifier("e"))).tpe - tassert(b == builtins::int_) - tassert(e == builtins::int_) -} - -def test_array_lit { - var str = " - let a = [1, 2, 3, 4] - let b: [int] = a - " - var res = typecheck(str) - let a = (@scope::get(res.module.scope, parser::make_identifier("a"))).tpe - let b = (@scope::get(res.module.scope, parser::make_identifier("b"))).tpe - tassert((@a).kind == typechecking::TypeKind::STATIC_ARRAY) - tassert((@a).tpe == builtins::int_) - tassert((@a).length == 4) - tassert((@b).kind == typechecking::TypeKind::ARRAY) - tassert((@b).tpe == builtins::int_) -} - -def test_array_inference { - var str = " - let a: [?; int] = [1, 2, 3, 4] - let b: [int] = [1, 2, 3, 4] - " - var res = typecheck(str) -} - -def test_array_inference_fail { - var str = " - let a: [?; float] = [1, 2, 3, 4] - " - var res = typecheck(str) -} - -def test_array_size_and_value { - var str = " - let a = [1, 2, 3, 4] - let b: [int] = a - let c = a.size - let d = a.value - let e = b.size - let f = b.value - " - var res = typecheck(str) - let c = (@scope::get(res.module.scope, parser::make_identifier("c"))).tpe - let d = (@scope::get(res.module.scope, parser::make_identifier("d"))).tpe - let e = (@scope::get(res.module.scope, parser::make_identifier("e"))).tpe - let f = (@scope::get(res.module.scope, parser::make_identifier("f"))).tpe - tassert(c == builtins::size_t_ and e == builtins::size_t_) - tassert(typechecking::is_pointer(d) and typechecking::is_pointer(f)) - tassert((@d).tpe == builtins::int_ and (@f).tpe == builtins::int_) -} - -def test_call { - var str = " - def demo_function_1 - def demo_function_2(a: int) - demo_function_1() // empty function - demo_function_2(42) // function with unnamed parameter - demo_function_2(a=42) // function with named parameter - " - var res = typecheck(str) -} - -def test_call_fail { - var str = " - def demo_function_2(a: int) - demo_function_2(a=42, a=11) // function with named parameter twice - " - var res = typecheck(str) - - str = " - def no_return - var a: int - a = no_return() - " - res = typecheck(str) -} - -def test_yield { - var str = " - def some_function -> int { - yield 20 - yield 30 - return 40 - } - for var i in some_function() { - print(i) - } - " - var res = typecheck(str) -} - -def test_closure { - var str = " - def some_function { - def inner_function { - - } - } - " - var res = typecheck(str) -} - -def test_closure_fail { - var str = " - def some_function { - export def inner_function {} - def inner_function(a: int = 20) {} - def inner_function(a: int...) {} - } - " - var res = typecheck(str) -} - -export def run_tests { - toolchain::no_incremental = true // TODO Temporary - toolchain::include_path.push("src") - - toolchain::prepare_preload() - toolchain::create_types_main() - - print("Running tests on Typechecking...\n") - run_test("test_vardecl", *test_vardecl) - run_test("test_vardecl_fail", *test_vardecl_fail, "", strip_margin(" - |main@2:9 - | const a, b = 20 - | ^~~~~~~~~~~~~~~ - |Unbalanced assignment - | - |main@4:13 - | var c = 10 - | ^~ - |Redeclaration of `c` - | - |main@5:16 - | var e, (c) = 10 - | ^~~~ - |Must assign a value - | - |main@6:14 - | var f: int = \"string\" - | ^~~~~~ - |Incompatible types [char] and int\n")) - run_test("test_var_let", *test_var_let, "", strip_margin(" - |main@3:9 - | a = null - | ^~ - |Assignment to non var - | - |main@4:9 - | @a = 20 - | ^~~ - |Assignment to non var - | - |main@3:9 - | a[0] = 20 - | ^~~ - |Assignment to non var - | - |main@3:9 - | a[0] = 20 - | ^~~ - |Assignment to non var\n")) - run_test("test_literals", *test_literals) - run_test("test_assign", *test_assign) - run_test("test_assign_fail", *test_assign_fail, "", strip_margin(" - |main@4:9 - | foo = 40 - | ^~~~ - |Assignment to non var - | - |main@6:9 - | bar = \"string\" - | ^~~~ - |Incompatible types, can't assign [char] to int - | - |main@2:14 - | var v - | ^ - |Need to specify a type\n")) - run_test("test_operators", *test_operators) - run_test("test_operators_fail", *test_operators_fail, "", strip_margin(" - |main@4:17 - | var c = a & b - | ^~~~~ - |Invalid operands of type float and int to bitwise operator - | - |main@6:17 - | var e = not d - | ^~~~~ - |Incompatible type [char], must be boolean type\n")) - run_test("test_def", *test_def) - /*run_test("test_def_fail", *test_def_fail, "", strip_margin(" - |main@3:13 - | def foo {} - | ^~~~ - |Function `foo` was already declared previously (same arguments) - | - |main@3:20 - | export var foo: int - | ^~~~~~~~~~~~ - |Can't share non top level variable - | - |main@4:20 - | export def nested_function {} - | ^~~~~~~~~~~~~~~~~~~~~~ - |Can't share non top level function\n"))*/ // TODO - run_test("test_def_polymorph", *test_def_polymorph) - run_test("test_typedecl", *test_typedecl) - run_test("test_typedecl_fail", *test_typedecl_fail, "", strip_margin(" - |main@3:9 - | type A = float - | ^~~~~~~~~~~~~~ - |Redeclaration of `A` - | - |main@5:9 - | type B = int - | ^~~~~~~~~~~~ - |Redeclaration of `B`\n")) - run_test("test_struct", *test_struct) - run_test("test_import", *test_import) - run_test("test_import_fail", *test_import_fail) - run_test("test_return", *test_return) - run_test("test_return_fail", *test_return_fail, "", strip_margin(" - |main@3:13 - | return false, 'c' - | ^~~~~~~~~~~~~~~~~ - |Wrong type of return argument, got bool, expected int - | - |main@3:13 - | return false, 'c' - | ^~~~~~~~~~~~~~~~~ - |Wrong type of return argument, got char, expected bool\n")) - run_test("test_pointers", *test_pointers) - run_test("test_pointers_fail", *test_pointers_fail, "", strip_margin(" - |main@3:17 - | let b = @a - | ^~ - |Needs to be a pointer or reference type, got int\n")) - run_test("test_member_access", *test_member_access) - run_test("test_array_subscript", *test_array_subscript) - run_test("test_array_lit", *test_array_lit) - run_test("test_array_inference", *test_array_inference) - run_test("test_array_inference_fail", *test_array_inference_fail, "", strip_margin(" - |main@2:14 - | let a: [?; float] = [1, 2, 3, 4] - | ^~~~~~~~~~~~~ - |Incompatible types [4; int] and [?; float]\n")) - run_test("test_array_size_and_value", *test_array_size_and_value) - run_test("test_call", *test_call) - run_test("test_call_fail", *test_call_fail, "", strip_margin(" - |main@3:31 - | demo_function_2(a=42, a=11) // function with named parameter twice - | ^~~~ - |Cannot have the same parameter name multiple times in a function call. Parameter name was `a`. - | - |main@4:9 - | a = no_return() - | ^~ - |Incompatible types, can't assign void to int\n")) - run_test("test_yield", *test_yield) - run_test("test_closure", *test_closure) - run_test("test_closure_fail", *test_closure_fail, "", strip_margin(" - |main@3:24 - | export def inner_function {} - | ^~~~~~~~~~~~~~~ - |Invalid modifier to closure - | - |main@4:32 - | def inner_function(a: int = 20) {} - | ^~~~~~~~~~~ - |Can't have default parameters for closure - | - |main@5:32 - | def inner_function(a: int...) {} - | ^~~~~~~~~ - |Can't have varargs for closure\n")) -} \ No newline at end of file diff --git a/src/test/testsuite.pr b/src/test/testsuite.pr deleted file mode 100644 index 8a800080..00000000 --- a/src/test/testsuite.pr +++ /dev/null @@ -1,374 +0,0 @@ -import util -import parser -import vector -import map -import debug -import io - -#if not defined WIN32 { - import linux -} else { - import windows -} - -import test_json -import test_getopt -import test_lexer -import test_parser -import test_typechecking -import test_compiler -import test_runtime -import test_ctfe -import test_vector as test_vec -import test_expr_eval - -export var match_string: &string = "*" -export var fork_process: bool = true -export var capture_stdout: bool = true - -def print_divider(c: char) { - let termsize = util::get_terminal_size() - for var i in 0..termsize.col { - print(c) - } - print("\n") -} - -let stdout_file = "tmp/stdout.txt" -let stderr_file = "tmp/stderr.txt" - -var test_count = 0 -var failed_test_count = 0 -// Shared memory -var asserts: *int - -export def tassert(cond: bool) { - asserts[0] += 1 - var stream = debug::stdout_orig - if not capture_stdout { - stream = std::stdout() - } - if not cond { - cstd::fprintf(stream, "x".value) - asserts[1] += 1 - } else { - cstd::fprintf(stream, ".".value) - } - cstd::fflush(stream) -} - -export def run_test(desc: &string, function: def () -> (), expected_out: &string, expected_err: &string) { - if not util::match(match_string, desc) { - return - } - - test_count += 1 - - var num_printed = print(">", desc, " ") - cstd::fflush(std::stdout()) - - if capture_stdout { - io::redirect_stdout_to_file(stdout_file) - io::redirect_stderr_to_file(stderr_file) - } - - #if defined WIN32 { - asserts = allocate((size_of int) * 2) !*int - } else { - asserts = linux::mmap(null, (size_of int) * 2, 3 /*PROT_READ | PROT_WRITE*/, 33 /*MAP_SHARED | MAP_ANONYMOUS*/, -1, 0) !*int - } - asserts[0] = asserts[1] = 0 - - var segfault = false - - #if defined WIN32 { - function() - } else { - if fork_process { - let pid = linux::fork() - if pid == 0 { - function() - exit(0) - } - - var status: int - linux::waitpid(pid, *status, 0) - if status & 0x7f == 11 /*SIGSEGV*/{ - segfault = true - } - } else { - function() - } - } - - - var out_ok = true - var err_ok = true - var err: &string - var out: &string - - if capture_stdout { - io::restore_stdout() - io::restore_stderr() - - let stdout_fh = open(stdout_file, "rb") - out = read_all(stdout_fh) - close(stdout_fh) - - let stderr_fh = open(stderr_file, "rb") - err = read_all(stderr_fh) - close(stderr_fh) - - out_ok = out == expected_out - err_ok = err == expected_err - tassert(out_ok) - tassert(err_ok) - } - - let assert_count = asserts[0] - let failed_assert_count = asserts[1] - - #if defined WIN32 { - free(asserts) - } else { - linux::munmap(asserts, (size_of int) * 2) - } - - num_printed += assert_count - let termsize = util::get_terminal_size() - let spacing = termsize.col - num_printed - 13 - - if spacing > 0 { - for var i in 0..spacing { - print(" ") - } - } else { - print("\n") - } - - if segfault { - print("[ \x1B[31mSEGFAULT\x1B[0m ]\n") - } else { - print("[") - cstd::printf("%2d/%-2d".value, assert_count - failed_assert_count, assert_count) - if failed_assert_count == 0 { - print(" \x1B[32mOK\x1B[0m ") - } else { - print(" \x1B[31mERROR\x1B[0m") - } - print("]\n") - } - - if capture_stdout { - if not out_ok { - print_divider('-') - print("Expected standard out:\n") - print(expected_out, "\n") - print("Actual standard out:\n") - print(out, "\n") - print_divider('-') - } - - if not err_ok { - print_divider('-') - print("Expected standard error:\n") - print(expected_err, "\n") - print("Actual standard error:\n") - print(err, "\n") - print_divider('-') - } - } - - if failed_assert_count > 0 or segfault { - failed_test_count += 1 - } -} - -export def run_test(desc: string, function: def () -> ()) { - run_test(desc, function, "", "") -} - -def test_vector { - var vec = vector::make(int) - vec.push(0) - vec.push(1) - vec.push(2) - - tassert(vec[0] == 0) - tassert(vec[1] == 1) - tassert(vec[2] == 2) - - vec[0] = 3 - - tassert(vec[0] == 3) - - vec = vector::make(int) - var vec2 = vector::make(int) - - for var i in 0..5 { - vec.push(i) - vec2.push(i) - } - - vector::insert(vec, 2, 10) - vector::insert(vec, 2, vec2) - - // TODO actually verify this -} - -def test_split_lines { - var str = "this\nis\na\ntest" - var res = util::split_lines(str) - - tassert(res.size == 4) - tassert(res[0] == "this") - tassert(res[1] == "is") - tassert(res[2] == "a") - tassert(res[3] == "test") - - str = "this is a test" - res = util::split_lines(str) - - tassert(res.size == 1) - tassert(res[0] == "this is a test") - - str = "this\r\nis\r\na\r\ntest" - res = util::split_lines(str) - - tassert(res.size == 4) - tassert(res[0] == "this") - tassert(res[1] == "is") - tassert(res[2] == "a") - tassert(res[3] == "test") -} - -def test_find_substr { - var str = "foo%%bar%%baz" - tassert(util::find_substr(str, "banana", 0) == -1) - tassert(util::find_substr(str, "%%", 0) == 3) - tassert(util::find_substr(str, "%%", 4) == 8) -} - -def test_replace_all { - var str = "foo%%bar%%baz" - tassert(util::replace_all(str, "%%", ", ") == "foo, bar, baz") - - str = "%%" - tassert(util::replace_all(str, "%%", "") == "") -} - -def test_util { - print("Running tests on Util...\n") - run_test("test_split_lines", *test_split_lines) - //run_test("test_int_to_str", *test_int_to_str) - run_test("test_find_substr", *test_find_substr) - run_test("test_replace_all", *test_replace_all) -} - -// TODO these tests don't nearly cover all cases -def test_map_simple { - let m = map::make(int) - m["foo"] = 20 - m["bar"] = 50 - - tassert(map::size(m) == 2) - tassert(m["foo"] == 20) - tassert(m["bar"] == 50) - - map::remove(m, "foo") - tassert(map::size(m) == 1) - tassert(not map::get(m, "foo").exists) -} - -def test_map_collision { - let m = map::make(int) - m["JUvEoj"] = 20 - m["JVVdoj"] = 50 - - tassert(map::size(m) == 2) - tassert(m["JUvEoj"] == 20) - tassert(m["JVVdoj"] == 50) - - map::remove(m, "JVVdoj") - tassert(map::size(m) == 1) - tassert(not map::get(m, "JVVdoj").exists) -} - -def test_map_resize { - let m = map::make(int, 2) - m["1"] = 1 - m["2"] = 2 - m["3"] = 3 - m["4"] = 4 - - tassert(map::size(m) == 4) - - tassert(m["1"] == 1) - tassert(m["2"] == 2) - tassert(m["3"] == 3) - tassert(m["4"] == 4) -} - -def is_in(array: &[&string], key: &string) -> bool { - for var i in 0..array.size { - let value = array[i] - if value == key { - return true - } - } - return false -} - -def test_map_keys { - let m = map::make(int) - m["JUvEoj"] = 20 - m["JVVdoj"] = 50 - m["foo"] = 0 - m["bar"] = 1 - - let keys = map::keys(m) - tassert(keys.size == 4) - tassert(is_in(keys, "JUvEoj")) - tassert(is_in(keys, "JVVdoj")) - tassert(is_in(keys, "foo")) - tassert(is_in(keys, "bar")) -} - -def test_map { - print("Running tests on Map...\n") - run_test("test_map_simple", *test_map_simple) - run_test("test_map_collision", *test_map_collision) - run_test("test_map_resize", *test_map_resize) - run_test("test_map_keys", *test_map_keys) -} - -export def run_test_suite { - #if defined WIN32 { - windows::CreateDirectoryA("tmp".value, null) - } else { - linux::mkdir("tmp".value, 0o777) - } - - //run_test("test_buffer", *test_buffer) TODO Write a test for std - run_test("test_vector", *test_vector) - - test_util() - test_map() - - test_json::run_tests() - test_getopt::run_tests() - test_lexer::run_tests() - test_parser::run_tests() - test_typechecking::run_tests() - test_compiler::run_tests() - test_runtime::run_tests() - test_ctfe::run_tests() - test_vec::run_tests() - test_expr_eval::run_tests() - - print_divider('=') - print("Finished. Succeeded: ", test_count - failed_test_count, "/", test_count, "\n") - if failed_test_count > 0 { - exit(1) - } -} \ No newline at end of file diff --git a/src/testrunner.pr b/src/testrunner.pr index ca7e19b6..b02b4f93 100644 --- a/src/testrunner.pr +++ b/src/testrunner.pr @@ -172,7 +172,7 @@ for var i in 0..files.length { let lib = shared::load(dll_file, init = false) // We only want the symbol information for var symbol in @lib.symbols { - if symbol.name.starts_with("__test::") { + if symbol.name.starts_with("__test::") and std::match(filter_str, symbol.name) { tests_to_run.push(symbol.name) } } diff --git a/src/toolchain.pr b/src/toolchain.pr index ad2618b6..2e202e8f 100644 --- a/src/toolchain.pr +++ b/src/toolchain.pr @@ -91,8 +91,11 @@ export const version = create_version_string() // Debug stuff export var print_ast = false export var print_tokens = false +export var print_typed_ast = false +export var continue_on_output = false // This flag controls emitting debug information to llvm export var debug_sym = false +export var main_file_name: &string = null var main_module_file: &string @@ -278,7 +281,7 @@ export def find_module_file(path: &string, calling_module: &Module) -> &string { } if not path.starts_with("/") and calling_module.filename { - let base = util::dirname(calling_module.filename) + let base = dirname(calling_module.filename) let module_path = absolute_path(base + "/" + path + ".pr") if util::exists(module_path) { return module_path @@ -352,7 +355,7 @@ export def create_module_if_absent(filename: &string, modulename: &string) -> &M return module } -export def consteval_file(filename: &string, modulename: &string) -> &Module { +export def consteval_file(filename: &string, modulename: &string, display_name: &string = null) -> &Module { var module: &Module if modules.contains(filename) { module = modules[filename] @@ -365,15 +368,30 @@ export def consteval_file(filename: &string, modulename: &string) -> &Module { module = create_module_if_absent(filename, modulename) module.stage = Stage::PREPROCESS + if display_name { + module.filename = display_name + } debug::trace("Lexing ", modulename) let tokens = lexer::lex(module.text) - let node = parser::parse(tokens, module.lines, filename, modulename) + let node = parser::parse(tokens, module.lines, filename, modulename, display_name = display_name) delete(tokens) module.node = node module.compiler_state = compiler::make_state(module) + let filename_type = typechecking::make_static_array(builtins::char_, filename.size) + let exe_global = compiler::make_global_value( + filename_type, "__file__", + { kind = compiler::ValueKind::STRING, tpe = filename_type, s = filename } !&compiler::Value, + module.compiler_state, private = false + ) + let exe_value = scope::create_variable( + module.scope, make_identifier("__file__"), + parser::ShareMarker::EXPORT, parser::VarDecl::LET, filename_type, null + ) + exe_value.assembly_name = exe_global.name + consteval::consteval(module) return module @@ -558,7 +576,7 @@ export def compile_main_file(filename: &string) { error("File ", filename, " is not a Princess source file\n") exit(1) } - include_path.push(absolute_path(util::dirname(filename))) + include_path.push(absolute_path(dirname(filename))) if print_ast or print_tokens { let buf = file_loader(filename) @@ -571,13 +589,14 @@ export def compile_main_file(filename: &string) { let tokens = lexer::lex(buf) if print_tokens { print(json::to_string(lexer::token_list_to_json(tokens)), "\n") - exit(0) + if not continue_on_output { exit(0) } } let node = parser::parse(tokens, lines, filename, "main") delete(tokens) + if error_count > 0 { exit(1) } print(json::to_string(debug::node_to_json(node)), "\n") - exit(0) + if not continue_on_output { exit(0) } } @@ -587,7 +606,7 @@ export def compile_main_file(filename: &string) { create_types_main() main_module_file = filename - var module = consteval_file(filename, "main") + var module = consteval_file(filename, "main", display_name = main_file_name) if not module { exit(1) } module.stage = Stage::RESOLVE_DEPENDENCIES @@ -596,6 +615,12 @@ export def compile_main_file(filename: &string) { module.stage = Stage::TYPECHECKING typechecking::typecheck(module) + if print_typed_ast { + if error_count > 0 { exit(1) } + print(json::to_string(debug::node_to_json(module.node, types = true)), "\n") + if not continue_on_output { exit(0) } + } + load_file_type() module.stage = Stage::COMPILING diff --git a/src/typechecking.pr b/src/typechecking.pr index b0b5f0a8..7f41e8fd 100644 --- a/src/typechecking.pr +++ b/src/typechecking.pr @@ -3461,6 +3461,8 @@ export def walk_Def(node: &parser::Node, state: &State) { imported = imported } !&compiler::Function node.value.def_.function = function + } else { + function.tpe = tpe } var phase = scope::Phase::DECLARED @@ -3527,6 +3529,8 @@ export def walk_Def(node: &parser::Node, state: &State) { } if function.has_yield { + // FIXME generators should be a separate type + // because this overwrites return_t, which might contain useful information let generator_ctor = { kind = parser::NodeKind::TYPE_CONSTRUCTOR } !&parser::Node diff --git a/src/util.pr b/src/util.pr index 12d6564f..905b1aa8 100644 --- a/src/util.pr +++ b/src/util.pr @@ -114,32 +114,6 @@ export def split(str: &string, by: &string) -> &[&string] { return res.to_array() } -export def dirname(file: &string) -> &string { - var last_slash = -1 - for var i in 0..file.size { - let c = file[i] - if c == '/' or c == '\\' { - last_slash = i - } - } - let ret = allocate_ref(char, last_slash + 2) - memcopy(file.value, ret.value, last_slash + 1) - return ret -} - -export def basename(file: &string) -> &string { - var last_slash = 0 - for var i in 0..file.size { - let c = file[i] - if c == '/' or c == '\\' { - last_slash = i - } - } - let ret = allocate_ref(char, file.size - last_slash) - memcopy(file.value ++ last_slash, ret.value, file.size - last_slash) - return ret -} - export def exe_folder -> &string { return dirname(executable_file()) } @@ -231,31 +205,6 @@ export def get_terminal_size -> TermSize { } -// https://stackoverflow.com/a/23457543/3258949 -// TODO This algorithm is very inefficient - -def match(pattern: &string, candidate: &string, p: int, c: int) -> bool { - if pattern[p] == '\0' { - return candidate[c] == '\0' - } else if pattern[p] == '*' { - while candidate[c] != '\0' { - if match(pattern, candidate, p + 1, c) { - return true - } - c += 1 - } - return match(pattern, candidate, p + 1, c) - } else if pattern[p] != '?' and pattern[p] != candidate[c] { - return false - } else { - return match(pattern, candidate, p + 1, c + 1) - } -} - -export def match(pattern: &string, candidate: &string) -> bool { - return match(pattern, candidate, 0, 0) -} - export def bytes_in_glyph(c: char) -> int { if c & 0b10000000 == 0 { return 1 diff --git a/src/getopt.pr b/std/getopt.pr similarity index 99% rename from src/getopt.pr rename to std/getopt.pr index 8bca7ae0..cdcaf9c9 100644 --- a/src/getopt.pr +++ b/std/getopt.pr @@ -1,8 +1,9 @@ // TODO This needs to be tested, and reworked +import cstd +import std import map import vector -import util export type ValueKind = enum { STRING diff --git a/std/std.pr b/std/std.pr index 1aa9621e..0ac36864 100644 --- a/std/std.pr +++ b/std/std.pr @@ -222,6 +222,31 @@ export def strip_margin(s: &string) -> &string { return res } +// https://stackoverflow.com/a/23457543/3258949 +// TODO This algorithm is very inefficient + +def match(pattern: &string, candidate: &string, p: int, c: int) -> bool { + if pattern[p] == '\0' { + return candidate[c] == '\0' + } else if pattern[p] == '*' { + while candidate[c] != '\0' { + if match(pattern, candidate, p + 1, c) { + return true + } + c += 1 + } + return match(pattern, candidate, p + 1, c) + } else if pattern[p] != '?' and pattern[p] != candidate[c] { + return false + } else { + return match(pattern, candidate, p + 1, c + 1) + } +} + +export def match(pattern: &string, candidate: &string) -> bool { + return match(pattern, candidate, 0, 0) +} + export type ToString = interface { def to_string -> &string } @@ -772,6 +797,32 @@ export def system(command: &string) -> int { return cstd::system(command.value) } +export def dirname(file: &string) -> &string { + var last_slash = -1 + for var i in 0..file.size { + let c = file[i] + if c == '/' or c == '\\' { + last_slash = i + } + } + let ret = allocate_ref(char, last_slash + 2) + memcopy(file.value, ret.value, last_slash + 1) + return ret +} + +export def basename(file: &string) -> &string { + var last_slash = 0 + for var i in 0..file.size { + let c = file[i] + if c == '/' or c == '\\' { + last_slash = i + } + } + let ret = allocate_ref(char, file.size - last_slash) + memcopy(file.value ++ last_slash, ret.value, file.size - last_slash) + return ret +} + export def executable_file -> &string { let resolved = zero_allocate(char, PATH_MAX) defer delete(resolved) diff --git a/test/common.pr b/test/common.pr index f32328a4..b7b52165 100644 --- a/test/common.pr +++ b/test/common.pr @@ -7,7 +7,10 @@ import process cstd::_setmode(2, 0x8000) } -export def run_compiler(file: &string, str: &string, args: &string) -> &string { +export let tmpfolder = tmpfolder("princess") + +export def run_compiler_on_source(str: &string, args: [&string]) -> &string { + let file = tmpfolder + "/main.pr" let fh = open(file, "w") fprint(fh, str) fh.close() @@ -15,16 +18,23 @@ export def run_compiler(file: &string, str: &string, args: &string) -> &string { return run_compiler(file, args) } -export def run_compiler(file: &string, args: &string) -> &string { +export def run_compiler(file: &string, args: [&string]) -> &string { let r, w = io::pipe() var compiler: &string = runtime::executable let env = cstd::getenv("PRINCESS_COMPILER".value) if env { compiler = make_string(env) } + let res = allocate_ref(type &string, args.size + 2) + res[0] = file + res[1] = "--no-incremental" // TODO Enable incremental compilation + for var i in 0..args.size { + res[i + 2] = args[i] + } + let proc = *process::spawn( - compiler, - [file, args] ![&string], + compiler, + res, stdout = w ) proc.wait() @@ -41,4 +51,47 @@ export def run_compiler(file: &string, args: &string) -> &string { let ast = r.read_all_pipe() close(r) return ast +} + +export def test_file(name: &string) -> &string { + return dirname(__file__) + "/runtime/" + name +} + +export def executable(name: &string) -> &string { + #if defined WIN32 { + return name + ".exe" + } + return name +} + +export def compile_source(src: &string) -> int { + return run_source(src, run = false) +} + +export def run_source(src: &string, run: bool = true) -> int { + let file = tmpfolder + "/main" + let fh = open(file + ".pr", "w") + fprint(fh, src) + fh.close() + return run_file(file, run) +} + +export def compile_file(name: &string) -> int { + return run_file(name, run = false) +} + +export def run_file(name: &string, run: bool = true) -> int { + let src = name + ".pr" + let exe = executable(name) + + let res = run_compiler(src, ["-o"! &string, exe]) + if not res { return 1 } + + if run { + let proc = *process::spawn(exe, [] ![&string]) + proc.wait() + proc.dispose() + return proc.exit_code + } + return 0 } \ No newline at end of file diff --git a/src/test/module/a.pr b/test/runtime/module/a.pr similarity index 100% rename from src/test/module/a.pr rename to test/runtime/module/a.pr diff --git a/src/test/module/b.pr b/test/runtime/module/b.pr similarity index 100% rename from src/test/module/b.pr rename to test/runtime/module/b.pr diff --git a/test/runtime/test_imports b/test/runtime/test_imports new file mode 100644 index 0000000000000000000000000000000000000000..fcb65634ad930a3ad3e4416c266fc107af47bfea GIT binary patch literal 251336 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

dn5V8wKE7$*vddJSA^lDYU$lKAKh^KC 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 Y27j8bVuv9R760l-7@cHAur8hd2a39--v9sr literal 0 HcmV?d00001 diff --git a/test/runtime/test_imports.pr b/test/runtime/test_imports.pr new file mode 100644 index 00000000..739adec6 --- /dev/null +++ b/test/runtime/test_imports.pr @@ -0,0 +1,14 @@ +import module::a as A +import module::b + +def test_imports { + assert A::multiply_by_2(10) == 20 + let a, b = return_multiple() + assert a == 10 + assert b == 20 + print(A::Enum::SOME_ENUM_VALUE, "\n") + + let c = {10, 10} !A::Point + let d = module::b::some_value +} +test_imports \ No newline at end of file diff --git a/test/runtime/test_reflection b/test/runtime/test_reflection new file mode 100644 index 0000000000000000000000000000000000000000..ab76c653d1804cb9c62a46510208bdbf5169e409 GIT binary patch literal 253816 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 literal 0 HcmV?d00001 diff --git a/test/runtime/test_reflection.pr b/test/runtime/test_reflection.pr new file mode 100644 index 00000000..c92f9242 --- /dev/null +++ b/test/runtime/test_reflection.pr @@ -0,0 +1,43 @@ +type Struct4 = struct { a: int; b: float } +type Interface = interface { + def function(a: int) -> int +} + +def function(s: Struct4, a: int) -> int { + return s.a + a +} + +def test_reflection { + type T = int + assert T.kind == runtime::TypeKind::WORD + assert T.name == "int32" + assert T.unsig == false + + assert Struct4.kind == runtime::TypeKind::STRUCT + assert Struct4.fields.size == 2 + assert Struct4.fields[0].tpe == int + assert Struct4.fields[0].name == "a" + assert Struct4.fields[1].tpe == float + assert Struct4.fields[1].name == "b" + + assert Struct4.type_members.size == 1 + let member = Struct4.type_members[0] + assert member.name == "main::function::(main::Struct4, int32)" + assert member.parameter_t.size == 2 + assert member.parameter_t[0] == Struct4 + assert member.parameter_t[1] == int + assert member.return_t.size == 1 + assert member.return_t[0] == int + + assert Interface.kind == runtime::TypeKind::STRUCTURAL + assert Interface.structural_members.size == 1 + let smember = Interface.structural_members[0] + assert smember.name == "function" + assert smember.parameter_t.size == 1 + assert smember.parameter_t[0] == int + assert smember.return_t.size == 1 + assert smember.return_t[0] == int + + assert runtime::implements(Struct4, Interface) +} +test_reflection \ No newline at end of file diff --git a/test/runtime/test_vector b/test/runtime/test_vector new file mode 100644 index 0000000000000000000000000000000000000000..e7cb4a5287a9b1d6914e4eebdccc02777c62f37d GIT binary patch literal 261360 zcmeFad3>Ey`@X$9+|&?_A=RP;MGPfMD2h~DQd)wd#zwUjv_xCf99nd%A*L!G#9S0H zR~4yNcg-=^9CJbubB%qEbDb->2=)KwbpsAwe~$_-+RZogNE$c zu|tPU>rcnbZW(RmuTdIO{x_4U`=wLZ)<310zL{0{w`XR(%nEFG4mnj+EB#lj>=-sP zt+9(YGg4E(nXx{zV<}tOE>%F;KdrHKgo^5y{**>^T)K)kTVp2Q+v=AH<8~&$R9kG9 zhOq4^9!P6!ZP(^k69-zeM`)jkv9gCZTVwlvTALa7x!;VZ+^;omSm%Cyzlbx7<5Fw& zn;HAfjQv_;vE?$Yv2{JQCi?$^SYObwlr3$SDr5$Rf77V8`YHcn;wbU#IKSC(UafIR zShP&0HMaKKpMDzW|LITbvL6urmbWgg`$=nztCQJg>~SM^*nXR_qk4}$?!;3j^`6vs zhu%AEzx9NZw(b+=y%qz}KDF1r2W77Os^rJbPJUpm&z||X^py<{JEi3BZmVnD8iVxI zMn7sFmn-B|YxPt8|Kz8f4r~0EhF6mNZ~3#9lV3=F_5Y%C*mBx;UykpL<>>sr9Gy3p zlYe44`5%{)ziB!7y_Pf1j?2lHEGIu}Ir-*_)@-HtZKVmugm6tQl_m|WDpyjl$Urzgrmygkbv$pI88PD6aVMQPV#36u$4?wFLX~kU>>#R|SUG<5(WA6otnFjQpI#Nau{CO} z&j{d{F~^B_%#0a#^d$Z{?!?gCLgP*tHF5N~s?3;^sz#rfnJ{tuiN|Pb;^?tsGsuq} zd(ttPqeq@Jej>F|^c+9>wBt@3rG^tv8k-q&?C6OTGRL?Xxv^-BnJ{|v32J@PDHAi} zMvptD>h#Q*W5%8|VRUAk8%nq8=!unTG+j@Cdl;1MIV0&$_n9nC-|oETfuZ#4BWlUT)x znZ1S#-ebUsK3n(Mx}=S_-M$UC<3-_2=>K(Uqt?v7qgr<6TKeDHb>IxTE^0d07V`g7 z);Vq^ooSC^f6z|{coebqdT{j>)47Z!nd7M|x8`xj<>^XxO5Aq;j&1!HKeLBq+U`5T z2LCj+%dgm)BsR6ncWsw%X_qf(mtWd0zj3>K_j>zEJ5D833)|&euO%uJwae=|)B01~ zE*~$gq13lszWsHzv|YaSTCWae?eZ*e+fRAB{K{?FOlEkye7r>p)rxj`o$FeED%<6G zLE3(*+T~Yk%Vsi@+T~kcTa~NZ<=Y?kQ`_a+pGRxj<=1SdKcih<*ZS6<+IIPFtx4j{ zcKNm2_XiGcVn5H)@~%zx;n!;Qy|`|L<4er>^V&Q8sx=m$GTe zCl7SYlwD9ivE#CavdIg&%nxg`tmISD%QpF(f4go_3TeAiwdTfU{A}``wslEtZV212 zYg?DX=K8Sxg0^)DY_1F2&uUx0jy2bY?K#@krLegsY(J!JT>_h{!}dMe)@8T3Ds11X zZCwhRE5i2m+SVnoxjbxNscl{QnoGm>#oE>-uemsEpRa9Q>Y59~_8HpNC9XL?Y>(Hr zE^W=3uzkF?b?eaF@(+nkMrvD^xaP*NeVDd&X=`o>+XrY{m$c^ku)Vjobt!AE3)_2W zTbHor+OWN|wsi~ATobnYXj_-E=IXG$g|>AGYpx308);jYuI7rcy^gkZ$!abS+iPfB zm#XH{u)VUjb%|;&4%;2ItxHpLVc7oTeztW14$i)IR9W`ZvdN#fln)!6 ztIu4pN2V+{uV#uuuJEb;nPmm{@D9b#HEKV9%+_5u&@WJ#OwH{2aRV}CyXxPGYtB|m zyVOe0D6y<@OwIf;X=CkAPlxvBeHTKurEK1JyO+&d+NrF=!m`)?nYenJ!irJhfA*Ju z^{&4h#twGMng^9-zi2vx7inSg8JP}8&i`M2YX8l}=@{7eyO(9p>eZzzJF!=O*)-8K zsOcwOVh)4u?Ix%3(!NsdhpT->ZeXurnqzC6Hl)|EvS|Z*Rg@j`e09GrMO`n@j<|4O zuLCp9x{8<4VEAkuEZO?9&F9f_SlLdCx?Wk|tHV?pUCjTd&a3{U!_*jmMk z(7vLUlj}QV3H*OZ^Hogpf00Hb( zw`v`x#<%$*vRjprE>v0&Zs3^RR_c~(s{d=*vN9U+GU^|wP%kL|@KTW~Wv^1}?6Xay zW795W#|%M~Y~jMrU9=?9QrGTE^3O2(PhL9sqRwmIs>YVLR5FLHbcXza4jJ$F0A$ES%D7X=~e-(98XrT6x+fp3pHK#E@y%&7d?S zdjv~*>3a2LK=;AZI=?@7+K~6V^uKu6`}u>XO?;o!S??DPoi_0OqM;OuhfW*ze&3TmeSgoW6T9$pJmj*fY>M+1EnrVDxG}G7^_g5NX zYt$l!7hqa-EooXc5?Fu_2>PKeWDy$)T`xV5YmOGEfi3-r7a0TBx8rcyiEZlIt}(JVT;jp8h#CZosIEh@>-B0~!!G|{*HGiu8fwg1!}<`X^wLgd3{PvQp`~j!wK{Cho*J|2R5tCAAkwsS>9S>$mu9+NpsONNy_}F~)+Oy? z&wKl2oUfcGqq0v2m-M;}{?`uQypUS~Elo8Q{ph%z6kyuiIH*U$Ae(N{p^+Wdt4fDo zr4B#-8KTWgdR40@=}AiS&s=ACjhj?qcU+9jXh|C#LbWgQlk?c@b+JEn*98q=nz1G@Q3+H!&)?SEPo7^*G~N6!4=!>ie%|WjeW) z>*Q9}^a~>48nPEB=e@RH)_Qv0vu&{PLNvNVbGX+C>I_V0PD1k`oT-0h8m$+dFgLvk zDepz{=0MUpr`<{nY7-BwwWF)GTA^9WB>F|0e$2nL>!mtWG`HfA9@49yn(L(Y?}-(w zO;P(c4eI!>$rowz#hQFk(^9Ho@|!XF&CZWts`m*yD=z?+h{AM;=Pwf`bNxr!&yM0}UwpQt_ zN!JYqGHdQNnsl$xqC;b;cK@aAZb@pmA1PCtQnl%;a;XlQzPhdWZx>qKNaHqnLD_sa z)`5Oa{r1b+Mjh8`hYroUqN`Egvergnm3Ls3cWB+gO4|BKnc1ew8pgEDE*;wKG21V< z_2j;sZ=&^f9h!AN9mY4g?<&kA_-=>qcCEgB{-xA@Mw9z?XgBk1+u99kmGt^dD=jYD zrGIhPDbchz)2y53V0v+B_t5C#!QG1&ZQmid7vo->&Tewwj_q8wX>-wyv=>$e;gy&+ zxVUU{y&CO%uh6dd)@{8HNPFuwoK{-M7z^9R*gMm_S=wR}$ADg(X;no{zx=&S=VWeQ z80J=idPBY2TPAG_yyd?ZctwU1dThxFV9VAMKwOqB{?)WgYttvX*yr>nxQm!94_8(zls&>Y_G6f`Za{(md+dg%T#tm(SUc-{2muuj_? z+YQ4f25fykTCe$Z&PS~~Q3YdLi?QX$vE?(iwYpw9uHD$U-z}}wwPRYpMPZj?3giZp zYbcwx{cB}2n%?3}6~@z*@pMhcv)cdLc=A1-{N@W7PZ(qzRCQf&54&hKaJqm0&-2%L zOBSm!Hz?sG&Pg=H)-#Itp-XzbN~5;1Xx|GbPIaBHyN7x}KhMnOpQd+Obf*w+eNa?V z+x3dvdIg8<5Oy`XYJB<;&olEA;IGg)3tB2!$$fKhZs;^R=bA+GTQ`Lu|Vn$d)m|@LIT8^-M*6$kql3m`*PI zx)B>pO&e6VVd*4SOXIvsE8})WjB!$>aZaUWF<%;EoKR`8=Tlm!{K8VrrZi5bw2N}N zj6&N~&RejU&G}<$vP*Rbv~=?KUAtcNOlZLt_eRfk;e!dw8t3%q{p{Jg-IzaT&lL9& z>OG_RbM_bN;F>>Yc$z&b#Zf|C+~?0ZS*UT$pL4oU``!FGlZARiY5tr`gm$|k#pyy_ z+~?1^MQFE~LU(&GZTpxo=#B~3^YW&9=s28TC;f(ruH9VPCvsH}bvFOHU|H8Go6{;B zavaNl@hf%LDI5Je)3NK6@TSg&q~~n)EH0jZpA`EFJ-FS49!A@HHNmgly+qsnM*H#n z&-y|A59xn!|AYDu(=WpMb&dCfsu3^C?UmnmzT!nw8Br-XIQMLM2z%srS)k4HRp}bA zzA%K+{KX+wtMVZ@B%7Q+xDyBSu9F?6DCCl(2}LLJ&QdPf7sOY%3)tP+BCw;g1>kDW zX(&lYkYD>U3zMJ9=tZWH*n$!GGN?x`gLC1)Y2Y2Iq1io(hGYxA+NTpEDQF_lZV)0} zP7dCE!05dJm~nR1H2XW6{p|fEXzzC*2`wNNy7(Zds|_v}+iV(PaBf}|^})IR`9%vA z&(pf}28U$x#(Ol&Bx2tsU>wc6V7{{p!MG9+gGbr07W8PYfV2|l5KCP=0n|z`nzcNd zf)Mh$+4BwReXU-v-ZVwvKCsBy>%r)G5qK0Mrolweo}(do9zZO0ad$9!&fc4K&hGjI zfqBl+RxY`Vdb!oFR&RTrCjnTNjYd4xTWwC7Rw zJd=8*)hpH8o(F-$o!tYBp4))WSav!ga1$A9O`Y=gndmbJ_$q^1m z5(ejTEwmoYnX&G9#c*bPF5rTO5V%jPc|oNqy|hrb!)3YpIt6ZLmdb$ZX61`YhjZkK z!fbN?d0{#OaM2HAD+Vj?4eQqvjMG^eJT3H2emkgjI!%zK^A>Tui_e0dPI9=Uv&j*5 z*cO3FmR&!UT?MRicB#ZXgfGBzt@k?UwVSUxW_83fUA!?Carvh@m@QM_@j|Hg&o6sP z^9|>|VZv;(nn&{|?c#i!z~P}?@)j5ezk=KSL`L@bHiAdG-OFv+{$;fqeKzkhQZ%}X z5!HA;)f%t6jsvTmJq(OH-(KKFp2+r~XSoTaS*}5x?BcRvaSYjH5-x*t3#%B$;M|`1 zMK3FcLuYGnXm(GoIVJnt5!RrTOc}SXOUt+jEY*e=BJ+y!c|+&YDx2)9kV{UWPnV_v z!r@>X_aHFiY@al{0l2zEa>=To$Nl&19{1P8&Mv+K>h1`$mM4SR4+^~^Va zA(-!MUYh*_kqxZ(m88*Im@J00NY4=qTzm-BT?uAa+3aeYZHQKpWmijO|D<`LvrQ87 z>+}}5rS+Z#ZT7J0nAH+DcJWfsr-Qs5Y__A#{-V&=vd!vd*|))BXXmHcI<>XljiAjg zQysH2iQBkX3F>B$nY}wFEaQ6$xkT$*X4wVmX0r#uQfF^Uv(vzV)|&*{>^RjCI+)nc z#Q|WP*;&CX?`(UXW6yi3S6F?9dfW2?u-w`4VBEh)fCpH12x!k;A$e{=EOT*fFurt! zHrvo<7gDIQ>;!eQSp`_>?9ep3GdRk6n}Ig#t~zE3@n9E!yp8LXS9AUoTFtx#3fvdc zrrNUms+-Mr0Vg?Ilx7RSan|by+UzHkW!6Znbn#`-=aalKHapg4{peL=+09egZs1gB zJEhqcL{7EdhoH?~fn@e1@njcgg3)Xxo2_g!t#7SmJEyWg(0qooA4$yfeGxp@db2^B z-K{!i(}`!eI2nv)vu1~7ywBl&gbhwld8g1YT#oJwTgnr#eD~#A{s4i$%<)+w5AKokgL^ zvd5{L%?<_|ogI*7i@{s0*AukaYN})Q=dGPGH@esas)*T6Hrv@|THmFX9jIxW&BVfmuP*vG!GDNkjkzKW}N+9VjjYm z;KSB?1N6)ms7~((iTAsB6By0TwOO^zw7%Uf`-i$&_A4;o**DYdJaDe{?gwplv+9^# zLVVoC)4^!Ak$Zzpw*@6zd zvfNm846k!Zrx23Pez_k+XzAAj^kUou#&J#q8=aj5>SmJ$qro}BAvpl_I0rx)XEE_% z7kh$ww*~7vSq-f33Tsm`)8TF}(K$5h{!OqxK_WI84rZJk1V-yVV9x3rfVR$uWc~NU zoib0m_%-Oeje>oGSu(_ChtjslvU{qV&9(yzoh?kWd0>O}{y@)W-#{{3OnlMB=RhAr z1>ezy+tKd{gLCs6sq1NfEiQxk6|lBJH@e|hzy||9S0BQl{7J8=a)Ey5nF_| z&pNB=wZZXAY|1>yH#7(jy&f!f_C7GK)Aitc9^FNthdv3?&_@&BbnyVt`)$F2HXCNM zc@&0Q_I`D<*$rU1vs2UTDc}{18tIXs%??zZOeyga7kh(YopR^TM6XH*K(^qg2eo8* zpHrmy6*qUvRM_DhF#4XLtdE!BV7%fE0+;xZ=mXk!V@SUF#4la^`=-`O=3OY4Y@#*6 zQ*)r{Xqry4=K<>Nx$X{DI=dAZJ$ryRcseV9_WTV4d45j3#>LlC&n;}WrOis|HPy1c z!DzM)SnceJY4&GCZnNGepv_)~WcCd4W*2A0B2#+#p)j*o6mrSBXw9%}msIu_n%6k{ zsl+_rSHb(NH#h1nOzu-1q3elvxp)y6Pjywn<+*wlvSWMImgU%!U)PQh_T=+~*`b_z zdfya=mE7!5>(QM}=(1#h26{Xg$8iX_)T0{+#&zEotO?S|`kx9`rHpXa|BSZm+4!06ine9RO7?#5Q%k0JTKM10W2 zC%||eecfhnDCCkN1PX0d07kQpV0UM~mzam}0eHRV@jU2B&QTqqyNFl2cr_Sbf>UgE zs?9nfTWr}Db+hb;V3D&gq}j*8+pTvyXtQfn$LxIKO)j1UMziiV>tVBxD3n_EMRl{; zY_PAhccj@X!TYRtE@-nV)iFDgIMc+|cZ-Oea zjCVW`R`X7UTrz-OQ!QHzMzfw^wX-Xy+20Upu-@lUZ(;HlqzOJte9^@Rz&OD&n+J^CfVmvrnYiJHgMacNJ)}DXJrMGVvo9j{@TaFSl8Z&0eNZZ`nEOX0yA%+0I^_ zX3qncSnov8W+PO`YzXly7k2`qSs$BiXS10U8Z3K_y4mb}aFMeorP(9EU#vG6wAs$8 zW40Nw#l^M2X!h29VHw|6$R%3eM$1;Io6U{{7dyLmn%xmxX1!jZ%?eaUs3Y-r7r(!u z?KPWZv(p{Uu;(E(U264#>TS<$!6s+d2jhOS3fSe1aObfUS$j4^@_d`v$;J6#oZx!F zEa_>pJ`(tLfabaZ7|m7%GtT}lF%RKOa1HCd0orVV>hyk)xT=dcfpMpNW|mensaMD) zdB}FR>>ui8*{{HSXWvY-^T3|gyC1aK&8j1G39*}tr-Q!7&Knub@{VyBWzSEj7hC-m z^|t4eV4<@!!MK{&fSX$Oe9)c~AbD00H*|3*7*}%zo2_WGxfDt*d$+pTY&zK2*~w|P z3f#eZM}junS9Q#GA#UMf5vVUGa1OisUae-{Jr4IOxX{dfW4Ou*}&*z&OEy z-~h{R3)*udNS}?a zAZW9Js$;e-ah!|m$0ED_1~x0SnbvoaWzSGIn;i?*J3B1R_6N_f-qxVaHc%b2Rf(s# z`1^Hj$M&-`!!piS$R%3e#g;ut-E6i8*x>9oX?8vE0_&{=+UyUMW%d>E92egN8Z z&BoYF>)T}6;#9UL*y!xaY4$fnYOMD;XtTEX_X~yxPT!!FW*LdzY56U{(lu_bG6HLOuVx0m6^f+v+cY z8E2mW<5}xY@Gi?<1=@28B+rwHH@SEe7@x50XR~sfy-cCdvUAkUW_N+zoxM8Eo(I-h z??ljMBUHz12=QJQcLL)z;Kw^P!MvXwepcZ9W$JycewljP^GvYF*-9`@@F4JM%kBZ% zb2~_$g~Uf(%md>Smg%?*&OO&iVF7bBH?x)Y< z&I5%vfN@Au!3JkfNwXuthY_LeexQd`sydn8#5-JE2h?*I%x;?-%x+i6C0PnhmOWM7 zJpW_BMrX^@?5^Om*4qNK*}AGD)P?xCi@)&TPrut@wx`YZve_uwEVbSnXuz!qn> zOtam=SFM+THv3hN6fygZxX{H0P zv|b}I~NZF z<4gC(oUod2D&&&qDU@3FF?F-qZD3z#Ytro5;Hqzho$`3lW{0beP#N)Wo0Wk2{unbm z6&J#3HoKidxn-|VH=CUUmN~2E=P|42=iO|k=jS%tL3PYFCg!`C59&;ZOAni^W3zK9 zR9JSby4mbdaJaL2ejc-WeqLxjJwLbE>Z)V*4^R8naq$~4n$3M8%gE>8zfg$E=>8Z(%(>KeyQuJyJyIU1Bd67p7(-Y*yiLv^}>*XR6iLP1U=Albrnp zfw-T13YJ**RnVUGkUZ}rZtddrpe|CZW+$6gEZ42G%&+kY=9(ceCC- zpv`Vj9kZ##om@Nx)HxipJ9z|2xXVu>Kc_I$vahL|&7KBpoz?U6nAP+1y{xC_=QcZ4 zb*@Kq&GuIvv)zdMxVR-4 z&6e;~kePk!hl5(*MV7rt-E1}ytanz=&tq24&kwVno}b%nE7dXUK^*4d3SitRFSl8Z z&9uIYEjv=(Y_=cR;H;jX$E=>8kFuVgpWAFj)iL||HatnO+Y^L>XvTXQp zg3a{#ghpre{5+cJ`T2>~)AMtieG19!Rbr)!b5pao!n32^Z~JMH)_198!-o@Wrq3s| zIIGVmM6-{<)2;UsXtSqO$Lt>Bco(k))U08aKQ;5POzCipOA4@pHGNp zbHFLqy9>104An8afOxixsw^m@ZkiT>GKJN&g%0C(X0xbVZ9?ko9(MQX1frt zaTS>6z%pmI1fyqn@P5lCpgn($4?#a8-sNIL>UlSh ztXR~0{N!qPdR1C>D=?b%04tnbA!3Bs zvMZ*tKhwO**-s?q`Mv@^YrQ8yo6S-kv+IaYx_BWNSMz(G8Sxykfr6eNPJO%W`Qepd zd`kE_jhMck2_mF*sj>G{(zf?KV70T?f^n^{9hzo$R@Qo(fi~-|I%Wy+78ifyQF=6cl7~agY_6XX9Zj2h%kHagHroZ9?QBt+ zEdU>~UPsVoKcOtMM&c|NUk2kc9%Zu;Hq-hxSa$PNwi~#}*-mM;1(CVd`w+C*E0D~d zBtGWiOfZ^tuvtf&X?+_l+c}l}f#!>y{YYY-?~C9<>&*sjcDL%7O()j7I2nv)xASm_ zWxT`TPCqL8hWb*gFII1>KL<8B`w$p+%A3JgEqe)Q&$A(U9#4G1#Y4b&OqSVfu+0`y z=(1wCUOcRBHme0Q&R&{k&j8=G-m##~hO3U*AmSS?_5tGrzu|ce6I|l(t)JdpPrcCU z7pb>BCxZFT9u39`?hAfy*2Y(&^^Sz zY<4XeXEw=Zr`t^HTVdIs)XlPu;BaSOPP22sJe%DG+H8jEm|Z|z!Nu`le9hLi*?JB= z?fD+{NmkFPw>=*LE1kUsjQh!D;M$fw6SU`8NS=ohS9ftwFi!B9`&p@MQm>Fp9;GnV zvbU<6%`OM4ojohf9tUn@y@NrU?WHm~|y?>f&E~W`#acwq7G> zv)3S*Jx%QA;=Q0gTaL>Rn+E3gF-I(jzW`V-&Z%U<|44s*+8%OT@Ko;T6KiR5f69qFfi^e zSK-1uueRCq6qZ`{F?F-qZD5PDHEH&2@ObMT58CW-)iEn0j&ZRh7IE3ZW;@#Kb_!j( zge!tRUlh&s`J#-o`g~E$>hne8t*6fy*=z^ZG1G^OPIOV9FH#Y+cX>EOc+by>w7%Uf zJ67F1vqQmrXZK9A+kt0TuMo7^>Z)V*4x5%=4shiEV2Me9u zFwL$8o^QQBqu#<~2_&<3iRZYuFg4r2W`#D>`u4T#MyYI9u-MtZB<3MBgVU_{cGO## zpR@Ci`C6@cn&Og_MtR;GkA;jE&*+Jw(6K2PrS~>L%?|Q>SD8% zY^L?CwCuy`X0uwb!r4pH>>1#F);kuo*>Ke{8$`Ur#Xev(yO)PUEaNOcBhva#vg~E* zX0tQFDrYOx>_Omc>+J#BY&+F4DV4&sE!fYV<@P*@#5WoCSVw+3P@iUJS|eG~#D2 zjso>;oz?u1M@58>96t7gBYnQD$?E$2RrJ*7uNFJ2&tFAPeg5hn%j)x2_B;xbr#^i3 zlZ*QNRh;K}a^d^U_MB|bTI!jV!nyiV_4Yi^09)*NEEqk9fh#W#w}AaYd-j3kxq;fb zxGETrj!o>jsm;!$kZ&`6{wkX3^H*J*)#tBbR-eBru%14DWwSihG1G^yR&!CGzlul4 zA|6@r>w7T;{rcV%V)*#)cOW0|JvN*edRF?x@GZ?7R}E8tFMZgN0~b5{NSeI`{LO}! zfga7dsxz9g#2;Ne6!iJE=gKx)C73;%|E|_;kNia;hL4KB1v02LJep-3%=$rZ3HWYk zm+0AgJ3WfOkg*5njMTS=5!3t+_jGho&wG4g z?-`!QXM3(}Gd)kMvFur3G&>HQ>g>U3b^usly<*U2;gJt!dft=oqMrA}mo7Yy&(#;J zz*md)*EaOk;-=6re6{$SfTcxLbehuniRGW-GsjMd&h$7o1>@+}1ZOy#0pq%Vi|d9S zznr+z*so8fluXFZ&iTR~p1paKjM?st2 zsXAs?5x;k_8jMTvybcoX|H*{8<`U`ETUvTiT6&rH!%KQAXlY4GT6#+@Jr0cX(6ev8 zz+I?b{27y(TH?ka5tjJ3fc2RVBwCtZA7ZGy9dKS_2>tVCe5e-T8_>50e6~)3zW`RR zlUU_PDu3Mk&&6Sol>cz?SXO{6>@!33mrh$*T|0jgxMi1|6`c!re z=f8Kr_(CoKhdcWq7KQWySPafU?|kb)hgQzw%?f z4B@l?CxJt1^Sgr;^%m-C*#*7xd`0a?Ixz}?f?+(>+t%Lrww*x!n<99N(pGcLpK+)jGb12M%$&VW4;8JkzILeK81mo4EQjK%TL4+c= z+XEcucH4lyFqBld-B3cY+wBaV=5{(qdTIG92HJ)6SD-lH_`6Ao?$r9 zc0G+J?s^(erL(=#?CRi!Hu#6V(7WFE+BF&Q2gGw-)VVV*x$oCY;{AGG1gb5od(LRK z1~|#tWfJpjmVj4U?_JPlFQ|^$>FS_+Uvnu%iagt^Cn21(}>euoCNx4PjtV|YHHu3%~up=TJ}wKv)Meb)>(btDrR+V zy4QO8yp_#PR~?}-#M@mw5R9v-*8(%G9c`YaFx#>ZsGH4nuB&rapSOxxU2~qWo<477 zvtg&jD;UMsvawAJ0WH&g!{H96~4XJL|QeXEQw-k=ZN6CKsOs z!`(r)_XphUVD_QIM+BN~j837|^HcS|>6P#7*I=CBJK!IdT>#osZ{5pN@7w?AqTaXn zdF}%3uGPAJbG_sJ2Nw85`EuITUB+&tifprG`tC$`u*%o`1dQfC^84$pzO3s@Z8mR+ zztlcOoZ;dBqH|ezCK9Um*@a?<;iqR9E3d z?<;r!*Fu{86yiUg{mEdvgSC3KaIoq-8*TelHks;U_mu0&+G!*h{r3YG`JT2P82vW~ zSMxn>H_-koLh}FlIx;SP0?MCL(iXT7^qB?Pl+$*&&308cA4gk&<<731W;=sxc(Ol8 znzjp*Pa&DTN?g^&xnTUI?`0m*Vy4dy=sr5s`6F>5h8yLtKpK1)8YC|e^n>2x;5XL0 z9gO$-`Yu1kX9?b!5`B-q#qIPxehrFy@v>@-KARk=_UVy(4SnVGz$RzMr`Zu;f%S%fHrrKo zgtj2A=Hl95G^^(nh1om;@Ao|Gt@+yGI!Lqb-NI>jv_x!u0GM%hcThVoZMOn9w0aNF z)+_i^M#HPr<&{dlj@jl zX6boIE?EiLGRyv|ZkGKFEOoXa%{~PVwB9|S&2CT~p{c}vE}jBLvwdy0pUt$s!!7%o zy4mb$u-w^u)9egzf9qWU+U!)-F*}A>=3+S*kGdbYPVmzG=FRCIG2kR;4+NuU zDLC4)y+M1f56N>C;s_U)X4^b>vYEbX&UAONX9Z1btv*z}?YT2p~$?ILfZx5C`yCE1~ z^3}jwto|qJUj8MJtluTx;Nrs6THpO;@_j=n(07+vetprH5$qDSO8SM6?5e=u1;nG) z&da3i@yMjgS@~#XX)B-mZ22(g@!Sq+JXa9!aPb^4p2qZ@TE^29LV>;z%y_;gFrIJ1 zR>_hOl5Z7q$qV#twDaRqwzEv?oRv=;k9?l6@s2jK2Q?OKDDnEEo@qQ^A-0O{il)`woNT+n@NXi(7-b z)xbsHK_%!rqXd1&lcv+DXS#<2VX}IAu2o=*M{*<>J@*E4p3aV-J&PcD77(9uu_Nf; z5AyWgP1auDwZv23J*DaK)VtgB5cRg_K(LFm+k(+^eeiY5t^(TguVd`lOnlMBw?Q5L zxad2NcF}JTHl?dX%8ezt-eC4{u8~5ooxi;1YZW5EIS9Z=e>|TXAm1*ya3b=gv{csGC>w6|l_NC)4aq@K@_y1KR9D)e)LNT;gH{7+=BtZFYdoUZqfB*|}ge zyBi$t?DRA{8O(ehZcwX0n;oq>X8RKVu-PtPT+N?ngqi)Kz~}ZTR9W^~b@R-ofR)ak zoMw*#SGL(cpw0TJj?m`HxY!MhW;ffcHiUv(ymhOsPovokn~ai(t@j73o!t$Lr^qeA z0;_iiZM_mC>t9E5Z|ve{VBAFq;=*1t$Yux7cBW-_S2vq&1=c#-Bh9V=ZeYEi(6ia+ zkj!2q_HglOFwXOIlsuZtUW9 zV4T^-Hk)R%F32vj>@VtO*-ycGXJ1XTbHNhp-3{98det$zh`6OlDLzL`+@POYnUGP&DR`WSK#+*>Md5kUA^sj z1=#59Ibb}}PXPC}>~PSYgCTkDKpf=a#-JZy7G`Q5B z2Y}IYckn>VZUx%2CnV36iTk?v+tF>F-EG#xVI6ypplP8!hp4wbcLMXB-4u+TYl25u zHUrx82Mpx-5%CZgUraq0@cTVywC5ZaI^-1i{SS>YoAdyq^$K9Ivp=B|55-1sl+|Ab zZT&PP>wAe6F3yNWJdd;4@eU{0Q{%3%`nT%s>AnY+JDUUJbRPjvwCpXQJ+Fl1c`mWi z#j#*KA`609(k+C7wH>+>xFhMIE$(w@U1P6@rR5RSf>q953d)PNXMm^KvU<^YYbTH?15k$K`B^mlio4A zFj*hc2v#AU>EhCgwh^2hJd^SEoZv9g)`!xg$tHVB#Maw^4bB#V@g>g#vsV8Dbua%n zkgOLIr?~hW7$@J&)@z4Q(A}X2fyu8Ewo29wAz4o$m#mIQ;X2`n`$x(ik4#!T9{GgV zmcOq7UTw>VK#%7(NaLv?Uh3l6U_6a2yehmHxey8#IXq8bJTHW;k{3frUQ*zD!t|~1 zcpj6o$0L(sXXO*eBcGdXc|7Rx91dwbWyBdSmVj|QCkC^;lN_q-c_Z~nR=-%i?Rgql z>Fg*l9uoV5FI#pu(4N~s@?4Kt=i*9W_)kJ*^VYE0nhtB(^JMBZRzFI;?YR$F?QCB# zdTs*#ZP_(Idv=24*)oC?vWp*r!83QBZp2#}2I$PA{{V*8qZjRz$t5LVG~5VW>}=OG z``5;uGCPJpL7p^&Hhd3~VUF0x#YaH@GF&p~N?fwZo(en{K&#gC$WLYeruhtKzm}Ni z{0_Ln7vWxN0cf*FRY&MnMHepzqgm4x+JSmD6KL}fg*wZAqvn=f49;}+xitF_*wuPB zgEp&C9ig*{E4z3+7|o^ymwAOM@E;^>2=e{&7l(%7Vf)A6knG8P1|V~~RZXu!2<9ir<#O-Q9e`&wuHMe`3P~>*^g7e*O1{n38ce}?3 z@v-=A;A?JIleU}ZcJ~wdTJHw%W4D_M#`!+sc6Sm=-R>%IiQ83!{;X)pgKl?|g4<04 zm%7~~FplqTx0_BVce}~p3e9@mk}6QE%Ik59+g(N&?sjK_-Q2Dc41a!~&uWECX?{zH z;ps=`ul3Q&=kh}sl;03y_yEdh;E-%((U57g;(tChIaEG8B&)~1KU`t6t-+0Lwl3%g zm<2=BIG5~1sC2tc!LLvyyC&$JsrNv)+m=w}cI$)Rx!o$Db}@eM@8@=#6DGP{H}F@t z>(th+=k{*5Az_l+tp@(%c7Jlr`5|YrmD}|oRJ+{@;L6{G@%<#wwR&Ud?i zD0XwZZ$RyIJX$Ia89o3PVp!ZC!6DgFj^9Lmn77(bw#s5~6RSK2`d7!Ezq;LLgsE=V z0RHNBPl38bafrVwc2bJU$FucmS`bN4)zxF%Dp#M0Cetigo@~gjZ)1MChk6mhv zeGVkl+NTs;6jYPmpx=loILhtzA*=|<^KI(P_VB90>*9r=Z(|DdhZH&1Ds1)(g(Ay-s%{?gt6-tC zbJOhI;N8}n4%+M@)iIk$yw$~{!DyzxX^2@Tn>A4AYuTsN&1Uz2#m-)vW~YEpS?^@f zW+PR{Y(L_CF7^X;j$|3{;JrIem3R6ryxS<~hvqe4sU6M+o{q71P6oV&JFZy_1IM_lY; z4)j^7Kz~y%>P2bk&9Joe;>@J?gL^lFmX@TXrT3+akAU$&KQg>ISaMW&b1)eZwt83C zuK?xQHtCp}d{5_EXFmYrteyw|w)$hBt?z_6y4>upR@CHR@)wv%zv_k599QfWKI8AZW7^)iK+M_@#?o!EmpXE$C~r zoouG{t+eb3>SnXyV1=`T(rh2_AM0%Z+ALpn%>KTVKPKkl*I-=6_jx;xJEjjp=>4I? zM}CiPA9_x;NneTBdK0k9*)_npZ!SZ!%TGGmlO>?7KZIoc0D5|VdQn<>J>B~e z(9)8WwDh{UcrF+Z@5SMLww~{X(EB}y_x-M0Bh41s|J17!mGg|tDgtj zdORfS5yTB$90Eq`vu%Bj&7P#N*s?R#&1Tnt4bGmQW={gQv)&P)&4#Lu+0MkRT-*$d zW`)6}zFY-P{WUuEcllW_dAPIf9&lb^2>hlVVmS4G1+tHI@hE@cEinDy^C|dEXqUVS z#=FJLFE*GegL-Y);B}D8MF-1#m&&{kz8%^ni@2^V>2GZ{Ds>9`HWvT?^W5s_K}XLcGhxkzh2NV6%xfdyPVcWuI0zo81cz zcXmday#RdNdU_AnX2+SU^F|@W=GlVaN5qWY?->*tOTracB3@g66*1H$9*?&~WEK6*5@l?<^L&;t?E3?@b6dEl1 zy1Loy8E}!av(oH!;9u6e5VYB8s$({a_=}7CgK;&#=168WzaenaTB0rfI}_BKtbV6@ z+w&@Lv9r}+T+MOdN=tQ8N)7|a5)Tf0b4KeUrxX8Uk@lwLHH-iGeI5ol>iN?Lk7 zT>O^zkfQXL><9ch`W1oS5}Ul$tSz4N)1$~HyGX>=MPR-MJ-pNwn@>i|PN=wLv%U|*bdEUhcZ>(gK z6Fl1C1pVMQ2wX{x`0u)bzW+*ef+M5zo3C4m&Tp%^-4yVlW;@&w+c|@*&VW!EKOsf*RtkE}ji)@bLpxg$OYW zy{C-t0*ab`qlSS$?=DqG|MYk5Z@^;jgp0vee{fgtXAgnV9}51&?OfFREAd4c6Wugv zj)M`}%$8IT7}3#TD;XKv#1ZA_UFQ)!B5jZJ7O=+I%RqTE`ZK|UJ?YAr<@1M-Mzkk! zZx^=%{dK|Wne?pNng!1$^Yj^E&gTUEfH#1P!d+D|6%2b|uD&XWl;#)xseL{iBYnX5 zrl0!g-E!{ElF6x56?mB4j|9WHl&=d^*?QC1i95q&H8{@aPd@$mk?;SSz}B6r*qt6E zB`5Azlk3{b$%Wt#zW1EamhE5GqC4gIHbva$iY1WE`<>TZ-~8h(kL0@Zxg>dAF9hRi zPXHTzr(FTY*MBIuyKkm<2L1YP32C*v6L)km0mIO<1=D54_X~q#>vv(28g2656Qf;& zy$_IzUxVGjdS|x+qjwK*x3K=n3ZT7zJI~&q6L)a&H86Vjv5WNL%PYObmX=;Ll-@q> z{S&<{ElEvFdV9F|H0X0ef!@PqT8#>vw-9Ku>^iCJieRI&KTFKB`ve?jy;ne+J)=58 zvxxh-cpVsju|3~rlWo=o*`=2KMcpj>DcIudt7&#FIKp~&gEqTfb<8dz4tH@P=!<>9 zCU%itTr}xrb_i!E=|w~7o$ub$K}$y4>c6^#0 z0nW7E5YT43s*c$f#2GHG4aPT}yW6aX%`T)+Y}pCwX0r;g$l0N3c4zQm>umoEQ<`l-u$rnoRuM#VXJboeK81i}d0=q*rBW=|w~7b@(gXM_mb8T9T5M-Y=Fu67X5SEbo%FwbV=K${(JZ%D@L5Lb6`MKC@bD79n%5K8t? z$R#IHue16Q>TS=#V6C$|fYEbfu*|agpglW4^8D^xP6jT%4;D!%Td;(y@Q`f5x4JNA zOTKgXULlug+>33pxkPN;4Xk&z6Q~!Pwk=4WYxNI7TfYLy`blEBi!;G(Y<)#AORiMl z&a5G1OQzYo3(_ri`9&&r`4nt)_Ej)WdoK8dn8=ny-s93^!$~-+X+U)4Z&(>R|BKrpX2y?arnSa(gfP@T}XxtiJ!UnFzENblT|gX zaJXcXE`i%_fAk%n^o1_?gYS6orsAIj)RrPq?iqg}1FysDV6n5$fEoa8XMvk|9j=Sn zg~`Q`hIJZo9T!J|KD3fM9Kv*vHO$$Lzvn7f8b@B5v+t0T_SD+AVnN0EF1 zEx_oxHdyCuXE5$5KcF?(vLAu=d==8%=MwjD@oq4_zjD4@_`69CQxwt{X@1B56pc4#`Sm}T*n8;W1t6d7oR(yHlFo6g=H}Yl1fGtU5wJ{Mj)x z-o=l=IN#Icl1(PrY$$DqTXtu4v)N`~xwC7f*$&_o>wSlw%|3=?_7d@I7oSMY)(K`M z>)LZYdv1tMmDN{E)&Hbdg|kgy+_&BWFSG2kpgkXkf)uKewAl6pS~bW@EM1C z1$MDI&+J=uvCDf>aW)4|a`q80dfx(GXZg!Od!Gx*do1xv7Y_yF;vQzx!=tIsx+TLx zw&Wm%T=EdjXWHy$iFpW@fHlsZ4#u5n40xwq4g@`ffslrSnWJ!8&J$rP==AgVx&`wAlu#BeW{<9v6TAqiw#|?svzw*%{)Ed=9Q=YexA{|EB+{sxlwV&bDNK9_p$VDBA+cR^nTeosfI$?EHX z(Q`#`v9muT5IsKu7h3ie(4Nmg@|;Dickwzf?pyCo4)cAVz+J`%4j(FT-lkcXox*wQ zD~WizZ-Onho(Hy`x53w~egkOhOCVXFPJF?|F*B`Cy`G2C^WQ`1rcHidqIsFk zswCzi90?XXyEhn@VMnmpF1w|IHtAM{)b}6# z{^nO+1m2@pojr5X^kO^$);N0$C{Nm626pvG&WzcG$yi7uIh449i+h4`BzMUrTQZZt zNc0{NYohmbxTxqon09M2gI0)P4 zcQSYnvgw}DG_Jz#{~p5;v|nns!BX=Wb^x24-589!Mn1TiZT?=``nr4vX$Wf?7?8P9snL_^Wq`$Dqv`AelWyJle&3K)nskGCq7xn3DALLp$ls zw6yf1q4Z96@0UPJOH$I(JKn`>!MMj%AdSP(a>y2pw9zu^^;Tb^-u8SKtaElD7}xG$ z@J!3rg7&-ulIJr_g_)(3$tw%!Ab$HF$?O;%qIv~?aN>py<&n3?Y4 zS74lO%UNN%KREnIpsB`PXwQD?ZO_fYd}q6Xak`zryDi&-tUW)0V6^^~&c)7t2FB?&fR9@JDbUvUL$bbsc%O??!8qOiHrpdu zCj;!MaaUOVL-qD_UjWOUeH@I_y&bH#>=mFr&xhoB67dNaj{xIzzdbW7@plBK`+W#W zivq_l&8FJq9*NlcTCmF5DPWxL$>2*?KMJ(zq9e)VkAl6nJ=WPxg=5g~=X} zUX5*t!(3bs)PB!!j`RSIijFgBcp=qBYfn&LYgd4aogJEHcLtBO=w_f_|L&?Iln_U_ z_~YrVZwco88IJCrfBCRJnl>$#-B;agwhP$gY*Csm04G?lBWSaqP?lLE@dOuNPR)GY z>KV^l{pgh`4Qsi1D%%ZQYO_vhwgr)Mt@j~lvsWOQJxM&x#hIWEWY$vWEkZbNaUYFV zzRfzPvOlP~vmZ&!^L-J#*m|=;o87HCX48q2U7QTY7w&T(tkTmD?WEV;($b64(wpwy zcYv0bq@<;HnTu6moW~X6bdc!0q<1W9xdXf`aNAqk7sZlxmuKkM*S51H>%m+H7CL(& z7*7`yz}xLt0eUd|LmJF(#Oqz$67-YCyj~v6CjS~h@AaMCpxrpmrO$9Xj+LUvaVS{o z?4Dp8$9CXDwkiZYj@2QJwI>UPBh*DTTHpwfAGrJ|43EGpM^GGs%uy zNzvoz0aiG>0vN~f6Z-YGY6Lxw*C37KY2srp-V4TY471}w{~AZ4V@I!*UJ&Wm*h>0w z0Mf5^_GK_$I_7{c+v6_K1DFA602dG!xHum4qlLV0kY^#5D6}m^@6oXz`wq6TqE>l==5 zvRUc%o(G;0PRPmqU|hV9)t>iH2~}?Q1o*Kn?gaCd&E~!1b_)oT-0nf}d$+r(wOwvr zelh^P{`reS4408N!T9BK_0i{oxV9zN!PS{lls2F|CfJZUd(}Ta#wb20slWN{$ErAGXdsPOJI-|5G`sxS41ZlcCZi zF{-I)!DK3-GFehcqm)Tuh_onUiMf@GJ!@la$TG-B5~gh?3gbh{lICO0+9XT%-}8FE zu9;Kc$8Y|*p69yW@7L=(?{n^R?{jNS&$c>3gNd6|%mRI3TFJ%q?2mD#w?NXS=Z2=Y zU9-;wC2f)>ZF*m+cqpiM$P%kS_G7gLz8^#=lk9BJWha59%8rb)1Hpf#*A0|ed#fXq zO8iB|zpvcw+$gt`ESZ>l8HSu2dZ{8|=ThClSp5T!Wn}jp=uJEbR_hVYT+nZ#)4-qf zAZ9$MCPqNkL@sfwikYA-CeORJ(+}Y%0*@tkgpl~zLVY_~KiFnfbS<-L)X62LskJ`` ztWfqu&^#I26HGMDHEi$M%BTfooirdeQt`*{>pQsx7dk1C*=WYpO7HUMAc6%FSW}gt7tM~@!523r6OERmwJbTFVXmpw!AI{r$vHD)%PI>M`z^?^g zf*mCLUr?T_AoDCI9;D&}pxtWNvk#`4XJR9PtxdMY;||o*<@uA%)_!gQQJ7B4%jNwp%I1LX*%drhvTZ?m?gg3W&hHwg zoUG!Pps(?{@*Ja(FVCS&DUy00n=Q{yV4<=tK=*6_o-5fOk(K8b$UN5*N2vHR==<4F zW{ni~kmn)jERgy>pnLwwtYT%ig6_EioG96qpgdoI%(Ij@R>hk^-%q>G;dm}mC?hcR z7wY9w|IB7gMm0b?H=M&)NlD!L*=Z%ngUQWD7#q&V-JXL0=nOQP%y0*@cwe`J8 zCeNCPtnUXalud$uWt<9LC-rfltWSr`x<7H6ibsNWU%-C;HYM!tP6F1yTkuOF#h+}G z&($z|r_8K>Z^8PnQFa*UE%XITn}GfBS(c%65*kt-$-F*9er^&nTPO|A=>}_%`TE-AiWK3ccmolga5)Zy&3tf~m^> zjesBCZ^1>9-3ZEaEo7cA5*MoYFzBc8$9BJ$OngFMQ8(Kb|9=hjY^ncdv$daJfEmiZ z3%ciP;B%5)49fF<$UKw8#VSq({l&kl&&M2ilUm)X&!MOer&e&c0=z~m|96On!`e*@`DBA$^K7K_1ds%%9 zs*m-M_3<)si;9nf{vUh(Eez|B68gw$pmrMW-p-$lv1PFrF?KMuTE;adtajc4%avUQ znlWP+f&a+y4$oFbb0BNyGGeWYV?h6hKMT~(Jqq`lG5;rl`c|ngvDs382;8LXe9%vY znc!Y~=GwFZP)jfhGS5LaPQ~t^zctrSX2&QTE6@9=rwj;}lVY1K&nv)Md5#6$^Axa^ zWcz{g> z5ZFQLO+i`zu~pVz6WglzKIo5WZK|q5?N=VF<2&tf^NMpn5pbv=(zPaV5ZbR z0A*bT*=iWh)>tZVq>A`AXM0?Yqd*or>4z*Fv2o(yjZT=()w)+XEJ|LUVq zCjWa)U;a0OMao_dhA$=XxpQ!cjE8|*m*XJo>Ih{r_+MVib5+S_wHa%dNZ29dhImRkpK65 z9s8Y(4za-V6{ggV3O9!Kpm&rCZdLa0_``qSg2xBFXd|eO)><8*7l}Pod>GU>5)!Mf z4Q8t?@VzT!Q_c!z|JXF`{&(O`nQe-*Yrx^sdmfb8BUVSKgg8jWS)f0O-Su+_{2v1f zsWJ;6T9ui7ZncTB_PJGWp%gqCK1n2aU|%kur$@4HPfC|QAn5U5}PKo zhrl+<&X2P*!O7Aq0A)7H>X;28j#aTc=+FG^J2D)zr!DaR{U~Hg_7Uwz=8TklPn#~&_F$f}sd4si z#O{;sx1dZvhRk#=ah{4Vg8H;_Vtz19++u;}RcIARws|c355x17{m#VH!Y1%B>8$}} z_8+Sw^aydGiY1^u`eHecmRUEM{Yzn*WWTp*lKl`YRJJnCz5qTey;4wSw^|*u*~BMQ zoCLbr`{6zE#0I@b{t<;@$yV7knJoc}lzk}9&IezX-b_$tldX=~DB=q$4g%fGKBLYK zPE(jJPx~BhsnqRrxb9gDmMD7#=;zB=aJ6Jl0p*zknP*qxt17ky?M@c617&8Pb!SYH zLb+t8+BEIpIIv9Fyf}Ld_?Gkz2W57k)e&k!T&vUmUu0^MW1+G@0y>_m=Ci-0pMC?8^_rl zh-{Hw4JfmBAv1f8_>qc>L4C_EVV?(JHU0Adw!Srz-7}W`nc<3SMdhW&lCGR0A}`i0LIw*)=Ks>nr1|*fg2V0h=g$S)3hX*`~SH;}B40$5@@r;TBbF4f?5HBC}g%X6u_S z*(o+$X8B+nWrxPuKH&aMgIOm~W^JsFSw!4h#h)&$H|s959x}7_&6Mmgn4Pd zGbppSAv1f0c&LhHpr88F_2$%!@a9zAgTllVc{f3Nq+EV6747I};9zCn0sZQ=9PB3f zCqQ}M3z_$g#4ajc4*DT%DeqPxBwEYUzI#w8^*3y`JpTjcEBgrOo+aQhlAQ(0^J2(6 z&nEU%aWLqfFNe3J63Z;`f9fd|N%m2jCbL_?Y0A!yvy;F<(i;iN>_n?0)RWj>#rB{t z?m03WEwkGwlt}h!nC{jT^pk5=8}wN$gDM5OC`HUY_^@@<;s3)VrpR>ctqHlXelVOC#;Uy zUBr$mUI*$RM+eC)O=dq)SS#5rHchhY!3t$xjm`tFo$p-q$7Xs}kXDBBM7lX5Tc zT*>Z4R-WHL=J^3}l!~iB-9DosG8-zhZV04H_F&M>_6FN1`@4y$g|EN@>AeTaY_-)f zdyY6(#RoxO&28a*kf>H+yWS3IjC!`zci3#H*MJ$yz6JUYE(51D%eAv?5h%|Eka^A_ zPFC?U(9g}=Wp;=iIa*|Io$CpfEFFuN9%*%Yf|mQTD=#i5|@U{9I# zlG$!OrajuGuKsUQeX0v2w>pM-dV?Z|>0v0OUJI)>k z-rp>k?GMUq536Ig{eng*cdGa)=*R3}nWZZnBF{lgDUo`2o2~OC9V}8d0s49J2U?Fe z3!Yzt^4tWO=Ne+EiqC_-gRATvmG}b^%flx34*Y%T9L`n9Y{wZQxR6uLgaUCxcaz9Rx?FFpG)Fd7X8+hU$$kemQFc?DT?76uz2`xhJz{mtN{GLxILnKiI;~{ZT4vu< zNSEw~Hce)gU>jv$h_j`Jdxcx(&7jO?TN1NL#J^=W(upmRaC^0t%UuU1HN@ z_7Iq%?EE-86KpE80#Ih7td7tiVx(esFJg9%%tp)1);CA8x7ak9T?J+jsWg_TV_XH`qaXzoRF!Zy__=NNlI#YS3@z z17$WyX12bCl1-0g6JUX|f0&qB_!`WV-us};)>s|0=ZP6AE(HBTX797GjNyG2zMq0@ zk!1h0X_DOvPE&S6oLvd_listS%u20}+0DcrD$W4iY_81a>75K)-xA4wVAEu_3M^K( zJkCABaoC?Z67c&1$;>jwefqpfsWT)FSnN0x8l|3!a=73|Q z*AUZr5T3Na{|}{}a&EYr_}*q~hd%^s!<>O(Gwk#6@~>iS8~HCWCHX%DHc@sy=>9Xodt^}n%6}AO{)33O zs@NU$o6i@#oVbhs=CB#=AMN)>Gi339es45g+0iDfc1{8xm3A*s#u-+}*nV&H0Tu1{ zM*XH_uVM3#6RtADWHifyes45K>Sx+)sSf}%mHj`zH~O4p|Np-?TBf4?-l*O`i4K-o zy3FkNM)M@wEjBwC9IWi#an^osv_g7cf!e`ce{b|f747#%{m8DI6!vVD1^%xiTKSSq z#Ik=de5A5pgTBA-gX^TX0+iYFR!3+dakYx`Kwr)AGMgZ?KPePScB@U(GHw71lwBET zp9MdV-udNnb}W|nwkCX=vOK>0)3x{$ZV+0E~BtivSVzT_F)KEu59l(dl>k; z^!5j3wujX*+dh^DmMVS<`krl@81~Fw(_+j}#;%oYADbq#PGE(yE#hngFxorUru~SX z%(g&gwx0O6%wCSoZj+h4w!|1)-%XNj8Ot^VtCihmVrtZxF_$uRUU>a|k;#%4?X1F%NfRiIzu%E5yq`v54<`H*?eB(_qq0QAQ` z9~K19j}$((!21r=n~c%>4mMk!_Pe7yYmqwhe`HQP@ZEU^R(X`O;@oW=$^A= zHe2Cpc|K}GYlT~RAudVN8QtYcQjM713`J(Pmh{sd*b0Lrh@KiFBq`4hbweZ zI6~Ie_h6ZvYa-g+lfg`7vq8Tpb_9D%eLqmvjUcnGJ&y-rDsBe-vFzJCy}|k&g=!1@ zUtXrp0ay`zPrDpH9)dof%4o4ndfTaF)BU>hFfHn{yC6+HiO4QLof`F z8uc-0tp6a#|G)}m-;T4dfTQ=!wPwpex!z-SGB*%MsyGF-J>`QOfAMG* zM|*Bqf49m1F^tnljl5;224s=Gn?<0Azkg6NjtV4)hO%og#<4;1>;- z(QN8&Gzlz~(MZtGn}OhDX>|j&W9=a`N+pg{@$WVDpA7nkhi-g}vB(O153!AX4>3Ez zhTbJOAz(#b2>d3(KJ}GWhWuZ=FhBa3;H|9%+lFz`i=eLFSzl?~dxUU_t%@qZLp1K` zc-*HNw~i3L%2E|A1v516G0;DVVb3ktDSKYg24m2kR~)Tz_PjzD^2FO3_X@%P33M6Q zTjTBo)nB60#?^hhf#1JnGhMn1z#NUA6OaFojpy?Wgbo^40-m68v+BoXJ)?2=5i&Hc z7#yZ?SAfO8fVXE?6D7ecWK;pgdB}4 z1Se|TXfQmVsajEF8GcxDt9>9UXJ0m|!nc4<1(De%nNJAz#~!}{jtJu-TLW7@#@TaJ ziuU}}5AOEr;)0)yj9FJ+|a_YC-!m9h{oH!no@RBQ@?) zaG|8njmO=haaR!vG;SieNaIG-jjLKw9Wwn>i&Jya4J&**I3ziWpL$E!9Q&jxx4vjN zJWW!^g5{Fx0yYoXoWa$0yZ7%|RWLi3i+KI1n@lX+4)h*2fs16b22>CKfovTfAwHyH3FtjsqaLo^y@#2*_pp`mC34$fYFdYt zV3D%Vg5JaZ;B&G`g6d%gWIbF!T&&{hp!blb9@_2JLsn~L+w9)TV@z8r)7wl`ty~S3 zDmxkU`;<}OD{>nIs+C@lwbFt3qKeHyZ{>MAA(M$0c0VtlvQ6GEWn8sf&NUTzpA1$g zn+^IhbOb9UzaJ>?Mv!^eRy0g`UB%6yE<{-)%N?en=jLBT?EZ(*sRZ ztuz5^l>G%=Uxv@X_vH2ts8%WgpgyG5bILVWsfU|hOfR+@^up9NEu zy&v>7Pl7*4ekv&M3n248o%ofC{Xt)I`>k|#w7WtN_ugqP$wb%PTe*#CgJpWPiK>;! zV5YL8KwtAg;BRv44yu(7khRjBxLw76Uavp(s`5iCYZdIbzjwJPth7!3{}(e0WH!LW z)WXqVp0e#gZ(%R6Ve?#@wi6e%@C{@wd_eqDEvy24HO`m!c=xt%*D>~Rgr-TpHRz^$ zfQ8C#H&KoK6x>^;>p+<m;k5F4v_mmyO)*Zv)2`<<17DO(N9o9}^BFOm9pHe2eO zz#?VWfPUDY2U|;aAt=uh$UJ8eQ&qeW^c`IsJQGhTJZ&Mq06*@VzWc8*ZK+JlOjNDh z36?5*E$C~033#a7&H>fRP{>;8Lp)H$PN27vqaOP2-a{YX+$6WF8DA~8$)=|4D6m4= zL7*>3ckl?=q=V|AIb=Qj^IF4{!&LkZ^h5B;xnb=$6FBWZwGc1IM&I;S`k}N_rkzbx zt+WDblx+n1a@1ncOKzJ%wemJ(t-M0aRIv>7<+xO>T&7m0?B2>`-}EE%JJZ^nAFfMZ znW$QM4@^LSg1kaR9dr&R3fUJcE#5@&$e6_xX-|c4L`I7w&S$S@S%yR?rY!z36e*g3NIbpZIAh6qCTHrc_PO;QmgYLNpI8E8@ z2)O5`;6;*M2g-9fWS&nD3sk%d^hbm@%ClIWNqPQ5y;SPo*=+6SCa^@=HK2Pw4^Eft zLQtM1ka^A`UaI1SpgmUSYS&$!J%VReR@h4GDQoL{txT4hh^!w2%ay$i^uu~Jc!Sg@ zgR&kCne|D;St|AdeTg@n9oF_k0*!p6t&c5KMGF|VRVH&xMAnyq)yj?m-FgUkhtzw6 zvOXL#>(<1ZRNMo!CvKR{lG$vTO`)(;viUYmW<$YRW&6b0PT)f6wE$%nSsk;Vmh*LC z6}NzX3rd&SAu=1r*e2t{C8MuRlUW9sqHN1J+Yo$0dfU*GSq)@nZxJ6+aT(~Bj8$jZ zqGqiQA+g2+zbA@Ly43fL)&F8vsvvHz?0y$ULtgE?03Z=--9hOP+hnGa=76spm=k zC7UhJN5LFrZw1|RHn>T$lR$Z%1DWTE#Purn1l{x5QDJS%Lr6Slp(=WidV$pE+H84F z14k-59(2!B!EYsd94OCB$UM`CpQzXj^w+XZljrI3JVTzBQ7@AE7@IB6Az-1hy+QXp z4E#&7`-Ae_12WI;uQW{gQN>R|_xx?7?Pp@A1zx{rY>8z1*fg1S0*jSx5oa5K(SEr$ z?ML)vwgob?^~4kvUk3f6cdyLulUW7=rIKwK%QgfTD7($X)WRoVs`TCfWwy-fm@OhU zRq+ncZ;Hp@!p;9!nKeSTT(Y$`O|qN8GG*V4voC=MN$*imW_Ma0vulYhRJ;WAOKZ)U z;r{A>1XlAi3*2-1BZqeww^lC8O-0^MfJ>FV3-m*H9oSj&g`m98gUovvF6lR+@&%deHNWH{n%X1c3t?Y%Md!7k)m+Sygo>`E29!l)0;=Z6?deVbg+95KV zO`%q@lWdyIMuJ$n`Wjusa@msL&IyWM$>S_yf`9@+gu_9po z0uN$(lL_HE+ufAppAPPne**NK{R7>>viKU5|0c-%*AV-w_&n%m(%JGqCzuYgH~bSL zcW=P-)760KdjqDQs_grqH?RUcT^`SXYG5H`4a_4BQE@uxXV)KRga!E1Li~X2XWz85 zjK@kp*e1WT%(THWeaS?%7LS6N%H9h4z3FUljNB%HYULcrS~-z8QpKL2uf;8DrDXS3 zlDo9RJ<_#msO_NTIslZ zEA4h^g;i;-RtBI@EYqV+RIRiF3zgjq^j3Caai!e81l7t1khQXkc!`STpdX-@PY(xZ znT7ZOy%4flODyoZ1`cI1`_;tM!slR#velrs@G5w{T%H8g!hMjnP)wYu;uWA@1xDb) z{+=nbFDNXP?7KEiX0L(e$}Wzx3&5MDHwTp2RI6h)j##W>9_SbH-%ktI);|c0d7Z*q z$v$P%WOff&q3jKDb_#f}^zuQO4YxW%#}aQ&?6=+-4NyH#eb(8`c(qu8vL;pxh5HZisECb(XDFM%>E zvpQyX5?85sE$9cbyUcpXY&(T)$$o0nB)bmGRCZ~ceGJ?rz1u*UU1xR73W?P!jt2cE z`N8n8ni~~1S>XCkJx}V-+iZC*1ap*~2l`nv9sE+V6F_;M37O{r;wLH|4f+nwz=ek# zGi6pvAz!jL+ccTY07oi&L7Y7u+%CQTpv<~i9kYXp->A4Z=sTDuvvvvx%ky&T)1-c$ z&6ejdut3?qpzmM?_>W{;g7Rz(ndgp|_<#N?)_}f)EAqmkuC&1C2^d=}*?u-nW}U$z zWn0DBMqso3b8T8JdNTVTWM*#@8>;vU=sS46%*Kb1HbI{4(J7UBYOMY@vr3fx*0j{g zMzE!1SA+6=5i-w*iTkK{3+T6pR9rZM&1Jox!v3e>+J z6f^KWa7c1u#*n#B)%_Q|i-+5ubiIUt<)et#ObnNiTS4!AHn>UINpW_hjYW`Y13~rP z)9Pf}6E~`u3fg(WHLH1WSy3Ab{Zq?Z+U(Ht3XqPPvJ6L1; z!=eVf--?H?V4?+CVF6gPnnYup+i$HyIh)ws_IsTx-emTBCppibrJM~(ZK z5PoHo@ArexY21sToe{j@UlB4nsnc3pN8uZR*Mt5Owl>E;&asw$%HjQG`2e_7Qa8C2 zza%|4KR$k#}fwC?zP3fb{l zNBly?rJ&BOuAQyTWa4lF2cwk!?T4-N+teS7%M6o4`SE4FJIR?dn!$u~HFb;yUNuRrR8lF zXi7JSXfpehE~inp$6D?|U@6nk?GE~FFde)t9JMF`%Kx7s^8b!ltl}n6A6iZ%&5h5W zGTi=LFGGf==Z2;?U)}$~Y)PA>?V9Obui~0m+HOERKIAFs3b9gC)Bs=#Br(@Em3TXJXpPx53Ay_X;Sp zr>u_9J;Vo9ya9Bx8_gwts9WTlewe;w;7Hm0*JNb#I+&+y5Ledp%VT|+Uum;2KcD!d zio-#>7I0xHBh=V6H<`Hcq_DU5KhFaMU4@gN8%_nQl^qvn^T4kA=h`A21IqA7tCKm9 z*ipqMpl&}|PuOBst*8i{^iM51z-H^i383AiX=R=Um4+h!aJ+5(pld*GcO@YVOwBv6 z{&rUg`t&n2y@*Wsh{-|q)2{%TUKGN>)SR^X>6e3b7nJZ8K{CIlS^EpVkYS8^Bl*9-@<&Jz?g*;N+dha zrb%`>Sgh=XIC~m+FMGkX98d@2XseTHM=VltFR(2_+&Q0aF3GGjf@jtUc}}5TCiQ%q zEzhCg0%iMve%tBa zXW)Y8OfyTiyh@%QQeP|2N}H`ce*s*oY$@n_elxgUJ2wN=o=<|zb0l$%iUYxL|Cda( zljp&~GfKChe}$DeNd6BocB`D`o09xzg4N0vfPP6n1N=}H$Aj|k4w-*Cv0B9h===N{ zH*og(^$@yN*v*~Se{`$Am|;yOhwJ{?CL-&>V6CjPK({^={8H-sg0fD5%=(8h{Aibo zAAxpO<1#LowLD**sG|xi;-KL&jD{*IAuRA@MJnjRt*DhXu2ir^qu; zo@=P*OZ|D9EzgBup0e{m-@)l%Yk5up<#{G#o&$(YR6H8=|Izf*VB5i#J3>hOY=QeV z>eHltgUy!b6tFesLuO%q6##YB{$GJQ|Rmz8 zJVUatg7SO@GSB;n!&EE={bF3GeLWoja%d!gUmB}lfdq-vn}2yrJiz8xZ2IJ+48&$td-{&(ARbdSR~orpga$U z%(FG|3KjPN-SeX0nYdVHQz)d$EZ?TdY$(`7**v#$_%_LW}$Fz!;2NA4%9!EA#4VbKx1f+DydXcmmi)woPTxTx}eB6yX?HS?@J z-^^o&h9nDka2hSLImxIjgv1jTc)gX7d2u+Sx`4jZZNPM8Bhb&Np9b)hM;2Q^Ek!kC zOYti4dKI4pweC^apJZYPA}s$<3)+vtQvcUxYe&Bavz7f2bk9m~p=4hG<@qRNp0^Tj zQ*kzE|F4#Xwg+k@b{vz@`?l8lN%NL(Y&VN5BIXJ4DGea!$zD%%ot&xYW0+MR94%CiPC z&$oz=sJIODyO{R!>>$sM@;nrsBB}2Sy60caDpd9x&^rG5jrRM{z@uR=cfvt);YT7_dF z^Xx*bQLzo!LY_^7OGWA-x$OOb4mI{=kZRk|E&a2AD{4dF<*-AoqL;%0R@7KvVzo_N z(7t}+BE$GAwrAxw3XirK799`UA9xhFI82HT0(EOk8)}33++RGd6ZoRWwWu4%&yN&d z5^f%|jyG{XSXI$jHeLS|a7}15>IeE)jxVzDRnb`lzv`R-zApV9@wo9ej;9El7(BEt zO<&+T4ekW$W)qF{!8Hudfx|K7|22Y}G`KAo_OPn|;95I&{=;2cIqh!hZ!J~S+DKNj z)>gBu0~b|h`7a~xOb^9Hps#lst=PfY$(lTBoQxg|srvK4 z^t07~>3ajFpP}p_LU8tAJA`t9C;>F3GH z^t}Po&r!An^af^u>*aAFs0Pl4tbxJAH&o05y@3zHvWM^fzGuk&M99=Hz^#lekkf2a z(y^Wdj#PFe=>7x2_hr!ylz)53{8Ne5D*k<@inv`I`%jYpO-N8a- z(?R!7fS<_X54Wg{zJttv6LFJ@YhwS#!A<|RprIOQw0i@lzd%-|?+uuKv9e!--oX3d z7xGx)9+lDakTtN7Sfk=RFR}m+9H&#T34D)nGP*aU>W_fwm&?lZy#doNRrVRs8@Lbr zULM7uj=*%t8kj)bs^V#0#I2vZ)v&TWy3SG$J$LDW>`}H^72VG?`va3;h5V=1iShn8 z7V<@8 z%`ssaD=qN4En00P+a#9#h2g2ner96Y-*><)=`9Ck_O#Uzx|i5h#T!94E0Eblnc4bg zNcMA^CfRB*UD;RT?2}-B>D>*=tk~+9T|w-v;#knl_LAA&GPCu~mh5XbO=gS1Ol23u z**V})>0JiOY@F3G%Oeg{@fgs}p6M5s@mUL1k*)7w$=+krWOf6XqwJJ8n-7kX-cV3x z$66hsF2vy~wgKI2xXezKnXT_g$zE>LWOg2yr|hse+ZP-!y$n!h2Us1m#>CMo?l_~~ z?B~8=&wjDM;~T~lNcI$)CbNEEzOtR;Y%B0m=`{jn_A|<6_CMl872l4{?v~jCnc4bI zlkDNKY-_Mk**)Uyc0^`L?^94_??7g@oOp$bPk_FRePq^GX12b?l8s{7pBP@G>=qN# z{;mgalHSXp%$~G5W_J^>QSo|EFM~vz`-Elu)B>+RQCJ|^8k;8Bx4;r*m&Msd;9b(Y z1C-eut0Qz7alVRUK;N?>nO!3@Ti-ItzGBm4RtAoA+iTA45 z2XwRcGV35STi>OUz00P_>^iVq*}^zG8hl22CxJ5SYjw;rh>xq-5_Gf5-eDQ5Eb#h1 zg|(8s)TYVoT(CmfljCeQxJ-H-L7BC(Izo+z&#PE_dcE01nO!I|Ti;ER9b(gD)*Gx= z_OLj+KUgWf6i{Z{Q8u$riLa@+E;id+W(k?u`finMr&zWHSfgx%IQt_a?@8}tP-g2P zGkcl%rizb)el|Xv9hR}&0{^cEt(}r>7|U*Bc&)OZn3(qW4X{Rf{{dyT$m$5)LENa~ zHK3cFYA$-WBN`UiAEP9r6V!m|r(PEB<4oVJOg}~0M?in5QUd-ck6EA^xEQhq&L)1L z;$YBULHVXv+`yNC>l^sgHu;<{gEM4h`rd%)w^8;&&>J`t{7W7KKsAsBSp$a>e^PN@ z&>JY)rGcw>-bQPz?-+tbt>RhpX5H^aei3idSG$;QAGK*Eae8BMdH; zmFar}reC7$P|zFb10FArPM{iS16czRFvsYQXfD%F6V;0n;y2 zwgu=7GywDD@gp8;U<+gotS1gq@#VOIX1g@dc=rbW?GaYM^s8lM`rd%)S19{2=nbp| z&y~lEpc;4_vIcG^o~~jM=!f7TbMXt&1A*%g!Ch*=^tZ~&^t}Po-=yrrpf_*}I9VQ7 zfok9)$Qn3{I9A0IKyM&>mj-(5-auD1VEQRj!j;hUy#dp&RRa@2Z(syCQy#gX8t4I8 z1BVa`Ron;EyA#nn-QyKl7r1@}R@-J(WcqE?fa!Y!rr$)_Owb!h1C#P-2C9KShpU0D z#H&@@0Qw3{*rkE7yEkyQ8ZiA#S(&~!VEXCG{)U=2@CA5}Jl+M>z)Hwg;926$D&7zJ z>u-N|i&xc zmj+69Zy>1#Og~>%rtb}yex9;(KyTnO@FjVS0o6brWDOicT&&{ZpszreT^i`Ldjsie z!1Sld%JjVf(=SkV2_Dkh*&5JaIeZKJpRAUF>SHlveJmhuRB;aIN58T6(S`;Z?&_S3{>%&u zVfxjwGJS8r^edEI1o}eU0e&ZsYd|${8DtHNA%3ai5Ky0th#oT+7NQLc@sM#cdN`!& zZwB`%d%p$V-)Cyd<>7*Kg9+=nOaW`uPCjVHj2#O8CdWRWt&F-r)=nGZHWee#AI~4_ z-ZiF>jC$?fN~U@k&GeDRoP-4YD3SA^xcz-T?Jp zWAxvnY)P)~U_G!Z>ufU_t@rFsb+$&?N()ud{%jx% zb}6XyWh`W^oI>1R#eSe4plJ72{y8!%&c7DwUv1V^bTefc~(ze-(hKR$w^JkU|a8@v^Vs( zT`MY~r+*bf^tFYms0SL^GC2fv>wUmq^M> z`UPTt6-zmfh&WWm zi$LG&BV~4!1+M<-oV8s-Dse;ZpLHkiGf7=i5>Si!s*%@H?BoqH93LG!v z(?NAL5VEei5zkWbV9-A-v$l)1Gp|DpdrLvM>6R6G&%hYt4! zmlfrq&_A`Xv&|0g$6pt)q9lZz)V#y35a*^tB@kkflSGkdN-Rb z&x64XW%mZ%^LMl^3i}g%1WyR19n8v6 zwgz<1x4@~AT?Wc?F=U<#h?lB32h_(1qd_t|L1C~wf1q9<^^a_}_Ol8csq7NaJs$$E zk?ed>o>xQWIhi;^#ZjQ|=eHTQw$XPM_}&kNX_9@>rpfGKuu$1s;_Ox6T=&cWFt@^*^Z#^ z&VJxhW&brXweUT-TzVgZGJDhNn7u@NLB&Twzr*P$v%_SzKeE-5O^MBZVE9^PKQb|y zRe|fIw*-{gV^+uPHe!W}SA%|0tUk;Zt)j*XJOEo8gmO|#yRfb6&|pSU&{vcNYFQ4mIzsys zC#skN`ZN6xGlJPi7Wlp-g(fqC**P{%t)B>{DBCm6wg<15UMeWF23AMt$Bz7tv5Fsq zehjXX*(`)@_pg0+i9&I9E+3o_3OiI1vyCg=yUKxPwVR!JdWvM<;)nU#VgmAyI6 z&H!JR-UXn{Mp_-Sfy5;$b_4xD?j^ImW%dw-LdnjzX)>D$7ARW~XU_oNmfrE8%(`10 zvvlGr6%(MFJ;M>Q+mwF-a*=O_n^-bYYMWKjc*YmY?Nn1!566Milsy9U)ja_GNH&c@ z_3&E<_3#Dpzbd{9`jz+i;8Ia*1wQ{a%|8EDek2>ZbgT?mQEh>8hLuZ>sxLoem`rq3 ztNRh`kFNj4{;@DF`X2NLn0D?{wDaD21MR$jM&s#tb0;>5$ zLgW4*6Hb<@=xgwGje8#qch*%E)t2GfSQJdzgUtFpcr0K=c?dbF1xMFcE;sb2t#$>h zL645#BG@0e416L?j23}jsWvD*seF);he!aSJ~A!8bVu)?@e&=!@y}_C!_sAU9Bq$ zO@ZT^Z9QjpXG4d7pkdteF2~R1?D(A+#z%Jiyw_chpSNkpFHhs__=OulRYjp?I4)&j z$8%CMdel2-8^+F!!rs@7jJBfT9oR*(UziuJle$o)?I6pJ+cEQTcH9POoE^6?j!&}I zXrb&HXRFHsM3Z1Y?d)Q4w%WGqMct$#P1=W>5##@CUvIJ%yg)}|1L&t;zS*+6Ikvj# zS!`%^vkc>X920uDzC#TiBRhai@BL`7cbFHo1AUcG0d2ZgFY3Xjul6Bej>hj3kGE@v z?IUeOonYU`7T^gQ+yJcG$Mjj@3_6M3V0^E5A3K0~TFB<0EGzO&fqfht_OT}$zK@3S zK7MRV#-{IM1)IK)PlLU~yy#xg_i>$%504;tf0a$&#|OY1jlU@#|4JAi+K3*3eIHA} z6Et`hX#2>QAfB>1ShJDgR@aLSzttHg(@v3XKZ47222Tv*qE?`Gt|C8V z_`%`qdWCj|$*8Lo+SZSa_5_DZ;b#t>u9_8@VfcU!dDcj6EEDxM#ftP0a#CwT3{P!; zF-)cnkwI^Qw|E%%dl(n(59%QES-Gfjz)O!x}`}Ic(}T zXK=bE%}A#+Uhg4zN2i11bT0G?s8?+vBxzyz@Yw zKFRS~&>t6G0+#4;;W?o9aU%Gw9{TkJ)ki1D`e;G?RK*6MKkB}hmb6a%UTR=}Z9f^^ z;+x)Av2S``1JP(x6jq{}IjGx%!4zfp25sH2{=IFZlr$~DSD^aZ2w7jNiK!|+2k!Fa ztn~2IGTPFb7I|D|q5dq58dy90K5AcHT9e^>ptn&0*62z1)1bF;FZl7{xi;-aP;E?u ztc~%+cT_wT^yOL1EuAZ4ruD}Im<3^fxORqq!;NQ;V@$9j)dC}meMEIghY_C})}6x1 zsKg}e_Jhy$vT1*`Fcz#0^P*EgeSs)ZWaF!%iwJ)6It$$6SVVapsVDPu z*=QJ>1=obrqc7;kB?HV?wq=}c2v!HLXxqVcr$-HB$K@^J8!9dX{qe$SOxeYJh;O?2 z0c=i_O=Hl_cQCzB*&wb(H~r6IeVr7GNt*cr;`=Jj0mJL9`eshGopZ^kJz48RCq~qS zP4D5CcKkf57XLF)7rXw0^TNEr;lJmUS_jGK6v~7=3-NkhW6Jy=&)yAFihLcxx^)CI zb=J28{rqkScIlUE)3#;To!>Q3SV!U^DlP;44z-K9B%>pIH_FseN8j{Yemk|Y7xHCl zWv7X1{k{ZCl>IO0t-KCy)51LkYE>VAtd*OHU#WN{=ywklT80%0D=qMQn$#<#zTRfb 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

DXkg+Rj#IjlsF`0jPis@0{A}MBC=2 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 Q4F2wKlDabk$R3No0UD7O&j0`b literal 0 HcmV?d00001 diff --git a/src/test/test_vector.pr b/test/runtime/test_vector.pr similarity index 78% rename from src/test/test_vector.pr rename to test/runtime/test_vector.pr index 2eb99ebb..f8acda67 100644 --- a/src/test/test_vector.pr +++ b/test/runtime/test_vector.pr @@ -1,6 +1,3 @@ -import util -import test::testsuite - let INITIAL_SIZE = 8 type Vector = struct { @@ -99,19 +96,5 @@ def test_vector { print("\n") } -export def run_tests { - print("Running vector test... \n") - run_test("test_vector", *test_vector, strip_margin("\ - |Destructing Vector - |0 20 30 40 - |Destructing S: 40 - |Destructing S: 30 - |Destructing S: 20 - |Destructing S: 0 - |Destructing Vector - |Destructing Vector - |Destructing S: 20 - |Destructing S: 30 - |Destructing S: 40 - |Destructing S: 0\n"), "") -} +// run this +test_vector() \ No newline at end of file diff --git a/test/test_compiler.pr b/test/test_compiler.pr new file mode 100644 index 00000000..98bbdf40 --- /dev/null +++ b/test/test_compiler.pr @@ -0,0 +1,970 @@ +import common +import json + +def compile(str: &string) -> &Json { + let include_dir = dirname(__file__) + let types = run_compiler_on_source(str, [ + "--continue-on-output" !&string, + "--typed-ast" !&string, + "--name" !&string, + "main" !&string, + "--include" !&string, + include_dir + ]) + + if not types { return null } + return json::parse(types) +} + +def #test test_arithmetic { + var str = """ + 10 + 10 + 10 + 10 * 2 + 5 / 4 - 5 % 3 + 10.5 / 4.0 + 10 << 1 + 10 >> 2 + -10 + -10.5 + """ + assert compile(str) != null +} + +def #test test_compare { + var str = """ + let a = 10 == 20 + let b = 10 > 20 + let c = 10 < 20 + + let d = 5 + let e = 1 < d < 10 + """ + assert compile(str) != null +} + +def #test test_pointer_arithmetic { + var str = """ + let a = 20 + let b = *a + let c = b ++ 20 -- 5 + + var d: *int + @(d ++ 10) = 20 + """ + assert compile(str) != null +} + +def #test test_assign_eq { + var str = """ + var a = 10 + a += 20 + a <<= 1 + a >>= 2 + a *= 5 + a /= 10 + """ + assert compile(str) != null +} + +def #test test_string_literal { + // Conversion between static and dynamic arrays + var str = """ + def function -> [4; char] {} + + var a: [char] = "abc" + var b: [char] = function() + + def two_returns -> [4; char], [5; char] {} + var c: [char], d: [char] = two_returns() + """ + assert compile(str) != null +} + +def #test test_boolean_op { + var str = """ + let a = true + let b = false + let c = a and b + let d = a or b + let e = not d + """ + assert compile(str) != null +} + +def #test test_assert { + var str = """ + assert + assert 1 == 2 + assert 1 == 2, \"What is this\" + """ + assert compile(str) != null +} + +def #test test_function_pointers { + var str = """ + def some_function -> int { return 20 } + let a = *some_function + let b = a() + """ + assert compile(str) != null +} + +def #test test_if_expression { + var str = """ + let a = 10 if 10 > 20 else 5 + var b: int + var c: int + @(*b if 10 > 20 else *c) = 10 + """ + assert compile(str) != null +} + +def #test test_if { + var str = """ + def foo -> int { return 0 } + + if true { + foo() + } + foo() + + if true { + let x = foo() + } else if false { + let x = foo() + } else if true { + let x = foo() + } + let x = foo() + + if true { + foo() + } else { + foo() + } + foo() + + if true { + foo() + if true { + foo() + } else { + foo() + } + } else { + foo() + if true { + foo() + } else if true { + foo() + } else { + foo() + } + } + foo() + """ + assert compile(str) != null +} + +def #test test_loop { + var str = """ + def foo + loop { + foo() + continue + foo() + break + foo() + } + + loop { + if true { + break + } else { + continue + } + break + } + + loop { + continue + loop { + continue + break + } + break + } + """ + assert compile(str) != null +} + +def #test test_while { + var str = """ + var i = 0 + while i < 10 { + i += 1 + } + """ + assert compile(str) != null +} + +def #test test_for { + var str = """ + for var i in 0..10 { + print(i) + } + + var j = 0 + for j in 0..=10 { + print(j) + } + """ + assert compile(str) != null +} + +def #test test_vardecl { + var str = """ + var foo: byte = 5 + var bar: long + let baz, (bar) = 0, 1 + """ + var res = compile(str) + assert res["body"][0]["left"][0]["value"]["type_tag"]["name"].as_string() == "byte" + assert res["body"][1]["left"][0]["value"]["type_tag"]["name"].as_string() == "long" + assert res["body"][2]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" + assert res["body"][2]["left"][1]["value"]["type_tag"]["name"].as_string() == "long" +} + +def #test test_vardecl_fail { + var str = """ + const a, b = 20 + var c, d = 10, 20, 30 + var c = 10 + var e, (c) = 10 + var f: int = "string" + """ + assert compile(str) == null + assert env.err() == strip_margin(""" + |main@2:9 + | const a, b = 20 + | ^~~~~~~~~~~~~~~ + |Unbalanced assignment + | + |main@4:13 + | var c = 10 + | ^~ + |Redeclaration of `c` + | + |main@5:16 + | var e, (c) = 10 + | ^~~~ + |Must assign a value + | + |main@6:14 + | var f: int = "string" + | ^~~~~~ + |Incompatible types [char] and int\n""") +} + +def #test test_var_let { + var str = """ + let a: *let int = null + a = null + @a = 20 + + var b: [let int] + b[0] = 20 + + var c: [4; let int] + c[0] = 20 + """ + assert compile(str) == null + assert env.err() == strip_margin(""" + |main@3:9 + | a = null + | ^~ + |Assignment to non var + | + |main@4:9 + | @a = 20 + | ^~~ + |Assignment to non var + | + |main@7:9 + | b[0] = 20 + | ^~~ + |Assignment to non var + | + |main@10:9 + | c[0] = 20 + | ^~~ + |Assignment to non var\n""") +} + +def #test test_literals { + var str = """ + let v1 = "string" + let v2 = 'c' + let v3 = 0.0 + let v4 = 0xFF + let v5 = false + """ + var res = compile(str) + assert res["body"][0]["left"][0]["value"]["type_tag"]["name"].as_string() == "[char]" + assert res["body"][1]["left"][0]["value"]["type_tag"]["name"].as_string() == "char" + assert res["body"][2]["left"][0]["value"]["type_tag"]["name"].as_string() == "double" + assert res["body"][3]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" + assert res["body"][4]["left"][0]["value"]["type_tag"]["name"].as_string() == "bool" +} + +def #test test_switch { + var str = """ + let a = 20 + switch a { + case 10: print(1) + case 11..=19: print(2) + case 20, 25: print(3) + case: print(4) + } + + switch a { + case 0..=100: print(1) + case 101, 102, 103: print(2) + case 104..200, 205: print(3) + case: print(4) + } + """ + assert compile(str) != null +} + +def #test test_assign { + var str = """ + var foo = 5 + var bar = 10 + + foo, bar = 10, 20 + + def function -> int, int { + return 0, 0 + } + foo, bar = function() + """ + assert compile(str) != null +} + +def #test test_assign_fail { + var str = """ + var v + let foo = 20 + foo = 40 + var bar: int + bar = "string" + """ + assert compile(str) == null + assert env.err() == strip_margin(" + |main@4:9 + | foo = 40 + | ^~~~ + |Assignment to non var + | + |main@6:9 + | bar = \"string\" + | ^~~~ + |Incompatible types, can't assign [char] to int + | + |main@2:14 + | var v + | ^ + |Need to specify a type\n") +} + +def #test test_operators { + var str = """ + let foo = 0 + let bar = -foo + let baz = +50 + let v3 = 10 + 20 + let v4 = v3 + 0 !short + let v5 = 0 !long - 0 !int + let v6 = 0 !long & 0 !int + """ + let res = compile(str) + + assert res["body"][0]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" + assert res["body"][1]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" + assert res["body"][2]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" + assert res["body"][3]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" + assert res["body"][4]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" + assert res["body"][5]["left"][0]["value"]["type_tag"]["name"].as_string() == "long" + assert res["body"][6]["left"][0]["value"]["type_tag"]["name"].as_string() == "long" +} + +def #test test_operators_fail { + var str = """ + var a = 0 !float + var b = 1 + var c = a & b + var d = \"string\" + var e = not d + """ + assert compile(str) == null + assert env.err() == strip_margin(" + |main@4:17 + | var c = a & b + | ^~~~~ + |Invalid operands of type float and int to bitwise operator + | + |main@6:17 + | var e = not d + | ^~~~~ + |Incompatible type [char], must be boolean type\n") +} + +def #test test_def { + var str = """ + def foo + def foo {} + def foo(a: int) {} + def foo(a: long...) {} + def bar(a: type T, type B) {} + """ + assert compile(str) != null +} + +def #test test_def_fail { + var str = """ + def foo {} + def foo {} + + def bar { + export var foo: int + export def nested_function {} + } + """ + assert compile(str) == null + assert env.err() == strip_margin(""" + |main@3:13 + | def foo {} + | ^~~~ + |Function `foo` was already declared previously (same arguments) + | + |main@6:20 + | export var foo: int + | ^~~~~~~~~~~~ + |Can't share non top level variable + | + |main@7:24 + | export def nested_function {} + | ^~~~~~~~~~~~~~~~ + |Invalid modifier to closure\n""") +} + +def #test test_def_polymorph { + var str = """ + def function(type T) -> T { + var t: T + return t + } + function(int) + + def function2(a: type T) -> T { + return a + } + function2(10) + """ + assert compile(str) != null +} + +def #test test_typedecl { + var str = """ + type A = int + type B = A + + var a: B = 0 + + type C + type C = int + """ + assert compile(str) != null +} + +def #test test_typedecl_fail { + var str = """ + type A = int + type A = float + var B = 0 + type B = int + type module::A + type module::A = int + """ + assert compile(str) == null + assert env.err() == strip_margin(""" + |main@3:9 + | type A = float + | ^~~~~~~~~~~~~~ + |Redeclaration of `A` + | + |main@5:9 + | type B = int + | ^~~~~~~~~~~~ + |Redeclaration of `B` + | + |main@6:14 + | type module::A + | ^~~~~~~~~ + |Can't declare type in sub scope + | + |main@7:14 + | type module::A = int + | ^~~~~~~~~~ + |Can't declare type in sub scope\n""") +} + +def #test test_struct { + var str = """ + type A = struct { + a: int32 + b: int64 + c: int16 + d: int8 + } + type B = struct { + a: int8 + b: int16 + } + type C = struct { + a: int16 + b: int8 + c: int32 + } + type D = struct #union { + a: int8 + b: int32 + c: int64 + } + """ + let res = compile(str) + let A = res["body"][0]["right"][0]["type_tag"] + assert A["size"].as_double() == 24 + assert A["align"].as_double() == 8 + + let B = res["body"][1]["right"][0]["type_tag"] + assert B["size"].as_double() == 4 + assert B["align"].as_double() == 2 + + let C = res["body"][2]["right"][0]["type_tag"] + assert C["size"].as_double() == 8 + assert C["align"].as_double() == 4 + + let D = res["body"][3]["right"][0]["type_tag"] + assert D["size"].as_double() == 8 + assert D["align"].as_double() == 8 +} + +def #test test_struct_lit { + let src = """ + type T = struct { + a: int + b: int + } + let a = {10, 20} !T + + let b = 20 + let c = 50 + let d = {a = b, b = c} !T + + type A = struct { + a: int + } + type B = struct { + b: A + c: int + } + + let e = 20 + let f = 50 + let g = {{e} !A, f} !B + + def ret_a -> A { + return {10} + } + + let h: A = {10} + var i: A + i = {10} + + type C = struct { + a: int + b: int + c: int + } + let j = {a = 10} !C + """ + assert compile(src) != null +} + +def #test test_size_of { + var str = """ + type T = struct { + a: int + b: int + } + + let a = size_of T + let b = size_of int + let c = size_of type * + let d = size_of type_of a + let e = size_of type_of a + b + """ + assert compile(str) != null +} + +def #test test_align_of { + var str = """ + type T = struct { + a: int + b: int + } + + let a = align_of T + let b = align_of int + let c = align_of type * + let d = align_of type_of a + let e = align_of type_of a + b + """ + assert compile(str) != null +} + +def #test test_type_of { + var str = " + let a = 20 + let b: (type_of a) = 30 + + def some_function(type T) {} + + some_function(type_of a) + " + assert compile(str) != null +} + +def #test test_import { + let str = """ + import runtime::module::a + + runtime::module::a::multiply_by_2(4) + + def multiply_by_2(a: int) -> int { + return a * 2 + } + + multiply_by_2(10) + multiply_by_2(10.5) + """ + assert compile(str) != null +} + +def #test test_import_fail { + let str = """ + import test::a as A + multiply_by_2(10.5) + """ + assert compile(str) == null + assert env.err() == strip_margin(" + |main@2:16 + | import test::a as A + | ^~~~~~~~ + |Module `test::a` could not be found + | + |main@3:9 + | multiply_by_2(10.5) + | ^~~~~~~~~~~~~ + |Function `multiply_by_2` not found. Arguments were of type double\n") +} + +def #test test_return { + let str = """ + def foo -> int { + return 0 + } + def bar -> int, bool { + return 0, true + } + def baz -> int, bool { + return bar() + } + """ + assert compile(str) != null +} + +def #test test_return_fail { + let str = """ + def foo -> int, bool { + return false, 'c' + } + """ + assert compile(str) == null + assert env.err() == strip_margin(" + |main@3:13 + | return false, 'c' + | ^~~~~~~~~~~~~~~~~ + |Wrong type of return argument, got bool, expected int + | + |main@3:13 + | return false, 'c' + | ^~~~~~~~~~~~~~~~~ + |Wrong type of return argument, got char, expected bool\n") +} + +def #test test_pointers { + let str = """ + let a = 10 + let b = *a + let c = @b + """ + let res = compile(str) + + assert res["body"][0]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" + assert res["body"][1]["left"][0]["value"]["type_tag"]["name"].as_string() == "*int" + assert res["body"][2]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" +} + +def #test test_pointers_fail { + let str = """ + let a = 10 + let b = @a + """ + + assert compile(str) == null + assert env.err() == strip_margin(" + |main@3:17 + | let b = @a + | ^~ + |Needs to be a pointer or reference type, got int\n") +} + +def #test test_ref { + var str = """ + var a: &int + var b: & + b = a + + var c: &int = 20 + var d = c + + var e: &int = 20 + var f = @e + + var g: &int = 20 + var h = g !&float + var i = g !*int + """ + + let res = compile(str) + + assert res["body"][0]["left"][0]["value"]["type_tag"]["name"].as_string() == "&int" + assert res["body"][1]["left"][0]["value"]["type_tag"]["name"].as_string() == "&" + assert res["body"][3]["left"][0]["value"]["type_tag"]["name"].as_string() == "&int" + assert res["body"][4]["left"][0]["value"]["type_tag"]["name"].as_string() == "&int" + assert res["body"][5]["left"][0]["value"]["type_tag"]["name"].as_string() == "&int" + assert res["body"][6]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" + assert res["body"][7]["left"][0]["value"]["type_tag"]["name"].as_string() == "&int" + assert res["body"][8]["left"][0]["value"]["type_tag"]["name"].as_string() == "&float" + assert res["body"][9]["left"][0]["value"]["type_tag"]["name"].as_string() == "*int" +} + +def #test test_convert { + var str = """ + let a = 10 !float + let b = a !int + + let c = 10 !float + 20 + let d = 10 !uint + 20 + + let e = 200 !bool + let f = 1.5 !bool + let g: *int = null + let h = g !bool + + let i: int64 = 20 + let j: int16 = 20 + + def foo(a: int64) {} + foo(10) + """ + let res = compile(str) + + assert res["body"][0]["left"][0]["value"]["type_tag"]["name"].as_string() == "float" + assert res["body"][1]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" + assert res["body"][2]["left"][0]["value"]["type_tag"]["name"].as_string() == "float" + assert res["body"][3]["left"][0]["value"]["type_tag"]["name"].as_string() == "uint" + assert res["body"][4]["left"][0]["value"]["type_tag"]["name"].as_string() == "bool" + assert res["body"][5]["left"][0]["value"]["type_tag"]["name"].as_string() == "bool" + assert res["body"][6]["left"][0]["value"]["type_tag"]["name"].as_string() == "*int" + assert res["body"][7]["left"][0]["value"]["type_tag"]["name"].as_string() == "bool" +} + +def #test test_member_access { + let str = """ + type T = struct { + a: int + b: double + } + var foo: T + let a = foo.a + let b = foo.b + """ + let res = compile(str) + + assert res["body"][2]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" + assert res["body"][3]["left"][0]["value"]["type_tag"]["name"].as_string() == "double" +} + +def #test test_array_subscript { + let str = """ + var a: [4; int] + let b = a[2] + + var c = 10 + var d = *c + let e = d[2] + """ + let res = compile(str) + + assert res["body"][0]["left"][0]["value"]["type_tag"]["name"].as_string() == "[4; int]" + assert res["body"][1]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" + assert res["body"][2]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" + assert res["body"][3]["left"][0]["value"]["type_tag"]["name"].as_string() == "*int" + assert res["body"][4]["left"][0]["value"]["type_tag"]["name"].as_string() == "int" +} + +def #test test_array_lit { + let str = """ + let a = [1, 2, 3, 4] + let b: [int] = a + """ + let res = compile(str) + + assert res["body"][0]["left"][0]["value"]["type_tag"]["name"].as_string() == "[4; int]" + assert res["body"][1]["left"][0]["value"]["type_tag"]["name"].as_string() == "[int]" +} + +def #test test_array_inference { + let str = """ + let a: [?; int] = [1, 2, 3, 4] + let b: [int] = [1, 2, 3, 4] + """ + let res = compile(str) + + assert res["body"][0]["left"][0]["value"]["type_tag"]["name"].as_string() == "[4; int]" + assert res["body"][1]["left"][0]["value"]["type_tag"]["name"].as_string() == "[int]" +} + +def #test test_array_inference_fail { + let str = """ + let a: [?; float] = [1, 2, 3, 4] + """ + assert compile(str) == null + assert env.err() == strip_margin(" + |main@2:14 + | let a: [?; float] = [1, 2, 3, 4] + | ^~~~~~~~~~~~~ + |Incompatible types [4; int] and [?; float]\n") +} + +def #test test_array_size_and_value { + let str = """ + let a = [1, 2, 3, 4] + let b: [int] = a + let c = a.size + let d = a.value + let e = b.size + let f = b.value + """ + assert compile(str) != null +} + +def #test test_call { + let str = """ + def demo_function_1 + def demo_function_2(a: int) + demo_function_1() // empty function + demo_function_2(42) // function with unnamed parameter + demo_function_2(a=42) // function with named parameter + """ + assert compile(str) != null +} + +def #test test_call_fail { + let str = """ + def demo_function_2(a: int) + demo_function_2(a=42, a=11) // function with named parameter twice + + def no_return + var a: int + a = no_return() + """ + assert compile(str) == null + assert env.err() == strip_margin(" + |main@3:31 + | demo_function_2(a=42, a=11) // function with named parameter twice + | ^~~~ + |Cannot have the same parameter name multiple times in a function call. Parameter name was `a`. + | + |main@7:9 + | a = no_return() + | ^~ + |Incompatible types, can't assign void to int\n") +} + +def #test test_yield { + let str = """ + def some_function -> int { + yield 20 + yield 30 + return 40 + } + for var i in some_function() { + print(i) + } + """ + assert compile(str) != null +} + +def #test test_closure { + let str = """ + def some_function { + var a: int = 4 + def inner_function { + print(a) + let a_ref = *a + @a_ref = 20 + } + inner_function() + } + """ + assert compile(str) != null +} + +def #test test_closure_fail { + let str = """ + def some_function { + export def inner_function {} + def inner_function(a: int = 20) {} + def inner_function(a: int...) {} + } + """ + assert compile(str) == null + assert env.err() == strip_margin(" + |main@3:24 + | export def inner_function {} + | ^~~~~~~~~~~~~~~ + |Invalid modifier to closure + | + |main@4:32 + | def inner_function(a: int = 20) {} + | ^~~~~~~~~~~ + |Can't have default parameters for closure + | + |main@5:32 + | def inner_function(a: int...) {} + | ^~~~~~~~~ + |Can't have varargs for closure\n") +} \ No newline at end of file diff --git a/test/test_ctfe.pr b/test/test_ctfe.pr new file mode 100644 index 00000000..bf467657 --- /dev/null +++ b/test/test_ctfe.pr @@ -0,0 +1,102 @@ +import common + +def #test test_constants { + let src = """ + const c = 4 + def test_constants { + // We can't use pointers here + const c = 4 + assert c == 4 + } + test_constants + assert c == 4 + """ + assert run_source(src) == 0 +} + +def #test test_func_call { + let src = """ + def sum(a: int, b: int) -> int { + return a + b + } + + def test_func_call { + // TODO Varargs don't work for some reason + const sum = sum(10, 20) + assert sum == 30 + } + test_func_call + """ + assert run_source(src) == 0 +} + +def #test test_static_if { + let src = """ + def sum(a: int, b: int) -> int { + return a + b + } + + def test_static_if { + const s = sum(10, 20) + #if s > 10 { + var a: int = 10 + } else { + var a: int = 20 + } + assert a == 10 + } + test_static_if + """ + assert run_source(src) == 0 +} + +def #test test_c_functions { + let src = """ + def return_random_number -> long { + cstd::srand(100) + return cstd::rand() + } + + def test_c_functions { + const ac = return_random_number() + let al = return_random_number() + + assert ac == al + } + test_c_functions + """ + assert run_source(src) == 0 +} + +def #test test_strings { + let src = """ + def append_str(a: string, b: string) -> string { + let res = a + b + return @res + } + + const hello_world = append_str("Hello ", "World!") + + def test_strings { + assert hello_world == "Hello World!" + } + test_strings + """ + assert run_source(src) == 0 +} + +def #test test_bug_1 { + let src = """ + def test_bug_1_ -> bool { + return true == (true == true) + } + + def test_bug_1 { + const ac = test_bug_1_() + let al = test_bug_1_() + assert ac == al == true + } + test_bug_1 + """ + assert run_source(src) == 0 +} \ No newline at end of file diff --git a/src/test/test_getopt.pr b/test/test_getopt.pr similarity index 77% rename from src/test/test_getopt.pr rename to test/test_getopt.pr index cc2270ef..9e3aeace 100644 --- a/src/test/test_getopt.pr +++ b/test/test_getopt.pr @@ -1,16 +1,13 @@ import getopt -import util -import test::testsuite - -def test_positional { +def #test test_positional { let args = ["test", "some", "arg", "more"] let options = [ option("arg1"), option("arg2", 2) ] let parser = *getopt::make_parser(options, "-") - tassert(parser.parse(args)) + assert parser.parse(args) print("arg1: ", parser.get_value("arg1").str, "\n") @@ -20,9 +17,13 @@ def test_positional { print(arg2[i], " ") } print("\n") + + assert env.out() == strip_margin("\ + |arg1: some + |arg2: arg more \n") } -def test_longopts { +def #test test_longopts { let args = [ "test", "--arg1", @@ -38,7 +39,7 @@ def test_longopts { option("--arg5", "default") ] let parser = *getopt::make_parser(options, "-") - tassert(parser.parse(args)) + assert parser.parse(args) print("arg1: ", parser.get_value("--arg1").b, "\n") print("arg2: ", parser.get_value("--arg2").str, "\n") @@ -46,9 +47,16 @@ def test_longopts { let arg4 = parser.get_value("--arg4").arr print("arg4: ", arg4[0], " ", arg4[1], "\n") print("arg5: ", parser.get_value("--arg5").str, "\n") + + assert env.out() == strip_margin("\ + |arg1: true + |arg2: test + |arg3: test + |arg4: foo bar + |arg5: default\n") } -def test_shortopts { +def #test test_shortopts { let args = [ "test", "-ab", @@ -64,7 +72,7 @@ def test_shortopts { option('e', "--arg5", 2) ] let parser = *getopt::make_parser(options, "-") - tassert(parser.parse(args)) + assert parser.parse(args) print("a: ", parser.get_value("--arg1").b, "\n") print("b: ", parser.get_value("--arg2").b, "\n") @@ -72,23 +80,11 @@ def test_shortopts { print("d: ", parser.get_value("--arg4").str, "\n") let arg5 = parser.get_value("--arg5").arr print("e: ", arg5[0], " ", arg5[1], "\n") -} -export def run_tests { - print("Running tests on getopt... \n") - run_test("test_positional", *test_positional, strip_margin("\ - |arg1: some - |arg2: arg more \n"), "") - run_test("test_longopts", *test_longopts, strip_margin("\ - |arg1: true - |arg2: test - |arg3: test - |arg4: foo bar - |arg5: default\n"), "") - run_test("test_shortopts", *test_shortopts, strip_margin("\ + assert env.out() == strip_margin("\ |a: true |b: false |c: Foo |d: test - |e: foo bar\n"), "") -} + |e: foo bar\n") +} \ No newline at end of file diff --git a/test/test_json.pr b/test/test_json.pr index 5eb9be6d..af4b321c 100644 --- a/test/test_json.pr +++ b/test/test_json.pr @@ -1,5 +1,6 @@ import json import optional +import common def #test test_numbers { let data = """ diff --git a/test/test_lexer.pr b/test/test_lexer.pr index e76392fd..a5cb3c2f 100644 --- a/test/test_lexer.pr +++ b/test/test_lexer.pr @@ -2,8 +2,7 @@ import common import json def lex(str: &string) -> &Json { - let file = tmpfolder("princess") + "/main.pr" - return json::parse(common::run_compiler(file, str, "--tokens")) + return json::parse(common::run_compiler_on_source(str, ["--tokens" !&string])) } def #test test_empty_file { diff --git a/test/test_map.pr b/test/test_map.pr new file mode 100644 index 00000000..d75810f7 --- /dev/null +++ b/test/test_map.pr @@ -0,0 +1,71 @@ +import common +import map + +// TODO these tests don't nearly cover all cases +def #test test_map_simple { + let m = map::make(int) + m["foo"] = 20 + m["bar"] = 50 + + assert map::size(m) == 2 + assert m["foo"] == 20 + assert m["bar"] == 50 + + map::remove(m, "foo") + assert map::size(m) == 1 + assert not map::get(m, "foo").exists +} + +def #test test_map_collision { + let m = map::make(int) + m["JUvEoj"] = 20 + m["JVVdoj"] = 50 + + assert map::size(m) == 2 + assert m["JUvEoj"] == 20 + assert m["JVVdoj"] == 50 + + map::remove(m, "JVVdoj") + assert map::size(m) == 1 + assert not map::get(m, "JVVdoj").exists +} + +def #test test_map_resize { + let m = map::make(int, 2) + m["1"] = 1 + m["2"] = 2 + m["3"] = 3 + m["4"] = 4 + + assert map::size(m) == 4 + + assert m["1"] == 1 + assert m["2"] == 2 + assert m["3"] == 3 + assert m["4"] == 4 +} + +def is_in(array: &[&string], key: &string) -> bool { + for var i in 0..array.size { + let value = array[i] + if value == key { + return true + } + } + return false +} + +def #test test_map_keys { + let m = map::make(int) + m["JUvEoj"] = 20 + m["JVVdoj"] = 50 + m["foo"] = 0 + m["bar"] = 1 + + let keys = map::keys(m) + assert keys.size == 4 + assert is_in(keys, "JUvEoj") + assert is_in(keys, "JVVdoj") + assert is_in(keys, "foo") + assert is_in(keys, "bar") +} \ No newline at end of file diff --git a/test/test_parser.pr b/test/test_parser.pr index 645144f6..e5fb9558 100644 --- a/test/test_parser.pr +++ b/test/test_parser.pr @@ -2,8 +2,7 @@ import json import common def parse(str: &string) -> &Json { - let file = tmpfolder("princess") + "/main.pr" - return json::parse(common::run_compiler(file, str, "--ast")) + return json::parse(common::run_compiler_on_source(str, ["--ast" !&string])) } def program(jsn: &Json) -> &Json { diff --git a/test/test_runtime.pr b/test/test_runtime.pr new file mode 100644 index 00000000..598a08a0 --- /dev/null +++ b/test/test_runtime.pr @@ -0,0 +1,729 @@ +import common + +def #test test_vector { + assert run_file(test_file("test_vector")) == 0 + assert env.out() == strip_margin("\ + |Destructing Vector + |0 20 30 40 + |Destructing S: 40 + |Destructing S: 30 + |Destructing S: 20 + |Destructing S: 0 + |Destructing Vector + |Destructing Vector + |Destructing S: 20 + |Destructing S: 30 + |Destructing S: 40 + |Destructing S: 0\n" + ) +} + +def #test test_loop { + let src = """ + def test_loop { + var cnt = 0 + while cnt < 10 { + print(cnt) + cnt += 1 + } + print("\n") + + for var i in 0..10 { + print(i) + } + print("\n") + + let foo: *int = null + while foo != null { + @foo = 10 + } + + for var i in 0..10 { + if i == 5 { continue } + print(i) + } + print("\n") + } + test_loop + """ + assert run_source(src) == 0 + assert env.out() == strip_margin("\ + |0123456789 + |0123456789 + |012346789\n" + ) +} + +def #test test_import { + assert run_file(test_file("test_imports")) == 0 + assert env.out() == "0\n" +} + +def #test test_print { + let src = """ + type Point = struct { + x: int + y: int + } + + def test_print { + let a = 20 + let b = 0xDEADBABE !* + print("Hello World ", 1, " ", 'x', " ", 10.5, " ", b, "\n") + error("Hello World ", 1, " ", 'x', " ", 10.5, " ", b, "\n") + + let point: Point = {10, 20} + print(point, "\n") + + let array = [1, 2, 3, 4] + print(array, "\n") + } + test_print + """ + assert run_source(src) == 0 + assert env.out() == strip_margin("\ + |Hello World 1 x 10.500000 0xdeadbabe + |{x = 10, y = 20} !main::Point + |[1, 2, 3, 4]\n" + ) + assert env.err() == strip_margin("\ + |Hello World 1 x 10.500000 0xdeadbabe\n" + ) +} + +def #test test_function_calls { + let src = """ + def pass_dynamic_array(a: string) { + print(a) + } + + def function(a: int, b: double) -> double { return a * b } + def function(b: double, a: int) -> double { return a * b } + def function -> int { return 10 } + + def test_function_calls { + pass_dynamic_array("Some string\n") + pass_dynamic_array(a = "Named parameter\n") + + function(2, 1.5) + function(1.5, 2) + function(2, b = 1.5) + function(1.5, a = 2) + // function(a = 1, b = 1.5) # Ambiguous reference + + assert function == 10 + } + test_function_calls + """ + assert run_source(src) == 0 + assert env.out() == strip_margin("\ + |Some string + |Named parameter\n" + ) +} + +def #test test_length { + let src = """ + def test_length { + let a = "Some string" + assert length(a) == 11 + assert a.length == 11 + } + test_length + """ + assert run_source(src) == 0 +} + +def #test test_allocate { + let src = """ + def test_allocate { + let a = allocate(size_of int) !*int + @a = 10 + assert @a == 10 + free(a) + + let b = allocate(int) + @b = 20 + assert @b == 20 + free(b) + + let c = allocate(int, 10) + c[0] = 10 + c[9] = 20 + assert c[0] == 10 + assert c[9] == 20 + free(c) + } + test_allocate + """ + assert run_source(src) == 0 +} + +def #test test_file_binary { + let src = """ + def test_file_binary { + let fp = open("tmp/test_file_io_binary", "wb+") + + let str = "Some text" + write(fp, str) + let i = 10 + write(fp, *i) + + rewind(fp) + + var str2: [10; char] + read(fp, str2) + print(str2, "\n") + + var i2: int + read(fp, *i2) + print(i2, "\n") + + close(fp) + } + test_file_binary + """ + assert run_source(src) == 0 +} + +def #test test_file_text { + let src = """ + def test_file_text { + let fp = open("tmp/test_file_io_text", "w+") + + fprint(fp, "This is a test\n", 10) + + seek(fp, 0, SEEK_SET) // Same as rewind + + var buffer: [20; char] + read_line(fp, buffer) + print(buffer) + var num: int + cstd::fscanf(fp, "%d".value, *num) + print(num, "\n") + + close(fp) + } + test_file_text + """ + assert run_source(src) == 0 +} + +def #test test_operators { + // TODO We need to test a lot more + let src = """ + def test_operators { + let g = true and false + let h = true and true + let i = false and true + assert not g + assert h + assert not i + } + test_operators + """ + assert run_source(src) == 0 +} + +def #test test_enum { + let src = """ + type Enum = enum { + A = 10; + B; C; D + } + + type Enum2 = enum { + A = 10 + B = A + C + } + + def pass_enum(a: Enum) {} + + def test_enum { + assert Enum::A == 10 + assert Enum::B == 11 + pass_enum(Enum::A) + let a = Enum::A !int + let b = 10 !Enum + pass_enum(b) + + print(to_string(Enum::A), "\n") + print(Enum::B, "\n") + } + test_enum + """ + assert run_source(src) == 0 + assert env.out() == strip_margin("\ + |A + |11\n" + ) +} + +def #test test_function_pointers { + let src = """ + def some_function { + print("Hello\n") + } + + def test_function_pointers { + let function = *some_function + function() + } + test_function_pointers + """ + assert run_source(src) == 0 + assert env.out() == "Hello\n" +} + +def #test test_structs { + let src = """ + type Struct = struct { + a: &string + b: int + c: char + } + + def test_structs { + let s = { + c = 10 + } !Struct + assert s.a == null + assert s.c == 10 + assert s.b == 0 + } + test_structs + """ + assert run_source(src) == 0 +} + +def #test test_unions { + let src = """ + type Union = struct #union { + a: string + b: long + c: int + } + + def test_unions { + let u = { + "some string" + } !Union + print(u, "\n") + + let u2 = { + b = 20 + } !Union + u2.b = 120 + print(u2.c, "\n") + + let u3 = {} !Union + } + test_unions + """ + assert run_source(src) == 0 + assert env.out() == strip_margin("\ + |{a = some string, b = 12, c = 12} !main::Union + |120\n" + ) +} + +def #test test_strings { + let src = """ + def test_strings { + let stra = "Some value" + assert stra == "Some value" + assert stra != "Other value" + } + test_strings + """ + assert run_source(src) == 0 +} + +def #test test_if_stmts { + let src = """ + def test_if_stmts { + if false { + print("false\n") + } else if starts_with("foo", "f") { + print("true\n") + } else { + print("false\n") + } + } + test_if_stmts + """ + assert run_source(src) == 0 + assert env.out() == "true\n" +} + +def #test test_recursion { + let src = """ + def fact(n: int) -> int { + if n <= 1 { return 1 } + else { + return n * fact(n - 1) + } + } + + def test_recursion { + assert fact(10) == 3628800 + } + test_recursion + """ + assert run_source(src) == 0 +} + +def #test test_scoping { + let src = """ + def test_scoping { + var a = 10 + if true { + assert a == 10 + a = 15 + var a = 20 + assert a == 20 + } + assert a == 15 + } + """ + assert run_source(src) == 0 +} + +def #test test_arrays { + let src = """ + def pass_array(a: [int]) { + for var i in 0..a.size { + print(a[i], " ") + } + print("\n") + } + + def test_arrays { + let a = [10, 20, 30] + let b = [] ![int] + pass_array(a) + pass_array(b) + } + test_arrays + """ + assert run_source(src) == 0 + assert env.out() == "10 20 30 \n\n" +} + +def #test test_deref { + let src = """ + type Struct2 = struct { + a: int + t: *Struct2 + } + + def test_deref { + let s = allocate(Struct2) + s.a = 10 + s.t = allocate(Struct2) + s.t.a = 20 + print(s.a, " ", s.t.a, "\n") + } + test_deref + """ + assert run_source(src) == 0 + assert env.out() == "10 20\n" +} + +def #test test_ucs { + let src = """ + type Struct2 = struct { + a: int + t: *Struct2 + } + + def function(s: Struct2) -> int { return s.a } + def function(s: Struct2, a: int) -> int { return s.a + a } + def inc(a: int) -> int { return a + 1} + + def test_ucs { + let s: Struct2 = { 10, null } + + assert s.function() == 10 + assert s.function.inc == 11 + assert s.function(10).inc() == 21 + } + test_ucs + """ + assert run_source(src) == 0 +} + +def #test test_anonymous { + let src = """ + type Struct3 = struct { + a: int + b: struct { + c: int + d: int + } + struct #union { + e: int64 + f: double + } + } + + def test_anonymous { + var s: Struct3 + s = {10, {20, 30}} + s.a = 10 + s.b = {20, 30} + s.e = 0x4034800000000000 + + print(s.f, "\n") + } + test_anonymous + """ + assert run_source(src) == 0 + assert env.out() == "20.500000\n" +} + +def #test test_varargs { + let src = """ + def sum(args: int...) -> int { + var sum = 0 + for var i in 0..args.size { + sum += args[i] + } + return sum + } + + def my_print(args: string...) { + for var i in 0..args.size { + print(args[i], " ") + } + print("\n") + } + + def test_varargs { + assert sum(1, 2, 3) == 6 + assert sum([1, 2, 3]) == 6 + my_print("foo", "bar", "baz") + } + test_varargs + """ + assert run_source(src) == 0 + assert env.out() == "foo bar baz \n" +} + +def #test test_if_expression { + let src = """ + type Struct = struct { + a: &string + b: int + c: char + } + + def test_if_expression { + // TODO I've seen these fail but I can't quite pin down what's wrong with them + var a = 10 if 10 > 20 else 20 + assert a == 20 + var b: int + @(*a if 10 > 20 else *b) = 30 + assert b == 30 + + let c = { c = 10 } !Struct + let d = { c = 0 } !Struct if 10 > 20 else c + assert d.c == 10 + } + test_if_expression + """ + assert run_source(src) == 0 +} + +def #test test_default_parameters { + let src = """ + def takes_default_param(a: int = 0, b: string = "some value") { + print(a, " ", b, "\n") + } + + def test_default_parameters { + takes_default_param() + takes_default_param(10) + takes_default_param(20, "Hello world!") + } + test_default_parameters + """ + assert run_source(src) == 0 + assert env.out() == strip_margin("\ + |0 some value + |10 some value + |20 Hello world!\n" + ) +} + +def #test test_function_overloads { + let src = """ + def function(a: int, b: double) -> double { return a * b } + def function(b: double, a: int) -> double { return a * b } + def function -> int { return 10 } + + def test_function_overloads { + let f1 = *function::() + let f2 = *function::(int, double) + let f3 = *function::(double, int) + + assert f1() == 10 + assert f2(10, 10.5) == 105 + assert f3(10.5, 10) == 105 + } + test_function_overloads + """ + assert run_source(src) == 0 +} + +def #test test_underscore { + let src = """ + def test_underscore { + let _, _ = 10, 20 + assert _ == 20 + _ = "Hello World!" + assert _ == "Hello World!" + } + test_underscore + """ + assert run_source(src) == 0 +} + +def #test test_def_polymorph { + let src = """ + type Struct = struct { + a: &string + b: int + c: char + } + + def function(type T) -> size_t { + return T.size + } + + def add(a: type T, b: T) -> T { + return a + b + } + + def test_def_polymorph { + assert function(int) == 4 + assert function(Struct) == 32 + + assert add(10, 10) == 20 + assert add(10.5, 20.5) == 31.0 + } + test_def_polymorph + """ + assert run_source(src) == 0 +} + +def #test test_type_of { + let src = """ + def test_type_of { + let a = 20 + let b: (type_of a) = 30 + type T = type_of a + + assert T == int + assert (type_of b) == int + } + test_type_of + """ + assert run_source(src) == 0 +} + +def #test test_reflection { + assert run_file(test_file("test_reflection")) == 0 +} + +def #test test_yield { + let src = """ + def range_for(a: int, b: int) -> int { + for var i in a..b { + yield i + } + } + + def range_while(a: int, b: int) -> int { + var i = a + while i < b { + yield i + i = i + 1 + } + } + + def test_yield { + for var i in range_for(0, 10) { + print(i, " ") + } + print("\n") + + for var i in range_while(0, 10) { + print(i, " ") + } + print("\n") + } + test_yield + """ + assert run_source(src) == 0 + assert env.out() == strip_margin("\ + |0 1 2 3 4 5 6 7 8 9 + |0 1 2 3 4 5 6 7 8 9 \n" + ) +} + +def #test test_generators { + let src = """ + type Struct5 = struct { + a: int; b: int; c: int + } + + def iterate(s: *Struct5) -> int { + yield s.a + yield s.b + yield s.c + } + + def test_generators { + let s = { 10, 20, 30 } !Struct5 + + for var i in *s { + print(i, " ") + } + print("\n") + } + test_generators + """ + assert run_source(src) == 0 + assert env.out() == strip_margin("\ + |10 20 30 \n" + ) +} + +def #test test_closures { + let src = """ + def test_closures { + def inner(a: int) -> int { + def inner -> int { + return a + } + return inner() + } + assert inner(10) == 10 + + var a = 20 + var b = 30 + def capture { + assert a == 20 + let local = *b + @local = 40 + assert @local == 40 + } + capture() + assert b == 40 + } + test_closures + """ + assert run_source(src) == 0 +} \ No newline at end of file diff --git a/travis.py b/travis.py index 8dafc69f..b1518266 100644 --- a/travis.py +++ b/travis.py @@ -3,7 +3,13 @@ import subprocess import build import os +import sys +def compile(extra): + args = [build.exe_file("bin/princess2"), "--no-incremental", "-d", "-Isrc", "--buildfolder=build", "--outfile", build.exe_file("bin/princess3"), "src/main.pr"] + if sys.platform == "win32": + args += build.WIN_ARGS + subprocess.check_call(args + extra) def main(): Path("build").mkdir(exist_ok = True) @@ -15,8 +21,13 @@ def main(): build.testrunner([]) print("Running test suite") - os.environ["PRINCESS_COMPILER"] = build.exe_file("bin/princess2") - subprocess.check_call(["bin/testrunner", "./test"]) + # TODO also test on windows + if sys.platform != "win32": + os.environ["PRINCESS_COMPILER"] = build.exe_file("bin/princess2") + subprocess.check_call(["bin/testrunner", "./test"]) + + print("Bootstrapping...") + compile([]) if __name__ == "__main__": main() \ No newline at end of file diff --git a/version b/version index fd77cfda..80e8e28f 100644 --- a/version +++ b/version @@ -1 +1 @@ -VERSION=0.3.3 \ No newline at end of file +VERSION=0.3.4 \ No newline at end of file