diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp index 58ab42773dd4a0754bf43e8e5cba89d29da5574f..fbf7b60a21d0ea6aed9e9609d2b4c733a56fbcbc 100644 --- a/src/language/PugsParser.cpp +++ b/src/language/PugsParser.cpp @@ -1,6 +1,7 @@ #include <language/PugsParser.hpp> #include <language/PEGGrammar.hpp> +#include <language/ast/ASTBacktrace.hpp> #include <language/ast/ASTBuilder.hpp> #include <language/ast/ASTModulesImporter.hpp> #include <language/ast/ASTNode.hpp> @@ -31,6 +32,7 @@ #include <fstream> #include <iostream> +#include <memory> #include <sstream> #include <unordered_map> #include <variant> @@ -53,8 +55,8 @@ parser(const std::string& filename) auto parse_and_execute = [](auto& input) { OperatorRepository::create(); - - std::unique_ptr<ASTNode> root_node = ASTBuilder::build(input); + ASTBacktrace::create(input); + std::unique_ptr<ASTNode> root_node = ASTBuilder::build(*input); ASTModulesImporter module_importer{*root_node}; ASTNodeTypeCleaner<language::import_instruction>{*root_node}; @@ -94,8 +96,8 @@ parser(const std::string& filename) OperatorRepository::destroy(); }; + auto input = std::make_shared<TAO_PEGTL_NAMESPACE::file_input<>>(filename); if (not SignalManager::pauseOnError()) { - TAO_PEGTL_NAMESPACE::read_input input(filename); try { parse_and_execute(input); } @@ -119,13 +121,18 @@ parser(const std::string& filename) std::cerr << rang::style::bold << p.source << ':' << p.line << ':' << p.column << ": " << rang::style::reset << rang::fgB::red << "error: " << rang::fg::reset << rang::style::bold << message << rang::style::reset << '\n' - << input.line_at(p) << '\n' + << input->line_at(p) << '\n' << std::string(p.column - 1, ' ') << rang::fgB::yellow << '^' << rang::fg::reset << '\n'; finalize(); std::exit(1); } + catch (const IExitError& e) { + std::cerr << ASTBacktrace::getInstance().errorMessageAt(e.what()) << '\n'; + + finalize(); + std::exit(1); + } } else { - TAO_PEGTL_NAMESPACE::read_input input(filename); parse_and_execute(input); } } diff --git a/src/language/ast/ASTBacktrace.cpp b/src/language/ast/ASTBacktrace.cpp new file mode 100644 index 0000000000000000000000000000000000000000..18442ec439194924fe83a5080b5bee2016eab4da --- /dev/null +++ b/src/language/ast/ASTBacktrace.cpp @@ -0,0 +1,63 @@ +#include <language/ast/ASTBacktrace.hpp> + +#include <language/ast/ASTNode.hpp> + +ASTBacktrace* ASTBacktrace::m_instance = nullptr; + +ASTBacktrace::ASTBacktrace(const std::shared_ptr<TAO_PEGTL_NAMESPACE::file_input<>>& file_input) + : m_file_input(file_input) +{} + +std::string +ASTBacktrace::errorMessageAt(const std::string& message) const +{ + auto& stack = ASTBacktrace::getInstance().m_stack; + std::ostringstream error_msg; + + auto p = stack[stack.size() - 1]->begin(); + error_msg << rang::style::bold << p.source << ':' << p.line << ':' << p.column << ": " << rang::style::reset + << message << rang::fg::reset << '\n'; + + if (m_file_input.use_count() > 0) { + error_msg << m_file_input->line_at(p) << '\n' + << std::string(p.column - 1, ' ') << rang::fgB::yellow << '^' << rang::fg::reset << '\n'; + } + + return error_msg.str(); +} + +SourceLocation +ASTBacktrace::sourceLocation() const +{ + auto& stack = ASTBacktrace::getInstance().m_stack; + + auto p = stack[stack.size() - 1]->begin(); + return SourceLocation(p.source, p.line, p.column); +} + +void +ASTBacktrace::create() +{ + if (m_instance == nullptr) { + m_instance = new ASTBacktrace(); + } else { + throw UnexpectedError("ASTBackTrace was already created!"); + } +} + +void +ASTBacktrace::create(const std::shared_ptr<TAO_PEGTL_NAMESPACE::file_input<>>& file_input) +{ + if (m_instance == nullptr) { + m_instance = new ASTBacktrace(file_input); + } else { + throw UnexpectedError("ASTBackTrace was already created!"); + } +} + +void +ASTBacktrace::destroy() +{ + delete m_instance; + m_instance = nullptr; +} diff --git a/src/language/ast/ASTBacktrace.hpp b/src/language/ast/ASTBacktrace.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6ea9a53645ea4c4fda5c35585a80e44392254b5f --- /dev/null +++ b/src/language/ast/ASTBacktrace.hpp @@ -0,0 +1,57 @@ +#ifndef AST_BACTRACE_HPP +#define AST_BACTRACE_HPP + +#include <utils/PugsAssert.hpp> +#include <utils/SourceLocation.hpp> + +#include <pegtl/file_input.hpp> +#include <string> +#include <vector> + +class ASTNode; +class ASTBacktrace +{ + private: + std::vector<const ASTNode*> m_stack; + + std::shared_ptr<TAO_PEGTL_NAMESPACE::file_input<>> m_file_input; + + static ASTBacktrace* m_instance; + + ASTBacktrace() = default; + ASTBacktrace(const std::shared_ptr<TAO_PEGTL_NAMESPACE::file_input<>>& file_input); + ~ASTBacktrace() = default; + + public: + std::string errorMessageAt(const std::string& error_msg) const; + + SourceLocation sourceLocation() const; + + void + push(const ASTNode* node) + { + m_stack.push_back(node); + } + + void + pop() + { + m_stack.pop_back(); + } + + static void create(); // for unit tests only + static void create(const std::shared_ptr<TAO_PEGTL_NAMESPACE::file_input<>>& file_input); + static void destroy(); + + static ASTBacktrace& + getInstance() + { + Assert(m_instance != nullptr); + return *m_instance; + } + + ASTBacktrace(const ASTBacktrace&) = delete; + ASTBacktrace(ASTBacktrace&&) = delete; +}; + +#endif // AST_BACTRACE_HPP diff --git a/src/language/ast/ASTBuilder.cpp b/src/language/ast/ASTBuilder.cpp index 326d4139e709507c95f6d40f49ca1f87411b7b5c..d7d8dbc1fe9936a734a395695570d982a9b10779 100644 --- a/src/language/ast/ASTBuilder.cpp +++ b/src/language/ast/ASTBuilder.cpp @@ -312,5 +312,5 @@ ASTBuilder::build(InputT& input) return root_node; } -template std::unique_ptr<ASTNode> ASTBuilder::build(TAO_PEGTL_NAMESPACE::read_input<>& input); +template std::unique_ptr<ASTNode> ASTBuilder::build(TAO_PEGTL_NAMESPACE::file_input<>& input); template std::unique_ptr<ASTNode> ASTBuilder::build(TAO_PEGTL_NAMESPACE::string_input<>& input); diff --git a/src/language/ast/ASTNode.cpp b/src/language/ast/ASTNode.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cddc0b4898035c65f546dd31d0e4eead68c6a998 --- /dev/null +++ b/src/language/ast/ASTNode.cpp @@ -0,0 +1,3 @@ +#include <language/ast/ASTNode.hpp> + +bool ASTNode::m_stack_details = true; diff --git a/src/language/ast/ASTNode.hpp b/src/language/ast/ASTNode.hpp index f9f9ad6db2b7302bb657722a2dc91988e051a146..19b43a9272229d97bef9c96a8210506e23513a40 100644 --- a/src/language/ast/ASTNode.hpp +++ b/src/language/ast/ASTNode.hpp @@ -1,6 +1,7 @@ #ifndef AST_NODE_HPP #define AST_NODE_HPP +#include <language/ast/ASTBacktrace.hpp> #include <language/node_processor/ExecutionPolicy.hpp> #include <language/node_processor/INodeProcessor.hpp> #include <language/utils/ASTNodeDataType.hpp> @@ -9,13 +10,18 @@ #include <utils/PugsAssert.hpp> #include <utils/PugsMacros.hpp> +#include <pegtl.hpp> #include <pegtl/contrib/parse_tree.hpp> +inline TAO_PEGTL_NAMESPACE::file_input<>* p_file_input = nullptr; + class SymbolTable; class ASTNode : public TAO_PEGTL_NAMESPACE::parse_tree::basic_node<ASTNode> { private: + static bool m_stack_details; + PUGS_INLINE decltype(m_end) _getEnd() const @@ -41,6 +47,18 @@ class ASTNode : public TAO_PEGTL_NAMESPACE::parse_tree::basic_node<ASTNode> } public: + static bool + getStackDetails() + { + return m_stack_details; + } + + static void + setStackDetails(const bool stack_details) + { + m_stack_details = stack_details; + } + std::shared_ptr<SymbolTable> m_symbol_table; std::unique_ptr<INodeProcessor> m_node_processor; @@ -88,8 +106,29 @@ class ASTNode : public TAO_PEGTL_NAMESPACE::parse_tree::basic_node<ASTNode> execute(ExecutionPolicy& exec_policy) { Assert(m_node_processor, "undefined node processor"); + if (exec_policy.exec()) { - return m_node_processor->execute(exec_policy); + if (m_stack_details) { + if (m_node_processor->type() == INodeProcessor::Type::builtin_function_processor) { + ASTBacktrace::getInstance().push(this); + + m_stack_details = false; + auto result = m_node_processor->execute(exec_policy); + m_stack_details = true; + + ASTBacktrace::getInstance().pop(); + + return result; + } else { + ASTBacktrace::getInstance().push(this); + auto result = m_node_processor->execute(exec_policy); + ASTBacktrace::getInstance().pop(); + + return result; + } + } else { + return m_node_processor->execute(exec_policy); + } } else { return {}; } diff --git a/src/language/ast/CMakeLists.txt b/src/language/ast/CMakeLists.txt index a901d7c09679c37d54420f51d347537fe5e18aef..63e208c2b153b7f05318ee15066f5da0f7e2cb8c 100644 --- a/src/language/ast/CMakeLists.txt +++ b/src/language/ast/CMakeLists.txt @@ -1,8 +1,10 @@ # ------------------- Source files -------------------- add_library(PugsLanguageAST + ASTBacktrace.cpp ASTBuilder.cpp ASTModulesImporter.cpp + ASTNode.cpp ASTNodeAffectationExpressionBuilder.cpp ASTNodeArraySubscriptExpressionBuilder.cpp ASTNodeBinaryOperatorExpressionBuilder.cpp diff --git a/src/language/node_processor/ASTNodeExpressionListProcessor.hpp b/src/language/node_processor/ASTNodeExpressionListProcessor.hpp index 21823176e8b7f8d9eb0c0760c52ae0fb1749f0e3..bc6f2788f1d4e524339f8fc320d7351e1f825836 100644 --- a/src/language/node_processor/ASTNodeExpressionListProcessor.hpp +++ b/src/language/node_processor/ASTNodeExpressionListProcessor.hpp @@ -76,6 +76,12 @@ class ASTNodeExpressionListProcessor final : public INodeProcessor } public: + Type + type() const + { + return Type::expression_list_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/ASTNodeListProcessor.hpp b/src/language/node_processor/ASTNodeListProcessor.hpp index 5a9d8c0b8be23ad9c563ce7d8ed30f25df29505f..142d33f7d7ce085b57c3a3746f9f559c87e4408e 100644 --- a/src/language/node_processor/ASTNodeListProcessor.hpp +++ b/src/language/node_processor/ASTNodeListProcessor.hpp @@ -12,6 +12,12 @@ class ASTNodeListProcessor final : public INodeProcessor ASTNode& m_node; public: + Type + type() const + { + return Type::list_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/AffectationProcessor.hpp b/src/language/node_processor/AffectationProcessor.hpp index 8fea3a7546b9f96298e97b0603a849c84915f47a..b18665a0fdd572590822e2592090ba7441b9856e 100644 --- a/src/language/node_processor/AffectationProcessor.hpp +++ b/src/language/node_processor/AffectationProcessor.hpp @@ -453,6 +453,12 @@ class AffectationProcessor final : public INodeProcessor } public: + Type + type() const + { + return Type::affectation_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { @@ -495,6 +501,12 @@ class AffectationToTupleProcessor final : public AffectationToDataVariantProcess ASTNode& m_rhs_node; public: + Type + type() const + { + return Type::affectation_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { @@ -555,6 +567,12 @@ class AffectationFromTupleProcessor final : public AffectationToDataVariantProce ASTNode& m_rhs_node; public: + Type + type() const + { + return Type::affectation_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { @@ -682,6 +700,12 @@ class AffectationToTupleFromListProcessor final : public AffectationToDataVarian } public: + Type + type() const + { + return Type::affectation_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { @@ -755,6 +779,12 @@ class AffectationToTupleFromTupleProcessor final : public AffectationToDataVaria } public: + Type + type() const + { + return Type::affectation_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { @@ -787,6 +817,12 @@ template <typename ValueT> class AffectationFromZeroProcessor final : public AffectationToDataVariantProcessorBase { public: + Type + type() const + { + return Type::affectation_processor; + } + DataVariant execute(ExecutionPolicy&) { @@ -830,6 +866,12 @@ class ListAffectationProcessor final : public INodeProcessor } } + Type + type() const + { + return Type::affectation_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { @@ -938,6 +980,12 @@ class ListAffectationFromTupleProcessor final : public INodeProcessor } } + Type + type() const + { + return Type::affectation_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/ArraySubscriptProcessor.hpp b/src/language/node_processor/ArraySubscriptProcessor.hpp index 43eb962b9d724b19b4cfe7ab808f52dd73d1fce2..4166c0d98ba34c3d390dc69524a7145b4e4a7cdb 100644 --- a/src/language/node_processor/ArraySubscriptProcessor.hpp +++ b/src/language/node_processor/ArraySubscriptProcessor.hpp @@ -12,6 +12,12 @@ class ArraySubscriptProcessor : public INodeProcessor ASTNode& m_array_subscript_expression; public: + Type + type() const + { + return Type::array_subscript_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/BinaryExpressionProcessor.hpp b/src/language/node_processor/BinaryExpressionProcessor.hpp index a2111464ce05a8148ff4886f9614952641ed65d5..d91f39d905c1f055ed7d95d6a15ff7f258fc2385 100644 --- a/src/language/node_processor/BinaryExpressionProcessor.hpp +++ b/src/language/node_processor/BinaryExpressionProcessor.hpp @@ -223,6 +223,12 @@ struct BinaryExpressionProcessor final : public INodeProcessor } public: + Type + type() const + { + return Type::binary_expression_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { @@ -253,6 +259,12 @@ struct BinaryExpressionProcessor<BinaryOpT, std::shared_ptr<ValueT>, std::shared } public: + Type + type() const + { + return Type::binary_expression_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { @@ -290,6 +302,12 @@ struct BinaryExpressionProcessor<BinaryOpT, std::shared_ptr<ValueT>, A_DataT, st } public: + Type + type() const + { + return Type::binary_expression_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { @@ -328,6 +346,12 @@ struct BinaryExpressionProcessor<BinaryOpT, std::shared_ptr<ValueT>, std::shared } public: + Type + type() const + { + return Type::binary_expression_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/BreakProcessor.hpp b/src/language/node_processor/BreakProcessor.hpp index 6f6d4a306c99723ab2e5ce7f4fc4864eebd77926..d403d89fe4b8e5abbad4fec9e85b264e1294017d 100644 --- a/src/language/node_processor/BreakProcessor.hpp +++ b/src/language/node_processor/BreakProcessor.hpp @@ -6,6 +6,12 @@ class BreakProcessor final : public INodeProcessor { public: + Type + type() const + { + return Type::break_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/BuiltinFunctionProcessor.hpp b/src/language/node_processor/BuiltinFunctionProcessor.hpp index 7e5a112b46f32792cf2fda652379a4a5f2f064aa..e427160a44cbbb78be3067e6526e44e2f65c8b53 100644 --- a/src/language/node_processor/BuiltinFunctionProcessor.hpp +++ b/src/language/node_processor/BuiltinFunctionProcessor.hpp @@ -7,14 +7,18 @@ #include <language/utils/BuiltinFunctionEmbedder.hpp> #include <language/utils/ParseError.hpp> -#include <utils/SignalManager.hpp> - class BuiltinFunctionExpressionProcessor final : public INodeProcessor { private: std::shared_ptr<IBuiltinFunctionEmbedder> m_embedded; public: + Type + type() const + { + return Type::builtin_function_expression_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { @@ -46,6 +50,12 @@ class BuiltinFunctionProcessor : public INodeProcessor m_function_expression_processor = std::move(function_processor); } + Type + type() const + { + return Type::builtin_function_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { @@ -74,18 +84,7 @@ class BuiltinFunctionProcessor : public INodeProcessor } } - if (SignalManager::pauseOnError()) { - // LCOV_EXCL_START - return m_function_expression_processor->execute(context_exec_policy); - // LCOV_EXCL_STOP - } else { - try { - return m_function_expression_processor->execute(context_exec_policy); - } - catch (std::runtime_error& e) { - throw ParseError(e.what(), {m_argument_node.begin()}); - } - } + return m_function_expression_processor->execute(context_exec_policy); } BuiltinFunctionProcessor(ASTNode& argument_node) : m_argument_node{argument_node} {} diff --git a/src/language/node_processor/ConcatExpressionProcessor.hpp b/src/language/node_processor/ConcatExpressionProcessor.hpp index 4653c341c7b322fb338e15c09dada90b98472a8c..5fa6bbbdac7c0c06f57737fb2197c8323ef02cf6 100644 --- a/src/language/node_processor/ConcatExpressionProcessor.hpp +++ b/src/language/node_processor/ConcatExpressionProcessor.hpp @@ -41,6 +41,12 @@ class ConcatExpressionProcessor final : public INodeProcessor } public: + Type + type() const + { + return Type::concat_expression_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/ContinueProcessor.hpp b/src/language/node_processor/ContinueProcessor.hpp index e8e5d6c7daf807c94986ea58f40e327a60f5a7a4..c98ad4312136e89a55a1661ae9bf412e8243e060 100644 --- a/src/language/node_processor/ContinueProcessor.hpp +++ b/src/language/node_processor/ContinueProcessor.hpp @@ -6,6 +6,12 @@ class ContinueProcessor final : public INodeProcessor { public: + Type + type() const + { + return Type::continue_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/DoWhileProcessor.hpp b/src/language/node_processor/DoWhileProcessor.hpp index 6f3c14b7f8706c6d5480f792e449c1f110b74498..593fd4bf178ea0734ce4e512fd913c4cc760ee98 100644 --- a/src/language/node_processor/DoWhileProcessor.hpp +++ b/src/language/node_processor/DoWhileProcessor.hpp @@ -11,6 +11,12 @@ class DoWhileProcessor final : public INodeProcessor ASTNode& m_node; public: + Type + type() const + { + return Type::do_while_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/FakeProcessor.hpp b/src/language/node_processor/FakeProcessor.hpp index ce3b7d257aa8d3684fd06ff87496ce1b66fa9bf5..f947ec2a10d0e62ac7f1c977e698cf0f1fa46794 100644 --- a/src/language/node_processor/FakeProcessor.hpp +++ b/src/language/node_processor/FakeProcessor.hpp @@ -6,6 +6,12 @@ class FakeProcessor final : public INodeProcessor { public: + Type + type() const + { + return Type::fake_processor; + } + DataVariant execute(ExecutionPolicy&) { diff --git a/src/language/node_processor/ForProcessor.hpp b/src/language/node_processor/ForProcessor.hpp index 4199e0c42867398167c2f1fa5927d87e7f4fddc6..674c7d05ea4e6f89c4941eddc15540556961ae87 100644 --- a/src/language/node_processor/ForProcessor.hpp +++ b/src/language/node_processor/ForProcessor.hpp @@ -11,6 +11,12 @@ class ForProcessor final : public INodeProcessor ASTNode& m_node; public: + Type + type() const + { + return Type::for_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/FunctionProcessor.hpp b/src/language/node_processor/FunctionProcessor.hpp index 2b3e65ecb130c6f50105a5cba08552e43e16596c..69ca0e488be67ae618f2f893049bd48a2a635d8d 100644 --- a/src/language/node_processor/FunctionProcessor.hpp +++ b/src/language/node_processor/FunctionProcessor.hpp @@ -16,6 +16,12 @@ class FunctionExpressionProcessor final : public INodeProcessor ASTNode& m_function_expression; public: + Type + type() const + { + return Type::function_expression_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { @@ -292,6 +298,12 @@ class FunctionProcessor : public INodeProcessor m_function_expression_processors.emplace_back(std::move(function_processor)); } + Type + type() const + { + return Type::function_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/INodeProcessor.hpp b/src/language/node_processor/INodeProcessor.hpp index 2c35b6c49cadd69536c415f5a86e5786c953a86c..942a22717c7678d9d82902f4da534b7a0b9e1357 100644 --- a/src/language/node_processor/INodeProcessor.hpp +++ b/src/language/node_processor/INodeProcessor.hpp @@ -11,6 +11,37 @@ class INodeProcessor { public: + enum class Type + { + affectation_processor, + array_subscript_processor, + binary_expression_processor, + break_processor, + builtin_function_expression_processor, + builtin_function_processor, + concat_expression_processor, + continue_processor, + do_while_processor, + expression_list_processor, + fake_processor, + for_processor, + function_expression_processor, + function_processor, + if_processor, + inc_dec_expression_processor, + inner_list_to_vector_processor, + list_processor, + local_name_processor, + name_processor, + tiny_matrix_expression_processor, + tiny_vector_expression_processor, + unary_expression_processor, + value_processor, + while_processor + }; + + virtual Type type() const = 0; + virtual DataVariant execute(ExecutionPolicy& exec_policy) = 0; std::string diff --git a/src/language/node_processor/IfProcessor.hpp b/src/language/node_processor/IfProcessor.hpp index 18d87bb89f11ee0f335fe0637f4569dc5b3cab15..0d7497eaf832d257d12dec349de4fe0c6b033ab9 100644 --- a/src/language/node_processor/IfProcessor.hpp +++ b/src/language/node_processor/IfProcessor.hpp @@ -11,6 +11,12 @@ class IfProcessor final : public INodeProcessor ASTNode& m_node; public: + Type + type() const + { + return Type::if_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/IncDecExpressionProcessor.hpp b/src/language/node_processor/IncDecExpressionProcessor.hpp index 199d3ebb834e7b89dfdc714b89977c6ae78c7b0c..186d3da7c3e7524863ee690067286a79ff4f34c1 100644 --- a/src/language/node_processor/IncDecExpressionProcessor.hpp +++ b/src/language/node_processor/IncDecExpressionProcessor.hpp @@ -71,6 +71,12 @@ class IncDecExpressionProcessor final : public INodeProcessor DataVariant* p_value{nullptr}; public: + Type + type() const + { + return Type::inc_dec_expression_processor; + } + DataVariant execute(ExecutionPolicy&) { diff --git a/src/language/node_processor/InnerListToVectorProcessor.hpp b/src/language/node_processor/InnerListToVectorProcessor.hpp index ef74daaabe5c0e2f475b1693b7bb9627ed600f40..12ab335b1c6e38ba477da91a06ad19329c3fc8aa 100644 --- a/src/language/node_processor/InnerListToVectorProcessor.hpp +++ b/src/language/node_processor/InnerListToVectorProcessor.hpp @@ -11,6 +11,12 @@ class InnerListToVectorProcessor final : public INodeProcessor std::unique_ptr<ASTNodeExpressionListProcessor> m_expression_list_processor; public: + Type + type() const + { + return Type::inner_list_to_vector_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/LocalNameProcessor.hpp b/src/language/node_processor/LocalNameProcessor.hpp index 51d442b266288360c1d5f6fe000ba72fa7057cb9..e7d7f40d849f6325387be26af49a0bbfe3971a6d 100644 --- a/src/language/node_processor/LocalNameProcessor.hpp +++ b/src/language/node_processor/LocalNameProcessor.hpp @@ -13,6 +13,12 @@ class LocalNameProcessor final : public INodeProcessor int32_t m_context_id; public: + Type + type() const + { + return Type::local_name_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/NameProcessor.hpp b/src/language/node_processor/NameProcessor.hpp index d5dee908565a2d7ccdff03ee509c87f841770c8d..04bbde4d01c36d086408601f9ab5875a1f19a01f 100644 --- a/src/language/node_processor/NameProcessor.hpp +++ b/src/language/node_processor/NameProcessor.hpp @@ -12,6 +12,12 @@ class NameProcessor final : public INodeProcessor DataVariant* p_value{nullptr}; public: + Type + type() const + { + return Type::name_processor; + } + DataVariant execute(ExecutionPolicy&) { diff --git a/src/language/node_processor/TinyMatrixExpressionProcessor.hpp b/src/language/node_processor/TinyMatrixExpressionProcessor.hpp index bcb3e65f35b301c6adbe12eeb02e6024cb9ea0da..91d1a53b2c2c7cb7f8da7af8051d5ebdfd1b3736 100644 --- a/src/language/node_processor/TinyMatrixExpressionProcessor.hpp +++ b/src/language/node_processor/TinyMatrixExpressionProcessor.hpp @@ -13,6 +13,12 @@ class TinyMatrixExpressionProcessor final : public INodeProcessor ASTNode& m_node; public: + Type + type() const + { + return Type::tiny_matrix_expression_processor; + } + PUGS_INLINE DataVariant execute(ExecutionPolicy& exec_policy) diff --git a/src/language/node_processor/TinyVectorExpressionProcessor.hpp b/src/language/node_processor/TinyVectorExpressionProcessor.hpp index ac86b9025b54f673c3cad636aaf1178a55e436a1..5c1a2d946bd37e1d9bb0f9bedb91e54985bf26dc 100644 --- a/src/language/node_processor/TinyVectorExpressionProcessor.hpp +++ b/src/language/node_processor/TinyVectorExpressionProcessor.hpp @@ -13,6 +13,12 @@ class TinyVectorExpressionProcessor final : public INodeProcessor ASTNode& m_node; public: + Type + type() const + { + return Type::tiny_vector_expression_processor; + } + PUGS_INLINE DataVariant execute(ExecutionPolicy& exec_policy) diff --git a/src/language/node_processor/UnaryExpressionProcessor.hpp b/src/language/node_processor/UnaryExpressionProcessor.hpp index cdc4fc54111fd3a52854160347b5753e3787bcd5..06bbfde45ab560112a776ffa765b9277272442c5 100644 --- a/src/language/node_processor/UnaryExpressionProcessor.hpp +++ b/src/language/node_processor/UnaryExpressionProcessor.hpp @@ -46,6 +46,12 @@ class UnaryExpressionProcessor final : public INodeProcessor } public: + Type + type() const + { + return Type::unary_expression_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { @@ -72,6 +78,12 @@ class UnaryExpressionProcessor<UnaryOpT, std::shared_ptr<ValueT>, std::shared_pt } public: + Type + type() const + { + return Type::unary_expression_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/language/node_processor/ValueProcessor.hpp b/src/language/node_processor/ValueProcessor.hpp index 342198223e763fdb66781a632da0d107182234d5..66f054fe837cd9de59ad76ddb7f8f513b73a1b15 100644 --- a/src/language/node_processor/ValueProcessor.hpp +++ b/src/language/node_processor/ValueProcessor.hpp @@ -12,6 +12,12 @@ class ValueProcessor final : public INodeProcessor DataVariant m_value; public: + Type + type() const + { + return Type::value_processor; + } + PUGS_INLINE DataVariant execute(ExecutionPolicy&) diff --git a/src/language/node_processor/WhileProcessor.hpp b/src/language/node_processor/WhileProcessor.hpp index af7cc604bb6c2d5f74cb894a1f05ba20acfb35f6..72c8f4186e81cfcc587e6cf55d6f503ee3f0f154 100644 --- a/src/language/node_processor/WhileProcessor.hpp +++ b/src/language/node_processor/WhileProcessor.hpp @@ -11,6 +11,12 @@ class WhileProcessor final : public INodeProcessor ASTNode& m_node; public: + Type + type() const + { + return Type::while_processor; + } + DataVariant execute(ExecutionPolicy& exec_policy) { diff --git a/src/utils/BacktraceManager.cpp b/src/utils/BacktraceManager.cpp index 0ba95d6a6edd0e52b059e0b28638384eec13b602..a7142a45c141cbc203c9a2c2247c706223ac301b 100644 --- a/src/utils/BacktraceManager.cpp +++ b/src/utils/BacktraceManager.cpp @@ -25,7 +25,7 @@ BacktraceManager::BacktraceManager() char** ptr = backtrace_symbols(buffer, ret); for (int i = 2; i < ret; ++i) { - m_lines.push_back(ptr[i]); + m_stack_lines.push_back(ptr[i]); } free(ptr); @@ -35,27 +35,35 @@ std::ostream& operator<<(std::ostream& os, const BacktraceManager& btm) { if (BacktraceManager::s_show) { - const std::vector<std::string>& lines = btm.m_lines; + const std::vector<std::string>& stack_lines = btm.m_stack_lines; const std::regex mangled_function(R"%(\(.*\+)%"); - const int width = std::log10(lines.size()) + 1; + const int width = std::log10(stack_lines.size()) + 1; - for (size_t i_line = 0; i_line < lines.size(); ++i_line) { - const auto& line = lines[i_line]; - os << rang::fg::green << "[" << std::setw(width) << i_line + 1 << '/' << lines.size() << "] " << rang::fg::reset; + for (size_t i_stack_line = 0; i_stack_line < stack_lines.size(); ++i_stack_line) { + const size_t i_line = stack_lines.size() - i_stack_line - 1; + const auto& stack_line = stack_lines[i_line]; + os << rang::fg::green << "[" << std::setw(width) << i_line + 1 << '/' << stack_lines.size() << "] " + << rang::fg::reset; std::smatch matchex; - if (std::regex_search(line, matchex, mangled_function)) { + if (std::regex_search(stack_line, matchex, mangled_function)) { std::string prefix = matchex.prefix().str(); - std::string function = line.substr(matchex.position() + 1, matchex.length() - 2); + std::string function = stack_line.substr(matchex.position() + 1, matchex.length() - 2); std::string suffix = matchex.suffix().str(); - os << prefix << '('; + os << prefix << '\n'; + os << std::setw(5 + 2 * width) << "from " << '('; if (function.size() > 0) { - os << rang::style::bold << demangle(function) << rang::style::reset; + std::string function_full_name = demangle(function); + if (function_full_name.size() > 80) { + function_full_name.resize(75); + function_full_name += "[...]"; + } + os << rang::style::bold << function_full_name << rang::style::reset; } os << '+' << suffix << '\n'; } else { - os << line << '\n'; + os << stack_line << '\n'; } } } else { diff --git a/src/utils/BacktraceManager.hpp b/src/utils/BacktraceManager.hpp index e990ffd3b4060f71370a0f8b7386cdfcd6c03ea8..3f5ac23f8a830f20fa36071285d239bb01cd6c26 100644 --- a/src/utils/BacktraceManager.hpp +++ b/src/utils/BacktraceManager.hpp @@ -8,7 +8,7 @@ class BacktraceManager { private: static bool s_show; - std::vector<std::string> m_lines; + std::vector<std::string> m_stack_lines; public: static void setShow(bool show_backtrace); diff --git a/src/utils/Exceptions.cpp b/src/utils/Exceptions.cpp index 1bf598b7ceac54e0cff3d8b2662b35bdc0654e07..5ffc6f943edc2afa489d0e50a4568cef7effb9da 100644 --- a/src/utils/Exceptions.cpp +++ b/src/utils/Exceptions.cpp @@ -10,23 +10,26 @@ RawError::RawError(std::string_view error_msg) : IExitError(std::string{error_ms NormalError::NormalError(std::string_view error_msg) : IExitError([&] { std::ostringstream os; - os << rang::style::bold << "error:" << rang::style::reset << ' ' << error_msg; + os << rang::fgB::red << "error:" << rang::style::reset << ' ' << error_msg; return os.str(); }()) {} -UnexpectedError::UnexpectedError(std::string_view error_msg) +UnexpectedError::UnexpectedError(std::string_view error_msg, const std::experimental::source_location& source_location) : IBacktraceError([&] { std::ostringstream os; os << rang::fgB::red << "unexpected error:" << rang::style::reset << ' ' << error_msg; return os.str(); - }()) + }()), + m_source_location{source_location} {} -NotImplementedError::NotImplementedError(std::string_view error_msg) +NotImplementedError::NotImplementedError(std::string_view error_msg, + const std::experimental::source_location& source_location) : IBacktraceError([&] { std::ostringstream os; os << rang::fgB::yellow << "not implemented yet:" << rang::style::reset << ' ' << error_msg; return os.str(); - }()) + }()), + m_source_location{source_location} {} diff --git a/src/utils/Exceptions.hpp b/src/utils/Exceptions.hpp index eb229198bc7fcc16d3d4216e859b66c6cf496376..46bfd60bd4b3f5b3cf5ca19c527595fcf92d34db 100644 --- a/src/utils/Exceptions.hpp +++ b/src/utils/Exceptions.hpp @@ -3,6 +3,9 @@ #include <stdexcept> #include <string> +#include <string_view> + +#include <experimental/source_location> struct IExitError : public std::runtime_error { @@ -32,6 +35,8 @@ struct NormalError : public IExitError struct IBacktraceError : public std::runtime_error { + virtual const std::experimental::source_location& sourceLocation() const = 0; + IBacktraceError(const IBacktraceError&) = delete; IBacktraceError(IBacktraceError&&) = delete; @@ -39,20 +44,42 @@ struct IBacktraceError : public std::runtime_error virtual ~IBacktraceError() = default; }; -struct UnexpectedError : IBacktraceError +class UnexpectedError final : public IBacktraceError { + private: + const std::experimental::source_location m_source_location; + + public: + const std::experimental::source_location& + sourceLocation() const + { + return m_source_location; + } + UnexpectedError(const UnexpectedError&) = delete; UnexpectedError(UnexpectedError&&) = delete; - UnexpectedError(std::string_view error_msg); + UnexpectedError(std::string_view error_msg, + const std::experimental::source_location& = std::experimental::source_location::current()); }; -struct NotImplementedError : IBacktraceError +class NotImplementedError final : public IBacktraceError { + private: + const std::experimental::source_location m_source_location; + + public: + const std::experimental::source_location& + sourceLocation() const + { + return m_source_location; + } + NotImplementedError(const NotImplementedError&) = delete; NotImplementedError(NotImplementedError&&) = delete; - NotImplementedError(std::string_view error_msg); + NotImplementedError(std::string_view error_msg, + const std::experimental::source_location& = std::experimental::source_location::current()); }; #endif // EXCEPTIONS_HPP diff --git a/src/utils/PugsUtils.cpp b/src/utils/PugsUtils.cpp index 4e1f521656683b371f488ee90df5d49e061d9c7b..3677d5c8fded780fcb2a468809443e0e26131ccf 100644 --- a/src/utils/PugsUtils.cpp +++ b/src/utils/PugsUtils.cpp @@ -109,8 +109,8 @@ initialize(int& argc, char* argv[]) bool show_preamble = true; app.add_flag("--preamble,!--no-preamble", show_preamble, "Show execution info preamble [default: true]"); - bool show_backtrace = false; - app.add_flag("-b,--backtrace,!--no-backtrace", show_backtrace, "Show backtrace on failure [default: false]"); + bool show_backtrace = true; + app.add_flag("-b,--backtrace,!--no-backtrace", show_backtrace, "Show backtrace on failure [default: true]"); app.add_flag("--signal,!--no-signal", enable_signals, "Catches signals [default: true]"); diff --git a/src/utils/SignalManager.cpp b/src/utils/SignalManager.cpp index 399f3164c2046f4ec25a009160a6f01b11da85ef..f2721177285d3ed5c8edb7ca484a685679c94e5d 100644 --- a/src/utils/SignalManager.cpp +++ b/src/utils/SignalManager.cpp @@ -1,5 +1,7 @@ #include <utils/SignalManager.hpp> +#include <language/ast/ASTBacktrace.hpp> +#include <language/utils/ParseError.hpp> #include <utils/BacktraceManager.hpp> #include <utils/ConsoleManager.hpp> #include <utils/Messenger.hpp> @@ -67,41 +69,58 @@ SignalManager::pauseForDebug(int signal) void SignalManager::handler(int signal) { - std::signal(SIGFPE, SIG_DFL); - std::signal(SIGSEGV, SIG_IGN); - std::signal(SIGTERM, SIG_DFL); - std::signal(SIGINT, SIG_DFL); - std::signal(SIGABRT, SIG_DFL); - - // Each failing process must write - std::cerr.setstate(std::ios::goodbit); - - BacktraceManager bm; - std::cerr << bm << '\n'; - - std::exception_ptr eptr = std::current_exception(); - try { - if (eptr) { - std::rethrow_exception(eptr); + static std::mutex mutex; + + if (mutex.try_lock()) { + std::signal(SIGTERM, SIG_DFL); + std::signal(SIGINT, SIG_DFL); + std::signal(SIGABRT, SIG_DFL); + + // Each failing process must write + std::cerr.setstate(std::ios::goodbit); + + std::cerr << BacktraceManager{} << '\n'; + + std::cerr << "\n *** " << rang::style::reset << rang::fg::reset << rang::style::bold << "Signal " << rang::fgB::red + << signalName(signal) << rang::fg::reset << " caught" << rang::style::reset << " ***\n\n"; + + std::exception_ptr eptr = std::current_exception(); + try { + if (eptr) { + std::rethrow_exception(eptr); + } else { + std::ostringstream error_msg; + error_msg << "received " << signalName(signal); + std::cerr << ASTBacktrace::getInstance().errorMessageAt(error_msg.str()) << '\n'; + } + } + catch (const IBacktraceError& backtrace_error) { + auto source_location = backtrace_error.sourceLocation(); + std::cerr << rang::fgB::cyan << source_location.file_name() << ':' << source_location.line() << ':' + << source_location.column() << ':' << rang::fg::reset << rang::fgB::yellow + << " threw the following exception" << rang::fg::reset << "\n\n"; + std::cerr << ASTBacktrace::getInstance().errorMessageAt(backtrace_error.what()) << '\n'; + } + catch (const ParseError& parse_error) { + auto p = parse_error.positions().front(); + std::cerr << rang::style::bold << p.source << ':' << p.line << ':' << p.column << ':' << rang::style::reset + << rang::fgB::red << " error: " << rang::fg::reset << rang::style::bold << parse_error.what() + << rang::style::reset << '\n'; + } + catch (const IExitError& exit_error) { + std::cerr << ASTBacktrace::getInstance().errorMessageAt(exit_error.what()) << '\n'; + } + catch (const AssertError& assert_error) { + std::cerr << assert_error << '\n'; + } + catch (...) { + std::cerr << "Unknown exception!\n"; } - } - catch (const NotImplementedError& not_implemented_error) { - std::cerr << not_implemented_error.what() << '\n'; - } - catch (const UnexpectedError& unexpected_error) { - std::cerr << unexpected_error.what() << '\n'; - } - catch (const AssertError& assert_error) { - std::cerr << assert_error << '\n'; - } - catch (...) { - std::cerr << "Unknown exception!\n"; - } - std::cerr << "\n *** " << rang::style::reset << rang::fg::reset << rang::style::bold << "Signal " << rang::fgB::red - << signalName(signal) << rang::fg::reset << " caught" << rang::style::reset << " ***\n"; + SignalManager::pauseForDebug(signal); - SignalManager::pauseForDebug(signal); + mutex.unlock(); + } } void diff --git a/src/utils/SourceLocation.hpp b/src/utils/SourceLocation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d57116c8c47146cefad751b556ba767f98e35f70 --- /dev/null +++ b/src/utils/SourceLocation.hpp @@ -0,0 +1,58 @@ +#ifndef SOURCE_LOCATION_HPP +#define SOURCE_LOCATION_HPP + +#include <experimental/source_location> +#include <string> + +class SourceLocation +{ + private: + std::string m_filename; + std::string m_function; + size_t m_line; + size_t m_column; + + public: + const std::string& + filename() const + { + return m_filename; + } + + const std::string& + function() const + { + return m_function; + } + + size_t + line() const + { + return m_line; + } + + size_t + column() const + { + return m_column; + } + + SourceLocation( + const std::experimental::source_location& source_location = std::experimental::source_location::current()) + : m_filename{source_location.file_name()}, + m_function{source_location.function_name()}, + m_line{source_location.line()}, + m_column{source_location.column()} + {} + + SourceLocation(std::string filename, size_t line, size_t column, std::string function = "") + : m_filename{filename}, m_function{function}, m_line{line}, m_column{column} + {} + + SourceLocation(SourceLocation&&) = default; + SourceLocation(const SourceLocation&) = default; + + ~SourceLocation() = default; +}; + +#endif // SOURCE_LOCATION_HPP diff --git a/tests/test_ASTModulesImporter.cpp b/tests/test_ASTModulesImporter.cpp index 4be8e087dd89490caf6be0a8ba3132588fd919df..f70fa9b2bc118c4498072de10414d346b17717b4 100644 --- a/tests/test_ASTModulesImporter.cpp +++ b/tests/test_ASTModulesImporter.cpp @@ -1,6 +1,7 @@ #include <catch2/catch_test_macros.hpp> #include <catch2/matchers/catch_matchers_all.hpp> +#include <language/ast/ASTBacktrace.hpp> #include <language/ast/ASTBuilder.hpp> #include <language/ast/ASTModulesImporter.hpp> #include <language/ast/ASTNodeExpressionBuilder.hpp> @@ -37,7 +38,9 @@ test_ASTExecutionInfo(const ASTNode& root_node, const ModuleRepository& module_r test_ASTExecutionInfo(*ast, module_repository); \ \ ExecutionPolicy exec_policy; \ + ASTBacktrace::create(); \ ast->execute(exec_policy); \ + ASTBacktrace::destroy(); \ \ std::stringstream ast_output; \ ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::data_type}}; \ diff --git a/tests/test_ASTNode.cpp b/tests/test_ASTNode.cpp index bb4b07f9b1d8a2022a0b5961b7e76ac80922f1b9..468a27a89dbe3be40c20ad386cd82434e52f2807 100644 --- a/tests/test_ASTNode.cpp +++ b/tests/test_ASTNode.cpp @@ -2,6 +2,7 @@ #include <catch2/matchers/catch_matchers_all.hpp> #include <language/PEGGrammar.hpp> +#include <language/ast/ASTBacktrace.hpp> #include <language/ast/ASTNode.hpp> #include <language/node_processor/FakeProcessor.hpp> #include <utils/Demangle.hpp> @@ -17,12 +18,16 @@ TEST_CASE("ASTNode", "[language]") ExecutionPolicy exec_policy; #ifndef NDEBUG + ASTBacktrace::create(); REQUIRE_THROWS(ast_node.execute(exec_policy)); + ASTBacktrace::destroy(); #endif // NDEBUG ast_node.m_node_processor = std::make_unique<FakeProcessor>(); + ASTBacktrace::create(); REQUIRE_NOTHROW(ast_node.execute(exec_policy)); + ASTBacktrace::destroy(); } SECTION("name") diff --git a/tests/test_ASTNodeListProcessor.cpp b/tests/test_ASTNodeListProcessor.cpp index 934eb58912179a90158df2c3885a923ba7cf736c..d858b313aa695d39912953712858bf1bbb5e257e 100644 --- a/tests/test_ASTNodeListProcessor.cpp +++ b/tests/test_ASTNodeListProcessor.cpp @@ -1,6 +1,7 @@ #include <catch2/catch_test_macros.hpp> #include <catch2/matchers/catch_matchers_all.hpp> +#include <language/ast/ASTBacktrace.hpp> #include <language/ast/ASTBuilder.hpp> #include <language/ast/ASTNodeDataTypeBuilder.hpp> #include <language/ast/ASTNodeDeclarationToAffectationConverter.hpp> @@ -35,7 +36,9 @@ true; ASTNodeExpressionBuilder{*ast}; ExecutionPolicy exec_policy; + ASTBacktrace::create(); ast->execute(exec_policy); + ASTBacktrace::destroy(); REQUIRE(ast->children[0]->is_type<language::integer>()); REQUIRE(ast->children[1]->is_type<language::true_kw>()); diff --git a/tests/test_AffectationProcessor.cpp b/tests/test_AffectationProcessor.cpp index 71670fd5d75b4ae7d20d8ece4b3ef980165cd382..03781088ae664cff01ebde37314e0af1b15826ca 100644 --- a/tests/test_AffectationProcessor.cpp +++ b/tests/test_AffectationProcessor.cpp @@ -16,6 +16,7 @@ #include <utils/Stringify.hpp> #include <FixturesForBuiltinT.hpp> +#include <language/ast/ASTBacktrace.hpp> #include <language/utils/BasicAffectationRegistrerFor.hpp> #include <pegtl/string_input.hpp> @@ -37,7 +38,9 @@ \ ASTNodeExpressionBuilder{*ast}; \ ExecutionPolicy exec_policy; \ + ASTBacktrace::create(); \ ast->execute(exec_policy); \ + ASTBacktrace::destroy(); \ \ auto symbol_table = ast->m_symbol_table; \ \ @@ -98,7 +101,9 @@ \ ASTNodeExpressionBuilder{*ast}; \ ExecutionPolicy exec_policy; \ + ASTBacktrace::create(); \ ast->execute(exec_policy); \ + ASTBacktrace::destroy(); \ \ using namespace TAO_PEGTL_NAMESPACE; \ position use_position{internal::iterator{"fixture"}, "fixture"}; \ @@ -150,7 +155,9 @@ ASTNodeExpressionBuilder{*ast}; \ ExecutionPolicy exec_policy; \ \ + ASTBacktrace::create(); \ REQUIRE_THROWS_WITH(ast->execute(exec_policy), error_message); \ + ASTBacktrace::destroy(); \ } // clazy:excludeall=non-pod-global-static diff --git a/tests/test_AffectationToStringProcessor.cpp b/tests/test_AffectationToStringProcessor.cpp index 6b20e7ca84e7c7f80654ed6a053a34068df83889..8e15ddc66cb379b841232ad377d244833aa618a6 100644 --- a/tests/test_AffectationToStringProcessor.cpp +++ b/tests/test_AffectationToStringProcessor.cpp @@ -1,6 +1,7 @@ #include <catch2/catch_test_macros.hpp> #include <catch2/matchers/catch_matchers_all.hpp> +#include <language/ast/ASTBacktrace.hpp> #include <language/ast/ASTBuilder.hpp> #include <language/ast/ASTModulesImporter.hpp> #include <language/ast/ASTNodeAffectationExpressionBuilder.hpp> @@ -32,7 +33,9 @@ \ ASTNodeExpressionBuilder{*ast}; \ ExecutionPolicy exec_policy; \ + ASTBacktrace::create(); \ ast->execute(exec_policy); \ + ASTBacktrace::destroy(); \ \ auto symbol_table = ast->m_symbol_table; \ \ diff --git a/tests/test_AffectationToTupleProcessor.cpp b/tests/test_AffectationToTupleProcessor.cpp index 84d1a1639d52107a802ff66f8cff9dfd3bff0b5f..ca6a6294b77f14ed8846a60823fdf8d8632a56ba 100644 --- a/tests/test_AffectationToTupleProcessor.cpp +++ b/tests/test_AffectationToTupleProcessor.cpp @@ -1,6 +1,7 @@ #include <catch2/catch_test_macros.hpp> #include <catch2/matchers/catch_matchers_all.hpp> +#include <language/ast/ASTBacktrace.hpp> #include <language/ast/ASTBuilder.hpp> #include <language/ast/ASTModulesImporter.hpp> #include <language/ast/ASTNodeAffectationExpressionBuilder.hpp> @@ -32,7 +33,9 @@ \ ASTNodeExpressionBuilder{*ast}; \ ExecutionPolicy exec_policy; \ + ASTBacktrace::create(); \ ast->execute(exec_policy); \ + ASTBacktrace::destroy(); \ \ auto symbol_table = ast->m_symbol_table; \ \ @@ -63,7 +66,9 @@ ASTNodeExpressionBuilder{*ast}; \ ExecutionPolicy exec_policy; \ \ + ASTBacktrace::create(); \ REQUIRE_THROWS_WITH(ast->execute(exec_policy), error_message); \ + ASTBacktrace::destroy(); \ } // clazy:excludeall=non-pod-global-static diff --git a/tests/test_ArraySubscriptProcessor.cpp b/tests/test_ArraySubscriptProcessor.cpp index 5b1ac6c1cf0a00f56a4da806b86bb4124c42b317..949951c226c55ee77234885175e5f0f9a42f287f 100644 --- a/tests/test_ArraySubscriptProcessor.cpp +++ b/tests/test_ArraySubscriptProcessor.cpp @@ -1,6 +1,7 @@ #include <catch2/catch_test_macros.hpp> #include <catch2/matchers/catch_matchers_all.hpp> +#include <language/ast/ASTBacktrace.hpp> #include <language/ast/ASTBuilder.hpp> #include <language/ast/ASTModulesImporter.hpp> #include <language/ast/ASTNodeAffectationExpressionBuilder.hpp> @@ -33,7 +34,9 @@ \ ASTNodeExpressionBuilder{*ast}; \ ExecutionPolicy exec_policy; \ + ASTBacktrace::create(); \ ast->execute(exec_policy); \ + ASTBacktrace::destroy(); \ \ auto symbol_table = ast->m_symbol_table; \ \ @@ -66,7 +69,9 @@ \ ASTNodeExpressionBuilder{*ast}; \ ExecutionPolicy exec_policy; \ + ASTBacktrace::create(); \ ast->execute(exec_policy); \ + ASTBacktrace::destroy(); \ }; \ \ REQUIRE_THROWS_WITH(eval(), error_message); \ diff --git a/tests/test_BinaryExpressionProcessor_arithmetic.cpp b/tests/test_BinaryExpressionProcessor_arithmetic.cpp index 83869150f8ba220c54c3389b4982eabab3c522d4..c93face344864f42e968322ce86f0f03efeabae9 100644 --- a/tests/test_BinaryExpressionProcessor_arithmetic.cpp +++ b/tests/test_BinaryExpressionProcessor_arithmetic.cpp @@ -76,7 +76,9 @@ \ ASTNodeExpressionBuilder{*ast}; \ ExecutionPolicy exec_policy; \ + ASTBacktrace::create(); \ ast->execute(exec_policy); \ + ASTBacktrace::destroy(); \ \ using namespace TAO_PEGTL_NAMESPACE; \ position use_position{internal::iterator{"fixture"}, "fixture"}; \ @@ -153,7 +155,9 @@ \ ASTNodeExpressionBuilder{*ast}; \ ExecutionPolicy exec_policy; \ + ASTBacktrace::create(); \ REQUIRE_THROWS_WITH(ast->execute(exec_policy), error_msg); \ + ASTBacktrace::destroy(); \ } TEST_CASE("BinaryExpressionProcessor arithmetic", "[language]") diff --git a/tests/test_BinaryExpressionProcessor_shift.cpp b/tests/test_BinaryExpressionProcessor_shift.cpp index 71addbac7a1c80aaf49d1b236f1edfed1f182a4e..190b9f2b26d39d831550b70fef528a06f2c4503e 100644 --- a/tests/test_BinaryExpressionProcessor_shift.cpp +++ b/tests/test_BinaryExpressionProcessor_shift.cpp @@ -64,7 +64,9 @@ fout << createSocketServer(0) << "\n";)"; ASTNodeExpressionBuilder{*ast}; ExecutionPolicy exec_policy; + ASTBacktrace::create(); ast->execute(exec_policy); + ASTBacktrace::destroy(); } REQUIRE(std::filesystem::exists(filename)); diff --git a/tests/test_BinaryExpressionProcessor_utils.hpp b/tests/test_BinaryExpressionProcessor_utils.hpp index c8e3440cfd75b1320c146d5eb342a2a5d343a20f..5983cda355f76c7ed58d47fa544dc5fd82ba3b09 100644 --- a/tests/test_BinaryExpressionProcessor_utils.hpp +++ b/tests/test_BinaryExpressionProcessor_utils.hpp @@ -1,6 +1,7 @@ #ifndef TEST_BINARY_EXPRESSION_PROCESSOR_UTILS_HPP #define TEST_BINARY_EXPRESSION_PROCESSOR_UTILS_HPP +#include <language/ast/ASTBacktrace.hpp> #include <language/ast/ASTBuilder.hpp> #include <language/ast/ASTModulesImporter.hpp> #include <language/ast/ASTNodeDataTypeBuilder.hpp> @@ -30,7 +31,9 @@ \ ASTNodeExpressionBuilder{*ast}; \ ExecutionPolicy exec_policy; \ + ASTBacktrace::create(); \ ast->execute(exec_policy); \ + ASTBacktrace::destroy(); \ \ auto symbol_table = ast->m_symbol_table; \ \ diff --git a/tests/test_BuiltinFunctionProcessor.cpp b/tests/test_BuiltinFunctionProcessor.cpp index 8de9ec2c2ed9e61479aa2d7165bf6e506fd6caf6..67812b0a4442e4d336dd20d5d579137804fe190b 100644 --- a/tests/test_BuiltinFunctionProcessor.cpp +++ b/tests/test_BuiltinFunctionProcessor.cpp @@ -1,6 +1,7 @@ #include <catch2/catch_test_macros.hpp> #include <catch2/matchers/catch_matchers_predicate.hpp> +#include <language/ast/ASTBacktrace.hpp> #include <language/ast/ASTBuilder.hpp> #include <language/ast/ASTModulesImporter.hpp> #include <language/ast/ASTNodeDataTypeBuilder.hpp> @@ -31,7 +32,9 @@ \ ASTNodeExpressionBuilder{*ast}; \ ExecutionPolicy exec_policy; \ + ASTBacktrace::create(); \ ast->execute(exec_policy); \ + ASTBacktrace::destroy(); \ \ auto symbol_table = ast->m_symbol_table; \ \ @@ -69,7 +72,9 @@ ASTNodeExpressionBuilder{*ast}; \ ExecutionPolicy exec_policy; \ using namespace Catch::Matchers; \ + ASTBacktrace::create(); \ REQUIRE_THROWS_WITH(ast->execute(exec_policy), expected_error); \ + ASTBacktrace::destroy(); \ } // clazy:excludeall=non-pod-global-static diff --git a/tests/test_DiscreteFunctionIntegrator.cpp b/tests/test_DiscreteFunctionIntegrator.cpp index b3ba2efba4ae8fe3dc90b8b54f6df6032d622e8c..26a14385f67501c8f9145d5bfa6756517726849e 100644 --- a/tests/test_DiscreteFunctionIntegrator.cpp +++ b/tests/test_DiscreteFunctionIntegrator.cpp @@ -31,6 +31,9 @@ TEST_CASE("DiscreteFunctionIntegrator", "[scheme]") { + const bool stack_details = ASTNode::getStackDetails(); + ASTNode::setStackDetails(false); + auto same_cell_value = [](auto f, auto g) -> bool { using ItemIdType = typename decltype(f)::index_type; for (ItemIdType item_id = 0; item_id < f.numberOfItems(); ++item_id) { @@ -749,4 +752,6 @@ let R3x3_non_linear_3d: R^3 -> R^3x3, x -> [[2 * exp(x[0]) * sin(x[1]) + 3, sin( } } } + + ASTNode::setStackDetails(stack_details); } diff --git a/tests/test_DiscreteFunctionIntegratorByZone.cpp b/tests/test_DiscreteFunctionIntegratorByZone.cpp index 217c15b38d17195f2e3baa56d0a698f0b2c9c2a4..0b550b063fd14ec53df39f9395c4061ef997f17e 100644 --- a/tests/test_DiscreteFunctionIntegratorByZone.cpp +++ b/tests/test_DiscreteFunctionIntegratorByZone.cpp @@ -33,6 +33,9 @@ TEST_CASE("DiscreteFunctionIntegratorByZone", "[scheme]") { + const bool stack_details = ASTNode::getStackDetails(); + ASTNode::setStackDetails(false); + auto same_cell_value = [](auto f, auto g) -> bool { using ItemIdType = typename decltype(f)::index_type; for (ItemIdType item_id = 0; item_id < f.numberOfItems(); ++item_id) { @@ -1030,4 +1033,6 @@ let R3x3_non_linear_3d: R^3 -> R^3x3, x -> [[2 * exp(x[0]) * sin(x[1]) + 3, sin( REQUIRE(same_cell_value(cell_value, discrete_function.get<DiscreteFunctionP0<Dimension, const DataType>>())); } } + + ASTNode::setStackDetails(stack_details); } diff --git a/tests/test_DiscreteFunctionInterpoler.cpp b/tests/test_DiscreteFunctionInterpoler.cpp index 0287d97c89ef966f5a4d68ecd091875b3e19e14b..fd3f3b6724e3ff8efd1cd3446d261cd06de448fb 100644 --- a/tests/test_DiscreteFunctionInterpoler.cpp +++ b/tests/test_DiscreteFunctionInterpoler.cpp @@ -29,6 +29,9 @@ TEST_CASE("DiscreteFunctionInterpoler", "[scheme]") { + const bool stack_details = ASTNode::getStackDetails(); + ASTNode::setStackDetails(false); + auto same_cell_value = [](auto f, auto g) -> bool { using ItemIdType = typename decltype(f)::index_type; for (ItemIdType item_id = 0; item_id < f.numberOfItems(); ++item_id) { @@ -908,4 +911,6 @@ let R3x3_non_linear_3d: R^3 -> R^3x3, x -> [[2 * exp(x[0]) * sin(x[1]) + 3, sin( } } } + + ASTNode::setStackDetails(stack_details); } diff --git a/tests/test_DiscreteFunctionInterpolerByZone.cpp b/tests/test_DiscreteFunctionInterpolerByZone.cpp index c4e6f0a00a15a8921615bb0540adf3c3668e7300..8a0297d3ef1de251c23a66107303aa02f3d23fb8 100644 --- a/tests/test_DiscreteFunctionInterpolerByZone.cpp +++ b/tests/test_DiscreteFunctionInterpolerByZone.cpp @@ -31,6 +31,9 @@ TEST_CASE("DiscreteFunctionInterpolerByZone", "[scheme]") { + const bool stack_details = ASTNode::getStackDetails(); + ASTNode::setStackDetails(false); + auto same_cell_value = [](auto f, auto g) -> bool { using ItemIdType = typename decltype(f)::index_type; for (ItemIdType item_id = 0; item_id < f.numberOfItems(); ++item_id) { @@ -1042,4 +1045,6 @@ let R3x3_non_linear_3d: R^3 -> R^3x3, x -> [[2 * exp(x[0]) * sin(x[1]) + 3, sin( REQUIRE(same_cell_value(cell_value, discrete_function.get<DiscreteFunctionP0<Dimension, const DataType>>())); } } + + ASTNode::setStackDetails(stack_details); } diff --git a/tests/test_DiscreteFunctionVectorIntegrator.cpp b/tests/test_DiscreteFunctionVectorIntegrator.cpp index 4c510542ba9b244d505b7531db8d49f0c106bc2d..60afd2dbcf3e1e730cbaf273166e0258d8ae40f2 100644 --- a/tests/test_DiscreteFunctionVectorIntegrator.cpp +++ b/tests/test_DiscreteFunctionVectorIntegrator.cpp @@ -32,6 +32,9 @@ TEST_CASE("DiscreteFunctionVectorIntegrator", "[scheme]") { + const bool stack_details = ASTNode::getStackDetails(); + ASTNode::setStackDetails(false); + auto same_cell_value = [](const CellValue<const double>& fi, const size_t i, const auto& f) -> bool { for (CellId cell_id = 0; cell_id < fi.numberOfItems(); ++cell_id) { if (fi[cell_id] != f[cell_id][i]) { @@ -396,4 +399,6 @@ Invalid value type: R^2)"; } } } + + ASTNode::setStackDetails(stack_details); } diff --git a/tests/test_DiscreteFunctionVectorIntegratorByZone.cpp b/tests/test_DiscreteFunctionVectorIntegratorByZone.cpp index ac516d3ff9b7d20e3cedd152f522c7f7263e8acd..01297d03df6cbadc0a7cff50546aa2737444e4d8 100644 --- a/tests/test_DiscreteFunctionVectorIntegratorByZone.cpp +++ b/tests/test_DiscreteFunctionVectorIntegratorByZone.cpp @@ -34,6 +34,9 @@ TEST_CASE("DiscreteFunctionVectorIntegratorByZone", "[scheme]") { + const bool stack_details = ASTNode::getStackDetails(); + ASTNode::setStackDetails(false); + auto same_cell_value = [](const CellValue<const double>& fi, const size_t i, const auto& f) -> bool { for (CellId cell_id = 0; cell_id < fi.numberOfItems(); ++cell_id) { if (fi[cell_id] != f[cell_id][i]) { @@ -438,4 +441,6 @@ let R_scalar_non_linear_3d: R^3 -> R, x -> 2 * exp(x[0] + x[1]) + 3 * x[2]; REQUIRE(i == function_id_list.size()); } + + ASTNode::setStackDetails(stack_details); } diff --git a/tests/test_DiscreteFunctionVectorInterpoler.cpp b/tests/test_DiscreteFunctionVectorInterpoler.cpp index e47b8754d7ff7fe46d8f90d903af2efaed06be51..3a4871076739a3fc873bd0cd69547099f9f67c67 100644 --- a/tests/test_DiscreteFunctionVectorInterpoler.cpp +++ b/tests/test_DiscreteFunctionVectorInterpoler.cpp @@ -29,6 +29,9 @@ TEST_CASE("DiscreteFunctionVectorInterpoler", "[scheme]") { + const bool stack_details = ASTNode::getStackDetails(); + ASTNode::setStackDetails(false); + auto same_cell_value = [](const CellValue<const double>& fi, const size_t i, const auto& f) -> bool { for (CellId cell_id = 0; cell_id < fi.numberOfItems(); ++cell_id) { if (fi[cell_id] != f[cell_id][i]) { @@ -444,4 +447,6 @@ Invalid interpolation value type: R^2)"; } } } + + ASTNode::setStackDetails(stack_details); } diff --git a/tests/test_DiscreteFunctionVectorInterpolerByZone.cpp b/tests/test_DiscreteFunctionVectorInterpolerByZone.cpp index 2fe9849341741d0483202621f40cb45dbc4acc81..0547aa3cf6bfe74a27b44630a34bb1d6f9e7724b 100644 --- a/tests/test_DiscreteFunctionVectorInterpolerByZone.cpp +++ b/tests/test_DiscreteFunctionVectorInterpolerByZone.cpp @@ -31,6 +31,9 @@ TEST_CASE("DiscreteFunctionVectorInterpolerByZone", "[scheme]") { + const bool stack_details = ASTNode::getStackDetails(); + ASTNode::setStackDetails(false); + auto same_cell_value = [](const CellValue<const double>& fi, const size_t i, const auto& f) -> bool { for (CellId cell_id = 0; cell_id < fi.numberOfItems(); ++cell_id) { if (fi[cell_id] != f[cell_id][i]) { @@ -509,4 +512,6 @@ Invalid interpolation value type: R^2)"; } } } + + ASTNode::setStackDetails(stack_details); } diff --git a/tests/test_InterpolateItemArray.cpp b/tests/test_InterpolateItemArray.cpp index 6d020282ad0d0a953ca7e815357d5461f5dd3a76..61674ce2d3d5e105fb7f8f1b6322ccc0f6ff4dcd 100644 --- a/tests/test_InterpolateItemArray.cpp +++ b/tests/test_InterpolateItemArray.cpp @@ -26,6 +26,9 @@ TEST_CASE("InterpolateItemArray", "[language]") { + const bool stack_details = ASTNode::getStackDetails(); + ASTNode::setStackDetails(false); + SECTION("interpolate on all items") { auto same_cell_array = [](auto f, auto g) -> bool { @@ -1106,4 +1109,6 @@ let f_3d: R^3 -> (R^3), x -> (2*x, [2*x[0]-x[1], 3*x[2]-x[0], x[1]+x[2]], 0); } } } + + ASTNode::setStackDetails(stack_details); } diff --git a/tests/test_InterpolateItemValue.cpp b/tests/test_InterpolateItemValue.cpp index f53921ed19cfdd35549b2c032dd0ce8d27620ff3..9ee0a324f01728d54f88c0d864dd5950c7cb2339 100644 --- a/tests/test_InterpolateItemValue.cpp +++ b/tests/test_InterpolateItemValue.cpp @@ -26,6 +26,9 @@ TEST_CASE("InterpolateItemValue", "[language]") { + const bool stack_details = ASTNode::getStackDetails(); + ASTNode::setStackDetails(false); + SECTION("interpolate on all items") { auto same_item_value = [](auto f, auto g) -> bool { @@ -1085,4 +1088,6 @@ let R2x2_non_linear_3d: R^3 -> R^2x2, x -> [[2 * exp(x[0]) * sin(x[1]) + 3 * cos } } } + + ASTNode::setStackDetails(stack_details); } diff --git a/tests/test_ItemArrayVariantFunctionInterpoler.cpp b/tests/test_ItemArrayVariantFunctionInterpoler.cpp index 7ceaf2207ef53526f19511aa31415ce8efcd577a..3a2c4aadaaba0794a3ebca697739e093e712ef3e 100644 --- a/tests/test_ItemArrayVariantFunctionInterpoler.cpp +++ b/tests/test_ItemArrayVariantFunctionInterpoler.cpp @@ -26,6 +26,9 @@ TEST_CASE("ItemArrayVariantFunctionInterpoler", "[scheme]") { + const bool stack_details = ASTNode::getStackDetails(); + ASTNode::setStackDetails(false); + auto same_item_array = [](auto f, auto g) -> bool { using ItemIdType = typename decltype(f)::index_type; if (f.sizeOfArrays() != g.sizeOfArrays()) { @@ -672,4 +675,6 @@ let R2x2_non_linear_3d: R^3 -> R^2x2, } } } + + ASTNode::setStackDetails(stack_details); } diff --git a/tests/test_ItemValueVariantFunctionInterpoler.cpp b/tests/test_ItemValueVariantFunctionInterpoler.cpp index 19f53e1085fb058960737b2543c2892e8d6d9fb2..be1d4272b8019d493760d228735fa5d08985ef04 100644 --- a/tests/test_ItemValueVariantFunctionInterpoler.cpp +++ b/tests/test_ItemValueVariantFunctionInterpoler.cpp @@ -26,6 +26,9 @@ TEST_CASE("ItemValueVariantFunctionInterpoler", "[scheme]") { + const bool stack_details = ASTNode::getStackDetails(); + ASTNode::setStackDetails(false); + auto same_item_value = [](auto f, auto g) -> bool { using ItemIdType = typename decltype(f)::index_type; for (ItemIdType item_id = 0; item_id < f.numberOfItems(); ++item_id) { @@ -544,4 +547,6 @@ let R2x2_non_linear_3d: R^3 -> R^2x2, x -> [[2 * exp(x[0]) * sin(x[1]) + 3, sin( } } } + + ASTNode::setStackDetails(stack_details); }