From ccba230f698bc9fed9c81b5592d58192759be868 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Fri, 9 May 2025 22:15:04 +0200 Subject: [PATCH 1/8] feat(parser, errors): improving context in parsing errors --- include/Ark/Compiler/AST/BaseParser.hpp | 11 +++++------ include/Ark/Compiler/AST/Parser.hpp | 2 +- src/arkreactor/Compiler/AST/BaseParser.cpp | 12 ++++-------- src/arkreactor/Compiler/AST/Parser.cpp | 15 +++++++-------- .../compileTime/invalid_codepoint.expected | 4 ++-- .../failure/incomplete_arguments.expected | 2 +- .../ParserSuite/failure/incomplete_begin.expected | 2 +- .../ParserSuite/failure/incomplete_call.expected | 2 +- .../ParserSuite/failure/incomplete_list.expected | 2 +- .../failure/incomplete_macro_arguments.expected | 2 +- 10 files changed, 24 insertions(+), 30 deletions(-) diff --git a/include/Ark/Compiler/AST/BaseParser.hpp b/include/Ark/Compiler/AST/BaseParser.hpp index 10abd1e03..a316e67b3 100644 --- a/include/Ark/Compiler/AST/BaseParser.hpp +++ b/include/Ark/Compiler/AST/BaseParser.hpp @@ -50,7 +50,7 @@ namespace Ark::internal void initParser(const std::string& filename, const std::string& code); - FilePosition getCursor() const; + [[nodiscard]] FilePosition getCursor() const; /** * @@ -67,12 +67,12 @@ namespace Ark::internal void errorWithNextToken(const std::string& message); /** - * @brief Generate an error for a given node when a suffix is missing + * @brief Check for a closing char or generate an error * * @param suffix a suffix char, eg " or ) - * @param node_name can be "string", "node" ; represents a structure + * @param context can be "string", "node" ; represents a structure */ - void errorMissingSuffix(char suffix, const std::string& node_name); + void expectSuffixOrError(char suffix, const std::string& context); /** * @@ -84,7 +84,7 @@ namespace Ark::internal * * @return file size in bytes */ - std::size_t getSize() const { return m_str.size(); } + [[nodiscard]] std::size_t getSize() const { return m_str.size(); } /** * @@ -119,7 +119,6 @@ namespace Ark::internal bool spaceComment(std::string* s = nullptr); bool newlineOrComment(std::string* s = nullptr); bool prefix(char c); - bool suffix(char c); bool number(std::string* s = nullptr); bool signedNumber(std::string* s = nullptr); bool hexNumber(unsigned length, std::string* s = nullptr); diff --git a/include/Ark/Compiler/AST/Parser.hpp b/include/Ark/Compiler/AST/Parser.hpp index 80c4c6d38..70bf67be1 100644 --- a/include/Ark/Compiler/AST/Parser.hpp +++ b/include/Ark/Compiler/AST/Parser.hpp @@ -184,7 +184,7 @@ namespace Ark::internal if (accept(IsChar('"'))) break; if (isEOF()) - errorMissingSuffix('"', "string"); + expectSuffixOrError('"', "after string"); } return { Node(NodeType::String, res) }; diff --git a/src/arkreactor/Compiler/AST/BaseParser.cpp b/src/arkreactor/Compiler/AST/BaseParser.cpp index daa0692b9..8d86a73b3 100644 --- a/src/arkreactor/Compiler/AST/BaseParser.cpp +++ b/src/arkreactor/Compiler/AST/BaseParser.cpp @@ -93,7 +93,7 @@ namespace Ark::internal for (std::size_t i = 0, end = m_it_to_row.size(); i < end; ++i) { auto [at, line] = m_it_to_row[i]; - if (it < at) + if (it <= at) { m_filepos.row = line - 1; break; @@ -132,9 +132,10 @@ namespace Ark::internal error(message, next_token); } - void BaseParser::errorMissingSuffix(const char suffix, const std::string& node_name) + void BaseParser::expectSuffixOrError(const char suffix, const std::string& context) { - errorWithNextToken(fmt::format("Missing '{}' after {}", suffix, node_name)); + if (!accept(IsChar(suffix))) + errorWithNextToken(fmt::format("Missing '{}' {}", suffix, context)); } bool BaseParser::accept(const CharPred& t, std::string* s) @@ -240,11 +241,6 @@ namespace Ark::internal return true; } - bool BaseParser::suffix(const char c) - { - return accept(IsChar(c)); - } - bool BaseParser::number(std::string* s) { if (accept(IsDigit, s)) diff --git a/src/arkreactor/Compiler/AST/Parser.cpp b/src/arkreactor/Compiler/AST/Parser.cpp index fa890e3d6..b8871abbd 100644 --- a/src/arkreactor/Compiler/AST/Parser.cpp +++ b/src/arkreactor/Compiler/AST/Parser.cpp @@ -337,7 +337,7 @@ namespace Ark::internal setNodePosAndFilename(leaf->list().back()); space(); - expect(IsChar(')')); + expectSuffixOrError(')', fmt::format("in import `{}'", import_data.toPackageString())); // save the import data structure to know we encounter an import node, and retrieve its data more easily later on import_data.with_prefix = false; @@ -441,7 +441,7 @@ namespace Ark::internal } newlineOrComment(&comment); - expect(IsChar(!alt_syntax ? ')' : '}')); + expectSuffixOrError(!alt_syntax ? ')' : '}', "to close block"); setNodePosAndFilename(leaf->list().back()); leaf->list().back().attachCommentAfter(comment); return leaf; @@ -731,7 +731,7 @@ namespace Ark::internal if (newlineOrComment(&comment)) leaf->list().back().attachCommentAfter(comment); - expect(IsChar(')')); + expectSuffixOrError(')', fmt::format("to close macro `{}'", symbol_name)); return leaf; } else @@ -745,7 +745,7 @@ namespace Ark::internal if (newlineOrComment(&comment)) leaf->list().back().attachCommentAfter(comment); - expect(IsChar(')')); + expectSuffixOrError(')', fmt::format("to close macro `{}'", symbol_name)); return leaf; } @@ -790,7 +790,7 @@ namespace Ark::internal if (newlineOrComment(&comment)) leaf->list().back().attachCommentAfter(comment); - expect(IsChar(')')); + expectSuffixOrError(')', fmt::format("in function call to `{}'", func.value().repr())); return leaf; } @@ -821,7 +821,7 @@ namespace Ark::internal } leaf->list().back().attachCommentAfter(comment); - expect(IsChar(']')); + expectSuffixOrError(']', "to end list definition"); return leaf; } @@ -907,8 +907,7 @@ namespace Ark::internal if (result->isListLike()) setNodePosAndFilename(result->list().back()); - if (!suffix(')')) - errorMissingSuffix(')', name); + expectSuffixOrError(')', "after " + name); comment.clear(); if (spaceComment(&comment)) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_codepoint.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_codepoint.expected index 014de3e97..02e48cf15 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_codepoint.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/invalid_codepoint.expected @@ -1,5 +1,5 @@ -At � @ 2:1 +At � @ 1:1 1 | � + | ^~~ 2 | - | ^ invalid syntax, expected node diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_arguments.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_arguments.expected index d777c3edb..daf52b051 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_arguments.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_arguments.expected @@ -2,4 +2,4 @@ In file tests/unittests/resources/ParserSuite/failure/incomplete_arguments.ark At EOF @ 1:7 1 | (fun (a | ^ - Expected ')' \ No newline at end of file + Missing ')' in function call to `a' diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_begin.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_begin.expected index d39e8011b..0cdec03c6 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_begin.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_begin.expected @@ -2,4 +2,4 @@ In file tests/unittests/resources/ParserSuite/failure/incomplete_begin.ark At EOF @ 1:15 1 | { a b (let c d) | ^ - Expected '}' \ No newline at end of file + Missing '}' to close block diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_call.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_call.expected index 2c84a1799..d22c9d93c 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_call.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_call.expected @@ -2,4 +2,4 @@ In file tests/unittests/resources/ParserSuite/failure/incomplete_call.ark At EOF @ 1:25 1 | (a b c (if (ok true) 1 2) | ^ - Expected ')' \ No newline at end of file + Missing ')' in function call to `a' diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_list.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_list.expected index b4731a759..b642833bd 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_list.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_list.expected @@ -4,4 +4,4 @@ At EOF @ 3:7 2 | 1 3 | 2 3 | ^ - Expected ']' \ No newline at end of file + Missing ']' to end list definition diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.expected index a9142902a..6a5635757 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.expected @@ -2,4 +2,4 @@ In file tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments At EOF @ 1:9 1 | ($ foo (a | ^ - Expected ')' \ No newline at end of file + Missing ')' in function call to `a' From a4b8a0d8ae6c6b03d2c2cbd14006be095876038b Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Sat, 10 May 2025 11:51:58 +0200 Subject: [PATCH 2/8] refactor(code error): CodeError now takes a context to hold the filename, line, column, expression of an error --- CHANGELOG.md | 1 + include/Ark/Exceptions.hpp | 34 +++++--- src/arkreactor/Compiler/AST/BaseParser.cpp | 2 +- .../Compiler/Lowerer/ASTLowerer.cpp | 2 +- src/arkreactor/Compiler/Macros/Processor.cpp | 2 +- .../NameResolution/NameResolutionPass.cpp | 83 ++++++++++--------- .../Compiler/Package/ImportSolver.cpp | 9 +- src/arkreactor/Exceptions.cpp | 20 ++--- tests/unittests/TestsHelper.hpp | 19 +++-- 9 files changed, 97 insertions(+), 75 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6047067f3..7df53533f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -119,6 +119,7 @@ - when possible, accessing variables from the current scope is compiled to a new instruction `LOAD_SYMBOL_BY_INDEX`, to avoid the sometimes expansive lookup by id - this works inside normal scopes (introduced by while loops) and functions scopes, but not for closures - VM stack size is now 4096 instead of 8192 +- `Ark::CodeError` now takes a `CodeErrorContext` to store the source (filename, line, column, expression) of an error ### Removed - removed unused `NodeType::Closure` diff --git a/include/Ark/Exceptions.hpp b/include/Ark/Exceptions.hpp index 5b8ac89c5..50372137d 100644 --- a/include/Ark/Exceptions.hpp +++ b/include/Ark/Exceptions.hpp @@ -12,6 +12,7 @@ #define INCLUDE_ARK_EXCEPTIONS_HPP #include +#include #include #include #include @@ -95,11 +96,7 @@ namespace Ark std::string m_details; }; - /** - * @brief CodeError thrown by the compiler (parser, macro processor, optimizer, and compiler itself) - * - */ - struct ARK_API CodeError final : Error + struct ARK_API CodeErrorContext final { const std::string filename; const std::size_t line; @@ -107,15 +104,26 @@ namespace Ark const std::string expr; const std::optional symbol; - CodeError( - const std::string& what, - std::string filename_, - const std::size_t lineNum, - const std::size_t column, - std::string exp, - const std::optional opt_sym = std::nullopt) : + CodeErrorContext(std::string filename_, const std::size_t lineNum, const std::size_t column, std::string expression, const std::optional maybe_symbol = std::nullopt) : + filename(std::move(filename_)), + line(lineNum), + col(column), + expr(std::move(expression)), + symbol(maybe_symbol) + {} + }; + + /** + * @brief CodeError thrown by the compiler (parser, macro processor, optimizer, and compiler itself) + * + */ + struct ARK_API CodeError final : Error + { + const CodeErrorContext context; + + CodeError(const std::string& what, CodeErrorContext ctx) : Error(what), - filename(std::move(filename_)), line(lineNum), col(column), expr(std::move(exp)), symbol(opt_sym) + context(std::move(ctx)) {} }; diff --git a/src/arkreactor/Compiler/AST/BaseParser.cpp b/src/arkreactor/Compiler/AST/BaseParser.cpp index 8d86a73b3..aaeee2df2 100644 --- a/src/arkreactor/Compiler/AST/BaseParser.cpp +++ b/src/arkreactor/Compiler/AST/BaseParser.cpp @@ -118,7 +118,7 @@ namespace Ark::internal void BaseParser::error(const std::string& error, std::string exp) { const auto [row, col] = getCursor(); - throw CodeError(error, m_filename, row, col, std::move(exp), m_sym); + throw CodeError(error, CodeErrorContext(m_filename, row, col, std::move(exp), m_sym)); } void BaseParser::errorWithNextToken(const std::string& message) diff --git a/src/arkreactor/Compiler/Lowerer/ASTLowerer.cpp b/src/arkreactor/Compiler/Lowerer/ASTLowerer.cpp index 4d8424294..26540c0b2 100644 --- a/src/arkreactor/Compiler/Lowerer/ASTLowerer.cpp +++ b/src/arkreactor/Compiler/Lowerer/ASTLowerer.cpp @@ -121,7 +121,7 @@ namespace Ark::internal void ASTLowerer::buildAndThrowError(const std::string& message, const Node& node) { - throw CodeError(message, node.filename(), node.line(), node.col(), node.repr()); + throw CodeError(message, CodeErrorContext(node.filename(), node.line(), node.col(), node.repr())); } void ASTLowerer::compileExpression(const Node& x, const Page p, const bool is_result_unused, const bool is_terminal, const std::string& var_name) diff --git a/src/arkreactor/Compiler/Macros/Processor.cpp b/src/arkreactor/Compiler/Macros/Processor.cpp index fa3139b07..0a4fe8a70 100644 --- a/src/arkreactor/Compiler/Macros/Processor.cpp +++ b/src/arkreactor/Compiler/Macros/Processor.cpp @@ -735,6 +735,6 @@ namespace Ark::internal void MacroProcessor::throwMacroProcessingError(const std::string& message, const Node& node) { - throw CodeError(message, node.filename(), node.line(), node.col(), node.repr()); + throw CodeError(message, CodeErrorContext(node.filename(), node.line(), node.col(), node.repr())); } } diff --git a/src/arkreactor/Compiler/NameResolution/NameResolutionPass.cpp b/src/arkreactor/Compiler/NameResolution/NameResolutionPass.cpp index 06af0b854..544c3ff11 100644 --- a/src/arkreactor/Compiler/NameResolution/NameResolutionPass.cpp +++ b/src/arkreactor/Compiler/NameResolution/NameResolutionPass.cpp @@ -93,10 +93,11 @@ namespace Ark::internal if (std::ranges::find(Language::UpdateRef, funcname) != Language::UpdateRef.end() && m_scope_resolver.isImmutable(arg).value_or(false)) throw CodeError( fmt::format("MutabilityError: Can not modify the constant list `{}' using `{}'", arg, funcname), - node.filename(), - node.constList()[1].line(), - node.constList()[1].col(), - arg); + CodeErrorContext( + node.filename(), + node.constList()[1].line(), + node.constList()[1].col(), + arg)); // check that we aren't doing a (append! a a) nor a (concat! a a) if (funcname == Language::AppendInPlace || funcname == Language::ConcatInPlace) @@ -106,10 +107,11 @@ namespace Ark::internal if (node.constList()[i].nodeType() == NodeType::Symbol && node.constList()[i].string() == arg) throw CodeError( fmt::format("MutabilityError: Can not {} the list `{}' to itself", funcname, arg), - node.filename(), - node.constList()[1].line(), - node.constList()[1].col(), - arg); + CodeErrorContext( + node.filename(), + node.constList()[1].line(), + node.constList()[1].col(), + arg)); } } } @@ -141,10 +143,11 @@ namespace Ark::internal if (!scope->get(sym, true).has_value()) throw CodeError( fmt::format("ImportError: Can not import symbol {} from {}, as it isn't in the package", sym, namespace_.name), - namespace_.ast->filename(), - namespace_.ast->line(), - namespace_.ast->col(), - "import"); + CodeErrorContext( + namespace_.ast->filename(), + namespace_.ast->line(), + namespace_.ast->col(), + "import")); } } @@ -176,27 +179,30 @@ namespace Ark::internal if (m_language_symbols.contains(name) && register_declarations) throw CodeError( fmt::format("Can not use a reserved identifier ('{}') as a {} name.", name, keyword == Keyword::Let ? "constant" : "variable"), - node.filename(), - node.constList()[1].line(), - node.constList()[1].col(), - name); + CodeErrorContext( + node.filename(), + node.constList()[1].line(), + node.constList()[1].col(), + name)); if (m_scope_resolver.isInScope(name) && keyword == Keyword::Let && register_declarations) throw CodeError( fmt::format("MutabilityError: Can not use 'let' to redefine variable `{}'", name), - node.filename(), - node.constList()[1].line(), - node.constList()[1].col(), - name); + CodeErrorContext( + node.filename(), + node.constList()[1].line(), + node.constList()[1].col(), + name)); if (keyword == Keyword::Set && m_scope_resolver.isRegistered(name)) { if (m_scope_resolver.isImmutable(name).value_or(false) && register_declarations) throw CodeError( fmt::format("MutabilityError: Can not set the constant `{}' to {}", name, node.constList()[2].repr()), - node.filename(), - node.constList()[1].line(), - node.constList()[1].col(), - name); + CodeErrorContext( + node.filename(), + node.constList()[1].line(), + node.constList()[1].col(), + name)); updateSymbolWithFullyQualifiedName(node.list()[1]); } @@ -238,10 +244,11 @@ namespace Ark::internal if (!m_scope_resolver.isRegistered(child.string()) && register_declarations) throw CodeError( fmt::format("Can not capture {} because it is referencing a variable defined in an unreachable scope.", child.string()), - child.filename(), - child.line(), - child.col(), - child.repr()); + CodeErrorContext( + child.filename(), + child.line(), + child.col(), + child.repr())); // update the declared variable name to use the fully qualified name // this will prevent name conflicts, and handle scope resolution @@ -318,10 +325,11 @@ namespace Ark::internal fmt::format( "Symbol `{}' was resolved to `{}', which is also a builtin name. Either the symbol or the package it's in needs to be renamed to avoid conflicting with the builtin.", symbol.string(), fqn), - symbol.filename(), - symbol.line(), - symbol.col(), - symbol.repr()); + CodeErrorContext( + symbol.filename(), + symbol.line(), + symbol.col(), + symbol.repr())); } if (!allowed) { @@ -339,10 +347,11 @@ namespace Ark::internal throw CodeError( message, - symbol.filename(), - symbol.line(), - symbol.col(), - symbol.repr()); + CodeErrorContext( + symbol.filename(), + symbol.line(), + symbol.col(), + symbol.repr())); } symbol.setString(fqn); @@ -374,7 +383,7 @@ namespace Ark::internal message = fmt::format(R"(Unbound variable error "{}" (did you mean "{}"?{}))", str, suggestion, add_note ? note_about_prefix : ""); } - throw CodeError(message, sym.filename(), sym.line(), sym.col(), sym.repr()); + throw CodeError(message, CodeErrorContext(sym.filename(), sym.line(), sym.col(), sym.repr())); } } } diff --git a/src/arkreactor/Compiler/Package/ImportSolver.cpp b/src/arkreactor/Compiler/Package/ImportSolver.cpp index 244169476..db0ac679b 100644 --- a/src/arkreactor/Compiler/Package/ImportSolver.cpp +++ b/src/arkreactor/Compiler/Package/ImportSolver.cpp @@ -206,9 +206,10 @@ namespace Ark::internal throw CodeError( fmt::format("While processing file {}, couldn't import {}: file not found", file.generic_string(), import.toPackageString()), - file.generic_string(), - import.line, - import.col, - fmt::format("(import {})", import.toPackageString())); + CodeErrorContext( + file.generic_string(), + import.line, + import.col, + fmt::format("(import {})", import.toPackageString()))); } } diff --git a/src/arkreactor/Exceptions.cpp b/src/arkreactor/Exceptions.cpp index 39985acd4..8e8f7f22d 100644 --- a/src/arkreactor/Exceptions.cpp +++ b/src/arkreactor/Exceptions.cpp @@ -194,9 +194,9 @@ namespace Ark::Diagnostics colorize = false; std::string escaped_symbol; - if (e.symbol.has_value()) + if (e.context.symbol.has_value()) { - switch (e.symbol.value().codepoint()) + switch (e.context.symbol.value().codepoint()) { case '\n': escaped_symbol = "'\\n'"; break; case '\r': escaped_symbol = "'\\r'"; break; @@ -205,25 +205,25 @@ namespace Ark::Diagnostics case '\0': escaped_symbol = "EOF"; break; case ' ': escaped_symbol = "' '"; break; default: - escaped_symbol = e.symbol.value().c_str(); + escaped_symbol = e.context.symbol.value().c_str(); } } else - escaped_symbol = e.expr; + escaped_symbol = e.context.expr; std::string file_content; - if (e.filename != ARK_NO_NAME_FILE) - file_content = Utils::readFile(e.filename); + if (e.context.filename != ARK_NO_NAME_FILE) + file_content = Utils::readFile(e.context.filename); helper( os, e.what(), colorize, - e.filename, + e.context.filename, file_content, escaped_symbol, - e.line, - e.col, - e.expr.size()); + e.context.line, + e.context.col, + e.context.expr.size()); } } diff --git a/tests/unittests/TestsHelper.hpp b/tests/unittests/TestsHelper.hpp index 828d0f180..b8d13855f 100644 --- a/tests/unittests/TestsHelper.hpp +++ b/tests/unittests/TestsHelper.hpp @@ -38,7 +38,7 @@ struct IterTestFilesParam * @brief Iterate over the files inside a folder, looking for "name.ark" & "name.expected" files to create a TestData structure * @param folder folder to list files in * @param test test function, taking a TestData&& with the paths of the input and its expected result - * @param expected_ext optionally specify the expected extension. Defaults to "expected" + * @param params optionally specify the expected extension. Defaults to "expected" */ void iterTestFiles(const std::string& folder, std::function&& test, IterTestFilesParam&& params = {}); @@ -56,9 +56,11 @@ std::string getResourcePath(const std::string& folder); */ inline std::string& ltrim(std::string& s) { - s.erase(s.begin(), std::ranges::find_if(s, [](const unsigned char ch) { - return !std::isspace(ch); - })); + s.erase( + s.begin(), + std::ranges::find_if(s.begin(), s.end(), [](const unsigned char ch) { + return !std::isspace(ch); + })); return s; } @@ -69,10 +71,11 @@ inline std::string& ltrim(std::string& s) */ inline std::string& rtrim(std::string& s) { - s.erase(std::ranges::find_if(s.rbegin(), s.rend(), [](const unsigned char ch) { - return !std::isspace(ch); - }).base(), - s.end()); + s.erase( + std::ranges::find_if(s.rbegin(), s.rend(), [](const unsigned char ch) { + return !std::isspace(ch); + }).base(), + s.end()); return s; } From 0fe5f00bc551e248f2b07bfcce631684ceb40ac8 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Sat, 10 May 2025 13:39:34 +0200 Subject: [PATCH 3/8] feat(parser): adding optional source context for errors --- include/Ark/Compiler/AST/BaseParser.hpp | 17 +++++++++++--- include/Ark/Exceptions.hpp | 6 +++-- src/arkreactor/Compiler/AST/BaseParser.cpp | 27 +++++++++++++++++----- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/include/Ark/Compiler/AST/BaseParser.hpp b/include/Ark/Compiler/AST/BaseParser.hpp index a316e67b3..57a731759 100644 --- a/include/Ark/Compiler/AST/BaseParser.hpp +++ b/include/Ark/Compiler/AST/BaseParser.hpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -52,27 +53,32 @@ namespace Ark::internal [[nodiscard]] FilePosition getCursor() const; + [[nodiscard]] CodeErrorContext generateErrorContext(const std::string& expr); + /** * * @param error an error message * @param exp the expression causing the error + * @param additional_context optional context created when a node is being parsed */ - void error(const std::string& error, std::string exp); + void error(const std::string& error, std::string exp, const std::optional& additional_context = std::nullopt); /** * @brief Fetch the next token (space and paren delimited) to generate an error * * @param message an error message + * @param additional_context optional context created when a node is being parsed */ - void errorWithNextToken(const std::string& message); + void errorWithNextToken(const std::string& message, const std::optional& additional_context = std::nullopt); /** * @brief Check for a closing char or generate an error * * @param suffix a suffix char, eg " or ) * @param context can be "string", "node" ; represents a structure + * @param additional_context optional context created when a node is being parsed */ - void expectSuffixOrError(char suffix, const std::string& context); + void expectSuffixOrError(char suffix, const std::string& context, const std::optional& additional_context = std::nullopt); /** * @@ -92,6 +98,11 @@ namespace Ark::internal */ [[nodiscard]] bool isEOF() const { return m_it == m_str.end(); } + /** + * @brief Backtrack to a given position (this is NOT an offset!) + * + * @param n position in the source file (byte number) + */ void backtrack(long n); /** diff --git a/include/Ark/Exceptions.hpp b/include/Ark/Exceptions.hpp index 50372137d..056940467 100644 --- a/include/Ark/Exceptions.hpp +++ b/include/Ark/Exceptions.hpp @@ -120,10 +120,12 @@ namespace Ark struct ARK_API CodeError final : Error { const CodeErrorContext context; + const std::optional additional_context; - CodeError(const std::string& what, CodeErrorContext ctx) : + CodeError(const std::string& what, CodeErrorContext ctx, std::optional maybe_more_context = std::nullopt) : Error(what), - context(std::move(ctx)) + context(std::move(ctx)), + additional_context(std::move(maybe_more_context)) {} }; diff --git a/src/arkreactor/Compiler/AST/BaseParser.cpp b/src/arkreactor/Compiler/AST/BaseParser.cpp index aaeee2df2..a4c2b7518 100644 --- a/src/arkreactor/Compiler/AST/BaseParser.cpp +++ b/src/arkreactor/Compiler/AST/BaseParser.cpp @@ -115,13 +115,28 @@ namespace Ark::internal return m_filepos; } - void BaseParser::error(const std::string& error, std::string exp) + CodeErrorContext BaseParser::generateErrorContext(const std::string& expr) { const auto [row, col] = getCursor(); - throw CodeError(error, CodeErrorContext(m_filename, row, col, std::move(exp), m_sym)); + + return CodeErrorContext( + m_filename, + row, + col, + expr, + m_sym); + } + + void BaseParser::error(const std::string& error, std::string exp, const std::optional& additional_context) + { + const auto [row, col] = getCursor(); + throw CodeError( + error, + CodeErrorContext(m_filename, row, col, std::move(exp), m_sym), + additional_context); } - void BaseParser::errorWithNextToken(const std::string& message) + void BaseParser::errorWithNextToken(const std::string& message, const std::optional& additional_context) { const auto pos = getCount(); std::string next_token; @@ -129,13 +144,13 @@ namespace Ark::internal anyUntil(IsEither(IsInlineSpace, IsEither(IsChar('('), IsChar(')'))), &next_token); backtrack(pos); - error(message, next_token); + error(message, next_token, additional_context); } - void BaseParser::expectSuffixOrError(const char suffix, const std::string& context) + void BaseParser::expectSuffixOrError(const char suffix, const std::string& context, const std::optional& additional_context) { if (!accept(IsChar(suffix))) - errorWithNextToken(fmt::format("Missing '{}' {}", suffix, context)); + errorWithNextToken(fmt::format("Missing '{}' {}", suffix, context), additional_context); } bool BaseParser::accept(const CharPred& t, std::string* s) From a076be9f299c5ed03993542680896ad82138ff42 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Sun, 11 May 2025 15:20:19 +0200 Subject: [PATCH 4/8] feat(error, parser): showing the error parent to help understand errors --- include/Ark/Compiler/AST/BaseParser.hpp | 6 +- include/Ark/Exceptions.hpp | 17 +- src/arkreactor/Compiler/AST/Parser.cpp | 25 +- src/arkreactor/Exceptions.cpp | 217 ++++++++++++++---- src/arkreactor/VM/VM.cpp | 8 +- .../runtime/arity_error_async.expected | 2 +- .../runtime/at_at_eq_out_of_range_x.expected | 2 +- .../runtime/at_at_eq_out_of_range_y.expected | 2 +- .../runtime/at_at_inner_out_of_range.expected | 2 +- .../runtime/at_at_out_of_range.expected | 2 +- .../runtime/at_eq_out_of_range.expected | 2 +- .../runtime/at_out_of_range.expected | 2 +- .../runtime/at_str_out_of_range.expected | 2 +- .../runtime/closure_field_wrong_fqn.expected | 2 +- .../DiagnosticsSuite/runtime/db0.expected | 2 +- .../runtime/del_unbound.expected | 2 +- .../runtime/fmt_arg_not_found.expected | 2 +- .../runtime/list_set_at.expected | 2 +- .../runtime/list_slice_end_start.expected | 2 +- .../runtime/list_slice_past_end.expected | 2 +- .../runtime/list_slice_start_less_0.expected | 2 +- .../runtime/list_slice_step_null.expected | 2 +- .../runtime/mathln_out_of_range.expected | 2 +- .../runtime/nil_not_a_function.expected | 2 +- .../runtime/not_a_closure.expected | 2 +- .../runtime/not_callable.expected | 2 +- .../runtime/not_callable_with_args.expected | 2 +- .../runtime/not_enough_args.expected | 2 +- .../runtime/out_of_range_in_place.expected | 2 +- .../runtime/pop_out_of_range.expected | 2 +- .../runtime/recursion_depth.expected | 2 +- .../runtime/set_unbound.expected | 2 +- .../runtime/str_remove_out_of_bound.expected | 2 +- .../runtime/string_set_at.expected | 2 +- .../runtime/too_many_args.expected | 2 +- .../runtime/unbound_var.expected | 2 +- .../runtime/unknown_field.expected | 2 +- .../typeChecking/add_num_str.expected | 2 +- .../append_in_place_num_num.expected | 2 +- .../typeChecking/append_num_num.expected | 2 +- .../typeChecking/assert_num_num.expected | 2 +- .../at_at_eq_list_num_num_num.expected | 2 +- .../at_at_eq_num_num_num_num.expected | 2 +- .../typeChecking/at_at_num_num_num.expected | 2 +- .../typeChecking/at_eq_num_num_num.expected | 2 +- .../typeChecking/at_list_str.expected | 2 +- .../typeChecking/at_num_num.expected | 2 +- .../typeChecking/await_num.expected | 2 +- .../concat_in_place_list_num.expected | 2 +- .../concat_in_place_num_num.expected | 2 +- .../typeChecking/concat_list_num.expected | 2 +- .../typeChecking/concat_num_num.expected | 2 +- .../typeChecking/decrement_str_num.expected | 2 +- .../typeChecking/div_str_num.expected | 2 +- .../typeChecking/empty_num.expected | 2 +- .../typeChecking/hasfield_num_str.expected | 2 +- .../typeChecking/head_num.expected | 2 +- .../typeChecking/increment_str_num.expected | 2 +- .../ioappendtofile_num_num.expected | 2 +- .../typeChecking/iodir_num.expected | 2 +- .../typeChecking/iofileexists_num.expected | 2 +- .../typeChecking/iolistfiles_num.expected | 2 +- .../typeChecking/iomakedir_num.expected | 2 +- .../ioreadfile_inexistent.expected | 2 +- .../typeChecking/ioreadfile_num.expected | 2 +- .../typeChecking/ioremovefiles_num.expected | 2 +- .../ioremovefiles_str_num.expected | 2 +- .../typeChecking/iowritefile_num_num.expected | 2 +- .../typeChecking/len_num.expected | 2 +- .../typeChecking/listfill_str.expected | 2 +- .../typeChecking/listfind_str_num.expected | 2 +- .../typeChecking/listreverse_str.expected | 2 +- .../typeChecking/listsetat_str.expected | 2 +- .../listslice_str_num_bool_nil.expected | 2 +- .../typeChecking/listsort_str.expected | 2 +- .../typeChecking/mathacosh_str.expected | 2 +- .../typeChecking/matharccos_str.expected | 2 +- .../typeChecking/matharcsin_str.expected | 2 +- .../typeChecking/matharctan_str.expected | 2 +- .../typeChecking/mathasinh_str.expected | 2 +- .../typeChecking/mathatanh_str.expected | 2 +- .../typeChecking/mathceil_str.expected | 2 +- .../typeChecking/mathcos_str.expected | 2 +- .../typeChecking/mathcosh_str.expected | 2 +- .../typeChecking/mathexp_str.expected | 2 +- .../typeChecking/mathfloor_str.expected | 2 +- .../typeChecking/mathln_str.expected | 2 +- .../typeChecking/mathround_str.expected | 2 +- .../typeChecking/mathsin_str.expected | 2 +- .../typeChecking/mathsinh_str.expected | 2 +- .../typeChecking/mathtan_str.expected | 2 +- .../typeChecking/mathtanh_str.expected | 2 +- .../typeChecking/mod_str_str.expected | 2 +- .../typeChecking/mul_str_num.expected | 2 +- .../pop_in_place_num_num.expected | 2 +- .../typeChecking/pop_num_num.expected | 2 +- .../typeChecking/random_str_str.expected | 2 +- .../typeChecking/stringchr_str.expected | 2 +- .../typeChecking/stringfind_num.expected | 2 +- .../typeChecking/stringformat_num.expected | 2 +- .../typeChecking/stringord_num.expected | 2 +- .../typeChecking/stringremoveat_num.expected | 2 +- .../typeChecking/stringsetat_str.expected | 2 +- .../typeChecking/sub_str_str.expected | 2 +- .../typeChecking/syssleep_str.expected | 2 +- .../typeChecking/tail_num.expected | 2 +- .../typeChecking/tonumber_num.expected | 2 +- .../ParserSuite/failure/huge_number.expected | 4 +- .../failure/incomplete_arguments.expected | 6 +- .../failure/incomplete_begin.expected | 6 +- .../failure/incomplete_call.expected | 6 +- .../ParserSuite/failure/incomplete_call_2.ark | 9 + .../failure/incomplete_call_2.expected | 13 ++ .../failure/incomplete_del.expected | 4 +- .../failure/incomplete_fun.expected | 4 +- .../failure/incomplete_if.expected | 5 +- .../failure/incomplete_import_1.expected | 4 +- .../failure/incomplete_import_2.expected | 4 +- .../failure/incomplete_let.expected | 4 +- .../failure/incomplete_list.expected | 3 +- .../failure/incomplete_macro.expected | 4 +- .../incomplete_macro_arguments.expected | 6 +- .../failure/incomplete_macro_spread.expected | 4 +- .../failure/incomplete_package_name.expected | 4 +- .../failure/incomplete_string.expected | 4 +- .../failure/incorrect_arg_capture.expected | 4 +- .../failure/incorrect_escape_seq.expected | 4 +- .../failure/incorrect_import.expected | 4 +- .../ParserSuite/failure/invalid.expected | 4 +- 129 files changed, 382 insertions(+), 205 deletions(-) create mode 100644 tests/unittests/resources/ParserSuite/failure/incomplete_call_2.ark create mode 100644 tests/unittests/resources/ParserSuite/failure/incomplete_call_2.expected diff --git a/include/Ark/Compiler/AST/BaseParser.hpp b/include/Ark/Compiler/AST/BaseParser.hpp index 57a731759..363690981 100644 --- a/include/Ark/Compiler/AST/BaseParser.hpp +++ b/include/Ark/Compiler/AST/BaseParser.hpp @@ -1,5 +1,5 @@ -#ifndef SRC_BASEPARSER_HPP -#define SRC_BASEPARSER_HPP +#ifndef ARK_COMPILER_AST_BASEPARSER_HPP +#define ARK_COMPILER_AST_BASEPARSER_HPP #include #include @@ -157,4 +157,4 @@ namespace Ark::internal }; } -#endif +#endif // ARK_COMPILER_AST_BASEPARSER_HPP diff --git a/include/Ark/Exceptions.hpp b/include/Ark/Exceptions.hpp index 056940467..7cbc72d42 100644 --- a/include/Ark/Exceptions.hpp +++ b/include/Ark/Exceptions.hpp @@ -135,14 +135,25 @@ namespace Ark * @brief Helper to create a colorized context to report errors to the user * * @param os stream in which the error will be written - * @param code content of the source file where the error is + * @param filename path to the file in which the error is + * @param expr optional expression causing the error + * @param sym_size length of expression to underline (can be 0) * @param target_line line where the error is * @param col_start where the error starts on the given line - * @param sym_size bad expression that triggered the error + * @param maybe_context optional context, parent of the error * @param whole_line when true, underline the whole line, disregarding col_start and sym_size * @param colorize generate colors or not */ - ARK_API void makeContext(std::ostream& os, const std::string& code, std::size_t target_line, std::size_t col_start, std::size_t sym_size, bool whole_line, bool colorize); + ARK_API void makeContext( + std::ostream& os, + const std::string& filename, + const std::optional& expr, + std::size_t sym_size, + std::size_t target_line, + std::size_t col_start, + const std::optional& maybe_context, + bool whole_line, + bool colorize); /** * @brief Helper used by the compiler to generate a colorized context from a node diff --git a/src/arkreactor/Compiler/AST/Parser.cpp b/src/arkreactor/Compiler/AST/Parser.cpp index b8871abbd..927acb5fb 100644 --- a/src/arkreactor/Compiler/AST/Parser.cpp +++ b/src/arkreactor/Compiler/AST/Parser.cpp @@ -274,8 +274,10 @@ namespace Ark::internal std::optional leaf { NodeType::List }; setNodePosAndFilename(leaf.value()); + auto context = generateErrorContext("("); if (!accept(IsChar('('))) return std::nullopt; + std::string comment; newlineOrComment(&comment); leaf->attachNearestCommentBefore(comment); @@ -337,7 +339,7 @@ namespace Ark::internal setNodePosAndFilename(leaf->list().back()); space(); - expectSuffixOrError(')', fmt::format("in import `{}'", import_data.toPackageString())); + expectSuffixOrError(')', fmt::format("in import `{}'", import_data.toPackageString()), context); // save the import data structure to know we encounter an import node, and retrieve its data more easily later on import_data.with_prefix = false; @@ -401,7 +403,7 @@ namespace Ark::internal if (newlineOrComment(&comment)) leaf->list().back().attachCommentAfter(comment); - expect(IsChar(')')); + expectSuffixOrError(')', fmt::format("in import `{}'", import_data.toPackageString()), context); return leaf; } @@ -410,6 +412,7 @@ namespace Ark::internal std::optional leaf { NodeType::List }; setNodePosAndFilename(leaf.value()); + auto context = generateErrorContext("("); bool alt_syntax = false; std::string comment; if (accept(IsChar('('))) @@ -441,7 +444,7 @@ namespace Ark::internal } newlineOrComment(&comment); - expectSuffixOrError(!alt_syntax ? ')' : '}', "to close block"); + expectSuffixOrError(alt_syntax ? '}' : ')', "to close block", context); setNodePosAndFilename(leaf->list().back()); leaf->list().back().attachCommentAfter(comment); return leaf; @@ -679,6 +682,7 @@ namespace Ark::internal std::optional leaf { NodeType::Macro }; setNodePosAndFilename(leaf.value()); + auto context = generateErrorContext("("); if (!accept(IsChar('('))) return std::nullopt; std::string comment; @@ -731,13 +735,13 @@ namespace Ark::internal if (newlineOrComment(&comment)) leaf->list().back().attachCommentAfter(comment); - expectSuffixOrError(')', fmt::format("to close macro `{}'", symbol_name)); + expectSuffixOrError(')', fmt::format("to close macro `{}'", symbol_name), context); return leaf; } else { backtrack(position); - errorWithNextToken(fmt::format("Expected a value while defining macro `{}'", symbol_name)); + errorWithNextToken(fmt::format("Expected a value while defining macro `{}'", symbol_name), context); } setNodePosAndFilename(leaf->list().back()); @@ -745,12 +749,13 @@ namespace Ark::internal if (newlineOrComment(&comment)) leaf->list().back().attachCommentAfter(comment); - expectSuffixOrError(')', fmt::format("to close macro `{}'", symbol_name)); + expectSuffixOrError(')', fmt::format("to close macro `{}'", symbol_name), context); return leaf; } std::optional Parser::functionCall() { + auto context = generateErrorContext("("); if (!accept(IsChar('('))) return std::nullopt; std::string comment; @@ -790,7 +795,7 @@ namespace Ark::internal if (newlineOrComment(&comment)) leaf->list().back().attachCommentAfter(comment); - expectSuffixOrError(')', fmt::format("in function call to `{}'", func.value().repr())); + expectSuffixOrError(')', fmt::format("in function call to `{}'", func.value().repr()), context); return leaf; } @@ -799,6 +804,7 @@ namespace Ark::internal std::optional leaf { NodeType::List }; setNodePosAndFilename(leaf.value()); + auto context = generateErrorContext("["); if (!accept(IsChar('['))) return std::nullopt; leaf->push_back(Node(NodeType::Symbol, "list")); @@ -821,7 +827,7 @@ namespace Ark::internal } leaf->list().back().attachCommentAfter(comment); - expectSuffixOrError(']', "to end list definition"); + expectSuffixOrError(']', "to end list definition", context); return leaf; } @@ -891,6 +897,7 @@ namespace Ark::internal std::optional Parser::wrapped(std::optional (Parser::*parser)(), const std::string& name) { auto cursor = getCursor(); + auto context = generateErrorContext("("); if (!prefix('(')) return std::nullopt; std::string comment; @@ -907,7 +914,7 @@ namespace Ark::internal if (result->isListLike()) setNodePosAndFilename(result->list().back()); - expectSuffixOrError(')', "after " + name); + expectSuffixOrError(')', "after " + name, context); comment.clear(); if (spaceComment(&comment)) diff --git a/src/arkreactor/Exceptions.cpp b/src/arkreactor/Exceptions.cpp index 8e8f7f22d..71b69fe92 100644 --- a/src/arkreactor/Exceptions.cpp +++ b/src/arkreactor/Exceptions.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -83,57 +84,191 @@ namespace Ark::Diagnostics } } - void makeContext(std::ostream& os, const std::string& code, const std::size_t target_line, const std::size_t col_start, const std::size_t sym_size, const bool whole_line, const bool colorize) + void makeContext( + std::ostream& os, + const std::string& filename, + const std::optional& expr, + const std::size_t sym_size, + const std::size_t target_line, + const std::size_t col_start, + const std::optional& maybe_context, // can not be populated at runtime, only compile time + const bool whole_line, + const bool colorize) { + assert(!(maybe_context && whole_line) && "Can not create error context when a context is given AND the whole line has to be underlined"); + using namespace Ark::literals; - const std::vector ctx = Utils::splitString(code, '\n'); - if (target_line >= ctx.size()) + auto show_file_location = [&] { + if (filename != ARK_NO_NAME_FILE) + fmt::print(os, "In file {}:{}\n", filename, target_line + 1); + if (expr) + fmt::print(os, "At {} @ {}:{}\n", expr.value(), target_line + 1, col_start); + }; + + auto compute_start_end_window = [](const std::size_t center_of_window, const std::size_t line_count) { + std::size_t start = center_of_window >= 3 ? center_of_window - 3 : 0; + std::size_t end = center_of_window + 3 <= line_count ? center_of_window + 3 : line_count; + return std::make_pair(start, end); + }; + + auto print_line = [&os, colorize](const std::size_t i, const std::vector& lines, LineColorContextCounts& color_context) { + // show current line with its number + fmt::print(os, "{: >5} |{}", i + 1, !lines[i].empty() ? " " : ""); + if (colorize) + colorizeLine(lines[i], color_context, os); + else + fmt::print(os, "{}", lines[i]); + fmt::print(os, "\n"); + }; + + const std::string line_no_num = " |"; + + auto print_context_hint = [&os, &maybe_context, &line_no_num, colorize]() mutable { + if (!maybe_context) + return; + + fmt::print(os, "{}", line_no_num); + fmt::print( + os, + "{: <{}}{}\n", + // padding os spaces + " ", + std::max(1_z, maybe_context->col), // fixing padding when the error is on the first character + // underline the parent of the error in red + fmt::styled("^ expression started here", colorize ? fmt::fg(fmt::color::red) : fmt::text_style())); + }; + + const std::string code = filename == ARK_NO_NAME_FILE ? "" : Utils::readFile(filename); + const std::vector lines = Utils::splitString(code, '\n'); + if (target_line >= lines.size() || code.empty()) + { + // show the "in file..." before early return + show_file_location(); return; + } - const std::size_t first_line = target_line >= 3 ? target_line - 3 : 0; - const std::size_t last_line = (target_line + 3) <= ctx.size() ? target_line + 3 : ctx.size(); - std::size_t overflow = (col_start + sym_size < ctx[target_line].size()) ? 0 : col_start + sym_size - ctx[target_line].size(); // number of characters that are on more lines below - LineColorContextCounts line_color_context_counts; + auto [first_line, last_line] = compute_start_end_window(target_line, lines.size()); + // number of characters that are on more lines below + std::size_t overflow = (col_start + sym_size < lines[target_line].size()) ? 0 : col_start + sym_size - lines[target_line].size(); - for (auto i = first_line; i < last_line; ++i) + const bool ctx_same_file = maybe_context && maybe_context->filename == filename; + const bool ctx_in_window = ctx_same_file && maybe_context && + maybe_context->line >= first_line && + maybe_context->line < last_line; + + std::size_t start_line_skipping_at = 0; + std::size_t stop_line_skipping_at = first_line; + if (ctx_same_file && !ctx_in_window) { - fmt::print(os, "{: >5} |{}", i + 1, !ctx[i].empty() ? " " : ""); - if (colorize) - colorizeLine(ctx[i], line_color_context_counts, os); + // showing the context will require an ellipsis, to avoid showing too many lines in the error message + if (maybe_context->line + 3 < first_line) + start_line_skipping_at = maybe_context->line + 3; else - fmt::print(os, "{}", ctx[i]); + stop_line_skipping_at = start_line_skipping_at; + + // due to how context works, if it points to the same file, + // we are guaranteed it will be before our error + first_line = maybe_context->line >= 3 ? maybe_context->line - 3 : 0; + } + else if (maybe_context && !ctx_same_file && !maybe_context->filename.empty()) + { + // show the location of the parent of our error first + fmt::print(os, "Error originated from file {}:{}\n", maybe_context->filename, maybe_context->line + 1); + + const std::vector ctx_source_lines = Utils::splitString(Utils::readFile(maybe_context->filename), '\n'); + auto [ctx_first_line, ctx_last_line] = compute_start_end_window(maybe_context->line, ctx_source_lines.size()); + LineColorContextCounts line_color_context_counts; + + for (auto i = ctx_first_line; i < ctx_last_line; ++i) + { + print_line(i, ctx_source_lines, line_color_context_counts); + if (i == maybe_context->line) + print_context_hint(); + } + fmt::print(os, "\n"); + } + + show_file_location(); + LineColorContextCounts line_color_context_counts; + + for (auto i = first_line; i < last_line; ++i) + { + if (i >= start_line_skipping_at && i < stop_line_skipping_at) + continue; + print_line(i, lines, line_color_context_counts); + // if the error context is in the current file, point to it as the parent of our error + if (maybe_context && i == maybe_context->line && i != target_line) + print_context_hint(); + + // if the next line number wants us to skip line, and start != stop (meaning they got adjusted), + // display an ellipsis + if (i + 1 == start_line_skipping_at && i + 1 != stop_line_skipping_at) + fmt::print(os, " ... |\n"); + + // show where the error occurred if (i == target_line || (i > target_line && overflow > 0)) { - fmt::print(os, " |"); + fmt::print(os, "{}", line_no_num); if (!whole_line) { // if we have an overflow then we start at the beginning of the line const std::size_t curr_col_start = (overflow == 0) ? col_start : 0; // if we have an overflow, it is used as the end of the line - const std::size_t col_end = (i == target_line) ? std::min(col_start + sym_size, ctx[target_line].size()) - : std::min(overflow, ctx[i].size()); + const std::size_t col_end = (i == target_line) ? std::min(col_start + sym_size, lines[target_line].size()) + : std::min(overflow, lines[i].size()); // update the overflow to avoid going here again if not needed - overflow = (overflow > ctx[i].size()) ? overflow - ctx[i].size() : 0; + overflow = (overflow > lines[i].size()) ? overflow - lines[i].size() : 0; - fmt::print( - os, - "{: <{}}{:~<{}}\n", - // padding of spaces - " ", - std::max(1_z, curr_col_start), // fixing padding when the error is on the first character - // underline the error in red - fmt::styled("^", colorize ? fmt::fg(fmt::color::red) : fmt::text_style()), - col_end - curr_col_start); + // show the error where it's at, using the normal process, if there is no context OR if the context line is different from the error line + if (!maybe_context || maybe_context->line != target_line) + fmt::print( + os, + "{: <{}}{:~<{}}\n", + // padding of spaces + " ", + std::max(1_z, curr_col_start), // fixing padding when the error is on the first character + // underline the error in red + fmt::styled("^", colorize ? fmt::fg(fmt::color::red) : fmt::text_style()), + col_end - curr_col_start); + else if (i == target_line) // i == target_line to avoid having to deal with overflow + { + const auto padding_size = std::max(1_z, maybe_context->col); + + fmt::print( + os, + "{: <{}}{}{}{: <{}}\n", + // padding of spaces + " ", + padding_size, + // indicate where the parent is, with color + fmt::styled("│", colorize ? fmt::fg(fmt::color::red) : fmt::text_style()), + // yet another padding of spaces between the parent and error column (if need be) + (maybe_context->col == col_start) ? "" : fmt::format("{: <{}}", " ", col_start - maybe_context->col), + // underline the error in red + fmt::styled("└─ error", colorize ? fmt::fg(fmt::color::red) : fmt::text_style()), + col_end - curr_col_start); + // new line, some spacing between the error and the parent + fmt::print(os, "{}{: <{}}{}\n", line_no_num, " ", padding_size, fmt::styled("│", colorize ? fmt::fg(fmt::color::red) : fmt::text_style())); + // new line, now show the "expression started here for the source" + fmt::print( + os, + "{}{: <{}}{}\n", + line_no_num, + // padding of spaces + " ", + padding_size, + fmt::styled("└─ expression started here", colorize ? fmt::fg(fmt::color::red) : fmt::text_style())); + } } else { // first non-whitespace character of the line // +1 for the leading whitespace after ` |` before the code - const std::size_t curr_col_start = ctx[i].find_first_not_of(" \t\v") + 1; + const std::size_t curr_col_start = lines[i].find_first_not_of(" \t\v") + 1; // highlight the current line but skip any leading whitespace fmt::print( @@ -144,22 +279,19 @@ namespace Ark::Diagnostics curr_col_start, // underline the whole line in red fmt::styled("^", colorize ? fmt::fg(fmt::color::red) : fmt::text_style()), - ctx[target_line].size() - curr_col_start); + lines[target_line].size() - curr_col_start); } } } } - template - void helper(std::ostream& os, const std::string& message, const bool colorize, const std::string& filename, const std::string& code, const T& expr, - const std::size_t line, std::size_t column, const std::size_t sym_size) + void helper(std::ostream& os, const std::string& message, const bool colorize, + const std::string& filename, + const std::optional& expr, const std::size_t sym_size, + const std::size_t line, const std::size_t column, + const std::optional& maybe_context = std::nullopt) { - if (filename != ARK_NO_NAME_FILE) - fmt::print(os, "In file {}\n", filename); - fmt::print(os, "At {} @ {}:{}\n", expr, line + 1, column); - - if (!code.empty()) - makeContext(os, code, line, column, sym_size, /* whole_line= */ false, colorize); + makeContext(os, filename, expr, sym_size, line, column, maybe_context, /* whole_line= */ false, colorize); const auto message_lines = Utils::splitString(message, '\n'); for (const auto& text : message_lines) @@ -179,11 +311,10 @@ namespace Ark::Diagnostics message, true, node.filename(), - (node.filename() == ARK_NO_NAME_FILE) ? "" : Utils::readFile(node.filename()), node.repr(), + size, node.line(), - node.col(), - size); + node.col()); return ss.str(); } @@ -211,19 +342,15 @@ namespace Ark::Diagnostics else escaped_symbol = e.context.expr; - std::string file_content; - if (e.context.filename != ARK_NO_NAME_FILE) - file_content = Utils::readFile(e.context.filename); - helper( os, e.what(), colorize, e.context.filename, - file_content, escaped_symbol, + e.context.expr.size(), e.context.line, e.context.col, - e.context.expr.size()); + e.additional_context); } } diff --git a/src/arkreactor/VM/VM.cpp b/src/arkreactor/VM/VM.cpp index b946f7c30..510211bc5 100644 --- a/src/arkreactor/VM/VM.cpp +++ b/src/arkreactor/VM/VM.cpp @@ -1700,15 +1700,15 @@ namespace Ark { const auto filename = m_state.m_filenames[maybe_location->filename_id]; - fmt::println(os, "In file {}", filename, maybe_location->line + 1); - if (Utils::fileExists(filename)) Diagnostics::makeContext( os, - Utils::readFile(filename), + filename, + /* expr= */ std::nullopt, + /* sym_size= */ 0, maybe_location->line, /* col_start= */ 0, - /* sym_size= */ 0, + /* maybe_context= */ std::nullopt, /* whole_line= */ true, /* colorize= */ colorize); fmt::println(os, ""); diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/arity_error_async.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/arity_error_async.expected index 6c7903b17..e9f852f7a 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/arity_error_async.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/arity_error_async.expected @@ -1,6 +1,6 @@ ArityError: When calling `(sum 1 2 3 4)', received 4 arguments, but expected 3: `(sum a b c)' -In file tests/unittests/resources/DiagnosticsSuite/runtime/arity_error_async.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/arity_error_async.ark:4 1 | (let sum (fun (a b c) 2 | (+ a b c))) 3 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_eq_out_of_range_x.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_eq_out_of_range_x.expected index 7c764bd43..53ce73f40 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_eq_out_of_range_x.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_eq_out_of_range_x.expected @@ -1,6 +1,6 @@ IndexError: @@= index (x: 1) out of range (inner indexable size: 1) -In file tests/unittests/resources/DiagnosticsSuite/runtime/at_at_eq_out_of_range_x.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/at_at_eq_out_of_range_x.ark:2 1 | (mut a [[1]]) 2 | (@@= a 0 1 2) | ^~~~~~~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_eq_out_of_range_y.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_eq_out_of_range_y.expected index 4cd835b14..b7c83f21c 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_eq_out_of_range_y.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_eq_out_of_range_y.expected @@ -1,6 +1,6 @@ IndexError: @@= index (y: 1) out of range (list size: 1) -In file tests/unittests/resources/DiagnosticsSuite/runtime/at_at_eq_out_of_range_y.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/at_at_eq_out_of_range_y.ark:2 1 | (mut a [[1]]) 2 | (@@= a 1 0 2) | ^~~~~~~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_inner_out_of_range.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_inner_out_of_range.expected index 2ebda34f7..81dea38b4 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_inner_out_of_range.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_inner_out_of_range.expected @@ -1,6 +1,6 @@ IndexError: @@ index (x: 6) out of range (inner indexable size: 4) -In file tests/unittests/resources/DiagnosticsSuite/runtime/at_at_inner_out_of_range.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/at_at_inner_out_of_range.ark:2 1 | (let lst [[0 1 2 3] [4 5 6 7] [8 9 0 1]]) 2 | (print (@@ lst 0 6)) | ^~~~~~~~~~~~~~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_out_of_range.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_out_of_range.expected index 58062c864..d86438d00 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_out_of_range.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/at_at_out_of_range.expected @@ -1,6 +1,6 @@ IndexError: @@ index (3) out of range (list size: 3) -In file tests/unittests/resources/DiagnosticsSuite/runtime/at_at_out_of_range.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/at_at_out_of_range.ark:2 1 | (let lst [[0 1 2 3] [4 5 6 7] [8 9 0 1]]) 2 | (print (@@ lst 3 1)) | ^~~~~~~~~~~~~~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/at_eq_out_of_range.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/at_eq_out_of_range.expected index 8187cc3e7..029b542f0 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/at_eq_out_of_range.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/at_eq_out_of_range.expected @@ -1,6 +1,6 @@ IndexError: @= index (1) out of range (indexable size: 1) -In file tests/unittests/resources/DiagnosticsSuite/runtime/at_eq_out_of_range.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/at_eq_out_of_range.ark:2 1 | (mut a [1]) 2 | (@= a 1 2) | ^~~~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/at_out_of_range.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/at_out_of_range.expected index f25f27811..7b71d5fb8 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/at_out_of_range.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/at_out_of_range.expected @@ -1,6 +1,6 @@ IndexError: -2 out of range [1] (length 1) -In file tests/unittests/resources/DiagnosticsSuite/runtime/at_out_of_range.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/at_out_of_range.ark:2 1 | (let a [1]) 2 | (@ a -2) | ^~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/at_str_out_of_range.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/at_str_out_of_range.expected index de9b9bfbf..0e48bcefa 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/at_str_out_of_range.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/at_str_out_of_range.expected @@ -1,6 +1,6 @@ IndexError: 1 out of range "a" (length 1) -In file tests/unittests/resources/DiagnosticsSuite/runtime/at_str_out_of_range.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/at_str_out_of_range.ark:2 1 | (let a "a") 2 | (@ a 1) | ^~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/closure_field_wrong_fqn.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/closure_field_wrong_fqn.expected index 0e8c017f6..40f149aed 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/closure_field_wrong_fqn.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/closure_field_wrong_fqn.expected @@ -1,6 +1,6 @@ ScopeError: `b:b' isn't in the closure environment: (.a=hello .b=1). A variable in the package might have the same name as 'b:b', and name resolution tried to fully qualify it. Rename either the variable or the capture to solve this -In file tests/unittests/resources/DiagnosticsSuite/runtime/closure_field_wrong_fqn/b.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/closure_field_wrong_fqn/b.ark:10 7 | (let make (fun (a b) 8 | (fun (&a &b) ()))) 9 | (let foo (make "hello" 1)) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/db0.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/db0.expected index 96fa85ff3..c3aedc711 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/db0.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/db0.expected @@ -1,6 +1,6 @@ DivisionByZero: Can not compute expression (/ 5 0) -In file tests/unittests/resources/DiagnosticsSuite/runtime/db0.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/db0.ark:1 1 | (/ 5 0.0) | ^~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/del_unbound.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/del_unbound.expected index 091c68ee8..3d60884a7 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/del_unbound.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/del_unbound.expected @@ -1,6 +1,6 @@ ScopeError: Can not delete unbound variable `a' -In file tests/unittests/resources/DiagnosticsSuite/runtime/del_unbound.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/del_unbound.ark:1 1 | (del a) | ^~~~~~ 2 | (let a 0) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/fmt_arg_not_found.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/fmt_arg_not_found.expected index 7ac3592ca..556eae09e 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/fmt_arg_not_found.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/fmt_arg_not_found.expected @@ -1,6 +1,6 @@ string:format: can not format "Hello {}, I'm {}" (1 argument provided) because of argument not found -In file tests/unittests/resources/DiagnosticsSuite/runtime/fmt_arg_not_found.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/fmt_arg_not_found.ark:1 1 | (string:format "Hello {}, I'm {}" "World") | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/list_set_at.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/list_set_at.expected index 70c4b10f9..333bc9751 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/list_set_at.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/list_set_at.expected @@ -1,6 +1,6 @@ IndexError: list:setAt index (4) out of range (list size: 4) -In file tests/unittests/resources/DiagnosticsSuite/runtime/list_set_at.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/list_set_at.ark:1 1 | (list:setAt [0 1 2 3] 4 9) | ^~~~~~~~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_end_start.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_end_start.expected index 9aa6d5d3a..3560a6905 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_end_start.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_end_start.expected @@ -1,6 +1,6 @@ list:slice: start position (6) must be less or equal to the end position (5) -In file tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_end_start.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_end_start.ark:1 1 | (list:slice [1 2 3 4 5 6 7 8 9] 6 5 1) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_past_end.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_past_end.expected index 6292b4d90..c52a6a51e 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_past_end.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_past_end.expected @@ -1,6 +1,6 @@ list:slice: end index 12 out of range (length: 9) -In file tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_past_end.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_past_end.ark:1 1 | (list:slice [1 2 3 4 5 6 7 8 9] 6 12 1) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_start_less_0.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_start_less_0.expected index 90b54eab8..7592acc32 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_start_less_0.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_start_less_0.expected @@ -1,6 +1,6 @@ list:slice: start index -1 can not be less than 0 -In file tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_start_less_0.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_start_less_0.ark:1 1 | (list:slice [1 2 3 4 5 6 7 8 9] -1 5 1) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_step_null.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_step_null.expected index 7162e4a90..1bc4856fc 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_step_null.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_step_null.expected @@ -1,6 +1,6 @@ list:slice: step can not be null or negative -In file tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_step_null.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/list_slice_step_null.ark:1 1 | (list:slice [1 2 3 4 5 6 7 8 9] 4 5 -1) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/mathln_out_of_range.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/mathln_out_of_range.expected index 830889b43..45f46553d 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/mathln_out_of_range.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/mathln_out_of_range.expected @@ -1,6 +1,6 @@ math:ln: value -1 must be greater than 0 -In file tests/unittests/resources/DiagnosticsSuite/runtime/mathln_out_of_range.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/mathln_out_of_range.ark:1 1 | (math:ln -1) | ^~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/nil_not_a_function.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/nil_not_a_function.expected index f913ab9ca..1c6f7e09a 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/nil_not_a_function.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/nil_not_a_function.expected @@ -1,6 +1,6 @@ TypeError: nil is not a Function but a Nil -In file tests/unittests/resources/DiagnosticsSuite/runtime/nil_not_a_function.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/nil_not_a_function.ark:1 1 | (()) | ^~~ 2 | (fun (a b) (if 1 2 3)) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/not_a_closure.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/not_a_closure.expected index dda9178b0..86d2c2a05 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/not_a_closure.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/not_a_closure.expected @@ -1,6 +1,6 @@ TypeError: `a' is a Number, not a Closure, can not get the field `c' from it -In file tests/unittests/resources/DiagnosticsSuite/runtime/not_a_closure.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/not_a_closure.ark:3 1 | (let a 5) 2 | (let c 5) 3 | (let b a.c) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/not_callable.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/not_callable.expected index fea63f89f..7139c4fae 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/not_callable.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/not_callable.expected @@ -1,6 +1,6 @@ TypeError: nil is not a Function but a Nil -In file tests/unittests/resources/DiagnosticsSuite/runtime/not_callable.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/not_callable.ark:1 1 | (()) | ^~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/not_callable_with_args.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/not_callable_with_args.expected index 1593769d7..645d9bd7b 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/not_callable_with_args.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/not_callable_with_args.expected @@ -1,6 +1,6 @@ TypeError: nil is not a Function but a Nil -In file tests/unittests/resources/DiagnosticsSuite/runtime/not_callable_with_args.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/not_callable_with_args.ark:3 1 | (let a 1) 2 | 3 | (nil 2 a) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/not_enough_args.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/not_enough_args.expected index 4c4163323..be543e0fe 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/not_enough_args.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/not_enough_args.expected @@ -1,6 +1,6 @@ ArityError: When calling `(foo 1)', received 1 argument, but expected 2: `(foo a b)' -In file tests/unittests/resources/DiagnosticsSuite/runtime/not_enough_args.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/not_enough_args.ark:2 1 | (let foo (fun (a b) (+ a b))) 2 | (foo 1) | ^~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/out_of_range_in_place.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/out_of_range_in_place.expected index e06632388..2a0cfd420 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/out_of_range_in_place.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/out_of_range_in_place.expected @@ -1,6 +1,6 @@ IndexError: pop! index (4) out of range (list size: 3) -In file tests/unittests/resources/DiagnosticsSuite/runtime/out_of_range_in_place.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/out_of_range_in_place.ark:2 1 | (mut a [1 2 3]) 2 | (pop! a 4) | ^~~~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/pop_out_of_range.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/pop_out_of_range.expected index 41e8fdc4f..7a9d08305 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/pop_out_of_range.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/pop_out_of_range.expected @@ -1,6 +1,6 @@ IndexError: pop index (4) out of range (list size: 3) -In file tests/unittests/resources/DiagnosticsSuite/runtime/pop_out_of_range.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/pop_out_of_range.ark:2 1 | (let a [1 2 3]) 2 | (pop a 4) | ^~~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/recursion_depth.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/recursion_depth.expected index 9ca11738f..d23a3b3f7 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/recursion_depth.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/recursion_depth.expected @@ -1,6 +1,6 @@ VMError: Maximum recursion depth exceeded. You could consider rewriting your function `foo' to make use of tail-call optimization. -In file tests/unittests/resources/DiagnosticsSuite/runtime/recursion_depth.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/recursion_depth.ark:3 1 | (let foo (fun (a) { 2 | # hack to avoid getting TCO-ed 3 | (let tmp (foo (+ a 1))) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/set_unbound.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/set_unbound.expected index cd0be8059..4faea2e17 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/set_unbound.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/set_unbound.expected @@ -1,6 +1,6 @@ ScopeError: Unbound variable `a', can not change its value to 5 -In file tests/unittests/resources/DiagnosticsSuite/runtime/set_unbound.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/set_unbound.ark:1 1 | (set a 5) | ^~~~~~~~ 2 | (let a 0) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/str_remove_out_of_bound.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/str_remove_out_of_bound.expected index 42790fa93..65e8d6184 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/str_remove_out_of_bound.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/str_remove_out_of_bound.expected @@ -1,6 +1,6 @@ string:removeAt: index 5 out of range (length: 3) -In file tests/unittests/resources/DiagnosticsSuite/runtime/str_remove_out_of_bound.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/str_remove_out_of_bound.ark:1 1 | (string:removeAt "abc" 5) | ^~~~~~~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/string_set_at.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/string_set_at.expected index 423015a56..b4a2234bf 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/string_set_at.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/string_set_at.expected @@ -1,6 +1,6 @@ IndexError: string:setAt index (4) out of range (string size: 4) -In file tests/unittests/resources/DiagnosticsSuite/runtime/string_set_at.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/string_set_at.ark:1 1 | (string:setAt "0123" 4 "9") | ^~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/too_many_args.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/too_many_args.expected index 00c38696f..d589e55b0 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/too_many_args.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/too_many_args.expected @@ -1,6 +1,6 @@ ArityError: When calling `(foo 1 2 3)', received 3 arguments, but expected 2: `(foo a b)' -In file tests/unittests/resources/DiagnosticsSuite/runtime/too_many_args.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/too_many_args.ark:2 1 | (let foo (fun (a b) (+ a b))) 2 | (foo 1 2 3) | ^~~~~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/unbound_var.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/unbound_var.expected index fd0f8185c..89cb74f09 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/unbound_var.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/unbound_var.expected @@ -1,6 +1,6 @@ ScopeError: Unbound variable `a' -In file tests/unittests/resources/DiagnosticsSuite/runtime/unbound_var.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/unbound_var.ark:1 1 | (let b a) | ^~~~~~~~ 2 | (let a 5) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/unknown_field.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/unknown_field.expected index 0afa2e325..ef63cd047 100644 --- a/tests/unittests/resources/DiagnosticsSuite/runtime/unknown_field.expected +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/unknown_field.expected @@ -1,6 +1,6 @@ ScopeError: `c' isn't in the closure environment: (.a=5) -In file tests/unittests/resources/DiagnosticsSuite/runtime/unknown_field.ark +In file tests/unittests/resources/DiagnosticsSuite/runtime/unknown_field.ark:4 1 | (let a 5) 2 | (let c 6) 3 | (let b (fun (&a) ())) diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/add_num_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/add_num_str.expected index ab4bc1ebf..d9afdf6bc 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/add_num_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/add_num_str.expected @@ -5,7 +5,7 @@ Alternative 2: -> a (String) was of type Number -> b (String) -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/add_num_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/add_num_str.ark:1 1 | (+ 1 "2") | ^~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/append_in_place_num_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/append_in_place_num_num.expected index 704f2960c..edad9617b 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/append_in_place_num_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/append_in_place_num_num.expected @@ -2,7 +2,7 @@ Function append! expected at least 2 arguments and got 2 -> list (List) was of type Number -> variadic value (any) -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/append_in_place_num_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/append_in_place_num_num.ark:2 1 | (mut L 1) 2 | (append! L 5) | ^~~~~~~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/append_num_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/append_num_num.expected index 08bfdc928..5ad4e3524 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/append_num_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/append_num_num.expected @@ -2,7 +2,7 @@ Function append expected at least 2 arguments and got 2 -> list (List) was of type Number -> variadic value (any) -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/append_num_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/append_num_num.ark:1 1 | (append 1 3) | ^~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/assert_num_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/assert_num_num.expected index 40d0a0595..9e1c73961 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/assert_num_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/assert_num_num.expected @@ -2,7 +2,7 @@ Function assert expected 2 arguments -> expr (any) -> message (String) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/assert_num_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/assert_num_num.ark:1 1 | (assert 1 2) | ^~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_eq_list_num_num_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_eq_list_num_num_num.expected index 3bcb25e3a..2fb310358 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_eq_list_num_num_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_eq_list_num_num_num.expected @@ -9,7 +9,7 @@ Alternative 2: -> y (Number) -> char (String) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_eq_list_num_num_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_eq_list_num_num_num.ark:1 1 | (@@= [1 2 3 4] 0 1 4) | ^~~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_eq_num_num_num_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_eq_num_num_num_num.expected index 9c067ba47..a30f1e133 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_eq_num_num_num_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_eq_num_num_num_num.expected @@ -4,7 +4,7 @@ Function @@= expected 4 arguments -> y (Number) -> new_value (any) -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_eq_num_num_num_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_eq_num_num_num_num.ark:1 1 | (@@= 1 2 3 4) | ^~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_num_num_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_num_num_num.expected index e04db3625..05cdf5b0d 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_num_num_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_num_num_num.expected @@ -3,7 +3,7 @@ Function @@ expected 3 arguments -> y (Number) -> x (Number) -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_num_num_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/at_at_num_num_num.ark:1 1 | (@@ 1 2 3) | ^~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_eq_num_num_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_eq_num_num_num.expected index 7f59e744c..7b33c8519 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_eq_num_num_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_eq_num_num_num.expected @@ -7,7 +7,7 @@ Alternative 2: -> index (Number) -> char (String) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/at_eq_num_num_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/at_eq_num_num_num.ark:1 1 | (@= 1 2 3) | ^~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_list_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_list_str.expected index caf6153d8..a0dd0f611 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_list_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_list_str.expected @@ -5,7 +5,7 @@ Alternative 2: -> src (String) was of type List -> idx (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/at_list_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/at_list_str.ark:1 1 | (@ [] "1") | ^~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_num_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_num_num.expected index 2e4f82ee2..64c6e62fa 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_num_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/at_num_num.expected @@ -5,7 +5,7 @@ Alternative 2: -> src (String) was of type Number -> idx (Number) -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/at_num_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/at_num_num.ark:1 1 | (@ 1 2) | ^~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/await_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/await_num.expected index d6d7a3948..dd7ad48cd 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/await_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/await_num.expected @@ -1,7 +1,7 @@ Function await expected 1 argument -> future (UserType) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/await_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/await_num.ark:1 1 | (await 1) | ^~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_in_place_list_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_in_place_list_num.expected index 2cfbff0b5..c0a26d9ea 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_in_place_list_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_in_place_list_num.expected @@ -2,7 +2,7 @@ Function concat! expected 2 arguments -> dst (List) -> src (List) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_in_place_list_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_in_place_list_num.ark:2 1 | (mut L []) 2 | (concat! L 5) | ^~~~~~~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_in_place_num_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_in_place_num_num.expected index c81c8a125..f6e239abf 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_in_place_num_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_in_place_num_num.expected @@ -2,7 +2,7 @@ Function concat! expected 2 arguments -> dst (List) was of type Number -> src (List) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_in_place_num_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_in_place_num_num.ark:2 1 | (mut L 1) 2 | (concat! L 5) | ^~~~~~~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_list_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_list_num.expected index a3161617a..15822e372 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_list_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_list_num.expected @@ -2,7 +2,7 @@ Function concat expected 2 arguments -> dst (List) -> src (List) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_list_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_list_num.ark:1 1 | (concat [1] 3) | ^~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_num_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_num_num.expected index 730bdbbc2..aa2cc5515 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_num_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_num_num.expected @@ -2,7 +2,7 @@ Function concat expected 2 arguments -> dst (List) was of type Number -> src (List) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_num_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/concat_num_num.ark:1 1 | (concat 1 3) | ^~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/decrement_str_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/decrement_str_num.expected index e7e4f4427..e312d805a 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/decrement_str_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/decrement_str_num.expected @@ -2,7 +2,7 @@ Function - expected 2 arguments -> a (Number) was of type String -> b (Number) was of type Function -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/decrement_str_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/decrement_str_num.ark:2 1 | (mut n "1") 2 | (set n (- n 1)) | ^~~~~~~~~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/div_str_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/div_str_num.expected index 60fb7dbbf..f1e417e4d 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/div_str_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/div_str_num.expected @@ -2,7 +2,7 @@ Function / expected 2 arguments -> a (Number) was of type String -> b (Number) -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/div_str_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/div_str_num.ark:1 1 | (/ "3" 5) | ^~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/empty_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/empty_num.expected index 36e0aa47a..5e8d17fcb 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/empty_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/empty_num.expected @@ -3,7 +3,7 @@ Function empty? expected 1 argument Alternative 2: -> value (String) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/empty_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/empty_num.ark:1 1 | (empty? 1) | ^~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/hasfield_num_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/hasfield_num_str.expected index d25fe8dc1..401faaee4 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/hasfield_num_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/hasfield_num_str.expected @@ -2,7 +2,7 @@ Function hasField expected 2 arguments -> closure (Closure) was of type Number -> field (String) -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/hasfield_num_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/hasfield_num_str.ark:1 1 | (hasField 1 "c") | ^~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/head_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/head_num.expected index 12b6d6307..0f7e9491a 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/head_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/head_num.expected @@ -3,7 +3,7 @@ Function head expected 1 argument Alternative 2: -> value (String) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/head_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/head_num.ark:1 1 | (head 5) | ^~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/increment_str_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/increment_str_num.expected index fa22a3571..1ab03a557 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/increment_str_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/increment_str_num.expected @@ -2,7 +2,7 @@ Function + expected 2 arguments -> a (Number) was of type String -> b (Number) was of type Function -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/increment_str_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/increment_str_num.ark:2 1 | (mut n "1") 2 | (set n (+ n 1)) | ^~~~~~~~~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioappendtofile_num_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioappendtofile_num_num.expected index f473fbd32..e2279118f 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioappendtofile_num_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioappendtofile_num_num.expected @@ -2,7 +2,7 @@ Function io:appendToFile expected 2 arguments -> filename (String) was of type Number -> content (any) -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/ioappendtofile_num_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/ioappendtofile_num_num.ark:1 1 | (io:appendToFile 1 2) | ^~~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/iodir_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/iodir_num.expected index 360f34a3a..838eb529b 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/iodir_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/iodir_num.expected @@ -1,7 +1,7 @@ Function io:dir? expected 1 argument -> path (String) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/iodir_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/iodir_num.ark:1 1 | (io:dir? 1) | ^~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/iofileexists_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/iofileexists_num.expected index d95c79970..5a577c3f4 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/iofileexists_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/iofileexists_num.expected @@ -1,7 +1,7 @@ Function io:fileExists? expected 1 argument -> filename (String) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/iofileexists_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/iofileexists_num.ark:1 1 | (io:fileExists? 1) | ^~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/iolistfiles_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/iolistfiles_num.expected index a2af6fd13..9bac4bae5 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/iolistfiles_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/iolistfiles_num.expected @@ -1,7 +1,7 @@ Function io:listFiles expected 1 argument -> path (String) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/iolistfiles_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/iolistfiles_num.ark:1 1 | (io:listFiles 1) | ^~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/iomakedir_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/iomakedir_num.expected index 4c7e97c76..6ba7fadcb 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/iomakedir_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/iomakedir_num.expected @@ -1,7 +1,7 @@ Function io:makeDir expected 1 argument -> path (String) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/iomakedir_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/iomakedir_num.ark:1 1 | (io:makeDir 1) | ^~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioreadfile_inexistent.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioreadfile_inexistent.expected index 2721850df..07af299c7 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioreadfile_inexistent.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioreadfile_inexistent.expected @@ -1,6 +1,6 @@ io:readFile: couldn't read file "non-existing-file.weird" because it doesn't exist -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/ioreadfile_inexistent.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/ioreadfile_inexistent.ark:1 1 | (io:readFile "non-existing-file.weird") | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioreadfile_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioreadfile_num.expected index 252a28d4b..23705ada6 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioreadfile_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioreadfile_num.expected @@ -1,7 +1,7 @@ Function io:readFile expected 1 argument -> filename (String) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/ioreadfile_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/ioreadfile_num.ark:1 1 | (io:readFile 1) | ^~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioremovefiles_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioremovefiles_num.expected index e6c888c22..3a103a029 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioremovefiles_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioremovefiles_num.expected @@ -1,7 +1,7 @@ Function io:removeFiles expected at least 1 argument and got 1 -> variadic filename (String) 1 argument do not match -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/ioremovefiles_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/ioremovefiles_num.ark:1 1 | (io:removeFiles 1) | ^~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioremovefiles_str_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioremovefiles_str_num.expected index 012aac471..883017366 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioremovefiles_str_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/ioremovefiles_str_num.expected @@ -2,7 +2,7 @@ Function io:removeFiles expected at least 2 arguments and got 2 -> filename (String) -> variadic filenames (String) 1 argument do not match -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/ioremovefiles_str_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/ioremovefiles_str_num.ark:2 1 | (io:writeFile "hello" "content") 2 | (io:removeFiles "hello" 1) | ^~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/iowritefile_num_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/iowritefile_num_num.expected index b6125d337..d38797380 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/iowritefile_num_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/iowritefile_num_num.expected @@ -2,7 +2,7 @@ Function io:writeFile expected 2 arguments -> filename (String) was of type Number -> content (any) -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/iowritefile_num_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/iowritefile_num_num.ark:1 1 | (io:writeFile 1 2) | ^~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/len_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/len_num.expected index 153c2e786..e1b1e44ad 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/len_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/len_num.expected @@ -3,7 +3,7 @@ Function len expected 1 argument Alternative 2: -> value (String) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/len_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/len_num.ark:1 1 | (len 1) | ^~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/listfill_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/listfill_str.expected index fb0ddfe61..f7a78f266 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/listfill_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/listfill_str.expected @@ -2,7 +2,7 @@ Function list:fill expected 2 arguments but got 1 -> size (Number) was of type String -> value (any) was not provided -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/listfill_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/listfill_str.ark:1 1 | (list:fill "hello") | ^~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/listfind_str_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/listfind_str_num.expected index 4aba3afc3..c089968c5 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/listfind_str_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/listfind_str_num.expected @@ -2,7 +2,7 @@ Function list:find expected 2 arguments -> list (List) was of type String -> value (any) -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/listfind_str_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/listfind_str_num.ark:1 1 | (list:find "hello" 1) | ^~~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/listreverse_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/listreverse_str.expected index 323f62b9a..b070d4aae 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/listreverse_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/listreverse_str.expected @@ -1,7 +1,7 @@ Function list:reverse expected 1 argument -> list (List) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/listreverse_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/listreverse_str.ark:1 1 | (list:reverse "hello") | ^~~~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/listsetat_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/listsetat_str.expected index 97c7268eb..90d7f9608 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/listsetat_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/listsetat_str.expected @@ -3,7 +3,7 @@ Function list:setAt expected 3 arguments but got 1 -> index (Number) was not provided -> value (any) was not provided -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/listsetat_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/listsetat_str.ark:1 1 | (list:setAt "hello") | ^~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/listslice_str_num_bool_nil.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/listslice_str_num_bool_nil.expected index 8f957a4e2..b6c33f363 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/listslice_str_num_bool_nil.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/listslice_str_num_bool_nil.expected @@ -4,7 +4,7 @@ Function list:slice expected 4 arguments -> end (Number) was of type Bool -> step (Number) was of type Nil -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/listslice_str_num_bool_nil.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/listslice_str_num_bool_nil.ark:1 1 | (list:slice "hello" 1 true nil) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/listsort_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/listsort_str.expected index 8e9e61606..8ab8c769d 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/listsort_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/listsort_str.expected @@ -1,7 +1,7 @@ Function list:sort expected 1 argument -> list (List) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/listsort_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/listsort_str.ark:1 1 | (list:sort "hello") | ^~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathacosh_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathacosh_str.expected index e3c8c3598..f0101bdc6 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathacosh_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathacosh_str.expected @@ -1,7 +1,7 @@ Function math:acosh expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathacosh_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathacosh_str.ark:1 1 | (math:acosh "1") | ^~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/matharccos_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/matharccos_str.expected index 943d9854d..19c0f9069 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/matharccos_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/matharccos_str.expected @@ -1,7 +1,7 @@ Function math:arccos expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/matharccos_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/matharccos_str.ark:1 1 | (math:arccos "1") | ^~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/matharcsin_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/matharcsin_str.expected index 99c10057d..b33cc165d 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/matharcsin_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/matharcsin_str.expected @@ -1,7 +1,7 @@ Function math:arcsin expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/matharcsin_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/matharcsin_str.ark:1 1 | (math:arcsin "1") | ^~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/matharctan_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/matharctan_str.expected index aaaedb522..710590c05 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/matharctan_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/matharctan_str.expected @@ -1,7 +1,7 @@ Function math:arctan expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/matharctan_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/matharctan_str.ark:1 1 | (math:arctan "1") | ^~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathasinh_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathasinh_str.expected index 557d2965c..2b6893ee6 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathasinh_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathasinh_str.expected @@ -1,7 +1,7 @@ Function math:asinh expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathasinh_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathasinh_str.ark:1 1 | (math:asinh "1") | ^~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathatanh_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathatanh_str.expected index 0103c742f..27b7b071f 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathatanh_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathatanh_str.expected @@ -1,7 +1,7 @@ Function math:atanh expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathatanh_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathatanh_str.ark:1 1 | (math:atanh "1") | ^~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathceil_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathceil_str.expected index 4bdce4593..8eca9ea31 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathceil_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathceil_str.expected @@ -1,7 +1,7 @@ Function math:ceil expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathceil_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathceil_str.ark:1 1 | (math:ceil "1") | ^~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathcos_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathcos_str.expected index ea1e82d4e..c93dd2338 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathcos_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathcos_str.expected @@ -1,7 +1,7 @@ Function math:cos expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathcos_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathcos_str.ark:1 1 | (math:cos "1") | ^~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathcosh_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathcosh_str.expected index 0aa9b2d1d..a566a317e 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathcosh_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathcosh_str.expected @@ -1,7 +1,7 @@ Function math:cosh expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathcosh_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathcosh_str.ark:1 1 | (math:cosh "1") | ^~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathexp_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathexp_str.expected index 012be07aa..3ed74fc9b 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathexp_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathexp_str.expected @@ -1,7 +1,7 @@ Function math:exp expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathexp_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathexp_str.ark:1 1 | (math:exp "1") | ^~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathfloor_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathfloor_str.expected index 79a4fd933..00a21e901 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathfloor_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathfloor_str.expected @@ -1,7 +1,7 @@ Function math:floor expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathfloor_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathfloor_str.ark:1 1 | (math:floor "1") | ^~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathln_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathln_str.expected index 00a01c4d9..5e9037430 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathln_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathln_str.expected @@ -1,7 +1,7 @@ Function math:ln expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathln_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathln_str.ark:1 1 | (math:ln "1") | ^~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathround_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathround_str.expected index dba3ad3f5..1d3da4034 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathround_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathround_str.expected @@ -1,7 +1,7 @@ Function math:round expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathround_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathround_str.ark:1 1 | (math:round "1") | ^~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathsin_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathsin_str.expected index 0a45daab0..ed4cd8a1c 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathsin_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathsin_str.expected @@ -1,7 +1,7 @@ Function math:sin expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathsin_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathsin_str.ark:1 1 | (math:sin "1") | ^~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathsinh_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathsinh_str.expected index fc317fcc1..71dc566f5 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathsinh_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathsinh_str.expected @@ -1,7 +1,7 @@ Function math:sinh expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathsinh_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathsinh_str.ark:1 1 | (math:sinh "1") | ^~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathtan_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathtan_str.expected index c817db9a9..3c2269d93 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathtan_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathtan_str.expected @@ -1,7 +1,7 @@ Function math:tan expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathtan_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathtan_str.ark:1 1 | (math:tan "1") | ^~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathtanh_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathtanh_str.expected index 4a003d7f1..69657c28b 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathtanh_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mathtanh_str.expected @@ -1,7 +1,7 @@ Function math:tanh expected 1 argument -> value (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathtanh_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mathtanh_str.ark:1 1 | (math:tanh "1") | ^~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mod_str_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mod_str_str.expected index 1a3c8c44a..b2e26af85 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mod_str_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mod_str_str.expected @@ -2,7 +2,7 @@ Function mod expected 2 arguments -> a (Number) was of type String -> b (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mod_str_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mod_str_str.ark:1 1 | (mod "1" "2") | ^~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mul_str_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mul_str_num.expected index 34ecf187d..1a01146e7 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/mul_str_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/mul_str_num.expected @@ -2,7 +2,7 @@ Function * expected 2 arguments -> a (Number) was of type String -> b (Number) -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mul_str_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/mul_str_num.ark:1 1 | (* "3" 4) | ^~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/pop_in_place_num_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/pop_in_place_num_num.expected index ab007cd5a..51a3e0c1a 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/pop_in_place_num_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/pop_in_place_num_num.expected @@ -2,7 +2,7 @@ Function pop! expected 2 arguments -> list (List) was of type Number -> index (Number) -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/pop_in_place_num_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/pop_in_place_num_num.ark:1 1 | (pop! 5 5) | ^~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/pop_num_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/pop_num_num.expected index f4ba5e72b..abd080ccf 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/pop_num_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/pop_num_num.expected @@ -2,7 +2,7 @@ Function pop expected 2 arguments -> list (List) was of type Number -> index (Number) -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/pop_num_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/pop_num_num.ark:1 1 | (pop 5 5) | ^~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/random_str_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/random_str_str.expected index ed85625c3..d4a8de091 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/random_str_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/random_str_str.expected @@ -2,7 +2,7 @@ Function random expected 2 arguments -> min (Number) was of type String -> max (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/random_str_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/random_str_str.ark:1 1 | (random "1" "2") | ^~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringchr_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringchr_str.expected index f2056783e..f1d7047ba 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringchr_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringchr_str.expected @@ -1,7 +1,7 @@ Function string:chr expected 1 argument -> codepoint (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/stringchr_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/stringchr_str.ark:1 1 | (string:chr "1") | ^~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringfind_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringfind_num.expected index d5923ef8c..d80a79999 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringfind_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringfind_num.expected @@ -6,7 +6,7 @@ Alternative 2: -> substr (String) was not provided -> startIndex (Number) was not provided -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/stringfind_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/stringfind_num.ark:1 1 | (string:find 1) | ^~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringformat_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringformat_num.expected index 3e671c352..92326fb12 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringformat_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringformat_num.expected @@ -2,7 +2,7 @@ Function string:format expected at least 2 arguments but got 1 -> string (String) was of type Number -> variadic value (any) was not provided -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/stringformat_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/stringformat_num.ark:1 1 | (string:format 1) | ^~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringord_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringord_num.expected index ad943ced4..ffbc4dbb4 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringord_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringord_num.expected @@ -1,7 +1,7 @@ Function string:ord expected 1 argument -> string (String) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/stringord_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/stringord_num.ark:1 1 | (string:ord 1) | ^~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringremoveat_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringremoveat_num.expected index 47e364870..c5c117380 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringremoveat_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringremoveat_num.expected @@ -2,7 +2,7 @@ Function string:removeAt expected 2 arguments but got 1 -> string (String) was of type Number -> index (Number) was not provided -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/stringremoveat_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/stringremoveat_num.ark:1 1 | (string:removeAt 1) | ^~~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringsetat_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringsetat_str.expected index b43f170a4..3d73c32d1 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringsetat_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/stringsetat_str.expected @@ -3,7 +3,7 @@ Function string:setAt expected 3 arguments but got 1 -> index (Number) was not provided -> value (String) was not provided -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/stringsetat_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/stringsetat_str.ark:1 1 | (string:setAt "1") | ^~~~~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/sub_str_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/sub_str_str.expected index 6bd101655..0fd006044 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/sub_str_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/sub_str_str.expected @@ -2,7 +2,7 @@ Function - expected 2 arguments -> a (Number) was of type String -> b (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/sub_str_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/sub_str_str.ark:1 1 | (- "1" "2") | ^~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/syssleep_str.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/syssleep_str.expected index f36d4349c..82861b508 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/syssleep_str.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/syssleep_str.expected @@ -1,7 +1,7 @@ Function sys:sleep expected 1 argument -> duration (Number) was of type String -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/syssleep_str.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/syssleep_str.ark:1 1 | (sys:sleep "1") | ^~~~~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/tail_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/tail_num.expected index 9923e523a..6dd49822a 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/tail_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/tail_num.expected @@ -3,7 +3,7 @@ Function tail expected 1 argument Alternative 2: -> value (String) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/tail_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/tail_num.ark:1 1 | (tail 5) | ^~~~~~~ 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/typeChecking/tonumber_num.expected b/tests/unittests/resources/DiagnosticsSuite/typeChecking/tonumber_num.expected index 434d2d293..4447832e3 100644 --- a/tests/unittests/resources/DiagnosticsSuite/typeChecking/tonumber_num.expected +++ b/tests/unittests/resources/DiagnosticsSuite/typeChecking/tonumber_num.expected @@ -1,7 +1,7 @@ Function toNumber expected 1 argument -> value (String) was of type Number -In file tests/unittests/resources/DiagnosticsSuite/typeChecking/tonumber_num.ark +In file tests/unittests/resources/DiagnosticsSuite/typeChecking/tonumber_num.ark:1 1 | (toNumber 5) | ^~~~~~~~~~~ 2 | diff --git a/tests/unittests/resources/ParserSuite/failure/huge_number.expected b/tests/unittests/resources/ParserSuite/failure/huge_number.expected index 25003f95c..6e5f79be8 100644 --- a/tests/unittests/resources/ParserSuite/failure/huge_number.expected +++ b/tests/unittests/resources/ParserSuite/failure/huge_number.expected @@ -1,5 +1,5 @@ -In file tests/unittests/resources/ParserSuite/failure/huge_number.ark +In file tests/unittests/resources/ParserSuite/failure/huge_number.ark:1 At 1 @ 1:8 1 | (let a 1e+4932) | ^~~~~~~ - Is not a valid number \ No newline at end of file + Is not a valid number diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_arguments.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_arguments.expected index daf52b051..ea68b9000 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_arguments.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_arguments.expected @@ -1,5 +1,7 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_arguments.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_arguments.ark:1 At EOF @ 1:7 1 | (fun (a - | ^ + | │ └─ error + | │ + | └─ expression started here Missing ')' in function call to `a' diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_begin.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_begin.expected index 0cdec03c6..38a7df9cd 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_begin.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_begin.expected @@ -1,5 +1,7 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_begin.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_begin.ark:1 At EOF @ 1:15 1 | { a b (let c d) - | ^ + | │ └─ error + | │ + | └─ expression started here Missing '}' to close block diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_call.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_call.expected index d22c9d93c..c80af1029 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_call.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_call.expected @@ -1,5 +1,7 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_call.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_call.ark:1 At EOF @ 1:25 1 | (a b c (if (ok true) 1 2) - | ^ + | │ └─ error + | │ + | └─ expression started here Missing ')' in function call to `a' diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_call_2.ark b/tests/unittests/resources/ParserSuite/failure/incomplete_call_2.ark new file mode 100644 index 000000000..3b07b774c --- /dev/null +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_call_2.ark @@ -0,0 +1,9 @@ +(a b c +# test comment +# cropped +# test +# resume +(if + (ok true) + 1 + 2) diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_call_2.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_call_2.expected new file mode 100644 index 000000000..fb5187e49 --- /dev/null +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_call_2.expected @@ -0,0 +1,13 @@ +In file tests/unittests/resources/ParserSuite/failure/incomplete_call_2.ark:10 +At EOF @ 10:0 + 1 | (a b c + | ^ expression started here + 2 | # test comment + 3 | # cropped + ... | + 7 | (ok true) + 8 | 1 + 9 | 2) + 10 | + | ^ + Missing ')' in function call to `a' \ No newline at end of file diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_del.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_del.expected index 5be12fa18..77062a1f5 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_del.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_del.expected @@ -1,5 +1,5 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_del.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_del.ark:1 At ) @ 1:5 1 | (del) | ^ - del needs a symbol \ No newline at end of file + del needs a symbol diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_fun.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_fun.expected index 1ff5aa369..8d67c90dc 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_fun.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_fun.expected @@ -1,5 +1,5 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_fun.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_fun.ark:1 At ) @ 1:14 1 | (fun (a b &c)) | ^ - Expected a body for the function \ No newline at end of file + Expected a body for the function diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_if.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_if.expected index 20fb1d1aa..a4e7eff65 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_if.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_if.expected @@ -1,6 +1,7 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_if.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_if.ark:2 At EOF @ 2:0 1 | (if 1 2 3 + | ^ expression started here 2 | | ^ - Missing ')' after condition \ No newline at end of file + Missing ')' after condition diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_import_1.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_import_1.expected index 8dc5c73f9..eced21cc6 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_import_1.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_import_1.expected @@ -1,5 +1,5 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_import_1.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_import_1.ark:1 At ) @ 1:8 1 | (import) | ^ - Import expected a package name \ No newline at end of file + Import expected a package name diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_import_2.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_import_2.expected index 36d515c7e..ca5464ccb 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_import_2.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_import_2.expected @@ -1,5 +1,5 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_import_2.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_import_2.ark:1 At ' ' @ 1:11 1 | (import a. ) | ^ - Package name expected after '.' \ No newline at end of file + Package name expected after '.' diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_let.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_let.expected index 4c87db5ed..13a3f2838 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_let.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_let.expected @@ -1,6 +1,6 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_let.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_let.ark:2 At EOF @ 2:3 1 | ( 2 | let | ^ - let needs a symbol \ No newline at end of file + let needs a symbol diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_list.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_list.expected index b642833bd..baacb0483 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_list.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_list.expected @@ -1,6 +1,7 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_list.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_list.ark:3 At EOF @ 3:7 1 | [ + | ^ expression started here 2 | 1 3 | 2 3 | ^ diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_macro.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_macro.expected index af7e608c0..ae42fd78b 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_macro.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_macro.expected @@ -1,5 +1,5 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_macro.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_macro.ark:1 At ( @ 1:4 1 | ($ (a) a) | ^ - $ needs a symbol to declare a macro \ No newline at end of file + $ needs a symbol to declare a macro diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.expected index 6a5635757..c473d102d 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.expected @@ -1,5 +1,7 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.ark:1 At EOF @ 1:9 1 | ($ foo (a - | ^ + | │ └─ error + | │ + | └─ expression started here Missing ')' in function call to `a' diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.expected index ab7b2a08a..9a3a0b71d 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.expected @@ -1,5 +1,5 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_macro_spread.ark:1 At ) @ 1:16 1 | ($ foo (bar ...) (bar)) | ^ - Expected a name for the variadic arguments list \ No newline at end of file + Expected a name for the variadic arguments list diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_package_name.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_package_name.expected index a5c09a58a..402e45491 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_package_name.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_package_name.expected @@ -1,5 +1,5 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_package_name.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_package_name.ark:1 At EOF @ 1:12 1 | (import a.b. | ^ - Package name expected after '.' \ No newline at end of file + Package name expected after '.' diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_string.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_string.expected index d95267804..4c5bea930 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_string.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_string.expected @@ -1,5 +1,5 @@ -In file tests/unittests/resources/ParserSuite/failure/incomplete_string.ark +In file tests/unittests/resources/ParserSuite/failure/incomplete_string.ark:1 At EOF @ 1:14 1 | (let a "1 2 3) | ^ - Missing '"' after string \ No newline at end of file + Missing '"' after string diff --git a/tests/unittests/resources/ParserSuite/failure/incorrect_arg_capture.expected b/tests/unittests/resources/ParserSuite/failure/incorrect_arg_capture.expected index bb5229a4c..6fcb57dff 100644 --- a/tests/unittests/resources/ParserSuite/failure/incorrect_arg_capture.expected +++ b/tests/unittests/resources/ParserSuite/failure/incorrect_arg_capture.expected @@ -1,5 +1,5 @@ -In file tests/unittests/resources/ParserSuite/failure/incorrect_arg_capture.ark +In file tests/unittests/resources/ParserSuite/failure/incorrect_arg_capture.ark:1 At c @ 1:12 1 | (fun (a &b c) 1) | ^ - Captured variables should be at the end of the argument list \ No newline at end of file + Captured variables should be at the end of the argument list diff --git a/tests/unittests/resources/ParserSuite/failure/incorrect_escape_seq.expected b/tests/unittests/resources/ParserSuite/failure/incorrect_escape_seq.expected index 43bc3ceb6..b81021aae 100644 --- a/tests/unittests/resources/ParserSuite/failure/incorrect_escape_seq.expected +++ b/tests/unittests/resources/ParserSuite/failure/incorrect_escape_seq.expected @@ -1,5 +1,5 @@ -In file tests/unittests/resources/ParserSuite/failure/incorrect_escape_seq.ark +In file tests/unittests/resources/ParserSuite/failure/incorrect_escape_seq.ark:1 At \ @ 1:9 1 | (print "\i bla bla bla") | ^ - Unknown escape sequence \ No newline at end of file + Unknown escape sequence diff --git a/tests/unittests/resources/ParserSuite/failure/incorrect_import.expected b/tests/unittests/resources/ParserSuite/failure/incorrect_import.expected index ee709512c..ca04764a8 100644 --- a/tests/unittests/resources/ParserSuite/failure/incorrect_import.expected +++ b/tests/unittests/resources/ParserSuite/failure/incorrect_import.expected @@ -1,5 +1,5 @@ -In file tests/unittests/resources/ParserSuite/failure/incorrect_import.ark +In file tests/unittests/resources/ParserSuite/failure/incorrect_import.ark:1 At : @ 1:15 1 | (import a.b :c:*) | ^~ - Glob pattern can not follow a symbol to import \ No newline at end of file + Glob pattern can not follow a symbol to import diff --git a/tests/unittests/resources/ParserSuite/failure/invalid.expected b/tests/unittests/resources/ParserSuite/failure/invalid.expected index 9b3ad37bb..39fff5353 100644 --- a/tests/unittests/resources/ParserSuite/failure/invalid.expected +++ b/tests/unittests/resources/ParserSuite/failure/invalid.expected @@ -1,6 +1,6 @@ -In file tests/unittests/resources/ParserSuite/failure/invalid.ark +In file tests/unittests/resources/ParserSuite/failure/invalid.ark:1 At ) @ 1:10 1 | (print 1)) | ^ 2 | - invalid syntax, expected node \ No newline at end of file + invalid syntax, expected node From 793b28a342d52b9cc7a261a97cfea41a6aeff130 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Sun, 11 May 2025 16:05:11 +0200 Subject: [PATCH 5/8] feat(error, parser): better error messages for trailing paren/bracket/square bracket --- include/Ark/Compiler/AST/BaseParser.hpp | 2 ++ src/arkreactor/Compiler/AST/BaseParser.cpp | 5 +++++ src/arkreactor/Compiler/AST/Parser.cpp | 12 +++++++++++- src/arkreactor/Exceptions.cpp | 6 +++--- .../resources/ParserSuite/failure/invalid.expected | 6 ------ .../failure/unexpected_closing_bracket.ark | 3 +++ .../failure/unexpected_closing_bracket.expected | 8 ++++++++ .../{invalid.ark => unexpected_closing_paren.ark} | 0 .../failure/unexpected_closing_paren.expected | 6 ++++++ .../failure/unexpected_closing_square_bracket.ark | 3 +++ .../unexpected_closing_square_bracket.expected | 8 ++++++++ 11 files changed, 49 insertions(+), 10 deletions(-) delete mode 100644 tests/unittests/resources/ParserSuite/failure/invalid.expected create mode 100644 tests/unittests/resources/ParserSuite/failure/unexpected_closing_bracket.ark create mode 100644 tests/unittests/resources/ParserSuite/failure/unexpected_closing_bracket.expected rename tests/unittests/resources/ParserSuite/failure/{invalid.ark => unexpected_closing_paren.ark} (100%) create mode 100644 tests/unittests/resources/ParserSuite/failure/unexpected_closing_paren.expected create mode 100644 tests/unittests/resources/ParserSuite/failure/unexpected_closing_square_bracket.ark create mode 100644 tests/unittests/resources/ParserSuite/failure/unexpected_closing_square_bracket.expected diff --git a/include/Ark/Compiler/AST/BaseParser.hpp b/include/Ark/Compiler/AST/BaseParser.hpp index 363690981..1f302d883 100644 --- a/include/Ark/Compiler/AST/BaseParser.hpp +++ b/include/Ark/Compiler/AST/BaseParser.hpp @@ -122,6 +122,8 @@ namespace Ark::internal */ bool expect(const CharPred& t, std::string* s = nullptr); + [[nodiscard]] std::string peek() const; + // basic parsers bool space(std::string* s = nullptr); diff --git a/src/arkreactor/Compiler/AST/BaseParser.cpp b/src/arkreactor/Compiler/AST/BaseParser.cpp index a4c2b7518..3a0f40dd3 100644 --- a/src/arkreactor/Compiler/AST/BaseParser.cpp +++ b/src/arkreactor/Compiler/AST/BaseParser.cpp @@ -181,6 +181,11 @@ namespace Ark::internal return true; } + std::string BaseParser::peek() const + { + return m_sym.c_str(); + } + bool BaseParser::space(std::string* s) { if (accept(IsSpace)) diff --git a/src/arkreactor/Compiler/AST/Parser.cpp b/src/arkreactor/Compiler/AST/Parser.cpp index 927acb5fb..65c5de089 100644 --- a/src/arkreactor/Compiler/AST/Parser.cpp +++ b/src/arkreactor/Compiler/AST/Parser.cpp @@ -38,7 +38,17 @@ namespace Ark::internal else { backtrack(pos); - errorWithNextToken("invalid syntax, expected node"); + std::string out = peek(); + std::string message; + if (out == ")") + message = "Unexpected closing paren"; + else if (out == "}") + message = "Unexpected closing bracket"; + else if (out == "]") + message = "Unexpected closing square bracket"; + else + errorWithNextToken("invalid syntax, expected node"); + errorWithNextToken(message); } } diff --git a/src/arkreactor/Exceptions.cpp b/src/arkreactor/Exceptions.cpp index 71b69fe92..e63110545 100644 --- a/src/arkreactor/Exceptions.cpp +++ b/src/arkreactor/Exceptions.cpp @@ -208,8 +208,8 @@ namespace Ark::Diagnostics if (i + 1 == start_line_skipping_at && i + 1 != stop_line_skipping_at) fmt::print(os, " ... |\n"); - // show where the error occurred - if (i == target_line || (i > target_line && overflow > 0)) + // show where the error occurred (do not mark empty lines as being part of the error when we have overflow) + if (i == target_line || (i > target_line && overflow > 0 && !lines[i].empty())) { fmt::print(os, "{}", line_no_num); @@ -234,7 +234,7 @@ namespace Ark::Diagnostics // underline the error in red fmt::styled("^", colorize ? fmt::fg(fmt::color::red) : fmt::text_style()), col_end - curr_col_start); - else if (i == target_line) // i == target_line to avoid having to deal with overflow + else if (i == target_line) // maybe_context has a value, i == target_line to avoid having to deal with overflow { const auto padding_size = std::max(1_z, maybe_context->col); diff --git a/tests/unittests/resources/ParserSuite/failure/invalid.expected b/tests/unittests/resources/ParserSuite/failure/invalid.expected deleted file mode 100644 index 39fff5353..000000000 --- a/tests/unittests/resources/ParserSuite/failure/invalid.expected +++ /dev/null @@ -1,6 +0,0 @@ -In file tests/unittests/resources/ParserSuite/failure/invalid.ark:1 -At ) @ 1:10 - 1 | (print 1)) - | ^ - 2 | - invalid syntax, expected node diff --git a/tests/unittests/resources/ParserSuite/failure/unexpected_closing_bracket.ark b/tests/unittests/resources/ParserSuite/failure/unexpected_closing_bracket.ark new file mode 100644 index 000000000..2d9fa2287 --- /dev/null +++ b/tests/unittests/resources/ParserSuite/failure/unexpected_closing_bracket.ark @@ -0,0 +1,3 @@ +(let a 1) +(print a) +} diff --git a/tests/unittests/resources/ParserSuite/failure/unexpected_closing_bracket.expected b/tests/unittests/resources/ParserSuite/failure/unexpected_closing_bracket.expected new file mode 100644 index 000000000..d62bd4fb2 --- /dev/null +++ b/tests/unittests/resources/ParserSuite/failure/unexpected_closing_bracket.expected @@ -0,0 +1,8 @@ +In file tests/unittests/resources/ParserSuite/failure/unexpected_closing_bracket.ark:3 +At } @ 3:1 + 1 | (let a 1) + 2 | (print a) + 3 | } + | ^ + 4 | + Unexpected closing bracket diff --git a/tests/unittests/resources/ParserSuite/failure/invalid.ark b/tests/unittests/resources/ParserSuite/failure/unexpected_closing_paren.ark similarity index 100% rename from tests/unittests/resources/ParserSuite/failure/invalid.ark rename to tests/unittests/resources/ParserSuite/failure/unexpected_closing_paren.ark diff --git a/tests/unittests/resources/ParserSuite/failure/unexpected_closing_paren.expected b/tests/unittests/resources/ParserSuite/failure/unexpected_closing_paren.expected new file mode 100644 index 000000000..ba80c2e8c --- /dev/null +++ b/tests/unittests/resources/ParserSuite/failure/unexpected_closing_paren.expected @@ -0,0 +1,6 @@ +In file tests/unittests/resources/ParserSuite/failure/unexpected_closing_paren.ark:1 +At ) @ 1:10 + 1 | (print 1)) + | ^ + 2 | + Unexpected closing paren diff --git a/tests/unittests/resources/ParserSuite/failure/unexpected_closing_square_bracket.ark b/tests/unittests/resources/ParserSuite/failure/unexpected_closing_square_bracket.ark new file mode 100644 index 000000000..9b69e0781 --- /dev/null +++ b/tests/unittests/resources/ParserSuite/failure/unexpected_closing_square_bracket.ark @@ -0,0 +1,3 @@ +(let a 1) +(print a) +] diff --git a/tests/unittests/resources/ParserSuite/failure/unexpected_closing_square_bracket.expected b/tests/unittests/resources/ParserSuite/failure/unexpected_closing_square_bracket.expected new file mode 100644 index 000000000..8a414ec02 --- /dev/null +++ b/tests/unittests/resources/ParserSuite/failure/unexpected_closing_square_bracket.expected @@ -0,0 +1,8 @@ +In file tests/unittests/resources/ParserSuite/failure/unexpected_closing_square_bracket.ark:3 +At ] @ 3:1 + 1 | (let a 1) + 2 | (print a) + 3 | ] + | ^ + 4 | + Unexpected closing square bracket From 38bca0a2a3c68c6683f653512429c2d926cf42b9 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Sun, 11 May 2025 16:12:22 +0200 Subject: [PATCH 6/8] fix(ci): valgrind 3.24.0-2 has been replaced by the -3 version --- .github/workflows/ci.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1e420072c..8f8ae0f6e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -380,12 +380,13 @@ jobs: sudo apt-get update --fix-missing sudo apt-get install -y clang-16 lld-16 libc++-16-dev libc++abi-16-dev clang-tools-16 - - name: Install valgrind 3.24.0 + - name: Install valgrind 3.24+ shell: bash run: | - wget --no-check-certificate http://ftp.us.debian.org/debian/pool/main/v/valgrind/valgrind_3.24.0-2_amd64.deb + valgrind_ver=3.24.0-3_amd64 + wget --no-check-certificate http://ftp.us.debian.org/debian/pool/main/v/valgrind/valgrind_${valgrind_ver}.deb sudo apt remove needrestart - sudo apt install ./valgrind_3.24.0-2_amd64.deb + sudo apt install ./valgrind_${valgrind_ver}.deb - name: Valgrind checks for memory leaks shell: bash From 9341e45e375f8bdb75ec490fdd7c2b9444a0354e Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Mon, 12 May 2025 19:32:14 +0200 Subject: [PATCH 7/8] fix(import solver, error): the error message about non existing files while importing didn't show the correct path to the file --- include/Ark/Compiler/Package/ImportSolver.hpp | 14 ++++-- .../Compiler/Package/ImportSolver.cpp | 47 +++++++++++-------- .../compileTime/import_not_found.ark | 3 ++ .../compileTime/import_not_found.expected | 6 +++ 4 files changed, 46 insertions(+), 24 deletions(-) create mode 100644 tests/unittests/resources/DiagnosticsSuite/compileTime/import_not_found.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/compileTime/import_not_found.expected diff --git a/include/Ark/Compiler/Package/ImportSolver.hpp b/include/Ark/Compiler/Package/ImportSolver.hpp index c76ee773f..e32dbebea 100644 --- a/include/Ark/Compiler/Package/ImportSolver.hpp +++ b/include/Ark/Compiler/Package/ImportSolver.hpp @@ -48,11 +48,17 @@ namespace Ark::internal [[nodiscard]] const Node& ast() const noexcept override; private: + struct ImportWithSource + { + std::filesystem::path file; + Import import; + }; + unsigned m_debug_level; std::vector m_libenv; std::filesystem::path m_root; ///< Folder were the entry file is Node m_ast; - std::stack m_imports; + std::stack m_imports; std::unordered_map m_packages; ///< Package name to package AST & data mapping std::vector m_imported; ///< List of imports, in the order they were found and parsed @@ -67,11 +73,11 @@ namespace Ark::internal * @brief Parse a given file and returns a list of its imports. * The AST is parsed and stored in m_modules[import.prefix] * - * @param base_path path to the file containing the import + * @param source path to the file containing the import * @param import current import directive - * @return std::vector imports found in the processed file + * @return std::vector imports found in the processed file */ - std::vector parseImport(const std::filesystem::path& base_path, const Import& import); + std::vector parseImport(const std::filesystem::path& source, const Import& import); /** * @brief Search for an import file, using the root file path diff --git a/src/arkreactor/Compiler/Package/ImportSolver.cpp b/src/arkreactor/Compiler/Package/ImportSolver.cpp index db0ac679b..e836d3b72 100644 --- a/src/arkreactor/Compiler/Package/ImportSolver.cpp +++ b/src/arkreactor/Compiler/Package/ImportSolver.cpp @@ -16,13 +16,10 @@ namespace Ark::internal ImportSolver& ImportSolver::setup(const std::filesystem::path& root, const std::vector& origin_imports) { - if (is_directory(root)) - m_root = root; - else - m_root = root.parent_path(); + m_root = root.parent_path(); for (const auto& origin_import : std::ranges::reverse_view(origin_imports)) - m_imports.push(origin_import); + m_imports.push({ root, origin_import }); return *this; } @@ -33,27 +30,27 @@ namespace Ark::internal while (!m_imports.empty()) { - Import import = m_imports.top(); - m_logger.debug("Importing {}", import.toPackageString()); + ImportWithSource source = m_imports.top(); + m_logger.debug("Importing {}", source.import.toPackageString()); // Remove the top element to process the other imports // It needs to be removed first because we might be adding // other imports later and don't want to pop THEM m_imports.pop(); - const auto package = import.toPackageString(); + const auto package = source.import.toPackageString(); if (m_packages.contains(package)) { // merge the definition, so that we can generate valid Full Qualified Names in the name & scope resolver - m_packages[package].import.with_prefix |= import.with_prefix; - m_packages[package].import.is_glob |= import.is_glob; - for (auto&& symbol : import.symbols) + m_packages[package].import.with_prefix |= source.import.with_prefix; + m_packages[package].import.is_glob |= source.import.is_glob; + for (auto&& symbol : source.import.symbols) m_packages[package].import.symbols.push_back(symbol); } else { // NOTE: since the "file" (=root) argument doesn't change between all calls, we could get rid of it - std::vector temp = parseImport(m_root, import); + std::vector temp = parseImport(source.file, source.import); for (auto& additional_import : std::ranges::reverse_view(temp)) m_imports.push(additional_import); } @@ -138,11 +135,11 @@ namespace Ark::internal return m_ast; } - std::vector ImportSolver::parseImport(const std::filesystem::path& base_path, const Import& import) + std::vector ImportSolver::parseImport(const std::filesystem::path& source, const Import& import) { - m_logger.traceStart(fmt::format("parseImport {}", base_path.string())); + m_logger.traceStart(fmt::format("parseImport {}", source.string())); - const auto path = findFile(base_path, import); + const auto path = findFile(source, import); if (path.extension() == ".arkm") // Nothing to import in case of modules { // Creating an import node that will stay there when visiting the AST and @@ -151,9 +148,11 @@ namespace Ark::internal module_node.push_back(Node(Keyword::Import)); auto package_node = Node(NodeType::List); - std::ranges::transform(import.package, std::back_inserter(package_node.list()), [](const std::string& stem) { - return Node(NodeType::String, stem); - }); + std::ranges::transform( + import.package, + std::back_inserter(package_node.list()), [](const std::string& stem) { + return Node(NodeType::String, stem); + }); module_node.push_back(package_node); // empty symbols list module_node.push_back(Node(NodeType::List)); @@ -177,7 +176,15 @@ namespace Ark::internal }; m_logger.traceEnd(); - return parser.imports(); + + auto imports = parser.imports(); + std::vector output; + std::ranges::transform( + imports, + std::back_inserter(output), [&path](const Import& i) { + return ImportWithSource { path, i }; + }); + return output; } std::optional testExtensions(const std::filesystem::path& folder, const std::string& package_path) @@ -205,7 +212,7 @@ namespace Ark::internal // fallback, we couldn't find the file throw CodeError( fmt::format("While processing file {}, couldn't import {}: file not found", - file.generic_string(), import.toPackageString()), + file.filename().string(), import.toPackageString()), CodeErrorContext( file.generic_string(), import.line, diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/import_not_found.ark b/tests/unittests/resources/DiagnosticsSuite/compileTime/import_not_found.ark new file mode 100644 index 000000000..3380577e4 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/import_not_found.ark @@ -0,0 +1,3 @@ +(import error__this_file_will_never_exist) + +(print 1) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/import_not_found.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/import_not_found.expected new file mode 100644 index 000000000..fa65db683 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/import_not_found.expected @@ -0,0 +1,6 @@ +At (import error__this_file_will_never_exist) @ 1:42 + 1 | (import error__this_file_will_never_exist) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | + 3 | (print 1) + While processing file import_not_found.ark, couldn't import error__this_file_will_never_exist: file not found From 65f588822febbbdb41c4efa5f348f7fdb68eb374 Mon Sep 17 00:00:00 2001 From: Alexandre Plateau Date: Tue, 13 May 2025 22:22:08 +0200 Subject: [PATCH 8/8] feat(macro processor, error): adding better error messages when a macro fails, to show the macro we were expanding and what failed --- include/Ark/Compiler/Macros/Executor.hpp | 10 +++++- .../Compiler/Macros/Executors/Conditional.hpp | 2 ++ .../Compiler/Macros/Executors/Function.hpp | 4 ++- .../Ark/Compiler/Macros/Executors/Symbol.hpp | 4 ++- include/Ark/Compiler/Macros/Processor.hpp | 13 ++++---- include/Ark/Exceptions.hpp | 10 ++++++ src/arkreactor/Compiler/Macros/Executor.cpp | 2 +- .../Compiler/Macros/Executors/Conditional.cpp | 5 +++ .../Compiler/Macros/Executors/Function.cpp | 8 +++++ .../Compiler/Macros/Executors/Symbol.cpp | 7 +++++ src/arkreactor/Compiler/Macros/Processor.cpp | 31 +++++++++++++++++-- .../NameResolution/NameResolutionPass.cpp | 2 +- src/arkreactor/Exceptions.cpp | 16 ++++++---- .../unittests/Suites/BytecodeReaderSuite.cpp | 1 - .../compileTime/argcount_unknown_arg.expected | 5 +++ .../compileTime/at_out_of_range.expected | 4 ++- .../compileTime/capture_out_of_scope.expected | 2 +- .../macro_paste_arity_error.expected | 4 ++- .../macro_spread_not_enough_args.expected | 1 + .../macro_symcat_arg_type_error.expected | 4 ++- .../macro_symcat_type_error.expected | 4 ++- .../compileTime/max_depth_eval.expected | 4 ++- .../max_unification_depth.expected | 8 +++++ .../compileTime/not_enough_args.expected | 1 + .../compileTime/too_many_args.expected | 1 + .../compileTime/unbound_capture.expected | 2 +- .../compileTime/undef_macro_number.expected | 4 ++- .../failure/incomplete_arguments.expected | 2 +- .../failure/incomplete_begin.expected | 2 +- .../failure/incomplete_call.expected | 2 +- .../incomplete_macro_arguments.expected | 2 +- 31 files changed, 134 insertions(+), 33 deletions(-) diff --git a/include/Ark/Compiler/Macros/Executor.hpp b/include/Ark/Compiler/Macros/Executor.hpp index 974b61e6e..e782c24d9 100644 --- a/include/Ark/Compiler/Macros/Executor.hpp +++ b/include/Ark/Compiler/Macros/Executor.hpp @@ -58,6 +58,14 @@ namespace Ark::internal */ virtual bool canHandle(Node& node) = 0; + /** + * @brief Returns the macro node that will be expanded + * + * @param node AST node on which the executor will run + * @return Node + */ + virtual Node macroNode(Node& node) = 0; + protected: unsigned int m_debug; MacroProcessor* m_processor; ///< This is a non-owned pointer. @@ -118,7 +126,7 @@ namespace Ark::internal * @param message the error * @param node the node in which there is an error */ - [[noreturn]] static void throwMacroProcessingError(const std::string& message, const Node& node); + [[noreturn]] void throwMacroProcessingError(const std::string& message, const Node& node); }; } diff --git a/include/Ark/Compiler/Macros/Executors/Conditional.hpp b/include/Ark/Compiler/Macros/Executors/Conditional.hpp index 0e88e66de..bc8f56a8b 100644 --- a/include/Ark/Compiler/Macros/Executors/Conditional.hpp +++ b/include/Ark/Compiler/Macros/Executors/Conditional.hpp @@ -39,6 +39,8 @@ namespace Ark::internal * @return true if the executor can handle the given node */ [[nodiscard]] bool canHandle(Node& node) override; + + [[nodiscard]] Node macroNode(Node& node) override; }; } diff --git a/include/Ark/Compiler/Macros/Executors/Function.hpp b/include/Ark/Compiler/Macros/Executors/Function.hpp index e776e3299..60dfa5000 100644 --- a/include/Ark/Compiler/Macros/Executors/Function.hpp +++ b/include/Ark/Compiler/Macros/Executors/Function.hpp @@ -28,7 +28,7 @@ namespace Ark::internal /** * * @param node - * @param depth depth of the macro processor evalution + * @param depth depth of the macro processor evaluation * @return true if the applying worked */ bool applyMacro(Node& node, unsigned depth) override; @@ -40,6 +40,8 @@ namespace Ark::internal */ [[nodiscard]] bool canHandle(Node& node) override; + [[nodiscard]] Node macroNode(Node& node) override; + private: void unify(const std::unordered_map& map, Node& target, Node* parent, std::size_t index = 0, std::size_t unify_depth = 0); }; diff --git a/include/Ark/Compiler/Macros/Executors/Symbol.hpp b/include/Ark/Compiler/Macros/Executors/Symbol.hpp index 5644b50c2..2505c79b3 100644 --- a/include/Ark/Compiler/Macros/Executors/Symbol.hpp +++ b/include/Ark/Compiler/Macros/Executors/Symbol.hpp @@ -28,7 +28,7 @@ namespace Ark::internal /** * * @param node - * @param depth depth of the macro processor evalution + * @param depth depth of the macro processor evaluation * @return true if the applying worked */ bool applyMacro(Node& node, unsigned depth) override; @@ -39,6 +39,8 @@ namespace Ark::internal * @return true if the executor can handle the given node */ [[nodiscard]] bool canHandle(Node& node) override; + + [[nodiscard]] Node macroNode(Node& node) override; }; } diff --git a/include/Ark/Compiler/Macros/Processor.hpp b/include/Ark/Compiler/Macros/Processor.hpp index 61be1a941..54f729fd6 100644 --- a/include/Ark/Compiler/Macros/Processor.hpp +++ b/include/Ark/Compiler/Macros/Processor.hpp @@ -55,8 +55,9 @@ namespace Ark::internal friend class MacroExecutor; private: - Node m_ast; ///< The modified AST - std::vector m_macros; ///< Handling macros in a scope fashion + Node m_ast; ///< The modified AST + std::vector m_macros; ///< Handling macros in a scope fashion + std::vector m_macros_being_applied; ///< Stack of macros being applied. The last one is the current one we are working on std::shared_ptr m_conditional_executor; std::vector> m_executors; std::unordered_map m_defined_functions; @@ -152,7 +153,7 @@ namespace Ark::internal * @param name the name of the macro being applied * @param kind the macro kind, empty by default (eg "operator", "condition") */ - static void checkMacroArgCountEq(const Node& node, std::size_t expected, const std::string& name, const std::string& kind = ""); + void checkMacroArgCountEq(const Node& node, std::size_t expected, const std::string& name, const std::string& kind = ""); /** * @brief Check if the given node has at least the provided argument count, otherwise throws an error @@ -162,7 +163,7 @@ namespace Ark::internal * @param name the name of the macro being applied * @param kind the macro kind, empty by default (eg "operator", "condition") */ - static void checkMacroArgCountGe(const Node& node, std::size_t expected, const std::string& name, const std::string& kind = ""); + void checkMacroArgCountGe(const Node& node, std::size_t expected, const std::string& name, const std::string& kind = ""); /** * @brief Evaluate only the macros @@ -181,7 +182,7 @@ namespace Ark::internal * @return true * @return false */ - static bool isTruthy(const Node& node); + bool isTruthy(const Node& node); /** * @brief Throw a macro processing error @@ -189,7 +190,7 @@ namespace Ark::internal * @param message the error * @param node the node in which there is an error */ - [[noreturn]] static void throwMacroProcessingError(const std::string& message, const Node& node); + [[noreturn]] void throwMacroProcessingError(const std::string& message, const Node& node) const; }; } diff --git a/include/Ark/Exceptions.hpp b/include/Ark/Exceptions.hpp index 7cbc72d42..4cf649bc9 100644 --- a/include/Ark/Exceptions.hpp +++ b/include/Ark/Exceptions.hpp @@ -103,6 +103,7 @@ namespace Ark const std::size_t col; const std::string expr; const std::optional symbol; + const bool is_macro_expansion = false; CodeErrorContext(std::string filename_, const std::size_t lineNum, const std::size_t column, std::string expression, const std::optional maybe_symbol = std::nullopt) : filename(std::move(filename_)), @@ -111,6 +112,15 @@ namespace Ark expr(std::move(expression)), symbol(maybe_symbol) {} + + CodeErrorContext(std::string filename_, const std::size_t lineNum, const std::size_t column, std::string expression, const bool from_macro_expansion) : + filename(std::move(filename_)), + line(lineNum), + col(column), + expr(std::move(expression)), + symbol(std::nullopt), + is_macro_expansion(from_macro_expansion) + {} }; /** diff --git a/src/arkreactor/Compiler/Macros/Executor.cpp b/src/arkreactor/Compiler/Macros/Executor.cpp index 4065d40e6..427fcb579 100644 --- a/src/arkreactor/Compiler/Macros/Executor.cpp +++ b/src/arkreactor/Compiler/Macros/Executor.cpp @@ -36,6 +36,6 @@ namespace Ark::internal void MacroExecutor::throwMacroProcessingError(const std::string& message, const Node& node) { - MacroProcessor::throwMacroProcessingError(message, node); + m_processor->throwMacroProcessingError(message, node); } } diff --git a/src/arkreactor/Compiler/Macros/Executors/Conditional.cpp b/src/arkreactor/Compiler/Macros/Executors/Conditional.cpp index 353ed3607..320a38c5c 100644 --- a/src/arkreactor/Compiler/Macros/Executors/Conditional.cpp +++ b/src/arkreactor/Compiler/Macros/Executors/Conditional.cpp @@ -34,4 +34,9 @@ namespace Ark::internal { return node.nodeType() == NodeType::Macro && node.list()[0].nodeType() == NodeType::Keyword && node.list()[0].keyword() == Keyword::If; } + + Node ConditionalExecutor::macroNode(Node& node) + { + return node; + } } diff --git a/src/arkreactor/Compiler/Macros/Executors/Function.cpp b/src/arkreactor/Compiler/Macros/Executors/Function.cpp index 4e95ed96b..027313a60 100644 --- a/src/arkreactor/Compiler/Macros/Executors/Function.cpp +++ b/src/arkreactor/Compiler/Macros/Executors/Function.cpp @@ -87,6 +87,14 @@ namespace Ark::internal return false; } + Node FunctionExecutor::macroNode(Node& node) + { + const Node& first = node.list()[0]; + if (const Node* macro = findNearestMacro(first.string()); macro != nullptr && macro->constList().size() == 3) + return *macro; + return {}; + } + void FunctionExecutor::unify(const std::unordered_map& map, Node& target, Node* parent, const std::size_t index, const std::size_t unify_depth) { if (unify_depth > MaxMacroUnificationDepth) diff --git a/src/arkreactor/Compiler/Macros/Executors/Symbol.cpp b/src/arkreactor/Compiler/Macros/Executors/Symbol.cpp index 658a6ee00..07aad53b3 100644 --- a/src/arkreactor/Compiler/Macros/Executors/Symbol.cpp +++ b/src/arkreactor/Compiler/Macros/Executors/Symbol.cpp @@ -23,4 +23,11 @@ namespace Ark::internal return false; } + + Node SymbolExecutor::macroNode(Node& node) + { + if (const Node* macro = findNearestMacro(node.string()); macro != nullptr) + return *macro; + return {}; + } } diff --git a/src/arkreactor/Compiler/Macros/Processor.cpp b/src/arkreactor/Compiler/Macros/Processor.cpp index 0a4fe8a70..09b067c88 100644 --- a/src/arkreactor/Compiler/Macros/Processor.cpp +++ b/src/arkreactor/Compiler/Macros/Processor.cpp @@ -197,7 +197,11 @@ namespace Ark::internal { if (executor->canHandle(node)) { - if (executor->applyMacro(node, depth)) + m_macros_being_applied.push_back(executor->macroNode(node)); + const bool applied = executor->applyMacro(node, depth); + m_macros_being_applied.pop_back(); + + if (applied) return true; } } @@ -733,8 +737,29 @@ namespace Ark::internal return false; } - void MacroProcessor::throwMacroProcessingError(const std::string& message, const Node& node) + void MacroProcessor::throwMacroProcessingError(const std::string& message, const Node& node) const { - throw CodeError(message, CodeErrorContext(node.filename(), node.line(), node.col(), node.repr())); + const std::optional maybe_context = [this]() -> std::optional { + if (!m_macros_being_applied.empty()) + { + const Node& origin = m_macros_being_applied.front(); + return CodeErrorContext( + origin.filename(), + origin.line(), + origin.col(), + origin.repr(), + /* from_macro_expansion= */ true); + } + return std::nullopt; + }(); + + throw CodeError( + message, + CodeErrorContext( + node.filename(), + node.line(), + node.col(), + node.repr()), + maybe_context); } } diff --git a/src/arkreactor/Compiler/NameResolution/NameResolutionPass.cpp b/src/arkreactor/Compiler/NameResolution/NameResolutionPass.cpp index 544c3ff11..01ac629de 100644 --- a/src/arkreactor/Compiler/NameResolution/NameResolutionPass.cpp +++ b/src/arkreactor/Compiler/NameResolution/NameResolutionPass.cpp @@ -243,7 +243,7 @@ namespace Ark::internal { if (!m_scope_resolver.isRegistered(child.string()) && register_declarations) throw CodeError( - fmt::format("Can not capture {} because it is referencing a variable defined in an unreachable scope.", child.string()), + fmt::format("Can not capture `{}' because it is referencing a variable defined in an unreachable scope.", child.string()), CodeErrorContext( child.filename(), child.line(), diff --git a/src/arkreactor/Exceptions.cpp b/src/arkreactor/Exceptions.cpp index e63110545..582e5092f 100644 --- a/src/arkreactor/Exceptions.cpp +++ b/src/arkreactor/Exceptions.cpp @@ -136,7 +136,9 @@ namespace Ark::Diagnostics " ", std::max(1_z, maybe_context->col), // fixing padding when the error is on the first character // underline the parent of the error in red - fmt::styled("^ expression started here", colorize ? fmt::fg(fmt::color::red) : fmt::text_style())); + fmt::styled( + maybe_context->is_macro_expansion ? "^ macro expansion started here" : "^ expression started here", + colorize ? fmt::fg(fmt::color::red) : fmt::text_style())); }; const std::string code = filename == ARK_NO_NAME_FILE ? "" : Utils::readFile(filename); @@ -240,17 +242,17 @@ namespace Ark::Diagnostics fmt::print( os, - "{: <{}}{}{}{: <{}}\n", + "{: <{}}{}{}{}\n", // padding of spaces " ", padding_size, // indicate where the parent is, with color fmt::styled("│", colorize ? fmt::fg(fmt::color::red) : fmt::text_style()), // yet another padding of spaces between the parent and error column (if need be) - (maybe_context->col == col_start) ? "" : fmt::format("{: <{}}", " ", col_start - maybe_context->col), + // -2 to account for the │ and then └ + (col_start - maybe_context->col <= 2) ? "" : fmt::format("{: <{}}", " ", col_start - maybe_context->col - 2), // underline the error in red - fmt::styled("└─ error", colorize ? fmt::fg(fmt::color::red) : fmt::text_style()), - col_end - curr_col_start); + fmt::styled("└─ error", colorize ? fmt::fg(fmt::color::red) : fmt::text_style())); // new line, some spacing between the error and the parent fmt::print(os, "{}{: <{}}{}\n", line_no_num, " ", padding_size, fmt::styled("│", colorize ? fmt::fg(fmt::color::red) : fmt::text_style())); // new line, now show the "expression started here for the source" @@ -261,7 +263,9 @@ namespace Ark::Diagnostics // padding of spaces " ", padding_size, - fmt::styled("└─ expression started here", colorize ? fmt::fg(fmt::color::red) : fmt::text_style())); + fmt::styled( + maybe_context->is_macro_expansion ? "└─ macro expansion started here" : "└─ expression started here", + colorize ? fmt::fg(fmt::color::red) : fmt::text_style())); } } else diff --git a/tests/unittests/Suites/BytecodeReaderSuite.cpp b/tests/unittests/Suites/BytecodeReaderSuite.cpp index 278aa9ca4..cae21c58b 100644 --- a/tests/unittests/Suites/BytecodeReaderSuite.cpp +++ b/tests/unittests/Suites/BytecodeReaderSuite.cpp @@ -63,7 +63,6 @@ ut::suite<"BytecodeReader"> bcr_suite = [] { const auto symbols_block = bcr.symbols(); const auto values_block = bcr.values(symbols_block); - // todo test the filenames and inst_locations block const auto filenames_block = bcr.filenames(values_block); const auto inst_locations_block = bcr.instLocations(filenames_block); const auto [pages, start_code] = bcr.code(inst_locations_block); diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/argcount_unknown_arg.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/argcount_unknown_arg.expected index 2d1069540..a9dab0057 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/argcount_unknown_arg.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/argcount_unknown_arg.expected @@ -1,4 +1,9 @@ At test_func1!2 @ 13:28 + 1 | ($ suffix-dup (sym x) { + | ^ macro expansion started here + 2 | ($if (> x 1) + 3 | (suffix-dup sym (- x 1))) + ... | 10 | 11 | (let test_func (fun (a b c) (* a b c))) 12 | (let test_func1 (partial test_func 1)) 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 05b5c61c4..310e4500b 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,8 @@ At (@ (list 1 5 6 7 8) -9) @ 1:39 1 | ($ last (...args) (print args " => " (@ args -9))) - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | │ └─ error + | │ + | └─ macro expansion started here 2 | (last 1 5 6 7 8) 3 | Index (-9) out of range (list size: 5) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/capture_out_of_scope.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/capture_out_of_scope.expected index fea121a05..cf5d72277 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/capture_out_of_scope.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/capture_out_of_scope.expected @@ -4,4 +4,4 @@ At &cap @ 2:16 | ^~~~ 3 | (print foo bar) 4 | - Can not capture cap because it is referencing a variable defined in an unreachable scope. + Can not capture `cap' because it is referencing a variable defined in an unreachable scope. 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 32186a79a..4ee58c3e2 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,8 @@ At ($as-is b (list)) @ 1:7 1 | ($ a ($as-is b [])) - | ^~~~~~~~~~~~~~~~~~~ + | │ └─ error + | │ + | └─ macro expansion started here 2 | (print a) 3 | When expanding `$as-is', expected one argument, got 2 arguments 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 a28687bf3..207309094 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,6 @@ At (foo 1 2) @ 4:2 1 | ($ foo (a b c ...d) + | ^ macro expansion started here 2 | (+ a b c ...d)) 3 | 4 | (foo 1 2) 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 369d68cbb..e256d20ca 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,8 @@ At (list) @ 1:17 1 | ($ a ($symcat b [])) - | ^~~~~~~~~~~~~~~~~~~~ + | │ └─ error + | │ + | └─ macro expansion started here 2 | (print a) 3 | When expanding `$symcat', expected either a Number, String or Symbol, got a List: (list) 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 6460fe57c..84c45af34 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,8 @@ At ($symcat 5 2) @ 1:7 1 | ($ a ($symcat 5 2)) - | ^~~~~~~~~~~~~~~~~~~ + | │ └─ error + | │ + | └─ macro expansion started here 2 | (print a) 3 | When expanding `$symcat', expected the first argument to be a Symbol, got a Number: 5 diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth_eval.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth_eval.expected index 7c3a93041..c8ec839df 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth_eval.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_depth_eval.expected @@ -1,6 +1,8 @@ At last @ 1:11 1 | ($ last ((last 1 5 6 7 8) 0 s "@" (@ a00s -9))) - | ^~~~ + | │ └─ error + | │ + | └─ macro expansion started here 2 | (last 1 5 6 7 8) 3 | Max macro processing 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/max_unification_depth.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_unification_depth.expected index a2f459e52..3348b031c 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/max_unification_depth.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/max_unification_depth.expected @@ -1,4 +1,12 @@ 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))) + 5 | ($symcat sym x)}) + 6 | + 7 | ($ partial (func ...defargs) { + | ^ macro expansion started here + 8 | ($ 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 diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/not_enough_args.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/not_enough_args.expected index 8afb9153b..7f6a83e25 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/not_enough_args.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/not_enough_args.expected @@ -1,5 +1,6 @@ At (foo 1 2) @ 4:2 1 | ($ foo (a b c) + | ^ macro expansion started here 2 | (+ a b c)) 3 | 4 | (foo 1 2) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/too_many_args.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/too_many_args.expected index a17b664c6..73c522838 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/too_many_args.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/too_many_args.expected @@ -1,5 +1,6 @@ At (foo 1 2 3 4) @ 4:2 1 | ($ foo (a b c) + | ^ macro expansion started here 2 | (+ a b c)) 3 | 4 | (foo 1 2 3 4) diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/unbound_capture.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/unbound_capture.expected index cc8727029..3082c456f 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/unbound_capture.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/unbound_capture.expected @@ -2,4 +2,4 @@ At &d @ 1:14 1 | (mut d (fun (&d) (print d))) | ^~ 2 | - Can not capture d because it is referencing a variable defined in an unreachable scope. + Can not capture `d' because it is referencing a variable defined in an unreachable scope. diff --git a/tests/unittests/resources/DiagnosticsSuite/compileTime/undef_macro_number.expected b/tests/unittests/resources/DiagnosticsSuite/compileTime/undef_macro_number.expected index eb943bab2..92394b39d 100644 --- a/tests/unittests/resources/DiagnosticsSuite/compileTime/undef_macro_number.expected +++ b/tests/unittests/resources/DiagnosticsSuite/compileTime/undef_macro_number.expected @@ -1,5 +1,7 @@ At 1 @ 1:9 1 | ($undef 1) - | ^ + | │ └─ error + | │ + | └─ macro expansion started here 2 | When expanding `$undef', got a Number. Can not un-define a macro without a valid name diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_arguments.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_arguments.expected index ea68b9000..7306decf3 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_arguments.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_arguments.expected @@ -1,7 +1,7 @@ In file tests/unittests/resources/ParserSuite/failure/incomplete_arguments.ark:1 At EOF @ 1:7 1 | (fun (a - | │ └─ error + | │└─ error | │ | └─ expression started here Missing ')' in function call to `a' diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_begin.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_begin.expected index 38a7df9cd..580f393ff 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_begin.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_begin.expected @@ -1,7 +1,7 @@ In file tests/unittests/resources/ParserSuite/failure/incomplete_begin.ark:1 At EOF @ 1:15 1 | { a b (let c d) - | │ └─ error + | │ └─ error | │ | └─ expression started here Missing '}' to close block diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_call.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_call.expected index c80af1029..134fb0204 100644 --- a/tests/unittests/resources/ParserSuite/failure/incomplete_call.expected +++ b/tests/unittests/resources/ParserSuite/failure/incomplete_call.expected @@ -1,7 +1,7 @@ In file tests/unittests/resources/ParserSuite/failure/incomplete_call.ark:1 At EOF @ 1:25 1 | (a b c (if (ok true) 1 2) - | │ └─ error + | │ └─ error | │ | └─ expression started here Missing ')' in function call to `a' diff --git a/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.expected b/tests/unittests/resources/ParserSuite/failure/incomplete_macro_arguments.expected index c473d102d..ac4c32441 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 + | │└─ error | │ | └─ expression started here Missing ')' in function call to `a'