From 3e19d62669d899a55585b535614261036c4bf579 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Thu, 15 May 2025 20:28:31 +0200 Subject: [PATCH 01/22] feat(cmake): adding define when we are building an exe, to be able to enable/disable code for embedding/the interpreter --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 04edbf55..bbb4b044 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -264,6 +264,9 @@ if (ARK_BENCHMARKS) endif () if (ARK_BUILD_EXE) + # ArkScript lib needs to know if we are building an exe to enable/disable specific code for embedding + target_compile_definitions(ArkReactor PRIVATE ARK_BUILD_EXE=1) + # additional files needed for the exe (repl, command line and stuff) file(GLOB_RECURSE EXE_SOURCES ${ark_SOURCE_DIR}/src/arkscript/*.cpp From c1448410bc88d259278870126a64684fcb27ec43 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Thu, 15 May 2025 20:29:19 +0200 Subject: [PATCH 02/22] feat: check for NOCOLOR env var only when building an exe --- src/arkreactor/Exceptions.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/arkreactor/Exceptions.cpp b/src/arkreactor/Exceptions.cpp index 582e5092..48ce05c4 100644 --- a/src/arkreactor/Exceptions.cpp +++ b/src/arkreactor/Exceptions.cpp @@ -325,8 +325,10 @@ namespace Ark::Diagnostics void generate(const CodeError& e, std::ostream& os, bool colorize) { +#ifdef ARK_BUILD_EXE if (const char* nocolor = std::getenv("NOCOLOR"); nocolor != nullptr) colorize = false; +#endif std::string escaped_symbol; if (e.context.symbol.has_value()) From 1ad14f4d3dde7cc71cd41ed4a48599f7eb0c9664 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Thu, 15 May 2025 21:12:03 +0200 Subject: [PATCH 03/22] feat(tools): adding more commands to fuzzer-crash-triage.py script r to run the code again x to show the source --- tests/fuzzing/fuzzer-crash-triage.py | 57 ++++++++++++++++++---------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/tests/fuzzing/fuzzer-crash-triage.py b/tests/fuzzing/fuzzer-crash-triage.py index c4004298..5ecce88f 100755 --- a/tests/fuzzing/fuzzer-crash-triage.py +++ b/tests/fuzzing/fuzzer-crash-triage.py @@ -2,19 +2,54 @@ import sys import os +arkscript = None +if os.path.exists("cmake-build-debug/arkscript"): + arkscript = "cmake-build-debug/arkscript" +elif os.path.exists("build/arkscript"): + arkscript = "build/arkscript" +else: + print("Couldn't find a suitable arkscript executable") + sys.exit(1) + +if not os.path.exists("fct-ok"): + os.mkdir("fct-ok") +if not os.path.exists("fct-bad"): + os.mkdir("fct-bad") + + +def run_file(file: str): + print(f"{file}\n{'-' * len(file)}") + exit_code = os.system(f"{arkscript} \"{file}\"") + print(f"\nEXITCODE: {exit_code}\n\n") + def handle_command(i: int, count: int, file: str): - command = input(f"[{i}/{count}] o,c,s,q,? > ").strip().lower() + command = input(f"[{i}/{count}] o,c,r,x,s,q,? > ").strip().lower() if command == "o": os.rename(file, f"fct-ok/{os.path.basename(file)}") elif command == "c": os.rename(file, f"fct-bad/{os.path.basename(file)}") + elif command == "r": + run_file(file) + return True + elif command == "x": + with open(file) as f: + print(f.read()) + return True elif command == "s": pass elif command == "q": sys.exit(0) elif command == "?": - print("\to: ok, not a crash\n\tc: crash\n\ts: skip\n\tq: quit\n\t?: this help message") + messages = [ + "o: ok, not a crash", + "c: crash", + "r: run again", + "x: show source code", + "s: skip", + "q: quit", + "?: this help message"] + print("\t" + "\n\t".join(messages)) return True else: print("Unknown command.") @@ -23,20 +58,6 @@ def handle_command(i: int, count: int, file: str): def main(): - arkscript = None - if os.path.exists("cmake-build-debug/arkscript"): - arkscript = "cmake-build-debug/arkscript" - elif os.path.exists("build/arkscript"): - arkscript = "build/arkscript" - else: - print("Couldn't find a suitable arkscript executable") - sys.exit(1) - - if not os.path.exists("fct-ok"): - os.mkdir("fct-ok") - if not os.path.exists("fct-bad"): - os.mkdir("fct-bad") - args = [f for f in sys.argv[1:] if "__arkscript__" not in f] files_count = len(args) @@ -46,9 +67,7 @@ def main(): for i, file in enumerate(args): if os.path.exists(file) and os.path.isfile(file): - print(f"{file}\n{'-' * len(file)}") - os.system(f"{arkscript} \"{file}\"") - print("\n\n") + run_file(file) while handle_command(i + 1, files_count, file): pass print() From eab73b1fdc4387bceae73e9f5e86f3c8d7448cae Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Sat, 17 May 2025 18:14:53 +0200 Subject: [PATCH 04/22] refactor(parser): adding a limit to the number of node that can be nested while parsing --- include/Ark/Compiler/AST/Parser.hpp | 5 +- include/Ark/Constants.hpp.in | 1 + src/arkreactor/Compiler/AST/Parser.cpp | 98 ++++++++++--------- .../ParserSuite/failure/deeply_nested.ark | 37 +++++++ .../failure/deeply_nested.expected | 10 ++ 5 files changed, 106 insertions(+), 45 deletions(-) create mode 100644 tests/unittests/resources/ParserSuite/failure/deeply_nested.ark create mode 100644 tests/unittests/resources/ParserSuite/failure/deeply_nested.expected diff --git a/include/Ark/Compiler/AST/Parser.hpp b/include/Ark/Compiler/AST/Parser.hpp index 70bf67be..d1060e5d 100644 --- a/include/Ark/Compiler/AST/Parser.hpp +++ b/include/Ark/Compiler/AST/Parser.hpp @@ -19,8 +19,9 @@ #include #include -#include #include +#include +#include #include @@ -61,6 +62,8 @@ namespace Ark::internal Node m_ast; std::vector m_imports; unsigned m_allow_macro_behavior; ///< Toggled on when inside a macro definition, off afterward + std::size_t m_nested_nodes; ///< Nested node counter + std::vector()>> m_parsers; /** * @brief Update a node given a file position diff --git a/include/Ark/Constants.hpp.in b/include/Ark/Constants.hpp.in index fcc0cbb9..89f71be9 100644 --- a/include/Ark/Constants.hpp.in +++ b/include/Ark/Constants.hpp.in @@ -62,6 +62,7 @@ namespace Ark | FeatureIROptimizer | FeatureNameResolver; + constexpr std::size_t MaxNestedNodes = 1024; ///< Maximum number of nodes that can be nested while parsing code constexpr std::size_t MaxMacroProcessingDepth = 256; ///< Controls the number of recursive calls to MacroProcessor::processNode constexpr std::size_t MaxMacroUnificationDepth = 256; ///< Controls the number of recursive calls to MacroProcessor::unify constexpr std::size_t VMStackSize = 4096; diff --git a/src/arkreactor/Compiler/AST/Parser.cpp b/src/arkreactor/Compiler/AST/Parser.cpp index 65c5de08..816a323c 100644 --- a/src/arkreactor/Compiler/AST/Parser.cpp +++ b/src/arkreactor/Compiler/AST/Parser.cpp @@ -6,9 +6,46 @@ namespace Ark::internal { Parser::Parser(const unsigned debug, const bool interpret) : BaseParser(), m_interpret(interpret), m_logger("Parser", debug), - m_ast(NodeType::List), m_imports({}), m_allow_macro_behavior(0) + m_ast(NodeType::List), m_imports({}), m_allow_macro_behavior(0), + m_nested_nodes(0) { m_ast.push_back(Node(Keyword::Begin)); + + m_parsers = { + [this]() { + return wrapped(&Parser::letMutSet, "variable assignment or declaration"); + }, + [this]() { + return wrapped(&Parser::function, "function"); + }, + [this]() { + return wrapped(&Parser::condition, "condition"); + }, + [this]() { + return wrapped(&Parser::loop, "loop"); + }, + [this]() { + return import_(); + }, + [this]() { + return block(); + }, + [this]() { + return wrapped(&Parser::macroCondition, "$if"); + }, + [this]() { + return macro(); + }, + [this]() { + return wrapped(&Parser::del, "del"); + }, + [this]() { + return functionCall(); + }, + [this]() { + return list(); + } + }; } void Parser::process(const std::string& filename, const std::string& code) @@ -78,54 +115,27 @@ namespace Ark::internal std::optional Parser::node() { - // save current position in buffer to be able to go back if needed - const auto position = getCount(); - - if (auto result = wrapped(&Parser::letMutSet, "variable assignment or declaration")) - return result; - backtrack(position); - - if (auto result = wrapped(&Parser::function, "function")) - return result; - backtrack(position); - - if (auto result = wrapped(&Parser::condition, "condition")) - return result; - backtrack(position); - - if (auto result = wrapped(&Parser::loop, "loop")) - return result; - backtrack(position); - - if (auto result = import_(); result.has_value()) - return result; - backtrack(position); + ++m_nested_nodes; - if (auto result = block(); result.has_value()) - return result; - backtrack(position); - - if (auto result = wrapped(&Parser::macroCondition, "$if")) - return result; - backtrack(position); + if (m_nested_nodes > MaxNestedNodes) + errorWithNextToken(fmt::format("Too many nested node while parsing, exceeds limit of {}. Consider rewriting your code by breaking it in functions and macros.", MaxNestedNodes)); - if (auto result = macro(); result.has_value()) - return result; - backtrack(position); - - if (auto result = wrapped(&Parser::del, "del")) - return result; - backtrack(position); + // save current position in buffer to be able to go back if needed + const auto position = getCount(); + std::optional result = std::nullopt; - if (auto result = functionCall(); result.has_value()) - return result; - backtrack(position); + for (auto&& parser : m_parsers) + { + result = parser(); - if (auto result = list(); result.has_value()) - return result; - backtrack(position); + if (result) + break; + backtrack(position); + } - return std::nullopt; // will never reach + // return std::nullopt only on parsing error, nothing matched, the user provided terrible code + --m_nested_nodes; + return result; } std::optional Parser::letMutSet() diff --git a/tests/unittests/resources/ParserSuite/failure/deeply_nested.ark b/tests/unittests/resources/ParserSuite/failure/deeply_nested.ark new file mode 100644 index 00000000..b08a23bb --- /dev/null +++ b/tests/unittests/resources/ParserSuite/failure/deeply_nested.ark @@ -0,0 +1,37 @@ +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((((((((( +func 1 2 3 +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))))))))) diff --git a/tests/unittests/resources/ParserSuite/failure/deeply_nested.expected b/tests/unittests/resources/ParserSuite/failure/deeply_nested.expected new file mode 100644 index 00000000..b3020839 --- /dev/null +++ b/tests/unittests/resources/ParserSuite/failure/deeply_nested.expected @@ -0,0 +1,10 @@ +In file tests/unittests/resources/ParserSuite/failure/deeply_nested.ark:9 +At ( @ 9:73 + 6 | ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( + 7 | ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( + 8 | ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( + 9 | ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( + | ^ + 10 | ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( + 11 | ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( + Too many nested node while parsing, exceeds limit of 1024. Consider rewriting your code by breaking it in functions and macros. From f440062519b034d18b2396c8ace72faf244b9a04 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Wed, 21 May 2025 18:24:20 +0200 Subject: [PATCH 05/22] feat(syntax)!: using 'macro' instead of '$' to define macros --- CHANGELOG.md | 4 +- examples/macros.ark | 28 ++++---- lib/std | 2 +- src/arkreactor/Compiler/AST/Node.cpp | 2 +- src/arkreactor/Compiler/AST/Parser.cpp | 4 +- .../Compiler/Macros/Executors/Function.cpp | 2 +- .../Compiler/Macros/Executors/Symbol.cpp | 2 +- src/arkreactor/Compiler/Macros/Processor.cpp | 2 +- src/arkscript/Formatter.cpp | 2 +- tests/fuzzing/arkscript.dict | 1 + tests/fuzzing/corpus-cmin-tmin/d.ark | 14 ++-- .../corpus-cmin-tmin/examples_macros.ark | 28 ++++---- ...suite_compiletime_argcount_unknown_arg.ark | 6 +- ...sticssuite_compiletime_at_out_of_range.ark | 2 +- ...cssuite_compiletime_bad_macro_arg_list.ark | 2 +- ...osticssuite_compiletime_duplicated_arg.ark | 2 +- ...ticssuite_compiletime_incomplete_macro.ark | 2 +- ...gnosticssuite_compiletime_invalid_func.ark | 2 +- ...agnosticssuite_compiletime_invalid_let.ark | 4 +- ...suite_compiletime_invalid_let_in_macro.ark | 2 +- ...suite_compiletime_invalid_sym_func_def.ark | 2 +- ...nosticssuite_compiletime_invalid_while.ark | 2 +- ...te_compiletime_macro_empty_arity_error.ark | 2 +- ...ite_compiletime_macro_head_arity_error.ark | 2 +- ...uite_compiletime_macro_len_arity_error.ark | 2 +- ...te_compiletime_macro_paste_arity_error.ark | 2 +- ...mpiletime_macro_spread_not_enough_args.ark | 2 +- ...ompiletime_macro_symcat_arg_type_error.ark | 2 +- ...e_compiletime_macro_symcat_arity_error.ark | 2 +- ...te_compiletime_macro_symcat_type_error.ark | 2 +- ...ite_compiletime_macro_tail_arity_error.ark | 2 +- ...diagnosticssuite_compiletime_max_depth.ark | 2 +- ...osticssuite_compiletime_max_depth_eval.ark | 2 +- ...uite_compiletime_max_unification_depth.ark | 12 ++-- ...ticssuite_compiletime_reused_macro_arg.ark | 2 +- ...nosticssuite_compiletime_too_many_args.ark | 2 +- ...cssuite_compiletime_unevaluated_spread.ark | 2 +- ...ticssuite_compiletime_well_formed_args.ark | 2 +- ...formattersuite_comment_after_macro_arg.ark | 2 +- ...ces_formattersuite_comments_after_call.ark | 2 +- ...ttests_resources_formattersuite_macros.ark | 8 +-- ...ttests_resources_langsuite_macro-tests.ark | 68 +++++++++---------- ...s_parsersuite_failure_incomplete_macro.ark | 2 +- ...ite_failure_incomplete_macro_arguments.ark | 2 +- ...rsuite_failure_incomplete_macro_spread.ark | 2 +- ...ts_resources_parsersuite_success_macro.ark | 14 ++-- ...rces_rosettasuite_extend_your_language.ark | 2 +- tests/fuzzing/corpus-cmin/d.ark | 14 ++-- tests/fuzzing/corpus-cmin/examples_macros.ark | 28 ++++---- ...suite_compiletime_argcount_unknown_arg.ark | 6 +- ...sticssuite_compiletime_at_out_of_range.ark | 2 +- ...cssuite_compiletime_bad_macro_arg_list.ark | 2 +- ...osticssuite_compiletime_duplicated_arg.ark | 2 +- ...ticssuite_compiletime_incomplete_macro.ark | 2 +- ...gnosticssuite_compiletime_invalid_func.ark | 2 +- ...agnosticssuite_compiletime_invalid_let.ark | 4 +- ...suite_compiletime_invalid_let_in_macro.ark | 2 +- ...suite_compiletime_invalid_sym_func_def.ark | 2 +- ...nosticssuite_compiletime_invalid_while.ark | 2 +- ...te_compiletime_macro_empty_arity_error.ark | 2 +- ...ite_compiletime_macro_head_arity_error.ark | 2 +- ...uite_compiletime_macro_len_arity_error.ark | 2 +- ...te_compiletime_macro_paste_arity_error.ark | 2 +- ...mpiletime_macro_spread_not_enough_args.ark | 2 +- ...ompiletime_macro_symcat_arg_type_error.ark | 2 +- ...e_compiletime_macro_symcat_arity_error.ark | 2 +- ...te_compiletime_macro_symcat_type_error.ark | 2 +- ...ite_compiletime_macro_tail_arity_error.ark | 2 +- ...diagnosticssuite_compiletime_max_depth.ark | 2 +- ...osticssuite_compiletime_max_depth_eval.ark | 2 +- ...uite_compiletime_max_unification_depth.ark | 12 ++-- ...ticssuite_compiletime_reused_macro_arg.ark | 2 +- ...nosticssuite_compiletime_too_many_args.ark | 2 +- ...cssuite_compiletime_unevaluated_spread.ark | 2 +- ...ticssuite_compiletime_well_formed_args.ark | 2 +- ...formattersuite_comment_after_macro_arg.ark | 2 +- ...ces_formattersuite_comments_after_call.ark | 2 +- ...ttests_resources_formattersuite_macros.ark | 8 +-- ...ttests_resources_langsuite_macro-tests.ark | 68 +++++++++---------- ...s_parsersuite_failure_incomplete_macro.ark | 2 +- ...ite_failure_incomplete_macro_arguments.ark | 2 +- ...rsuite_failure_incomplete_macro_spread.ark | 2 +- ...ts_resources_parsersuite_success_macro.ark | 14 ++-- ...rces_rosettasuite_extend_your_language.ark | 2 +- tests/fuzzing/corpus/d.ark | 14 ++-- tests/fuzzing/corpus/examples_macros.ark | 28 ++++---- ...ts_unittests_resources_astsuite_macros.ark | 28 ++++---- ...suite_compiletime_argcount_unknown_arg.ark | 6 +- ...sticssuite_compiletime_at_out_of_range.ark | 2 +- ...cssuite_compiletime_bad_macro_arg_list.ark | 2 +- ...osticssuite_compiletime_duplicated_arg.ark | 2 +- ...ticssuite_compiletime_incomplete_macro.ark | 2 +- ...gnosticssuite_compiletime_invalid_func.ark | 2 +- ...agnosticssuite_compiletime_invalid_let.ark | 4 +- ...suite_compiletime_invalid_let_in_macro.ark | 2 +- ...suite_compiletime_invalid_sym_func_def.ark | 2 +- ...nosticssuite_compiletime_invalid_while.ark | 2 +- ...te_compiletime_macro_empty_arity_error.ark | 2 +- ...ite_compiletime_macro_head_arity_error.ark | 2 +- ...uite_compiletime_macro_len_arity_error.ark | 2 +- ...te_compiletime_macro_paste_arity_error.ark | 2 +- ...mpiletime_macro_spread_not_enough_args.ark | 2 +- ...ompiletime_macro_symcat_arg_type_error.ark | 2 +- ...e_compiletime_macro_symcat_arity_error.ark | 2 +- ...te_compiletime_macro_symcat_type_error.ark | 2 +- ...ite_compiletime_macro_tail_arity_error.ark | 2 +- ...diagnosticssuite_compiletime_max_depth.ark | 2 +- ...osticssuite_compiletime_max_depth_eval.ark | 2 +- ...uite_compiletime_max_unification_depth.ark | 12 ++-- ...sticssuite_compiletime_not_enough_args.ark | 2 +- ...ticssuite_compiletime_reused_macro_arg.ark | 2 +- ...nosticssuite_compiletime_too_many_args.ark | 2 +- ...cssuite_compiletime_unevaluated_spread.ark | 2 +- ...ticssuite_compiletime_well_formed_args.ark | 2 +- ...formattersuite_comment_after_macro_arg.ark | 2 +- ...ces_formattersuite_comments_after_call.ark | 2 +- ...ts_resources_formattersuite_macro_cond.ark | 2 +- ...ttests_resources_formattersuite_macros.ark | 8 +-- ...ttests_resources_langsuite_macro-tests.ark | 68 +++++++++---------- ...s_parsersuite_failure_incomplete_macro.ark | 2 +- ...ite_failure_incomplete_macro_arguments.ark | 2 +- ...rsuite_failure_incomplete_macro_spread.ark | 2 +- ...ts_resources_parsersuite_success_macro.ark | 14 ++-- ...rces_rosettasuite_extend_your_language.ark | 2 +- tests/unittests/resources/ASTSuite/macros.ark | 28 ++++---- .../compileTime/argcount_unknown_arg.ark | 6 +- .../compileTime/argcount_unknown_arg.expected | 2 +- .../compileTime/at_out_of_range.ark | 2 +- .../compileTime/at_out_of_range.expected | 6 +- .../compileTime/duplicated_arg.ark | 2 +- .../compileTime/duplicated_arg.expected | 6 +- .../compileTime/incomplete_macro.ark | 2 +- .../compileTime/incomplete_macro.expected | 6 +- .../compileTime/invalid_func.ark | 2 +- .../compileTime/invalid_func.expected | 2 +- .../compileTime/invalid_let.ark | 4 +- .../compileTime/invalid_let_in_macro.ark | 2 +- .../compileTime/invalid_let_in_macro.expected | 6 +- .../compileTime/invalid_sym_func_def.ark | 2 +- .../compileTime/invalid_sym_func_def.expected | 2 +- .../compileTime/invalid_while.ark | 2 +- .../compileTime/invalid_while.expected | 6 +- .../compileTime/macro_empty_arity_error.ark | 2 +- .../macro_empty_arity_error.expected | 6 +- .../compileTime/macro_head_arity_error.ark | 2 +- .../macro_head_arity_error.expected | 6 +- .../compileTime/macro_len_arity_error.ark | 2 +- .../macro_len_arity_error.expected | 6 +- .../compileTime/macro_paste_arity_error.ark | 2 +- .../macro_paste_arity_error.expected | 6 +- .../macro_spread_not_enough_args.ark | 2 +- .../macro_spread_not_enough_args.expected | 2 +- .../macro_symcat_arg_type_error.ark | 2 +- .../macro_symcat_arg_type_error.expected | 6 +- .../compileTime/macro_symcat_arity_error.ark | 2 +- .../macro_symcat_arity_error.expected | 6 +- .../compileTime/macro_symcat_type_error.ark | 2 +- .../macro_symcat_type_error.expected | 6 +- .../compileTime/macro_tail_arity_error.ark | 2 +- .../macro_tail_arity_error.expected | 6 +- .../compileTime/max_depth.ark | 2 +- .../compileTime/max_depth.expected | 6 +- .../compileTime/max_depth_eval.ark | 2 +- .../compileTime/max_depth_eval.expected | 6 +- .../compileTime/max_unification_depth.ark | 12 ++-- .../max_unification_depth.expected | 14 ++-- .../compileTime/not_enough_args.ark | 2 +- .../compileTime/not_enough_args.expected | 2 +- .../compileTime/reused_macro_arg.ark | 2 +- .../compileTime/reused_macro_arg.expected | 6 +- .../compileTime/too_many_args.ark | 2 +- .../compileTime/too_many_args.expected | 2 +- .../compileTime/unevaluated_spread.ark | 2 +- .../compileTime/unevaluated_spread.expected | 2 +- .../compileTime/well_formed_args.ark | 2 +- .../compileTime/well_formed_args.expected | 6 +- .../comment_after_macro_arg.ark | 2 +- .../comment_after_macro_arg.expected | 2 +- .../FormatterSuite/comments_after_call.ark | 4 +- .../comments_after_call.expected | 2 +- .../resources/FormatterSuite/macro_cond.ark | 4 +- .../FormatterSuite/macro_cond.expected | 2 +- .../resources/FormatterSuite/macros.ark | 10 +-- .../resources/FormatterSuite/macros.expected | 8 +-- .../resources/LangSuite/macro-tests.ark | 68 +++++++++---------- .../ParserSuite/failure/incomplete_macro.ark | 2 +- .../failure/incomplete_macro.expected | 9 +-- .../failure/incomplete_macro_arguments.ark | 2 +- .../incomplete_macro_arguments.expected | 12 ++-- .../failure/incomplete_macro_spread.ark | 2 +- .../failure/incomplete_macro_spread.expected | 7 +- .../resources/ParserSuite/success/macro.ark | 18 ++--- .../RosettaSuite/extend_your_language.ark | 2 +- 193 files changed, 551 insertions(+), 548 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7df53533..3cf22a25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,7 +54,7 @@ - more documentation about the compiler implementation - more documentation about the virtual machine - closures can be now be compared field per field: `(= closure1 closure2)` will work only if they have the same fields (name) and if the values match -- macros are now defined like `($ name value)` / `($ name (args args args) body)` / `($if cond then else)` +- macros are now defined like `(macro name value)` / `(macro name (args args args) body)` / `($if cond then else)` - upgraded from C++17 to C++20 - new parser, new syntax for imports: `(import package.sub.file)` - allow nodes to be empty when dumping the AST to JSON @@ -67,7 +67,7 @@ - fixed a bug in the compiler where one could pass something other than a list to `(fun)` as the argument block, resulting in a crash - fixed a bug in the compiler generating not callable functions - fixed a bug in the macro processor generating invalid `let` / `mut` / `set` nodes -- fixed a bug in the macro processor allowing out of bounds access with `($ test (@ [1 2 3] -5))` +- fixed a bug in the macro processor allowing out of bounds access with `(macro test (@ [1 2 3] -5))` - fixed a bug in the vm which wrongfully allowed self concat in place: `(concat! lst lst)` - fixed a bug in the compiler where one could "use" operators without calling them: `(print nil?)` - fixed a bug in the compiler allowing the use of operators without any argument: `(+)` diff --git a/examples/macros.ark b/examples/macros.ark index 4d345be0..81d2022f 100644 --- a/examples/macros.ark +++ b/examples/macros.ark @@ -1,9 +1,9 @@ -($ suffix-dup (sym x) { +(macro suffix-dup (sym x) { ($if (> x 1) (suffix-dup sym (- x 1))) ($symcat sym x) }) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef bloc) }) @@ -15,10 +15,10 @@ (print "Expected arguments for test_func1: " ($argcount test_func1) ", expected " 2) (print "Calling them: " (test_func 1 2 3) " " (test_func1 2 3)) -($ foo (a b) (+ a b)) +(macro foo (a b) (+ a b)) (print "Using macro foo (a b) => (+ a b): " (foo 1 2)) -($ var 12) +(macro var 12) (print "Using macro constant var=12: " var) ($if (= var 12) @@ -29,17 +29,17 @@ (print "This was executed in a if macro, testing (and true true)") (print "You shouldn't see this (bis)")) -($ defun (name args body) (let name (fun args body))) +(macro defun (name args body) (let name (fun args body))) (defun a_func (a b) (+ a b)) (print "Generated a function with a macro, a_func (a b) => (+ a b)") (print "Calling (a_func 1 2): " (a_func 1 2)) -($ one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) +(macro one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) (one 1 2) (one 1 3 4) (one 1 5 6 7 8) -($ last (...args) (print "Macro 'last', returns the last argument given in " args " => " (@ args -1))) +(macro last (...args) (print "Macro 'last', returns the last argument given in " args " => " (@ args -1))) (last 1 2) (last 1 3 4) (last 1 5 6 7 8) @@ -47,24 +47,24 @@ { (print "Testing macros in scopes and macro shadowing") - ($ test (+ 1 2 3)) + (macro test (+ 1 2 3)) (print "(global) Reading macro 'test', expected 6, " test) ((fun () { - ($ test (- 1 2 3)) + (macro test (- 1 2 3)) (print "(sub scope) Reading macro 'test', expected -4, " test) })) (print "(global) Reading macro 'test', expected 6, " test) { - ($ test 555) + (macro test 555) (print "(subscope) Reading macro 'test', expected 555, " test) - ($ undef test) + (macro undef test) (print "(subscope, undef test) Reading macro 'test', expected 6, " test) - ($ undef a) } } + (macro undef a) } } (print "Demonstrating a threading macro") -($ -> (arg fn1 ...fn) { +(macro -> (arg fn1 ...fn) { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) (fn1 arg)) }) diff --git a/lib/std b/lib/std index a24e382b..c1993572 160000 --- a/lib/std +++ b/lib/std @@ -1 +1 @@ -Subproject commit a24e382b498d92af438e9e5a937aac0a90bdb0eb +Subproject commit c199357219b94ce172150bd3a1395af246c63299 diff --git a/src/arkreactor/Compiler/AST/Node.cpp b/src/arkreactor/Compiler/AST/Node.cpp index df99933d..23164d5d 100644 --- a/src/arkreactor/Compiler/AST/Node.cpp +++ b/src/arkreactor/Compiler/AST/Node.cpp @@ -203,7 +203,7 @@ namespace Ark::internal break; case NodeType::Macro: - data += "($ "; + data += "(macro "; for (std::size_t i = 0, end = constList().size(); i < end; ++i) { data += constList()[i].repr(); diff --git a/src/arkreactor/Compiler/AST/Parser.cpp b/src/arkreactor/Compiler/AST/Parser.cpp index 816a323c..68afad26 100644 --- a/src/arkreactor/Compiler/AST/Parser.cpp +++ b/src/arkreactor/Compiler/AST/Parser.cpp @@ -708,14 +708,14 @@ namespace Ark::internal std::string comment; newlineOrComment(&comment); - if (!oneOf({ "$" })) + if (!oneOf({ "macro" })) return std::nullopt; newlineOrComment(&comment); leaf->attachNearestCommentBefore(comment); std::string symbol_name; if (!name(&symbol_name)) - errorWithNextToken("$ needs a symbol to declare a macro"); + errorWithNextToken("Expected a symbol to declare a macro"); comment.clear(); newlineOrComment(&comment); diff --git a/src/arkreactor/Compiler/Macros/Executors/Function.cpp b/src/arkreactor/Compiler/Macros/Executors/Function.cpp index 027313a6..0f581148 100644 --- a/src/arkreactor/Compiler/Macros/Executors/Function.cpp +++ b/src/arkreactor/Compiler/Macros/Executors/Function.cpp @@ -17,7 +17,7 @@ namespace Ark::internal { const Node& first = node.list()[0]; - // ($ name (args) body) + // (macro name (args) body) if (const Node* macro = findNearestMacro(first.string()); macro != nullptr && macro->constList().size() == 3) { Node temp_body = macro->constList()[2]; diff --git a/src/arkreactor/Compiler/Macros/Executors/Symbol.cpp b/src/arkreactor/Compiler/Macros/Executors/Symbol.cpp index 07aad53b..1f50ab00 100644 --- a/src/arkreactor/Compiler/Macros/Executors/Symbol.cpp +++ b/src/arkreactor/Compiler/Macros/Executors/Symbol.cpp @@ -11,7 +11,7 @@ namespace Ark::internal { if (const Node* macro = findNearestMacro(node.string()); macro != nullptr) { - // ($ name value) + // (macro name value) if (macro->constList().size() == 2) { node.updateValueAndType(macro->constList()[1]); diff --git a/src/arkreactor/Compiler/Macros/Processor.cpp b/src/arkreactor/Compiler/Macros/Processor.cpp index 09b067c8..0ee07463 100644 --- a/src/arkreactor/Compiler/Macros/Processor.cpp +++ b/src/arkreactor/Compiler/Macros/Processor.cpp @@ -55,7 +55,7 @@ namespace Ark::internal const Node& first_node = node.list()[0]; - // ($ name value) + // (macro name value) if (node.constList().size() == 2) { assert(first_node.nodeType() == NodeType::Symbol && "Can not define a macro without a symbol"); diff --git a/src/arkscript/Formatter.cpp b/src/arkscript/Formatter.cpp index 3306612d..a9b4f7ee 100644 --- a/src/arkscript/Formatter.cpp +++ b/src/arkscript/Formatter.cpp @@ -512,7 +512,7 @@ std::string Formatter::formatMacro(const Node& node, const std::size_t indent) if (isListStartingWithKeyword(node, Keyword::If)) return formatCondition(node, indent, /* is_macro= */ true); - std::string result = "($ "; + std::string result = "(macro "; bool after_newline = false; for (std::size_t i = 0, end = node.constList().size(); i < end; ++i) diff --git a/tests/fuzzing/arkscript.dict b/tests/fuzzing/arkscript.dict index b4fadb91..85366c6a 100644 --- a/tests/fuzzing/arkscript.dict +++ b/tests/fuzzing/arkscript.dict @@ -7,6 +7,7 @@ "while" "begin" "import" +"macro" "(" ")" diff --git a/tests/fuzzing/corpus-cmin-tmin/d.ark b/tests/fuzzing/corpus-cmin-tmin/d.ark index bfe1fec8..4c3142e5 100644 --- a/tests/fuzzing/corpus-cmin-tmin/d.ark +++ b/tests/fuzzing/corpus-cmin-tmin/d.ark @@ -1,4 +1,4 @@ -($ __count_placeholders(acc x ...xs) +(macro __count_placeholders(acc x ...xs) ($if (empty? xs) ($if (= "0" ($repr x)) (+ 0 acc) @@ -7,11 +7,11 @@ (__count_placeholders (+ 1 acc) ...xs) (__count_placeholders acc ...xs)))) -($ __suffix_dup (sym x) { +(macro __suffix_dup (sym x) { ($if (> x 1) (__suffix_dup sym (- x 1))) ($symcat sym x) }) -($ __replace_placeholders (replacements x ...xs) { +(macro __replace_placeholders (replacements x ...xs) { ($if (empty? xs) ($if (= "0" ($repr x)) (h00d replacements) @@ -24,10 +24,10 @@ x (__replace_placeholders replacements ...xs) }))}) -($ ! (call ...args) { - ($ length (__count_placeholders 0 ...args)) - ($ arg_bloc (__suffix_dup arg length)) - ($ all_args (__replace_placeholders [arg_bloc] ...args)) +(macro ! (call ...args) { + (macro length (__count_placeholders 0 ...args)) + (macro arg_bloc (__suffix_dup arg length)) + (macro all_args (__replace_placeholders [arg_bloc] ...args)) (fun (arg_bloc) (call all_args)) }) (let foo (fun (a b c d) diff --git a/tests/fuzzing/corpus-cmin-tmin/examples_macros.ark b/tests/fuzzing/corpus-cmin-tmin/examples_macros.ark index f43e4f62..77ff0f47 100644 --- a/tests/fuzzing/corpus-cmin-tmin/examples_macros.ark +++ b/tests/fuzzing/corpus-cmin-tmin/examples_macros.ark @@ -1,9 +1,9 @@ -($ suffix-dup (sym x) { +(macro suffix-dup (sym x) { ($if (> x 1) (suffix-dup sym (- x 1))) ($symcat sym x) }) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef b000) }) @@ -15,10 +15,10 @@ (print "0000000000000000000000000000000000 " ($argcount test_func1) "0 expected " 2) (print "00000000000000" (test_func 1 2 3) "0" (test_func1 2 3)) -($ foo (a b) (+ a b)) +(macro foo (a b) (+ a b)) (print "0000000000000000000000000000000000" (foo 1 2)) -($ var 12) +(macro var 12) (print "00000000000000000000000000000" var) ($if (= var 12) @@ -29,17 +29,17 @@ (print "00000000000000000000000000000000000000000000000000000000") (p0000 "0000000000000000000000000000")) -($ defun (name args body) (let name (fun args body))) +(macro defun (name args body) (let name (fun args body))) (defun a_func (a b) (+ a b)) (print "0000000000000000000000000000000000000000000000000000000000") (print "0000000000000000000000" (a_func 1 2)) -($ one (...args) (print "00000000000000000000000000000000000000000000000" args " => " (@ args 1))) +(macro one (...args) (print "00000000000000000000000000000000000000000000000" args " => " (@ args 1))) (one 1 2) (one 1 3 4) (one 1 5 6 7 8) -($ last (...args) (print "0000000000000000000000000000000000000000000000000" args " => " (@ args -1))) +(macro last (...args) (print "0000000000000000000000000000000000000000000000000" args " => " (@ args -1))) (last 1 2) (last 1 3 4) (last 1 5 6 7 8) @@ -47,24 +47,24 @@ { (print "00000000000000000000000000000000000000000000") - ($ test (+ 0 2 3)) + (macro test (+ 0 2 3)) (print "(global) 0eading macro 0test00 expected 60 " test) ((fun () { - ($ test (- 1 0 3)) + (macro test (- 1 0 3)) (print "0000000000000000000000000000000000000000000000 " test) })) (print "(global) 0eading macro 0test00 expected 60 " test) { - ($ test 555) + (macro test 555) (print "00000000000000000000000000000000000000000000500" test) - ($ undef test) + (macro undef test) (print "000000000000000000000000000000000000000000000000000000000" test) - ($ undef a) } } + (macro undef a) } } (print "0000000000000000000000000000000") -($ -> (arg fn1 ...fn) { +(macro -> (arg fn1 ...fn) { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) (fn1 arg)) }) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_argcount_unknown_arg.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_argcount_unknown_arg.ark index 1b00630d..66c55f8d 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_argcount_unknown_arg.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_argcount_unknown_arg.ark @@ -1,10 +1,10 @@ -($ suffix-dup (sym x) { +(macro suffix-dup (sym x) { ($if (> x 1) (suffix-dup sym (- x 1))) ($symcat sym x)}) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef o0)}) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_at_out_of_range.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_at_out_of_range.ark index 76412875..6f784b6a 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_at_out_of_range.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_at_out_of_range.ark @@ -1,2 +1,2 @@ -($ last (...a00s) (p0000 a00s "0000" (@ a00s -9))) +(macro last (...a00s) (p0000 a00s "0000" (@ a00s -9))) (last 1 5 6 7 8) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_bad_macro_arg_list.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_bad_macro_arg_list.ark index 2d58f75a..dfa34dc5 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_bad_macro_arg_list.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_bad_macro_arg_list.ark @@ -1,2 +1,2 @@ -($ b ($symcat c)) +(macro b ($symcat c)) (p0000 b) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_duplicated_arg.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_duplicated_arg.ark index a37cabf1..84f3c37f 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_duplicated_arg.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_duplicated_arg.ark @@ -1,4 +1,4 @@ -($ -> (a00 f0 ...f0)0{ +(macro -> (a00 f0 ...f0)0{ 00(0000(00(000000)00) 00000000(000(0000000)000000) 000000000000 diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_incomplete_macro.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_incomplete_macro.ark index 14ce0737..ff26dea3 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_incomplete_macro.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_incomplete_macro.ark @@ -1 +1 @@ -($ f00) +(macro f00) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_func.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_func.ark index e2e4c0a3..40c270c1 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_func.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_func.ark @@ -1 +1 @@ -(let foo (fun (a b) ($ a b))) +(let foo (fun (a b) (macro a b))) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let.ark index 894e8892..f5b8bf95 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let.ark @@ -1,5 +1,5 @@ -($ partial (func ...defargs) { - ($ b0000(suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro b0000(suffix-dup a (- ($argcount func) (len defargs)))) }) (let test_func (fun (a b c) (* a b c))) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let_in_macro.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let_in_macro.ark index 7173b37b..e8f2a227 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let_in_macro.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let_in_macro.ark @@ -1,3 +1,3 @@ -($ d0000 (n000 a000 b000) (let 0000 (000))) +(macro d0000 (n000 a000 b000) (let 0000 (000))) (0(000)0(00000)) (000000(0000000000)) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_sym_func_def.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_sym_func_def.ark index 8d570e0e..4047675f 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_sym_func_def.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_sym_func_def.ark @@ -1,2 +1,2 @@ -($ defun(na0e a000 bod0) (let na0e (fun a000 bod0))) +(macro defun(na0e a000 bod0) (let na0e (fun a000 bod0))) (defun 0 (a b) (+ a b)) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_while.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_while.ark index 2ac15074..ea165c0a 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_while.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_while.ark @@ -1 +1 @@ -(while($ a 0){(mut c(()))}) +(while(macro a 0){(mut c(()))}) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_empty_arity_error.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_empty_arity_error.ark index 2fb7ac0b..a8ce0703 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_empty_arity_error.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_empty_arity_error.ark @@ -1,2 +1,2 @@ -($ a (empty? 1 2)) +(macro a (empty? 1 2)) (p0000 a) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_head_arity_error.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_head_arity_error.ark index 917d7487..275aad3f 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_head_arity_error.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_head_arity_error.ark @@ -1,2 +1,2 @@ -($ a (head 1 2)) +(macro a (head 1 2)) (p0000 a) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_len_arity_error.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_len_arity_error.ark index 9d0d8963..ce659161 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_len_arity_error.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_len_arity_error.ark @@ -1,2 +1,2 @@ -($ a (len 1 2)) +(macro a (len 1 2)) (p0000 a) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_paste_arity_error.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_paste_arity_error.ark index 2dbc8d1d..75482258 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_paste_arity_error.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_paste_arity_error.ark @@ -1,2 +1,2 @@ -($ a ($as-is b [])) +(macro a ($as-is b [])) (p0000 a) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_spread_not_enough_args.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_spread_not_enough_args.ark index 5e206b7f..fa746d74 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_spread_not_enough_args.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_spread_not_enough_args.ark @@ -1,4 +1,4 @@ -($ f00 (a b c ...d) +(macro f00 (a b c ...d) (+ a b c ...d)) (f00 1 2) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arg_type_error.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arg_type_error.ark index 4435bf66..b91acae7 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arg_type_error.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arg_type_error.ark @@ -1,2 +1,2 @@ -($ a ($symcat b [])) +(macro a ($symcat b [])) (p0000 a) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arity_error.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arity_error.ark index b003cd05..af8ebdfd 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arity_error.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arity_error.ark @@ -1,2 +1,2 @@ -($ a { ($symcat b) }) +(macro a { ($symcat b) }) (p0000 a) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_type_error.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_type_error.ark index 86d12ce8..b94d6ee0 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_type_error.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_type_error.ark @@ -1,2 +1,2 @@ -($ a ($symcat 5 2)) +(macro a ($symcat 5 2)) (p0000 a) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_tail_arity_error.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_tail_arity_error.ark index c71138a2..86f23519 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_tail_arity_error.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_tail_arity_error.ark @@ -1,2 +1,2 @@ -($ a (tail 1 2)) +(macro a (tail 1 2)) (p0000 a) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth.ark index 7c53241b..6355e640 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth.ark @@ -1,2 +1,2 @@ -($ s00e (/ s00e 0)) +(macro s00e (/ s00e 0)) (let s00 s00e) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth_eval.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth_eval.ark index c106e82a..83a9eb56 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth_eval.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth_eval.ark @@ -1,2 +1,2 @@ -($ las0 ((las0 0 0 0 0 0) 0 s "0" (@ a000 -0))) +(macro las0 ((las0 0 0 0 0 0) 0 s "0" (@ a000 -0))) (las0 0 0 0 0 0) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_max_unification_depth.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_max_unification_depth.ark index 65122c37..7721955f 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_max_unification_depth.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_max_unification_depth.ark @@ -1,11 +1,11 @@ -($ suffix-dup (s00 x){ +(macro suffix-dup (s00 x){ ($if (+ x 0) e0_0000 - ($ p0(a b c) (* a b c))) + (macro p0(a b c) (* a b c))) ($000000 s00 x)}) -($ partial (func ...defar0s) { - ($ b0000(s00000-000 a0(len defar0s))) +(macro partial (func ...defar0s) { + (macro b0000(s00000-000 a0(len defar0s))) (fun (b000) (func ...defar0s b000)) ($00000 b000)}) @@ -14,7 +14,7 @@ (* a b) (let i00000(p000000 t0 t_0000 0)) (let e0000000 - ($ p0r0000 (func ...defar0s) { - ($ b0000(s00000-000 a (l00 d000000))) + (macro p0r0000 (func ...defar0s) { + (macro b0000(s00000-000 a (l00 d000000))) (fun (b000) (f000 ...d000000 b000)) ($00000 b000)})))) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_reused_macro_arg.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_reused_macro_arg.ark index ac9eb8d1..67da031d 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_reused_macro_arg.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_reused_macro_arg.ark @@ -1 +1 @@ -($ f00 (b00 b00 000)0()) +(macro f00 (b00 b00 000)0()) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_too_many_args.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_too_many_args.ark index 514c25fc..ca2e4e05 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_too_many_args.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_too_many_args.ark @@ -1,4 +1,4 @@ -($ f00(a b c) +(macro f00(a b c) (+ a b c)) (f00 1 2 3 4) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_unevaluated_spread.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_unevaluated_spread.ark index 3b4dc134..aaa257fe 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_unevaluated_spread.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_unevaluated_spread.ark @@ -1,4 +1,4 @@ -($ p0000000{ +(macro p0000000{ (fun (a) (f000 ...d000000)) }) (let b (p000000)) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_well_formed_args.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_well_formed_args.ark index 62af6a8d..89901726 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_well_formed_args.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_diagnosticssuite_compiletime_well_formed_args.ark @@ -1,4 +1,4 @@ -($ defun (let n000 (fun a000 nil))) +(macro defun (let n000 (fun a000 nil))) (let foo 0) (let a 2) (let b 3) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_formattersuite_comment_after_macro_arg.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_formattersuite_comment_after_macro_arg.ark index 708ec26d..b533be78 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_formattersuite_comment_after_macro_arg.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_formattersuite_comment_after_macro_arg.ark @@ -1,4 +1,4 @@ -($ -0()#0000000 +(macro -0()#0000000 { ($if (> (l00 f0)0) (-> (f00 a00) ...f0) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_formattersuite_comments_after_call.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_formattersuite_comments_after_call.ark index 305ac10f..ab27570a 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_formattersuite_comments_after_call.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_formattersuite_comments_after_call.ark @@ -1,4 +1,4 @@ -($ foo (...a00#0000000000000000000000 +(macro foo (...a00#0000000000000000000000 ) () #000000000000000000 ) [ a b c #0000000000000 diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_formattersuite_macros.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_formattersuite_macros.ark index 764182d8..659d973f 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_formattersuite_macros.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_formattersuite_macros.ark @@ -1,6 +1,6 @@ -($ foo (a b) (+ a b)) -($ v00 00) -($ de000 (n000 a000 b000) (let n000 (fun a000 b000))) -($ one (...a000) (p0000 "00000000000000000000000000000000000000000000000" a000 "0000" (@ a000 0))) +(macro foo (a b) (+ a b)) +(macro v00 00) +(macro de000 (n000 a000 b000) (let n000 (fun a000 b000))) +(macro one (...a000) (p0000 "00000000000000000000000000000000000000000000000" a000 "0000" (@ a000 0))) ($undef a) ($repr a) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_langsuite_macro-tests.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_langsuite_macro-tests.ark index f46f1f1e..e2a51691 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_langsuite_macro-tests.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_langsuite_macro-tests.ark @@ -1,13 +1,13 @@ (import std.Testing) -($ suffix-dup (sym x) { +(macro suffix-dup (sym x) { ($if (> x 1) (suffix-dup sym (- x 1))) ($symcat sym x)}) (let magic_func (fun ((suffix-dup a 3)) (- a1 a2 a3))) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)}) @@ -16,38 +16,38 @@ (let test_func1_2 (partial test_func1 2)) (test:suite macro { - ($ nice_value 12) + (macro nice_value 12) (test:case "basic macros" { - ($ void () nil) + (macro void () nil) (test:eq (void) nil) - ($ add_two (a b) (+ a b)) + (macro add_two (a b) (+ a b)) (test:eq (add_two 1 2) 3) (test:eq (add_two nice_value 2) 14) - ($ c (a b) (* a b)) + (macro c (a b) (* a b)) (test:eq (c 4 10) 40) - ($ d (a b) (/ a b)) + (macro d (a b) (/ a b)) (test:eq (d 10 2) 5) - ($ e (+ 1 2 3)) - ($ f (* 2 2 3)) - ($ g (- 1 2 3)) - ($ h (/ 12 2 3)) + (macro e (+ 1 2 3)) + (macro f (* 2 2 3)) + (macro g (- 1 2 3)) + (macro h (/ 12 2 3)) (test:eq e 6) (test:eq f 12) (test:eq g -4) (test:eq h (/ 12 6)) }) (test:case "node manipulation" { - ($ node_tail () (tail (begin 1 2 3))) - ($ length () (len (fun () 5))) - ($ not_empty_node () (empty? (fun () ()))) - ($ empty_node () (empty? ())) - ($ empty_node_bis (empty? ())) + (macro node_tail () (tail (begin 1 2 3))) + (macro length () (len (fun () 5))) + (macro not_empty_node () (empty? (fun () ()))) + (macro empty_node () (empty? ())) + (macro empty_node_bis (empty? ())) (test:eq (length) 3) (test:eq (not_empty_node) false) @@ -72,9 +72,9 @@ (test:expect ($if (@ [true false] -2) true false)) (test:expect ($if 1 true false)) ($if true { - ($ in_if_1 true) - ($ in_if_2 true)}) - ($if true ($ new_value true)) + (macro in_if_1 true) + (macro in_if_2 true)}) + ($if true (macro new_value true)) (test:expect (and in_if_1 in_if_2) "a variable can be defined inside a conditional macro") (test:expect new_value "variable can be defined inside a conditional macro") @@ -82,11 +82,11 @@ ($undef in_if_2) }) { - ($ val (+ 1 2 3)) + (macro val (+ 1 2 3)) (test:eq val 6 "val should be computed to 6") { - ($ val 0) + (macro val 0) (test:eq val 0 "val is shadowed") ($undef val) (test:eq val 6 "shadowed version should be undefined") @@ -95,57 +95,57 @@ (test:eq val 6 "val should still resolve to 6")} (test:case "macro expansion" { - ($ bar (a ...args) (+ a (len args))) + (macro bar (a ...args) (+ a (len args))) (test:eq (bar 1) 1) (test:eq (bar 2 3) 3) (test:eq (bar 4 5 6) 6) (test:eq (bar 7 8 9 10) 10) - ($ egg (...args) (bar ...args)) + (macro egg (...args) (bar ...args)) (test:eq (egg 1) 1) (test:eq (egg 0 1) 1) (test:eq (egg 0 0 0 1) 3) - ($ h (...args) (head args)) + (macro h (...args) (head args)) (test:eq (h) nil) (test:eq (h 1) 1) (test:eq (h 1 2) 1) - ($ g (...args) (tail args)) + (macro g (...args) (tail args)) (test:eq (g) []) (test:eq (g 1) []) (test:eq (g 1 2) [2]) (test:eq (g 1 2 3) [2 3]) - ($ one (...args) (@ args 1)) + (macro one (...args) (@ args 1)) (test:eq (one 1 2) 2) (test:eq (one 1 3 4) 3) (test:eq (one 1 5 6 7 8) 5) - ($ last (...args) (@ args -1)) + (macro last (...args) (@ args -1)) (test:eq (last 1 2) 2) (test:eq (last 1 3 4) 4) (test:eq (last 1 5 6 7 8) 8) }) (test:case "generate valid arkscript code with macros" { - ($ make-func (retval) (fun () retval)) + (macro make-func (retval) (fun () retval)) (let a-func (make-func 1)) (test:eq (type a-func) "Function") (test:eq (a-func) 1) - ($ defun (name args body) (let name (fun args body))) + (macro defun (name args body) (let name (fun args body))) (defun foo (a b) (+ a b)) (test:eq (type foo) "Function") (test:eq (foo 2 3) 5) - ($ get_symbol (bloc) (@ bloc 1)) - ($ define (bloc) (let (get_symbol bloc) (@ bloc 2))) + (macro get_symbol (bloc) (@ bloc 1)) + (macro define (bloc) (let (get_symbol bloc) (@ bloc 2))) (define (let a 12)) (test:eq a 12) }) (test:case "define variable with a macro adding a suffix" { - ($ nice_value 12) - ($ define (prefix suffix value) (let ($symcat prefix suffix) value)) + (macro nice_value 12) + (macro define (prefix suffix value) (let ($symcat prefix suffix) value)) (define a 1 2) (test:eq a1 2) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_failure_incomplete_macro.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_failure_incomplete_macro.ark index ceb5aaee..4eedd563 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_failure_incomplete_macro.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_failure_incomplete_macro.ark @@ -1 +1 @@ -($ (0)00) +(macro (0)00) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_arguments.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_arguments.ark index 350371da..99d523d8 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_arguments.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_arguments.ark @@ -1 +1 @@ -($ f00 (a +(macro f00 (a diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_spread.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_spread.ark index d9489654..7ec0fe04 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_spread.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_spread.ark @@ -1 +1 @@ -($ f00 (b00 ...)0(000)) +(macro f00 (b00 ...)0(000)) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_success_macro.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_success_macro.ark index ca9884bf..cc8626ba 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_success_macro.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_parsersuite_success_macro.ark @@ -1,5 +1,5 @@ -($ a 0) -($ b()0) +(macro a 0) +(macro b()0) ($ c#00000000000 ( #000000000 @@ -8,11 +8,11 @@ e ) 0 #00000 ) -($ f(g)0) -($ h(i j) (let a 0)) +(macro f(g)0) +(macro h(i j) (let a 0)) -($ h (i j) (let a0(if i 0 0))) -($ k (l ...m) (p0000 l m)) -($ n0( +(macro h (i j) (let a0(if i 0 0))) +(macro k (l ...m) (p0000 l m)) +(macro n0( ...p ) (p0000 p)) diff --git a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_rosettasuite_extend_your_language.ark b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_rosettasuite_extend_your_language.ark index fe781497..5998248d 100644 --- a/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_rosettasuite_extend_your_language.ark +++ b/tests/fuzzing/corpus-cmin-tmin/tests_unittests_resources_rosettasuite_extend_your_language.ark @@ -1,4 +1,4 @@ -($ if2 (conds bothConditionsAreTrue firstConditionIsTrue secondConditionIsTrue noConditionIsTrue) { +(macro if2 (conds bothConditionsAreTrue firstConditionIsTrue secondConditionIsTrue noConditionIsTrue) { (mut result1 (head conds)) (mut result2 (@ conds 1)) (if (and result1 result2) diff --git a/tests/fuzzing/corpus-cmin/d.ark b/tests/fuzzing/corpus-cmin/d.ark index a2572700..471ae7d2 100644 --- a/tests/fuzzing/corpus-cmin/d.ark +++ b/tests/fuzzing/corpus-cmin/d.ark @@ -1,4 +1,4 @@ -($ __count_placeholders (acc x ...xs) +(macro __count_placeholders (acc x ...xs) ($if (empty? xs) ($if (= "_" ($repr x)) (+ 1 acc) @@ -7,11 +7,11 @@ (__count_placeholders (+ 1 acc) ...xs) (__count_placeholders acc ...xs)))) -($ __suffix_dup (sym x) { +(macro __suffix_dup (sym x) { ($if (> x 1) (__suffix_dup sym (- x 1))) ($symcat sym x) }) -($ __replace_placeholders (replacements x ...xs) { +(macro __replace_placeholders (replacements x ...xs) { ($if (empty? xs) ($if (= "_" ($repr x)) (head replacements) @@ -24,10 +24,10 @@ x (__replace_placeholders replacements ...xs) }))}) -($ ! (call ...args) { - ($ length (__count_placeholders 0 ...args)) - ($ arg_bloc (__suffix_dup arg length)) - ($ all_args (__replace_placeholders [arg_bloc] ...args)) +(macro ! (call ...args) { + (macro length (__count_placeholders 0 ...args)) + (macro arg_bloc (__suffix_dup arg length)) + (macro all_args (__replace_placeholders [arg_bloc] ...args)) (fun (arg_bloc) (call all_args)) }) (let foo (fun (a b c d) diff --git a/tests/fuzzing/corpus-cmin/examples_macros.ark b/tests/fuzzing/corpus-cmin/examples_macros.ark index 4d345be0..81d2022f 100644 --- a/tests/fuzzing/corpus-cmin/examples_macros.ark +++ b/tests/fuzzing/corpus-cmin/examples_macros.ark @@ -1,9 +1,9 @@ -($ suffix-dup (sym x) { +(macro suffix-dup (sym x) { ($if (> x 1) (suffix-dup sym (- x 1))) ($symcat sym x) }) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef bloc) }) @@ -15,10 +15,10 @@ (print "Expected arguments for test_func1: " ($argcount test_func1) ", expected " 2) (print "Calling them: " (test_func 1 2 3) " " (test_func1 2 3)) -($ foo (a b) (+ a b)) +(macro foo (a b) (+ a b)) (print "Using macro foo (a b) => (+ a b): " (foo 1 2)) -($ var 12) +(macro var 12) (print "Using macro constant var=12: " var) ($if (= var 12) @@ -29,17 +29,17 @@ (print "This was executed in a if macro, testing (and true true)") (print "You shouldn't see this (bis)")) -($ defun (name args body) (let name (fun args body))) +(macro defun (name args body) (let name (fun args body))) (defun a_func (a b) (+ a b)) (print "Generated a function with a macro, a_func (a b) => (+ a b)") (print "Calling (a_func 1 2): " (a_func 1 2)) -($ one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) +(macro one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) (one 1 2) (one 1 3 4) (one 1 5 6 7 8) -($ last (...args) (print "Macro 'last', returns the last argument given in " args " => " (@ args -1))) +(macro last (...args) (print "Macro 'last', returns the last argument given in " args " => " (@ args -1))) (last 1 2) (last 1 3 4) (last 1 5 6 7 8) @@ -47,24 +47,24 @@ { (print "Testing macros in scopes and macro shadowing") - ($ test (+ 1 2 3)) + (macro test (+ 1 2 3)) (print "(global) Reading macro 'test', expected 6, " test) ((fun () { - ($ test (- 1 2 3)) + (macro test (- 1 2 3)) (print "(sub scope) Reading macro 'test', expected -4, " test) })) (print "(global) Reading macro 'test', expected 6, " test) { - ($ test 555) + (macro test 555) (print "(subscope) Reading macro 'test', expected 555, " test) - ($ undef test) + (macro undef test) (print "(subscope, undef test) Reading macro 'test', expected 6, " test) - ($ undef a) } } + (macro undef a) } } (print "Demonstrating a threading macro") -($ -> (arg fn1 ...fn) { +(macro -> (arg fn1 ...fn) { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) (fn1 arg)) }) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_argcount_unknown_arg.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_argcount_unknown_arg.ark index 3e5b9126..2a55f7e3 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_argcount_unknown_arg.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_argcount_unknown_arg.ark @@ -1,10 +1,10 @@ -($ suffix-dup (sym x) { +(macro suffix-dup (sym x) { ($if (> x 1) (suffix-dup sym (- x 1))) ($symcat sym x)}) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)}) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_at_out_of_range.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_at_out_of_range.ark index 8807fb94..12122fb3 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_at_out_of_range.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_at_out_of_range.ark @@ -1,2 +1,2 @@ -($ last (...args) (print args " => " (@ args -9))) +(macro last (...args) (print args " => " (@ args -9))) (last 1 5 6 7 8) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_bad_macro_arg_list.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_bad_macro_arg_list.ark index 9c93a9ae..9ecfe0a9 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_bad_macro_arg_list.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_bad_macro_arg_list.ark @@ -1,2 +1,2 @@ -($ b ($symcat c)) +(macro b ($symcat c)) (print b) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_duplicated_arg.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_duplicated_arg.ark index 1a98502e..4fd6ebf5 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_duplicated_arg.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_duplicated_arg.ark @@ -1,4 +1,4 @@ -($ -> (arg fn ...fn) { +(macro -> (arg fn ...fn) { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) (fn1 arg))}) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_incomplete_macro.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_incomplete_macro.ark index ec2576e6..692f1994 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_incomplete_macro.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_incomplete_macro.ark @@ -1 +1 @@ -($ foo) +(macro foo) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_func.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_func.ark index e2e4c0a3..40c270c1 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_func.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_func.ark @@ -1 +1 @@ -(let foo (fun (a b) ($ a b))) +(let foo (fun (a b) (macro a b))) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let.ark index f4d8906b..c743abf5 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let.ark @@ -1,5 +1,5 @@ -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) }) (let test_func (fun (a b c) (* a b c))) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let_in_macro.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let_in_macro.ark index 23b7761e..b5673c3c 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let_in_macro.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let_in_macro.ark @@ -1,3 +1,3 @@ -($ defun (name args body) (let 0000 (fun args body))) +(macro defun (name args body) (let 0000 (fun args body))) (defun a_func (a b) (+ a b)) (print (a_func 1 2)) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_sym_func_def.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_sym_func_def.ark index 36f8429a..efbca0af 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_sym_func_def.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_sym_func_def.ark @@ -1,2 +1,2 @@ -($ defun (name args body) (let name (fun args body))) +(macro defun (name args body) (let name (fun args body))) (defun 0 (a b) (+ a b)) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_while.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_while.ark index b7ee3107..0b69bda2 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_while.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_invalid_while.ark @@ -1,2 +1,2 @@ -(while ($ a 1) { +(while (macro a 1) { (mut acc (+ acc (@ [] a)))}) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_empty_arity_error.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_empty_arity_error.ark index b934b651..0d865d0e 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_empty_arity_error.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_empty_arity_error.ark @@ -1,2 +1,2 @@ -($ a (empty? 1 2)) +(macro a (empty? 1 2)) (print a) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_head_arity_error.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_head_arity_error.ark index ae9e1d05..73fe70d4 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_head_arity_error.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_head_arity_error.ark @@ -1,2 +1,2 @@ -($ a (head 1 2)) +(macro a (head 1 2)) (print a) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_len_arity_error.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_len_arity_error.ark index 3a8d5329..e34b7877 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_len_arity_error.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_len_arity_error.ark @@ -1,2 +1,2 @@ -($ a (len 1 2)) +(macro a (len 1 2)) (print a) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_paste_arity_error.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_paste_arity_error.ark index fa8e31ed..7037a573 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_paste_arity_error.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_paste_arity_error.ark @@ -1,2 +1,2 @@ -($ a ($as-is b [])) +(macro a ($as-is b [])) (print a) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_spread_not_enough_args.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_spread_not_enough_args.ark index 6fcf3f1e..5eb2450c 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_spread_not_enough_args.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_spread_not_enough_args.ark @@ -1,4 +1,4 @@ -($ foo (a b c ...d) +(macro foo (a b c ...d) (+ a b c ...d)) (foo 1 2) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arg_type_error.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arg_type_error.ark index 90a7a515..9386559a 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arg_type_error.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arg_type_error.ark @@ -1,2 +1,2 @@ -($ a ($symcat b [])) +(macro a ($symcat b [])) (print a) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arity_error.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arity_error.ark index 714be5ad..844646e3 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arity_error.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arity_error.ark @@ -1,2 +1,2 @@ -($ a { ($symcat b) }) +(macro a { ($symcat b) }) (print a) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_type_error.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_type_error.ark index 4e89e75a..6f78333a 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_type_error.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_type_error.ark @@ -1,2 +1,2 @@ -($ a ($symcat 5 2)) +(macro a ($symcat 5 2)) (print a) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_tail_arity_error.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_tail_arity_error.ark index 0c4d06d7..2a2636d0 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_tail_arity_error.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_macro_tail_arity_error.ark @@ -1,2 +1,2 @@ -($ a (tail 1 2)) +(macro a (tail 1 2)) (print a) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth.ark index ded7da30..a1f03451 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth.ark @@ -1,2 +1,2 @@ -($ size (/ size 4)) +(macro size (/ size 4)) (let sum size) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth_eval.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth_eval.ark index 43c78c50..05f4135a 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth_eval.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_max_depth_eval.ark @@ -1,2 +1,2 @@ -($ last ((last 1 5 6 7 8) 0 s "@" (@ a00s -9))) +(macro last ((last 1 5 6 7 8) 0 s "@" (@ a00s -9))) (last 1 5 6 7 8) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_max_unification_depth.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_max_unification_depth.ark index 10f94aae..fc6a5572 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_max_unification_depth.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_max_unification_depth.ark @@ -1,11 +1,11 @@ -($ suffix-dup (sym x){ +(macro suffix-dup (sym x){ ($if (+ x 1) est_func - ($ p (a b c) (* a b c))) + (macro p (a b c) (* a b c))) ($symcat sym x)}) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (len defargs))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (len defargs))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)}) @@ -14,7 +14,7 @@ (* a b) (let inner (partial te t_func 0)) (let est_func - ($ partial (func ...defargs) { - ($ bloc (suffix-dup a (len defargs))) + (macro partial (func ...defargs) { + (macro bloc (suffix-dup a (len defargs))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)})))) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_reused_macro_arg.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_reused_macro_arg.ark index 3c0711b8..590299ec 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_reused_macro_arg.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_reused_macro_arg.ark @@ -1 +1 @@ -($ foo (bar bar egg) ()) +(macro foo (bar bar egg) ()) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_too_many_args.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_too_many_args.ark index d864d544..939e9a4e 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_too_many_args.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_too_many_args.ark @@ -1,4 +1,4 @@ -($ foo (a b c) +(macro foo (a b c) (+ a b c)) (foo 1 2 3 4) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_unevaluated_spread.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_unevaluated_spread.ark index 8c24b14b..d021d203 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_unevaluated_spread.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_unevaluated_spread.ark @@ -1,4 +1,4 @@ -($ partial { +(macro partial { (fun (a) (func ...defargs)) }) (let b (partial)) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_well_formed_args.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_well_formed_args.ark index 0b78bcd7..5ee42f4b 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_well_formed_args.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_diagnosticssuite_compiletime_well_formed_args.ark @@ -1,4 +1,4 @@ -($ defun (let name (fun args nil))) +(macro defun (let name (fun args nil))) (let foo 1) (let a 2) (let b 3) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_formattersuite_comment_after_macro_arg.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_formattersuite_comment_after_macro_arg.ark index 4af692a6..eb6dfc92 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_formattersuite_comment_after_macro_arg.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_formattersuite_comment_after_macro_arg.ark @@ -1,4 +1,4 @@ -($ -> ()#comment +(macro -> ()#comment { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_formattersuite_comments_after_call.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_formattersuite_comments_after_call.ark index aaf982c3..b2ff3283 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_formattersuite_comments_after_call.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_formattersuite_comments_after_call.ark @@ -1,4 +1,4 @@ -($ foo (...args # all the args go there +(macro foo (...args # all the args go there ) () # the body is empty ) [ a b c # last element diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_formattersuite_macros.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_formattersuite_macros.ark index 70bb67bc..f7b1912f 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_formattersuite_macros.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_formattersuite_macros.ark @@ -1,6 +1,6 @@ -($ foo (a b) (+ a b)) -($ var 12) -($ defun (name args body) (let name (fun args body))) -($ one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) +(macro foo (a b) (+ a b)) +(macro var 12) +(macro defun (name args body) (let name (fun args body))) +(macro one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) ($undef a) ($repr a) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_langsuite_macro-tests.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_langsuite_macro-tests.ark index f46f1f1e..e2a51691 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_langsuite_macro-tests.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_langsuite_macro-tests.ark @@ -1,13 +1,13 @@ (import std.Testing) -($ suffix-dup (sym x) { +(macro suffix-dup (sym x) { ($if (> x 1) (suffix-dup sym (- x 1))) ($symcat sym x)}) (let magic_func (fun ((suffix-dup a 3)) (- a1 a2 a3))) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)}) @@ -16,38 +16,38 @@ (let test_func1_2 (partial test_func1 2)) (test:suite macro { - ($ nice_value 12) + (macro nice_value 12) (test:case "basic macros" { - ($ void () nil) + (macro void () nil) (test:eq (void) nil) - ($ add_two (a b) (+ a b)) + (macro add_two (a b) (+ a b)) (test:eq (add_two 1 2) 3) (test:eq (add_two nice_value 2) 14) - ($ c (a b) (* a b)) + (macro c (a b) (* a b)) (test:eq (c 4 10) 40) - ($ d (a b) (/ a b)) + (macro d (a b) (/ a b)) (test:eq (d 10 2) 5) - ($ e (+ 1 2 3)) - ($ f (* 2 2 3)) - ($ g (- 1 2 3)) - ($ h (/ 12 2 3)) + (macro e (+ 1 2 3)) + (macro f (* 2 2 3)) + (macro g (- 1 2 3)) + (macro h (/ 12 2 3)) (test:eq e 6) (test:eq f 12) (test:eq g -4) (test:eq h (/ 12 6)) }) (test:case "node manipulation" { - ($ node_tail () (tail (begin 1 2 3))) - ($ length () (len (fun () 5))) - ($ not_empty_node () (empty? (fun () ()))) - ($ empty_node () (empty? ())) - ($ empty_node_bis (empty? ())) + (macro node_tail () (tail (begin 1 2 3))) + (macro length () (len (fun () 5))) + (macro not_empty_node () (empty? (fun () ()))) + (macro empty_node () (empty? ())) + (macro empty_node_bis (empty? ())) (test:eq (length) 3) (test:eq (not_empty_node) false) @@ -72,9 +72,9 @@ (test:expect ($if (@ [true false] -2) true false)) (test:expect ($if 1 true false)) ($if true { - ($ in_if_1 true) - ($ in_if_2 true)}) - ($if true ($ new_value true)) + (macro in_if_1 true) + (macro in_if_2 true)}) + ($if true (macro new_value true)) (test:expect (and in_if_1 in_if_2) "a variable can be defined inside a conditional macro") (test:expect new_value "variable can be defined inside a conditional macro") @@ -82,11 +82,11 @@ ($undef in_if_2) }) { - ($ val (+ 1 2 3)) + (macro val (+ 1 2 3)) (test:eq val 6 "val should be computed to 6") { - ($ val 0) + (macro val 0) (test:eq val 0 "val is shadowed") ($undef val) (test:eq val 6 "shadowed version should be undefined") @@ -95,57 +95,57 @@ (test:eq val 6 "val should still resolve to 6")} (test:case "macro expansion" { - ($ bar (a ...args) (+ a (len args))) + (macro bar (a ...args) (+ a (len args))) (test:eq (bar 1) 1) (test:eq (bar 2 3) 3) (test:eq (bar 4 5 6) 6) (test:eq (bar 7 8 9 10) 10) - ($ egg (...args) (bar ...args)) + (macro egg (...args) (bar ...args)) (test:eq (egg 1) 1) (test:eq (egg 0 1) 1) (test:eq (egg 0 0 0 1) 3) - ($ h (...args) (head args)) + (macro h (...args) (head args)) (test:eq (h) nil) (test:eq (h 1) 1) (test:eq (h 1 2) 1) - ($ g (...args) (tail args)) + (macro g (...args) (tail args)) (test:eq (g) []) (test:eq (g 1) []) (test:eq (g 1 2) [2]) (test:eq (g 1 2 3) [2 3]) - ($ one (...args) (@ args 1)) + (macro one (...args) (@ args 1)) (test:eq (one 1 2) 2) (test:eq (one 1 3 4) 3) (test:eq (one 1 5 6 7 8) 5) - ($ last (...args) (@ args -1)) + (macro last (...args) (@ args -1)) (test:eq (last 1 2) 2) (test:eq (last 1 3 4) 4) (test:eq (last 1 5 6 7 8) 8) }) (test:case "generate valid arkscript code with macros" { - ($ make-func (retval) (fun () retval)) + (macro make-func (retval) (fun () retval)) (let a-func (make-func 1)) (test:eq (type a-func) "Function") (test:eq (a-func) 1) - ($ defun (name args body) (let name (fun args body))) + (macro defun (name args body) (let name (fun args body))) (defun foo (a b) (+ a b)) (test:eq (type foo) "Function") (test:eq (foo 2 3) 5) - ($ get_symbol (bloc) (@ bloc 1)) - ($ define (bloc) (let (get_symbol bloc) (@ bloc 2))) + (macro get_symbol (bloc) (@ bloc 1)) + (macro define (bloc) (let (get_symbol bloc) (@ bloc 2))) (define (let a 12)) (test:eq a 12) }) (test:case "define variable with a macro adding a suffix" { - ($ nice_value 12) - ($ define (prefix suffix value) (let ($symcat prefix suffix) value)) + (macro nice_value 12) + (macro define (prefix suffix value) (let ($symcat prefix suffix) value)) (define a 1 2) (test:eq a1 2) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_failure_incomplete_macro.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_failure_incomplete_macro.ark index 46261cd9..0e6a330e 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_failure_incomplete_macro.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_failure_incomplete_macro.ark @@ -1 +1 @@ -($ (a) a) +(macro (a) a) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_arguments.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_arguments.ark index 88c585ef..862e0ed4 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_arguments.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_arguments.ark @@ -1 +1 @@ -($ foo (a +(macro foo (a diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_spread.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_spread.ark index 93f9f294..e26ff231 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_spread.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_failure_incomplete_macro_spread.ark @@ -1 +1 @@ -($ foo (bar ...) (bar)) +(macro foo (bar ...) (bar)) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_success_macro.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_success_macro.ark index 1e224b4a..9359f41b 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_success_macro.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_parsersuite_success_macro.ark @@ -1,5 +1,5 @@ -($ a 1) -($ b () 2) +(macro a 1) +(macro b () 2) ($ c # macro name ( # arg list @@ -8,11 +8,11 @@ e ) 3 # body ) -($ f(g)4) -($ h(i j) (let a 1)) +(macro f(g)4) +(macro h(i j) (let a 1)) -($ h (i j) (let a (if i 2 3))) -($ k (l ...m) (print l m)) -($ n ( +(macro h (i j) (let a (if i 2 3))) +(macro k (l ...m) (print l m)) +(macro n ( ...p ) (print p)) diff --git a/tests/fuzzing/corpus-cmin/tests_unittests_resources_rosettasuite_extend_your_language.ark b/tests/fuzzing/corpus-cmin/tests_unittests_resources_rosettasuite_extend_your_language.ark index fe781497..5998248d 100644 --- a/tests/fuzzing/corpus-cmin/tests_unittests_resources_rosettasuite_extend_your_language.ark +++ b/tests/fuzzing/corpus-cmin/tests_unittests_resources_rosettasuite_extend_your_language.ark @@ -1,4 +1,4 @@ -($ if2 (conds bothConditionsAreTrue firstConditionIsTrue secondConditionIsTrue noConditionIsTrue) { +(macro if2 (conds bothConditionsAreTrue firstConditionIsTrue secondConditionIsTrue noConditionIsTrue) { (mut result1 (head conds)) (mut result2 (@ conds 1)) (if (and result1 result2) diff --git a/tests/fuzzing/corpus/d.ark b/tests/fuzzing/corpus/d.ark index a2572700..471ae7d2 100644 --- a/tests/fuzzing/corpus/d.ark +++ b/tests/fuzzing/corpus/d.ark @@ -1,4 +1,4 @@ -($ __count_placeholders (acc x ...xs) +(macro __count_placeholders (acc x ...xs) ($if (empty? xs) ($if (= "_" ($repr x)) (+ 1 acc) @@ -7,11 +7,11 @@ (__count_placeholders (+ 1 acc) ...xs) (__count_placeholders acc ...xs)))) -($ __suffix_dup (sym x) { +(macro __suffix_dup (sym x) { ($if (> x 1) (__suffix_dup sym (- x 1))) ($symcat sym x) }) -($ __replace_placeholders (replacements x ...xs) { +(macro __replace_placeholders (replacements x ...xs) { ($if (empty? xs) ($if (= "_" ($repr x)) (head replacements) @@ -24,10 +24,10 @@ x (__replace_placeholders replacements ...xs) }))}) -($ ! (call ...args) { - ($ length (__count_placeholders 0 ...args)) - ($ arg_bloc (__suffix_dup arg length)) - ($ all_args (__replace_placeholders [arg_bloc] ...args)) +(macro ! (call ...args) { + (macro length (__count_placeholders 0 ...args)) + (macro arg_bloc (__suffix_dup arg length)) + (macro all_args (__replace_placeholders [arg_bloc] ...args)) (fun (arg_bloc) (call all_args)) }) (let foo (fun (a b c d) diff --git a/tests/fuzzing/corpus/examples_macros.ark b/tests/fuzzing/corpus/examples_macros.ark index 4d345be0..81d2022f 100644 --- a/tests/fuzzing/corpus/examples_macros.ark +++ b/tests/fuzzing/corpus/examples_macros.ark @@ -1,9 +1,9 @@ -($ suffix-dup (sym x) { +(macro suffix-dup (sym x) { ($if (> x 1) (suffix-dup sym (- x 1))) ($symcat sym x) }) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef bloc) }) @@ -15,10 +15,10 @@ (print "Expected arguments for test_func1: " ($argcount test_func1) ", expected " 2) (print "Calling them: " (test_func 1 2 3) " " (test_func1 2 3)) -($ foo (a b) (+ a b)) +(macro foo (a b) (+ a b)) (print "Using macro foo (a b) => (+ a b): " (foo 1 2)) -($ var 12) +(macro var 12) (print "Using macro constant var=12: " var) ($if (= var 12) @@ -29,17 +29,17 @@ (print "This was executed in a if macro, testing (and true true)") (print "You shouldn't see this (bis)")) -($ defun (name args body) (let name (fun args body))) +(macro defun (name args body) (let name (fun args body))) (defun a_func (a b) (+ a b)) (print "Generated a function with a macro, a_func (a b) => (+ a b)") (print "Calling (a_func 1 2): " (a_func 1 2)) -($ one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) +(macro one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) (one 1 2) (one 1 3 4) (one 1 5 6 7 8) -($ last (...args) (print "Macro 'last', returns the last argument given in " args " => " (@ args -1))) +(macro last (...args) (print "Macro 'last', returns the last argument given in " args " => " (@ args -1))) (last 1 2) (last 1 3 4) (last 1 5 6 7 8) @@ -47,24 +47,24 @@ { (print "Testing macros in scopes and macro shadowing") - ($ test (+ 1 2 3)) + (macro test (+ 1 2 3)) (print "(global) Reading macro 'test', expected 6, " test) ((fun () { - ($ test (- 1 2 3)) + (macro test (- 1 2 3)) (print "(sub scope) Reading macro 'test', expected -4, " test) })) (print "(global) Reading macro 'test', expected 6, " test) { - ($ test 555) + (macro test 555) (print "(subscope) Reading macro 'test', expected 555, " test) - ($ undef test) + (macro undef test) (print "(subscope, undef test) Reading macro 'test', expected 6, " test) - ($ undef a) } } + (macro undef a) } } (print "Demonstrating a threading macro") -($ -> (arg fn1 ...fn) { +(macro -> (arg fn1 ...fn) { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) (fn1 arg)) }) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_astsuite_macros.ark b/tests/fuzzing/corpus/tests_unittests_resources_astsuite_macros.ark index 4a6dc1c9..87f205e9 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_astsuite_macros.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_astsuite_macros.ark @@ -1,10 +1,10 @@ -($ suffix-dup (sym x) { +(macro suffix-dup (sym x) { ($if (> x 1) (suffix-dup sym (- x 1))) ($symcat sym x)}) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)}) @@ -16,10 +16,10 @@ (print "Expected arguments for test_func1: " ($argcount test_func1) ", expected " 2) (print "Calling them: " (test_func 1 2 3) " " (test_func1 2 3)) -($ foo (a b) (+ a b)) +(macro foo (a b) (+ a b)) (print "Using macro foo (a b) => (+ a b): " (foo 1 2)) -($ var 12) +(macro var 12) (print "Using macro constant var=12: " var) ($if (= var 12) @@ -30,17 +30,17 @@ (print "This was executed in a if macro, testing (and true true)") (print "You shouldn't see this (bis)")) -($ defun (name args body) (let name (fun args body))) +(macro defun (name args body) (let name (fun args body))) (defun a_func (a b) (+ a b)) (print "Generated a function with a macro, a_func (a b) => (+ a b)") (print "Calling (a_func 1 2): " (a_func 1 2)) -($ one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) +(macro one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) (one 1 2) (one 1 3 4) (one 1 5 6 7 8) -($ last (...args) (print "Macro 'last', returns the last argument given in " args " => " (@ args -1))) +(macro last (...args) (print "Macro 'last', returns the last argument given in " args " => " (@ args -1))) (last 1 2) (last 1 3 4) (last 1 5 6 7 8) @@ -48,25 +48,25 @@ { (print "Testing macros in scopes and macro shadowing") - ($ test (+ 1 2 3)) + (macro test (+ 1 2 3)) (print "(global) Reading macro 'test', expected 6, " test) ((fun () { - ($ test (- 1 2 3)) + (macro test (- 1 2 3)) (print "(sub scope) Reading macro 'test', expected -4, " test)})) (print "(global) Reading macro 'test', expected 6, " test) { - ($ test 555) + (macro test 555) (print "(subscope) Reading macro 'test', expected 555, " test) - ($ undef test) + (macro undef test) (print "(subscope, undef test) Reading macro 'test', expected 6, " test) - ($ undef a)}} + (macro undef a)}} (print "Demonstrating a threading macro") -($ -> (arg fn1 ...fn) { +(macro -> (arg fn1 ...fn) { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) (fn1 arg))}) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_argcount_unknown_arg.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_argcount_unknown_arg.ark index 3e5b9126..2a55f7e3 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_argcount_unknown_arg.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_argcount_unknown_arg.ark @@ -1,10 +1,10 @@ -($ suffix-dup (sym x) { +(macro suffix-dup (sym x) { ($if (> x 1) (suffix-dup sym (- x 1))) ($symcat sym x)}) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)}) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_at_out_of_range.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_at_out_of_range.ark index 8807fb94..12122fb3 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_at_out_of_range.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_at_out_of_range.ark @@ -1,2 +1,2 @@ -($ last (...args) (print args " => " (@ args -9))) +(macro last (...args) (print args " => " (@ args -9))) (last 1 5 6 7 8) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_bad_macro_arg_list.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_bad_macro_arg_list.ark index 9c93a9ae..9ecfe0a9 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_bad_macro_arg_list.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_bad_macro_arg_list.ark @@ -1,2 +1,2 @@ -($ b ($symcat c)) +(macro b ($symcat c)) (print b) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_duplicated_arg.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_duplicated_arg.ark index 1a98502e..4fd6ebf5 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_duplicated_arg.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_duplicated_arg.ark @@ -1,4 +1,4 @@ -($ -> (arg fn ...fn) { +(macro -> (arg fn ...fn) { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) (fn1 arg))}) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_incomplete_macro.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_incomplete_macro.ark index ec2576e6..692f1994 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_incomplete_macro.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_incomplete_macro.ark @@ -1 +1 @@ -($ foo) +(macro foo) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_func.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_func.ark index e2e4c0a3..40c270c1 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_func.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_func.ark @@ -1 +1 @@ -(let foo (fun (a b) ($ a b))) +(let foo (fun (a b) (macro a b))) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let.ark index f4d8906b..c743abf5 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let.ark @@ -1,5 +1,5 @@ -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) }) (let test_func (fun (a b c) (* a b c))) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let_in_macro.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let_in_macro.ark index 23b7761e..b5673c3c 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let_in_macro.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_let_in_macro.ark @@ -1,3 +1,3 @@ -($ defun (name args body) (let 0000 (fun args body))) +(macro defun (name args body) (let 0000 (fun args body))) (defun a_func (a b) (+ a b)) (print (a_func 1 2)) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_sym_func_def.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_sym_func_def.ark index 36f8429a..efbca0af 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_sym_func_def.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_sym_func_def.ark @@ -1,2 +1,2 @@ -($ defun (name args body) (let name (fun args body))) +(macro defun (name args body) (let name (fun args body))) (defun 0 (a b) (+ a b)) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_while.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_while.ark index b7ee3107..0b69bda2 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_while.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_invalid_while.ark @@ -1,2 +1,2 @@ -(while ($ a 1) { +(while (macro a 1) { (mut acc (+ acc (@ [] a)))}) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_empty_arity_error.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_empty_arity_error.ark index b934b651..0d865d0e 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_empty_arity_error.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_empty_arity_error.ark @@ -1,2 +1,2 @@ -($ a (empty? 1 2)) +(macro a (empty? 1 2)) (print a) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_head_arity_error.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_head_arity_error.ark index ae9e1d05..73fe70d4 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_head_arity_error.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_head_arity_error.ark @@ -1,2 +1,2 @@ -($ a (head 1 2)) +(macro a (head 1 2)) (print a) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_len_arity_error.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_len_arity_error.ark index 3a8d5329..e34b7877 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_len_arity_error.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_len_arity_error.ark @@ -1,2 +1,2 @@ -($ a (len 1 2)) +(macro a (len 1 2)) (print a) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_paste_arity_error.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_paste_arity_error.ark index fa8e31ed..7037a573 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_paste_arity_error.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_paste_arity_error.ark @@ -1,2 +1,2 @@ -($ a ($as-is b [])) +(macro a ($as-is b [])) (print a) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_spread_not_enough_args.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_spread_not_enough_args.ark index 6fcf3f1e..5eb2450c 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_spread_not_enough_args.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_spread_not_enough_args.ark @@ -1,4 +1,4 @@ -($ foo (a b c ...d) +(macro foo (a b c ...d) (+ a b c ...d)) (foo 1 2) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arg_type_error.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arg_type_error.ark index 90a7a515..9386559a 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arg_type_error.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arg_type_error.ark @@ -1,2 +1,2 @@ -($ a ($symcat b [])) +(macro a ($symcat b [])) (print a) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arity_error.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arity_error.ark index 714be5ad..844646e3 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arity_error.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_arity_error.ark @@ -1,2 +1,2 @@ -($ a { ($symcat b) }) +(macro a { ($symcat b) }) (print a) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_type_error.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_type_error.ark index 4e89e75a..6f78333a 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_type_error.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_symcat_type_error.ark @@ -1,2 +1,2 @@ -($ a ($symcat 5 2)) +(macro a ($symcat 5 2)) (print a) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_tail_arity_error.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_tail_arity_error.ark index 0c4d06d7..2a2636d0 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_tail_arity_error.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_macro_tail_arity_error.ark @@ -1,2 +1,2 @@ -($ a (tail 1 2)) +(macro a (tail 1 2)) (print a) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_max_depth.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_max_depth.ark index ded7da30..a1f03451 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_max_depth.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_max_depth.ark @@ -1,2 +1,2 @@ -($ size (/ size 4)) +(macro size (/ size 4)) (let sum size) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_max_depth_eval.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_max_depth_eval.ark index 43c78c50..05f4135a 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_max_depth_eval.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_max_depth_eval.ark @@ -1,2 +1,2 @@ -($ last ((last 1 5 6 7 8) 0 s "@" (@ a00s -9))) +(macro last ((last 1 5 6 7 8) 0 s "@" (@ a00s -9))) (last 1 5 6 7 8) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_max_unification_depth.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_max_unification_depth.ark index 10f94aae..fc6a5572 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_max_unification_depth.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_max_unification_depth.ark @@ -1,11 +1,11 @@ -($ suffix-dup (sym x){ +(macro suffix-dup (sym x){ ($if (+ x 1) est_func - ($ p (a b c) (* a b c))) + (macro p (a b c) (* a b c))) ($symcat sym x)}) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (len defargs))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (len defargs))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)}) @@ -14,7 +14,7 @@ (* a b) (let inner (partial te t_func 0)) (let est_func - ($ partial (func ...defargs) { - ($ bloc (suffix-dup a (len defargs))) + (macro partial (func ...defargs) { + (macro bloc (suffix-dup a (len defargs))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)})))) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_not_enough_args.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_not_enough_args.ark index 49430d0c..c0e91dcb 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_not_enough_args.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_not_enough_args.ark @@ -1,4 +1,4 @@ -($ foo (a b c) +(macro foo (a b c) (+ a b c)) (foo 1 2) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_reused_macro_arg.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_reused_macro_arg.ark index 3c0711b8..590299ec 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_reused_macro_arg.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_reused_macro_arg.ark @@ -1 +1 @@ -($ foo (bar bar egg) ()) +(macro foo (bar bar egg) ()) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_too_many_args.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_too_many_args.ark index d864d544..939e9a4e 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_too_many_args.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_too_many_args.ark @@ -1,4 +1,4 @@ -($ foo (a b c) +(macro foo (a b c) (+ a b c)) (foo 1 2 3 4) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_unevaluated_spread.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_unevaluated_spread.ark index 8c24b14b..d021d203 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_unevaluated_spread.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_unevaluated_spread.ark @@ -1,4 +1,4 @@ -($ partial { +(macro partial { (fun (a) (func ...defargs)) }) (let b (partial)) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_well_formed_args.ark b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_well_formed_args.ark index 0b78bcd7..5ee42f4b 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_well_formed_args.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_diagnosticssuite_compiletime_well_formed_args.ark @@ -1,4 +1,4 @@ -($ defun (let name (fun args nil))) +(macro defun (let name (fun args nil))) (let foo 1) (let a 2) (let b 3) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_comment_after_macro_arg.ark b/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_comment_after_macro_arg.ark index 4af692a6..eb6dfc92 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_comment_after_macro_arg.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_comment_after_macro_arg.ark @@ -1,4 +1,4 @@ -($ -> ()#comment +(macro -> ()#comment { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_comments_after_call.ark b/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_comments_after_call.ark index aaf982c3..b2ff3283 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_comments_after_call.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_comments_after_call.ark @@ -1,4 +1,4 @@ -($ foo (...args # all the args go there +(macro foo (...args # all the args go there ) () # the body is empty ) [ a b c # last element diff --git a/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_macro_cond.ark b/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_macro_cond.ark index 1b077005..86ee184d 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_macro_cond.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_macro_cond.ark @@ -1,2 +1,2 @@ -($ -> (arg fn1 ...fn) { +(macro -> (arg fn1 ...fn) { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) (fn1 arg))}) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_macros.ark b/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_macros.ark index 70bb67bc..f7b1912f 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_macros.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_formattersuite_macros.ark @@ -1,6 +1,6 @@ -($ foo (a b) (+ a b)) -($ var 12) -($ defun (name args body) (let name (fun args body))) -($ one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) +(macro foo (a b) (+ a b)) +(macro var 12) +(macro defun (name args body) (let name (fun args body))) +(macro one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) ($undef a) ($repr a) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_langsuite_macro-tests.ark b/tests/fuzzing/corpus/tests_unittests_resources_langsuite_macro-tests.ark index f46f1f1e..e2a51691 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_langsuite_macro-tests.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_langsuite_macro-tests.ark @@ -1,13 +1,13 @@ (import std.Testing) -($ suffix-dup (sym x) { +(macro suffix-dup (sym x) { ($if (> x 1) (suffix-dup sym (- x 1))) ($symcat sym x)}) (let magic_func (fun ((suffix-dup a 3)) (- a1 a2 a3))) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)}) @@ -16,38 +16,38 @@ (let test_func1_2 (partial test_func1 2)) (test:suite macro { - ($ nice_value 12) + (macro nice_value 12) (test:case "basic macros" { - ($ void () nil) + (macro void () nil) (test:eq (void) nil) - ($ add_two (a b) (+ a b)) + (macro add_two (a b) (+ a b)) (test:eq (add_two 1 2) 3) (test:eq (add_two nice_value 2) 14) - ($ c (a b) (* a b)) + (macro c (a b) (* a b)) (test:eq (c 4 10) 40) - ($ d (a b) (/ a b)) + (macro d (a b) (/ a b)) (test:eq (d 10 2) 5) - ($ e (+ 1 2 3)) - ($ f (* 2 2 3)) - ($ g (- 1 2 3)) - ($ h (/ 12 2 3)) + (macro e (+ 1 2 3)) + (macro f (* 2 2 3)) + (macro g (- 1 2 3)) + (macro h (/ 12 2 3)) (test:eq e 6) (test:eq f 12) (test:eq g -4) (test:eq h (/ 12 6)) }) (test:case "node manipulation" { - ($ node_tail () (tail (begin 1 2 3))) - ($ length () (len (fun () 5))) - ($ not_empty_node () (empty? (fun () ()))) - ($ empty_node () (empty? ())) - ($ empty_node_bis (empty? ())) + (macro node_tail () (tail (begin 1 2 3))) + (macro length () (len (fun () 5))) + (macro not_empty_node () (empty? (fun () ()))) + (macro empty_node () (empty? ())) + (macro empty_node_bis (empty? ())) (test:eq (length) 3) (test:eq (not_empty_node) false) @@ -72,9 +72,9 @@ (test:expect ($if (@ [true false] -2) true false)) (test:expect ($if 1 true false)) ($if true { - ($ in_if_1 true) - ($ in_if_2 true)}) - ($if true ($ new_value true)) + (macro in_if_1 true) + (macro in_if_2 true)}) + ($if true (macro new_value true)) (test:expect (and in_if_1 in_if_2) "a variable can be defined inside a conditional macro") (test:expect new_value "variable can be defined inside a conditional macro") @@ -82,11 +82,11 @@ ($undef in_if_2) }) { - ($ val (+ 1 2 3)) + (macro val (+ 1 2 3)) (test:eq val 6 "val should be computed to 6") { - ($ val 0) + (macro val 0) (test:eq val 0 "val is shadowed") ($undef val) (test:eq val 6 "shadowed version should be undefined") @@ -95,57 +95,57 @@ (test:eq val 6 "val should still resolve to 6")} (test:case "macro expansion" { - ($ bar (a ...args) (+ a (len args))) + (macro bar (a ...args) (+ a (len args))) (test:eq (bar 1) 1) (test:eq (bar 2 3) 3) (test:eq (bar 4 5 6) 6) (test:eq (bar 7 8 9 10) 10) - ($ egg (...args) (bar ...args)) + (macro egg (...args) (bar ...args)) (test:eq (egg 1) 1) (test:eq (egg 0 1) 1) (test:eq (egg 0 0 0 1) 3) - ($ h (...args) (head args)) + (macro h (...args) (head args)) (test:eq (h) nil) (test:eq (h 1) 1) (test:eq (h 1 2) 1) - ($ g (...args) (tail args)) + (macro g (...args) (tail args)) (test:eq (g) []) (test:eq (g 1) []) (test:eq (g 1 2) [2]) (test:eq (g 1 2 3) [2 3]) - ($ one (...args) (@ args 1)) + (macro one (...args) (@ args 1)) (test:eq (one 1 2) 2) (test:eq (one 1 3 4) 3) (test:eq (one 1 5 6 7 8) 5) - ($ last (...args) (@ args -1)) + (macro last (...args) (@ args -1)) (test:eq (last 1 2) 2) (test:eq (last 1 3 4) 4) (test:eq (last 1 5 6 7 8) 8) }) (test:case "generate valid arkscript code with macros" { - ($ make-func (retval) (fun () retval)) + (macro make-func (retval) (fun () retval)) (let a-func (make-func 1)) (test:eq (type a-func) "Function") (test:eq (a-func) 1) - ($ defun (name args body) (let name (fun args body))) + (macro defun (name args body) (let name (fun args body))) (defun foo (a b) (+ a b)) (test:eq (type foo) "Function") (test:eq (foo 2 3) 5) - ($ get_symbol (bloc) (@ bloc 1)) - ($ define (bloc) (let (get_symbol bloc) (@ bloc 2))) + (macro get_symbol (bloc) (@ bloc 1)) + (macro define (bloc) (let (get_symbol bloc) (@ bloc 2))) (define (let a 12)) (test:eq a 12) }) (test:case "define variable with a macro adding a suffix" { - ($ nice_value 12) - ($ define (prefix suffix value) (let ($symcat prefix suffix) value)) + (macro nice_value 12) + (macro define (prefix suffix value) (let ($symcat prefix suffix) value)) (define a 1 2) (test:eq a1 2) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_failure_incomplete_macro.ark b/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_failure_incomplete_macro.ark index 46261cd9..0e6a330e 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_failure_incomplete_macro.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_failure_incomplete_macro.ark @@ -1 +1 @@ -($ (a) a) +(macro (a) a) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_failure_incomplete_macro_arguments.ark b/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_failure_incomplete_macro_arguments.ark index 88c585ef..862e0ed4 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_failure_incomplete_macro_arguments.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_failure_incomplete_macro_arguments.ark @@ -1 +1 @@ -($ foo (a +(macro foo (a diff --git a/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_failure_incomplete_macro_spread.ark b/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_failure_incomplete_macro_spread.ark index 93f9f294..e26ff231 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_failure_incomplete_macro_spread.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_failure_incomplete_macro_spread.ark @@ -1 +1 @@ -($ foo (bar ...) (bar)) +(macro foo (bar ...) (bar)) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_success_macro.ark b/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_success_macro.ark index 1e224b4a..9359f41b 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_success_macro.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_parsersuite_success_macro.ark @@ -1,5 +1,5 @@ -($ a 1) -($ b () 2) +(macro a 1) +(macro b () 2) ($ c # macro name ( # arg list @@ -8,11 +8,11 @@ e ) 3 # body ) -($ f(g)4) -($ h(i j) (let a 1)) +(macro f(g)4) +(macro h(i j) (let a 1)) -($ h (i j) (let a (if i 2 3))) -($ k (l ...m) (print l m)) -($ n ( +(macro h (i j) (let a (if i 2 3))) +(macro k (l ...m) (print l m)) +(macro n ( ...p ) (print p)) diff --git a/tests/fuzzing/corpus/tests_unittests_resources_rosettasuite_extend_your_language.ark b/tests/fuzzing/corpus/tests_unittests_resources_rosettasuite_extend_your_language.ark index fe781497..5998248d 100644 --- a/tests/fuzzing/corpus/tests_unittests_resources_rosettasuite_extend_your_language.ark +++ b/tests/fuzzing/corpus/tests_unittests_resources_rosettasuite_extend_your_language.ark @@ -1,4 +1,4 @@ -($ if2 (conds bothConditionsAreTrue firstConditionIsTrue secondConditionIsTrue noConditionIsTrue) { +(macro if2 (conds bothConditionsAreTrue firstConditionIsTrue secondConditionIsTrue noConditionIsTrue) { (mut result1 (head conds)) (mut result2 (@ conds 1)) (if (and result1 result2) diff --git a/tests/unittests/resources/ASTSuite/macros.ark b/tests/unittests/resources/ASTSuite/macros.ark index 4a6dc1c9..87f205e9 100644 --- a/tests/unittests/resources/ASTSuite/macros.ark +++ b/tests/unittests/resources/ASTSuite/macros.ark @@ -1,10 +1,10 @@ -($ suffix-dup (sym x) { +(macro suffix-dup (sym x) { ($if (> x 1) (suffix-dup sym (- x 1))) ($symcat sym x)}) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)}) @@ -16,10 +16,10 @@ (print "Expected arguments for test_func1: " ($argcount test_func1) ", expected " 2) (print "Calling them: " (test_func 1 2 3) " " (test_func1 2 3)) -($ foo (a b) (+ a b)) +(macro foo (a b) (+ a b)) (print "Using macro foo (a b) => (+ a b): " (foo 1 2)) -($ var 12) +(macro var 12) (print "Using macro constant var=12: " var) ($if (= var 12) @@ -30,17 +30,17 @@ (print "This was executed in a if macro, testing (and true true)") (print "You shouldn't see this (bis)")) -($ defun (name args body) (let name (fun args body))) +(macro defun (name args body) (let name (fun args body))) (defun a_func (a b) (+ a b)) (print "Generated a function with a macro, a_func (a b) => (+ a b)") (print "Calling (a_func 1 2): " (a_func 1 2)) -($ one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) +(macro one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) (one 1 2) (one 1 3 4) (one 1 5 6 7 8) -($ last (...args) (print "Macro 'last', returns the last argument given in " args " => " (@ args -1))) +(macro last (...args) (print "Macro 'last', returns the last argument given in " args " => " (@ args -1))) (last 1 2) (last 1 3 4) (last 1 5 6 7 8) @@ -48,25 +48,25 @@ { (print "Testing macros in scopes and macro shadowing") - ($ test (+ 1 2 3)) + (macro test (+ 1 2 3)) (print "(global) Reading macro 'test', expected 6, " test) ((fun () { - ($ test (- 1 2 3)) + (macro test (- 1 2 3)) (print "(sub scope) Reading macro 'test', expected -4, " test)})) (print "(global) Reading macro 'test', expected 6, " test) { - ($ test 555) + (macro test 555) (print "(subscope) Reading macro 'test', expected 555, " test) - ($ undef test) + (macro undef test) (print "(subscope, undef test) Reading macro 'test', expected 6, " test) - ($ undef a)}} + (macro undef a)}} (print "Demonstrating a threading macro") -($ -> (arg fn1 ...fn) { +(macro -> (arg fn1 ...fn) { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) (fn1 arg))}) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/argcount_unknown_arg.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/argcount_unknown_arg.ark index 3e5b9126..2a55f7e3 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/argcount_unknown_arg.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/argcount_unknown_arg.ark @@ -1,10 +1,10 @@ -($ suffix-dup (sym x) { +(macro suffix-dup (sym x) { ($if (> x 1) (suffix-dup sym (- x 1))) ($symcat sym x)}) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)}) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/argcount_unknown_arg.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/argcount_unknown_arg.expected index a9dab005..ed7067b8 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/argcount_unknown_arg.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/argcount_unknown_arg.expected @@ -1,5 +1,5 @@ At test_func1!2 @ 13:28 - 1 | ($ suffix-dup (sym x) { + 1 | (macro suffix-dup (sym x) { | ^ macro expansion started here 2 | ($if (> x 1) 3 | (suffix-dup sym (- x 1))) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/at_out_of_range.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/at_out_of_range.ark index 8807fb94..12122fb3 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/at_out_of_range.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/at_out_of_range.ark @@ -1,2 +1,2 @@ -($ last (...args) (print args " => " (@ args -9))) +(macro last (...args) (print args " => " (@ args -9))) (last 1 5 6 7 8) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/at_out_of_range.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/at_out_of_range.expected index 310e4500..8a42fa5b 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/at_out_of_range.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/at_out_of_range.expected @@ -1,6 +1,6 @@ -At (@ (list 1 5 6 7 8) -9) @ 1:39 - 1 | ($ last (...args) (print args " => " (@ args -9))) - | │ └─ error +At (@ (list 1 5 6 7 8) -9) @ 1:43 + 1 | (macro last (...args) (print args " => " (@ args -9))) + | │ └─ error | │ | └─ macro expansion started here 2 | (last 1 5 6 7 8) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/duplicated_arg.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/duplicated_arg.ark index 1a98502e..4fd6ebf5 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/duplicated_arg.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/duplicated_arg.ark @@ -1,4 +1,4 @@ -($ -> (arg fn ...fn) { +(macro -> (arg fn ...fn) { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) (fn1 arg))}) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/duplicated_arg.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/duplicated_arg.expected index d3a42c68..1c3eb28c 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/duplicated_arg.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/duplicated_arg.expected @@ -1,6 +1,6 @@ -At . @ 1:15 - 1 | ($ -> (arg fn ...fn) { - | ^~~~~ +At . @ 1:19 + 1 | (macro -> (arg fn ...fn) { + | ^~~~~ 2 | ($if (> (len fn) 0) 3 | (-> (fn1 arg) ...fn) Argument names must be unique, can not reuse `fn' diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/incomplete_macro.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/incomplete_macro.ark index ec2576e6..692f1994 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/incomplete_macro.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/incomplete_macro.ark @@ -1 +1 @@ -($ foo) +(macro foo) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/incomplete_macro.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/incomplete_macro.expected index 80965e09..9f9a435e 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/incomplete_macro.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/incomplete_macro.expected @@ -1,5 +1,5 @@ -At ) @ 1:7 - 1 | ($ foo) - | ^ +At ) @ 1:11 + 1 | (macro foo) + | ^ 2 | Expected an argument list, atom or node while defining macro `foo' diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_func.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_func.ark index e2e4c0a3..40c270c1 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_func.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_func.ark @@ -1 +1 @@ -(let foo (fun (a b) ($ a b))) +(let foo (fun (a b) (macro a b))) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_func.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_func.expected index a362dda6..9f2aa650 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_func.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_func.expected @@ -1,5 +1,5 @@ At (fun (a b)) @ 1:11 - 1 | (let foo (fun (a b) ($ a b))) + 1 | (let foo (fun (a b) (macro a b))) | ^~~~~~~~~~~ 2 | Invalid node ; if it was computed by a macro, check that a node is returned diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_let.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_let.ark index f4d8906b..c743abf5 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_let.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_let.ark @@ -1,5 +1,5 @@ -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) }) (let test_func (fun (a b c) (* a b c))) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_let_in_macro.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_let_in_macro.ark index 23b7761e..b5673c3c 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_let_in_macro.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_let_in_macro.ark @@ -1,3 +1,3 @@ -($ defun (name args body) (let 0000 (fun args body))) +(macro defun (name args body) (let 0000 (fun args body))) (defun a_func (a b) (+ a b)) (print (a_func 1 2)) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_let_in_macro.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_let_in_macro.expected index 3555db69..c6905654 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_let_in_macro.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_let_in_macro.expected @@ -1,6 +1,6 @@ -At ' ' @ 1:36 - 1 | ($ defun (name args body) (let 0000 (fun args body))) - | ^ +At ' ' @ 1:40 + 1 | (macro defun (name args body) (let 0000 (fun args body))) + | ^ 2 | (defun a_func (a b) (+ a b)) 3 | (print (a_func 1 2)) Can not use a Number as a symbol name, even in a macro diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_sym_func_def.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_sym_func_def.ark index 36f8429a..efbca0af 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_sym_func_def.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_sym_func_def.ark @@ -1,2 +1,2 @@ -($ defun (name args body) (let name (fun args body))) +(macro defun (name args body) (let name (fun args body))) (defun 0 (a b) (+ a b)) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_sym_func_def.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_sym_func_def.expected index 028bf8a2..977ef941 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_sym_func_def.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_sym_func_def.expected @@ -1,5 +1,5 @@ At 0 @ 2:8 - 1 | ($ defun (name args body) (let name (fun args body))) + 1 | (macro defun (name args body) (let name (fun args body))) 2 | (defun 0 (a b) (+ a b)) | ^ 3 | diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_while.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_while.ark index b7ee3107..0b69bda2 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_while.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_while.ark @@ -1,2 +1,2 @@ -(while ($ a 1) { +(while (macro a 1) { (mut acc (+ acc (@ [] a)))}) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_while.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_while.expected index c5b6b384..eab04bf7 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_while.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_while.expected @@ -1,7 +1,7 @@ At (while (begin (mut acc (+ acc (@ (list) 1))))) @ 1:2 - 1 | (while ($ a 1) { - | ^~~~~~~~~~~~~~~~ + 1 | (while (macro a 1) { + | ^~~~~~~~~~~~~~~~~~~~ 2 | (mut acc (+ acc (@ [] a)))}) - | ^~~~~~~~~~~~~~~~ + | ^~~~~~~~ 3 | Invalid node ; if it was computed by a macro, check that a node is returned diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_empty_arity_error.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_empty_arity_error.ark index b934b651..0d865d0e 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_empty_arity_error.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_empty_arity_error.ark @@ -1,2 +1,2 @@ -($ a (empty? 1 2)) +(macro a (empty? 1 2)) (print a) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_empty_arity_error.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_empty_arity_error.expected index a50836ec..2c591452 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_empty_arity_error.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_empty_arity_error.expected @@ -1,6 +1,6 @@ -At (empty? 1 2) @ 1:7 - 1 | ($ a (empty? 1 2)) - | ^~~~~~~~~~~~~~~~~~ +At (empty? 1 2) @ 1:11 + 1 | (macro a (empty? 1 2)) + | ^~~~~~~~~~~~~~~~~~~~~~ 2 | (print a) 3 | When expanding `empty?' inside a macro, got 2 arguments, expected 1 diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_head_arity_error.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_head_arity_error.ark index ae9e1d05..73fe70d4 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_head_arity_error.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_head_arity_error.ark @@ -1,2 +1,2 @@ -($ a (head 1 2)) +(macro a (head 1 2)) (print a) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_head_arity_error.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_head_arity_error.expected index 6bea0b6c..88266cd2 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_head_arity_error.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_head_arity_error.expected @@ -1,6 +1,6 @@ -At (head 1 2) @ 1:7 - 1 | ($ a (head 1 2)) - | ^~~~~~~~~~~~~~~~ +At (head 1 2) @ 1:11 + 1 | (macro a (head 1 2)) + | ^~~~~~~~~~~~~~~~~~~~ 2 | (print a) 3 | When expanding `head' inside a macro, got 2 arguments, expected 1 diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_len_arity_error.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_len_arity_error.ark index 3a8d5329..e34b7877 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_len_arity_error.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_len_arity_error.ark @@ -1,2 +1,2 @@ -($ a (len 1 2)) +(macro a (len 1 2)) (print a) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_len_arity_error.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_len_arity_error.expected index 2d16fea9..b838cbab 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_len_arity_error.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_len_arity_error.expected @@ -1,6 +1,6 @@ -At (len 1 2) @ 1:7 - 1 | ($ a (len 1 2)) - | ^~~~~~~~~~~~~~~ +At (len 1 2) @ 1:11 + 1 | (macro a (len 1 2)) + | ^~~~~~~~~~~~~~~~~~~ 2 | (print a) 3 | When expanding `len' inside a macro, got 2 arguments, expected 1 diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_paste_arity_error.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_paste_arity_error.ark index fa8e31ed..7037a573 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_paste_arity_error.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_paste_arity_error.ark @@ -1,2 +1,2 @@ -($ a ($as-is b [])) +(macro a ($as-is b [])) (print a) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_paste_arity_error.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_paste_arity_error.expected index 4ee58c3e..bf927b02 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_paste_arity_error.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_paste_arity_error.expected @@ -1,6 +1,6 @@ -At ($as-is b (list)) @ 1:7 - 1 | ($ a ($as-is b [])) - | │ └─ error +At ($as-is b (list)) @ 1:11 + 1 | (macro a ($as-is b [])) + | │ └─ error | │ | └─ macro expansion started here 2 | (print a) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_spread_not_enough_args.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_spread_not_enough_args.ark index 6fcf3f1e..5eb2450c 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_spread_not_enough_args.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_spread_not_enough_args.ark @@ -1,4 +1,4 @@ -($ foo (a b c ...d) +(macro foo (a b c ...d) (+ a b c ...d)) (foo 1 2) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_spread_not_enough_args.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_spread_not_enough_args.expected index 20730909..c2567320 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_spread_not_enough_args.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_spread_not_enough_args.expected @@ -1,5 +1,5 @@ At (foo 1 2) @ 4:2 - 1 | ($ foo (a b c ...d) + 1 | (macro foo (a b c ...d) | ^ macro expansion started here 2 | (+ a b c ...d)) 3 | diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arg_type_error.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arg_type_error.ark index 90a7a515..9386559a 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arg_type_error.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arg_type_error.ark @@ -1,2 +1,2 @@ -($ a ($symcat b [])) +(macro a ($symcat b [])) (print a) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arg_type_error.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arg_type_error.expected index e256d20c..c15bcc94 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arg_type_error.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arg_type_error.expected @@ -1,6 +1,6 @@ -At (list) @ 1:17 - 1 | ($ a ($symcat b [])) - | │ └─ error +At (list) @ 1:21 + 1 | (macro a ($symcat b [])) + | │ └─ error | │ | └─ macro expansion started here 2 | (print a) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arity_error.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arity_error.ark index 714be5ad..844646e3 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arity_error.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arity_error.ark @@ -1,2 +1,2 @@ -($ a { ($symcat b) }) +(macro a { ($symcat b) }) (print a) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arity_error.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arity_error.expected index 3c3fc223..23262cc8 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arity_error.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_arity_error.expected @@ -1,6 +1,6 @@ -At ($symcat b) @ 1:9 - 1 | ($ a { ($symcat b) }) - | ^~~~~~~~~~~ +At ($symcat b) @ 1:13 + 1 | (macro a { ($symcat b) }) + | ^~~~~~~~~~~ 2 | (print a) 3 | When expanding `$symcat', expected at least 2 arguments, got 1 arguments diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_type_error.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_type_error.ark index 4e89e75a..6f78333a 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_type_error.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_type_error.ark @@ -1,2 +1,2 @@ -($ a ($symcat 5 2)) +(macro a ($symcat 5 2)) (print a) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_type_error.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_type_error.expected index 84c45af3..7a7f0451 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_type_error.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_symcat_type_error.expected @@ -1,6 +1,6 @@ -At ($symcat 5 2) @ 1:7 - 1 | ($ a ($symcat 5 2)) - | │ └─ error +At ($symcat 5 2) @ 1:11 + 1 | (macro a ($symcat 5 2)) + | │ └─ error | │ | └─ macro expansion started here 2 | (print a) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_tail_arity_error.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_tail_arity_error.ark index 0c4d06d7..2a2636d0 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_tail_arity_error.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_tail_arity_error.ark @@ -1,2 +1,2 @@ -($ a (tail 1 2)) +(macro a (tail 1 2)) (print a) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_tail_arity_error.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_tail_arity_error.expected index 3646993c..5cac5266 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_tail_arity_error.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/macro_tail_arity_error.expected @@ -1,6 +1,6 @@ -At (tail 1 2) @ 1:7 - 1 | ($ a (tail 1 2)) - | ^~~~~~~~~~~~~~~~ +At (tail 1 2) @ 1:11 + 1 | (macro a (tail 1 2)) + | ^~~~~~~~~~~~~~~~~~~~ 2 | (print a) 3 | When expanding `tail' inside a macro, got 2 arguments, expected 1 diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth.ark index ded7da30..a1f03451 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth.ark @@ -1,2 +1,2 @@ -($ size (/ size 4)) +(macro size (/ size 4)) (let sum size) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth.expected index 8ebfe769..99efaaaa 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth.expected @@ -1,6 +1,6 @@ -At / @ 1:10 - 1 | ($ size (/ size 4)) - | ^ +At / @ 1:14 + 1 | (macro size (/ size 4)) + | ^ 2 | (let sum size) 3 | Max recursion depth reached (256). You most likely have a badly defined recursive macro calling itself without a proper exit condition diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth_eval.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth_eval.ark index 43c78c50..05f4135a 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth_eval.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth_eval.ark @@ -1,2 +1,2 @@ -($ last ((last 1 5 6 7 8) 0 s "@" (@ a00s -9))) +(macro last ((last 1 5 6 7 8) 0 s "@" (@ a00s -9))) (last 1 5 6 7 8) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth_eval.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth_eval.expected index c8ec839d..9e08676a 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth_eval.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth_eval.expected @@ -1,6 +1,6 @@ -At last @ 1:11 - 1 | ($ last ((last 1 5 6 7 8) 0 s "@" (@ a00s -9))) - | │ └─ error +At last @ 1:15 + 1 | (macro last ((last 1 5 6 7 8) 0 s "@" (@ a00s -9))) + | │ └─ error | │ | └─ macro expansion started here 2 | (last 1 5 6 7 8) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_unification_depth.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_unification_depth.ark index 10f94aae..fc6a5572 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_unification_depth.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_unification_depth.ark @@ -1,11 +1,11 @@ -($ suffix-dup (sym x){ +(macro suffix-dup (sym x){ ($if (+ x 1) est_func - ($ p (a b c) (* a b c))) + (macro p (a b c) (* a b c))) ($symcat sym x)}) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (len defargs))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (len defargs))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)}) @@ -14,7 +14,7 @@ (* a b) (let inner (partial te t_func 0)) (let est_func - ($ partial (func ...defargs) { - ($ bloc (suffix-dup a (len defargs))) + (macro partial (func ...defargs) { + (macro bloc (suffix-dup a (len defargs))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)})))) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_unification_depth.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_unification_depth.expected index 3348b031..788739ee 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_unification_depth.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_unification_depth.expected @@ -1,18 +1,18 @@ -At ($ partial (func ...defargs) (begin ($ bloc (suffix-dup a (len defargs))) (fun (bloc) (func ...defargs bloc)) ($undef bloc))) @ 17:17 - 4 | ($ p (a b c) (* a b c))) +At (macro partial (func ...defargs) (begin (macro bloc (suffix-dup a (len defargs))) (fun (bloc) (func ...defargs bloc)) ($undef bloc))) @ 17:17 + 4 | (macro p (a b c) (* a b c))) 5 | ($symcat sym x)}) 6 | - 7 | ($ partial (func ...defargs) { + 7 | (macro partial (func ...defargs) { | ^ macro expansion started here - 8 | ($ bloc (suffix-dup a (len defargs))) + 8 | (macro bloc (suffix-dup a (len defargs))) 9 | (fun (bloc) (func ...defargs bloc)) ... | 14 | (* a b) 15 | (let inner (partial te t_func 0)) 16 | (let est_func - 17 | ($ partial (func ...defargs) { - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 18 | ($ bloc (suffix-dup a (len defargs))) + 17 | (macro partial (func ...defargs) { + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 18 | (macro bloc (suffix-dup a (len defargs))) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 19 | (fun (bloc) (func ...defargs bloc)) Max macro unification depth reached (256). You may have a macro trying to evaluate itself, try splitting your code in multiple nodes. diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/not_enough_args.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/not_enough_args.ark index 49430d0c..c0e91dcb 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/not_enough_args.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/not_enough_args.ark @@ -1,4 +1,4 @@ -($ foo (a b c) +(macro foo (a b c) (+ a b c)) (foo 1 2) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/not_enough_args.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/not_enough_args.expected index 7f6a83e2..6b4a5559 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/not_enough_args.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/not_enough_args.expected @@ -1,5 +1,5 @@ At (foo 1 2) @ 4:2 - 1 | ($ foo (a b c) + 1 | (macro foo (a b c) | ^ macro expansion started here 2 | (+ a b c)) 3 | diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/reused_macro_arg.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/reused_macro_arg.ark index 3c0711b8..590299ec 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/reused_macro_arg.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/reused_macro_arg.ark @@ -1 +1 @@ -($ foo (bar bar egg) ()) +(macro foo (bar bar egg) ()) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/reused_macro_arg.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/reused_macro_arg.expected index 8339d0bf..cfe1aef7 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/reused_macro_arg.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/reused_macro_arg.expected @@ -1,5 +1,5 @@ -At b @ 1:13 - 1 | ($ foo (bar bar egg) ()) - | ^~~ +At b @ 1:17 + 1 | (macro foo (bar bar egg) ()) + | ^~~ 2 | Argument names must be unique, can not reuse `bar' diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/too_many_args.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/too_many_args.ark index d864d544..939e9a4e 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/too_many_args.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/too_many_args.ark @@ -1,4 +1,4 @@ -($ foo (a b c) +(macro foo (a b c) (+ a b c)) (foo 1 2 3 4) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/too_many_args.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/too_many_args.expected index 73c52283..6716f0d6 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/too_many_args.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/too_many_args.expected @@ -1,5 +1,5 @@ At (foo 1 2 3 4) @ 4:2 - 1 | ($ foo (a b c) + 1 | (macro foo (a b c) | ^ macro expansion started here 2 | (+ a b c)) 3 | diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/unevaluated_spread.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/unevaluated_spread.ark index 8c24b14b..d021d203 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/unevaluated_spread.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/unevaluated_spread.ark @@ -1,4 +1,4 @@ -($ partial { +(macro partial { (fun (a) (func ...defargs)) }) (let b (partial)) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/unevaluated_spread.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/unevaluated_spread.expected index 481db9f8..656c39f8 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/unevaluated_spread.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/unevaluated_spread.expected @@ -1,5 +1,5 @@ At ...defargs @ 2:18 - 1 | ($ partial { + 1 | (macro partial { 2 | (fun (a) (func ...defargs)) }) | ^~~~~~~~~~ 3 | diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/well_formed_args.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/well_formed_args.ark index 0b78bcd7..5ee42f4b 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/well_formed_args.ark +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/well_formed_args.ark @@ -1,4 +1,4 @@ -($ defun (let name (fun args nil))) +(macro defun (let name (fun args nil))) (let foo 1) (let a 2) (let b 3) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/well_formed_args.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/well_formed_args.expected index c4748a86..d1e5349f 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/well_formed_args.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/well_formed_args.expected @@ -1,6 +1,6 @@ -At args @ 1:25 - 1 | ($ defun (let name (fun args nil))) - | ^~~~ +At args @ 1:29 + 1 | (macro defun (let name (fun args nil))) + | ^~~~ 2 | (let foo 1) 3 | (let a 2) Expected a well formed argument(s) list, got a Symbol diff --git a/tests/unittests/resources/FormatterSuite/comment_after_macro_arg.ark b/tests/unittests/resources/FormatterSuite/comment_after_macro_arg.ark index 4af692a6..eb6dfc92 100644 --- a/tests/unittests/resources/FormatterSuite/comment_after_macro_arg.ark +++ b/tests/unittests/resources/FormatterSuite/comment_after_macro_arg.ark @@ -1,4 +1,4 @@ -($ -> ()#comment +(macro -> ()#comment { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) diff --git a/tests/unittests/resources/FormatterSuite/comment_after_macro_arg.expected b/tests/unittests/resources/FormatterSuite/comment_after_macro_arg.expected index eca5544e..d98d32d2 100644 --- a/tests/unittests/resources/FormatterSuite/comment_after_macro_arg.expected +++ b/tests/unittests/resources/FormatterSuite/comment_after_macro_arg.expected @@ -1,4 +1,4 @@ -($ -> () #comment +(macro -> () #comment { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) diff --git a/tests/unittests/resources/FormatterSuite/comments_after_call.ark b/tests/unittests/resources/FormatterSuite/comments_after_call.ark index 900ffb28..b2ff3283 100644 --- a/tests/unittests/resources/FormatterSuite/comments_after_call.ark +++ b/tests/unittests/resources/FormatterSuite/comments_after_call.ark @@ -1,4 +1,4 @@ -($ foo (...args # all the args go there +(macro foo (...args # all the args go there ) () # the body is empty ) [ a b c # last element @@ -7,4 +7,4 @@ (foo # func bar # arg egg # arg bis - ) \ No newline at end of file + ) diff --git a/tests/unittests/resources/FormatterSuite/comments_after_call.expected b/tests/unittests/resources/FormatterSuite/comments_after_call.expected index ee628a87..1dfe0c70 100644 --- a/tests/unittests/resources/FormatterSuite/comments_after_call.expected +++ b/tests/unittests/resources/FormatterSuite/comments_after_call.expected @@ -1,4 +1,4 @@ -($ foo (...args # all the args go there +(macro foo (...args # all the args go there ) () # the body is empty ) diff --git a/tests/unittests/resources/FormatterSuite/macro_cond.ark b/tests/unittests/resources/FormatterSuite/macro_cond.ark index 1fd358be..86ee184d 100644 --- a/tests/unittests/resources/FormatterSuite/macro_cond.ark +++ b/tests/unittests/resources/FormatterSuite/macro_cond.ark @@ -1,2 +1,2 @@ -($ -> (arg fn1 ...fn) { - ($if (> (len fn) 0) (-> (fn1 arg) ...fn) (fn1 arg))}) \ No newline at end of file +(macro -> (arg fn1 ...fn) { + ($if (> (len fn) 0) (-> (fn1 arg) ...fn) (fn1 arg))}) diff --git a/tests/unittests/resources/FormatterSuite/macro_cond.expected b/tests/unittests/resources/FormatterSuite/macro_cond.expected index 65ce9b7f..02e0b480 100644 --- a/tests/unittests/resources/FormatterSuite/macro_cond.expected +++ b/tests/unittests/resources/FormatterSuite/macro_cond.expected @@ -1,4 +1,4 @@ -($ -> (arg fn1 ...fn) { +(macro -> (arg fn1 ...fn) { ($if (> (len fn) 0) (-> (fn1 arg) ...fn) (fn1 arg)) }) diff --git a/tests/unittests/resources/FormatterSuite/macros.ark b/tests/unittests/resources/FormatterSuite/macros.ark index e156af82..f7b1912f 100644 --- a/tests/unittests/resources/FormatterSuite/macros.ark +++ b/tests/unittests/resources/FormatterSuite/macros.ark @@ -1,6 +1,6 @@ -($ foo (a b) (+ a b)) -($ var 12) -($ defun (name args body) (let name (fun args body))) -($ one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) +(macro foo (a b) (+ a b)) +(macro var 12) +(macro defun (name args body) (let name (fun args body))) +(macro one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) ($undef a) -($repr a) \ No newline at end of file +($repr a) diff --git a/tests/unittests/resources/FormatterSuite/macros.expected b/tests/unittests/resources/FormatterSuite/macros.expected index 70bb67bc..f7b1912f 100644 --- a/tests/unittests/resources/FormatterSuite/macros.expected +++ b/tests/unittests/resources/FormatterSuite/macros.expected @@ -1,6 +1,6 @@ -($ foo (a b) (+ a b)) -($ var 12) -($ defun (name args body) (let name (fun args body))) -($ one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) +(macro foo (a b) (+ a b)) +(macro var 12) +(macro defun (name args body) (let name (fun args body))) +(macro one (...args) (print "Macro 'one', returns the 2nd argument given in " args " => " (@ args 1))) ($undef a) ($repr a) diff --git a/tests/unittests/resources/LangSuite/macro-tests.ark b/tests/unittests/resources/LangSuite/macro-tests.ark index f46f1f1e..e2a51691 100644 --- a/tests/unittests/resources/LangSuite/macro-tests.ark +++ b/tests/unittests/resources/LangSuite/macro-tests.ark @@ -1,13 +1,13 @@ (import std.Testing) -($ suffix-dup (sym x) { +(macro suffix-dup (sym x) { ($if (> x 1) (suffix-dup sym (- x 1))) ($symcat sym x)}) (let magic_func (fun ((suffix-dup a 3)) (- a1 a2 a3))) -($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) +(macro partial (func ...defargs) { + (macro bloc (suffix-dup a (- ($argcount func) (len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef bloc)}) @@ -16,38 +16,38 @@ (let test_func1_2 (partial test_func1 2)) (test:suite macro { - ($ nice_value 12) + (macro nice_value 12) (test:case "basic macros" { - ($ void () nil) + (macro void () nil) (test:eq (void) nil) - ($ add_two (a b) (+ a b)) + (macro add_two (a b) (+ a b)) (test:eq (add_two 1 2) 3) (test:eq (add_two nice_value 2) 14) - ($ c (a b) (* a b)) + (macro c (a b) (* a b)) (test:eq (c 4 10) 40) - ($ d (a b) (/ a b)) + (macro d (a b) (/ a b)) (test:eq (d 10 2) 5) - ($ e (+ 1 2 3)) - ($ f (* 2 2 3)) - ($ g (- 1 2 3)) - ($ h (/ 12 2 3)) + (macro e (+ 1 2 3)) + (macro f (* 2 2 3)) + (macro g (- 1 2 3)) + (macro h (/ 12 2 3)) (test:eq e 6) (test:eq f 12) (test:eq g -4) (test:eq h (/ 12 6)) }) (test:case "node manipulation" { - ($ node_tail () (tail (begin 1 2 3))) - ($ length () (len (fun () 5))) - ($ not_empty_node () (empty? (fun () ()))) - ($ empty_node () (empty? ())) - ($ empty_node_bis (empty? ())) + (macro node_tail () (tail (begin 1 2 3))) + (macro length () (len (fun () 5))) + (macro not_empty_node () (empty? (fun () ()))) + (macro empty_node () (empty? ())) + (macro empty_node_bis (empty? ())) (test:eq (length) 3) (test:eq (not_empty_node) false) @@ -72,9 +72,9 @@ (test:expect ($if (@ [true false] -2) true false)) (test:expect ($if 1 true false)) ($if true { - ($ in_if_1 true) - ($ in_if_2 true)}) - ($if true ($ new_value true)) + (macro in_if_1 true) + (macro in_if_2 true)}) + ($if true (macro new_value true)) (test:expect (and in_if_1 in_if_2) "a variable can be defined inside a conditional macro") (test:expect new_value "variable can be defined inside a conditional macro") @@ -82,11 +82,11 @@ ($undef in_if_2) }) { - ($ val (+ 1 2 3)) + (macro val (+ 1 2 3)) (test:eq val 6 "val should be computed to 6") { - ($ val 0) + (macro val 0) (test:eq val 0 "val is shadowed") ($undef val) (test:eq val 6 "shadowed version should be undefined") @@ -95,57 +95,57 @@ (test:eq val 6 "val should still resolve to 6")} (test:case "macro expansion" { - ($ bar (a ...args) (+ a (len args))) + (macro bar (a ...args) (+ a (len args))) (test:eq (bar 1) 1) (test:eq (bar 2 3) 3) (test:eq (bar 4 5 6) 6) (test:eq (bar 7 8 9 10) 10) - ($ egg (...args) (bar ...args)) + (macro egg (...args) (bar ...args)) (test:eq (egg 1) 1) (test:eq (egg 0 1) 1) (test:eq (egg 0 0 0 1) 3) - ($ h (...args) (head args)) + (macro h (...args) (head args)) (test:eq (h) nil) (test:eq (h 1) 1) (test:eq (h 1 2) 1) - ($ g (...args) (tail args)) + (macro g (...args) (tail args)) (test:eq (g) []) (test:eq (g 1) []) (test:eq (g 1 2) [2]) (test:eq (g 1 2 3) [2 3]) - ($ one (...args) (@ args 1)) + (macro one (...args) (@ args 1)) (test:eq (one 1 2) 2) (test:eq (one 1 3 4) 3) (test:eq (one 1 5 6 7 8) 5) - ($ last (...args) (@ args -1)) + (macro last (...args) (@ args -1)) (test:eq (last 1 2) 2) (test:eq (last 1 3 4) 4) (test:eq (last 1 5 6 7 8) 8) }) (test:case "generate valid arkscript code with macros" { - ($ make-func (retval) (fun () retval)) + (macro make-func (retval) (fun () retval)) (let a-func (make-func 1)) (test:eq (type a-func) "Function") (test:eq (a-func) 1) - ($ defun (name args body) (let name (fun args body))) + (macro defun (name args body) (let name (fun args body))) (defun foo (a b) (+ a b)) (test:eq (type foo) "Function") (test:eq (foo 2 3) 5) - ($ get_symbol (bloc) (@ bloc 1)) - ($ define (bloc) (let (get_symbol bloc) (@ bloc 2))) + (macro get_symbol (bloc) (@ bloc 1)) + (macro define (bloc) (let (get_symbol bloc) (@ bloc 2))) (define (let a 12)) (test:eq a 12) }) (test:case "define variable with a macro adding a suffix" { - ($ nice_value 12) - ($ define (prefix suffix value) (let ($symcat prefix suffix) value)) + (macro nice_value 12) + (macro define (prefix suffix value) (let ($symcat prefix suffix) value)) (define a 1 2) (test:eq a1 2) diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_macro.ark b/tests/unittests/resources/ParserSuite/failure/incomplete_macro.ark index d5fa0be0..0e6a330e 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_macro.ark +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_macro.ark @@ -1 +1 @@ -($ (a) a) \ No newline at end of file +(macro (a) a) diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_macro.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_macro.expected index ae42fd78..10a2f897 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_macro.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_macro.expected @@ -1,5 +1,6 @@ In file tests/unittests/resources/ParserSuite/failure/incomplete_macro.ark:1 -At ( @ 1:4 - 1 | ($ (a) a) - | ^ - $ needs a symbol to declare a macro +At ( @ 1:8 + 1 | (macro (a) a) + | ^ + 2 | + Expected a symbol to declare a macro diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.ark b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.ark index b2a8b411..862e0ed4 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.ark +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.ark @@ -1 +1 @@ -($ foo (a \ No newline at end of file +(macro foo (a diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.expected index ac4c3244..7ccc847f 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.expected @@ -1,7 +1,7 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.ark:1 -At EOF @ 1:9 - 1 | ($ foo (a - | │└─ error - | │ - | └─ expression started here +In file tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.ark:2 +At EOF @ 2:0 + 1 | (macro foo (a + | ^ expression started here + 2 | + | ^ Missing ')' in function call to `a' diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.ark b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.ark index 43e48c81..e26ff231 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.ark +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.ark @@ -1 +1 @@ -($ foo (bar ...) (bar)) \ No newline at end of file +(macro foo (bar ...) (bar)) diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.expected index 9a3a0b71..1589702f 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.expected @@ -1,5 +1,6 @@ In file tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.ark:1 -At ) @ 1:16 - 1 | ($ foo (bar ...) (bar)) - | ^ +At ) @ 1:20 + 1 | (macro foo (bar ...) (bar)) + | ^ + 2 | Expected a name for the variadic arguments list diff --git a/tests/unittests/resources/ParserSuite/success/macro.ark b/tests/unittests/resources/ParserSuite/success/macro.ark index 180ab33a..a0641c05 100644 --- a/tests/unittests/resources/ParserSuite/success/macro.ark +++ b/tests/unittests/resources/ParserSuite/success/macro.ark @@ -1,6 +1,6 @@ -($ a 1) -($ b () 2) -($ +(macro a 1) +(macro b () 2) +(macro c # macro name ( # arg list d # macro argument @@ -8,11 +8,11 @@ e ) 3 # body ) -($ f(g)4) -($ h(i j) (let a 1)) +(macro f(g)4) +(macro h(i j) (let a 1)) -($ h (i j) (let a (if i 2 3))) -($ k (l ...m) (print l m)) -($ n ( +(macro h (i j) (let a (if i 2 3))) +(macro k (l ...m) (print l m)) +(macro n ( ...p -) (print p)) \ No newline at end of file +) (print p)) diff --git a/tests/unittests/resources/RosettaSuite/extend_your_language.ark b/tests/unittests/resources/RosettaSuite/extend_your_language.ark index fe781497..5998248d 100644 --- a/tests/unittests/resources/RosettaSuite/extend_your_language.ark +++ b/tests/unittests/resources/RosettaSuite/extend_your_language.ark @@ -1,4 +1,4 @@ -($ if2 (conds bothConditionsAreTrue firstConditionIsTrue secondConditionIsTrue noConditionIsTrue) { +(macro if2 (conds bothConditionsAreTrue firstConditionIsTrue secondConditionIsTrue noConditionIsTrue) { (mut result1 (head conds)) (mut result2 (@ conds 1)) (if (and result1 result2) From 17f527cb819470e2728f86b630be9101f9a7547f Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Wed, 21 May 2025 19:35:41 +0200 Subject: [PATCH 06/22] fix(vm): when using @ on a list of 1 element, we couldn't use -1 as an index to get the last element It would convert -1 to an unsigned value, get 1, and see that 1 is outside our array, instead of checking if the index was negative and then using size + index as the wanted index --- lib/std | 2 +- src/arkreactor/VM/VM.cpp | 16 +++++++------- .../resources/LangSuite/list-tests.ark | 21 ++++++++++++++++++- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/std b/lib/std index c1993572..a794e340 160000 --- a/lib/std +++ b/lib/std @@ -1 +1 @@ -Subproject commit c199357219b94ce172150bd3a1395af246c63299 +Subproject commit a794e34099c4d75c50903d48937ed803ad23b4b5 diff --git a/src/arkreactor/VM/VM.cpp b/src/arkreactor/VM/VM.cpp index 510211bc..d5c58d8e 100644 --- a/src/arkreactor/VM/VM.cpp +++ b/src/arkreactor/VM/VM.cpp @@ -1171,25 +1171,27 @@ namespace Ark types::Contract { { types::Typedef("src", ValueType::String), types::Typedef("idx", ValueType::Number) } } } }, { a, *b }); - long idx = static_cast(b->number()); + const auto num = static_cast(b->number()); if (a.valueType() == ValueType::List) { - if (std::cmp_less(std::abs(idx), a.list().size())) - push(a.list()[static_cast(idx < 0 ? static_cast(a.list().size()) + idx : idx)], context); + const auto index = static_cast(num < 0 ? static_cast(a.list().size()) + num : num); + if (index < a.list().size()) + push(a.list()[index], context); else throwVMError( ErrorKind::Index, - fmt::format("{} out of range {} (length {})", idx, a.toString(*this), a.list().size())); + fmt::format("{} out of range {} (length {})", num, a.toString(*this), a.list().size())); } else if (a.valueType() == ValueType::String) { - if (std::cmp_less(std::abs(idx), a.string().size())) - push(Value(std::string(1, a.string()[static_cast(idx < 0 ? static_cast(a.string().size()) + idx : idx)])), context); + const auto index = static_cast(num < 0 ? static_cast(a.string().size()) + num : num); + if (index < a.string().size()) + push(Value(std::string(1, a.string()[index])), context); else throwVMError( ErrorKind::Index, - fmt::format("{} out of range \"{}\" (length {})", idx, a.string(), a.string().size())); + fmt::format("{} out of range \"{}\" (length {})", num, a.string(), a.string().size())); } else throw types::TypeCheckingError( diff --git a/tests/unittests/resources/LangSuite/list-tests.ark b/tests/unittests/resources/LangSuite/list-tests.ark index 2ca237c8..2a64ea3f 100644 --- a/tests/unittests/resources/LangSuite/list-tests.ark +++ b/tests/unittests/resources/LangSuite/list-tests.ark @@ -75,6 +75,13 @@ (test:eq (list:setAt [0 1 2 3] 3 9) [0 1 2 9]) (test:eq (list:setAt [0 1 2 9] -1 9) [0 1 2 9]) }) + (test:case "get element in list" { + (test:eq 0 (@ [0] -1)) + (test:eq 0 (@ [0] 0)) + (test:eq 5 (@ [0 5 9] 1)) + (test:eq 5 (@ [0 5 9] -2)) + (test:eq 9 (@ [0 5 9] -1)) }) + (test:case "get element in 2D list" { (let nested_list [[0 1 2] [3 4 5] [6 7 8]]) (test:eq 0 (@@ nested_list 0 0)) @@ -82,7 +89,19 @@ (test:eq 1 (@@ nested_list 0 -2)) (test:eq 8 (@@ nested_list -1 -1)) (test:eq 4 (@@ nested_list 1 1)) - (test:eq 4 (@@ nested_list -2 1)) }) + (test:eq 4 (@@ nested_list -2 1)) + + (let nested_list_1 [[0]]) + (test:eq 0 (@@ nested_list_1 0 0)) + (test:eq 0 (@@ nested_list_1 -1 0)) + (test:eq 0 (@@ nested_list_1 0 -1)) + (test:eq 0 (@@ nested_list_1 -1 -1)) + + (let nested_list_2 [[0 5 9]]) + (test:eq 0 (@@ nested_list_2 0 0)) + (test:eq 0 (@@ nested_list_2 -1 0)) + (test:eq 9 (@@ nested_list_2 0 -1)) + (test:eq 9 (@@ nested_list_2 -1 -1)) }) (test:case "in place mutation with @=" { (mut numbers [0 1 2 3 4]) From 3b5d472a8be6f6fc8182cb62ee7711556331e4f3 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Thu, 22 May 2025 17:48:49 +0200 Subject: [PATCH 07/22] feat(benchmarks): enhancing creation of runtime benchmarks while adding two new bench for closures and lists representing trees --- tests/benchmarks/main.cpp | 123 ++++-------------- .../resources/runtime/create_closure.ark | 34 +++++ .../resources/runtime/create_list.ark | 31 +++++ .../runtime/{for.ark => for_sum.ark} | 0 .../{man_or_boy_test.ark => man_or_boy.ark} | 0 5 files changed, 89 insertions(+), 99 deletions(-) create mode 100644 tests/benchmarks/resources/runtime/create_closure.ark create mode 100644 tests/benchmarks/resources/runtime/create_list.ark rename tests/benchmarks/resources/runtime/{for.ark => for_sum.ark} (100%) rename tests/benchmarks/resources/runtime/{man_or_boy_test.ark => man_or_boy.ark} (100%) diff --git a/tests/benchmarks/main.cpp b/tests/benchmarks/main.cpp index 8c825a25..f15035c6 100644 --- a/tests/benchmarks/main.cpp +++ b/tests/benchmarks/main.cpp @@ -8,108 +8,33 @@ #include #include +#define ARK_CREATE_RUNTIME_BENCH(name) \ + void name(benchmark::State& s) \ + { \ + Ark::State state({ std::filesystem::path(ARK_TESTS_ROOT "/lib/") }); \ + state.doFile(get_resource("runtime/" #name ".ark")); \ + for (auto _ : s) \ + { \ + Ark::VM vm(state); \ + benchmark::DoNotOptimize(vm.run()); \ + } \ + } \ + BENCHMARK(name)->Unit(benchmark::kMillisecond) + std::string get_resource(const std::string& path) { return (ARK_TESTS_ROOT "tests/benchmarks/resources/") + path; } -// cppcheck-suppress constParameterCallback -void quicksort(benchmark::State& s) -{ - Ark::State state; - state.doFile(get_resource("runtime/quicksort.ark")); - - for (auto _ : s) - { - Ark::VM vm(state); - benchmark::DoNotOptimize(vm.run()); - } -} -BENCHMARK(quicksort)->Unit(benchmark::kMillisecond); - -// cppcheck-suppress constParameterCallback -void ackermann(benchmark::State& s) -{ - Ark::State state; - state.doFile(get_resource("runtime/ackermann.ark")); - - for (auto _ : s) - { - Ark::VM vm(state); - benchmark::DoNotOptimize(vm.run()); - } -} -BENCHMARK(ackermann)->Unit(benchmark::kMillisecond)->Iterations(50); - -// cppcheck-suppress constParameterCallback -void fibonacci(benchmark::State& s) -{ - Ark::State state; - state.doFile(get_resource("runtime/fibonacci.ark")); - - for (auto _ : s) - { - Ark::VM vm(state); - benchmark::DoNotOptimize(vm.run()); - } -} -BENCHMARK(fibonacci)->Unit(benchmark::kMillisecond)->Iterations(100); - -// cppcheck-suppress constParameterCallback -void man_or_boy(benchmark::State& s) -{ - Ark::State state; - state.doFile(get_resource("runtime/man_or_boy_test.ark")); - - for (auto _ : s) - { - Ark::VM vm(state); - benchmark::DoNotOptimize(vm.run()); - } -} -BENCHMARK(man_or_boy)->Unit(benchmark::kMillisecond); - -// cppcheck-suppress constParameterCallback -void builtins(benchmark::State& s) -{ - Ark::State state; - state.doFile(get_resource("runtime/builtins.ark")); - - for (auto _ : s) - { - Ark::VM vm(state); - benchmark::DoNotOptimize(vm.run()); - } -} -BENCHMARK(builtins)->Unit(benchmark::kMillisecond); - -// cppcheck-suppress constParameterCallback -void binary_trees(benchmark::State& s) -{ - Ark::State state({ std::filesystem::path(ARK_TESTS_ROOT "/lib/") }); - state.doFile(get_resource("runtime/binary_trees.ark")); - - for (auto _ : s) - { - Ark::VM vm(state); - benchmark::DoNotOptimize(vm.run()); - } -} -BENCHMARK(binary_trees)->Unit(benchmark::kMillisecond); - -// cppcheck-suppress constParameterCallback -void for_sum(benchmark::State& s) -{ - Ark::State state; - state.doFile(get_resource("runtime/for.ark")); - - for (auto _ : s) - { - Ark::VM vm(state); - benchmark::DoNotOptimize(vm.run()); - } -} -BENCHMARK(for_sum)->Unit(benchmark::kMillisecond); +ARK_CREATE_RUNTIME_BENCH(quicksort); +ARK_CREATE_RUNTIME_BENCH(ackermann)->Iterations(50); +ARK_CREATE_RUNTIME_BENCH(fibonacci)->Iterations(100); +ARK_CREATE_RUNTIME_BENCH(man_or_boy); +ARK_CREATE_RUNTIME_BENCH(builtins); +ARK_CREATE_RUNTIME_BENCH(binary_trees); +ARK_CREATE_RUNTIME_BENCH(for_sum); +ARK_CREATE_RUNTIME_BENCH(create_closure); +ARK_CREATE_RUNTIME_BENCH(create_list); // -------------------------------------------- // parser benchmarks @@ -124,7 +49,7 @@ std::string readFile(const std::string& filename) constexpr int simple = 0, medium = 1, big = 2; -std::string select_file(long selection) +std::string select_file(const long selection) { switch (selection) { @@ -150,7 +75,7 @@ static void BM_Parse(benchmark::State& state) long linesCount = 0; for (const char c : code) if (c == '\n') - ++linesCount; + ++linesCount; // cppcheck-suppress useStlAlgorithm long long nodes = 0; long long lines = 0; diff --git a/tests/benchmarks/resources/runtime/create_closure.ark b/tests/benchmarks/resources/runtime/create_closure.ark new file mode 100644 index 00000000..21215625 --- /dev/null +++ b/tests/benchmarks/resources/runtime/create_closure.ark @@ -0,0 +1,34 @@ +(let create (fun (lhs rhs) + (fun (&lhs &rhs) ()))) + +(let sum (fun (data) + (+ + (if (= "Closure" (type data.lhs)) (sum data.lhs) data.lhs) + (if (= "Closure" (type data.rhs)) (sum data.rhs) data.rhs)))) + +(mut i 0) +(while (< i 100) { + (let tree + (create + (create + (create 1 2) + (create + 3 + (create + 4 + (create 5 6)))) + (create + (create + (create + (create 7 8) + 9) + (create 10 11)) + (create + (create + 12 + (create + 13 + (create 14 15))) + (create 16 17))))) + (sum tree) + (set i (+ 1 i) )}) diff --git a/tests/benchmarks/resources/runtime/create_list.ark b/tests/benchmarks/resources/runtime/create_list.ark new file mode 100644 index 00000000..08b72ac1 --- /dev/null +++ b/tests/benchmarks/resources/runtime/create_list.ark @@ -0,0 +1,31 @@ +(let sum (fun (data) + (+ + (if (= "List" (type (@ data 0))) (sum (@ data 0)) (@ data 0)) + (if (= "List" (type (@ data 1))) (sum (@ data 1)) (@ data 1))))) + +(mut i 0) +(while (< i 100) { + (let tree + [ + [ + [1 2] + [ + 3 + [ + 4 + [5 6]]]] + [ + [ + [ + [7 8] + 9] + [10 11]] + [ + [ + 12 + [ + 13 + [14 15]]] + [16 17]]]]) + (sum tree) + (set i (+ 1 i) )}) diff --git a/tests/benchmarks/resources/runtime/for.ark b/tests/benchmarks/resources/runtime/for_sum.ark similarity index 100% rename from tests/benchmarks/resources/runtime/for.ark rename to tests/benchmarks/resources/runtime/for_sum.ark diff --git a/tests/benchmarks/resources/runtime/man_or_boy_test.ark b/tests/benchmarks/resources/runtime/man_or_boy.ark similarity index 100% rename from tests/benchmarks/resources/runtime/man_or_boy_test.ark rename to tests/benchmarks/resources/runtime/man_or_boy.ark From 78804b34251044d5624c36ffaa0fc5a5b8d22db7 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Thu, 22 May 2025 18:16:05 +0200 Subject: [PATCH 08/22] feat(instructions): RESET_SCOPE now handles the JUMP of the while loop as well, compacting two instructions in one --- CHANGELOG.md | 2 +- include/Ark/Compiler/Instructions.hpp | 6 +++--- .../IntermediateRepresentation/Entity.hpp | 4 +--- .../IntermediateRepresentation/Entity.cpp | 8 +++----- .../IntermediateRepresentation/IRCompiler.cpp | 20 ++----------------- .../Compiler/Lowerer/ASTLowerer.cpp | 3 +-- src/arkreactor/VM/VM.cpp | 5 +++-- .../CompilerSuite/ir/99bottles.expected | 13 ++++++------ .../CompilerSuite/ir/ackermann.expected | 8 ++++---- .../CompilerSuite/ir/factorial.expected | 5 ++--- .../optimized_ir/99bottles.expected | 13 ++++++------ .../optimized_ir/ackermann.expected | 8 ++++---- .../optimized_ir/factorial.expected | 5 ++--- 13 files changed, 38 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cf22a25..bf92da4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,7 @@ - `STORE_FROM_INDEX` and `SET_VAL_FROM_INDEX` instructions for parity with the super instructions not using load by index - `INCREMENT_BY_INDEX` and `DECREMENT_BY_INDEX` instructions for parity with the super instructions not using load by index - `STORE_TAIL_BY_INDEX`, `STORE_HEAD_BY_INDEX`, `SET_VAL_TAIL_BY_INDEX`, `SET_VAL_HEAD_BY_INDEX` super instructions added for parity with the super instructions not using load by index -- `RESET_SCOPE` instruction emitted at the end of a while loop to reset a scope so that we can create multiple variables and use `LOAD_SYMBOL_BY_INDEX` +- `RESET_SCOPE_JUMP` instruction emitted at the end of a while loop to reset a scope so that we can create multiple variables and use `LOAD_SYMBOL_BY_INDEX` - instruction source location ; two new bytecode tables were added: one for filenames, another for (page pointer, instruction pointer, file id, line), allowing the VM to display better error messages when the source is available - show source location when a runtime error is thrown in the VM diff --git a/include/Ark/Compiler/Instructions.hpp b/include/Ark/Compiler/Instructions.hpp index c381a1cd..09478c51 100644 --- a/include/Ark/Compiler/Instructions.hpp +++ b/include/Ark/Compiler/Instructions.hpp @@ -143,8 +143,8 @@ namespace Ark::internal // @role Create a new local scope CREATE_SCOPE = 0x1d, - // @role Reset the current scope so that it is empty - RESET_SCOPE = 0x1e, + // @role Reset the current scope so that it is empty, and jump to a given location + RESET_SCOPE_JUMP = 0x1e, // @role Destroy the last local scope POP_SCOPE = 0x1f, @@ -337,7 +337,7 @@ namespace Ark::internal "POP", "DUP", "CREATE_SCOPE", - "RESET_SCOPE", + "RESET_SCOPE_JUMP", "POP_SCOPE", // operators "ADD", diff --git a/include/Ark/Compiler/IntermediateRepresentation/Entity.hpp b/include/Ark/Compiler/IntermediateRepresentation/Entity.hpp index fd9e238e..afbd91b3 100644 --- a/include/Ark/Compiler/IntermediateRepresentation/Entity.hpp +++ b/include/Ark/Compiler/IntermediateRepresentation/Entity.hpp @@ -24,8 +24,6 @@ namespace Ark::internal::IR { Label, Goto, - GotoIfTrue, - GotoIfFalse, Opcode, Opcode2Args }; @@ -46,7 +44,7 @@ namespace Ark::internal::IR static Entity Label(label_t value); - static Entity Goto(const Entity& label); + static Entity Goto(const Entity& label, Instruction inst = Instruction::JUMP); static Entity GotoIf(const Entity& label, bool cond); diff --git a/src/arkreactor/Compiler/IntermediateRepresentation/Entity.cpp b/src/arkreactor/Compiler/IntermediateRepresentation/Entity.cpp index fe33d62f..cc80ee43 100644 --- a/src/arkreactor/Compiler/IntermediateRepresentation/Entity.cpp +++ b/src/arkreactor/Compiler/IntermediateRepresentation/Entity.cpp @@ -25,20 +25,18 @@ namespace Ark::internal::IR return entity; } - Entity Entity::Goto(const Entity& label) + Entity Entity::Goto(const Entity& label, const Instruction inst) { auto jump = Entity(Kind::Goto); jump.m_label = label.m_label; + jump.m_inst = inst; return jump; } Entity Entity::GotoIf(const Entity& label, const bool cond) { - auto jump = Entity(cond ? Kind::GotoIfTrue : Kind::GotoIfFalse); - jump.m_label = label.m_label; - - return jump; + return Goto(label, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE); } Word Entity::bytecode() const diff --git a/src/arkreactor/Compiler/IntermediateRepresentation/IRCompiler.cpp b/src/arkreactor/Compiler/IntermediateRepresentation/IRCompiler.cpp index 0140392b..a216c781 100644 --- a/src/arkreactor/Compiler/IntermediateRepresentation/IRCompiler.cpp +++ b/src/arkreactor/Compiler/IntermediateRepresentation/IRCompiler.cpp @@ -80,15 +80,7 @@ namespace Ark::internal break; case IR::Kind::Goto: - fmt::println(stream, "\tGOTO L{}", entity.label()); - break; - - case IR::Kind::GotoIfTrue: - fmt::println(stream, "\tGOTO_IF_TRUE L{}", entity.label()); - break; - - case IR::Kind::GotoIfFalse: - fmt::println(stream, "\tGOTO_IF_FALSE L{}", entity.label()); + fmt::println(stream, "\t{} L{}", InstructionNames[entity.inst()], entity.label()); break; case IR::Kind::Opcode: @@ -152,15 +144,7 @@ namespace Ark::internal switch (inst.kind()) { case IR::Kind::Goto: - pushWord(Word(JUMP, label_to_position[inst.label()])); - break; - - case IR::Kind::GotoIfTrue: - pushWord(Word(POP_JUMP_IF_TRUE, label_to_position[inst.label()])); - break; - - case IR::Kind::GotoIfFalse: - pushWord(Word(POP_JUMP_IF_FALSE, label_to_position[inst.label()])); + pushWord(Word(inst.inst(), label_to_position[inst.label()])); break; case IR::Kind::Opcode: diff --git a/src/arkreactor/Compiler/Lowerer/ASTLowerer.cpp b/src/arkreactor/Compiler/Lowerer/ASTLowerer.cpp index 26540c0b..eeaadb39 100644 --- a/src/arkreactor/Compiler/Lowerer/ASTLowerer.cpp +++ b/src/arkreactor/Compiler/Lowerer/ASTLowerer.cpp @@ -452,9 +452,8 @@ namespace Ark::internal // reset the scope at the end of the loop so that indices are still valid // otherwise, (while true { (let a 5) (print a) (let b 6) (print b) }) // would print 5, 6, then only 6 as we emit LOAD_SYMBOL_FROM_INDEX 0 and b is the last in the scope - page(p).emplace_back(RESET_SCOPE); // loop, jump to the condition - page(p).emplace_back(IR::Entity::Goto(label_loop)); + page(p).emplace_back(IR::Entity::Goto(label_loop, RESET_SCOPE_JUMP)); // absolute address to jump to if condition is false page(p).emplace_back(label_end); diff --git a/src/arkreactor/VM/VM.cpp b/src/arkreactor/VM/VM.cpp index d5c58d8e..f80b3526 100644 --- a/src/arkreactor/VM/VM.cpp +++ b/src/arkreactor/VM/VM.cpp @@ -396,7 +396,7 @@ namespace Ark &&TARGET_POP, &&TARGET_DUP, &&TARGET_CREATE_SCOPE, - &&TARGET_RESET_SCOPE, + &&TARGET_RESET_SCOPE_JUMP, &&TARGET_POP_SCOPE, &&TARGET_ADD, &&TARGET_SUB, @@ -944,9 +944,10 @@ namespace Ark DISPATCH(); } - TARGET(RESET_SCOPE) + TARGET(RESET_SCOPE_JUMP) { context.locals.back().reset(); + context.ip = arg * 4; // instructions are 4 bytes DISPATCH(); } diff --git a/tests/unittests/resources/CompilerSuite/ir/99bottles.expected b/tests/unittests/resources/CompilerSuite/ir/99bottles.expected index fa715426..0eee12a9 100644 --- a/tests/unittests/resources/CompilerSuite/ir/99bottles.expected +++ b/tests/unittests/resources/CompilerSuite/ir/99bottles.expected @@ -3,9 +3,9 @@ page_0 LEN 0 LOAD_CONST 0 GE 0 - GOTO_IF_TRUE L0 + POP_JUMP_IF_TRUE L0 BUILTIN 2 - GOTO L1 + JUMP L1 .L0: LOAD_SYMBOL 1 LOAD_CONST 1 @@ -15,9 +15,9 @@ page_0 STORE 0 LOAD_SYMBOL_BY_INDEX 0 ISNIL 0 - GOTO_IF_TRUE L2 + POP_JUMP_IF_TRUE L2 LOAD_SYMBOL_BY_INDEX 0 - GOTO L3 + JUMP L3 .L2: LOAD_CONST 2 .L3: @@ -29,7 +29,7 @@ page_0 LOAD_SYMBOL 3 LOAD_CONST 0 GT 0 - GOTO_IF_FALSE L5 + POP_JUMP_IF_FALSE L5 LOAD_CONST 3 LOAD_SYMBOL 3 LOAD_SYMBOL 3 @@ -49,8 +49,7 @@ page_0 BUILTIN 9 CALL 1 POP 0 - RESET_SCOPE 0 - GOTO L4 + RESET_SCOPE_JUMP L4 .L5: POP_SCOPE 0 HALT 0 diff --git a/tests/unittests/resources/CompilerSuite/ir/ackermann.expected b/tests/unittests/resources/CompilerSuite/ir/ackermann.expected index f22f1b29..df8534e9 100644 --- a/tests/unittests/resources/CompilerSuite/ir/ackermann.expected +++ b/tests/unittests/resources/CompilerSuite/ir/ackermann.expected @@ -16,16 +16,16 @@ page_1 LOAD_SYMBOL_BY_INDEX 1 LOAD_CONST 1 GT 0 - GOTO_IF_TRUE L0 + POP_JUMP_IF_TRUE L0 LOAD_CONST 2 LOAD_SYMBOL_BY_INDEX 0 ADD 0 - GOTO L1 + JUMP L1 .L0: LOAD_CONST 1 LOAD_SYMBOL_BY_INDEX 0 EQ 0 - GOTO_IF_TRUE L2 + POP_JUMP_IF_TRUE L2 LOAD_SYMBOL_BY_INDEX 1 LOAD_SYMBOL_BY_INDEX 0 LOAD_CONST 2 @@ -36,7 +36,7 @@ page_1 LOAD_CONST 2 SUB 0 JUMP 0 - GOTO L3 + JUMP L3 .L2: LOAD_CONST 2 LOAD_SYMBOL_BY_INDEX 1 diff --git a/tests/unittests/resources/CompilerSuite/ir/factorial.expected b/tests/unittests/resources/CompilerSuite/ir/factorial.expected index 03a0d795..8427da39 100644 --- a/tests/unittests/resources/CompilerSuite/ir/factorial.expected +++ b/tests/unittests/resources/CompilerSuite/ir/factorial.expected @@ -20,7 +20,7 @@ page_1 LOAD_SYMBOL 3 LOAD_SYMBOL 1 LE 0 - GOTO_IF_FALSE L1 + POP_JUMP_IF_FALSE L1 LOAD_SYMBOL 2 LOAD_SYMBOL 3 MUL 0 @@ -29,8 +29,7 @@ page_1 LOAD_SYMBOL 3 ADD 0 SET_VAL 3 - RESET_SCOPE 0 - GOTO L0 + RESET_SCOPE_JUMP L0 .L1: POP_SCOPE 0 LOAD_SYMBOL_BY_INDEX 1 diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/99bottles.expected b/tests/unittests/resources/CompilerSuite/optimized_ir/99bottles.expected index 3101589d..a53e61cb 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/99bottles.expected +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/99bottles.expected @@ -3,9 +3,9 @@ page_0 LEN 0 LOAD_CONST 0 GE 0 - GOTO_IF_TRUE L0 + POP_JUMP_IF_TRUE L0 BUILTIN 2 - GOTO L1 + JUMP L1 .L0: LOAD_SYMBOL 1 LOAD_CONST 1 @@ -15,9 +15,9 @@ page_0 STORE 0 LOAD_SYMBOL_BY_INDEX 0 ISNIL 0 - GOTO_IF_TRUE L2 + POP_JUMP_IF_TRUE L2 LOAD_SYMBOL_BY_INDEX 0 - GOTO L3 + JUMP L3 .L2: LOAD_CONST 2 .L3: @@ -28,7 +28,7 @@ page_0 LOAD_SYMBOL 3 LOAD_CONST 0 GT 0 - GOTO_IF_FALSE L5 + POP_JUMP_IF_FALSE L5 LOAD_CONST 3 LOAD_SYMBOL 3 LOAD_SYMBOL 3 @@ -42,8 +42,7 @@ page_0 CALL_BUILTIN 24, 2 CALL_BUILTIN 9, 1 POP 0 - RESET_SCOPE 0 - GOTO L4 + RESET_SCOPE_JUMP L4 .L5: POP_SCOPE 0 HALT 0 diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/ackermann.expected b/tests/unittests/resources/CompilerSuite/optimized_ir/ackermann.expected index 15703fad..e1f17261 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/ackermann.expected +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/ackermann.expected @@ -13,21 +13,21 @@ page_1 LOAD_SYMBOL_BY_INDEX 1 LOAD_CONST 1 GT 0 - GOTO_IF_TRUE L0 + POP_JUMP_IF_TRUE L0 INCREMENT_BY_INDEX 0, 1 - GOTO L1 + JUMP L1 .L0: LOAD_CONST 1 LOAD_SYMBOL_BY_INDEX 0 EQ 0 - GOTO_IF_TRUE L2 + POP_JUMP_IF_TRUE L2 LOAD_SYMBOL_BY_INDEX 1 DECREMENT_BY_INDEX 0, 1 LOAD_SYMBOL 0 CALL 2 DECREMENT_BY_INDEX 1, 1 JUMP 0 - GOTO L3 + JUMP L3 .L2: LOAD_CONST 2 DECREMENT_BY_INDEX 1, 1 diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/factorial.expected b/tests/unittests/resources/CompilerSuite/optimized_ir/factorial.expected index 757b4947..d1c5771e 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/factorial.expected +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/factorial.expected @@ -15,15 +15,14 @@ page_1 LOAD_SYMBOL 3 LOAD_SYMBOL 1 LE 0 - GOTO_IF_FALSE L1 + POP_JUMP_IF_FALSE L1 LOAD_SYMBOL 2 LOAD_SYMBOL 3 MUL 0 SET_VAL 2 INCREMENT 3, 1 SET_VAL 3 - RESET_SCOPE 0 - GOTO L0 + RESET_SCOPE_JUMP L0 .L1: POP_SCOPE 0 LOAD_SYMBOL_BY_INDEX 1 From 93b6ee3e9c18fb497191a9536992622ca4133ba7 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Thu, 22 May 2025 19:01:30 +0200 Subject: [PATCH 09/22] refactor(vm): cleaning up implementation of push in the vm --- include/Ark/VM/VM.inl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/Ark/VM/VM.inl b/include/Ark/VM/VM.inl index fde8b7f6..d8371f05 100644 --- a/include/Ark/VM/VM.inl +++ b/include/Ark/VM/VM.inl @@ -158,15 +158,13 @@ inline Value* VM::pop(internal::ExecutionContext& context) inline void VM::push(const Value& value, internal::ExecutionContext& context) { - context.stack[context.sp].m_type = value.m_type; - context.stack[context.sp].m_value = value.m_value; + context.stack[context.sp] = value; ++context.sp; } inline void VM::push(Value&& value, internal::ExecutionContext& context) { - context.stack[context.sp].m_type = std::move(value.m_type); - context.stack[context.sp].m_value = std::move(value.m_value); + context.stack[context.sp] = std::move(value); ++context.sp; } From 4f0950fa3861fac0f47a992d400fbd5a173b8c64 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Thu, 22 May 2025 20:18:18 +0200 Subject: [PATCH 10/22] refactor(ir optimizer): better rule declaration --- .../IROptimizer.hpp | 40 +++++++++--- .../IROptimizer.cpp | 61 +++++++++---------- 2 files changed, 61 insertions(+), 40 deletions(-) diff --git a/include/Ark/Compiler/IntermediateRepresentation/IROptimizer.hpp b/include/Ark/Compiler/IntermediateRepresentation/IROptimizer.hpp index 3117618b..3439a7d3 100644 --- a/include/Ark/Compiler/IntermediateRepresentation/IROptimizer.hpp +++ b/include/Ark/Compiler/IntermediateRepresentation/IROptimizer.hpp @@ -48,19 +48,41 @@ namespace Ark::internal private: using Entities = std::vector; - using DualArgs = std::pair; + using Condition_t = std::function; + using Replacement_t = std::function; struct Rule { std::vector expected; - Instruction replacement; - std::function condition = [](const Entities&) { - return true; - }; ///< Additional condition to match - std::function createReplacement = - [](const Entities& entities) { - return std::make_pair(entities[0].primaryArg(), entities[1].primaryArg()); - }; ///< Create the replacement instructions from given context + Condition_t condition; ///< Additional condition to match + Replacement_t createReplacement; ///< Create the replacement instructions from given context + + Rule( + std::vector&& input, + Instruction replacement, + Condition_t&& cond = [](const Entities&) { + return true; + }) : + expected(std::move(input)), condition(std::move(cond)), createReplacement([replacement](const Entities& e) { + return IR::Entity(replacement, e[0].primaryArg(), e[1].primaryArg()); + }) + {} + + Rule( + std::vector&& input, + Condition_t&& cond, + Replacement_t&& repl) : + expected(std::move(input)), condition(std::move(cond)), createReplacement(std::move(repl)) + {} + + Rule( + std::vector&& input, + Replacement_t&& repl) : + expected(std::move(input)), condition([](const Entities&) { + return true; + }), + createReplacement(std::move(repl)) + {} }; std::vector m_ruleset_two; diff --git a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp index 9b20b053..0765a31f 100644 --- a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp +++ b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp @@ -42,69 +42,69 @@ namespace Ark::internal // ADD / SUB // ---> INCREMENT / DECREMENT a value Rule { - { LOAD_CONST, LOAD_SYMBOL, ADD }, INCREMENT, [this](const Entities& e) { + { LOAD_CONST, LOAD_SYMBOL, ADD }, [this](const Entities& e) { return isPositiveNumberInlinable(e[0].primaryArg()); }, [this](const Entities& e) { - return std::make_pair(e[1].primaryArg(), numberAsArg(e[0].primaryArg())); + return IR::Entity(INCREMENT, e[1].primaryArg(), numberAsArg(e[0].primaryArg())); } }, - Rule { { LOAD_SYMBOL, LOAD_CONST, ADD }, INCREMENT, [this](const Entities& e) { + Rule { { LOAD_SYMBOL, LOAD_CONST, ADD }, [this](const Entities& e) { return isPositiveNumberInlinable(e[1].primaryArg()); }, [this](const Entities& e) { - return std::make_pair(e[0].primaryArg(), numberAsArg(e[1].primaryArg())); + return IR::Entity(INCREMENT, e[0].primaryArg(), numberAsArg(e[1].primaryArg())); } }, - Rule { { LOAD_SYMBOL, LOAD_CONST, SUB }, DECREMENT, [this](const Entities& e) { + Rule { { LOAD_SYMBOL, LOAD_CONST, SUB }, [this](const Entities& e) { return isPositiveNumberInlinable(e[1].primaryArg()); }, [this](const Entities& e) { - return std::make_pair(e[0].primaryArg(), numberAsArg(e[1].primaryArg())); + return IR::Entity(DECREMENT, e[0].primaryArg(), numberAsArg(e[1].primaryArg())); } }, - Rule { { LOAD_CONST, LOAD_SYMBOL_BY_INDEX, ADD }, INCREMENT_BY_INDEX, [this](const Entities& e) { + Rule { { LOAD_CONST, LOAD_SYMBOL_BY_INDEX, ADD }, [this](const Entities& e) { return isPositiveNumberInlinable(e[0].primaryArg()); }, [this](const Entities& e) { - return std::make_pair(e[1].primaryArg(), numberAsArg(e[0].primaryArg())); + return IR::Entity(INCREMENT_BY_INDEX, e[1].primaryArg(), numberAsArg(e[0].primaryArg())); } }, - Rule { { LOAD_SYMBOL_BY_INDEX, LOAD_CONST, ADD }, INCREMENT_BY_INDEX, [this](const Entities& e) { + Rule { { LOAD_SYMBOL_BY_INDEX, LOAD_CONST, ADD }, [this](const Entities& e) { return isPositiveNumberInlinable(e[1].primaryArg()); }, [this](const Entities& e) { - return std::make_pair(e[0].primaryArg(), numberAsArg(e[1].primaryArg())); + return IR::Entity(INCREMENT_BY_INDEX, e[0].primaryArg(), numberAsArg(e[1].primaryArg())); } }, - Rule { { LOAD_SYMBOL_BY_INDEX, LOAD_CONST, SUB }, DECREMENT_BY_INDEX, [this](const Entities& e) { + Rule { { LOAD_SYMBOL_BY_INDEX, LOAD_CONST, SUB }, [this](const Entities& e) { return isPositiveNumberInlinable(e[1].primaryArg()); }, [this](const Entities& e) { - return std::make_pair(e[0].primaryArg(), numberAsArg(e[1].primaryArg())); + return IR::Entity(DECREMENT_BY_INDEX, e[0].primaryArg(), numberAsArg(e[1].primaryArg())); } }, // LOAD_SYMBOL list // TAIL / HEAD // STORE / SET_VAL a // ---> STORE_TAIL list a ; STORE_HEAD ; SET_VAL_TAIL ; SET_VAL_HEAD - Rule { .expected = { LOAD_SYMBOL, TAIL, STORE }, .replacement = STORE_TAIL, .createReplacement = [](const Entities& e) { - return std::make_pair(e[0].primaryArg(), e[2].primaryArg()); + Rule { { LOAD_SYMBOL, TAIL, STORE }, [](const Entities& e) { + return IR::Entity(STORE_TAIL, e[0].primaryArg(), e[2].primaryArg()); } }, - Rule { .expected = { LOAD_SYMBOL, TAIL, SET_VAL }, .replacement = SET_VAL_TAIL, .createReplacement = [](const Entities& e) { - return std::make_pair(e[0].primaryArg(), e[2].primaryArg()); + Rule { { LOAD_SYMBOL, TAIL, SET_VAL }, [](const Entities& e) { + return IR::Entity(SET_VAL_TAIL, e[0].primaryArg(), e[2].primaryArg()); } }, - Rule { .expected = { LOAD_SYMBOL, HEAD, STORE }, .replacement = STORE_HEAD, .createReplacement = [](const Entities& e) { - return std::make_pair(e[0].primaryArg(), e[2].primaryArg()); + Rule { { LOAD_SYMBOL, HEAD, STORE }, [](const Entities& e) { + return IR::Entity(STORE_HEAD, e[0].primaryArg(), e[2].primaryArg()); } }, - Rule { .expected = { LOAD_SYMBOL, HEAD, SET_VAL }, .replacement = SET_VAL_HEAD, .createReplacement = [](const Entities& e) { - return std::make_pair(e[0].primaryArg(), e[2].primaryArg()); + Rule { { LOAD_SYMBOL, HEAD, SET_VAL }, [](const Entities& e) { + return IR::Entity(SET_VAL_HEAD, e[0].primaryArg(), e[2].primaryArg()); } }, - Rule { .expected = { LOAD_SYMBOL_BY_INDEX, TAIL, STORE }, .replacement = STORE_TAIL_BY_INDEX, .createReplacement = [](const Entities& e) { - return std::make_pair(e[0].primaryArg(), e[2].primaryArg()); + Rule { { LOAD_SYMBOL_BY_INDEX, TAIL, STORE }, [](const Entities& e) { + return IR::Entity(STORE_TAIL_BY_INDEX, e[0].primaryArg(), e[2].primaryArg()); } }, - Rule { .expected = { LOAD_SYMBOL_BY_INDEX, TAIL, SET_VAL }, .replacement = SET_VAL_TAIL_BY_INDEX, .createReplacement = [](const Entities& e) { - return std::make_pair(e[0].primaryArg(), e[2].primaryArg()); + Rule { { LOAD_SYMBOL_BY_INDEX, TAIL, SET_VAL }, [](const Entities& e) { + return IR::Entity(SET_VAL_TAIL_BY_INDEX, e[0].primaryArg(), e[2].primaryArg()); } }, - Rule { .expected = { LOAD_SYMBOL_BY_INDEX, HEAD, STORE }, .replacement = STORE_HEAD_BY_INDEX, .createReplacement = [](const Entities& e) { - return std::make_pair(e[0].primaryArg(), e[2].primaryArg()); + Rule { { LOAD_SYMBOL_BY_INDEX, HEAD, STORE }, [](const Entities& e) { + return IR::Entity(STORE_HEAD_BY_INDEX, e[0].primaryArg(), e[2].primaryArg()); } }, - Rule { .expected = { LOAD_SYMBOL_BY_INDEX, HEAD, SET_VAL }, .replacement = SET_VAL_HEAD_BY_INDEX, .createReplacement = [](const Entities& e) { - return std::make_pair(e[0].primaryArg(), e[2].primaryArg()); + Rule { { LOAD_SYMBOL_BY_INDEX, HEAD, SET_VAL }, [](const Entities& e) { + return IR::Entity(SET_VAL_HEAD_BY_INDEX, e[0].primaryArg(), e[2].primaryArg()); } } }; } @@ -199,12 +199,11 @@ namespace Ark::internal return std::nullopt; } - for (const auto& [expected, replacement, condition, createReplacement] : rules) + for (const auto& [expected, condition, createReplacement] : rules) { if (match(expected, entities) && condition(entities)) { - auto [first, second] = createReplacement(entities); - auto output = IR::Entity(replacement, first, second); + auto output = createReplacement(entities); if (auto it = std::ranges::find_if(entities, [](const auto& entity) { return entity.hasValidSourceLocation(); From 5fa2e20939cafa94f542ccd9a80d7e8c5ce44a28 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Thu, 22 May 2025 21:05:31 +0200 Subject: [PATCH 11/22] feat(ir): adding IR::GotoWithArg to be able to generate gotos from the IROptmizer --- .../Ark/Compiler/IntermediateRepresentation/Entity.hpp | 3 +++ .../Compiler/IntermediateRepresentation/Entity.cpp | 10 ++++++++++ .../Compiler/IntermediateRepresentation/IRCompiler.cpp | 8 ++++++++ 3 files changed, 21 insertions(+) diff --git a/include/Ark/Compiler/IntermediateRepresentation/Entity.hpp b/include/Ark/Compiler/IntermediateRepresentation/Entity.hpp index afbd91b3..d6db7545 100644 --- a/include/Ark/Compiler/IntermediateRepresentation/Entity.hpp +++ b/include/Ark/Compiler/IntermediateRepresentation/Entity.hpp @@ -24,6 +24,7 @@ namespace Ark::internal::IR { Label, Goto, + GotoWithArg, Opcode, Opcode2Args }; @@ -46,6 +47,8 @@ namespace Ark::internal::IR static Entity Goto(const Entity& label, Instruction inst = Instruction::JUMP); + static Entity GotoWithArg(const Entity& label, Instruction inst, uint16_t primary_arg); + static Entity GotoIf(const Entity& label, bool cond); [[nodiscard]] Word bytecode() const; diff --git a/src/arkreactor/Compiler/IntermediateRepresentation/Entity.cpp b/src/arkreactor/Compiler/IntermediateRepresentation/Entity.cpp index cc80ee43..f7ab8fbb 100644 --- a/src/arkreactor/Compiler/IntermediateRepresentation/Entity.cpp +++ b/src/arkreactor/Compiler/IntermediateRepresentation/Entity.cpp @@ -34,6 +34,16 @@ namespace Ark::internal::IR return jump; } + Entity Entity::GotoWithArg(const Entity& label, const Instruction inst, const uint16_t primary_arg) + { + auto jump = Entity(Kind::GotoWithArg); + jump.m_label = label.m_label; + jump.m_inst = inst; + jump.m_primary_arg = primary_arg; + + return jump; + } + Entity Entity::GotoIf(const Entity& label, const bool cond) { return Goto(label, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE); diff --git a/src/arkreactor/Compiler/IntermediateRepresentation/IRCompiler.cpp b/src/arkreactor/Compiler/IntermediateRepresentation/IRCompiler.cpp index a216c781..7c832103 100644 --- a/src/arkreactor/Compiler/IntermediateRepresentation/IRCompiler.cpp +++ b/src/arkreactor/Compiler/IntermediateRepresentation/IRCompiler.cpp @@ -83,6 +83,10 @@ namespace Ark::internal fmt::println(stream, "\t{} L{}", InstructionNames[entity.inst()], entity.label()); break; + case IR::Kind::GotoWithArg: + fmt::println(stream, "\t{} L{}, {}", InstructionNames[entity.inst()], entity.label(), entity.primaryArg()); + break; + case IR::Kind::Opcode: fmt::println(stream, "\t{} {}", InstructionNames[entity.inst()], entity.primaryArg()); break; @@ -147,6 +151,10 @@ namespace Ark::internal pushWord(Word(inst.inst(), label_to_position[inst.label()])); break; + case IR::Kind::GotoWithArg: + pushWord(Word(inst.inst(), inst.primaryArg(), label_to_position[inst.label()])); + break; + case IR::Kind::Opcode: [[fallthrough]]; case IR::Kind::Opcode2Args: From d1c0eb7fbf597e40cb071dd852b41c0c58c0f09d Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Fri, 23 May 2025 10:44:13 +0200 Subject: [PATCH 12/22] feat(compiler, vm): adding new LT_CONST_JUMP_IF_FALSE instruction to merge LOAD_CONST;LT;POP_JUMP_IF_FALSE into one better instruction --- include/Ark/Compiler/Instructions.hpp | 9 ++++++-- .../IROptimizer.cpp | 7 ++++++ src/arkreactor/VM/VM.cpp | 12 +++++++++- .../CompilerSuite/optimized_ir/jumps.ark | 6 +++++ .../CompilerSuite/optimized_ir/jumps.expected | 23 +++++++++++++++++++ 5 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark create mode 100644 tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected diff --git a/include/Ark/Compiler/Instructions.hpp b/include/Ark/Compiler/Instructions.hpp index 09478c51..d6386c9e 100644 --- a/include/Ark/Compiler/Instructions.hpp +++ b/include/Ark/Compiler/Instructions.hpp @@ -44,7 +44,7 @@ namespace Ark::internal // @role Load a symbol from the locals stack by its index (starting from the end of the current scope) LOAD_SYMBOL_BY_INDEX = 0x02, - // @args symbol id + // @args constant id // @role Load a constant from its ID onto the stack LOAD_CONST = 0x03, @@ -303,6 +303,10 @@ namespace Ark::internal // @role Call a builtin by its id in #[code primary], with #[code secondary] arguments. Bypass the stack size check because we do not push IP/PP since builtins calls do not alter the stack CALL_BUILTIN = 0x4b, + // @args constant id, absolute address to jump to + // @role Compare #[code TS < constant], if the comparison fails, jump to the given address. Otherwise, does nothing + LT_CONST_JUMP_IF_FALSE = 0x4c, + InstructionsCount }; @@ -384,7 +388,8 @@ namespace Ark::internal "SET_VAL_TAIL_BY_INDEX", "SET_VAL_HEAD", "SET_VAL_HEAD_BY_INDEX", - "CALL_BUILTIN" + "CALL_BUILTIN", + "LT_CONST_JUMP_IF_FALSE" }; static_assert(InstructionNames.size() == static_cast(Instruction::InstructionsCount) && "Some instruction names appear to be missing"); diff --git a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp index 0765a31f..ec752a15 100644 --- a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp +++ b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp @@ -105,6 +105,13 @@ namespace Ark::internal } }, Rule { { LOAD_SYMBOL_BY_INDEX, HEAD, SET_VAL }, [](const Entities& e) { return IR::Entity(SET_VAL_HEAD_BY_INDEX, e[0].primaryArg(), e[2].primaryArg()); + } }, + // LOAD_CONST id + // + // POP_JUMP_IF_FALSE + // ---> _CONST_JUMP_IF_FALSE + Rule { { LOAD_CONST, LT, POP_JUMP_IF_FALSE }, [](const Entities& e) { + return IR::Entity::GotoWithArg(e[2], LT_CONST_JUMP_IF_FALSE, e[0].primaryArg()); } } }; } diff --git a/src/arkreactor/VM/VM.cpp b/src/arkreactor/VM/VM.cpp index f80b3526..c2fcc16a 100644 --- a/src/arkreactor/VM/VM.cpp +++ b/src/arkreactor/VM/VM.cpp @@ -441,7 +441,8 @@ namespace Ark &&TARGET_SET_VAL_TAIL_BY_INDEX, &&TARGET_SET_VAL_HEAD, &&TARGET_SET_VAL_HEAD_BY_INDEX, - &&TARGET_CALL_BUILTIN + &&TARGET_CALL_BUILTIN, + &&TARGET_LT_CONST_JUMP_IF_FALSE }; static_assert(opcode_targets.size() == static_cast(Instruction::InstructionsCount) && "Some instructions are not implemented in the VM"); @@ -1539,6 +1540,15 @@ namespace Ark GOTO_HALT(); DISPATCH(); } + + TARGET(LT_CONST_JUMP_IF_FALSE) + { + UNPACK_ARGS(); + const Value* sym = popAndResolveAsPtr(context); + if (!(*sym < *loadConstAsPtr(primary_arg))) + context.ip = secondary_arg * 4; + DISPATCH(); + } #pragma endregion } #if ARK_USE_COMPUTED_GOTOS diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark new file mode 100644 index 00000000..e8fe9c27 --- /dev/null +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark @@ -0,0 +1,6 @@ +(let foo (fun (e) e)) + +(mut i 0) +(while (< i 100) { + (e i) + (set i (+ 1 i)) }) diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected new file mode 100644 index 00000000..fc71bdce --- /dev/null +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected @@ -0,0 +1,23 @@ +page_0 + LOAD_CONST_STORE 0, 0 + LOAD_CONST_STORE 1, 2 + CREATE_SCOPE 0 +.L0: + LOAD_SYMBOL 2 + LT_CONST_JUMP_IF_FALSE L1, 2 + LOAD_SYMBOL 2 + LOAD_SYMBOL 1 + CALL 1 + POP 0 + INCREMENT 2, 1 + SET_VAL 2 + RESET_SCOPE_JUMP L0 +.L1: + POP_SCOPE 0 + HALT 0 + +page_1 + STORE 1 + LOAD_SYMBOL_BY_INDEX 0 + RET 0 + HALT 0 From c86dbbe030c42318e2331875e368254577359c78 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Thu, 22 May 2025 21:03:20 +0200 Subject: [PATCH 13/22] feat(tools): adding a script to find most frequent instruction pairs, to optimize in the IROptimizer --- .gitignore | 2 +- tools/ark_frequent_instructions.py | 106 +++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 tools/ark_frequent_instructions.py diff --git a/.gitignore b/.gitignore index 74212767..d1bf528d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,7 @@ __arkscript__/ *.arkc *.arkm /*.ark -/*.ark.ir +*.ark.ir !tests/unittests/resources/BytecodeReaderSuite/*.arkc # Generated files diff --git a/tools/ark_frequent_instructions.py b/tools/ark_frequent_instructions.py new file mode 100644 index 00000000..7b18cbf8 --- /dev/null +++ b/tools/ark_frequent_instructions.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 + +import os +import sys +import glob +from itertools import islice, tee + +super_insts = [ + "LOAD_CONST_LOAD_CONST", + "LOAD_CONST_STORE", + "LOAD_CONST_SET_VAL", + "STORE_FROM", + "STORE_FROM_INDEX", + "SET_VAL_FROM", + "SET_VAL_FROM_INDEX", + "INCREMENT", + "INCREMENT_BY_INDEX", + "DECREMENT", + "DECREMENT_BY_INDEX", + "STORE_TAIL", + "STORE_TAIL_BY_INDEX", + "STORE_HEAD", + "STORE_HEAD_BY_INDEX", + "SET_VAL_TAIL", + "SET_VAL_TAIL_BY_INDEX", + "SET_VAL_HEAD", + "SET_VAL_HEAD_BY_INDEX", + "CALL_BUILTIN", +] + +executable = None +for p in ["./arkscript", "cmake-build-debug/arkscript", "build/arkscript", "build/arkscript.exe"]: + if os.path.exists(p): + executable = p + break +if executable is None: + print("Couldn't find a valid arkscript executable") + sys.exit(1) + +ir = [] + +rosetta = glob.glob("tests/unittests/resources/RosettaSuite/*.ark") +for file in [ + "tests/unittests/resources/LangSuite/unittests.ark", + "lib/std/tests/all.ark" + ] + rosetta: + os.system(f"{executable} -c {file} -fno-optimizer -fdump-ir") + + if os.path.exists(f"{file}.ir"): + with open(f"{file}.ir") as f: + pages = f.read().split("\n\n") + for page in pages: + # only keep the instruction names + insts = [ + i.replace("\t", "").split(" ")[0] + for i in page.split("\n") + ] + # remove the page name (page_) + ir.append(insts[1:]) + + +def window(iterable, size): + iterators = tee(iterable, size) + iterators = [islice(iterator, i, None) for i, iterator in enumerate(iterators)] + yield from zip(*iterators) + + +def skip_inst_for_frequency(inst): + return inst in super_insts or inst.startswith(".L") + + +frequent_2 = {} +frequent_3 = {} +super_insts_freqs = {} + +for page in ir: + for pair in window(page, 3): + pair_two = (pair[0], pair[1]) + + if pair[0] in super_insts: + super_insts_freqs[pair[0]] = super_insts_freqs.get(pair[0], 0) + 1 + + # if there is a label in the middle of the expression group, + # omit it from the frequencies as this can't be optimized + if not skip_inst_for_frequency(pair[0]) and not skip_inst_for_frequency(pair[1]): + count_two = frequent_2.get(pair_two, 0) + frequent_2[pair_two] = count_two + 1 + if not skip_inst_for_frequency(pair[2]): + count_three = frequent_3.get(pair, 0) + frequent_3[pair] = count_three + 1 + + +def print_most_freqs(data, max_percent=20): + most = sorted(data.items(), key=lambda e: e[1], reverse=True) + interesting = most[:(len(most) * max_percent) // 100] + print("\n".join(f"{insts} -> {count}" for (insts, count) in interesting)) + + +print("Super instructions present:") +print_most_freqs(super_insts_freqs, max_percent=100) + +print("\nPairs of two:") +print_most_freqs(frequent_2) + +print("\nPairs of three:") +print_most_freqs(frequent_3) From 2175e0c7474b46e909dd6f416fc92d2e5870e150 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Fri, 23 May 2025 11:43:31 +0200 Subject: [PATCH 14/22] feat(compiler, vm): adding new CALL_SYMBOL instruction, to load and call a symbol immediately --- include/Ark/Compiler/Instructions.hpp | 5 ++++- include/Ark/VM/VM.hpp | 3 ++- include/Ark/VM/VM.inl | 12 ++++++++++-- .../IROptimizer.cpp | 3 ++- src/arkreactor/VM/VM.cpp | 19 +++++++++++-------- .../unittests/Suites/BytecodeReaderSuite.cpp | 4 ++-- .../optimized_ir/ackermann.expected | 3 +-- .../CompilerSuite/optimized_ir/jumps.expected | 3 +-- .../runtime/recursion_depth.expected | 4 ++-- 9 files changed, 35 insertions(+), 21 deletions(-) diff --git a/include/Ark/Compiler/Instructions.hpp b/include/Ark/Compiler/Instructions.hpp index d6386c9e..23d3c308 100644 --- a/include/Ark/Compiler/Instructions.hpp +++ b/include/Ark/Compiler/Instructions.hpp @@ -307,6 +307,8 @@ namespace Ark::internal // @role Compare #[code TS < constant], if the comparison fails, jump to the given address. Otherwise, does nothing LT_CONST_JUMP_IF_FALSE = 0x4c, + CALL_SYMBOL = 0x4d, + InstructionsCount }; @@ -389,7 +391,8 @@ namespace Ark::internal "SET_VAL_HEAD", "SET_VAL_HEAD_BY_INDEX", "CALL_BUILTIN", - "LT_CONST_JUMP_IF_FALSE" + "LT_CONST_JUMP_IF_FALSE", + "CALL_SYMBOL" }; static_assert(InstructionNames.size() == static_cast(Instruction::InstructionsCount) && "Some instruction names appear to be missing"); diff --git a/include/Ark/VM/VM.hpp b/include/Ark/VM/VM.hpp index 816fb5ba..d23988f3 100644 --- a/include/Ark/VM/VM.hpp +++ b/include/Ark/VM/VM.hpp @@ -365,8 +365,9 @@ namespace Ark * * @param context * @param argc number of arguments already sent + * @param function_ptr optional pointer to the function to call. If not provided, obtain it from the stack */ - inline void call(internal::ExecutionContext& context, uint16_t argc); + inline void call(internal::ExecutionContext& context, uint16_t argc, Value* function_ptr = nullptr); /** * @brief Builtin called when the CALL_BUILTIN instruction is met in the bytecode diff --git a/include/Ark/VM/VM.inl b/include/Ark/VM/VM.inl index d8371f05..999b4355 100644 --- a/include/Ark/VM/VM.inl +++ b/include/Ark/VM/VM.inl @@ -257,7 +257,7 @@ inline void VM::returnFromFuncCall(internal::ExecutionContext& context) context.locals.pop_back(); } -inline void VM::call(internal::ExecutionContext& context, const uint16_t argc) +inline void VM::call(internal::ExecutionContext& context, const uint16_t argc, Value* function_ptr) { /* Argument: number of arguments when calling the function @@ -268,7 +268,15 @@ inline void VM::call(internal::ExecutionContext& context, const uint16_t argc) */ using namespace internal; - Value function = *popAndResolveAsPtr(context); + // stack pointer + 2 because we push IP and PP + if (context.sp + 2u >= VMStackSize) [[unlikely]] + throwVMError( + ErrorKind::VM, + fmt::format( + "Maximum recursion depth exceeded. You could consider rewriting your function `{}' to make use of tail-call optimization.", + m_state.m_symbols[context.last_symbol])); + + Value function = function_ptr == nullptr ? *popAndResolveAsPtr(context) : *function_ptr; context.stacked_closure_scopes.emplace_back(nullptr); switch (function.valueType()) diff --git a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp index ec752a15..09795bd1 100644 --- a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp +++ b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp @@ -33,7 +33,8 @@ namespace Ark::internal Rule { { BUILTIN, CALL }, CALL_BUILTIN, [](const Entities& entities) { return Builtins::builtins[entities[0].primaryArg()].second.isFunction(); - } } + } }, + Rule { { LOAD_SYMBOL, CALL }, CALL_SYMBOL } }; m_ruleset_three = { diff --git a/src/arkreactor/VM/VM.cpp b/src/arkreactor/VM/VM.cpp index c2fcc16a..ee4ca0fb 100644 --- a/src/arkreactor/VM/VM.cpp +++ b/src/arkreactor/VM/VM.cpp @@ -442,7 +442,8 @@ namespace Ark &&TARGET_SET_VAL_HEAD, &&TARGET_SET_VAL_HEAD_BY_INDEX, &&TARGET_CALL_BUILTIN, - &&TARGET_LT_CONST_JUMP_IF_FALSE + &&TARGET_LT_CONST_JUMP_IF_FALSE, + &&TARGET_CALL_SYMBOL }; static_assert(opcode_targets.size() == static_cast(Instruction::InstructionsCount) && "Some instructions are not implemented in the VM"); @@ -565,13 +566,6 @@ namespace Ark TARGET(CALL) { - // stack pointer + 2 because we push IP and PP - if (context.sp + 2u >= VMStackSize) [[unlikely]] - throwVMError( - ErrorKind::VM, - fmt::format( - "Maximum recursion depth exceeded. You could consider rewriting your function `{}' to make use of tail-call optimization.", - m_state.m_symbols[context.last_symbol])); call(context, arg); if (!m_running) GOTO_HALT(); @@ -1549,6 +1543,15 @@ namespace Ark context.ip = secondary_arg * 4; DISPATCH(); } + + TARGET(CALL_SYMBOL) + { + UNPACK_ARGS(); + call(context, secondary_arg, loadSymbol(primary_arg, context)); + if (!m_running) + GOTO_HALT(); + DISPATCH(); + } #pragma endregion } #if ARK_USE_COMPUTED_GOTOS diff --git a/tests/unittests/Suites/BytecodeReaderSuite.cpp b/tests/unittests/Suites/BytecodeReaderSuite.cpp index cae21c58..d3104313 100644 --- a/tests/unittests/Suites/BytecodeReaderSuite.cpp +++ b/tests/unittests/Suites/BytecodeReaderSuite.cpp @@ -123,8 +123,8 @@ ut::suite<"BytecodeReader"> bcr_suite = [] { expect(that % pages.size() == 2ull); // 7 instructions on 4 bytes expect(that % pages[0].size() == 7 * 4ull); - // 24 instructions on 4 bytes - expect(that % pages[1].size() == 24 * 4ull); + // 23 instructions on 4 bytes + expect(that % pages[1].size() == 23 * 4ull); }; }; }; diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/ackermann.expected b/tests/unittests/resources/CompilerSuite/optimized_ir/ackermann.expected index e1f17261..516c0ca9 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/ackermann.expected +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/ackermann.expected @@ -23,8 +23,7 @@ page_1 POP_JUMP_IF_TRUE L2 LOAD_SYMBOL_BY_INDEX 1 DECREMENT_BY_INDEX 0, 1 - LOAD_SYMBOL 0 - CALL 2 + CALL_SYMBOL 0, 2 DECREMENT_BY_INDEX 1, 1 JUMP 0 JUMP L3 diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected index fc71bdce..ad3d9f9a 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected @@ -6,8 +6,7 @@ page_0 LOAD_SYMBOL 2 LT_CONST_JUMP_IF_FALSE L1, 2 LOAD_SYMBOL 2 - LOAD_SYMBOL 1 - CALL 1 + CALL_SYMBOL 1, 1 POP 0 INCREMENT 2, 1 SET_VAL 2 diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/recursion_depth.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/recursion_depth.expected index d23a3b3f..1e3a4028 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/recursion_depth.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/recursion_depth.expected @@ -8,10 +8,10 @@ In file tests/unittests/resources/DiagnosticsSuite/runtime/recursion_depth.ark:3 4 | tmp 5 | })) -[2047] In function `foo' (tests/unittests/resources/DiagnosticsSuite/runtime/recursion_depth.ark:3) +[2048] In function `foo' (tests/unittests/resources/DiagnosticsSuite/runtime/recursion_depth.ark:3) ... [ 1] In global scope (tests/unittests/resources/DiagnosticsSuite/runtime/recursion_depth.ark:7) Current scope variables values: foo = Function@1 -a = 2045 +a = 2046 From d040c6c6299e3f4ed595ef1568e9f62f9d5983a4 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Fri, 23 May 2025 12:12:41 +0200 Subject: [PATCH 15/22] feat(compiler, vm): adding new GET_FIELD_FROM_SYMBOL and GET_FIELD_FROM_SYMBOL_INDEX to load a field from a closure in a single instruction --- CHANGELOG.md | 2 + include/Ark/Compiler/Instructions.hpp | 14 ++- include/Ark/VM/VM.hpp | 6 +- .../IROptimizer.cpp | 25 ++-- src/arkreactor/VM/VM.cpp | 109 +++++++++++------- .../CompilerSuite/optimized_ir/closures.ark | 9 +- .../optimized_ir/closures.expected | 45 ++++---- 7 files changed, 123 insertions(+), 87 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf92da4c..d184f363 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,8 @@ - `RESET_SCOPE_JUMP` instruction emitted at the end of a while loop to reset a scope so that we can create multiple variables and use `LOAD_SYMBOL_BY_INDEX` - instruction source location ; two new bytecode tables were added: one for filenames, another for (page pointer, instruction pointer, file id, line), allowing the VM to display better error messages when the source is available - show source location when a runtime error is thrown in the VM +- `CAL_SYMBOL` super instruction to load and call a symbol in a single instruction +- `GET_FIELD_FROM_SYMBOL` and `GET_FIELD_FROM_SYMBOL_INDEX` super instructions to get a field from a closure and push it to the stack ### Changed - instructions are on 4 bytes: 1 byte for the instruction, 1 byte of padding, 2 bytes for an immediate argument diff --git a/include/Ark/Compiler/Instructions.hpp b/include/Ark/Compiler/Instructions.hpp index 23d3c308..49ed8133 100644 --- a/include/Ark/Compiler/Instructions.hpp +++ b/include/Ark/Compiler/Instructions.hpp @@ -307,8 +307,18 @@ namespace Ark::internal // @role Compare #[code TS < constant], if the comparison fails, jump to the given address. Otherwise, does nothing LT_CONST_JUMP_IF_FALSE = 0x4c, + // @args symbol id, argument count + // @role Call a symbol by its id in #[code primary], with #[code secondary] arguments CALL_SYMBOL = 0x4d, + // @args symbol id, field id in symbols table + // @role Push the field of a given symbol (which has to be a closure) on the stack + GET_FIELD_FROM_SYMBOL = 0x4e, + + // @args symbol index, field id in symbols table + // @role Push the field of a given symbol (which has to be a closure) on the stack + GET_FIELD_FROM_SYMBOL_INDEX = 0x4f, + InstructionsCount }; @@ -392,7 +402,9 @@ namespace Ark::internal "SET_VAL_HEAD_BY_INDEX", "CALL_BUILTIN", "LT_CONST_JUMP_IF_FALSE", - "CALL_SYMBOL" + "CALL_SYMBOL", + "GET_FIELD_FROM_SYMBOL", + "GET_FIELD_FROM_SYMBOL_INDEX" }; static_assert(InstructionNames.size() == static_cast(Instruction::InstructionsCount) && "Some instruction names appear to be missing"); diff --git a/include/Ark/VM/VM.hpp b/include/Ark/VM/VM.hpp index d23988f3..34d03e8f 100644 --- a/include/Ark/VM/VM.hpp +++ b/include/Ark/VM/VM.hpp @@ -229,6 +229,8 @@ namespace Ark */ inline void setVal(uint16_t id, const Value* val, internal::ExecutionContext& context); + Value getField(Value* closure, uint16_t id, internal::ExecutionContext& context); + // ================================================ // stack related // ================================================ @@ -336,9 +338,9 @@ namespace Ark * @param kind type of VM error * @param message */ - static void throwVMError(internal::ErrorKind kind, const std::string& message); + [[noreturn]] static void throwVMError(internal::ErrorKind kind, const std::string& message); - void throwArityError(std::size_t passed_arg_count, std::size_t expected_arg_count, internal::ExecutionContext& context); + [[noreturn]] void throwArityError(std::size_t passed_arg_count, std::size_t expected_arg_count, internal::ExecutionContext& context); void showBacktraceWithException(const std::exception& e, internal::ExecutionContext& context); diff --git a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp index 09795bd1..7137994c 100644 --- a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp +++ b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp @@ -16,25 +16,20 @@ namespace Ark::internal m_logger("IROptimizer", debug) { m_ruleset_two = { - Rule { - { LOAD_CONST, LOAD_CONST }, LOAD_CONST_LOAD_CONST }, - Rule { - { LOAD_CONST, STORE }, LOAD_CONST_STORE }, - Rule { - { LOAD_CONST, SET_VAL }, LOAD_CONST_SET_VAL }, - Rule { - { LOAD_SYMBOL, STORE }, STORE_FROM }, - Rule { - { LOAD_SYMBOL_BY_INDEX, STORE }, STORE_FROM_INDEX }, - Rule { - { LOAD_SYMBOL, SET_VAL }, SET_VAL_FROM }, - Rule { - { LOAD_SYMBOL_BY_INDEX, SET_VAL }, SET_VAL_FROM_INDEX }, + Rule { { LOAD_CONST, LOAD_CONST }, LOAD_CONST_LOAD_CONST }, + Rule { { LOAD_CONST, STORE }, LOAD_CONST_STORE }, + Rule { { LOAD_CONST, SET_VAL }, LOAD_CONST_SET_VAL }, + Rule { { LOAD_SYMBOL, STORE }, STORE_FROM }, + Rule { { LOAD_SYMBOL_BY_INDEX, STORE }, STORE_FROM_INDEX }, + Rule { { LOAD_SYMBOL, SET_VAL }, SET_VAL_FROM }, + Rule { { LOAD_SYMBOL_BY_INDEX, SET_VAL }, SET_VAL_FROM_INDEX }, Rule { { BUILTIN, CALL }, CALL_BUILTIN, [](const Entities& entities) { return Builtins::builtins[entities[0].primaryArg()].second.isFunction(); } }, - Rule { { LOAD_SYMBOL, CALL }, CALL_SYMBOL } + Rule { { LOAD_SYMBOL, CALL }, CALL_SYMBOL }, + Rule { { LOAD_SYMBOL, GET_FIELD }, GET_FIELD_FROM_SYMBOL }, + Rule { { LOAD_SYMBOL_BY_INDEX, GET_FIELD }, GET_FIELD_FROM_SYMBOL_INDEX }, }; m_ruleset_three = { diff --git a/src/arkreactor/VM/VM.cpp b/src/arkreactor/VM/VM.cpp index ee4ca0fb..fa739426 100644 --- a/src/arkreactor/VM/VM.cpp +++ b/src/arkreactor/VM/VM.cpp @@ -116,6 +116,53 @@ namespace Ark } } + Value VM::getField(Value* closure, const uint16_t id, ExecutionContext& context) + { + if (closure->valueType() != ValueType::Closure) + { + if (context.last_symbol < m_state.m_symbols.size()) [[likely]] + throwVMError( + ErrorKind::Type, + fmt::format( + "`{}' is a {}, not a Closure, can not get the field `{}' from it", + m_state.m_symbols[context.last_symbol], + types_to_str[static_cast(closure->valueType())], + m_state.m_symbols[id])); + else + throwVMError(ErrorKind::Type, + fmt::format( + "{} is not a Closure, can not get the field `{}' from it", + types_to_str[static_cast(closure->valueType())], + m_state.m_symbols[id])); + } + + if (Value* field = closure->refClosure().refScope()[id]; field != nullptr) + { + // check for CALL instruction (the instruction because context.ip is already on the next instruction word) + if (m_state.m_pages[context.pp][context.ip] == CALL) + return Value(Closure(closure->refClosure().scopePtr(), field->pageAddr())); + else + return *field; + } + else + { + if (!closure->refClosure().hasFieldEndingWith(m_state.m_symbols[id], *this)) + throwVMError( + ErrorKind::Scope, + fmt::format( + "`{0}' isn't in the closure environment: {1}", + m_state.m_symbols[id], + closure->refClosure().toString(*this))); + throwVMError( + ErrorKind::Scope, + fmt::format( + "`{0}' isn't in the closure environment: {1}. A variable in the package might have the same name as '{0}', " + "and name resolution tried to fully qualify it. Rename either the variable or the capture to solve this", + m_state.m_symbols[id], + closure->refClosure().toString(*this))); + } + } + Value& VM::operator[](const std::string& name) noexcept { // find id of object @@ -443,7 +490,9 @@ namespace Ark &&TARGET_SET_VAL_HEAD_BY_INDEX, &&TARGET_CALL_BUILTIN, &&TARGET_LT_CONST_JUMP_IF_FALSE, - &&TARGET_CALL_SYMBOL + &&TARGET_CALL_SYMBOL, + &&TARGET_GET_FIELD_FROM_SYMBOL, + &&TARGET_GET_FIELD_FROM_SYMBOL_INDEX }; static_assert(opcode_targets.size() == static_cast(Instruction::InstructionsCount) && "Some instructions are not implemented in the VM"); @@ -618,49 +667,7 @@ namespace Ark TARGET(GET_FIELD) { Value* var = popAndResolveAsPtr(context); - if (var->valueType() != ValueType::Closure) - { - if (context.last_symbol < m_state.m_symbols.size()) [[likely]] - throwVMError( - ErrorKind::Type, - fmt::format( - "`{}' is a {}, not a Closure, can not get the field `{}' from it", - m_state.m_symbols[context.last_symbol], - types_to_str[static_cast(var->valueType())], - m_state.m_symbols[arg])); - else - throwVMError(ErrorKind::Type, - fmt::format( - "{} is not a Closure, can not get the field `{}' from it", - types_to_str[static_cast(var->valueType())], - m_state.m_symbols[arg])); - } - - if (Value* field = var->refClosure().refScope()[arg]; field != nullptr) - { - // check for CALL instruction (the instruction because context.ip is already on the next instruction word) - if (m_state.m_pages[context.pp][context.ip] == CALL) - push(Value(Closure(var->refClosure().scopePtr(), field->pageAddr())), context); - else - push(field, context); - } - else - { - if (!var->refClosure().hasFieldEndingWith(m_state.m_symbols[arg], *this)) - throwVMError( - ErrorKind::Scope, - fmt::format( - "`{0}' isn't in the closure environment: {1}", - m_state.m_symbols[arg], - var->refClosure().toString(*this))); - throwVMError( - ErrorKind::Scope, - fmt::format( - "`{0}' isn't in the closure environment: {1}. A variable in the package might have the same name as '{0}', " - "and name resolution tried to fully qualify it. Rename either the variable or the capture to solve this", - m_state.m_symbols[arg], - var->refClosure().toString(*this))); - } + push(getField(var, arg, context), context); DISPATCH(); } @@ -1552,6 +1559,20 @@ namespace Ark GOTO_HALT(); DISPATCH(); } + + TARGET(GET_FIELD_FROM_SYMBOL) + { + UNPACK_ARGS(); + push(getField(loadSymbol(primary_arg, context), secondary_arg, context), context); + DISPATCH(); + } + + TARGET(GET_FIELD_FROM_SYMBOL_INDEX) + { + UNPACK_ARGS(); + push(getField(loadSymbolFromIndex(primary_arg, context), secondary_arg, context), context); + DISPATCH(); + } #pragma endregion } #if ARK_USE_COMPUTED_GOTOS diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/closures.ark b/tests/unittests/resources/CompilerSuite/optimized_ir/closures.ark index f818e563..cfef323a 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/closures.ark +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/closures.ark @@ -41,6 +41,9 @@ (let countdown-from-3 (countdown-from 3)) -(print "Countdown " (countdown-from-3)) # 2 -(print "Countdown " (countdown-from-3)) # 1 -(print "Countdown " (countdown-from-3)) # 0 +(let executor (fun () { + (print "Countdown " (countdown-from-3)) # 2 + (print "Countdown " (countdown-from-3)) # 1 + (print "Countdown " (countdown-from-3)) # 0 + (print countdown-from-3.number) # 0 +})) diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/closures.expected b/tests/unittests/resources/CompilerSuite/optimized_ir/closures.expected index 34ab4efa..525a45f5 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/closures.expected +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/closures.expected @@ -11,26 +11,22 @@ page_0 CALL 3 STORE 7 LOAD_CONST 9 - LOAD_SYMBOL_BY_INDEX 1 - GET_FIELD 2 + GET_FIELD_FROM_SYMBOL_INDEX 1, 2 CALL_BUILTIN 9, 2 POP 0 LOAD_CONST 10 CALL_BUILTIN 9, 1 POP 0 LOAD_CONST 11 - LOAD_SYMBOL_BY_INDEX 1 - GET_FIELD 4 + GET_FIELD_FROM_SYMBOL_INDEX 1, 4 CALL 1 POP 0 LOAD_CONST 12 - LOAD_SYMBOL_BY_INDEX 1 - GET_FIELD 2 + GET_FIELD_FROM_SYMBOL_INDEX 1, 2 CALL_BUILTIN 9, 2 POP 0 LOAD_CONST 13 - LOAD_SYMBOL_BY_INDEX 0 - GET_FIELD 2 + GET_FIELD_FROM_SYMBOL_INDEX 0, 2 CALL_BUILTIN 9, 2 POP 0 LOAD_CONST_STORE 14, 8 @@ -38,20 +34,7 @@ page_0 LOAD_SYMBOL_BY_INDEX 0 CALL 1 STORE 10 - LOAD_CONST 18 - LOAD_SYMBOL_BY_INDEX 0 - CALL 0 - CALL_BUILTIN 9, 2 - POP 0 - LOAD_CONST 18 - LOAD_SYMBOL_BY_INDEX 0 - CALL 0 - CALL_BUILTIN 9, 2 - POP 0 - LOAD_CONST 18 - LOAD_SYMBOL_BY_INDEX 0 - CALL 0 - CALL_BUILTIN 9, 2 + LOAD_CONST_STORE 18, 11 HALT 0 page_1 @@ -91,3 +74,21 @@ page_5 LOAD_SYMBOL 9 RET 0 HALT 0 + +page_6 + LOAD_CONST 19 + CALL_SYMBOL 10, 0 + CALL_BUILTIN 9, 2 + POP 0 + LOAD_CONST 19 + CALL_SYMBOL 10, 0 + CALL_BUILTIN 9, 2 + POP 0 + LOAD_CONST 19 + CALL_SYMBOL 10, 0 + CALL_BUILTIN 9, 2 + POP 0 + GET_FIELD_FROM_SYMBOL 10, 9 + CALL_BUILTIN 9, 1 + RET 0 + HALT 0 From 14e8d2a9659e8ae568e681e4d2a2f444b79ac29d Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Fri, 23 May 2025 12:24:33 +0200 Subject: [PATCH 16/22] chore: update ark_frequent_instructions.py script to add the new super instructions and ignore HALT in the frequencies --- tools/ark_frequent_instructions.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/ark_frequent_instructions.py b/tools/ark_frequent_instructions.py index 7b18cbf8..24340173 100644 --- a/tools/ark_frequent_instructions.py +++ b/tools/ark_frequent_instructions.py @@ -26,6 +26,10 @@ "SET_VAL_HEAD", "SET_VAL_HEAD_BY_INDEX", "CALL_BUILTIN", + "LT_CONST_JUMP_IF_FALSE", + "CALL_SYMBOL", + "GET_FIELD_FROM_SYMBOL", + "GET_FIELD_FROM_SYMBOL_INDEX" ] executable = None @@ -66,7 +70,7 @@ def window(iterable, size): def skip_inst_for_frequency(inst): - return inst in super_insts or inst.startswith(".L") + return inst in super_insts or inst.startswith(".L") or inst == "HALT" frequent_2 = {} From 6d4658ec7ca56b76e57fbd999bb901df4434c388 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Fri, 23 May 2025 12:35:48 +0200 Subject: [PATCH 17/22] feat(compiler, vm): adding new LT_SYM_JUMP_IF_FALSE super instruction to complement LT_CONST_JUMP_IF_FALSE --- CHANGELOG.md | 3 ++- examples/fizz_buzz.ark | 9 +++++---- include/Ark/Compiler/Instructions.hpp | 11 ++++++++--- lib/std | 2 +- .../IntermediateRepresentation/IROptimizer.cpp | 7 +++++-- src/arkreactor/VM/VM.cpp | 10 ++++++++++ .../resources/CompilerSuite/optimized_ir/jumps.ark | 5 +++++ .../CompilerSuite/optimized_ir/jumps.expected | 13 +++++++++++++ 8 files changed, 49 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d184f363..ef210dfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,7 +44,8 @@ - `RESET_SCOPE_JUMP` instruction emitted at the end of a while loop to reset a scope so that we can create multiple variables and use `LOAD_SYMBOL_BY_INDEX` - instruction source location ; two new bytecode tables were added: one for filenames, another for (page pointer, instruction pointer, file id, line), allowing the VM to display better error messages when the source is available - show source location when a runtime error is thrown in the VM -- `CAL_SYMBOL` super instruction to load and call a symbol in a single instruction +- `LT_CONST_JUMP_IF_FALSE` and `LT_SYM_JUMP_IF_FALSE` to compare a symbol to a const and a symbol to a symbol (respectively), then jump to an address if false (useful for while loops that check a simple `(< x n)` condition) +- `CALL_SYMBOL` super instruction to load and call a symbol in a single instruction - `GET_FIELD_FROM_SYMBOL` and `GET_FIELD_FROM_SYMBOL_INDEX` super instructions to get a field from a closure and push it to the stack ### Changed diff --git a/examples/fizz_buzz.ark b/examples/fizz_buzz.ark index ef589973..8ad84d3f 100644 --- a/examples/fizz_buzz.ark +++ b/examples/fizz_buzz.ark @@ -5,9 +5,10 @@ r (fun (e) (if (= 0 (mod e 15)) - (print "FizzBuzz") + (puts "FizzBuzz,") (if (= 0 (mod e 3)) - (print "Fizz") + (puts "Fizz,") (if (= 0 (mod e 5)) - (print "Buzz") - (print e)))))) + (puts "Buzz,") + (puts e ",")))))) +(puts "\n") diff --git a/include/Ark/Compiler/Instructions.hpp b/include/Ark/Compiler/Instructions.hpp index 49ed8133..29b6d402 100644 --- a/include/Ark/Compiler/Instructions.hpp +++ b/include/Ark/Compiler/Instructions.hpp @@ -307,17 +307,21 @@ namespace Ark::internal // @role Compare #[code TS < constant], if the comparison fails, jump to the given address. Otherwise, does nothing LT_CONST_JUMP_IF_FALSE = 0x4c, + // @args symbol id, absolute address to jump to + // @role Compare #[code TS < symbol], if the comparison fails, jump to the given address. Otherwise, does nothing + LT_SYM_JUMP_IF_FALSE = 0x4d, + // @args symbol id, argument count // @role Call a symbol by its id in #[code primary], with #[code secondary] arguments - CALL_SYMBOL = 0x4d, + CALL_SYMBOL = 0x4e, // @args symbol id, field id in symbols table // @role Push the field of a given symbol (which has to be a closure) on the stack - GET_FIELD_FROM_SYMBOL = 0x4e, + GET_FIELD_FROM_SYMBOL = 0x4f, // @args symbol index, field id in symbols table // @role Push the field of a given symbol (which has to be a closure) on the stack - GET_FIELD_FROM_SYMBOL_INDEX = 0x4f, + GET_FIELD_FROM_SYMBOL_INDEX = 0x50, InstructionsCount }; @@ -402,6 +406,7 @@ namespace Ark::internal "SET_VAL_HEAD_BY_INDEX", "CALL_BUILTIN", "LT_CONST_JUMP_IF_FALSE", + "LT_SYM_JUMP_IF_FALSE", "CALL_SYMBOL", "GET_FIELD_FROM_SYMBOL", "GET_FIELD_FROM_SYMBOL_INDEX" diff --git a/lib/std b/lib/std index a794e340..c3d9c409 160000 --- a/lib/std +++ b/lib/std @@ -1 +1 @@ -Subproject commit a794e34099c4d75c50903d48937ed803ad23b4b5 +Subproject commit c3d9c409c4216e39838d9a8e53af105727dd739e diff --git a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp index 7137994c..0391db3f 100644 --- a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp +++ b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp @@ -102,12 +102,15 @@ namespace Ark::internal Rule { { LOAD_SYMBOL_BY_INDEX, HEAD, SET_VAL }, [](const Entities& e) { return IR::Entity(SET_VAL_HEAD_BY_INDEX, e[0].primaryArg(), e[2].primaryArg()); } }, - // LOAD_CONST id + // LOAD_CONST id / LOAD_SYMBOL id // // POP_JUMP_IF_FALSE - // ---> _CONST_JUMP_IF_FALSE + // ---> _(CONST|SYM)_JUMP_IF_FALSE Rule { { LOAD_CONST, LT, POP_JUMP_IF_FALSE }, [](const Entities& e) { return IR::Entity::GotoWithArg(e[2], LT_CONST_JUMP_IF_FALSE, e[0].primaryArg()); + } }, + Rule { { LOAD_SYMBOL, LT, POP_JUMP_IF_FALSE }, [](const Entities& e) { + return IR::Entity::GotoWithArg(e[2], LT_SYM_JUMP_IF_FALSE, e[0].primaryArg()); } } }; } diff --git a/src/arkreactor/VM/VM.cpp b/src/arkreactor/VM/VM.cpp index fa739426..f9d73c6d 100644 --- a/src/arkreactor/VM/VM.cpp +++ b/src/arkreactor/VM/VM.cpp @@ -490,6 +490,7 @@ namespace Ark &&TARGET_SET_VAL_HEAD_BY_INDEX, &&TARGET_CALL_BUILTIN, &&TARGET_LT_CONST_JUMP_IF_FALSE, + &&TARGET_LT_SYM_JUMP_IF_FALSE, &&TARGET_CALL_SYMBOL, &&TARGET_GET_FIELD_FROM_SYMBOL, &&TARGET_GET_FIELD_FROM_SYMBOL_INDEX @@ -1551,6 +1552,15 @@ namespace Ark DISPATCH(); } + TARGET(LT_SYM_JUMP_IF_FALSE) + { + UNPACK_ARGS(); + const Value* sym = popAndResolveAsPtr(context); + if (!(*sym < *loadSymbol(primary_arg, context))) + context.ip = secondary_arg * 4; + DISPATCH(); + } + TARGET(CALL_SYMBOL) { UNPACK_ARGS(); diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark index e8fe9c27..c11a37b6 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark @@ -4,3 +4,8 @@ (while (< i 100) { (e i) (set i (+ 1 i)) }) + +(let n 100) +(while (< i n) { + (e i) + (set i (+ 1 i)) }) diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected index ad3d9f9a..659bc180 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected @@ -12,6 +12,19 @@ page_0 SET_VAL 2 RESET_SCOPE_JUMP L0 .L1: + POP_SCOPE 0 + LOAD_CONST_STORE 2, 3 + CREATE_SCOPE 0 +.L2: + LOAD_SYMBOL 2 + LT_SYM_JUMP_IF_FALSE L3, 3 + LOAD_SYMBOL 2 + CALL_SYMBOL 1, 1 + POP 0 + INCREMENT 2, 1 + SET_VAL 2 + RESET_SCOPE_JUMP L2 +.L3: POP_SCOPE 0 HALT 0 From 3f0e81b3f9b2d91db6f6a70c6833cad9e6157606 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Fri, 23 May 2025 12:46:20 +0200 Subject: [PATCH 18/22] feat(compiler, vm): adding new EQ_CONST_JUMP_IF_TRUE and EQ_SYM_INDEX_JUMP_IF_TRUE to compare a symbol to a const and a symbol to a symbol (respectively), then jump to an address if true --- CHANGELOG.md | 1 + include/Ark/Compiler/Instructions.hpp | 16 ++++++++++++--- .../IROptimizer.cpp | 10 ++++++++-- src/arkreactor/VM/VM.cpp | 20 +++++++++++++++++++ .../unittests/Suites/BytecodeReaderSuite.cpp | 4 ++-- .../optimized_ir/ackermann.expected | 4 +--- .../CompilerSuite/optimized_ir/jumps.ark | 6 ++++++ .../CompilerSuite/optimized_ir/jumps.expected | 7 +++++++ tools/ark_frequent_instructions.py | 3 +++ 9 files changed, 61 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef210dfa..30e99b04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ - `LT_CONST_JUMP_IF_FALSE` and `LT_SYM_JUMP_IF_FALSE` to compare a symbol to a const and a symbol to a symbol (respectively), then jump to an address if false (useful for while loops that check a simple `(< x n)` condition) - `CALL_SYMBOL` super instruction to load and call a symbol in a single instruction - `GET_FIELD_FROM_SYMBOL` and `GET_FIELD_FROM_SYMBOL_INDEX` super instructions to get a field from a closure and push it to the stack +- `EQ_CONST_JUMP_IF_TRUE` and `EQ_SYM_INDEX_JUMP_IF_TRUE` to compare a symbol to a const and a symbol to a symbol (respectively), then jump to an address if true (useful for conditions that check a simple `(= x n)` condition) ### Changed - instructions are on 4 bytes: 1 byte for the instruction, 1 byte of padding, 2 bytes for an immediate argument diff --git a/include/Ark/Compiler/Instructions.hpp b/include/Ark/Compiler/Instructions.hpp index 29b6d402..bac96639 100644 --- a/include/Ark/Compiler/Instructions.hpp +++ b/include/Ark/Compiler/Instructions.hpp @@ -311,17 +311,25 @@ namespace Ark::internal // @role Compare #[code TS < symbol], if the comparison fails, jump to the given address. Otherwise, does nothing LT_SYM_JUMP_IF_FALSE = 0x4d, + // @args constant id, absolute address to jump to + // @role Compare #[code TS == constant], if the comparison succeeds, jump to the given address. Otherwise, does nothing + EQ_CONST_JUMP_IF_TRUE = 0x4e, + + // @args symbol index, absolute address to jump to + // @role Compare #[code TS == symbol], if the comparison succeeds, jump to the given address. Otherwise, does nothing + EQ_SYM_INDEX_JUMP_IF_TRUE = 0x4f, + // @args symbol id, argument count // @role Call a symbol by its id in #[code primary], with #[code secondary] arguments - CALL_SYMBOL = 0x4e, + CALL_SYMBOL = 0x50, // @args symbol id, field id in symbols table // @role Push the field of a given symbol (which has to be a closure) on the stack - GET_FIELD_FROM_SYMBOL = 0x4f, + GET_FIELD_FROM_SYMBOL = 0x51, // @args symbol index, field id in symbols table // @role Push the field of a given symbol (which has to be a closure) on the stack - GET_FIELD_FROM_SYMBOL_INDEX = 0x50, + GET_FIELD_FROM_SYMBOL_INDEX = 0x52, InstructionsCount }; @@ -407,6 +415,8 @@ namespace Ark::internal "CALL_BUILTIN", "LT_CONST_JUMP_IF_FALSE", "LT_SYM_JUMP_IF_FALSE", + "EQ_CONST_JUMP_IF_TRUE", + "EQ_SYM_INDEX_JUMP_IF_TRUE", "CALL_SYMBOL", "GET_FIELD_FROM_SYMBOL", "GET_FIELD_FROM_SYMBOL_INDEX" diff --git a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp index 0391db3f..1e3cf260 100644 --- a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp +++ b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp @@ -104,13 +104,19 @@ namespace Ark::internal } }, // LOAD_CONST id / LOAD_SYMBOL id // - // POP_JUMP_IF_FALSE - // ---> _(CONST|SYM)_JUMP_IF_FALSE + // POP_JUMP_IF_(FALSE|TRUE) + // ---> _(CONST|SYM)_JUMP_IF_(FALSE|TRUE) Rule { { LOAD_CONST, LT, POP_JUMP_IF_FALSE }, [](const Entities& e) { return IR::Entity::GotoWithArg(e[2], LT_CONST_JUMP_IF_FALSE, e[0].primaryArg()); } }, Rule { { LOAD_SYMBOL, LT, POP_JUMP_IF_FALSE }, [](const Entities& e) { return IR::Entity::GotoWithArg(e[2], LT_SYM_JUMP_IF_FALSE, e[0].primaryArg()); + } }, + Rule { { LOAD_CONST, EQ, POP_JUMP_IF_TRUE }, [](const Entities& e) { + return IR::Entity::GotoWithArg(e[2], EQ_CONST_JUMP_IF_TRUE, e[0].primaryArg()); + } }, + Rule { { LOAD_SYMBOL_BY_INDEX, EQ, POP_JUMP_IF_TRUE }, [](const Entities& e) { + return IR::Entity::GotoWithArg(e[2], EQ_SYM_INDEX_JUMP_IF_TRUE, e[0].primaryArg()); } } }; } diff --git a/src/arkreactor/VM/VM.cpp b/src/arkreactor/VM/VM.cpp index f9d73c6d..7dc9ce5d 100644 --- a/src/arkreactor/VM/VM.cpp +++ b/src/arkreactor/VM/VM.cpp @@ -491,6 +491,8 @@ namespace Ark &&TARGET_CALL_BUILTIN, &&TARGET_LT_CONST_JUMP_IF_FALSE, &&TARGET_LT_SYM_JUMP_IF_FALSE, + &&TARGET_EQ_CONST_JUMP_IF_TRUE, + &&TARGET_EQ_SYM_INDEX_JUMP_IF_TRUE, &&TARGET_CALL_SYMBOL, &&TARGET_GET_FIELD_FROM_SYMBOL, &&TARGET_GET_FIELD_FROM_SYMBOL_INDEX @@ -1561,6 +1563,24 @@ namespace Ark DISPATCH(); } + TARGET(EQ_CONST_JUMP_IF_TRUE) + { + UNPACK_ARGS(); + const Value* sym = popAndResolveAsPtr(context); + if (*sym == *loadConstAsPtr(primary_arg)) + context.ip = secondary_arg * 4; + DISPATCH(); + } + + TARGET(EQ_SYM_INDEX_JUMP_IF_TRUE) + { + UNPACK_ARGS(); + const Value* sym = popAndResolveAsPtr(context); + if (*sym == *loadSymbolFromIndex(primary_arg, context)) + context.ip = secondary_arg * 4; + DISPATCH(); + } + TARGET(CALL_SYMBOL) { UNPACK_ARGS(); diff --git a/tests/unittests/Suites/BytecodeReaderSuite.cpp b/tests/unittests/Suites/BytecodeReaderSuite.cpp index d3104313..6c2d4f57 100644 --- a/tests/unittests/Suites/BytecodeReaderSuite.cpp +++ b/tests/unittests/Suites/BytecodeReaderSuite.cpp @@ -123,8 +123,8 @@ ut::suite<"BytecodeReader"> bcr_suite = [] { expect(that % pages.size() == 2ull); // 7 instructions on 4 bytes expect(that % pages[0].size() == 7 * 4ull); - // 23 instructions on 4 bytes - expect(that % pages[1].size() == 23 * 4ull); + // 21 instructions on 4 bytes + expect(that % pages[1].size() == 21 * 4ull); }; }; }; diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/ackermann.expected b/tests/unittests/resources/CompilerSuite/optimized_ir/ackermann.expected index 516c0ca9..7697f073 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/ackermann.expected +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/ackermann.expected @@ -18,9 +18,7 @@ page_1 JUMP L1 .L0: LOAD_CONST 1 - LOAD_SYMBOL_BY_INDEX 0 - EQ 0 - POP_JUMP_IF_TRUE L2 + EQ_SYM_INDEX_JUMP_IF_TRUE L2, 0 LOAD_SYMBOL_BY_INDEX 1 DECREMENT_BY_INDEX 0, 1 CALL_SYMBOL 0, 2 diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark index c11a37b6..6339202c 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark @@ -1,11 +1,17 @@ (let foo (fun (e) e)) (mut i 0) +# LT_CONST_JUMP_IF_FALSE (while (< i 100) { (e i) (set i (+ 1 i)) }) (let n 100) +# LT_SYM_JUMP_IF_FALSE (while (< i n) { (e i) (set i (+ 1 i)) }) + +# EQ_CONST_JUMP_IF_TRUE +(if (= i 5) + (print "i = 5")) diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected index 659bc180..001287d6 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected @@ -26,6 +26,13 @@ page_0 RESET_SCOPE_JUMP L2 .L3: POP_SCOPE 0 + LOAD_SYMBOL_BY_INDEX 1 + EQ_CONST_JUMP_IF_TRUE L4, 4 + JUMP L5 +.L4: + LOAD_CONST 5 + CALL_BUILTIN 9, 1 +.L5: HALT 0 page_1 diff --git a/tools/ark_frequent_instructions.py b/tools/ark_frequent_instructions.py index 24340173..7ad15688 100644 --- a/tools/ark_frequent_instructions.py +++ b/tools/ark_frequent_instructions.py @@ -27,6 +27,9 @@ "SET_VAL_HEAD_BY_INDEX", "CALL_BUILTIN", "LT_CONST_JUMP_IF_FALSE", + "LT_SYM_JUMP_IF_FALSE", + "EQ_CONST_JUMP_IF_TRUE", + "EQ_SYM_INDEX_JUMP_IF_TRUE", "CALL_SYMBOL", "GET_FIELD_FROM_SYMBOL", "GET_FIELD_FROM_SYMBOL_INDEX" From 553fe196f9bdb129390812286c3384a87985e8bd Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Fri, 23 May 2025 12:49:19 +0200 Subject: [PATCH 19/22] chore(tests): adding comments in the optimized IR tests to know what kind of super instruction we are testing --- .../resources/CompilerSuite/optimized_ir/increments.ark | 3 +++ .../resources/CompilerSuite/optimized_ir/lists.ark | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/increments.ark b/tests/unittests/resources/CompilerSuite/optimized_ir/increments.ark index 809c78b1..f5855421 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/increments.ark +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/increments.ark @@ -1,6 +1,9 @@ (mut i 1) +# INCREMENT_BY_INDEX (set i (+ i 4)) +# INCREMENT_BY_INDEX (set i (+ 6 i)) +# DECREMENT_BY_INDEX (set i (- i 8)) # should not be inlined (set i (+ i 4096)) diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/lists.ark b/tests/unittests/resources/CompilerSuite/optimized_ir/lists.ark index 9955ffef..2bc1705b 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/lists.ark +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/lists.ark @@ -1,17 +1,26 @@ (let source [1 2 3 4]) (let foo (fun () { + # STORE_HEAD (mut head_1 (head source)) + # STORE_TAIL (mut tail_1 (tail source)) + # STORE_FROM (mut copy_1 source) + # SET_VAL_HEAD (set copy_1 (head source)) + # SET_VAL_TAIL (set copy_1 (tail source)) })) (foo) +# STORE_HEAD_BY_INDEX (mut head_2 (head source)) +# STORE_TAIL_BY_INDEX (mut tail_2 (tail source)) (mut copy_2 source) +# SET_VAL_HEAD_BY_INDEX (set copy_2 (head source)) +# SET_VAL_TAIL_BY_INDEX (set copy_2 (tail source)) From 4f374ac9501245295fdd6ff202b3ede7304da18e Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Fri, 23 May 2025 12:55:29 +0200 Subject: [PATCH 20/22] feat(compiler, vm): adding new NEQ_CONST_JUMP_IF_TRUE super instruction to compare a symbol to a const, then jump to an address if they differ --- CHANGELOG.md | 1 + include/Ark/Compiler/Instructions.hpp | 11 ++++++++--- .../IntermediateRepresentation/IROptimizer.cpp | 3 +++ src/arkreactor/VM/VM.cpp | 10 ++++++++++ .../resources/CompilerSuite/optimized_ir/jumps.ark | 4 ++++ .../CompilerSuite/optimized_ir/jumps.expected | 8 ++++++++ tools/ark_frequent_instructions.py | 1 + 7 files changed, 35 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30e99b04..b910345d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ - `CALL_SYMBOL` super instruction to load and call a symbol in a single instruction - `GET_FIELD_FROM_SYMBOL` and `GET_FIELD_FROM_SYMBOL_INDEX` super instructions to get a field from a closure and push it to the stack - `EQ_CONST_JUMP_IF_TRUE` and `EQ_SYM_INDEX_JUMP_IF_TRUE` to compare a symbol to a const and a symbol to a symbol (respectively), then jump to an address if true (useful for conditions that check a simple `(= x n)` condition) +- `NEQ_CONST_JUMP_IF_TRUE` as a super instruction counterpart to `EQ_CONST_JUMP_IF_TRUE` ### Changed - instructions are on 4 bytes: 1 byte for the instruction, 1 byte of padding, 2 bytes for an immediate argument diff --git a/include/Ark/Compiler/Instructions.hpp b/include/Ark/Compiler/Instructions.hpp index bac96639..50af13ec 100644 --- a/include/Ark/Compiler/Instructions.hpp +++ b/include/Ark/Compiler/Instructions.hpp @@ -319,17 +319,21 @@ namespace Ark::internal // @role Compare #[code TS == symbol], if the comparison succeeds, jump to the given address. Otherwise, does nothing EQ_SYM_INDEX_JUMP_IF_TRUE = 0x4f, + // @args constant id, absolute address to jump to + // @role Compare #[code TS != constant], if the comparison succeeds, jump to the given address. Otherwise, does nothing + NEQ_CONST_JUMP_IF_TRUE = 0x50, + // @args symbol id, argument count // @role Call a symbol by its id in #[code primary], with #[code secondary] arguments - CALL_SYMBOL = 0x50, + CALL_SYMBOL = 0x51, // @args symbol id, field id in symbols table // @role Push the field of a given symbol (which has to be a closure) on the stack - GET_FIELD_FROM_SYMBOL = 0x51, + GET_FIELD_FROM_SYMBOL = 0x52, // @args symbol index, field id in symbols table // @role Push the field of a given symbol (which has to be a closure) on the stack - GET_FIELD_FROM_SYMBOL_INDEX = 0x52, + GET_FIELD_FROM_SYMBOL_INDEX = 0x53, InstructionsCount }; @@ -417,6 +421,7 @@ namespace Ark::internal "LT_SYM_JUMP_IF_FALSE", "EQ_CONST_JUMP_IF_TRUE", "EQ_SYM_INDEX_JUMP_IF_TRUE", + "NEQ_CONST_JUMP_IF_TRUE", "CALL_SYMBOL", "GET_FIELD_FROM_SYMBOL", "GET_FIELD_FROM_SYMBOL_INDEX" diff --git a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp index 1e3cf260..0e298728 100644 --- a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp +++ b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp @@ -117,6 +117,9 @@ namespace Ark::internal } }, Rule { { LOAD_SYMBOL_BY_INDEX, EQ, POP_JUMP_IF_TRUE }, [](const Entities& e) { return IR::Entity::GotoWithArg(e[2], EQ_SYM_INDEX_JUMP_IF_TRUE, e[0].primaryArg()); + } }, + Rule { { LOAD_CONST, NEQ, POP_JUMP_IF_TRUE }, [](const Entities& e) { + return IR::Entity::GotoWithArg(e[2], NEQ_CONST_JUMP_IF_TRUE, e[0].primaryArg()); } } }; } diff --git a/src/arkreactor/VM/VM.cpp b/src/arkreactor/VM/VM.cpp index 7dc9ce5d..d029f769 100644 --- a/src/arkreactor/VM/VM.cpp +++ b/src/arkreactor/VM/VM.cpp @@ -493,6 +493,7 @@ namespace Ark &&TARGET_LT_SYM_JUMP_IF_FALSE, &&TARGET_EQ_CONST_JUMP_IF_TRUE, &&TARGET_EQ_SYM_INDEX_JUMP_IF_TRUE, + &&TARGET_NEQ_CONST_JUMP_IF_TRUE, &&TARGET_CALL_SYMBOL, &&TARGET_GET_FIELD_FROM_SYMBOL, &&TARGET_GET_FIELD_FROM_SYMBOL_INDEX @@ -1581,6 +1582,15 @@ namespace Ark DISPATCH(); } + TARGET(NEQ_CONST_JUMP_IF_TRUE) + { + UNPACK_ARGS(); + const Value* sym = popAndResolveAsPtr(context); + if (*sym != *loadConstAsPtr(primary_arg)) + context.ip = secondary_arg * 4; + DISPATCH(); + } + TARGET(CALL_SYMBOL) { UNPACK_ARGS(); diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark index 6339202c..17dd63e4 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.ark @@ -15,3 +15,7 @@ # EQ_CONST_JUMP_IF_TRUE (if (= i 5) (print "i = 5")) + +# NEQ_CONST_JUMP_IF_TRUE +(if (!= i 5) + (print "i != 5")) diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected index 001287d6..449545ea 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/jumps.expected @@ -32,7 +32,15 @@ page_0 .L4: LOAD_CONST 5 CALL_BUILTIN 9, 1 + POP 0 .L5: + LOAD_SYMBOL_BY_INDEX 1 + NEQ_CONST_JUMP_IF_TRUE L6, 4 + JUMP L7 +.L6: + LOAD_CONST 6 + CALL_BUILTIN 9, 1 +.L7: HALT 0 page_1 diff --git a/tools/ark_frequent_instructions.py b/tools/ark_frequent_instructions.py index 7ad15688..4faabeba 100644 --- a/tools/ark_frequent_instructions.py +++ b/tools/ark_frequent_instructions.py @@ -30,6 +30,7 @@ "LT_SYM_JUMP_IF_FALSE", "EQ_CONST_JUMP_IF_TRUE", "EQ_SYM_INDEX_JUMP_IF_TRUE", + "NEQ_CONST_JUMP_IF_TRUE", "CALL_SYMBOL", "GET_FIELD_FROM_SYMBOL", "GET_FIELD_FROM_SYMBOL_INDEX" From ff6b0101ec4bd227dc95275961e6c4c77e02863a Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Fri, 23 May 2025 13:17:54 +0200 Subject: [PATCH 21/22] chore: playing with formatting so that clang format doesn't complain on the CI --- .../IROptimizer.hpp | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/include/Ark/Compiler/IntermediateRepresentation/IROptimizer.hpp b/include/Ark/Compiler/IntermediateRepresentation/IROptimizer.hpp index 3439a7d3..09abb14d 100644 --- a/include/Ark/Compiler/IntermediateRepresentation/IROptimizer.hpp +++ b/include/Ark/Compiler/IntermediateRepresentation/IROptimizer.hpp @@ -57,31 +57,24 @@ namespace Ark::internal Condition_t condition; ///< Additional condition to match Replacement_t createReplacement; ///< Create the replacement instructions from given context - Rule( - std::vector&& input, - Instruction replacement, - Condition_t&& cond = [](const Entities&) { - return true; - }) : - expected(std::move(input)), condition(std::move(cond)), createReplacement([replacement](const Entities& e) { + constexpr static auto default_cond = [](const Entities&) { + return true; + }; + + Rule(std::vector&& input, Instruction replacement, Condition_t&& cond = default_cond) : + expected(std::move(input)), condition(std::move(cond)) + { + createReplacement = [replacement](const Entities& e) { return IR::Entity(replacement, e[0].primaryArg(), e[1].primaryArg()); - }) - {} + }; + } - Rule( - std::vector&& input, - Condition_t&& cond, - Replacement_t&& repl) : + Rule(std::vector&& input, Condition_t&& cond, Replacement_t&& repl) : expected(std::move(input)), condition(std::move(cond)), createReplacement(std::move(repl)) {} - Rule( - std::vector&& input, - Replacement_t&& repl) : - expected(std::move(input)), condition([](const Entities&) { - return true; - }), - createReplacement(std::move(repl)) + Rule(std::vector&& input, Replacement_t&& repl) : + expected(std::move(input)), condition(default_cond), createReplacement(std::move(repl)) {} }; From 241f34224e09aacfcd0c65d8e00ea65e0876ed7b Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Fri, 23 May 2025 18:06:35 +0200 Subject: [PATCH 22/22] feat(compiler, vm): adding new AT_SYM_SYM and AT_SYM_INDEX_SYM_INDEX super instructions to get elements from list in a single instruction --- CHANGELOG.md | 1 + include/Ark/Compiler/Instructions.hpp | 7 +- include/Ark/VM/VM.hpp | 16 +-- include/Ark/VM/Value.hpp | 18 ++- .../IROptimizer.cpp | 7 +- src/arkreactor/VM/VM.cpp | 116 ++++++++++-------- .../CompilerSuite/optimized_ir/lists.ark | 9 +- .../CompilerSuite/optimized_ir/lists.expected | 25 ++-- tools/ark_frequent_instructions.py | 4 +- 9 files changed, 124 insertions(+), 79 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b910345d..3e3ec88d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ - `GET_FIELD_FROM_SYMBOL` and `GET_FIELD_FROM_SYMBOL_INDEX` super instructions to get a field from a closure and push it to the stack - `EQ_CONST_JUMP_IF_TRUE` and `EQ_SYM_INDEX_JUMP_IF_TRUE` to compare a symbol to a const and a symbol to a symbol (respectively), then jump to an address if true (useful for conditions that check a simple `(= x n)` condition) - `NEQ_CONST_JUMP_IF_TRUE` as a super instruction counterpart to `EQ_CONST_JUMP_IF_TRUE` +- `AT_SYM_SYM` and `AT_SYM_INDEX_SYM_INDEX` super instructions, to get an element from a list in a single instruction, avoiding 2 push and 2 pop ### Changed - instructions are on 4 bytes: 1 byte for the instruction, 1 byte of padding, 2 bytes for an immediate argument diff --git a/include/Ark/Compiler/Instructions.hpp b/include/Ark/Compiler/Instructions.hpp index 50af13ec..498f41fb 100644 --- a/include/Ark/Compiler/Instructions.hpp +++ b/include/Ark/Compiler/Instructions.hpp @@ -335,6 +335,9 @@ namespace Ark::internal // @role Push the field of a given symbol (which has to be a closure) on the stack GET_FIELD_FROM_SYMBOL_INDEX = 0x53, + AT_SYM_SYM = 0x54, + AT_SYM_INDEX_SYM_INDEX = 0x55, + InstructionsCount }; @@ -424,7 +427,9 @@ namespace Ark::internal "NEQ_CONST_JUMP_IF_TRUE", "CALL_SYMBOL", "GET_FIELD_FROM_SYMBOL", - "GET_FIELD_FROM_SYMBOL_INDEX" + "GET_FIELD_FROM_SYMBOL_INDEX", + "AT_SYM_SYM", + "AT_SYM_INDEX_SYM_INDEX" }; static_assert(InstructionNames.size() == static_cast(Instruction::InstructionsCount) && "Some instruction names appear to be missing"); diff --git a/include/Ark/VM/VM.hpp b/include/Ark/VM/VM.hpp index 34d03e8f..d54ece77 100644 --- a/include/Ark/VM/VM.hpp +++ b/include/Ark/VM/VM.hpp @@ -148,6 +148,14 @@ namespace Ark */ [[nodiscard]] bool forceReloadPlugins() const; + /** + * @brief Throw a VM error message + * + * @param kind type of VM error + * @param message + */ + [[noreturn]] static void throwVMError(internal::ErrorKind kind, const std::string& message); + friend class Value; friend class internal::Closure; friend class Repl; @@ -332,14 +340,6 @@ namespace Ark */ uint16_t findNearestVariableIdWithValue(const Value& value, internal::ExecutionContext& context) const noexcept; - /** - * @brief Throw a VM error message - * - * @param kind type of VM error - * @param message - */ - [[noreturn]] static void throwVMError(internal::ErrorKind kind, const std::string& message); - [[noreturn]] void throwArityError(std::size_t passed_arg_count, std::size_t expected_arg_count, internal::ExecutionContext& context); void showBacktraceWithException(const std::exception& e, internal::ExecutionContext& context); diff --git a/include/Ark/VM/Value.hpp b/include/Ark/VM/Value.hpp index d36d4fb4..b28def71 100644 --- a/include/Ark/VM/Value.hpp +++ b/include/Ark/VM/Value.hpp @@ -49,10 +49,20 @@ namespace Ark }; constexpr std::array types_to_str = { - "List", "Number", "String", "Function", - "CProc", "Closure", "UserType", "Nil", - "Bool", "Bool", "Undefined", "Reference", - "InstPtr" + "List", + "Number", + "String", + "Function", + "CProc", + "Closure", + "UserType", + "Nil", + "Bool", + "Bool", + "Undefined", + "Reference", + "InstPtr", + "Any" }; class ARK_API Value diff --git a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp index 0e298728..6e8df52c 100644 --- a/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp +++ b/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp @@ -120,7 +120,12 @@ namespace Ark::internal } }, Rule { { LOAD_CONST, NEQ, POP_JUMP_IF_TRUE }, [](const Entities& e) { return IR::Entity::GotoWithArg(e[2], NEQ_CONST_JUMP_IF_TRUE, e[0].primaryArg()); - } } + } }, + // LOAD_SYMBOL id + // LOAD_SYMBOL id2 + // AT + // ---> AT_SYM_SYM id id2 + Rule { { LOAD_SYMBOL, LOAD_SYMBOL, AT }, AT_SYM_SYM }, Rule { { LOAD_SYMBOL_BY_INDEX, LOAD_SYMBOL_BY_INDEX, AT }, AT_SYM_INDEX_SYM_INDEX } }; } diff --git a/src/arkreactor/VM/VM.cpp b/src/arkreactor/VM/VM.cpp index d029f769..d3d0766a 100644 --- a/src/arkreactor/VM/VM.cpp +++ b/src/arkreactor/VM/VM.cpp @@ -75,6 +75,45 @@ namespace Ark types::Contract { { types::Typedef("value", ValueType::String) } } } }, { *a }); } + + inline Value at(Value& container, Value& index, VM& vm) + { + if (index.valueType() != ValueType::Number) + throw types::TypeCheckingError( + "@", + { { types::Contract { { types::Typedef("src", ValueType::List), types::Typedef("idx", ValueType::Number) } }, + types::Contract { { types::Typedef("src", ValueType::String), types::Typedef("idx", ValueType::Number) } } } }, + { container, index }); + + const auto num = static_cast(index.number()); + + if (container.valueType() == ValueType::List) + { + const auto i = static_cast(num < 0 ? static_cast(container.list().size()) + num : num); + if (i < container.list().size()) + return container.list()[i]; + else + VM::throwVMError( + ErrorKind::Index, + fmt::format("{} out of range {} (length {})", num, container.toString(vm), container.list().size())); + } + else if (container.valueType() == ValueType::String) + { + const auto i = static_cast(num < 0 ? static_cast(container.string().size()) + num : num); + if (i < container.string().size()) + return Value(std::string(1, container.string()[i])); + else + VM::throwVMError( + ErrorKind::Index, + fmt::format("{} out of range \"{}\" (length {})", num, container.string(), container.string().size())); + } + else + throw types::TypeCheckingError( + "@", + { { types::Contract { { types::Typedef("src", ValueType::List), types::Typedef("idx", ValueType::Number) } }, + types::Contract { { types::Typedef("src", ValueType::String), types::Typedef("idx", ValueType::Number) } } } }, + { container, index }); + } } VM::VM(State& state) noexcept : @@ -367,6 +406,11 @@ namespace Ark } } + void VM::throwVMError(ErrorKind kind, const std::string& message) + { + throw std::runtime_error(std::string(errorKinds[static_cast(kind)]) + ": " + message + "\n"); + } + int VM::run(const bool fail_with_exception) { init(); @@ -496,7 +540,9 @@ namespace Ark &&TARGET_NEQ_CONST_JUMP_IF_TRUE, &&TARGET_CALL_SYMBOL, &&TARGET_GET_FIELD_FROM_SYMBOL, - &&TARGET_GET_FIELD_FROM_SYMBOL_INDEX + &&TARGET_GET_FIELD_FROM_SYMBOL_INDEX, + &&TARGET_AT_SYM_SYM, + &&TARGET_AT_SYM_INDEX_SYM_INDEX }; static_assert(opcode_targets.size() == static_cast(Instruction::InstructionsCount) && "Some instructions are not implemented in the VM"); @@ -1167,46 +1213,9 @@ namespace Ark TARGET(AT) { - { - const Value* b = popAndResolveAsPtr(context); - Value& a = *popAndResolveAsPtr(context); - - if (b->valueType() != ValueType::Number) - throw types::TypeCheckingError( - "@", - { { types::Contract { { types::Typedef("src", ValueType::List), types::Typedef("idx", ValueType::Number) } }, - types::Contract { { types::Typedef("src", ValueType::String), types::Typedef("idx", ValueType::Number) } } } }, - { a, *b }); - - const auto num = static_cast(b->number()); - - if (a.valueType() == ValueType::List) - { - const auto index = static_cast(num < 0 ? static_cast(a.list().size()) + num : num); - if (index < a.list().size()) - push(a.list()[index], context); - else - throwVMError( - ErrorKind::Index, - fmt::format("{} out of range {} (length {})", num, a.toString(*this), a.list().size())); - } - else if (a.valueType() == ValueType::String) - { - const auto index = static_cast(num < 0 ? static_cast(a.string().size()) + num : num); - if (index < a.string().size()) - push(Value(std::string(1, a.string()[index])), context); - else - throwVMError( - ErrorKind::Index, - fmt::format("{} out of range \"{}\" (length {})", num, a.string(), a.string().size())); - } - else - throw types::TypeCheckingError( - "@", - { { types::Contract { { types::Typedef("src", ValueType::List), types::Typedef("idx", ValueType::Number) } }, - types::Contract { { types::Typedef("src", ValueType::String), types::Typedef("idx", ValueType::Number) } } } }, - { a, *b }); - } + Value& b = *popAndResolveAsPtr(context); + Value& a = *popAndResolveAsPtr(context); + push(helper::at(a, b, *this), context); DISPATCH(); } @@ -1270,12 +1279,6 @@ namespace Ark TARGET(TYPE) { const Value* a = popAndResolveAsPtr(context); - if (a == &m_undefined_value) [[unlikely]] - throw types::TypeCheckingError( - "type", - { { types::Contract { { types::Typedef("value", ValueType::Any) } } } }, - {}); - push(Value(types_to_str[static_cast(a->valueType())]), context); DISPATCH(); } @@ -1613,6 +1616,20 @@ namespace Ark push(getField(loadSymbolFromIndex(primary_arg, context), secondary_arg, context), context); DISPATCH(); } + + TARGET(AT_SYM_SYM) + { + UNPACK_ARGS(); + push(helper::at(*loadSymbol(primary_arg, context), *loadSymbol(secondary_arg, context), *this), context); + DISPATCH(); + } + + TARGET(AT_SYM_INDEX_SYM_INDEX) + { + UNPACK_ARGS(); + push(helper::at(*loadSymbolFromIndex(primary_arg, context), *loadSymbolFromIndex(secondary_arg, context), *this), context); + DISPATCH(); + } #pragma endregion } #if ARK_USE_COMPUTED_GOTOS @@ -1673,11 +1690,6 @@ namespace Ark return std::numeric_limits::max(); } - void VM::throwVMError(ErrorKind kind, const std::string& message) - { - throw std::runtime_error(std::string(errorKinds[static_cast(kind)]) + ": " + message + "\n"); - } - void VM::throwArityError(std::size_t passed_arg_count, std::size_t expected_arg_count, internal::ExecutionContext& context) { std::vector arg_names; diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/lists.ark b/tests/unittests/resources/CompilerSuite/optimized_ir/lists.ark index 2bc1705b..018ed5e0 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/lists.ark +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/lists.ark @@ -1,4 +1,5 @@ (let source [1 2 3 4]) +(let n 1) (let foo (fun () { # STORE_HEAD @@ -11,7 +12,10 @@ # SET_VAL_HEAD (set copy_1 (head source)) # SET_VAL_TAIL - (set copy_1 (tail source)) })) + (set copy_1 (tail source)) + + # AT_SYM_SYM + (@ source n) })) (foo) # STORE_HEAD_BY_INDEX @@ -24,3 +28,6 @@ (set copy_2 (head source)) # SET_VAL_TAIL_BY_INDEX (set copy_2 (tail source)) + +# AT_SYM_INDEX_SYM_INDEX +(@ source n) diff --git a/tests/unittests/resources/CompilerSuite/optimized_ir/lists.expected b/tests/unittests/resources/CompilerSuite/optimized_ir/lists.expected index 90059d82..b0e7f43a 100644 --- a/tests/unittests/resources/CompilerSuite/optimized_ir/lists.expected +++ b/tests/unittests/resources/CompilerSuite/optimized_ir/lists.expected @@ -3,22 +3,25 @@ page_0 LOAD_CONST_LOAD_CONST 2, 3 LIST 4 STORE 0 - LOAD_CONST_STORE 4, 1 + LOAD_CONST_STORE 3, 1 + LOAD_CONST_STORE 4, 2 LOAD_SYMBOL_BY_INDEX 0 CALL 0 POP 0 - STORE_HEAD_BY_INDEX 1, 5 - STORE_TAIL_BY_INDEX 2, 6 - STORE_FROM_INDEX 3, 7 - SET_VAL_HEAD_BY_INDEX 4, 7 - SET_VAL_TAIL_BY_INDEX 4, 7 + STORE_HEAD_BY_INDEX 2, 6 + STORE_TAIL_BY_INDEX 3, 7 + STORE_FROM_INDEX 4, 8 + SET_VAL_HEAD_BY_INDEX 5, 8 + SET_VAL_TAIL_BY_INDEX 5, 8 + AT_SYM_INDEX_SYM_INDEX 5, 4 HALT 0 page_1 - STORE_HEAD 0, 2 - STORE_TAIL 0, 3 - STORE_FROM 0, 4 - SET_VAL_HEAD 0, 4 - SET_VAL_TAIL 0, 4 + STORE_HEAD 0, 3 + STORE_TAIL 0, 4 + STORE_FROM 0, 5 + SET_VAL_HEAD 0, 5 + SET_VAL_TAIL 0, 5 + AT_SYM_SYM 0, 1 RET 0 HALT 0 diff --git a/tools/ark_frequent_instructions.py b/tools/ark_frequent_instructions.py index 4faabeba..623a4a00 100644 --- a/tools/ark_frequent_instructions.py +++ b/tools/ark_frequent_instructions.py @@ -33,7 +33,9 @@ "NEQ_CONST_JUMP_IF_TRUE", "CALL_SYMBOL", "GET_FIELD_FROM_SYMBOL", - "GET_FIELD_FROM_SYMBOL_INDEX" + "GET_FIELD_FROM_SYMBOL_INDEX", + "AT_SYM_SYM", + "AT_SYM_INDEX_SYM_INDEX" ] executable = None