diff --git a/.gitignore b/.gitignore index e8ba8747559abdacd563868545e2a6666be82a3c..3bb6d6cbcf2906a99d3302595285d50145395fe5 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ CMakeCache.txt GPATH GRTAGS GTAGS +/.clangd/ diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp index ed00e3032b5efddcbfbd21124836f737889041e3..faab47780f0736c43285b3245a8ee07cc966f036 100644 --- a/src/language/PugsParser.cpp +++ b/src/language/PugsParser.cpp @@ -16,6 +16,7 @@ #include <language/utils/ASTDotPrinter.hpp> #include <language/utils/ASTExecutionInfo.hpp> #include <language/utils/ASTPrinter.hpp> +#include <language/utils/OperatorRepository.hpp> #include <language/utils/SymbolTable.hpp> #include <utils/PugsAssert.hpp> #include <utils/PugsUtils.hpp> @@ -48,6 +49,8 @@ parser(const std::string& filename) << rang::style::reset << " ...\n"; auto parse_and_execute = [](auto& input) { + OperatorRepository::create(); + std::unique_ptr<ASTNode> root_node = ASTBuilder::build(input); ASTModulesImporter module_importer{*root_node}; @@ -81,6 +84,8 @@ parser(const std::string& filename) root_node->execute(exec_all); root_node->m_symbol_table->clearValues(); + + OperatorRepository::destroy(); }; if (not SignalManager::pauseOnError()) { diff --git a/src/language/ast/ASTNode.hpp b/src/language/ast/ASTNode.hpp index a3b9bd21569d490b1bc7f450eee546279b91a681..d9568c612dd3e3a6223994cff6273b43d900b3c0 100644 --- a/src/language/ast/ASTNode.hpp +++ b/src/language/ast/ASTNode.hpp @@ -1,9 +1,9 @@ #ifndef AST_NODE_HPP #define AST_NODE_HPP -#include <language/ast/ASTNodeDataType.hpp> #include <language/node_processor/ExecutionPolicy.hpp> #include <language/node_processor/INodeProcessor.hpp> +#include <language/utils/ASTNodeDataType.hpp> #include <language/utils/DataVariant.hpp> #include <utils/PugsAssert.hpp> #include <utils/PugsMacros.hpp> diff --git a/src/language/ast/ASTNodeAffectationExpressionBuilder.cpp b/src/language/ast/ASTNodeAffectationExpressionBuilder.cpp index 66420138cd85f3fcf220ceec883f6c2b1b012759..6e712e3d84c0eb6d52064fdfecabd9dd6f9016db 100644 --- a/src/language/ast/ASTNodeAffectationExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeAffectationExpressionBuilder.cpp @@ -3,437 +3,54 @@ #include <algebra/TinyVector.hpp> #include <language/PEGGrammar.hpp> #include <language/ast/ASTNodeNaturalConversionChecker.hpp> -#include <language/node_processor/AffectationProcessor.hpp> +#include <language/node_processor/INodeProcessor.hpp> +#include <language/utils/AffectationMangler.hpp> +#include <language/utils/OperatorRepository.hpp> #include <language/utils/ParseError.hpp> - #include <utils/Exceptions.hpp> ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode& n) { - auto set_affectation_processor = [](ASTNode& n, const auto& operator_v) { - auto set_affectation_processor_for_data = [&](const auto& value, const ASTNodeDataType& data_type) { - using OperatorT = std::decay_t<decltype(operator_v)>; - using ValueT = std::decay_t<decltype(value)>; - - switch (data_type) { - case ASTNodeDataType::bool_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, bool>>(n); - break; - } - case ASTNodeDataType::unsigned_int_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, uint64_t>>(n); - break; - } - case ASTNodeDataType::int_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, int64_t>>(n); - break; - } - case ASTNodeDataType::double_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, double>>(n); - break; - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: undefined operand type for affectation", - std::vector{n.children[1]->begin()}); - } - // LCOV_EXCL_STOP - } - }; - - auto set_affectation_processor_for_vector_data = [&](const auto& value, const ASTNodeDataType& data_type) { - using OperatorT = std::decay_t<decltype(operator_v)>; - using ValueT = std::decay_t<decltype(value)>; - - if constexpr (std::is_same_v<OperatorT, language::eq_op>) { - switch (data_type) { - case ASTNodeDataType::vector_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, ValueT>>(n); - break; - } - case ASTNodeDataType::list_t: { - n.m_node_processor = std::make_unique<AffectationToTinyVectorFromListProcessor<OperatorT, ValueT>>(n); - break; - } - case ASTNodeDataType::bool_t: { - if constexpr (std::is_same_v<ValueT, TinyVector<1>>) { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, bool>>(n); - break; - } - } - case ASTNodeDataType::unsigned_int_t: { - if constexpr (std::is_same_v<ValueT, TinyVector<1>>) { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, uint64_t>>(n); - break; - } - } - case ASTNodeDataType::int_t: { - if constexpr (std::is_same_v<ValueT, TinyVector<1>>) { - if (n.children[1]->is_type<language::integer>()) { - if (std::stoi(n.children[1]->string()) == 0) { - n.m_node_processor = std::make_unique<AffectationFromZeroProcessor<ValueT>>(n); - break; - } - } - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, int64_t>>(n); - break; - } else if (n.children[1]->is_type<language::integer>()) { - if (std::stoi(n.children[1]->string()) == 0) { - n.m_node_processor = std::make_unique<AffectationFromZeroProcessor<ValueT>>(n); - break; - } - } - // LCOV_EXCL_START - throw ParseError("unexpected error: invalid integral value", std::vector{n.children[1]->begin()}); - // LCOV_EXCL_STOP - } - case ASTNodeDataType::double_t: { - if constexpr (std::is_same_v<ValueT, TinyVector<1>>) { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, double>>(n); - break; - } - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: invalid operand type", std::vector{n.children[1]->begin()}); - } - // LCOV_EXCL_STOP - } - } else if constexpr (std::is_same_v<OperatorT, language::pluseq_op> or - std::is_same_v<OperatorT, language::minuseq_op>) { - switch (data_type) { - case ASTNodeDataType::vector_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, ValueT>>(n); - break; - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: invalid operand type", std::vector{n.children[1]->begin()}); - } - // LCOV_EXCL_STOP - } - } else if constexpr (std::is_same_v<OperatorT, language::multiplyeq_op>) { - switch (data_type) { - case ASTNodeDataType::bool_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, bool>>(n); - break; - } - case ASTNodeDataType::unsigned_int_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, uint64_t>>(n); - break; - } - case ASTNodeDataType::int_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, int64_t>>(n); - break; - } - case ASTNodeDataType::double_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, double>>(n); - break; - } - default: { - throw ParseError("expecting scalar operand type", std::vector{n.children[1]->begin()}); - } - } - } else { - throw ParseError("invalid affectation operator for " + dataTypeName(n.m_data_type), std::vector{n.begin()}); - } - }; - - auto set_affectation_processor_for_string_data = [&](const ASTNodeDataType& data_type) { - using OperatorT = std::decay_t<decltype(operator_v)>; - - if constexpr (std::is_same_v<OperatorT, language::eq_op> or std::is_same_v<OperatorT, language::pluseq_op>) { - switch (data_type) { - case ASTNodeDataType::bool_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, bool>>(n); - break; - } - case ASTNodeDataType::unsigned_int_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, uint64_t>>(n); - break; - } - case ASTNodeDataType::int_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, int64_t>>(n); - break; - } - case ASTNodeDataType::double_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, double>>(n); - break; - } - case ASTNodeDataType::string_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, std::string>>(n); - break; - } - case ASTNodeDataType::vector_t: { - switch (data_type.dimension()) { - case 1: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, TinyVector<1>>>(n); - break; - } - case 2: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, TinyVector<2>>>(n); - break; - } - case 3: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, TinyVector<3>>>(n); - break; - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: invalid vector dimension for string affectation", - std::vector{n.children[1]->begin()}); - } - // LCOV_EXCL_STOP - } - break; - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: undefined operand type for string affectation", - std::vector{n.children[1]->begin()}); - } - // LCOV_EXCL_STOP - } - } else { - throw ParseError("invalid affectation operator for string", std::vector{n.begin()}); - } - }; - - auto set_affectation_processor_for_embedded_data = [&](const ASTNodeDataType& data_type) { - using OperatorT = std::decay_t<decltype(operator_v)>; - - if constexpr (std::is_same_v<OperatorT, language::eq_op>) { - switch (data_type) { - case ASTNodeDataType::type_id_t: { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, EmbeddedData, EmbeddedData>>(n); - break; - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: undefined operand type for embedded data affectation", - std::vector{n.children[1]->begin()}); - } - // LCOV_EXCL_STOP - } - } else { - throw ParseError("invalid affectation operator for '" + dataTypeName(n.children[0]->m_data_type) + "'", - std::vector{n.begin()}); - } - }; - - auto set_affectation_processor_for_tuple_data = [&](const ASTNodeDataType& content_data_type, - const ASTNodeDataType& data_type) { - using OperatorT = std::decay_t<decltype(operator_v)>; - if constexpr (std::is_same_v<OperatorT, language::eq_op>) { - if ((data_type == ASTNodeDataType::list_t) or (data_type == ASTNodeDataType::tuple_t)) { - switch (content_data_type) { - case ASTNodeDataType::type_id_t: { - n.m_node_processor = std::make_unique<AffectationToTupleFromListProcessor<OperatorT, EmbeddedData>>(n); - break; - } - case ASTNodeDataType::bool_t: { - n.m_node_processor = std::make_unique<AffectationToTupleFromListProcessor<OperatorT, bool>>(n); - break; - } - case ASTNodeDataType::unsigned_int_t: { - n.m_node_processor = std::make_unique<AffectationToTupleFromListProcessor<OperatorT, uint64_t>>(n); - break; - } - case ASTNodeDataType::int_t: { - n.m_node_processor = std::make_unique<AffectationToTupleFromListProcessor<OperatorT, int64_t>>(n); - break; - } - case ASTNodeDataType::double_t: { - n.m_node_processor = std::make_unique<AffectationToTupleFromListProcessor<OperatorT, double>>(n); - break; - } - case ASTNodeDataType::string_t: { - n.m_node_processor = std::make_unique<AffectationToTupleFromListProcessor<OperatorT, std::string>>(n); - break; - } - case ASTNodeDataType::vector_t: { - switch (content_data_type.dimension()) { - case 1: { - n.m_node_processor = std::make_unique<AffectationToTupleFromListProcessor<OperatorT, TinyVector<1>>>(n); - break; - } - case 2: { - n.m_node_processor = std::make_unique<AffectationToTupleFromListProcessor<OperatorT, TinyVector<2>>>(n); - break; - } - case 3: { - n.m_node_processor = std::make_unique<AffectationToTupleFromListProcessor<OperatorT, TinyVector<3>>>(n); - break; - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: invalid vector dimension for tuple affectation", - std::vector{n.children[1]->begin()}); - } - // LCOV_EXCL_STOP - } - break; - } - // LCOV_EXCL_START - default: { - throw UnexpectedError("invalid tuple content " + dataTypeName(content_data_type)); - } - // LCOV_EXCL_STOP - } - } else { - switch (content_data_type) { - case ASTNodeDataType::type_id_t: { - n.m_node_processor = std::make_unique<AffectationToTupleProcessor<OperatorT, EmbeddedData>>(n); - break; - } - case ASTNodeDataType::bool_t: { - n.m_node_processor = std::make_unique<AffectationToTupleProcessor<OperatorT, bool>>(n); - break; - } - case ASTNodeDataType::unsigned_int_t: { - n.m_node_processor = std::make_unique<AffectationToTupleProcessor<OperatorT, uint64_t>>(n); - break; - } - case ASTNodeDataType::int_t: { - n.m_node_processor = std::make_unique<AffectationToTupleProcessor<OperatorT, int64_t>>(n); - break; - } - case ASTNodeDataType::double_t: { - n.m_node_processor = std::make_unique<AffectationToTupleProcessor<OperatorT, double>>(n); - break; - } - case ASTNodeDataType::string_t: { - n.m_node_processor = std::make_unique<AffectationToTupleProcessor<OperatorT, std::string>>(n); - break; - } - case ASTNodeDataType::vector_t: { - switch (content_data_type.dimension()) { - case 1: { - n.m_node_processor = std::make_unique<AffectationToTupleProcessor<OperatorT, TinyVector<1>>>(n); - break; - } - case 2: { - n.m_node_processor = std::make_unique<AffectationToTupleProcessor<OperatorT, TinyVector<2>>>(n); - break; - } - case 3: { - n.m_node_processor = std::make_unique<AffectationToTupleProcessor<OperatorT, TinyVector<3>>>(n); - break; - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: invalid vector dimension for tuple affectation", - std::vector{n.children[1]->begin()}); - } - // LCOV_EXCL_STOP - } - break; - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: undefined operand type for tuple affectation", - std::vector{n.children[1]->begin()}); - } - // LCOV_EXCL_STOP - } - } - } else { - throw ParseError("invalid affectation operator for '" + dataTypeName(n.children[0]->m_data_type) + "'", - std::vector{n.begin()}); - } - }; - - auto set_affectation_processor_for_value = [&](const ASTNodeDataType& value_type) { - const ASTNodeDataType data_type = n.children[1]->m_data_type; - - switch (value_type) { - case ASTNodeDataType::bool_t: { - set_affectation_processor_for_data(bool{}, data_type); - break; - } - case ASTNodeDataType::unsigned_int_t: { - set_affectation_processor_for_data(uint64_t{}, data_type); - break; - } - case ASTNodeDataType::int_t: { - set_affectation_processor_for_data(int64_t{}, data_type); - break; - } - case ASTNodeDataType::double_t: { - set_affectation_processor_for_data(double{}, data_type); - break; - } - case ASTNodeDataType::vector_t: { - switch (value_type.dimension()) { - case 1: { - set_affectation_processor_for_vector_data(TinyVector<1>{}, data_type); - break; - } - case 2: { - set_affectation_processor_for_vector_data(TinyVector<2>{}, data_type); - break; - } - case 3: { - set_affectation_processor_for_vector_data(TinyVector<3>{}, data_type); - break; - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: unexpected vector dimension", std::vector{n.begin()}); - } - // LCOV_EXCL_STOP - } - break; - } - case ASTNodeDataType::string_t: { - set_affectation_processor_for_string_data(data_type); - break; - } - case ASTNodeDataType::type_id_t: { - set_affectation_processor_for_embedded_data(data_type); - break; - } - case ASTNodeDataType::tuple_t: { - const ASTNodeDataType& content_type = value_type.contentType(); - set_affectation_processor_for_tuple_data(content_type, data_type); - break; - } - default: { - throw ParseError("unexpected error: undefined value type for affectation", std::vector{n.children[0]->begin()}); - } - } - }; - - using OperatorT = std::decay_t<decltype(operator_v)>; - - const ASTNodeDataType& target_data_type = n.children[0]->m_data_type; - const ASTNodeDataType& source_data_type = n.children[1]->m_data_type; - - // Special treatment dedicated to R^1 to be able to initialize them - if (((target_data_type != source_data_type) and (target_data_type == ASTNodeDataType::vector_t) and - (target_data_type.dimension() == 1)) or - // Special treatment for R^d vectors and operator *= - ((target_data_type == ASTNodeDataType::vector_t) and (source_data_type != ASTNodeDataType::vector_t) and - std::is_same_v<OperatorT, language::multiplyeq_op>)) { - ASTNodeNaturalConversionChecker{*n.children[1], ASTNodeDataType::build<ASTNodeDataType::double_t>()}; + const ASTNodeDataType& target_data_type = n.children[0]->m_data_type; + const ASTNodeDataType& source_data_type = n.children[1]->m_data_type; + + const std::string affectation_name = [&] { + if (n.is_type<language::eq_op>()) { + return affectationMangler<language::eq_op>(target_data_type, source_data_type); + } else if (n.is_type<language::multiplyeq_op>()) { + return affectationMangler<language::multiplyeq_op>(target_data_type, source_data_type); + } else if (n.is_type<language::divideeq_op>()) { + return affectationMangler<language::divideeq_op>(target_data_type, source_data_type); + } else if (n.is_type<language::pluseq_op>()) { + return affectationMangler<language::pluseq_op>(target_data_type, source_data_type); + } else if (n.is_type<language::minuseq_op>()) { + return affectationMangler<language::minuseq_op>(target_data_type, source_data_type); } else { - ASTNodeNaturalConversionChecker{*n.children[1], target_data_type}; + throw ParseError("unexpected error: undefined affectation operator", std::vector{n.begin()}); } + }(); + + // Special treatment dedicated to R^1 to be able to initialize them + if (((target_data_type != source_data_type) and (target_data_type == ASTNodeDataType::vector_t) and + (target_data_type.dimension() == 1)) or + // Special treatment for R^d vectors and operator *= + ((target_data_type == ASTNodeDataType::vector_t) and (source_data_type != ASTNodeDataType::vector_t) and + n.is_type<language::multiplyeq_op>())) { + ASTNodeNaturalConversionChecker{*n.children[1], ASTNodeDataType::build<ASTNodeDataType::double_t>()}; + } else { + ASTNodeNaturalConversionChecker{*n.children[1], target_data_type}; + } - set_affectation_processor_for_value(target_data_type); - }; + const auto& optional_processor_builder = + OperatorRepository::instance().getAffectationProcessorBuilder(affectation_name); - if (n.is_type<language::eq_op>()) { - set_affectation_processor(n, language::eq_op{}); - } else if (n.is_type<language::multiplyeq_op>()) { - set_affectation_processor(n, language::multiplyeq_op{}); - } else if (n.is_type<language::divideeq_op>()) { - set_affectation_processor(n, language::divideeq_op{}); - } else if (n.is_type<language::pluseq_op>()) { - set_affectation_processor(n, language::pluseq_op{}); - } else if (n.is_type<language::minuseq_op>()) { - set_affectation_processor(n, language::minuseq_op{}); + if (optional_processor_builder.has_value()) { + n.m_node_processor = optional_processor_builder.value()->getNodeProcessor(n); } else { - throw ParseError("unexpected error: undefined affectation operator", std::vector{n.begin()}); + std::ostringstream error_message; + error_message << "undefined affectation type: "; + error_message << rang::fgB::red << affectation_name << rang::fg::reset; + + throw ParseError(error_message.str(), std::vector{n.children[0]->begin()}); } } diff --git a/src/language/ast/ASTNodeBinaryOperatorExpressionBuilder.cpp b/src/language/ast/ASTNodeBinaryOperatorExpressionBuilder.cpp index 64ff14deb191921c81e28ef1b3f36a0651ffc0e2..b6904220a9c42f2fcbfd49e8ce5881fbd9b7cf3a 100644 --- a/src/language/ast/ASTNodeBinaryOperatorExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeBinaryOperatorExpressionBuilder.cpp @@ -3,205 +3,59 @@ #include <language/PEGGrammar.hpp> #include <language/node_processor/BinaryExpressionProcessor.hpp> #include <language/node_processor/ConcatExpressionProcessor.hpp> +#include <language/utils/BinaryOperatorMangler.hpp> +#include <language/utils/OperatorRepository.hpp> #include <language/utils/ParseError.hpp> ASTNodeBinaryOperatorExpressionBuilder::ASTNodeBinaryOperatorExpressionBuilder(ASTNode& n) { - auto set_binary_operator_processor = [](ASTNode& n, const auto& operator_v) { - auto set_binary_operator_processor_for_data_b = [&](const auto data_a, const ASTNodeDataType& data_type_b) { - using OperatorT = std::decay_t<decltype(operator_v)>; - using DataTA = std::decay_t<decltype(data_a)>; - - if constexpr (std::is_same_v<DataTA, std::string>) { - if constexpr (std::is_same_v<OperatorT, language::plus_op>) { - switch (data_type_b) { - case ASTNodeDataType::bool_t: { - n.m_node_processor = std::make_unique<ConcatExpressionProcessor<bool>>(n); - break; - } - case ASTNodeDataType::unsigned_int_t: { - n.m_node_processor = std::make_unique<ConcatExpressionProcessor<uint64_t>>(n); - break; - } - case ASTNodeDataType::int_t: { - n.m_node_processor = std::make_unique<ConcatExpressionProcessor<int64_t>>(n); - break; - } - case ASTNodeDataType::double_t: { - n.m_node_processor = std::make_unique<ConcatExpressionProcessor<double>>(n); - break; - } - case ASTNodeDataType::string_t: { - n.m_node_processor = std::make_unique<ConcatExpressionProcessor<std::string>>(n); - break; - } - default: { - throw ParseError("undefined operand type for binary operator", std::vector{n.children[1]->begin()}); - } - } - - } else if constexpr ((std::is_same_v<OperatorT, language::eqeq_op>) or - (std::is_same_v<OperatorT, language::not_eq_op>)) { - if (data_type_b == ASTNodeDataType::string_t) { - n.m_node_processor = std::make_unique<BinaryExpressionProcessor<OperatorT, DataTA, std::string>>(n); - } else { - throw ParseError("undefined operand type for binary operator", std::vector{n.begin()}); - } - } else { - throw ParseError("undefined operand type for binary operator", std::vector{n.begin()}); - } - } else if constexpr (std::is_same_v<DataTA, TinyVector<1>> or std::is_same_v<DataTA, TinyVector<2>> or - std::is_same_v<DataTA, TinyVector<3>>) { - if ((data_type_b == ASTNodeDataType::vector_t)) { - if constexpr (std::is_same_v<OperatorT, language::plus_op> or std::is_same_v<OperatorT, language::minus_op> or - std::is_same_v<OperatorT, language::eqeq_op> or - std::is_same_v<OperatorT, language::not_eq_op>) { - if (data_a.dimension() == data_type_b.dimension()) { - n.m_node_processor = std::make_unique<BinaryExpressionProcessor<OperatorT, DataTA, DataTA>>(n); - } else { - throw ParseError("incompatible dimensions of operands", std::vector{n.begin()}); - } - } else { - throw ParseError("invalid binary operator", std::vector{n.begin()}); - } - } else { - // LCOV_EXCL_START - throw ParseError("unexpected error: invalid operand type for binary operator", - std::vector{n.children[1]->begin()}); - // LCOV_EXCL_STOP - } - } else { - switch (data_type_b) { - case ASTNodeDataType::bool_t: { - n.m_node_processor = std::make_unique<BinaryExpressionProcessor<OperatorT, DataTA, bool>>(n); - break; - } - case ASTNodeDataType::unsigned_int_t: { - n.m_node_processor = std::make_unique<BinaryExpressionProcessor<OperatorT, DataTA, uint64_t>>(n); - break; - } - case ASTNodeDataType::int_t: { - n.m_node_processor = std::make_unique<BinaryExpressionProcessor<OperatorT, DataTA, int64_t>>(n); - break; - } - case ASTNodeDataType::double_t: { - n.m_node_processor = std::make_unique<BinaryExpressionProcessor<OperatorT, DataTA, double>>(n); - break; - } - case ASTNodeDataType::vector_t: { - if constexpr (std::is_same_v<OperatorT, language::multiply_op>) { - switch (data_type_b.dimension()) { - case 1: { - n.m_node_processor = std::make_unique<BinaryExpressionProcessor<OperatorT, DataTA, TinyVector<1>>>(n); - break; - } - case 2: { - n.m_node_processor = std::make_unique<BinaryExpressionProcessor<OperatorT, DataTA, TinyVector<2>>>(n); - break; - } - case 3: { - n.m_node_processor = std::make_unique<BinaryExpressionProcessor<OperatorT, DataTA, TinyVector<3>>>(n); - break; - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: invalid dimension", std::vector{n.children[0]->begin()}); - } - // LCOV_EXCL_STOP - } - break; - } - } - default: { - throw ParseError("undefined operand type for binary operator", std::vector{n.children[1]->begin()}); - } - } - } - }; - - auto set_binary_operator_processor_for_data_a = [&](const ASTNodeDataType& data_type_a) { - const ASTNodeDataType data_type_b = n.children[1]->m_data_type; - switch (data_type_a) { - case ASTNodeDataType::bool_t: { - set_binary_operator_processor_for_data_b(bool{}, data_type_b); - break; - } - case ASTNodeDataType::unsigned_int_t: { - set_binary_operator_processor_for_data_b(uint64_t{}, data_type_b); - break; - } - case ASTNodeDataType::int_t: { - set_binary_operator_processor_for_data_b(int64_t{}, data_type_b); - break; - } - case ASTNodeDataType::double_t: { - set_binary_operator_processor_for_data_b(double{}, data_type_b); - break; - } - case ASTNodeDataType::string_t: { - set_binary_operator_processor_for_data_b(std::string{}, data_type_b); - break; - } - case ASTNodeDataType::vector_t: { - switch (data_type_a.dimension()) { - case 1: { - set_binary_operator_processor_for_data_b(TinyVector<1>{}, data_type_b); - break; - } - case 2: { - set_binary_operator_processor_for_data_b(TinyVector<2>{}, data_type_b); - break; - } - case 3: { - set_binary_operator_processor_for_data_b(TinyVector<3>{}, data_type_b); - break; - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: invalid dimension", std::vector{n.children[0]->begin()}); - } - // LCOV_EXCL_STOP - } - break; - } - default: { - throw ParseError("undefined operand type for binary operator", std::vector{n.children[0]->begin()}); - } - } - }; - - set_binary_operator_processor_for_data_a(n.children[0]->m_data_type); - }; - - if (n.is_type<language::multiply_op>()) { - set_binary_operator_processor(n, language::multiply_op{}); - } else if (n.is_type<language::divide_op>()) { - set_binary_operator_processor(n, language::divide_op{}); - } else if (n.is_type<language::plus_op>()) { - set_binary_operator_processor(n, language::plus_op{}); - } else if (n.is_type<language::minus_op>()) { - set_binary_operator_processor(n, language::minus_op{}); - - } else if (n.is_type<language::or_op>()) { - set_binary_operator_processor(n, language::or_op{}); - } else if (n.is_type<language::and_op>()) { - set_binary_operator_processor(n, language::and_op{}); - } else if (n.is_type<language::xor_op>()) { - set_binary_operator_processor(n, language::xor_op{}); - - } else if (n.is_type<language::greater_op>()) { - set_binary_operator_processor(n, language::greater_op{}); - } else if (n.is_type<language::greater_or_eq_op>()) { - set_binary_operator_processor(n, language::greater_or_eq_op{}); - } else if (n.is_type<language::lesser_op>()) { - set_binary_operator_processor(n, language::lesser_op{}); - } else if (n.is_type<language::lesser_or_eq_op>()) { - set_binary_operator_processor(n, language::lesser_or_eq_op{}); - } else if (n.is_type<language::eqeq_op>()) { - set_binary_operator_processor(n, language::eqeq_op{}); - } else if (n.is_type<language::not_eq_op>()) { - set_binary_operator_processor(n, language::not_eq_op{}); + const ASTNodeDataType& lhs_data_type = n.children[0]->m_data_type; + const ASTNodeDataType& rhs_data_type = n.children[1]->m_data_type; + + const std::string binary_operator_name = [&]() -> std::string { + if (n.is_type<language::multiply_op>()) { + return binaryOperatorMangler<language::multiply_op>(lhs_data_type, rhs_data_type); + } else if (n.is_type<language::divide_op>()) { + return binaryOperatorMangler<language::divide_op>(lhs_data_type, rhs_data_type); + } else if (n.is_type<language::plus_op>()) { + return binaryOperatorMangler<language::plus_op>(lhs_data_type, rhs_data_type); + } else if (n.is_type<language::minus_op>()) { + return binaryOperatorMangler<language::minus_op>(lhs_data_type, rhs_data_type); + + } else if (n.is_type<language::or_op>()) { + return binaryOperatorMangler<language::or_op>(lhs_data_type, rhs_data_type); + } else if (n.is_type<language::and_op>()) { + return binaryOperatorMangler<language::and_op>(lhs_data_type, rhs_data_type); + } else if (n.is_type<language::xor_op>()) { + return binaryOperatorMangler<language::xor_op>(lhs_data_type, rhs_data_type); + + } else if (n.is_type<language::greater_op>()) { + return binaryOperatorMangler<language::greater_op>(lhs_data_type, rhs_data_type); + } else if (n.is_type<language::greater_or_eq_op>()) { + return binaryOperatorMangler<language::greater_or_eq_op>(lhs_data_type, rhs_data_type); + } else if (n.is_type<language::lesser_op>()) { + return binaryOperatorMangler<language::lesser_op>(lhs_data_type, rhs_data_type); + } else if (n.is_type<language::lesser_or_eq_op>()) { + return binaryOperatorMangler<language::lesser_or_eq_op>(lhs_data_type, rhs_data_type); + } else if (n.is_type<language::eqeq_op>()) { + return binaryOperatorMangler<language::eqeq_op>(lhs_data_type, rhs_data_type); + } else if (n.is_type<language::not_eq_op>()) { + return binaryOperatorMangler<language::not_eq_op>(lhs_data_type, rhs_data_type); + } else { + throw ParseError("unexpected error: undefined binary operator", std::vector{n.begin()}); + } + }(); + + const auto& optional_processor_builder = + OperatorRepository::instance().getBinaryProcessorBuilder(binary_operator_name); + + if (optional_processor_builder.has_value()) { + n.m_node_processor = optional_processor_builder.value()->getNodeProcessor(n); } else { - throw ParseError("unexpected error: undefined binary operator", std::vector{n.begin()}); + std::ostringstream error_message; + error_message << "undefined binary operator type: "; + error_message << rang::fgB::red << binary_operator_name << rang::fg::reset; + + throw ParseError(error_message.str(), std::vector{n.children[0]->begin()}); } } diff --git a/src/language/ast/ASTNodeDataTypeBuilder.cpp b/src/language/ast/ASTNodeDataTypeBuilder.cpp index 7cbeb6adfdc96f8c2a56796c32c83592f0839d40..7c93b50527bbae5c352d62159e40d0eba3bb7aad 100644 --- a/src/language/ast/ASTNodeDataTypeBuilder.cpp +++ b/src/language/ast/ASTNodeDataTypeBuilder.cpp @@ -3,6 +3,7 @@ #include <language/PEGGrammar.hpp> #include <language/ast/ASTNodeNaturalConversionChecker.hpp> #include <language/utils/BuiltinFunctionEmbedder.hpp> +#include <language/utils/OperatorRepository.hpp> #include <language/utils/ParseError.hpp> #include <language/utils/SymbolTable.hpp> #include <utils/PugsAssert.hpp> @@ -282,7 +283,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const } else if (n.is_type<language::eq_op>() or n.is_type<language::multiplyeq_op>() or n.is_type<language::divideeq_op>() or n.is_type<language::pluseq_op>() or n.is_type<language::minuseq_op>()) { - n.m_data_type = n.children[0]->m_data_type; + n.m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); } else if (n.is_type<language::tuple_expression>()) { std::vector<std::shared_ptr<const ASTNodeDataType>> sub_data_type_list; @@ -351,52 +352,135 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const const ASTNode& test_node = *n.children[1]; ASTNodeNaturalConversionChecker{test_node, ASTNodeDataType::build<ASTNodeDataType::bool_t>()}; - } else if (n.is_type<language::unary_not>()) { - n.m_data_type = ASTNodeDataType::build<ASTNodeDataType::bool_t>(); - - const ASTNode& operand_node = *n.children[0]; - ASTNodeNaturalConversionChecker{operand_node, ASTNodeDataType::build<ASTNodeDataType::bool_t>()}; - - } else if (n.is_type<language::lesser_op>() or n.is_type<language::lesser_or_eq_op>() or - n.is_type<language::greater_op>() or n.is_type<language::greater_or_eq_op>() or - n.is_type<language::eqeq_op>() or n.is_type<language::not_eq_op>()) { - n.m_data_type = ASTNodeDataType::build<ASTNodeDataType::bool_t>(); - } else if (n.is_type<language::and_op>() or n.is_type<language::or_op>() or n.is_type<language::xor_op>()) { - n.m_data_type = ASTNodeDataType::build<ASTNodeDataType::bool_t>(); - - const ASTNode& lhs_node = *n.children[0]; - ASTNodeNaturalConversionChecker{lhs_node, ASTNodeDataType::build<ASTNodeDataType::bool_t>()}; + } else if (n.is_type<language::unary_not>() or n.is_type<language::unary_minus>()) { + auto& operator_repository = OperatorRepository::instance(); - const ASTNode& rhs_node = *n.children[1]; - ASTNodeNaturalConversionChecker{rhs_node, ASTNodeDataType::build<ASTNodeDataType::bool_t>()}; + auto optional_value_type = [&] { + if (n.is_type<language::unary_not>()) { + return operator_repository.getUnaryOperatorValueType( + unaryOperatorMangler<language::unary_not>(n.children[0]->m_data_type)); + } else if (n.is_type<language::unary_minus>()) { + return operator_repository.getUnaryOperatorValueType( + unaryOperatorMangler<language::unary_minus>(n.children[0]->m_data_type)); + } else { + // LCOV_EXCL_START + throw UnexpectedError("invalid unary operator type"); + // LCOV_EXCL_STOP + } + }(); - } else if (n.is_type<language::unary_minus>()) { - n.m_data_type = n.children[0]->m_data_type; - if ((n.children[0]->m_data_type == ASTNodeDataType::unsigned_int_t) or - (n.children[0]->m_data_type == ASTNodeDataType::bool_t)) { - n.m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); + if (optional_value_type.has_value()) { + n.m_data_type = optional_value_type.value(); } else { - n.m_data_type = n.children[0]->m_data_type; + std::ostringstream message; + message << "undefined unary operator\n" + << "note: unexpected operand type " << rang::fgB::red << dataTypeName(n.children[0]->m_data_type) + << rang::style::reset; + throw ParseError(message.str(), n.begin()); } + } else if (n.is_type<language::unary_plusplus>() or n.is_type<language::unary_minusminus>() or n.is_type<language::post_plusplus>() or n.is_type<language::post_minusminus>()) { - n.m_data_type = n.children[0]->m_data_type; + auto& operator_repository = OperatorRepository::instance(); + + auto optional_value_type = [&] { + if (n.is_type<language::unary_plusplus>()) { + return operator_repository.getIncDecOperatorValueType( + incDecOperatorMangler<language::unary_plusplus>(n.children[0]->m_data_type)); + } else if (n.is_type<language::unary_minusminus>()) { + return operator_repository.getIncDecOperatorValueType( + incDecOperatorMangler<language::unary_minusminus>(n.children[0]->m_data_type)); + } else if (n.is_type<language::post_minusminus>()) { + return operator_repository.getIncDecOperatorValueType( + incDecOperatorMangler<language::post_minusminus>(n.children[0]->m_data_type)); + } else if (n.is_type<language::post_plusplus>()) { + return operator_repository.getIncDecOperatorValueType( + incDecOperatorMangler<language::post_plusplus>(n.children[0]->m_data_type)); + } else { + // LCOV_EXCL_START + throw UnexpectedError("unexpected operator type"); + // LCOV_EXCL_STOP + } + }(); + + if (optional_value_type.has_value()) { + n.m_data_type = optional_value_type.value(); + } else { + std::ostringstream message; + message << "undefined increment/decrement operator\n" + << "note: unexpected operand type " << rang::fgB::red << dataTypeName(n.children[0]->m_data_type) + << rang::style::reset; + throw ParseError(message.str(), n.begin()); + } + } else if (n.is_type<language::plus_op>() or n.is_type<language::minus_op>() or - n.is_type<language::multiply_op>() or n.is_type<language::divide_op>()) { + n.is_type<language::multiply_op>() or n.is_type<language::divide_op>() or + n.is_type<language::lesser_op>() or n.is_type<language::lesser_or_eq_op>() or + n.is_type<language::greater_op>() or n.is_type<language::greater_or_eq_op>() or + n.is_type<language::eqeq_op>() or n.is_type<language::not_eq_op>() or n.is_type<language::and_op>() or + n.is_type<language::or_op>() or n.is_type<language::xor_op>()) { const ASTNodeDataType type_0 = n.children[0]->m_data_type; const ASTNodeDataType type_1 = n.children[1]->m_data_type; - if ((type_0 == ASTNodeDataType::bool_t) and (type_1 == ASTNodeDataType::bool_t)) { - n.m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); + auto& operator_repository = OperatorRepository::instance(); + + auto optional_value_type = [&] { + if (n.is_type<language::plus_op>()) { + return operator_repository.getBinaryOperatorValueType( + binaryOperatorMangler<language::plus_op>(type_0, type_1)); + } else if (n.is_type<language::minus_op>()) { + return operator_repository.getBinaryOperatorValueType( + binaryOperatorMangler<language::minus_op>(type_0, type_1)); + } else if (n.is_type<language::multiply_op>()) { + return operator_repository.getBinaryOperatorValueType( + binaryOperatorMangler<language::multiply_op>(type_0, type_1)); + } else if (n.is_type<language::divide_op>()) { + return operator_repository.getBinaryOperatorValueType( + binaryOperatorMangler<language::divide_op>(type_0, type_1)); + + } else if (n.is_type<language::lesser_op>()) { + return operator_repository.getBinaryOperatorValueType( + binaryOperatorMangler<language::lesser_op>(type_0, type_1)); + } else if (n.is_type<language::lesser_or_eq_op>()) { + return operator_repository.getBinaryOperatorValueType( + binaryOperatorMangler<language::lesser_or_eq_op>(type_0, type_1)); + } else if (n.is_type<language::greater_op>()) { + return operator_repository.getBinaryOperatorValueType( + binaryOperatorMangler<language::greater_op>(type_0, type_1)); + } else if (n.is_type<language::greater_or_eq_op>()) { + return operator_repository.getBinaryOperatorValueType( + binaryOperatorMangler<language::greater_or_eq_op>(type_0, type_1)); + } else if (n.is_type<language::eqeq_op>()) { + return operator_repository.getBinaryOperatorValueType( + binaryOperatorMangler<language::eqeq_op>(type_0, type_1)); + } else if (n.is_type<language::not_eq_op>()) { + return operator_repository.getBinaryOperatorValueType( + binaryOperatorMangler<language::not_eq_op>(type_0, type_1)); + + } else if (n.is_type<language::and_op>()) { + return operator_repository.getBinaryOperatorValueType( + binaryOperatorMangler<language::and_op>(type_0, type_1)); + } else if (n.is_type<language::or_op>()) { + return operator_repository.getBinaryOperatorValueType(binaryOperatorMangler<language::or_op>(type_0, type_1)); + } else if (n.is_type<language::xor_op>()) { + return operator_repository.getBinaryOperatorValueType( + binaryOperatorMangler<language::xor_op>(type_0, type_1)); + + } else { + // LCOV_EXCL_START + throw UnexpectedError("unexpected operator type"); + // LCOV_EXCL_STOP + } + }(); + + if (optional_value_type.has_value()) { + n.m_data_type = optional_value_type.value(); } else { - n.m_data_type = dataTypePromotion(type_0, type_1); - } - if (n.m_data_type == ASTNodeDataType::undefined_t) { std::ostringstream message; message << "undefined binary operator\n" - << "note: incompatible operand types " << n.children[0]->string() << " (" << dataTypeName(type_0) - << ") and " << n.children[1]->string() << " (" << dataTypeName(type_1) << ')'; + << "note: incompatible operand types " << dataTypeName(type_0) << " and " << dataTypeName(type_1); throw ParseError(message.str(), n.begin()); } + } else if (n.is_type<language::function_evaluation>()) { if (n.children[0]->m_data_type == ASTNodeDataType::function_t) { const std::string& function_name = n.children[0]->string(); diff --git a/src/language/ast/ASTNodeIncDecExpressionBuilder.cpp b/src/language/ast/ASTNodeIncDecExpressionBuilder.cpp index 71e5c3c4b16d8535091b98cab298ff6624661508..88b1758e757797d0844a06185105480e341635c8 100644 --- a/src/language/ast/ASTNodeIncDecExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeIncDecExpressionBuilder.cpp @@ -1,54 +1,47 @@ #include <language/ast/ASTNodeIncDecExpressionBuilder.hpp> #include <language/PEGGrammar.hpp> -#include <language/node_processor/IncDecExpressionProcessor.hpp> +#include <language/utils/IncDecOperatorMangler.hpp> +#include <language/utils/OperatorRepository.hpp> #include <language/utils/ParseError.hpp> ASTNodeIncDecExpressionBuilder::ASTNodeIncDecExpressionBuilder(ASTNode& n) { - auto set_inc_dec_operator_processor = [](ASTNode& n, const auto& operator_v) { - auto set_inc_dec_processor_for_value = [&](const ASTNodeDataType& data_type) { - using OperatorT = std::decay_t<decltype(operator_v)>; - switch (data_type) { - case ASTNodeDataType::unsigned_int_t: { - n.m_node_processor = std::make_unique<IncDecExpressionProcessor<OperatorT, uint64_t>>(n); - break; - } - case ASTNodeDataType::int_t: { - n.m_node_processor = std::make_unique<IncDecExpressionProcessor<OperatorT, int64_t>>(n); - break; - } - case ASTNodeDataType::double_t: { - n.m_node_processor = std::make_unique<IncDecExpressionProcessor<OperatorT, double>>(n); - break; - } - default: { - throw ParseError("unexpected error: undefined data type for unary operator", std::vector{n.begin()}); - } - } - }; - - if (not n.children[0]->is_type<language::name>()) { - if (n.children[0]->is_type<language::post_minusminus>() or n.children[0]->is_type<language::post_plusplus>() or - n.children[0]->is_type<language::unary_minusminus>() or n.children[0]->is_type<language::unary_plusplus>()) { - throw ParseError("chaining ++ or -- operators is not allowed", std::vector{n.children[0]->begin()}); - } else { - throw ParseError("invalid operand type for unary operator", std::vector{n.children[0]->begin()}); - } + const ASTNodeDataType& data_type = n.children[0]->m_data_type; + + if (not n.children[0]->is_type<language::name>()) { + std::ostringstream error_message; + error_message << "invalid operand type. ++/-- operators only apply to variables"; + + throw ParseError(error_message.str(), std::vector{n.children[0]->begin()}); + } + + const std::string inc_dec_operator_name = [&] { + if (n.is_type<language::unary_minusminus>()) { + return incDecOperatorMangler<language::unary_minusminus>(data_type); + } else if (n.is_type<language::unary_plusplus>()) { + return incDecOperatorMangler<language::unary_plusplus>(data_type); + } else if (n.is_type<language::post_minusminus>()) { + return incDecOperatorMangler<language::post_minusminus>(data_type); + } else if (n.is_type<language::post_plusplus>()) { + return incDecOperatorMangler<language::post_plusplus>(data_type); + } else { + // LCOV_EXCL_START + throw ParseError("unexpected error: undefined inc/dec operator", std::vector{n.begin()}); + // LCOV_EXCL_STOP } + }(); + + const auto& optional_processor_builder = + OperatorRepository::instance().getIncDecProcessorBuilder(inc_dec_operator_name); - set_inc_dec_processor_for_value(n.m_data_type); - }; - - if (n.is_type<language::unary_minusminus>()) { - set_inc_dec_operator_processor(n, language::unary_minusminus{}); - } else if (n.is_type<language::unary_plusplus>()) { - set_inc_dec_operator_processor(n, language::unary_plusplus{}); - } else if (n.is_type<language::post_minusminus>()) { - set_inc_dec_operator_processor(n, language::post_minusminus{}); - } else if (n.is_type<language::post_plusplus>()) { - set_inc_dec_operator_processor(n, language::post_plusplus{}); + if (optional_processor_builder.has_value()) { + n.m_node_processor = optional_processor_builder.value()->getNodeProcessor(n); } else { - throw ParseError("unexpected error: undefined increment/decrement operator", std::vector{n.begin()}); + std::ostringstream error_message; + error_message << "undefined affectation type: "; + error_message << rang::fgB::red << inc_dec_operator_name << rang::fg::reset; + + throw ParseError(error_message.str(), std::vector{n.children[0]->begin()}); } } diff --git a/src/language/ast/ASTNodeNaturalConversionChecker.hpp b/src/language/ast/ASTNodeNaturalConversionChecker.hpp index ebf83d7ca3d750d33fe6d18a6d0388bdea4c627c..9e96e49b90d5f7931aa4796a10f67dee0cfff6db 100644 --- a/src/language/ast/ASTNodeNaturalConversionChecker.hpp +++ b/src/language/ast/ASTNodeNaturalConversionChecker.hpp @@ -2,8 +2,8 @@ #define AST_NODE_NATURAL_CONVERSION_CHECKER_HPP #include <language/ast/ASTNode.hpp> -#include <language/ast/ASTNodeDataType.hpp> #include <language/ast/ASTNodeSubDataType.hpp> +#include <language/utils/ASTNodeDataType.hpp> struct AllowRToR1Conversion { diff --git a/src/language/ast/ASTNodeSubDataType.hpp b/src/language/ast/ASTNodeSubDataType.hpp index d7844d367ae686fe88e05bc119d198288eca45c6..358aca9a1419309796b9fcb9baf8eb9825e7a4eb 100644 --- a/src/language/ast/ASTNodeSubDataType.hpp +++ b/src/language/ast/ASTNodeSubDataType.hpp @@ -2,7 +2,7 @@ #define AST_NODE_SUB_DATA_TYPE_HPP #include <language/ast/ASTNode.hpp> -#include <language/ast/ASTNodeDataType.hpp> +#include <language/utils/ASTNodeDataType.hpp> struct ASTNodeSubDataType { diff --git a/src/language/ast/ASTNodeUnaryOperatorExpressionBuilder.cpp b/src/language/ast/ASTNodeUnaryOperatorExpressionBuilder.cpp index 7d94c3f58fe1762b582a0d984edc797b0fafd021..e011e693000d5b68de6fdd0ea98b4e7afe01a6f6 100644 --- a/src/language/ast/ASTNodeUnaryOperatorExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeUnaryOperatorExpressionBuilder.cpp @@ -1,100 +1,35 @@ #include <language/ast/ASTNodeUnaryOperatorExpressionBuilder.hpp> #include <language/PEGGrammar.hpp> -#include <language/node_processor/UnaryExpressionProcessor.hpp> +#include <language/utils/OperatorRepository.hpp> #include <language/utils/ParseError.hpp> +#include <language/utils/UnaryOperatorMangler.hpp> ASTNodeUnaryOperatorExpressionBuilder::ASTNodeUnaryOperatorExpressionBuilder(ASTNode& n) { - auto set_unary_operator_processor = [](ASTNode& n, const auto& operator_v) { - using OperatorT = std::decay_t<decltype(operator_v)>; + const ASTNodeDataType& data_type = n.children[0]->m_data_type; - auto set_unary_operator_processor_for_data = [&](const auto& value, const ASTNodeDataType& data_type) { - using ValueT = std::decay_t<decltype(value)>; - switch (data_type) { - case ASTNodeDataType::bool_t: { - n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, bool>>(n); - break; - } - case ASTNodeDataType::unsigned_int_t: { - n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, uint64_t>>(n); - break; - } - case ASTNodeDataType::int_t: { - n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, int64_t>>(n); - break; - } - case ASTNodeDataType::double_t: { - n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, double>>(n); - break; - } - default: { - throw ParseError("unexpected error: invalid operand type for unary operator", - std::vector{n.children[0]->begin()}); - } - } - }; + const std::string unary_operator_name = [&] { + if (n.is_type<language::unary_minus>()) { + return unaryOperatorMangler<language::unary_minus>(data_type); + } else if (n.is_type<language::unary_not>()) { + return unaryOperatorMangler<language::unary_not>(data_type); + } else { + // LCOV_EXCL_START + throw ParseError("unexpected error: undefined unary operator", std::vector{n.begin()}); + // LCOV_EXCL_STOP + } + }(); - auto set_unary_operator_processor_for_value = [&](const ASTNodeDataType& value_type) { - const ASTNodeDataType data_type = n.children[0]->m_data_type; - switch (value_type) { - case ASTNodeDataType::bool_t: { - set_unary_operator_processor_for_data(bool{}, data_type); - break; - } - case ASTNodeDataType::int_t: { - set_unary_operator_processor_for_data(int64_t{}, data_type); - break; - } - case ASTNodeDataType::double_t: { - set_unary_operator_processor_for_data(double{}, data_type); - break; - } - case ASTNodeDataType::vector_t: { - if constexpr (std::is_same_v<OperatorT, language::unary_minus>) { - switch (data_type.dimension()) { - case 1: { - using ValueT = TinyVector<1>; - n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, ValueT>>(n); - break; - } - case 2: { - using ValueT = TinyVector<2>; - n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, ValueT>>(n); - break; - } - case 3: { - using ValueT = TinyVector<3>; - n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, ValueT>>(n); - break; - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: invalid vector dimension", std::vector{n.begin()}); - } - // LCOV_EXCL_STOP - } - } else { - // LCOV_EXCL_START - throw ParseError("unexpected error: invalid unary operator for vector data", std::vector{n.begin()}); - // LCOV_EXCL_STOP - } - break; - } - default: { - throw ParseError("undefined value type for unary operator", std::vector{n.begin()}); - } - } - }; + const auto& optional_processor_builder = OperatorRepository::instance().getUnaryProcessorBuilder(unary_operator_name); - set_unary_operator_processor_for_value(n.m_data_type); - }; - - if (n.is_type<language::unary_minus>()) { - set_unary_operator_processor(n, language::unary_minus{}); - } else if (n.is_type<language::unary_not>()) { - set_unary_operator_processor(n, language::unary_not{}); + if (optional_processor_builder.has_value()) { + n.m_node_processor = optional_processor_builder.value()->getNodeProcessor(n); } else { - throw ParseError("unexpected error: undefined unary operator", std::vector{n.begin()}); + std::ostringstream error_message; + error_message << "undefined unary operator type: "; + error_message << rang::fgB::red << unary_operator_name << rang::fg::reset; + + throw ParseError(error_message.str(), std::vector{n.children[0]->begin()}); } } diff --git a/src/language/ast/CMakeLists.txt b/src/language/ast/CMakeLists.txt index f4c31774302ccff20b3d24f686fd7e381ff43822..458690fbd4fa341b257fcfe997e489048d1f961c 100644 --- a/src/language/ast/CMakeLists.txt +++ b/src/language/ast/CMakeLists.txt @@ -9,7 +9,7 @@ add_library(PugsLanguageAST ASTNodeBuiltinFunctionExpressionBuilder.cpp ASTNodeDataTypeBuilder.cpp ASTNodeDataTypeChecker.cpp - ASTNodeDataType.cpp +# ASTNodeDataType.cpp ASTNodeDataTypeFlattener.cpp ASTNodeDeclarationToAffectationConverter.cpp ASTNodeEmptyBlockCleaner.cpp diff --git a/src/language/modules/BuiltinModule.hpp b/src/language/modules/BuiltinModule.hpp index 6ea3ee56ae6f4b8c3cbfd86ede3370a638d0bff4..2be1d162578fb0d111e6eac7ae93e10dae981bce 100644 --- a/src/language/modules/BuiltinModule.hpp +++ b/src/language/modules/BuiltinModule.hpp @@ -1,8 +1,8 @@ #ifndef BUILTIN_MODULE_HPP #define BUILTIN_MODULE_HPP -#include <language/ast/ASTNodeDataType.hpp> #include <language/modules/IModule.hpp> +#include <language/utils/ASTNodeDataType.hpp> class IBuiltinFunctionEmbedder; class TypeDescriptor; diff --git a/src/language/modules/ModuleRepository.cpp b/src/language/modules/ModuleRepository.cpp index abb5d527d4858f86ff3a25e68f4d666c2da8193b..65bfcafd1f1c85f077a97f6e932fa97da0079537 100644 --- a/src/language/modules/ModuleRepository.cpp +++ b/src/language/modules/ModuleRepository.cpp @@ -8,6 +8,7 @@ #include <language/modules/SchemeModule.hpp> #include <language/modules/UtilsModule.hpp> #include <language/modules/VTKModule.hpp> +#include <language/utils/BasicAffectationRegistrerFor.hpp> #include <language/utils/BuiltinFunctionEmbedder.hpp> #include <language/utils/ParseError.hpp> #include <language/utils/SymbolTable.hpp> @@ -77,6 +78,11 @@ ModuleRepository::populateSymbolTable(const ASTNode& module_name_node, SymbolTab this->_populateEmbedderTableT(module_name_node, module_name, populating_module.getNameTypeMap(), ASTNodeDataType::build<ASTNodeDataType::type_name_id_t>(), symbol_table, symbol_table.typeEmbedderTable()); + + for (auto [symbol_name, embedded] : populating_module.getNameTypeMap()) { + BasicAffectationRegisterFor<EmbeddedData>(ASTNodeDataType::build<ASTNodeDataType::type_id_t>(symbol_name)); + } + } else { throw ParseError(std::string{"could not find module "} + module_name, std::vector{module_name_node.begin()}); } diff --git a/src/language/node_processor/AffectationProcessor.hpp b/src/language/node_processor/AffectationProcessor.hpp index 6cdb19dfdd36359f6cd798149c7f2908770aadd0..88d4488365427aecbffd48abf9e37a3b08e55707 100644 --- a/src/language/node_processor/AffectationProcessor.hpp +++ b/src/language/node_processor/AffectationProcessor.hpp @@ -391,7 +391,7 @@ class AffectationToTinyVectorFromListProcessor final : public INodeProcessor } }; -template <typename OperatorT, typename ValueT> +template <typename ValueT> class AffectationToTupleProcessor final : public INodeProcessor { private: @@ -403,7 +403,6 @@ class AffectationToTupleProcessor final : public INodeProcessor DataVariant execute(ExecutionPolicy& exec_policy) { - static_assert(std::is_same_v<OperatorT, language::eq_op>, "forbidden affection operator to tuples"); DataVariant value = m_node.children[1]->execute(exec_policy); std::visit( @@ -450,7 +449,7 @@ class AffectationToTupleProcessor final : public INodeProcessor } }; -template <typename OperatorT, typename ValueT> +template <typename ValueT> class AffectationToTupleFromListProcessor final : public INodeProcessor { private: @@ -562,8 +561,6 @@ class AffectationToTupleFromListProcessor final : public INodeProcessor DataVariant execute(ExecutionPolicy& exec_policy) { - static_assert(std::is_same_v<OperatorT, language::eq_op>, "forbidden affection operator for list to tuple"); - std::visit( [&](auto&& value_list) { using ValueListT = std::decay_t<decltype(value_list)>; diff --git a/src/language/node_processor/BinaryExpressionProcessor.hpp b/src/language/node_processor/BinaryExpressionProcessor.hpp index 8f5d9c3220cf3018104d5d53e2036b9bb8217214..cfbff72617d7b99e68ea9693eca96fa718c3f918 100644 --- a/src/language/node_processor/BinaryExpressionProcessor.hpp +++ b/src/language/node_processor/BinaryExpressionProcessor.hpp @@ -6,6 +6,8 @@ #include <language/node_processor/INodeProcessor.hpp> #include <language/utils/ParseError.hpp> +#include <type_traits> + template <typename Op> struct BinOp; @@ -154,68 +156,49 @@ struct BinOp<language::divide_op> } }; -template <typename BinaryOpT, typename A_DataT, typename B_DataT> -class BinaryExpressionProcessor final : public INodeProcessor +template <typename BinaryOpT, typename ValueT, typename A_DataT, typename B_DataT> +struct BinaryExpressionProcessor final : public INodeProcessor { + private: ASTNode& m_node; PUGS_INLINE DataVariant _eval(const DataVariant& a, const DataVariant& b) { - // Add 'signed' when necessary to avoid signed/unsigned comparison warnings - if constexpr ((not(std::is_same_v<A_DataT, bool> or std::is_same_v<B_DataT, bool>)) and - (std::is_same_v<BinaryOpT, language::and_op> or std::is_same_v<BinaryOpT, language::or_op> or - std::is_same_v<BinaryOpT, language::xor_op> or std::is_same_v<BinaryOpT, language::eqeq_op> or - std::is_same_v<BinaryOpT, language::not_eq_op> or std::is_same_v<BinaryOpT, language::lesser_op> or - std::is_same_v<BinaryOpT, language::lesser_or_eq_op> or - std::is_same_v<BinaryOpT, language::greater_op> or - std::is_same_v<BinaryOpT, language::greater_or_eq_op>) and - (std::is_signed_v<A_DataT> xor std::is_signed_v<B_DataT>)) { - if constexpr (std::is_unsigned_v<A_DataT>) { - using signed_A_DataT = std::make_signed_t<A_DataT>; - const signed_A_DataT signed_a = static_cast<signed_A_DataT>(std::get<A_DataT>(a)); - return BinOp<BinaryOpT>().eval(signed_a, std::get<B_DataT>(b)); + if constexpr (std::is_arithmetic_v<A_DataT> and std::is_arithmetic_v<B_DataT>) { + if constexpr (std::is_signed_v<A_DataT> and not std::is_signed_v<B_DataT>) { + if constexpr (std::is_same_v<B_DataT, bool>) { + return static_cast<ValueT>( + BinOp<BinaryOpT>().eval(std::get<A_DataT>(a), static_cast<int64_t>(std::get<B_DataT>(b)))); + } else { + return static_cast<ValueT>( + BinOp<BinaryOpT>().eval(std::get<A_DataT>(a), std::make_signed_t<B_DataT>(std::get<B_DataT>(b)))); + } + + } else if constexpr (not std::is_signed_v<A_DataT> and std::is_signed_v<B_DataT>) { + if constexpr (std::is_same_v<A_DataT, bool>) { + return static_cast<ValueT>( + BinOp<BinaryOpT>().eval(static_cast<int64_t>(std::get<A_DataT>(a)), std::get<B_DataT>(b))); + } else { + return static_cast<ValueT>( + BinOp<BinaryOpT>().eval(std::make_signed_t<A_DataT>(std::get<A_DataT>(a)), std::get<B_DataT>(b))); + } } else { - using signed_B_DataT = std::make_signed_t<B_DataT>; - const signed_B_DataT signed_b = static_cast<signed_B_DataT>(std::get<B_DataT>(b)); - return BinOp<BinaryOpT>().eval(std::get<A_DataT>(a), signed_b); + return static_cast<ValueT>(BinOp<BinaryOpT>().eval(std::get<A_DataT>(a), std::get<B_DataT>(b))); } } else { - auto result = BinOp<BinaryOpT>().eval(std::get<A_DataT>(a), std::get<B_DataT>(b)); - if constexpr (std::is_same_v<decltype(result), int>) { - return static_cast<int64_t>(result); - } else { - return result; - } + return static_cast<ValueT>(BinOp<BinaryOpT>().eval(std::get<A_DataT>(a), std::get<B_DataT>(b))); } } - static inline const bool m_is_defined{[] { - if constexpr (std::is_same_v<BinaryOpT, language::xor_op>) { - return std::is_same_v<std::decay_t<A_DataT>, std::decay_t<B_DataT>> and std::is_integral_v<std::decay_t<A_DataT>>; - } - return true; - }()}; - public: DataVariant execute(ExecutionPolicy& exec_policy) { - if constexpr (m_is_defined) { - return this->_eval(m_node.children[0]->execute(exec_policy), m_node.children[1]->execute(exec_policy)); - } else { - return {}; // LCOV_EXCL_LINE - } + return this->_eval(m_node.children[0]->execute(exec_policy), m_node.children[1]->execute(exec_policy)); } - BinaryExpressionProcessor(ASTNode& node) : m_node{node} - { - if constexpr (not m_is_defined) { - // LCOV_EXCL_START - throw ParseError("invalid operands to binary expression", std::vector{m_node.begin()}); - // LCOV_EXCL_STOP - } - } + BinaryExpressionProcessor(ASTNode& node) : m_node{node} {} }; #endif // BINARY_EXPRESSION_PROCESSOR_HPP diff --git a/src/language/node_processor/ConcatExpressionProcessor.hpp b/src/language/node_processor/ConcatExpressionProcessor.hpp index e47178494fe2bf88f8c7e5bebf9455c58732b08e..bb6357c87124110e973730ff6fb3eb9d5fdde5a3 100644 --- a/src/language/node_processor/ConcatExpressionProcessor.hpp +++ b/src/language/node_processor/ConcatExpressionProcessor.hpp @@ -16,8 +16,12 @@ class ConcatExpressionProcessor final : public INodeProcessor { if constexpr (std::is_same_v<B_DataT, std::string>) { return a + std::get<B_DataT>(b); - } else { + } else if constexpr (std::is_arithmetic_v<B_DataT>) { return a + std::to_string(std::get<B_DataT>(b)); + } else { + std::ostringstream os; + os << a << b; + return os.str(); } } diff --git a/src/language/node_processor/INodeProcessor.hpp b/src/language/node_processor/INodeProcessor.hpp index ce06b9484f7c7b141861bddfc88f5b5c3bf9eecc..2c35b6c49cadd69536c415f5a86e5786c953a86c 100644 --- a/src/language/node_processor/INodeProcessor.hpp +++ b/src/language/node_processor/INodeProcessor.hpp @@ -8,8 +8,9 @@ #include <string> #include <typeinfo> -struct INodeProcessor +class INodeProcessor { + public: virtual DataVariant execute(ExecutionPolicy& exec_policy) = 0; std::string diff --git a/src/language/node_processor/UnaryExpressionProcessor.hpp b/src/language/node_processor/UnaryExpressionProcessor.hpp index c99c7f2dd828583c7dad8048338e68d26c807be2..055e3a028be043c8a30189b7e4cccddd99aeef4a 100644 --- a/src/language/node_processor/UnaryExpressionProcessor.hpp +++ b/src/language/node_processor/UnaryExpressionProcessor.hpp @@ -2,8 +2,8 @@ #define UNARY_EXPRESSION_PROCESSOR_HPP #include <language/PEGGrammar.hpp> +#include <language/ast/ASTNode.hpp> #include <language/node_processor/INodeProcessor.hpp> -#include <language/utils/SymbolTable.hpp> template <typename Op> struct UnaryOp; diff --git a/src/language/ast/ASTNodeDataType.cpp b/src/language/utils/ASTNodeDataType.cpp similarity index 99% rename from src/language/ast/ASTNodeDataType.cpp rename to src/language/utils/ASTNodeDataType.cpp index 1f0847f865a6972e7865f4b50601898ab5930616..02a352ac3d0f7435c89445d4113b037bd0f54c2c 100644 --- a/src/language/ast/ASTNodeDataType.cpp +++ b/src/language/utils/ASTNodeDataType.cpp @@ -1,4 +1,4 @@ -#include <language/ast/ASTNodeDataType.hpp> +#include <language/utils/ASTNodeDataType.hpp> #include <language/PEGGrammar.hpp> #include <language/ast/ASTNode.hpp> diff --git a/src/language/ast/ASTNodeDataType.hpp b/src/language/utils/ASTNodeDataType.hpp similarity index 100% rename from src/language/ast/ASTNodeDataType.hpp rename to src/language/utils/ASTNodeDataType.hpp diff --git a/src/language/utils/ASTNodeDataTypeTraits.hpp b/src/language/utils/ASTNodeDataTypeTraits.hpp index 946d63483dc8a61c33ade0b223c0619a66880fdd..ed668e5e40e1ff4920602014367f379aa384adb9 100644 --- a/src/language/utils/ASTNodeDataTypeTraits.hpp +++ b/src/language/utils/ASTNodeDataTypeTraits.hpp @@ -1,8 +1,8 @@ -#ifndef AST_NODE_DATA_TYPE_TRAITS_H -#define AST_NODE_DATA_TYPE_TRAITS_H +#ifndef AST_NODE_DATA_TYPE_TRAITS_HPP +#define AST_NODE_DATA_TYPE_TRAITS_HPP #include <algebra/TinyVector.hpp> -#include <language/ast/ASTNodeDataType.hpp> +#include <language/utils/ASTNodeDataType.hpp> #include <language/utils/FunctionSymbolId.hpp> #include <vector> @@ -32,4 +32,4 @@ template <typename T> inline ASTNodeDataType ast_node_data_type_from<std::vector<T>> = ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ast_node_data_type_from<T>); -#endif // AST_NODE_DATA_TYPE_TRAITS_H +#endif // AST_NODE_DATA_TYPE_TRAITS_HPP diff --git a/src/language/utils/AffectationMangler.hpp b/src/language/utils/AffectationMangler.hpp new file mode 100644 index 0000000000000000000000000000000000000000..85aaab35bfbabde5b9bdbc9b250f8440e68829e6 --- /dev/null +++ b/src/language/utils/AffectationMangler.hpp @@ -0,0 +1,52 @@ +#ifndef AFFECTATION_MANGLER_HPP +#define AFFECTATION_MANGLER_HPP + +#include <language/utils/ASTNodeDataType.hpp> +#include <utils/Exceptions.hpp> + +#include <string> + +namespace language +{ +struct eq_op; +struct multiplyeq_op; +struct divideeq_op; +struct pluseq_op; +struct minuseq_op; +} // namespace language + +template <typename AffectationOperatorT> +std::string +affectationMangler(const ASTNodeDataType& lhs, const ASTNodeDataType& rhs) +{ + const std::string lhs_name = dataTypeName(lhs); + + const std::string operator_name = [] { + if constexpr (std::is_same_v<language::eq_op, AffectationOperatorT>) { + return "="; + } else if constexpr (std::is_same_v<language::multiplyeq_op, AffectationOperatorT>) { + return "*="; + } else if constexpr (std::is_same_v<language::divideeq_op, AffectationOperatorT>) { + return "/="; + } else if constexpr (std::is_same_v<language::pluseq_op, AffectationOperatorT>) { + return "+="; + } else if constexpr (std::is_same_v<language::minuseq_op, AffectationOperatorT>) { + return "-="; + } else { + static_assert(std::is_same_v<language::eq_op, AffectationOperatorT>, "undefined affectation operator"); + } + }(); + + const std::string rhs_name = [&]() -> std::string { + if (rhs == ASTNodeDataType::list_t) { + return "list"; + } else if (rhs == ASTNodeDataType::tuple_t) { + return "tuple"; + } else { + return dataTypeName(rhs); + } + }(); + return lhs_name + " " + operator_name + " " + rhs_name; +} + +#endif // AFFECTATION_MANGLER_HPP diff --git a/src/language/utils/AffectationProcessorBuilder.hpp b/src/language/utils/AffectationProcessorBuilder.hpp new file mode 100644 index 0000000000000000000000000000000000000000..02042ad8825c7c890727edba6dd5dc41691a7d9e --- /dev/null +++ b/src/language/utils/AffectationProcessorBuilder.hpp @@ -0,0 +1,86 @@ +#ifndef AFFECTATION_PROCESSOR_BUILDER_HPP +#define AFFECTATION_PROCESSOR_BUILDER_HPP + +#include <algebra/TinyVector.hpp> +#include <language/PEGGrammar.hpp> +#include <language/node_processor/AffectationProcessor.hpp> +#include <language/utils/IAffectationProcessorBuilder.hpp> + +#include <type_traits> + +template <typename OperatorT, typename ValueT, typename DataT> +class AffectationProcessorBuilder final : public IAffectationProcessorBuilder +{ + public: + AffectationProcessorBuilder() = default; + std::unique_ptr<INodeProcessor> + getNodeProcessor(ASTNode& node) const + { + if constexpr (std::is_same_v<ValueT, TinyVector<1>> and std::is_same_v<DataT, int64_t> and + std::is_same_v<OperatorT, language::eq_op>) { + // Special treatment for the case 0 -> R^1 + if ((node.children[1]->is_type<language::integer>()) and (std::stoi(node.children[1]->string()) == 0)) { + return std::make_unique<AffectationFromZeroProcessor<ValueT>>(node); + } else { + return std::make_unique<AffectationProcessor<OperatorT, ValueT, DataT>>(node); + } + } else { + return std::make_unique<AffectationProcessor<OperatorT, ValueT, DataT>>(node); + } + } +}; + +template <typename ValueT> +class AffectationToTupleProcessorBuilder final : public IAffectationProcessorBuilder +{ + public: + AffectationToTupleProcessorBuilder() = default; + std::unique_ptr<INodeProcessor> + getNodeProcessor(ASTNode& node) const + { + return std::make_unique<AffectationToTupleProcessor<ValueT>>(node); + } +}; + +template <typename ValueT> +class AffectationToTupleFromListProcessorBuilder final : public IAffectationProcessorBuilder +{ + public: + AffectationToTupleFromListProcessorBuilder() = default; + std::unique_ptr<INodeProcessor> + getNodeProcessor(ASTNode& node) const + { + return std::make_unique<AffectationToTupleFromListProcessor<ValueT>>(node); + } +}; + +template <typename OperatorT, typename ValueT> +class AffectationToTinyVectorFromListProcessorBuilder final : public IAffectationProcessorBuilder +{ + public: + AffectationToTinyVectorFromListProcessorBuilder() = default; + std::unique_ptr<INodeProcessor> + getNodeProcessor(ASTNode& node) const + { + return std::make_unique<AffectationToTinyVectorFromListProcessor<OperatorT, ValueT>>(node); + } +}; + +template <typename OperatorT, typename ValueT> +class AffectationFromZeroProcessorBuilder final : public IAffectationProcessorBuilder +{ + public: + AffectationFromZeroProcessorBuilder() = default; + std::unique_ptr<INodeProcessor> + getNodeProcessor(ASTNode& node) const + { + if (std::stoi(node.children[1]->string()) == 0) { + return std::make_unique<AffectationFromZeroProcessor<ValueT>>(node); + } + // LCOV_EXCL_START + throw ParseError("unexpected error: invalid integral value", std::vector{node.children[1]->begin()}); + // LCOV_EXCL_STOP + } +}; + +#endif // AFFECTATION_PROCESSOR_BUILDER_HPP diff --git a/src/language/utils/AffectationRegisterForB.cpp b/src/language/utils/AffectationRegisterForB.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69feaee7066a7d95f17bf539df75e46cf3fe27c5 --- /dev/null +++ b/src/language/utils/AffectationRegisterForB.cpp @@ -0,0 +1,10 @@ +#include <language/utils/AffectationRegisterForB.hpp> + +#include <language/utils/AffectationProcessorBuilder.hpp> +#include <language/utils/BasicAffectationRegistrerFor.hpp> +#include <language/utils/OperatorRepository.hpp> + +AffectationRegisterForB::AffectationRegisterForB() +{ + BasicAffectationRegisterFor<bool>{}; +} diff --git a/src/language/utils/AffectationRegisterForB.hpp b/src/language/utils/AffectationRegisterForB.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d6507ff7a1edf0d48839924a8b3aa051ff441c09 --- /dev/null +++ b/src/language/utils/AffectationRegisterForB.hpp @@ -0,0 +1,10 @@ +#ifndef AFFECTATION_REGISTER_FOR_B_HPP +#define AFFECTATION_REGISTER_FOR_B_HPP + +class AffectationRegisterForB +{ + public: + AffectationRegisterForB(); +}; + +#endif // AFFECTATION_REGISTER_FOR_B_HPP diff --git a/src/language/utils/AffectationRegisterForN.cpp b/src/language/utils/AffectationRegisterForN.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e7d54008f22845f8233b8475091c8cec774c6756 --- /dev/null +++ b/src/language/utils/AffectationRegisterForN.cpp @@ -0,0 +1,120 @@ +#include <language/utils/AffectationRegisterForN.hpp> + +#include <language/utils/AffectationProcessorBuilder.hpp> +#include <language/utils/BasicAffectationRegistrerFor.hpp> +#include <language/utils/OperatorRepository.hpp> + +void +AffectationRegisterForN::_register_eq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto N = ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(); + + repository + .addAffectation<language::eq_op>(N, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, uint64_t, bool>>()); + + repository.addAffectation< + language::eq_op>(N, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, uint64_t, int64_t>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(N), + ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<uint64_t>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(N), + ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<uint64_t>>()); +} + +void +AffectationRegisterForN::_register_pluseq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto N = ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(); + + repository.addAffectation< + language::pluseq_op>(N, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::pluseq_op, uint64_t, bool>>()); + + repository.addAffectation< + language::pluseq_op>(N, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder<language::pluseq_op, uint64_t, uint64_t>>()); + + repository.addAffectation< + language::pluseq_op>(N, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::pluseq_op, uint64_t, int64_t>>()); +} + +void +AffectationRegisterForN::_register_minuseq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto N = ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(); + + repository.addAffectation< + language::minuseq_op>(N, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::minuseq_op, uint64_t, bool>>()); + + repository.addAffectation< + language::minuseq_op>(N, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder<language::minuseq_op, uint64_t, uint64_t>>()); + + repository.addAffectation< + language::minuseq_op>(N, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::minuseq_op, uint64_t, int64_t>>()); +} + +void +AffectationRegisterForN::_register_multiplyeq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto N = ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(); + + repository.addAffectation< + language::multiplyeq_op>(N, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::multiplyeq_op, uint64_t, bool>>()); + + repository.addAffectation<language::multiplyeq_op>(N, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder< + language::multiplyeq_op, uint64_t, uint64_t>>()); + + repository.addAffectation<language::multiplyeq_op>(N, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder< + language::multiplyeq_op, uint64_t, int64_t>>()); +} + +void +AffectationRegisterForN::_register_divideeq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto N = ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(); + + repository.addAffectation< + language::divideeq_op>(N, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::divideeq_op, uint64_t, bool>>()); + + repository.addAffectation< + language::divideeq_op>(N, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder<language::divideeq_op, uint64_t, uint64_t>>()); + + repository.addAffectation< + language::divideeq_op>(N, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::divideeq_op, uint64_t, int64_t>>()); +} + +AffectationRegisterForN::AffectationRegisterForN() +{ + BasicAffectationRegisterFor<uint64_t>{}; + + this->_register_eq_op(); + this->_register_pluseq_op(); + this->_register_minuseq_op(); + this->_register_multiplyeq_op(); + this->_register_divideeq_op(); +} diff --git a/src/language/utils/AffectationRegisterForN.hpp b/src/language/utils/AffectationRegisterForN.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e97a652c094635fbaa54b9b267c37f3a169367a0 --- /dev/null +++ b/src/language/utils/AffectationRegisterForN.hpp @@ -0,0 +1,17 @@ +#ifndef AFFECTATION_REGISTER_FOR_N_HPP +#define AFFECTATION_REGISTER_FOR_N_HPP + +class AffectationRegisterForN +{ + private: + void _register_eq_op(); + void _register_pluseq_op(); + void _register_minuseq_op(); + void _register_multiplyeq_op(); + void _register_divideeq_op(); + + public: + AffectationRegisterForN(); +}; + +#endif // AFFECTATION_REGISTER_FOR_N_HPP diff --git a/src/language/utils/AffectationRegisterForR.cpp b/src/language/utils/AffectationRegisterForR.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ae7c63c4031f39871f64713c39cc7dcba8e0bae4 --- /dev/null +++ b/src/language/utils/AffectationRegisterForR.cpp @@ -0,0 +1,141 @@ +#include <language/utils/AffectationRegisterForR.hpp> + +#include <language/utils/AffectationProcessorBuilder.hpp> +#include <language/utils/BasicAffectationRegistrerFor.hpp> +#include <language/utils/OperatorRepository.hpp> + +void +AffectationRegisterForR::_register_eq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto R = ASTNodeDataType::build<ASTNodeDataType::double_t>(); + + repository + .addAffectation<language::eq_op>(R, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, double, bool>>()); + + repository.addAffectation< + language::eq_op>(R, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, double, uint64_t>>()); + + repository + .addAffectation<language::eq_op>(R, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, double, int64_t>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(R), + ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<double>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(R), + ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<double>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(R), + ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<double>>()); +} + +void +AffectationRegisterForR::_register_pluseq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto R = ASTNodeDataType::build<ASTNodeDataType::double_t>(); + + repository.addAffectation< + language::pluseq_op>(R, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::pluseq_op, double, bool>>()); + + repository.addAffectation< + language::pluseq_op>(R, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder<language::pluseq_op, double, uint64_t>>()); + + repository.addAffectation< + language::pluseq_op>(R, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::pluseq_op, double, int64_t>>()); + + repository.addAffectation< + language::pluseq_op>(R, R, std::make_shared<AffectationProcessorBuilder<language::pluseq_op, double, double>>()); +} + +void +AffectationRegisterForR::_register_minuseq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto R = ASTNodeDataType::build<ASTNodeDataType::double_t>(); + + repository.addAffectation< + language::minuseq_op>(R, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::minuseq_op, double, bool>>()); + + repository.addAffectation< + language::minuseq_op>(R, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder<language::minuseq_op, double, uint64_t>>()); + + repository.addAffectation< + language::minuseq_op>(R, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::minuseq_op, double, int64_t>>()); + + repository.addAffectation< + language::minuseq_op>(R, R, std::make_shared<AffectationProcessorBuilder<language::minuseq_op, double, double>>()); +} + +void +AffectationRegisterForR::_register_multiplyeq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto R = ASTNodeDataType::build<ASTNodeDataType::double_t>(); + + repository.addAffectation< + language::multiplyeq_op>(R, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::multiplyeq_op, double, bool>>()); + + repository.addAffectation<language::multiplyeq_op>(R, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder< + language::multiplyeq_op, double, uint64_t>>()); + + repository.addAffectation< + language::multiplyeq_op>(R, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::multiplyeq_op, double, int64_t>>()); + + repository.addAffectation< + language::multiplyeq_op>(R, R, + std::make_shared<AffectationProcessorBuilder<language::multiplyeq_op, double, double>>()); +} + +void +AffectationRegisterForR::_register_divideeq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto R = ASTNodeDataType::build<ASTNodeDataType::double_t>(); + + repository.addAffectation< + language::divideeq_op>(R, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::divideeq_op, double, bool>>()); + + repository.addAffectation< + language::divideeq_op>(R, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder<language::divideeq_op, double, uint64_t>>()); + + repository.addAffectation< + language::divideeq_op>(R, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::divideeq_op, double, int64_t>>()); + + repository.addAffectation< + language::divideeq_op>(R, R, + std::make_shared<AffectationProcessorBuilder<language::divideeq_op, double, double>>()); +} + +AffectationRegisterForR::AffectationRegisterForR() +{ + BasicAffectationRegisterFor<double>{}; + this->_register_eq_op(); + this->_register_pluseq_op(); + this->_register_minuseq_op(); + this->_register_multiplyeq_op(); + this->_register_divideeq_op(); +} diff --git a/src/language/utils/AffectationRegisterForR.hpp b/src/language/utils/AffectationRegisterForR.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3a004a92a276edad8dc52b015c2802aa4055aa11 --- /dev/null +++ b/src/language/utils/AffectationRegisterForR.hpp @@ -0,0 +1,17 @@ +#ifndef AFFECTATION_REGISTER_FOR_R_HPP +#define AFFECTATION_REGISTER_FOR_R_HPP + +class AffectationRegisterForR +{ + private: + void _register_eq_op(); + void _register_pluseq_op(); + void _register_minuseq_op(); + void _register_multiplyeq_op(); + void _register_divideeq_op(); + + public: + AffectationRegisterForR(); +}; + +#endif // AFFECTATION_REGISTER_FOR_R_HPP diff --git a/src/language/utils/AffectationRegisterForRn.cpp b/src/language/utils/AffectationRegisterForRn.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7d38dc64c1d245d4d6c530e891ffd6eaecd63372 --- /dev/null +++ b/src/language/utils/AffectationRegisterForRn.cpp @@ -0,0 +1,143 @@ +#include <language/utils/AffectationRegisterForRn.hpp> + +#include <language/utils/AffectationProcessorBuilder.hpp> +#include <language/utils/BasicAffectationRegistrerFor.hpp> +#include <language/utils/OperatorRepository.hpp> + +template <size_t Dimension> +void +AffectationRegisterForRn<Dimension>::_register_eq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto Rn = ASTNodeDataType::build<ASTNodeDataType::vector_t>(Dimension); + + repository.addAffectation< + language::eq_op>(Rn, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationFromZeroProcessorBuilder<language::eq_op, TinyVector<Dimension>>>()); + + repository.addAffectation<language::eq_op>(Rn, + ASTNodeDataType::build<ASTNodeDataType::list_t>( + std::vector<std::shared_ptr<const ASTNodeDataType>>{}), + std::make_shared<AffectationToTinyVectorFromListProcessorBuilder< + language::eq_op, TinyVector<Dimension>>>()); + + repository + .addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(Rn), + ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<TinyVector<Dimension>>>()); +} + +template <> +void +AffectationRegisterForRn<1>::_register_eq_op() +{ + constexpr size_t Dimension = 1; + + OperatorRepository& repository = OperatorRepository::instance(); + + auto Rn = ASTNodeDataType::build<ASTNodeDataType::vector_t>(Dimension); + + repository.addAffectation< + language::eq_op>(Rn, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, TinyVector<Dimension>, bool>>()); + + repository.addAffectation< + language::eq_op>(Rn, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, TinyVector<Dimension>, uint64_t>>()); + + repository.addAffectation< + language::eq_op>(Rn, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, TinyVector<Dimension>, int64_t>>()); + + repository.addAffectation< + language::eq_op>(Rn, ASTNodeDataType::build<ASTNodeDataType::double_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, TinyVector<Dimension>, double>>()); + + repository + .addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(Rn), + ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<TinyVector<Dimension>>>()); + + repository + .addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(Rn), + ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<TinyVector<Dimension>>>()); + + repository + .addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(Rn), + ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<TinyVector<Dimension>>>()); + + repository + .addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(Rn), + ASTNodeDataType::build<ASTNodeDataType::double_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<TinyVector<Dimension>>>()); +} + +template <size_t Dimension> +void +AffectationRegisterForRn<Dimension>::_register_pluseq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto Rn = ASTNodeDataType::build<ASTNodeDataType::vector_t>(Dimension); + + repository + .addAffectation<language::pluseq_op>(Rn, Rn, + std::make_shared<AffectationProcessorBuilder< + language::pluseq_op, TinyVector<Dimension>, TinyVector<Dimension>>>()); +} + +template <size_t Dimension> +void +AffectationRegisterForRn<Dimension>::_register_minuseq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto Rn = ASTNodeDataType::build<ASTNodeDataType::vector_t>(Dimension); + + repository + .addAffectation<language::minuseq_op>(Rn, Rn, + std::make_shared<AffectationProcessorBuilder< + language::minuseq_op, TinyVector<Dimension>, TinyVector<Dimension>>>()); +} + +template <size_t Dimension> +void +AffectationRegisterForRn<Dimension>::_register_multiplyeq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto Rn = ASTNodeDataType::build<ASTNodeDataType::vector_t>(Dimension); + + repository.addAffectation<language::multiplyeq_op>(Rn, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder< + language::multiplyeq_op, TinyVector<Dimension>, bool>>()); + + repository.addAffectation<language::multiplyeq_op>(Rn, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder< + language::multiplyeq_op, TinyVector<Dimension>, uint64_t>>()); + + repository.addAffectation<language::multiplyeq_op>(Rn, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder< + language::multiplyeq_op, TinyVector<Dimension>, int64_t>>()); + + repository.addAffectation<language::multiplyeq_op>(Rn, ASTNodeDataType::build<ASTNodeDataType::double_t>(), + std::make_shared<AffectationProcessorBuilder< + language::multiplyeq_op, TinyVector<Dimension>, double>>()); +} + +template <size_t Dimension> +AffectationRegisterForRn<Dimension>::AffectationRegisterForRn() +{ + BasicAffectationRegisterFor<TinyVector<Dimension>>{}; + this->_register_eq_op(); + this->_register_pluseq_op(); + this->_register_minuseq_op(); + this->_register_multiplyeq_op(); +} + +template class AffectationRegisterForRn<1>; +template class AffectationRegisterForRn<2>; +template class AffectationRegisterForRn<3>; diff --git a/src/language/utils/AffectationRegisterForRn.hpp b/src/language/utils/AffectationRegisterForRn.hpp new file mode 100644 index 0000000000000000000000000000000000000000..337a340b81b7a59d35ee11dd5946d2313560ebe8 --- /dev/null +++ b/src/language/utils/AffectationRegisterForRn.hpp @@ -0,0 +1,19 @@ +#ifndef AFFECTATION_REGISTER_FOR_RN_HPP +#define AFFECTATION_REGISTER_FOR_RN_HPP + +#include <cstdlib> + +template <size_t Dimension> +class AffectationRegisterForRn +{ + private: + void _register_eq_op(); + void _register_pluseq_op(); + void _register_minuseq_op(); + void _register_multiplyeq_op(); + + public: + AffectationRegisterForRn(); +}; + +#endif // AFFECTATION_REGISTER_FOR_RN_HPP diff --git a/src/language/utils/AffectationRegisterForString.cpp b/src/language/utils/AffectationRegisterForString.cpp new file mode 100644 index 0000000000000000000000000000000000000000..37446e243d6fcb14fcd6c3e97a845d17b831c2e6 --- /dev/null +++ b/src/language/utils/AffectationRegisterForString.cpp @@ -0,0 +1,140 @@ +#include <language/utils/AffectationRegisterForString.hpp> + +#include <language/utils/AffectationProcessorBuilder.hpp> +#include <language/utils/BasicAffectationRegistrerFor.hpp> +#include <language/utils/OperatorRepository.hpp> + +void +AffectationRegisterForString::_register_eq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto string_t = ASTNodeDataType::build<ASTNodeDataType::string_t>(); + + repository.addAffectation< + language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, bool>>()); + + repository.addAffectation< + language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, uint64_t>>()); + + repository.addAffectation< + language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, int64_t>>()); + + repository.addAffectation< + language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::double_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, double_t>>()); + + repository.addAffectation< + language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::vector_t>(1), + std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, TinyVector<1>>>()); + + repository.addAffectation< + language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::vector_t>(2), + std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, TinyVector<2>>>()); + + repository.addAffectation< + language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::vector_t>(3), + std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, TinyVector<3>>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t), + ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<std::string>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t), + ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<std::string>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t), + ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<std::string>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t), + ASTNodeDataType::build<ASTNodeDataType::double_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<std::string>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t), + ASTNodeDataType::build<ASTNodeDataType::vector_t>(1), + std::make_shared<AffectationToTupleProcessorBuilder<std::string>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t), + ASTNodeDataType::build<ASTNodeDataType::vector_t>(2), + std::make_shared<AffectationToTupleProcessorBuilder<std::string>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t), + ASTNodeDataType::build<ASTNodeDataType::vector_t>(3), + std::make_shared<AffectationToTupleProcessorBuilder<std::string>>()); +} + +void +AffectationRegisterForString::_register_pluseq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto string_t = ASTNodeDataType::build<ASTNodeDataType::string_t>(); + + repository.addAffectation<language::pluseq_op>(string_t, string_t, + std::make_shared<AffectationProcessorBuilder< + language::pluseq_op, std::string, std::string>>()); + + repository.addAffectation< + language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, bool>>()); + + repository.addAffectation< + language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, uint64_t>>()); + + repository.addAffectation< + language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, int64_t>>()); + + repository.addAffectation< + language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::double_t>(), + std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, double>>()); + + repository.addAffectation<language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::vector_t>(1), + std::make_shared<AffectationProcessorBuilder< + language::pluseq_op, std::string, TinyVector<1>>>()); + + repository.addAffectation<language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::vector_t>(2), + std::make_shared<AffectationProcessorBuilder< + language::pluseq_op, std::string, TinyVector<2>>>()); + + repository.addAffectation<language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::vector_t>(3), + std::make_shared<AffectationProcessorBuilder< + language::pluseq_op, std::string, TinyVector<3>>>()); + + // this->_addAffectation("string += string", + // std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, + // std::string>>()); + // this->_addAffectation("string += B", + // std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, bool>>()); + // this->_addAffectation("string += N", + // std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, uint64_t>>()); + // this->_addAffectation("string += Z", + // std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, int64_t>>()); + // this->_addAffectation("string += R", + // std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, double>>()); + // this + // ->_addAffectation("string += R^1", + // std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, + // TinyVector<1>>>()); + // this + // ->_addAffectation("string += R^2", + // std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, + // TinyVector<2>>>()); + // this + // ->_addAffectation("string += R^3", + // std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, + // TinyVector<3>>>()); +} + +AffectationRegisterForString::AffectationRegisterForString() +{ + BasicAffectationRegisterFor<std::string>{}; + this->_register_eq_op(); + this->_register_pluseq_op(); +} diff --git a/src/language/utils/AffectationRegisterForString.hpp b/src/language/utils/AffectationRegisterForString.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b6b6a47d4fcfe913f486d1069e73920795e1d451 --- /dev/null +++ b/src/language/utils/AffectationRegisterForString.hpp @@ -0,0 +1,14 @@ +#ifndef AFFECTATION_REGISTER_FOR_STRING_HPP +#define AFFECTATION_REGISTER_FOR_STRING_HPP + +class AffectationRegisterForString +{ + private: + void _register_eq_op(); + void _register_pluseq_op(); + + public: + AffectationRegisterForString(); +}; + +#endif // AFFECTATION_REGISTER_FOR_STRING_HPP diff --git a/src/language/utils/AffectationRegisterForZ.cpp b/src/language/utils/AffectationRegisterForZ.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9937a0edbaedce2ae054d02fc13d7c4e1168c698 --- /dev/null +++ b/src/language/utils/AffectationRegisterForZ.cpp @@ -0,0 +1,119 @@ +#include <language/utils/AffectationRegisterForZ.hpp> + +#include <language/utils/AffectationProcessorBuilder.hpp> +#include <language/utils/BasicAffectationRegistrerFor.hpp> +#include <language/utils/OperatorRepository.hpp> + +void +AffectationRegisterForZ::_register_eq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto Z = ASTNodeDataType::build<ASTNodeDataType::int_t>(); + + repository + .addAffectation<language::eq_op>(Z, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, int64_t, bool>>()); + + repository.addAffectation< + language::eq_op>(Z, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder<language::eq_op, int64_t, uint64_t>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(Z), + ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<int64_t>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(Z), + ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationToTupleProcessorBuilder<int64_t>>()); +} + +void +AffectationRegisterForZ::_register_pluseq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto Z = ASTNodeDataType::build<ASTNodeDataType::int_t>(); + + repository.addAffectation< + language::pluseq_op>(Z, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::pluseq_op, int64_t, bool>>()); + + repository.addAffectation< + language::pluseq_op>(Z, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder<language::pluseq_op, int64_t, uint64_t>>()); + + repository.addAffectation< + language::pluseq_op>(Z, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::pluseq_op, int64_t, int64_t>>()); +} + +void +AffectationRegisterForZ::_register_minuseq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto Z = ASTNodeDataType::build<ASTNodeDataType::int_t>(); + + repository.addAffectation< + language::minuseq_op>(Z, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::minuseq_op, int64_t, bool>>()); + + repository.addAffectation< + language::minuseq_op>(Z, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder<language::minuseq_op, int64_t, uint64_t>>()); + + repository.addAffectation< + language::minuseq_op>(Z, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::minuseq_op, int64_t, int64_t>>()); +} + +void +AffectationRegisterForZ::_register_multiplyeq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto Z = ASTNodeDataType::build<ASTNodeDataType::int_t>(); + + repository.addAffectation< + language::multiplyeq_op>(Z, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::multiplyeq_op, int64_t, bool>>()); + + repository.addAffectation<language::multiplyeq_op>(Z, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder< + language::multiplyeq_op, int64_t, uint64_t>>()); + + repository.addAffectation<language::multiplyeq_op>(Z, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder< + language::multiplyeq_op, int64_t, int64_t>>()); +} + +void +AffectationRegisterForZ::_register_divideeq_op() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto Z = ASTNodeDataType::build<ASTNodeDataType::int_t>(); + + repository.addAffectation< + language::divideeq_op>(Z, ASTNodeDataType::build<ASTNodeDataType::bool_t>(), + std::make_shared<AffectationProcessorBuilder<language::divideeq_op, int64_t, bool>>()); + + repository.addAffectation< + language::divideeq_op>(Z, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(), + std::make_shared<AffectationProcessorBuilder<language::divideeq_op, int64_t, uint64_t>>()); + + repository.addAffectation< + language::divideeq_op>(Z, ASTNodeDataType::build<ASTNodeDataType::int_t>(), + std::make_shared<AffectationProcessorBuilder<language::divideeq_op, int64_t, int64_t>>()); +} + +AffectationRegisterForZ::AffectationRegisterForZ() +{ + BasicAffectationRegisterFor<int64_t>{}; + this->_register_eq_op(); + this->_register_pluseq_op(); + this->_register_minuseq_op(); + this->_register_multiplyeq_op(); + this->_register_divideeq_op(); +} diff --git a/src/language/utils/AffectationRegisterForZ.hpp b/src/language/utils/AffectationRegisterForZ.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a559c94fda9ef5a089d85af9f9773693ce9c9fb4 --- /dev/null +++ b/src/language/utils/AffectationRegisterForZ.hpp @@ -0,0 +1,17 @@ +#ifndef AFFECTATION_REGISTER_FOR_Z_HPP +#define AFFECTATION_REGISTER_FOR_Z_HPP + +class AffectationRegisterForZ +{ + private: + void _register_eq_op(); + void _register_pluseq_op(); + void _register_minuseq_op(); + void _register_multiplyeq_op(); + void _register_divideeq_op(); + + public: + AffectationRegisterForZ(); +}; + +#endif // AFFECTATION_REGISTER_FOR_Z_HPP diff --git a/src/language/utils/BasicAffectationRegistrerFor.hpp b/src/language/utils/BasicAffectationRegistrerFor.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ccae4c32b596b39ce7b663da38e31e70c8dfbebc --- /dev/null +++ b/src/language/utils/BasicAffectationRegistrerFor.hpp @@ -0,0 +1,36 @@ +#ifndef BASIC_AFFECTATION_REGISTRER_FOR_HPP +#define BASIC_AFFECTATION_REGISTRER_FOR_HPP + +#include <language/utils/ASTNodeDataTypeTraits.hpp> +#include <language/utils/AffectationProcessorBuilder.hpp> +#include <language/utils/OperatorRepository.hpp> + +template <typename T> +class BasicAffectationRegisterFor +{ + public: + BasicAffectationRegisterFor() : BasicAffectationRegisterFor(ast_node_data_type_from<T>) {} + + BasicAffectationRegisterFor(const ASTNodeDataType& ast_node_data_type) + { + OperatorRepository& repository = OperatorRepository::instance(); + + repository.addAffectation<language::eq_op>(ast_node_data_type, ast_node_data_type, + std::make_shared<AffectationProcessorBuilder<language::eq_op, T, T>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ast_node_data_type), + ast_node_data_type, + std::make_shared<AffectationToTupleProcessorBuilder<T>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ast_node_data_type), + ASTNodeDataType::build<ASTNodeDataType::list_t>( + std::vector<std::shared_ptr<const ASTNodeDataType>>{}), + std::make_shared<AffectationToTupleFromListProcessorBuilder<T>>()); + + repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ast_node_data_type), + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ast_node_data_type), + std::make_shared<AffectationToTupleFromListProcessorBuilder<T>>()); + } +}; + +#endif // BASIC_AFFECTATION_REGISTRER_FOR_HPP diff --git a/src/language/utils/BasicBinaryOperatorRegisterComparisonOf.hpp b/src/language/utils/BasicBinaryOperatorRegisterComparisonOf.hpp new file mode 100644 index 0000000000000000000000000000000000000000..758117182df0c170c1c00c00ea38938668eae2c6 --- /dev/null +++ b/src/language/utils/BasicBinaryOperatorRegisterComparisonOf.hpp @@ -0,0 +1,34 @@ +#ifndef BASIC_BINARY_OPERATOR_REGISTER_COMPARISON_OF_HPP +#define BASIC_BINARY_OPERATOR_REGISTER_COMPARISON_OF_HPP + +#include <language/utils/BinaryOperatorProcessorBuilder.hpp> +#include <language/utils/OperatorRepository.hpp> + +template <typename A_DataT, typename B_DataT> +struct BasicBinaryOperatorRegisterComparisonOf +{ + BasicBinaryOperatorRegisterComparisonOf() + { + OperatorRepository& repository = OperatorRepository::instance(); + + repository.addBinaryOperator<language::eqeq_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::eqeq_op, bool, A_DataT, B_DataT>>()); + + repository.addBinaryOperator<language::not_eq_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::not_eq_op, bool, A_DataT, B_DataT>>()); + + repository.addBinaryOperator<language::greater_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::greater_op, bool, A_DataT, B_DataT>>()); + + repository.addBinaryOperator<language::greater_or_eq_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::greater_or_eq_op, bool, A_DataT, B_DataT>>()); + + repository.addBinaryOperator<language::lesser_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::lesser_op, bool, A_DataT, B_DataT>>()); + + repository.addBinaryOperator<language::lesser_or_eq_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::lesser_or_eq_op, bool, A_DataT, B_DataT>>()); + } +}; + +#endif // BASIC_BINARY_OPERATOR_REGISTER_COMPARISON_OF_HPP diff --git a/src/language/utils/BinaryOperatorMangler.hpp b/src/language/utils/BinaryOperatorMangler.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f3648f3fb860a6207b70ad712aee9935b669e493 --- /dev/null +++ b/src/language/utils/BinaryOperatorMangler.hpp @@ -0,0 +1,67 @@ +#ifndef BINARY_OPERATOR_MANGLER_HPP +#define BINARY_OPERATOR_MANGLER_HPP + +#include <language/utils/ASTNodeDataType.hpp> +#include <utils/Exceptions.hpp> + +#include <string> + +namespace language +{ +struct multiply_op; +struct divide_op; +struct plus_op; +struct minus_op; + +struct or_op; +struct and_op; +struct xor_op; + +struct greater_op; +struct greater_or_eq_op; +struct lesser_op; +struct lesser_or_eq_op; +struct eqeq_op; +struct not_eq_op; +} // namespace language + +template <typename BinaryOperatorT> +std::string +binaryOperatorMangler(const ASTNodeDataType& lhs_data_type, const ASTNodeDataType& rhs_data_type) +{ + const std::string operator_name = [] { + if constexpr (std::is_same_v<BinaryOperatorT, language::multiply_op>) { + return "*"; + } else if constexpr (std::is_same_v<BinaryOperatorT, language::divide_op>) { + return "/"; + } else if constexpr (std::is_same_v<BinaryOperatorT, language::plus_op>) { + return "+"; + } else if constexpr (std::is_same_v<BinaryOperatorT, language::minus_op>) { + return "-"; + } else if constexpr (std::is_same_v<BinaryOperatorT, language::or_op>) { + return "or"; + } else if constexpr (std::is_same_v<BinaryOperatorT, language::and_op>) { + return "and"; + } else if constexpr (std::is_same_v<BinaryOperatorT, language::xor_op>) { + return "xor"; + } else if constexpr (std::is_same_v<BinaryOperatorT, language::greater_op>) { + return ">"; + } else if constexpr (std::is_same_v<BinaryOperatorT, language::greater_or_eq_op>) { + return ">="; + } else if constexpr (std::is_same_v<BinaryOperatorT, language::lesser_op>) { + return "<"; + } else if constexpr (std::is_same_v<BinaryOperatorT, language::lesser_or_eq_op>) { + return "<="; + } else if constexpr (std::is_same_v<BinaryOperatorT, language::eqeq_op>) { + return "=="; + } else if constexpr (std::is_same_v<BinaryOperatorT, language::not_eq_op>) { + return "!="; + } else { + static_assert(std::is_same_v<language::multiply_op, BinaryOperatorT>, "undefined binary operator"); + } + }(); + + return dataTypeName(lhs_data_type) + " " + operator_name + " " + dataTypeName(rhs_data_type); +} + +#endif // BINARY_OPERATOR_MANGLER_HPP diff --git a/src/language/utils/BinaryOperatorProcessorBuilder.hpp b/src/language/utils/BinaryOperatorProcessorBuilder.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b8cb572d1e79c1882ed0288d79a4b73c6c130e5c --- /dev/null +++ b/src/language/utils/BinaryOperatorProcessorBuilder.hpp @@ -0,0 +1,43 @@ +#ifndef BINARY_OPERATOR_PROCESSOR_BUILDER_HPP +#define BINARY_OPERATOR_PROCESSOR_BUILDER_HPP + +#include <algebra/TinyVector.hpp> +#include <language/PEGGrammar.hpp> +#include <language/node_processor/BinaryExpressionProcessor.hpp> +#include <language/utils/ASTNodeDataTypeTraits.hpp> +#include <language/utils/IBinaryOperatorProcessorBuilder.hpp> + +#include <type_traits> + +template <typename OperatorT, typename ValueT, typename A_DataT, typename B_DataT> +class BinaryOperatorProcessorBuilder final : public IBinaryOperatorProcessorBuilder +{ + public: + BinaryOperatorProcessorBuilder() = default; + + ASTNodeDataType + getDataTypeOfA() const + { + return ast_node_data_type_from<A_DataT>; + } + + ASTNodeDataType + getDataTypeOfB() const + { + return ast_node_data_type_from<B_DataT>; + } + + ASTNodeDataType + getReturnValueType() const + { + return ast_node_data_type_from<ValueT>; + } + + std::unique_ptr<INodeProcessor> + getNodeProcessor(ASTNode& node) const + { + return std::make_unique<BinaryExpressionProcessor<OperatorT, ValueT, A_DataT, B_DataT>>(node); + } +}; + +#endif // BINARY_OPERATOR_PROCESSOR_BUILDER_HPP diff --git a/src/language/utils/BinaryOperatorRegisterForB.cpp b/src/language/utils/BinaryOperatorRegisterForB.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cba803aaf3e3d7d4c72be7b69ca1a835203a49b2 --- /dev/null +++ b/src/language/utils/BinaryOperatorRegisterForB.cpp @@ -0,0 +1,70 @@ +#include <language/utils/BinaryOperatorRegisterForB.hpp> + +#include <language/utils/BasicBinaryOperatorRegisterComparisonOf.hpp> + +void +BinaryOperatorRegisterForB::_register_comparisons() +{ + BasicBinaryOperatorRegisterComparisonOf<bool, bool>{}; +} + +void +BinaryOperatorRegisterForB::_register_logical_operators() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + repository.addBinaryOperator<language::and_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::and_op, bool, bool, bool>>()); + + repository.addBinaryOperator<language::or_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::or_op, bool, bool, bool>>()); + + repository.addBinaryOperator<language::xor_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::xor_op, bool, bool, bool>>()); +} + +void +BinaryOperatorRegisterForB::_register_plus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + repository.addBinaryOperator<language::plus_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::plus_op, uint64_t, bool, bool>>()); +} + +void +BinaryOperatorRegisterForB::_register_minus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + repository.addBinaryOperator<language::minus_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, int64_t, bool, bool>>()); +} + +void +BinaryOperatorRegisterForB::_register_multiply() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + repository.addBinaryOperator<language::multiply_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, uint64_t, bool, bool>>()); +} + +void +BinaryOperatorRegisterForB::_register_divide() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + repository.addBinaryOperator<language::divide_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::divide_op, uint64_t, bool, bool>>()); +} + +BinaryOperatorRegisterForB::BinaryOperatorRegisterForB() +{ + this->_register_comparisons(); + this->_register_logical_operators(); + this->_register_plus(); + this->_register_minus(); + this->_register_multiply(); + this->_register_divide(); +} diff --git a/src/language/utils/BinaryOperatorRegisterForB.hpp b/src/language/utils/BinaryOperatorRegisterForB.hpp new file mode 100644 index 0000000000000000000000000000000000000000..651411bf7f2cd8e8386d26c071220d36cb79a691 --- /dev/null +++ b/src/language/utils/BinaryOperatorRegisterForB.hpp @@ -0,0 +1,18 @@ +#ifndef BINARY_OPERATOR_REGISTER_FOR_B_HPP +#define BINARY_OPERATOR_REGISTER_FOR_B_HPP + +class BinaryOperatorRegisterForB +{ + private: + void _register_comparisons(); + void _register_logical_operators(); + void _register_plus(); + void _register_minus(); + void _register_multiply(); + void _register_divide(); + + public: + BinaryOperatorRegisterForB(); +}; + +#endif // BINARY_OPERATOR_REGISTER_FOR_B_HPP diff --git a/src/language/utils/BinaryOperatorRegisterForN.cpp b/src/language/utils/BinaryOperatorRegisterForN.cpp new file mode 100644 index 0000000000000000000000000000000000000000..66d589405545924af9e2de137f7738c9b40b8430 --- /dev/null +++ b/src/language/utils/BinaryOperatorRegisterForN.cpp @@ -0,0 +1,50 @@ +#include <language/utils/BinaryOperatorRegisterForN.hpp> + +#include <language/utils/BasicBinaryOperatorRegisterComparisonOf.hpp> + +void +BinaryOperatorRegisterForN::_register_comparisons() +{ + BasicBinaryOperatorRegisterComparisonOf<bool, uint64_t>{}; + BasicBinaryOperatorRegisterComparisonOf<uint64_t, bool>{}; + + BasicBinaryOperatorRegisterComparisonOf<uint64_t, uint64_t>{}; +} + +template <typename OperatorT> +void +BinaryOperatorRegisterForN::_register_arithmetic() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, uint64_t, uint64_t, bool>>()); + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, uint64_t, bool, uint64_t>>()); + + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, uint64_t, uint64_t, uint64_t>>()); +} + +void +BinaryOperatorRegisterForN::_register_minus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + repository.addBinaryOperator<language::minus_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, int64_t, uint64_t, bool>>()); + repository.addBinaryOperator<language::minus_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, int64_t, bool, uint64_t>>()); + + repository.addBinaryOperator<language::minus_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::minus_op, int64_t, uint64_t, uint64_t>>()); +} + +BinaryOperatorRegisterForN::BinaryOperatorRegisterForN() +{ + this->_register_comparisons(); + this->_register_arithmetic<language::plus_op>(); + this->_register_minus(); + this->_register_arithmetic<language::multiply_op>(); + this->_register_arithmetic<language::divide_op>(); +} diff --git a/src/language/utils/BinaryOperatorRegisterForN.hpp b/src/language/utils/BinaryOperatorRegisterForN.hpp new file mode 100644 index 0000000000000000000000000000000000000000..80dc52b013f36e05e08f7bf561f2ac3b41ccbfbf --- /dev/null +++ b/src/language/utils/BinaryOperatorRegisterForN.hpp @@ -0,0 +1,16 @@ +#ifndef BINARY_OPERATOR_REGISTER_FOR_N_HPP +#define BINARY_OPERATOR_REGISTER_FOR_N_HPP + +class BinaryOperatorRegisterForN +{ + private: + template <typename OperatorT> + void _register_arithmetic(); + void _register_comparisons(); + void _register_minus(); + + public: + BinaryOperatorRegisterForN(); +}; + +#endif // BINARY_OPERATOR_REGISTER_FOR_N_HPP diff --git a/src/language/utils/BinaryOperatorRegisterForR.cpp b/src/language/utils/BinaryOperatorRegisterForR.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f69988925e373fbd7369bff3d0bb87860b1aa3d --- /dev/null +++ b/src/language/utils/BinaryOperatorRegisterForR.cpp @@ -0,0 +1,52 @@ +#include <language/utils/BinaryOperatorRegisterForR.hpp> + +#include <language/utils/BasicBinaryOperatorRegisterComparisonOf.hpp> + +void +BinaryOperatorRegisterForR::_register_comparisons() +{ + BasicBinaryOperatorRegisterComparisonOf<bool, double>{}; + BasicBinaryOperatorRegisterComparisonOf<double, bool>{}; + + BasicBinaryOperatorRegisterComparisonOf<uint64_t, double>{}; + BasicBinaryOperatorRegisterComparisonOf<double, uint64_t>{}; + + BasicBinaryOperatorRegisterComparisonOf<int64_t, double>{}; + BasicBinaryOperatorRegisterComparisonOf<double, int64_t>{}; + + BasicBinaryOperatorRegisterComparisonOf<double, double>{}; +} + +template <typename OperatorT> +void +BinaryOperatorRegisterForR::_register_arithmetic() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, double, double, bool>>()); + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, double, bool, double>>()); + + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, double, double, uint64_t>>()); + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, double, uint64_t, double_t>>()); + + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, double, double, int64_t>>()); + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, double, int64_t, double_t>>()); + + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, double, double, double>>()); +} + +BinaryOperatorRegisterForR::BinaryOperatorRegisterForR() +{ + this->_register_comparisons(); + this->_register_arithmetic<language::plus_op>(); + this->_register_arithmetic<language::minus_op>(); + this->_register_arithmetic<language::multiply_op>(); + this->_register_arithmetic<language::divide_op>(); +} diff --git a/src/language/utils/BinaryOperatorRegisterForR.hpp b/src/language/utils/BinaryOperatorRegisterForR.hpp new file mode 100644 index 0000000000000000000000000000000000000000..cbde82fb3d36e565ef84d99b95b58c6c0556eb01 --- /dev/null +++ b/src/language/utils/BinaryOperatorRegisterForR.hpp @@ -0,0 +1,15 @@ +#ifndef BINARY_OPERATOR_REGISTER_FOR_R_HPP +#define BINARY_OPERATOR_REGISTER_FOR_R_HPP + +class BinaryOperatorRegisterForR +{ + private: + template <typename OperatorT> + void _register_arithmetic(); + void _register_comparisons(); + + public: + BinaryOperatorRegisterForR(); +}; + +#endif // BINARY_OPERATOR_REGISTER_FOR_R_HPP diff --git a/src/language/utils/BinaryOperatorRegisterForRn.cpp b/src/language/utils/BinaryOperatorRegisterForRn.cpp new file mode 100644 index 0000000000000000000000000000000000000000..41e5b031f7e3db02d8e59a9962e028c046f813a8 --- /dev/null +++ b/src/language/utils/BinaryOperatorRegisterForRn.cpp @@ -0,0 +1,67 @@ +#include <language/utils/BinaryOperatorRegisterForRn.hpp> + +#include <language/utils/BinaryOperatorProcessorBuilder.hpp> +#include <language/utils/OperatorRepository.hpp> + +template <size_t Dimension> +void +BinaryOperatorRegisterForRn<Dimension>::_register_comparisons() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + using Rn = TinyVector<Dimension>; + + repository.addBinaryOperator<language::eqeq_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::eqeq_op, bool, Rn, Rn>>()); + + repository.addBinaryOperator<language::not_eq_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::not_eq_op, bool, Rn, Rn>>()); +} + +template <size_t Dimension> +void +BinaryOperatorRegisterForRn<Dimension>::_register_product_by_a_scalar() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + using Rn = TinyVector<Dimension>; + + repository.addBinaryOperator<language::multiply_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, Rn, bool, Rn>>()); + + repository.addBinaryOperator<language::multiply_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, Rn, uint64_t, Rn>>()); + + repository.addBinaryOperator<language::multiply_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, Rn, int64_t, Rn>>()); + + repository.addBinaryOperator<language::multiply_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::multiply_op, Rn, double, Rn>>()); +} + +template <size_t Dimension> +template <typename OperatorT> +void +BinaryOperatorRegisterForRn<Dimension>::_register_arithmetic() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + using Rn = TinyVector<Dimension>; + + repository.addBinaryOperator<OperatorT>(std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, Rn, Rn, Rn>>()); +} + +template <size_t Dimension> +BinaryOperatorRegisterForRn<Dimension>::BinaryOperatorRegisterForRn() +{ + this->_register_comparisons(); + + this->_register_product_by_a_scalar(); + + this->_register_arithmetic<language::plus_op>(); + this->_register_arithmetic<language::minus_op>(); +} + +template class BinaryOperatorRegisterForRn<1>; +template class BinaryOperatorRegisterForRn<2>; +template class BinaryOperatorRegisterForRn<3>; diff --git a/src/language/utils/BinaryOperatorRegisterForRn.hpp b/src/language/utils/BinaryOperatorRegisterForRn.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b9f27d4165d236b913e3393e342a144019fe6015 --- /dev/null +++ b/src/language/utils/BinaryOperatorRegisterForRn.hpp @@ -0,0 +1,21 @@ +#ifndef BINARY_OPERATOR_REGISTER_FOR_RN_HPP +#define BINARY_OPERATOR_REGISTER_FOR_RN_HPP + +#include <cstdlib> + +template <size_t Dimension> +class BinaryOperatorRegisterForRn +{ + private: + void _register_comparisons(); + + void _register_product_by_a_scalar(); + + template <typename OperatorT> + void _register_arithmetic(); + + public: + BinaryOperatorRegisterForRn(); +}; + +#endif // BINARY_OPERATOR_REGISTER_FOR_RN_HPP diff --git a/src/language/utils/BinaryOperatorRegisterForString.cpp b/src/language/utils/BinaryOperatorRegisterForString.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1323e21ea0cd17cca712a286c6cf4192447e88e4 --- /dev/null +++ b/src/language/utils/BinaryOperatorRegisterForString.cpp @@ -0,0 +1,40 @@ +#include <language/utils/BinaryOperatorRegisterForString.hpp> + +#include <language/utils/BinaryOperatorProcessorBuilder.hpp> +#include <language/utils/ConcatExpressionProcessorBuilder.hpp> +#include <language/utils/OperatorRepository.hpp> + +void +BinaryOperatorRegisterForString::_register_comparisons() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + repository.addBinaryOperator<language::eqeq_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::eqeq_op, bool, std::string, std::string>>()); + + repository.addBinaryOperator<language::not_eq_op>( + std::make_shared<BinaryOperatorProcessorBuilder<language::not_eq_op, bool, std::string, std::string>>()); +} + +template <typename RHS_T> +void +BinaryOperatorRegisterForString::_register_concat() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + repository.addBinaryOperator<language::plus_op>(std::make_shared<ConcatExpressionProcessorBuilder<RHS_T>>()); +} + +BinaryOperatorRegisterForString::BinaryOperatorRegisterForString() +{ + this->_register_comparisons(); + + this->_register_concat<bool>(); + this->_register_concat<unsigned long>(); + this->_register_concat<long>(); + this->_register_concat<double>(); + this->_register_concat<TinyVector<1>>(); + this->_register_concat<TinyVector<2>>(); + this->_register_concat<TinyVector<3>>(); + this->_register_concat<std::string>(); +} diff --git a/src/language/utils/BinaryOperatorRegisterForString.hpp b/src/language/utils/BinaryOperatorRegisterForString.hpp new file mode 100644 index 0000000000000000000000000000000000000000..36af13ee6442086244ee5234ad496f3580f79c22 --- /dev/null +++ b/src/language/utils/BinaryOperatorRegisterForString.hpp @@ -0,0 +1,16 @@ +#ifndef BINARY_OPERATOR_REGISTER_FOR_STRING_HPP +#define BINARY_OPERATOR_REGISTER_FOR_STRING_HPP + +class BinaryOperatorRegisterForString +{ + private: + void _register_comparisons(); + + template <typename RHS_T> + void _register_concat(); + + public: + BinaryOperatorRegisterForString(); +}; + +#endif // BINARY_OPERATOR_REGISTER_FOR_STRING_HPP diff --git a/src/language/utils/BinaryOperatorRegisterForZ.cpp b/src/language/utils/BinaryOperatorRegisterForZ.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cc8b22d117a8bebc557efff84083b8e45dcf8602 --- /dev/null +++ b/src/language/utils/BinaryOperatorRegisterForZ.cpp @@ -0,0 +1,44 @@ +#include <language/utils/BinaryOperatorRegisterForZ.hpp> + +#include <language/utils/BasicBinaryOperatorRegisterComparisonOf.hpp> + +void +BinaryOperatorRegisterForZ::_register_comparisons() +{ + BasicBinaryOperatorRegisterComparisonOf<bool, int64_t>{}; + BasicBinaryOperatorRegisterComparisonOf<int64_t, bool>{}; + + BasicBinaryOperatorRegisterComparisonOf<uint64_t, int64_t>{}; + BasicBinaryOperatorRegisterComparisonOf<int64_t, uint64_t>{}; + + BasicBinaryOperatorRegisterComparisonOf<int64_t, int64_t>{}; +} + +template <typename OperatorT> +void +BinaryOperatorRegisterForZ::_register_arithmetic() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, int64_t, int64_t, bool>>()); + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, int64_t, bool, int64_t>>()); + + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, int64_t, int64_t, uint64_t>>()); + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, int64_t, uint64_t, int64_t>>()); + + repository.addBinaryOperator<OperatorT>( + std::make_shared<BinaryOperatorProcessorBuilder<OperatorT, int64_t, int64_t, int64_t>>()); +} + +BinaryOperatorRegisterForZ::BinaryOperatorRegisterForZ() +{ + this->_register_comparisons(); + this->_register_arithmetic<language::plus_op>(); + this->_register_arithmetic<language::minus_op>(); + this->_register_arithmetic<language::multiply_op>(); + this->_register_arithmetic<language::divide_op>(); +} diff --git a/src/language/utils/BinaryOperatorRegisterForZ.hpp b/src/language/utils/BinaryOperatorRegisterForZ.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3f9a7c30c2f8e3674e6ebda7e9069153a6162f13 --- /dev/null +++ b/src/language/utils/BinaryOperatorRegisterForZ.hpp @@ -0,0 +1,15 @@ +#ifndef BINARY_OPERATOR_REGISTER_FOR_Z_HPP +#define BINARY_OPERATOR_REGISTER_FOR_Z_HPP + +class BinaryOperatorRegisterForZ +{ + private: + template <typename OperatorT> + void _register_arithmetic(); + void _register_comparisons(); + + public: + BinaryOperatorRegisterForZ(); +}; + +#endif // BINARY_OPERATOR_REGISTER_FOR_Z_HPP diff --git a/src/language/utils/BuiltinFunctionEmbedder.hpp b/src/language/utils/BuiltinFunctionEmbedder.hpp index d394aa20f9721a1dc12821960890d0c1f0b6db1c..afb991acadcb36236bcd55a34c7840ca399ab6f0 100644 --- a/src/language/utils/BuiltinFunctionEmbedder.hpp +++ b/src/language/utils/BuiltinFunctionEmbedder.hpp @@ -1,7 +1,7 @@ #ifndef BUILTIN_FUNCTION_EMBEDDER_HPP #define BUILTIN_FUNCTION_EMBEDDER_HPP -#include <language/ast/ASTNodeDataType.hpp> +#include <language/utils/ASTNodeDataType.hpp> #include <language/utils/ASTNodeDataTypeTraits.hpp> #include <language/utils/DataHandler.hpp> #include <language/utils/DataVariant.hpp> diff --git a/src/language/utils/CMakeLists.txt b/src/language/utils/CMakeLists.txt index 1cb991d6c6d19a18579d3c0802a6ea032891d5c2..ed105ca479f5b17c3366d44320505dba5d2eacad 100644 --- a/src/language/utils/CMakeLists.txt +++ b/src/language/utils/CMakeLists.txt @@ -1,11 +1,33 @@ # ------------------- Source files -------------------- add_library(PugsLanguageUtils + AffectationRegisterForB.cpp + AffectationRegisterForN.cpp + AffectationRegisterForR.cpp + AffectationRegisterForRn.cpp + AffectationRegisterForString.cpp + AffectationRegisterForZ.cpp ASTDotPrinter.cpp ASTExecutionInfo.cpp + ASTNodeDataType.cpp ASTPrinter.cpp + BinaryOperatorRegisterForB.cpp + BinaryOperatorRegisterForN.cpp + BinaryOperatorRegisterForR.cpp + BinaryOperatorRegisterForRn.cpp + BinaryOperatorRegisterForString.cpp + BinaryOperatorRegisterForZ.cpp DataVariant.cpp EmbeddedData.cpp + IncDecOperatorRegisterForN.cpp + IncDecOperatorRegisterForR.cpp + IncDecOperatorRegisterForZ.cpp + OperatorRepository.cpp + UnaryOperatorRegisterForB.cpp + UnaryOperatorRegisterForN.cpp + UnaryOperatorRegisterForR.cpp + UnaryOperatorRegisterForRn.cpp + UnaryOperatorRegisterForZ.cpp ) diff --git a/src/language/utils/ConcatExpressionProcessorBuilder.hpp b/src/language/utils/ConcatExpressionProcessorBuilder.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8fed359622883368f8bdc3cbdfbebf524e314c50 --- /dev/null +++ b/src/language/utils/ConcatExpressionProcessorBuilder.hpp @@ -0,0 +1,42 @@ +#ifndef CONCAT_EXPRESSION_PROCESSOR_BUILDER_HPP +#define CONCAT_EXPRESSION_PROCESSOR_BUILDER_HPP + +#include <language/PEGGrammar.hpp> +#include <language/node_processor/ConcatExpressionProcessor.hpp> +#include <language/utils/ASTNodeDataTypeTraits.hpp> +#include <language/utils/IBinaryOperatorProcessorBuilder.hpp> + +#include <type_traits> + +template <typename B_DataT> +class ConcatExpressionProcessorBuilder final : public IBinaryOperatorProcessorBuilder +{ + public: + ConcatExpressionProcessorBuilder() = default; + + ASTNodeDataType + getDataTypeOfA() const + { + return ast_node_data_type_from<std::string>; + } + + ASTNodeDataType + getDataTypeOfB() const + { + return ast_node_data_type_from<B_DataT>; + } + + ASTNodeDataType + getReturnValueType() const + { + return ast_node_data_type_from<std::string>; + } + + std::unique_ptr<INodeProcessor> + getNodeProcessor(ASTNode& node) const + { + return std::make_unique<ConcatExpressionProcessor<B_DataT>>(node); + } +}; + +#endif // CONCAT_EXPRESSION_PROCESSOR_BUILDER_HPP diff --git a/src/language/utils/FunctionTable.hpp b/src/language/utils/FunctionTable.hpp index 43232fd60e4482a73dca1a4b257c7a6c0b6ef28a..6c6450c22ff8ff845ddd0c90dbcead1eec52203c 100644 --- a/src/language/utils/FunctionTable.hpp +++ b/src/language/utils/FunctionTable.hpp @@ -2,7 +2,7 @@ #define FUNCTION_TABLE_HPP #include <language/ast/ASTNode.hpp> -#include <language/ast/ASTNodeDataType.hpp> +#include <language/utils/ASTNodeDataType.hpp> #include <language/utils/DataVariant.hpp> #include <utils/PugsAssert.hpp> @@ -63,14 +63,16 @@ class FunctionTable } PUGS_INLINE - FunctionDescriptor& operator[](size_t function_id) + FunctionDescriptor& + operator[](size_t function_id) { Assert(function_id < m_function_descriptor_list.size()); return m_function_descriptor_list[function_id]; } PUGS_INLINE - const FunctionDescriptor& operator[](size_t function_id) const + const FunctionDescriptor& + operator[](size_t function_id) const { Assert(function_id < m_function_descriptor_list.size()); return m_function_descriptor_list[function_id]; diff --git a/src/language/utils/IAffectationProcessorBuilder.hpp b/src/language/utils/IAffectationProcessorBuilder.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6d5f8540df9435bba4b86e6bee22f980b5727d7b --- /dev/null +++ b/src/language/utils/IAffectationProcessorBuilder.hpp @@ -0,0 +1,17 @@ +#ifndef I_AFFECTATION_PROCESSOR_BUILDER_HPP +#define I_AFFECTATION_PROCESSOR_BUILDER_HPP + +class ASTNode; +class INodeProcessor; + +#include <memory> + +class IAffectationProcessorBuilder +{ + public: + virtual std::unique_ptr<INodeProcessor> getNodeProcessor(ASTNode& node) const = 0; + + virtual ~IAffectationProcessorBuilder() = default; +}; + +#endif // I_AFFECTATION_PROCESSOR_BUILDER_HPP diff --git a/src/language/utils/IBinaryOperatorProcessorBuilder.hpp b/src/language/utils/IBinaryOperatorProcessorBuilder.hpp new file mode 100644 index 0000000000000000000000000000000000000000..46a3a23010ed6e8bd0d6373f80f53d8bfd45e8c7 --- /dev/null +++ b/src/language/utils/IBinaryOperatorProcessorBuilder.hpp @@ -0,0 +1,23 @@ +#ifndef I_BINARY_OPERATOR_PROCESSOR_BUILDER_HPP +#define I_BINARY_OPERATOR_PROCESSOR_BUILDER_HPP + +class ASTNode; +class INodeProcessor; + +#include <language/utils/ASTNodeDataType.hpp> + +#include <memory> + +class IBinaryOperatorProcessorBuilder +{ + public: + [[nodiscard]] virtual std::unique_ptr<INodeProcessor> getNodeProcessor(ASTNode& node) const = 0; + + [[nodiscard]] virtual ASTNodeDataType getReturnValueType() const = 0; + [[nodiscard]] virtual ASTNodeDataType getDataTypeOfA() const = 0; + [[nodiscard]] virtual ASTNodeDataType getDataTypeOfB() const = 0; + + virtual ~IBinaryOperatorProcessorBuilder() = default; +}; + +#endif // I_BINARY_OPERATOR_PROCESSOR_BUILDER_HPP diff --git a/src/language/utils/IIncDecOperatorProcessorBuilder.hpp b/src/language/utils/IIncDecOperatorProcessorBuilder.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b84974a332326afa293757576efd6e2bdf40795e --- /dev/null +++ b/src/language/utils/IIncDecOperatorProcessorBuilder.hpp @@ -0,0 +1,20 @@ +#ifndef I_INC_DEC_OPERATOR_PROCESSOR_BUILDER_HPP +#define I_INC_DEC_OPERATOR_PROCESSOR_BUILDER_HPP + +class ASTNode; +class INodeProcessor; +#include <language/utils/ASTNodeDataType.hpp> + +#include <memory> + +class IIncDecOperatorProcessorBuilder +{ + public: + [[nodiscard]] virtual std::unique_ptr<INodeProcessor> getNodeProcessor(ASTNode& node) const = 0; + + [[nodiscard]] virtual ASTNodeDataType getReturnValueType() const = 0; + + virtual ~IIncDecOperatorProcessorBuilder() = default; +}; + +#endif // I_INC_DEC_OPERATOR_PROCESSOR_BUILDER_HPP diff --git a/src/language/utils/IUnaryOperatorProcessorBuilder.hpp b/src/language/utils/IUnaryOperatorProcessorBuilder.hpp new file mode 100644 index 0000000000000000000000000000000000000000..19b36e2feb42b9efc558ff5e554532c0f3d32824 --- /dev/null +++ b/src/language/utils/IUnaryOperatorProcessorBuilder.hpp @@ -0,0 +1,21 @@ +#ifndef I_UNARY_OPERATOR_PROCESSOR_BUILDER_HPP +#define I_UNARY_OPERATOR_PROCESSOR_BUILDER_HPP + +class ASTNode; +class INodeProcessor; + +#include <language/utils/ASTNodeDataType.hpp> + +#include <memory> + +class IUnaryOperatorProcessorBuilder +{ + public: + [[nodiscard]] virtual std::unique_ptr<INodeProcessor> getNodeProcessor(ASTNode& node) const = 0; + + [[nodiscard]] virtual ASTNodeDataType getReturnValueType() const = 0; + + virtual ~IUnaryOperatorProcessorBuilder() = default; +}; + +#endif // I_UNARY_OPERATOR_PROCESSOR_BUILDER_HPP diff --git a/src/language/utils/IncDecOperatorMangler.hpp b/src/language/utils/IncDecOperatorMangler.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ed5a84ae44c327116dbddef71880bd7b601fd97f --- /dev/null +++ b/src/language/utils/IncDecOperatorMangler.hpp @@ -0,0 +1,34 @@ +#ifndef INC_DEC_OPERATOR_MANGLER_HPP +#define INC_DEC_OPERATOR_MANGLER_HPP + +#include <language/utils/ASTNodeDataType.hpp> +#include <utils/Exceptions.hpp> + +#include <string> + +namespace language +{ +struct unary_minusminus; +struct unary_plusplus; +struct post_minusminus; +struct post_plusplus; +} // namespace language + +template <typename IncDecOperatorT> +std::string +incDecOperatorMangler(const ASTNodeDataType& operand) +{ + if constexpr (std::is_same_v<language::unary_minusminus, IncDecOperatorT>) { + return std::string{"-- "} + dataTypeName(operand); + } else if constexpr (std::is_same_v<language::post_minusminus, IncDecOperatorT>) { + return dataTypeName(operand) + " --"; + } else if constexpr (std::is_same_v<language::unary_plusplus, IncDecOperatorT>) { + return std::string{"++ "} + dataTypeName(operand); + } else if constexpr (std::is_same_v<language::post_plusplus, IncDecOperatorT>) { + return dataTypeName(operand) + " ++"; + } else { + static_assert(std::is_same_v<language::unary_minusminus, IncDecOperatorT>, "undefined inc/dec operator"); + } +} + +#endif // INC_DEC_OPERATOR_MANGLER_HPP diff --git a/src/language/utils/IncDecOperatorProcessorBuilder.hpp b/src/language/utils/IncDecOperatorProcessorBuilder.hpp new file mode 100644 index 0000000000000000000000000000000000000000..40da865ddf9c6ed480a859e9a158d21cb5562848 --- /dev/null +++ b/src/language/utils/IncDecOperatorProcessorBuilder.hpp @@ -0,0 +1,31 @@ +#ifndef INC_DEC_OPERATOR_PROCESSOR_BUILDER_HPP +#define INC_DEC_OPERATOR_PROCESSOR_BUILDER_HPP + +#include <algebra/TinyVector.hpp> +#include <language/PEGGrammar.hpp> +#include <language/node_processor/IncDecExpressionProcessor.hpp> +#include <language/utils/ASTNodeDataTypeTraits.hpp> +#include <language/utils/IIncDecOperatorProcessorBuilder.hpp> + +#include <type_traits> + +template <typename OperatorT, typename DataT> +class IncDecOperatorProcessorBuilder final : public IIncDecOperatorProcessorBuilder +{ + public: + IncDecOperatorProcessorBuilder() = default; + + ASTNodeDataType + getReturnValueType() const + { + return ast_node_data_type_from<DataT>; + } + + std::unique_ptr<INodeProcessor> + getNodeProcessor(ASTNode& node) const + { + return std::make_unique<IncDecExpressionProcessor<OperatorT, DataT>>(node); + } +}; + +#endif // INC_DEC_OPERATOR_PROCESSOR_BUILDER_HPP diff --git a/src/language/utils/IncDecOperatorRegisterForN.cpp b/src/language/utils/IncDecOperatorRegisterForN.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8e6a6369fcef13242abde08ffb59e75778b4793a --- /dev/null +++ b/src/language/utils/IncDecOperatorRegisterForN.cpp @@ -0,0 +1,58 @@ +#include <language/utils/IncDecOperatorRegisterForN.hpp> + +#include <language/utils/IncDecOperatorProcessorBuilder.hpp> +#include <language/utils/OperatorRepository.hpp> + +void +IncDecOperatorRegisterForN::_register_unary_minusminus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto N = ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(); + + repository.addIncDecOperator<language::unary_minusminus>(N, std::make_shared<IncDecOperatorProcessorBuilder< + language::unary_minusminus, uint64_t>>()); +} + +void +IncDecOperatorRegisterForN::_register_unary_plusplus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto N = ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(); + + repository.addIncDecOperator< + language::unary_plusplus>(N, + std::make_shared<IncDecOperatorProcessorBuilder<language::unary_plusplus, uint64_t>>()); +} + +void +IncDecOperatorRegisterForN::_register_post_minusminus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto N = ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(); + + repository.addIncDecOperator< + language::post_minusminus>(N, + std::make_shared<IncDecOperatorProcessorBuilder<language::post_minusminus, uint64_t>>()); +} + +void +IncDecOperatorRegisterForN::_register_post_plusplus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto N = ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(); + + repository.addIncDecOperator< + language::post_plusplus>(N, std::make_shared<IncDecOperatorProcessorBuilder<language::post_plusplus, uint64_t>>()); +} + +IncDecOperatorRegisterForN::IncDecOperatorRegisterForN() +{ + this->_register_unary_minusminus(); + this->_register_unary_plusplus(); + this->_register_post_minusminus(); + this->_register_post_plusplus(); +} diff --git a/src/language/utils/IncDecOperatorRegisterForN.hpp b/src/language/utils/IncDecOperatorRegisterForN.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c3e2682d8a0fb0122f813ec633bb08a37e997922 --- /dev/null +++ b/src/language/utils/IncDecOperatorRegisterForN.hpp @@ -0,0 +1,16 @@ +#ifndef INC_DEC_OPERATOR_REGISTER_FOR_N_HPP +#define INC_DEC_OPERATOR_REGISTER_FOR_N_HPP + +class IncDecOperatorRegisterForN +{ + private: + void _register_unary_minusminus(); + void _register_unary_plusplus(); + void _register_post_minusminus(); + void _register_post_plusplus(); + + public: + IncDecOperatorRegisterForN(); +}; + +#endif // INC_DEC_OPERATOR_REGISTER_FOR_N_HPP diff --git a/src/language/utils/IncDecOperatorRegisterForR.cpp b/src/language/utils/IncDecOperatorRegisterForR.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5031751468f6593d5eab1839cdf1f778c56837e7 --- /dev/null +++ b/src/language/utils/IncDecOperatorRegisterForR.cpp @@ -0,0 +1,58 @@ +#include <language/utils/IncDecOperatorRegisterForR.hpp> + +#include <language/utils/IncDecOperatorProcessorBuilder.hpp> +#include <language/utils/OperatorRepository.hpp> + +void +IncDecOperatorRegisterForR::_register_unary_minusminus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto R = ASTNodeDataType::build<ASTNodeDataType::double_t>(); + + repository.addIncDecOperator<language::unary_minusminus>(R, std::make_shared<IncDecOperatorProcessorBuilder< + language::unary_minusminus, double_t>>()); +} + +void +IncDecOperatorRegisterForR::_register_unary_plusplus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto R = ASTNodeDataType::build<ASTNodeDataType::double_t>(); + + repository.addIncDecOperator< + language::unary_plusplus>(R, + std::make_shared<IncDecOperatorProcessorBuilder<language::unary_plusplus, double_t>>()); +} + +void +IncDecOperatorRegisterForR::_register_post_minusminus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto R = ASTNodeDataType::build<ASTNodeDataType::double_t>(); + + repository.addIncDecOperator< + language::post_minusminus>(R, + std::make_shared<IncDecOperatorProcessorBuilder<language::post_minusminus, double_t>>()); +} + +void +IncDecOperatorRegisterForR::_register_post_plusplus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto R = ASTNodeDataType::build<ASTNodeDataType::double_t>(); + + repository.addIncDecOperator< + language::post_plusplus>(R, std::make_shared<IncDecOperatorProcessorBuilder<language::post_plusplus, double_t>>()); +} + +IncDecOperatorRegisterForR::IncDecOperatorRegisterForR() +{ + this->_register_unary_minusminus(); + this->_register_unary_plusplus(); + this->_register_post_minusminus(); + this->_register_post_plusplus(); +} diff --git a/src/language/utils/IncDecOperatorRegisterForR.hpp b/src/language/utils/IncDecOperatorRegisterForR.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5ede6b9999347788f9447d7b5eeb9fe28b8e4da7 --- /dev/null +++ b/src/language/utils/IncDecOperatorRegisterForR.hpp @@ -0,0 +1,16 @@ +#ifndef INC_DEC_OPERATOR_REGISTER_FOR_R_HPP +#define INC_DEC_OPERATOR_REGISTER_FOR_R_HPP + +class IncDecOperatorRegisterForR +{ + private: + void _register_unary_minusminus(); + void _register_unary_plusplus(); + void _register_post_minusminus(); + void _register_post_plusplus(); + + public: + IncDecOperatorRegisterForR(); +}; + +#endif // INC_DEC_OPERATOR_REGISTER_FOR_Z_HPP diff --git a/src/language/utils/IncDecOperatorRegisterForZ.cpp b/src/language/utils/IncDecOperatorRegisterForZ.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5a0bc0faa8bcf3ef0bcbed4837c44f5c9f147aa3 --- /dev/null +++ b/src/language/utils/IncDecOperatorRegisterForZ.cpp @@ -0,0 +1,57 @@ +#include <language/utils/IncDecOperatorRegisterForZ.hpp> + +#include <language/utils/IncDecOperatorProcessorBuilder.hpp> +#include <language/utils/OperatorRepository.hpp> + +void +IncDecOperatorRegisterForZ::_register_unary_minusminus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto Z = ASTNodeDataType::build<ASTNodeDataType::int_t>(); + + repository.addIncDecOperator<language::unary_minusminus>(Z, std::make_shared<IncDecOperatorProcessorBuilder< + language::unary_minusminus, int64_t>>()); +} + +void +IncDecOperatorRegisterForZ::_register_unary_plusplus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto Z = ASTNodeDataType::build<ASTNodeDataType::int_t>(); + + repository.addIncDecOperator< + language::unary_plusplus>(Z, std::make_shared<IncDecOperatorProcessorBuilder<language::unary_plusplus, int64_t>>()); +} + +void +IncDecOperatorRegisterForZ::_register_post_minusminus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto N = ASTNodeDataType::build<ASTNodeDataType::int_t>(); + + repository.addIncDecOperator< + language::post_minusminus>(N, + std::make_shared<IncDecOperatorProcessorBuilder<language::post_minusminus, int64_t>>()); +} + +void +IncDecOperatorRegisterForZ::_register_post_plusplus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto Z = ASTNodeDataType::build<ASTNodeDataType::int_t>(); + + repository.addIncDecOperator< + language::post_plusplus>(Z, std::make_shared<IncDecOperatorProcessorBuilder<language::post_plusplus, int64_t>>()); +} + +IncDecOperatorRegisterForZ::IncDecOperatorRegisterForZ() +{ + this->_register_unary_minusminus(); + this->_register_unary_plusplus(); + this->_register_post_minusminus(); + this->_register_post_plusplus(); +} diff --git a/src/language/utils/IncDecOperatorRegisterForZ.hpp b/src/language/utils/IncDecOperatorRegisterForZ.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b4ab27770b5a144245a297751a48d0b00f8322ba --- /dev/null +++ b/src/language/utils/IncDecOperatorRegisterForZ.hpp @@ -0,0 +1,16 @@ +#ifndef INC_DEC_OPERATOR_REGISTER_FOR_Z_HPP +#define INC_DEC_OPERATOR_REGISTER_FOR_Z_HPP + +class IncDecOperatorRegisterForZ +{ + private: + void _register_unary_minusminus(); + void _register_unary_plusplus(); + void _register_post_minusminus(); + void _register_post_plusplus(); + + public: + IncDecOperatorRegisterForZ(); +}; + +#endif // INC_DEC_OPERATOR_REGISTER_FOR_Z_HPP diff --git a/src/language/utils/OperatorRepository.cpp b/src/language/utils/OperatorRepository.cpp new file mode 100644 index 0000000000000000000000000000000000000000..93856da8c33793cad9189a25285b612b550f8d61 --- /dev/null +++ b/src/language/utils/OperatorRepository.cpp @@ -0,0 +1,90 @@ +#include <language/utils/OperatorRepository.hpp> + +#include <language/utils/AffectationProcessorBuilder.hpp> +#include <language/utils/AffectationRegisterForB.hpp> +#include <language/utils/AffectationRegisterForN.hpp> +#include <language/utils/AffectationRegisterForR.hpp> +#include <language/utils/AffectationRegisterForRn.hpp> +#include <language/utils/AffectationRegisterForString.hpp> +#include <language/utils/AffectationRegisterForZ.hpp> + +#include <language/utils/BinaryOperatorRegisterForB.hpp> +#include <language/utils/BinaryOperatorRegisterForN.hpp> +#include <language/utils/BinaryOperatorRegisterForR.hpp> +#include <language/utils/BinaryOperatorRegisterForRn.hpp> +#include <language/utils/BinaryOperatorRegisterForString.hpp> +#include <language/utils/BinaryOperatorRegisterForZ.hpp> + +#include <language/utils/IncDecOperatorRegisterForN.hpp> +#include <language/utils/IncDecOperatorRegisterForR.hpp> +#include <language/utils/IncDecOperatorRegisterForZ.hpp> + +#include <language/utils/UnaryOperatorRegisterForB.hpp> +#include <language/utils/UnaryOperatorRegisterForN.hpp> +#include <language/utils/UnaryOperatorRegisterForR.hpp> +#include <language/utils/UnaryOperatorRegisterForRn.hpp> +#include <language/utils/UnaryOperatorRegisterForZ.hpp> + +#include <utils/PugsAssert.hpp> + +OperatorRepository* OperatorRepository::m_instance = nullptr; + +void +OperatorRepository::reset() +{ + m_affectation_builder_list.clear(); + m_binary_operator_builder_list.clear(); + m_inc_dec_operator_builder_list.clear(); + m_unary_operator_builder_list.clear(); + this->_initialize(); +} + +void +OperatorRepository::create() +{ + Assert(m_instance == nullptr, "AffectationRepository was already created"); + m_instance = new OperatorRepository; + m_instance->_initialize(); +} + +void +OperatorRepository::destroy() +{ + Assert(m_instance != nullptr, "AffectationRepository was not created"); + delete m_instance; + m_instance = nullptr; +} + +void +OperatorRepository::_initialize() +{ + AffectationRegisterForB{}; + AffectationRegisterForN{}; + AffectationRegisterForZ{}; + AffectationRegisterForR{}; + AffectationRegisterForRn<1>{}; + AffectationRegisterForRn<2>{}; + AffectationRegisterForRn<3>{}; + AffectationRegisterForString{}; + + BinaryOperatorRegisterForB{}; + BinaryOperatorRegisterForN{}; + BinaryOperatorRegisterForZ{}; + BinaryOperatorRegisterForR{}; + BinaryOperatorRegisterForRn<1>{}; + BinaryOperatorRegisterForRn<2>{}; + BinaryOperatorRegisterForRn<3>{}; + BinaryOperatorRegisterForString{}; + + IncDecOperatorRegisterForN{}; + IncDecOperatorRegisterForR{}; + IncDecOperatorRegisterForZ{}; + + UnaryOperatorRegisterForB{}; + UnaryOperatorRegisterForN{}; + UnaryOperatorRegisterForZ{}; + UnaryOperatorRegisterForR{}; + UnaryOperatorRegisterForRn<1>{}; + UnaryOperatorRegisterForRn<2>{}; + UnaryOperatorRegisterForRn<3>{}; +} diff --git a/src/language/utils/OperatorRepository.hpp b/src/language/utils/OperatorRepository.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6ac61e6e245f8f545e4794ffb4bd4703d4806b82 --- /dev/null +++ b/src/language/utils/OperatorRepository.hpp @@ -0,0 +1,224 @@ +#ifndef OPERATOR_REPOSITORY_HPP +#define OPERATOR_REPOSITORY_HPP + +#include <language/node_processor/INodeProcessor.hpp> +#include <language/utils/ASTNodeDataType.hpp> +#include <language/utils/AffectationMangler.hpp> +#include <language/utils/BinaryOperatorMangler.hpp> +#include <language/utils/IAffectationProcessorBuilder.hpp> +#include <language/utils/IBinaryOperatorProcessorBuilder.hpp> +#include <language/utils/IIncDecOperatorProcessorBuilder.hpp> +#include <language/utils/IUnaryOperatorProcessorBuilder.hpp> +#include <language/utils/IncDecOperatorMangler.hpp> +#include <language/utils/UnaryOperatorMangler.hpp> + +#include <utils/Exceptions.hpp> + +#include <optional> +#include <unordered_map> + +class OperatorRepository +{ + private: + template <typename ProcessorBuilderT> + class Descriptor + { + private: + ASTNodeDataType m_value_type; + std::shared_ptr<const ProcessorBuilderT> m_processor_builder; + + public: + const ASTNodeDataType& + valueType() const + { + return m_value_type; + } + + const std::shared_ptr<const ProcessorBuilderT>& + processorBuilder() const + { + return m_processor_builder; + } + + Descriptor(const ASTNodeDataType& value_type, const std::shared_ptr<const ProcessorBuilderT>& processor_builder) + : m_value_type{value_type}, m_processor_builder{processor_builder} + {} + + Descriptor(const Descriptor&) = default; + Descriptor(Descriptor&&) = default; + Descriptor() = default; + ~Descriptor() = default; + }; + + std::unordered_map<std::string, Descriptor<IAffectationProcessorBuilder>> m_affectation_builder_list; + + std::unordered_map<std::string, Descriptor<IIncDecOperatorProcessorBuilder>> m_inc_dec_operator_builder_list; + + std::unordered_map<std::string, Descriptor<IBinaryOperatorProcessorBuilder>> m_binary_operator_builder_list; + + std::unordered_map<std::string, Descriptor<IUnaryOperatorProcessorBuilder>> m_unary_operator_builder_list; + + void _initialize(); + + public: + void reset(); + + template <typename BinaryOperatorTypeT> + void + addBinaryOperator(const std::shared_ptr<const IBinaryOperatorProcessorBuilder>& processor_builder) + { + const std::string binary_operator_type_name = + binaryOperatorMangler<BinaryOperatorTypeT>(processor_builder->getDataTypeOfA(), + processor_builder->getDataTypeOfB()); + if (not m_binary_operator_builder_list + .try_emplace(binary_operator_type_name, + Descriptor{processor_builder->getReturnValueType(), processor_builder}) + .second) { + // LCOV_EXCL_START + throw UnexpectedError(binary_operator_type_name + " has already an entry"); + // LCOV_EXCL_STOP + } + } + + template <typename OperatorTypeT> + void + addAffectation(const ASTNodeDataType& lhs_type, + const ASTNodeDataType& rhs_type, + const std::shared_ptr<const IAffectationProcessorBuilder>& processor_builder) + { + const std::string affectation_type_name = affectationMangler<OperatorTypeT>(lhs_type, rhs_type); + if (not m_affectation_builder_list + .try_emplace(affectation_type_name, + Descriptor{ASTNodeDataType::build<ASTNodeDataType::void_t>(), processor_builder}) + .second) { + // LCOV_EXCL_START + throw UnexpectedError(affectation_type_name + " has already an entry"); + // LCOV_EXCL_STOP + } + } + + template <typename OperatorTypeT> + void + addIncDecOperator(const ASTNodeDataType& operand_type, + const std::shared_ptr<const IIncDecOperatorProcessorBuilder>& processor_builder) + { + const std::string inc_dec_operator_type_name = incDecOperatorMangler<OperatorTypeT>(operand_type); + if (auto [i_descriptor, success] = + m_inc_dec_operator_builder_list.try_emplace(inc_dec_operator_type_name, + Descriptor{processor_builder->getReturnValueType(), + processor_builder}); + not success) { + // LCOV_EXCL_START + throw UnexpectedError(inc_dec_operator_type_name + " has already an entry"); + // LCOV_EXCL_STOP + } + } + + template <typename OperatorTypeT> + void + addUnaryOperator(const ASTNodeDataType& operand_type, + const std::shared_ptr<const IUnaryOperatorProcessorBuilder>& processor_builder) + { + const std::string unary_operator_type_name = unaryOperatorMangler<OperatorTypeT>(operand_type); + if (auto [i_descriptor, success] = + m_unary_operator_builder_list.try_emplace(unary_operator_type_name, + Descriptor{processor_builder->getReturnValueType(), + processor_builder}); + not success) { + // LCOV_EXCL_START + throw UnexpectedError(unary_operator_type_name + " has already an entry"); + // LCOV_EXCL_STOP + } + } + + [[nodiscard]] std::optional<std::shared_ptr<const IAffectationProcessorBuilder>> + getAffectationProcessorBuilder(const std::string& name) const + { + auto&& processor_builder = m_affectation_builder_list.find(name); + if (processor_builder != m_affectation_builder_list.end()) { + return processor_builder->second.processorBuilder(); + } + return {}; + } + + [[nodiscard]] std::optional<std::shared_ptr<const IIncDecOperatorProcessorBuilder>> + getIncDecProcessorBuilder(const std::string& name) const + { + auto&& processor_builder = m_inc_dec_operator_builder_list.find(name); + if (processor_builder != m_inc_dec_operator_builder_list.end()) { + return processor_builder->second.processorBuilder(); + } + return {}; + } + + [[nodiscard]] std::optional<std::shared_ptr<const IBinaryOperatorProcessorBuilder>> + getBinaryProcessorBuilder(const std::string& name) const + { + auto&& processor_builder = m_binary_operator_builder_list.find(name); + if (processor_builder != m_binary_operator_builder_list.end()) { + return processor_builder->second.processorBuilder(); + } + return {}; + } + + [[nodiscard]] std::optional<std::shared_ptr<const IUnaryOperatorProcessorBuilder>> + getUnaryProcessorBuilder(const std::string& name) const + { + auto&& processor_builder = m_unary_operator_builder_list.find(name); + if (processor_builder != m_unary_operator_builder_list.end()) { + return processor_builder->second.processorBuilder(); + } + return {}; + } + + [[nodiscard]] std::optional<ASTNodeDataType> + getIncDecOperatorValueType(const std::string& name) const + { + auto&& processor_builder = m_inc_dec_operator_builder_list.find(name); + if (processor_builder != m_inc_dec_operator_builder_list.end()) { + return processor_builder->second.valueType(); + } + return {}; + } + + [[nodiscard]] std::optional<ASTNodeDataType> + getBinaryOperatorValueType(const std::string& name) const + { + auto&& processor_builder = m_binary_operator_builder_list.find(name); + if (processor_builder != m_binary_operator_builder_list.end()) { + return processor_builder->second.valueType(); + } + return {}; + } + + [[nodiscard]] std::optional<ASTNodeDataType> + getUnaryOperatorValueType(const std::string& name) const + { + auto&& processor_builder = m_unary_operator_builder_list.find(name); + if (processor_builder != m_unary_operator_builder_list.end()) { + return processor_builder->second.valueType(); + } + return {}; + } + + static void create(); + + PUGS_INLINE + static OperatorRepository& + instance() + { + Assert(m_instance != nullptr); + return *m_instance; + } + + static void destroy(); + + private: + static OperatorRepository* m_instance; + + OperatorRepository() = default; + + ~OperatorRepository() = default; +}; + +#endif // OPERATOR_REPOSITORY_HPP diff --git a/src/language/utils/PugsFunctionAdapter.hpp b/src/language/utils/PugsFunctionAdapter.hpp index 17d97f509c2466b97d3a8ee46cc34ca8ee6b06fe..278c7274ff702cfc5e97f7b6075b5487e440580b 100644 --- a/src/language/utils/PugsFunctionAdapter.hpp +++ b/src/language/utils/PugsFunctionAdapter.hpp @@ -2,8 +2,8 @@ #define PUGS_FUNCTION_ADAPTER_HPP #include <language/ast/ASTNode.hpp> -#include <language/ast/ASTNodeDataType.hpp> #include <language/node_processor/ExecutionPolicy.hpp> +#include <language/utils/ASTNodeDataType.hpp> #include <language/utils/ASTNodeDataTypeTraits.hpp> #include <language/utils/SymbolTable.hpp> #include <utils/Array.hpp> diff --git a/src/language/utils/SymbolTable.hpp b/src/language/utils/SymbolTable.hpp index 39d414b1e120255e9d51c17266512458fcc5f1b8..6aa089bd8de7aa5a3a6a6cf2a8115e77de25dbe8 100644 --- a/src/language/utils/SymbolTable.hpp +++ b/src/language/utils/SymbolTable.hpp @@ -1,7 +1,7 @@ #ifndef SYMBOL_TABLE_HPP #define SYMBOL_TABLE_HPP -#include <language/ast/ASTNodeDataType.hpp> +#include <language/utils/ASTNodeDataType.hpp> #include <language/utils/DataVariant.hpp> #include <language/utils/EmbedderTable.hpp> #include <language/utils/FunctionTable.hpp> diff --git a/src/language/utils/UnaryOperatorMangler.hpp b/src/language/utils/UnaryOperatorMangler.hpp new file mode 100644 index 0000000000000000000000000000000000000000..380eb6fa0c5e260340eb2ab463f3a7567c6a301a --- /dev/null +++ b/src/language/utils/UnaryOperatorMangler.hpp @@ -0,0 +1,32 @@ +#ifndef UNARY_OPERATOR_MANGLER_HPP +#define UNARY_OPERATOR_MANGLER_HPP + +#include <language/utils/ASTNodeDataType.hpp> +#include <utils/Exceptions.hpp> + +#include <string> + +namespace language +{ +struct unary_minus; +struct unary_not; +} // namespace language + +template <typename UnaryOperatorT> +std::string +unaryOperatorMangler(const ASTNodeDataType& operand) +{ + const std::string operator_name = [] { + if constexpr (std::is_same_v<language::unary_minus, UnaryOperatorT>) { + return "-"; + } else if constexpr (std::is_same_v<language::unary_not, UnaryOperatorT>) { + return "not"; + } else { + static_assert(std::is_same_v<language::unary_minus, UnaryOperatorT>, "undefined unary operator"); + } + }(); + + return operator_name + " " + dataTypeName(operand); +} + +#endif // UNARY_OPERATOR_MANGLER_HPP diff --git a/src/language/utils/UnaryOperatorProcessorBuilder.hpp b/src/language/utils/UnaryOperatorProcessorBuilder.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d99d2e17536de2b31a3ac2c48f39800a2461f17d --- /dev/null +++ b/src/language/utils/UnaryOperatorProcessorBuilder.hpp @@ -0,0 +1,31 @@ +#ifndef UNARY_OPERATOR_PROCESSOR_BUILDER_HPP +#define UNARY_OPERATOR_PROCESSOR_BUILDER_HPP + +#include <algebra/TinyVector.hpp> +#include <language/PEGGrammar.hpp> +#include <language/node_processor/UnaryExpressionProcessor.hpp> +#include <language/utils/ASTNodeDataTypeTraits.hpp> +#include <language/utils/IUnaryOperatorProcessorBuilder.hpp> + +#include <type_traits> + +template <typename OperatorT, typename ValueT, typename DataT> +class UnaryOperatorProcessorBuilder final : public IUnaryOperatorProcessorBuilder +{ + public: + UnaryOperatorProcessorBuilder() = default; + + ASTNodeDataType + getReturnValueType() const + { + return ast_node_data_type_from<ValueT>; + } + + std::unique_ptr<INodeProcessor> + getNodeProcessor(ASTNode& node) const + { + return std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, DataT>>(node); + } +}; + +#endif // UNARY_OPERATOR_PROCESSOR_BUILDER_HPP diff --git a/src/language/utils/UnaryOperatorRegisterForB.cpp b/src/language/utils/UnaryOperatorRegisterForB.cpp new file mode 100644 index 0000000000000000000000000000000000000000..33173e82b896e8d013f125a3b47ce42682ac132d --- /dev/null +++ b/src/language/utils/UnaryOperatorRegisterForB.cpp @@ -0,0 +1,32 @@ +#include <language/utils/UnaryOperatorRegisterForB.hpp> + +#include <language/utils/OperatorRepository.hpp> +#include <language/utils/UnaryOperatorProcessorBuilder.hpp> + +void +UnaryOperatorRegisterForB::_register_unary_minus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto B = ASTNodeDataType::build<ASTNodeDataType::bool_t>(); + + repository.addUnaryOperator< + language::unary_minus>(B, std::make_shared<UnaryOperatorProcessorBuilder<language::unary_minus, int64_t, bool>>()); +} + +void +UnaryOperatorRegisterForB::_register_unary_not() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto B = ASTNodeDataType::build<ASTNodeDataType::bool_t>(); + + repository.addUnaryOperator< + language::unary_not>(B, std::make_shared<UnaryOperatorProcessorBuilder<language::unary_not, bool, bool>>()); +} + +UnaryOperatorRegisterForB::UnaryOperatorRegisterForB() +{ + this->_register_unary_minus(); + this->_register_unary_not(); +} diff --git a/src/language/utils/UnaryOperatorRegisterForB.hpp b/src/language/utils/UnaryOperatorRegisterForB.hpp new file mode 100644 index 0000000000000000000000000000000000000000..49f1f8f4e8cf02dab86d1e0b8c7008d03a137546 --- /dev/null +++ b/src/language/utils/UnaryOperatorRegisterForB.hpp @@ -0,0 +1,14 @@ +#ifndef UNARY_OPERATOR_REGISTER_FOR_B_HPP +#define UNARY_OPERATOR_REGISTER_FOR_B_HPP + +class UnaryOperatorRegisterForB +{ + private: + void _register_unary_minus(); + void _register_unary_not(); + + public: + UnaryOperatorRegisterForB(); +}; + +#endif // UNARY_OPERATOR_REGISTER_FOR_B_HPP diff --git a/src/language/utils/UnaryOperatorRegisterForN.cpp b/src/language/utils/UnaryOperatorRegisterForN.cpp new file mode 100644 index 0000000000000000000000000000000000000000..baed0e43eef169229cfbff58fb0592f894b83163 --- /dev/null +++ b/src/language/utils/UnaryOperatorRegisterForN.cpp @@ -0,0 +1,21 @@ +#include <language/utils/UnaryOperatorRegisterForN.hpp> + +#include <language/utils/OperatorRepository.hpp> +#include <language/utils/UnaryOperatorProcessorBuilder.hpp> + +void +UnaryOperatorRegisterForN::_register_unary_minus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto N = ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(); + + repository.addUnaryOperator< + language::unary_minus>(N, + std::make_shared<UnaryOperatorProcessorBuilder<language::unary_minus, int64_t, uint64_t>>()); +} + +UnaryOperatorRegisterForN::UnaryOperatorRegisterForN() +{ + this->_register_unary_minus(); +} diff --git a/src/language/utils/UnaryOperatorRegisterForN.hpp b/src/language/utils/UnaryOperatorRegisterForN.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d6a4ff62ed93e0db85b53f503de096f3dcc527ba --- /dev/null +++ b/src/language/utils/UnaryOperatorRegisterForN.hpp @@ -0,0 +1,13 @@ +#ifndef UNARY_OPERATOR_REGISTER_FOR_N_HPP +#define UNARY_OPERATOR_REGISTER_FOR_N_HPP + +class UnaryOperatorRegisterForN +{ + private: + void _register_unary_minus(); + + public: + UnaryOperatorRegisterForN(); +}; + +#endif // UNARY_OPERATOR_REGISTER_FOR_N_HPP diff --git a/src/language/utils/UnaryOperatorRegisterForR.cpp b/src/language/utils/UnaryOperatorRegisterForR.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c0c60a31f5f6c222232999c3b392a18f30a767c1 --- /dev/null +++ b/src/language/utils/UnaryOperatorRegisterForR.cpp @@ -0,0 +1,20 @@ +#include <language/utils/UnaryOperatorRegisterForR.hpp> + +#include <language/utils/OperatorRepository.hpp> +#include <language/utils/UnaryOperatorProcessorBuilder.hpp> + +void +UnaryOperatorRegisterForR::_register_unary_minus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto R = ASTNodeDataType::build<ASTNodeDataType::double_t>(); + + repository.addUnaryOperator< + language::unary_minus>(R, std::make_shared<UnaryOperatorProcessorBuilder<language::unary_minus, double, double>>()); +} + +UnaryOperatorRegisterForR::UnaryOperatorRegisterForR() +{ + this->_register_unary_minus(); +} diff --git a/src/language/utils/UnaryOperatorRegisterForR.hpp b/src/language/utils/UnaryOperatorRegisterForR.hpp new file mode 100644 index 0000000000000000000000000000000000000000..308fe639039da194c2419f3902a1f98868482716 --- /dev/null +++ b/src/language/utils/UnaryOperatorRegisterForR.hpp @@ -0,0 +1,13 @@ +#ifndef UNARY_OPERATOR_REGISTER_FOR_R_HPP +#define UNARY_OPERATOR_REGISTER_FOR_R_HPP + +class UnaryOperatorRegisterForR +{ + private: + void _register_unary_minus(); + + public: + UnaryOperatorRegisterForR(); +}; + +#endif // UNARY_OPERATOR_REGISTER_FOR_R_HPP diff --git a/src/language/utils/UnaryOperatorRegisterForRn.cpp b/src/language/utils/UnaryOperatorRegisterForRn.cpp new file mode 100644 index 0000000000000000000000000000000000000000..85cc03fa476a34a6bec65f2c7f88f1d76fbad809 --- /dev/null +++ b/src/language/utils/UnaryOperatorRegisterForRn.cpp @@ -0,0 +1,28 @@ +#include <language/utils/UnaryOperatorRegisterForRn.hpp> + +#include <language/utils/OperatorRepository.hpp> +#include <language/utils/UnaryOperatorProcessorBuilder.hpp> + +template <size_t Dimension> +void +UnaryOperatorRegisterForRn<Dimension>::_register_unary_minus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto Rn = ASTNodeDataType::build<ASTNodeDataType::vector_t>(Dimension); + + repository + .addUnaryOperator<language::unary_minus>(Rn, + std::make_shared<UnaryOperatorProcessorBuilder< + language::unary_minus, TinyVector<Dimension>, TinyVector<Dimension>>>()); +} + +template <size_t Dimension> +UnaryOperatorRegisterForRn<Dimension>::UnaryOperatorRegisterForRn() +{ + this->_register_unary_minus(); +} + +template class UnaryOperatorRegisterForRn<1>; +template class UnaryOperatorRegisterForRn<2>; +template class UnaryOperatorRegisterForRn<3>; diff --git a/src/language/utils/UnaryOperatorRegisterForRn.hpp b/src/language/utils/UnaryOperatorRegisterForRn.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a0000f2f588bdc84ccc77e3c03515a92126aac14 --- /dev/null +++ b/src/language/utils/UnaryOperatorRegisterForRn.hpp @@ -0,0 +1,16 @@ +#ifndef UNARY_OPERATOR_REGISTER_FOR_RN_HPP +#define UNARY_OPERATOR_REGISTER_FOR_RN_HPP + +#include <cstdlib> + +template <size_t Dimension> +class UnaryOperatorRegisterForRn +{ + private: + void _register_unary_minus(); + + public: + UnaryOperatorRegisterForRn(); +}; + +#endif // UNARY_OPERATOR_REGISTER_FOR_RN_HPP diff --git a/src/language/utils/UnaryOperatorRegisterForZ.cpp b/src/language/utils/UnaryOperatorRegisterForZ.cpp new file mode 100644 index 0000000000000000000000000000000000000000..89e0b4972a0a1e2a2556d2210ab4658b35f7b976 --- /dev/null +++ b/src/language/utils/UnaryOperatorRegisterForZ.cpp @@ -0,0 +1,21 @@ +#include <language/utils/UnaryOperatorRegisterForZ.hpp> + +#include <language/utils/OperatorRepository.hpp> +#include <language/utils/UnaryOperatorProcessorBuilder.hpp> + +void +UnaryOperatorRegisterForZ::_register_unary_minus() +{ + OperatorRepository& repository = OperatorRepository::instance(); + + auto Z = ASTNodeDataType::build<ASTNodeDataType::int_t>(); + + repository.addUnaryOperator< + language::unary_minus>(Z, + std::make_shared<UnaryOperatorProcessorBuilder<language::unary_minus, int64_t, int64_t>>()); +} + +UnaryOperatorRegisterForZ::UnaryOperatorRegisterForZ() +{ + this->_register_unary_minus(); +} diff --git a/src/language/utils/UnaryOperatorRegisterForZ.hpp b/src/language/utils/UnaryOperatorRegisterForZ.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a0e3065b139a23e1898bc4954b3b76a1df3f7e44 --- /dev/null +++ b/src/language/utils/UnaryOperatorRegisterForZ.hpp @@ -0,0 +1,13 @@ +#ifndef UNARY_OPERATOR_REGISTER_FOR_Z_HPP +#define UNARY_OPERATOR_REGISTER_FOR_Z_HPP + +class UnaryOperatorRegisterForZ +{ + private: + void _register_unary_minus(); + + public: + UnaryOperatorRegisterForZ(); +}; + +#endif // UNARY_OPERATOR_REGISTER_FOR_Z_HPP diff --git a/src/utils/Timer.hpp b/src/utils/Timer.hpp index e1ba542f2cda3969c1af397decc05451e7a3aaa4..786d7b789fb02993e2279f5e557c22423663a4e9 100644 --- a/src/utils/Timer.hpp +++ b/src/utils/Timer.hpp @@ -32,7 +32,9 @@ class Timer { switch (m_status) { case Status::running: { - return (m_elapsed_sum + std::chrono::duration<double>{std::chrono::system_clock::now() - m_start}).count(); + return (m_elapsed_sum + std::chrono::duration<double>{std::chrono::system_clock::now().time_since_epoch() - + m_start.time_since_epoch()}) + .count(); } case Status::paused: case Status::stopped: { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index edaa8069ad867aeaa139f68f646519a6219097d0..5ae8aeef954932a6051be1f6f916d20dbad2b9f3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -125,7 +125,16 @@ target_link_libraries (unit_tests target_link_libraries (mpi_unit_tests test_Pugs_MeshDataBase + PugsAlgebra + PugsUtils + PugsLanguage + PugsLanguageAST + PugsLanguageModules + PugsLanguageAlgorithms + PugsMesh + PugsAlgebra PugsUtils + PugsLanguageUtils PugsUtils PugsAlgebra PugsMesh kokkos diff --git a/tests/mpi_test_main.cpp b/tests/mpi_test_main.cpp index 87953af0c1d98a6b099b8d99606d8f4eaa686a40..44162aba3edce0e992b7f37e6df6cca1040b3291 100644 --- a/tests/mpi_test_main.cpp +++ b/tests/mpi_test_main.cpp @@ -4,6 +4,7 @@ #include <Kokkos_Core.hpp> #include <algebra/PETScWrapper.hpp> +#include <language/utils/OperatorRepository.hpp> #include <mesh/DiamondDualConnectivityManager.hpp> #include <mesh/DiamondDualMeshManager.hpp> #include <mesh/MeshDataManager.hpp> @@ -78,8 +79,12 @@ main(int argc, char* argv[]) } } + OperatorRepository::create(); + result = session.run(); + OperatorRepository::destroy(); + MeshDataBaseForTests::destroy(); DiamondDualMeshManager::destroy(); diff --git a/tests/test_ASTNodeAffectationExpressionBuilder.cpp b/tests/test_ASTNodeAffectationExpressionBuilder.cpp index 64d60d9bfbed21703850f2d945092a9d5ae49fe0..ecd72b1f04b52b47431e10d07b83d3dab441066e 100644 --- a/tests/test_ASTNodeAffectationExpressionBuilder.cpp +++ b/tests/test_ASTNodeAffectationExpressionBuilder.cpp @@ -10,33 +10,40 @@ #include <language/ast/ASTSymbolTableBuilder.hpp> #include <language/utils/ASTNodeDataTypeTraits.hpp> #include <language/utils/ASTPrinter.hpp> +#include <language/utils/BasicAffectationRegistrerFor.hpp> +#include <language/utils/EmbeddedData.hpp> #include <language/utils/TypeDescriptor.hpp> #include <utils/Demangle.hpp> #include <utils/Exceptions.hpp> #include <pegtl/string_input.hpp> -#define CHECK_AST(data, expected_output) \ - { \ - static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \ - static_assert(std::is_same_v<std::decay_t<decltype(expected_output)>, std::string_view> or \ - std::is_same_v<std::decay_t<decltype(expected_output)>, std::string>); \ - \ - string_input input{data, "test.pgs"}; \ - auto ast = ASTBuilder::build(input); \ - \ - ASTSymbolTableBuilder{*ast}; \ - ASTNodeDataTypeBuilder{*ast}; \ - \ - ASTNodeDeclarationToAffectationConverter{*ast}; \ - ASTNodeTypeCleaner<language::var_declaration>{*ast}; \ - \ - ASTNodeExpressionBuilder{*ast}; \ - \ - std::stringstream ast_output; \ - ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::exec_type}}; \ - \ - REQUIRE(ast_output.str() == expected_output); \ +#define CHECK_AST(data, expected_output) \ + { \ + static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \ + static_assert(std::is_same_v<std::decay_t<decltype(expected_output)>, std::string_view> or \ + std::is_same_v<std::decay_t<decltype(expected_output)>, std::string>); \ + \ + string_input input{data, "test.pgs"}; \ + \ + BasicAffectationRegisterFor<EmbeddedData>{ASTNodeDataType::build<ASTNodeDataType::type_id_t>("builtin_t")}; \ + \ + auto ast = ASTBuilder::build(input); \ + \ + ASTSymbolTableBuilder{*ast}; \ + ASTNodeDataTypeBuilder{*ast}; \ + \ + ASTNodeDeclarationToAffectationConverter{*ast}; \ + ASTNodeTypeCleaner<language::var_declaration>{*ast}; \ + \ + ASTNodeExpressionBuilder{*ast}; \ + \ + std::stringstream ast_output; \ + ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::exec_type}}; \ + \ + REQUIRE(ast_output.str() == expected_output); \ + \ + OperatorRepository::instance().reset(); \ } template <> @@ -44,51 +51,55 @@ inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const double>> = ASTNodeDataType::build<ASTNodeDataType::type_id_t>("builtin_t"); const auto builtin_data_type = ast_node_data_type_from<std::shared_ptr<const double>>; -#define CHECK_AST_WITH_BUILTIN(data, expected_output) \ - { \ - static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \ - static_assert(std::is_same_v<std::decay_t<decltype(expected_output)>, std::string_view> or \ - std::is_same_v<std::decay_t<decltype(expected_output)>, std::string>); \ - \ - string_input input{data, "test.pgs"}; \ - auto ast = ASTBuilder::build(input); \ - \ - SymbolTable& symbol_table = *ast->m_symbol_table; \ - auto [i_symbol, success] = symbol_table.add(builtin_data_type.nameOfTypeId(), ast->begin()); \ - if (not success) { \ - throw UnexpectedError("cannot add '" + builtin_data_type.nameOfTypeId() + "' type for testing"); \ - } \ - \ - i_symbol->attributes().setDataType(ASTNodeDataType::build<ASTNodeDataType::type_name_id_t>()); \ - i_symbol->attributes().setIsInitialized(); \ - i_symbol->attributes().value() = symbol_table.typeEmbedderTable().size(); \ - symbol_table.typeEmbedderTable().add(std::make_shared<TypeDescriptor>(builtin_data_type.nameOfTypeId())); \ - \ - auto [i_symbol_a, success_a] = symbol_table.add("a", ast->begin()); \ - if (not success_a) { \ - throw UnexpectedError("cannot add 'a' of type builtin_t for testing"); \ - } \ - i_symbol_a->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>); \ - i_symbol_a->attributes().setIsInitialized(); \ - auto [i_symbol_b, success_b] = symbol_table.add("b", ast->begin()); \ - if (not success_b) { \ - throw UnexpectedError("cannot add 'b' of type builtin_t for testing"); \ - } \ - i_symbol_b->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>); \ - i_symbol_b->attributes().setIsInitialized(); \ - \ - ASTSymbolTableBuilder{*ast}; \ - ASTNodeDataTypeBuilder{*ast}; \ - \ - ASTNodeDeclarationToAffectationConverter{*ast}; \ - ASTNodeTypeCleaner<language::var_declaration>{*ast}; \ - \ - ASTNodeExpressionBuilder{*ast}; \ - \ - std::stringstream ast_output; \ - ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::exec_type}}; \ - \ - REQUIRE(ast_output.str() == expected_output); \ +#define CHECK_AST_WITH_BUILTIN(data, expected_output) \ + { \ + static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \ + static_assert(std::is_same_v<std::decay_t<decltype(expected_output)>, std::string_view> or \ + std::is_same_v<std::decay_t<decltype(expected_output)>, std::string>); \ + \ + BasicAffectationRegisterFor<EmbeddedData>{ASTNodeDataType::build<ASTNodeDataType::type_id_t>("builtin_t")}; \ + \ + string_input input{data, "test.pgs"}; \ + auto ast = ASTBuilder::build(input); \ + \ + SymbolTable& symbol_table = *ast->m_symbol_table; \ + auto [i_symbol, success] = symbol_table.add(builtin_data_type.nameOfTypeId(), ast->begin()); \ + if (not success) { \ + throw UnexpectedError("cannot add '" + builtin_data_type.nameOfTypeId() + "' type for testing"); \ + } \ + \ + i_symbol->attributes().setDataType(ASTNodeDataType::build<ASTNodeDataType::type_name_id_t>()); \ + i_symbol->attributes().setIsInitialized(); \ + i_symbol->attributes().value() = symbol_table.typeEmbedderTable().size(); \ + symbol_table.typeEmbedderTable().add(std::make_shared<TypeDescriptor>(builtin_data_type.nameOfTypeId())); \ + \ + auto [i_symbol_a, success_a] = symbol_table.add("a", ast->begin()); \ + if (not success_a) { \ + throw UnexpectedError("cannot add 'a' of type builtin_t for testing"); \ + } \ + i_symbol_a->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>); \ + i_symbol_a->attributes().setIsInitialized(); \ + auto [i_symbol_b, success_b] = symbol_table.add("b", ast->begin()); \ + if (not success_b) { \ + throw UnexpectedError("cannot add 'b' of type builtin_t for testing"); \ + } \ + i_symbol_b->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>); \ + i_symbol_b->attributes().setIsInitialized(); \ + \ + ASTSymbolTableBuilder{*ast}; \ + ASTNodeDataTypeBuilder{*ast}; \ + \ + ASTNodeDeclarationToAffectationConverter{*ast}; \ + ASTNodeTypeCleaner<language::var_declaration>{*ast}; \ + \ + ASTNodeExpressionBuilder{*ast}; \ + \ + std::stringstream ast_output; \ + ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::exec_type}}; \ + \ + REQUIRE(ast_output.str() == expected_output); \ + \ + OperatorRepository::instance().reset(); \ } #define CHECK_AST_THROWS_WITH(data, expected_error) \ @@ -109,46 +120,50 @@ const auto builtin_data_type = ast_node_data_type_from<std::shared_ptr<const dou REQUIRE_THROWS_WITH(ASTNodeExpressionBuilder{*ast}, expected_error); \ } -#define CHECK_AST_WITH_BUILTIN_THROWS_WITH(data, expected_error) \ - { \ - static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \ - static_assert(std::is_same_v<std::decay_t<decltype(expected_error)>, std::string_view> or \ - std::is_same_v<std::decay_t<decltype(expected_error)>, std::string>); \ - \ - string_input input{data, "test.pgs"}; \ - auto ast = ASTBuilder::build(input); \ - \ - SymbolTable& symbol_table = *ast->m_symbol_table; \ - auto [i_symbol, success] = symbol_table.add(builtin_data_type.nameOfTypeId(), ast->begin()); \ - if (not success) { \ - throw UnexpectedError("cannot add '" + builtin_data_type.nameOfTypeId() + "' type for testing"); \ - } \ - \ - i_symbol->attributes().setDataType(ASTNodeDataType::build<ASTNodeDataType::type_name_id_t>()); \ - i_symbol->attributes().setIsInitialized(); \ - i_symbol->attributes().value() = symbol_table.typeEmbedderTable().size(); \ - symbol_table.typeEmbedderTable().add(std::make_shared<TypeDescriptor>(builtin_data_type.nameOfTypeId())); \ - \ - auto [i_symbol_a, success_a] = symbol_table.add("a", ast->begin()); \ - if (not success_a) { \ - throw UnexpectedError("cannot add 'a' of type builtin_t for testing"); \ - } \ - i_symbol_a->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>); \ - i_symbol_a->attributes().setIsInitialized(); \ - auto [i_symbol_b, success_b] = symbol_table.add("b", ast->begin()); \ - if (not success_b) { \ - throw UnexpectedError("cannot add 'b' of type builtin_t for testing"); \ - } \ - i_symbol_b->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>); \ - i_symbol_b->attributes().setIsInitialized(); \ - \ - ASTSymbolTableBuilder{*ast}; \ - ASTNodeDataTypeBuilder{*ast}; \ - \ - ASTNodeDeclarationToAffectationConverter{*ast}; \ - ASTNodeTypeCleaner<language::var_declaration>{*ast}; \ - \ - REQUIRE_THROWS_WITH(ASTNodeExpressionBuilder{*ast}, expected_error); \ +#define CHECK_AST_WITH_BUILTIN_THROWS_WITH(data, expected_error) \ + { \ + static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \ + static_assert(std::is_same_v<std::decay_t<decltype(expected_error)>, std::string_view> or \ + std::is_same_v<std::decay_t<decltype(expected_error)>, std::string>); \ + \ + BasicAffectationRegisterFor<EmbeddedData>{ASTNodeDataType::build<ASTNodeDataType::type_id_t>("builtin_t")}; \ + \ + string_input input{data, "test.pgs"}; \ + auto ast = ASTBuilder::build(input); \ + \ + SymbolTable& symbol_table = *ast->m_symbol_table; \ + auto [i_symbol, success] = symbol_table.add(builtin_data_type.nameOfTypeId(), ast->begin()); \ + if (not success) { \ + throw UnexpectedError("cannot add '" + builtin_data_type.nameOfTypeId() + "' type for testing"); \ + } \ + \ + i_symbol->attributes().setDataType(ASTNodeDataType::build<ASTNodeDataType::type_name_id_t>()); \ + i_symbol->attributes().setIsInitialized(); \ + i_symbol->attributes().value() = symbol_table.typeEmbedderTable().size(); \ + symbol_table.typeEmbedderTable().add(std::make_shared<TypeDescriptor>(builtin_data_type.nameOfTypeId())); \ + \ + auto [i_symbol_a, success_a] = symbol_table.add("a", ast->begin()); \ + if (not success_a) { \ + throw UnexpectedError("cannot add 'a' of type builtin_t for testing"); \ + } \ + i_symbol_a->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>); \ + i_symbol_a->attributes().setIsInitialized(); \ + auto [i_symbol_b, success_b] = symbol_table.add("b", ast->begin()); \ + if (not success_b) { \ + throw UnexpectedError("cannot add 'b' of type builtin_t for testing"); \ + } \ + i_symbol_b->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>); \ + i_symbol_b->attributes().setIsInitialized(); \ + \ + ASTSymbolTableBuilder{*ast}; \ + ASTNodeDataTypeBuilder{*ast}; \ + \ + ASTNodeDeclarationToAffectationConverter{*ast}; \ + ASTNodeTypeCleaner<language::var_declaration>{*ast}; \ + \ + REQUIRE_THROWS_WITH(ASTNodeExpressionBuilder{*ast}, expected_error); \ + \ + OperatorRepository::instance().reset(); \ } // clazy:excludeall=non-pod-global-static @@ -672,7 +687,7 @@ let t : (B), t = (true, false); std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToTupleFromListProcessor<language::eq_op, bool>) + `-(language::eq_op:AffectationToTupleFromListProcessor<bool>) +-(language::name:t:NameProcessor) `-(language::expression_list:ASTNodeExpressionListProcessor) +-(language::true_kw:ValueProcessor) @@ -690,7 +705,7 @@ let t : (N), t = (1, 2, 3, 5); std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToTupleFromListProcessor<language::eq_op, unsigned long>) + `-(language::eq_op:AffectationToTupleFromListProcessor<unsigned long>) +-(language::name:t:NameProcessor) `-(language::expression_list:ASTNodeExpressionListProcessor) +-(language::integer:1:ValueProcessor) @@ -714,7 +729,7 @@ let t : (Z), t = (2, n, true); +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>) | +-(language::name:n:NameProcessor) | `-(language::integer:3:ValueProcessor) - `-(language::eq_op:AffectationToTupleFromListProcessor<language::eq_op, long>) + `-(language::eq_op:AffectationToTupleFromListProcessor<long>) +-(language::name:t:NameProcessor) `-(language::expression_list:ASTNodeExpressionListProcessor) +-(language::integer:2:ValueProcessor) @@ -733,7 +748,7 @@ let t : (R), t = (2, 3.1, 5); std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToTupleFromListProcessor<language::eq_op, double>) + `-(language::eq_op:AffectationToTupleFromListProcessor<double>) +-(language::name:t:NameProcessor) `-(language::expression_list:ASTNodeExpressionListProcessor) +-(language::integer:2:ValueProcessor) @@ -760,7 +775,7 @@ let t3 : (R^1), t3 = (1, 2.3, 0); | `-(language::expression_list:ASTNodeExpressionListProcessor) | +-(language::integer:2:ValueProcessor) | `-(language::real:3.1:ValueProcessor) - +-(language::eq_op:AffectationToTupleFromListProcessor<language::eq_op, TinyVector<2ul, double> >) + +-(language::eq_op:AffectationToTupleFromListProcessor<TinyVector<2ul, double> >) | +-(language::name:t1:NameProcessor) | `-(language::expression_list:ASTNodeExpressionListProcessor) | +-(language::name:a:NameProcessor) @@ -768,12 +783,12 @@ let t3 : (R^1), t3 = (1, 2.3, 0); | | +-(language::integer:1:ValueProcessor) | | `-(language::integer:2:ValueProcessor) | `-(language::integer:0:ValueProcessor) - +-(language::eq_op:AffectationToTupleFromListProcessor<language::eq_op, TinyVector<3ul, double> >) + +-(language::eq_op:AffectationToTupleFromListProcessor<TinyVector<3ul, double> >) | +-(language::name:t2:NameProcessor) | `-(language::expression_list:ASTNodeExpressionListProcessor) | +-(language::integer:0:ValueProcessor) | `-(language::integer:0:ValueProcessor) - `-(language::eq_op:AffectationToTupleFromListProcessor<language::eq_op, TinyVector<1ul, double> >) + `-(language::eq_op:AffectationToTupleFromListProcessor<TinyVector<1ul, double> >) +-(language::name:t3:NameProcessor) `-(language::expression_list:ASTNodeExpressionListProcessor) +-(language::integer:1:ValueProcessor) @@ -792,7 +807,7 @@ let t : (string), t = ("foo", "bar"); std::string result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToTupleFromListProcessor<language::eq_op, )" + + `-(language::eq_op:AffectationToTupleFromListProcessor<)" + demangled_stdstring + R"( >) +-(language::name:t:NameProcessor) `-(language::expression_list:ASTNodeExpressionListProcessor) @@ -811,7 +826,7 @@ let t : (builtin_t), t= (a,b,a); std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToTupleFromListProcessor<language::eq_op, EmbeddedData>) + `-(language::eq_op:AffectationToTupleFromListProcessor<EmbeddedData>) +-(language::name:t:NameProcessor) `-(language::expression_list:ASTNodeExpressionListProcessor) +-(language::name:a:NameProcessor) @@ -833,7 +848,7 @@ let t : (B), t = true; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToTupleProcessor<language::eq_op, bool>) + `-(language::eq_op:AffectationToTupleProcessor<bool>) +-(language::name:t:NameProcessor) `-(language::true_kw:ValueProcessor) )"; @@ -849,7 +864,7 @@ let t : (N), t = 1; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToTupleProcessor<language::eq_op, unsigned long>) + `-(language::eq_op:AffectationToTupleProcessor<unsigned long>) +-(language::name:t:NameProcessor) `-(language::integer:1:ValueProcessor) )"; @@ -869,7 +884,7 @@ let t : (Z), t = n; +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>) | +-(language::name:n:NameProcessor) | `-(language::integer:3:ValueProcessor) - `-(language::eq_op:AffectationToTupleProcessor<language::eq_op, long>) + `-(language::eq_op:AffectationToTupleProcessor<long>) +-(language::name:t:NameProcessor) `-(language::name:n:NameProcessor) )"; @@ -885,7 +900,7 @@ let t : (R), t = 3.1; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToTupleProcessor<language::eq_op, double>) + `-(language::eq_op:AffectationToTupleProcessor<double>) +-(language::name:t:NameProcessor) `-(language::real:3.1:ValueProcessor) )"; @@ -909,13 +924,13 @@ let t3 : (R^1), t3 = 2.3; | `-(language::expression_list:ASTNodeExpressionListProcessor) | +-(language::integer:2:ValueProcessor) | `-(language::real:3.1:ValueProcessor) - +-(language::eq_op:AffectationToTupleProcessor<language::eq_op, TinyVector<2ul, double> >) + +-(language::eq_op:AffectationToTupleProcessor<TinyVector<2ul, double> >) | +-(language::name:t1:NameProcessor) | `-(language::name:a:NameProcessor) - +-(language::eq_op:AffectationToTupleProcessor<language::eq_op, TinyVector<3ul, double> >) + +-(language::eq_op:AffectationToTupleProcessor<TinyVector<3ul, double> >) | +-(language::name:t2:NameProcessor) | `-(language::integer:0:ValueProcessor) - `-(language::eq_op:AffectationToTupleProcessor<language::eq_op, TinyVector<1ul, double> >) + `-(language::eq_op:AffectationToTupleProcessor<TinyVector<1ul, double> >) +-(language::name:t3:NameProcessor) `-(language::real:2.3:ValueProcessor) )"; @@ -931,7 +946,7 @@ let t : (string), t = "foo"; std::string result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToTupleProcessor<language::eq_op, )" + + `-(language::eq_op:AffectationToTupleProcessor<)" + demangled_stdstring + R"( >) +-(language::name:t:NameProcessor) `-(language::literal:"foo":ValueProcessor) @@ -948,7 +963,7 @@ let t : (builtin_t), t = a; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToTupleProcessor<language::eq_op, EmbeddedData>) + `-(language::eq_op:AffectationToTupleProcessor<EmbeddedData>) +-(language::name:t:NameProcessor) `-(language::name:a:NameProcessor) )"; @@ -1511,33 +1526,20 @@ let x : R, x=1; x/=2.3; { SECTION("Invalid affectation operator") { - auto ast = std::make_unique<ASTNode>(); + auto ast = std::make_unique<ASTNode>(); + ast->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); + { + auto child_0 = std::make_unique<ASTNode>(); + child_0->m_data_type = ASTNodeDataType::build<ASTNodeDataType::bool_t>(); + auto child_1 = std::make_unique<ASTNode>(); + child_1->m_data_type = ASTNodeDataType::build<ASTNodeDataType::bool_t>(); + ast->children.emplace_back(std::move(child_0)); + ast->children.emplace_back(std::move(child_1)); + } REQUIRE_THROWS_WITH(ASTNodeAffectationExpressionBuilder{*ast}, "unexpected error: undefined affectation operator"); } - SECTION("Invalid lhs") - { - auto ast = std::make_unique<ASTNode>(); - ast->set_type<language::eq_op>(); - ast->children.emplace_back(std::make_unique<ASTNode>()); - ast->children.emplace_back(std::make_unique<ASTNode>()); - REQUIRE_THROWS_WITH(ASTNodeAffectationExpressionBuilder{*ast}, - "unexpected error: undefined value type for affectation"); - } - - SECTION("Invalid rhs") - { - auto ast = std::make_unique<ASTNode>(); - ast->set_type<language::eq_op>(); - - ast->children.emplace_back(std::make_unique<ASTNode>()); - ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - ast->children.emplace_back(std::make_unique<ASTNode>()); - REQUIRE_THROWS_WITH(ASTNodeAffectationExpressionBuilder{*ast}, - "unexpected error: invalid implicit conversion: undefined -> Z"); - } - SECTION("Invalid string rhs") { auto ast = std::make_unique<ASTNode>(); @@ -1558,7 +1560,7 @@ let x : R, x=1; x/=2.3; let s : string, s="foo"; s-="bar"; )"; - std::string error_message = "invalid affectation operator for string"; + std::string error_message = "undefined affectation type: string -= string"; CHECK_AST_THROWS_WITH(data, error_message); } @@ -1569,7 +1571,7 @@ let s : string, s="foo"; s-="bar"; let s : string, s="foo"; s*=2; )"; - std::string error_message = "invalid affectation operator for string"; + std::string error_message = "undefined affectation type: string *= Z"; CHECK_AST_THROWS_WITH(data, error_message); } @@ -1580,7 +1582,7 @@ let s : string, s="foo"; s*=2; let s : string, s="foo"; s/="bar"; )"; - std::string error_message = "invalid affectation operator for string"; + std::string error_message = "undefined affectation type: string /= string"; CHECK_AST_THROWS_WITH(data, error_message); } @@ -1592,7 +1594,7 @@ let s : string, s="foo"; s*=2; let s :builtin_t, s = a; s *= b; )"; - std::string error_message = "invalid affectation operator for 'builtin_t'"; + std::string error_message = "undefined affectation type: builtin_t *= builtin_t"; CHECK_AST_WITH_BUILTIN_THROWS_WITH(data, error_message); } @@ -1603,7 +1605,7 @@ let s : string, s="foo"; s*=2; let s :(R), s=(1,2,3); s *= 4; )"; - std::string error_message = "invalid affectation operator for 'tuple(R)'"; + std::string error_message = "undefined affectation type: tuple(R) *= Z"; CHECK_AST_THROWS_WITH(data, error_message); } @@ -1614,7 +1616,7 @@ let s : string, s="foo"; s*=2; let s : (builtin_t), s =(a,b); s *= b; )"; - std::string error_message = "invalid affectation operator for 'tuple(builtin_t)'"; + std::string error_message = "undefined affectation type: tuple(builtin_t) *= builtin_t"; CHECK_AST_WITH_BUILTIN_THROWS_WITH(data, error_message); } @@ -1721,7 +1723,7 @@ let x : R^2, x = 2; let x : R^3; let y : R^3; x /= y; )"; - std::string error_message = "invalid affectation operator for R^3"; + std::string error_message = "undefined affectation type: R^3 /= R^3"; CHECK_AST_THROWS_WITH(data, error_message); } @@ -1732,7 +1734,7 @@ let x : R^3; let y : R^3; x /= y; let x : R^2; let y : R^2; x /= y; )"; - std::string error_message = "invalid affectation operator for R^2"; + std::string error_message = "undefined affectation type: R^2 /= R^2"; CHECK_AST_THROWS_WITH(data, error_message); } @@ -1743,7 +1745,7 @@ let x : R^2; let y : R^2; x /= y; let x : R^1; let y : R^1; x /= y; )"; - std::string error_message = "invalid affectation operator for R^1"; + std::string error_message = "undefined affectation type: R^1 /= R^1"; CHECK_AST_THROWS_WITH(data, error_message); } @@ -1757,7 +1759,7 @@ let x : R^1; let y : R^1; x /= y; let x : R^3; let y : R^3; x *= y; )"; - std::string error_message = "expecting scalar operand type"; + std::string error_message = "undefined affectation type: R^3 *= R^3"; CHECK_AST_THROWS_WITH(data, error_message); } @@ -1768,7 +1770,7 @@ let x : R^3; let y : R^3; x *= y; let x : R^2; let y : R^2; x *= y; )"; - std::string error_message = "expecting scalar operand type"; + std::string error_message = "undefined affectation type: R^2 *= R^2"; CHECK_AST_THROWS_WITH(data, error_message); } @@ -1779,7 +1781,7 @@ let x : R^2; let y : R^2; x *= y; let x : R^1; let y : R^1; x *= y; )"; - std::string error_message = "expecting scalar operand type"; + std::string error_message = "undefined affectation type: R^1 *= R^1"; CHECK_AST_THROWS_WITH(data, error_message); } diff --git a/tests/test_ASTNodeBinaryOperatorExpressionBuilder.cpp b/tests/test_ASTNodeBinaryOperatorExpressionBuilder.cpp index 7226ec270bc72889cc13d37ebda069cbad7d3512..1c030e91791827d6a4b69a087c116b2cdd61fc33 100644 --- a/tests/test_ASTNodeBinaryOperatorExpressionBuilder.cpp +++ b/tests/test_ASTNodeBinaryOperatorExpressionBuilder.cpp @@ -35,6 +35,18 @@ REQUIRE(ast_output.str() == expected_output); \ } +#define REQUIRE_AST_THROWS_WITH(data, expected_output) \ + { \ + static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \ + \ + string_input input{data, "test.pgs"}; \ + auto ast = ASTBuilder::build(input); \ + \ + ASTSymbolTableBuilder{*ast}; \ + REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast}, expected_output); \ + } + +/* #define REQUIRE_AST_THROWS_WITH(data, expected_output) \ { \ static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \ @@ -50,6 +62,7 @@ \ REQUIRE_THROWS_WITH(ASTNodeExpressionBuilder{*ast}, expected_output); \ } +*/ // clazy:excludeall=non-pod-global-static @@ -67,11 +80,11 @@ false*b*true; std::string_view result = R"( (root:ASTNodeListProcessor) - +-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, bool, bool>) + +-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, unsigned long, bool, bool>) | +-(language::name:b:NameProcessor) | `-(language::true_kw:ValueProcessor) - `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, long, bool>) - +-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, bool, bool>) + `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, unsigned long, unsigned long, bool>) + +-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, unsigned long, bool, bool>) | +-(language::false_kw:ValueProcessor) | `-(language::name:b:NameProcessor) `-(language::true_kw:ValueProcessor) @@ -90,8 +103,8 @@ n*m*n; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, unsigned long, unsigned long>) - +-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, unsigned long, unsigned long>) + `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, unsigned long, unsigned long, unsigned long>) + +-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, unsigned long, unsigned long, unsigned long>) | +-(language::name:n:NameProcessor) | `-(language::name:m:NameProcessor) `-(language::name:n:NameProcessor) @@ -109,8 +122,8 @@ a*3*a; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, long, long>) - +-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, long, long>) + `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, long, long, long>) + +-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, long, long, long>) | +-(language::name:a:NameProcessor) | `-(language::integer:3:ValueProcessor) `-(language::name:a:NameProcessor) @@ -127,9 +140,9 @@ a*3*a; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, double, bool>) - +-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, double, long>) - | +-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, double, double>) + `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, double, double, bool>) + +-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, double, double, long>) + | +-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, double, double, double>) | | +-(language::real:2.3:ValueProcessor) | | `-(language::real:1.2:ValueProcessor) | `-(language::integer:2:ValueProcessor) @@ -151,7 +164,7 @@ let x : R^1, x = 3.7; +-(language::eq_op:AffectationProcessor<language::eq_op, TinyVector<1ul, double>, double>) | +-(language::name:x:NameProcessor) | `-(language::real:3.7:ValueProcessor) - `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, long, TinyVector<1ul, double> >) + `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, TinyVector<1ul, double>, long, TinyVector<1ul, double> >) +-(language::integer:2:ValueProcessor) `-(language::name:x:NameProcessor) )"; @@ -173,7 +186,7 @@ let x : R^2, x = (3.2,6); | `-(language::expression_list:ASTNodeExpressionListProcessor) | +-(language::real:3.2:ValueProcessor) | `-(language::integer:6:ValueProcessor) - `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, long, TinyVector<2ul, double> >) + `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, TinyVector<2ul, double>, long, TinyVector<2ul, double> >) +-(language::integer:2:ValueProcessor) `-(language::name:x:NameProcessor) )"; @@ -196,7 +209,7 @@ let x : R^3, x = (3.2,6,1.2); | +-(language::real:3.2:ValueProcessor) | +-(language::integer:6:ValueProcessor) | `-(language::real:1.2:ValueProcessor) - `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, long, TinyVector<3ul, double> >) + `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, TinyVector<3ul, double>, long, TinyVector<3ul, double> >) +-(language::integer:2:ValueProcessor) `-(language::name:x:NameProcessor) )"; @@ -217,11 +230,11 @@ false/b/true; std::string_view result = R"( (root:ASTNodeListProcessor) - +-(language::divide_op:BinaryExpressionProcessor<language::divide_op, bool, bool>) + +-(language::divide_op:BinaryExpressionProcessor<language::divide_op, unsigned long, bool, bool>) | +-(language::name:b:NameProcessor) | `-(language::true_kw:ValueProcessor) - `-(language::divide_op:BinaryExpressionProcessor<language::divide_op, long, bool>) - +-(language::divide_op:BinaryExpressionProcessor<language::divide_op, bool, bool>) + `-(language::divide_op:BinaryExpressionProcessor<language::divide_op, unsigned long, unsigned long, bool>) + +-(language::divide_op:BinaryExpressionProcessor<language::divide_op, unsigned long, bool, bool>) | +-(language::false_kw:ValueProcessor) | `-(language::name:b:NameProcessor) `-(language::true_kw:ValueProcessor) @@ -240,8 +253,8 @@ n/m/n; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::divide_op:BinaryExpressionProcessor<language::divide_op, unsigned long, unsigned long>) - +-(language::divide_op:BinaryExpressionProcessor<language::divide_op, unsigned long, unsigned long>) + `-(language::divide_op:BinaryExpressionProcessor<language::divide_op, unsigned long, unsigned long, unsigned long>) + +-(language::divide_op:BinaryExpressionProcessor<language::divide_op, unsigned long, unsigned long, unsigned long>) | +-(language::name:n:NameProcessor) | `-(language::name:m:NameProcessor) `-(language::name:n:NameProcessor) @@ -259,8 +272,8 @@ a/3/a; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::divide_op:BinaryExpressionProcessor<language::divide_op, long, long>) - +-(language::divide_op:BinaryExpressionProcessor<language::divide_op, long, long>) + `-(language::divide_op:BinaryExpressionProcessor<language::divide_op, long, long, long>) + +-(language::divide_op:BinaryExpressionProcessor<language::divide_op, long, long, long>) | +-(language::name:a:NameProcessor) | `-(language::integer:3:ValueProcessor) `-(language::name:a:NameProcessor) @@ -277,9 +290,9 @@ a/3/a; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::divide_op:BinaryExpressionProcessor<language::divide_op, double, bool>) - +-(language::divide_op:BinaryExpressionProcessor<language::divide_op, double, long>) - | +-(language::divide_op:BinaryExpressionProcessor<language::divide_op, double, double>) + `-(language::divide_op:BinaryExpressionProcessor<language::divide_op, double, double, bool>) + +-(language::divide_op:BinaryExpressionProcessor<language::divide_op, double, double, long>) + | +-(language::divide_op:BinaryExpressionProcessor<language::divide_op, double, double, double>) | | +-(language::real:2.3:ValueProcessor) | | `-(language::real:1.2:ValueProcessor) | `-(language::integer:2:ValueProcessor) @@ -302,11 +315,11 @@ false+b+true; std::string_view result = R"( (root:ASTNodeListProcessor) - +-(language::plus_op:BinaryExpressionProcessor<language::plus_op, bool, bool>) + +-(language::plus_op:BinaryExpressionProcessor<language::plus_op, unsigned long, bool, bool>) | +-(language::name:b:NameProcessor) | `-(language::true_kw:ValueProcessor) - `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, long, bool>) - +-(language::plus_op:BinaryExpressionProcessor<language::plus_op, bool, bool>) + `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, unsigned long, unsigned long, bool>) + +-(language::plus_op:BinaryExpressionProcessor<language::plus_op, unsigned long, bool, bool>) | +-(language::false_kw:ValueProcessor) | `-(language::name:b:NameProcessor) `-(language::true_kw:ValueProcessor) @@ -325,8 +338,8 @@ n+m+n; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, unsigned long, unsigned long>) - +-(language::plus_op:BinaryExpressionProcessor<language::plus_op, unsigned long, unsigned long>) + `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, unsigned long, unsigned long, unsigned long>) + +-(language::plus_op:BinaryExpressionProcessor<language::plus_op, unsigned long, unsigned long, unsigned long>) | +-(language::name:n:NameProcessor) | `-(language::name:m:NameProcessor) `-(language::name:n:NameProcessor) @@ -344,8 +357,8 @@ a+3+a; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, long, long>) - +-(language::plus_op:BinaryExpressionProcessor<language::plus_op, long, long>) + `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, long, long, long>) + +-(language::plus_op:BinaryExpressionProcessor<language::plus_op, long, long, long>) | +-(language::name:a:NameProcessor) | `-(language::integer:3:ValueProcessor) `-(language::name:a:NameProcessor) @@ -362,9 +375,9 @@ a+3+a; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, double, bool>) - +-(language::plus_op:BinaryExpressionProcessor<language::plus_op, double, long>) - | +-(language::plus_op:BinaryExpressionProcessor<language::plus_op, double, double>) + `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, double, double, bool>) + +-(language::plus_op:BinaryExpressionProcessor<language::plus_op, double, double, long>) + | +-(language::plus_op:BinaryExpressionProcessor<language::plus_op, double, double, double>) | | +-(language::real:2.3:ValueProcessor) | | `-(language::real:1.2:ValueProcessor) | `-(language::integer:2:ValueProcessor) @@ -390,7 +403,7 @@ x+y; +-(language::eq_op:AffectationProcessor<language::eq_op, TinyVector<1ul, double>, long>) | +-(language::name:y:NameProcessor) | `-(language::integer:2:ValueProcessor) - `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, TinyVector<1ul, double>, TinyVector<1ul, double> >) + `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, TinyVector<1ul, double>, TinyVector<1ul, double>, TinyVector<1ul, double> >) +-(language::name:x:NameProcessor) `-(language::name:y:NameProcessor) )"; @@ -418,7 +431,7 @@ x+y; | `-(language::expression_list:ASTNodeExpressionListProcessor) | +-(language::real:0.3:ValueProcessor) | `-(language::real:0.7:ValueProcessor) - `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, TinyVector<2ul, double>, TinyVector<2ul, double> >) + `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, TinyVector<2ul, double>, TinyVector<2ul, double>, TinyVector<2ul, double> >) +-(language::name:x:NameProcessor) `-(language::name:y:NameProcessor) )"; @@ -448,7 +461,7 @@ x+y; | +-(language::integer:4:ValueProcessor) | +-(language::integer:3:ValueProcessor) | `-(language::integer:2:ValueProcessor) - `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, TinyVector<3ul, double>, TinyVector<3ul, double> >) + `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, TinyVector<3ul, double>, TinyVector<3ul, double>, TinyVector<3ul, double> >) +-(language::name:x:NameProcessor) `-(language::name:y:NameProcessor) )"; @@ -556,11 +569,11 @@ false-b-true; std::string_view result = R"( (root:ASTNodeListProcessor) - +-(language::minus_op:BinaryExpressionProcessor<language::minus_op, bool, bool>) + +-(language::minus_op:BinaryExpressionProcessor<language::minus_op, long, bool, bool>) | +-(language::name:b:NameProcessor) | `-(language::true_kw:ValueProcessor) - `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, long, bool>) - +-(language::minus_op:BinaryExpressionProcessor<language::minus_op, bool, bool>) + `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, long, long, bool>) + +-(language::minus_op:BinaryExpressionProcessor<language::minus_op, long, bool, bool>) | +-(language::false_kw:ValueProcessor) | `-(language::name:b:NameProcessor) `-(language::true_kw:ValueProcessor) @@ -579,8 +592,8 @@ n-m-n; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, unsigned long, unsigned long>) - +-(language::minus_op:BinaryExpressionProcessor<language::minus_op, unsigned long, unsigned long>) + `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, long, long, unsigned long>) + +-(language::minus_op:BinaryExpressionProcessor<language::minus_op, long, unsigned long, unsigned long>) | +-(language::name:n:NameProcessor) | `-(language::name:m:NameProcessor) `-(language::name:n:NameProcessor) @@ -598,8 +611,8 @@ a-3-a; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, long, long>) - +-(language::minus_op:BinaryExpressionProcessor<language::minus_op, long, long>) + `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, long, long, long>) + +-(language::minus_op:BinaryExpressionProcessor<language::minus_op, long, long, long>) | +-(language::name:a:NameProcessor) | `-(language::integer:3:ValueProcessor) `-(language::name:a:NameProcessor) @@ -616,9 +629,9 @@ a-3-a; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, double, bool>) - +-(language::minus_op:BinaryExpressionProcessor<language::minus_op, double, long>) - | +-(language::minus_op:BinaryExpressionProcessor<language::minus_op, double, double>) + `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, double, double, bool>) + +-(language::minus_op:BinaryExpressionProcessor<language::minus_op, double, double, long>) + | +-(language::minus_op:BinaryExpressionProcessor<language::minus_op, double, double, double>) | | +-(language::real:2.3:ValueProcessor) | | `-(language::real:1.2:ValueProcessor) | `-(language::integer:2:ValueProcessor) @@ -644,7 +657,7 @@ x-y; +-(language::eq_op:AffectationProcessor<language::eq_op, TinyVector<1ul, double>, long>) | +-(language::name:y:NameProcessor) | `-(language::integer:2:ValueProcessor) - `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, TinyVector<1ul, double>, TinyVector<1ul, double> >) + `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, TinyVector<1ul, double>, TinyVector<1ul, double>, TinyVector<1ul, double> >) +-(language::name:x:NameProcessor) `-(language::name:y:NameProcessor) )"; @@ -672,7 +685,7 @@ x-y; | `-(language::expression_list:ASTNodeExpressionListProcessor) | +-(language::real:0.3:ValueProcessor) | `-(language::real:0.7:ValueProcessor) - `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, TinyVector<2ul, double>, TinyVector<2ul, double> >) + `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, TinyVector<2ul, double>, TinyVector<2ul, double>, TinyVector<2ul, double> >) +-(language::name:x:NameProcessor) `-(language::name:y:NameProcessor) )"; @@ -702,7 +715,7 @@ x-y; | +-(language::integer:4:ValueProcessor) | +-(language::integer:3:ValueProcessor) | `-(language::integer:2:ValueProcessor) - `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, TinyVector<3ul, double>, TinyVector<3ul, double> >) + `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, TinyVector<3ul, double>, TinyVector<3ul, double>, TinyVector<3ul, double> >) +-(language::name:x:NameProcessor) `-(language::name:y:NameProcessor) )"; @@ -723,11 +736,11 @@ false or b or true; std::string_view result = R"( (root:ASTNodeListProcessor) - +-(language::or_op:BinaryExpressionProcessor<language::or_op, bool, bool>) + +-(language::or_op:BinaryExpressionProcessor<language::or_op, bool, bool, bool>) | +-(language::name:b:NameProcessor) | `-(language::true_kw:ValueProcessor) - `-(language::or_op:BinaryExpressionProcessor<language::or_op, bool, bool>) - +-(language::or_op:BinaryExpressionProcessor<language::or_op, bool, bool>) + `-(language::or_op:BinaryExpressionProcessor<language::or_op, bool, bool, bool>) + +-(language::or_op:BinaryExpressionProcessor<language::or_op, bool, bool, bool>) | +-(language::false_kw:ValueProcessor) | `-(language::name:b:NameProcessor) `-(language::true_kw:ValueProcessor) @@ -749,11 +762,11 @@ false and b and true; std::string_view result = R"( (root:ASTNodeListProcessor) - +-(language::and_op:BinaryExpressionProcessor<language::and_op, bool, bool>) + +-(language::and_op:BinaryExpressionProcessor<language::and_op, bool, bool, bool>) | +-(language::name:b:NameProcessor) | `-(language::true_kw:ValueProcessor) - `-(language::and_op:BinaryExpressionProcessor<language::and_op, bool, bool>) - +-(language::and_op:BinaryExpressionProcessor<language::and_op, bool, bool>) + `-(language::and_op:BinaryExpressionProcessor<language::and_op, bool, bool, bool>) + +-(language::and_op:BinaryExpressionProcessor<language::and_op, bool, bool, bool>) | +-(language::false_kw:ValueProcessor) | `-(language::name:b:NameProcessor) `-(language::true_kw:ValueProcessor) @@ -775,11 +788,11 @@ false xor b xor true; std::string_view result = R"( (root:ASTNodeListProcessor) - +-(language::xor_op:BinaryExpressionProcessor<language::xor_op, bool, bool>) + +-(language::xor_op:BinaryExpressionProcessor<language::xor_op, bool, bool, bool>) | +-(language::name:b:NameProcessor) | `-(language::true_kw:ValueProcessor) - `-(language::xor_op:BinaryExpressionProcessor<language::xor_op, bool, bool>) - +-(language::xor_op:BinaryExpressionProcessor<language::xor_op, bool, bool>) + `-(language::xor_op:BinaryExpressionProcessor<language::xor_op, bool, bool, bool>) + +-(language::xor_op:BinaryExpressionProcessor<language::xor_op, bool, bool, bool>) | +-(language::false_kw:ValueProcessor) | `-(language::name:b:NameProcessor) `-(language::true_kw:ValueProcessor) @@ -800,7 +813,7 @@ b > true; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::greater_op:BinaryExpressionProcessor<language::greater_op, bool, bool>) + `-(language::greater_op:BinaryExpressionProcessor<language::greater_op, bool, bool, bool>) +-(language::name:b:NameProcessor) `-(language::true_kw:ValueProcessor) )"; @@ -818,7 +831,7 @@ n > m; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::greater_op:BinaryExpressionProcessor<language::greater_op, unsigned long, unsigned long>) + `-(language::greater_op:BinaryExpressionProcessor<language::greater_op, bool, unsigned long, unsigned long>) +-(language::name:n:NameProcessor) `-(language::name:m:NameProcessor) )"; @@ -835,7 +848,7 @@ a > 3; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::greater_op:BinaryExpressionProcessor<language::greater_op, long, long>) + `-(language::greater_op:BinaryExpressionProcessor<language::greater_op, bool, long, long>) +-(language::name:a:NameProcessor) `-(language::integer:3:ValueProcessor) )"; @@ -851,7 +864,7 @@ a > 3; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::greater_op:BinaryExpressionProcessor<language::greater_op, double, double>) + `-(language::greater_op:BinaryExpressionProcessor<language::greater_op, bool, double, double>) +-(language::real:2.3:ValueProcessor) `-(language::real:1.2:ValueProcessor) )"; @@ -871,7 +884,7 @@ b < true; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, bool, bool>) + `-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, bool, bool, bool>) +-(language::name:b:NameProcessor) `-(language::true_kw:ValueProcessor) )"; @@ -889,7 +902,7 @@ n < m; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, unsigned long, unsigned long>) + `-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, bool, unsigned long, unsigned long>) +-(language::name:n:NameProcessor) `-(language::name:m:NameProcessor) )"; @@ -906,7 +919,7 @@ a < 3; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, long, long>) + `-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, bool, long, long>) +-(language::name:a:NameProcessor) `-(language::integer:3:ValueProcessor) )"; @@ -922,7 +935,7 @@ a < 3; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, double, double>) + `-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, bool, double, double>) +-(language::real:2.3:ValueProcessor) `-(language::real:1.2:ValueProcessor) )"; @@ -941,7 +954,7 @@ b >= true; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::greater_or_eq_op:BinaryExpressionProcessor<language::greater_or_eq_op, bool, bool>) + `-(language::greater_or_eq_op:BinaryExpressionProcessor<language::greater_or_eq_op, bool, bool, bool>) +-(language::name:b:NameProcessor) `-(language::true_kw:ValueProcessor) )"; @@ -959,7 +972,7 @@ n >= m; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::greater_or_eq_op:BinaryExpressionProcessor<language::greater_or_eq_op, unsigned long, unsigned long>) + `-(language::greater_or_eq_op:BinaryExpressionProcessor<language::greater_or_eq_op, bool, unsigned long, unsigned long>) +-(language::name:n:NameProcessor) `-(language::name:m:NameProcessor) )"; @@ -976,7 +989,7 @@ a >= 3; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::greater_or_eq_op:BinaryExpressionProcessor<language::greater_or_eq_op, long, long>) + `-(language::greater_or_eq_op:BinaryExpressionProcessor<language::greater_or_eq_op, bool, long, long>) +-(language::name:a:NameProcessor) `-(language::integer:3:ValueProcessor) )"; @@ -992,7 +1005,7 @@ a >= 3; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::greater_or_eq_op:BinaryExpressionProcessor<language::greater_or_eq_op, double, double>) + `-(language::greater_or_eq_op:BinaryExpressionProcessor<language::greater_or_eq_op, bool, double, double>) +-(language::real:2.3:ValueProcessor) `-(language::real:1.2:ValueProcessor) )"; @@ -1012,7 +1025,7 @@ b <= true; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::lesser_or_eq_op:BinaryExpressionProcessor<language::lesser_or_eq_op, bool, bool>) + `-(language::lesser_or_eq_op:BinaryExpressionProcessor<language::lesser_or_eq_op, bool, bool, bool>) +-(language::name:b:NameProcessor) `-(language::true_kw:ValueProcessor) )"; @@ -1030,7 +1043,7 @@ n <= m; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::lesser_or_eq_op:BinaryExpressionProcessor<language::lesser_or_eq_op, unsigned long, unsigned long>) + `-(language::lesser_or_eq_op:BinaryExpressionProcessor<language::lesser_or_eq_op, bool, unsigned long, unsigned long>) +-(language::name:n:NameProcessor) `-(language::name:m:NameProcessor) )"; @@ -1047,7 +1060,7 @@ a <= 3; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::lesser_or_eq_op:BinaryExpressionProcessor<language::lesser_or_eq_op, long, long>) + `-(language::lesser_or_eq_op:BinaryExpressionProcessor<language::lesser_or_eq_op, bool, long, long>) +-(language::name:a:NameProcessor) `-(language::integer:3:ValueProcessor) )"; @@ -1063,7 +1076,7 @@ a <= 3; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::lesser_or_eq_op:BinaryExpressionProcessor<language::lesser_or_eq_op, double, double>) + `-(language::lesser_or_eq_op:BinaryExpressionProcessor<language::lesser_or_eq_op, bool, double, double>) +-(language::real:2.3:ValueProcessor) `-(language::real:1.2:ValueProcessor) )"; @@ -1083,7 +1096,7 @@ b == true; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, bool, bool>) + `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, bool, bool, bool>) +-(language::name:b:NameProcessor) `-(language::true_kw:ValueProcessor) )"; @@ -1101,7 +1114,7 @@ n == m; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, unsigned long, unsigned long>) + `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, bool, unsigned long, unsigned long>) +-(language::name:n:NameProcessor) `-(language::name:m:NameProcessor) )"; @@ -1118,7 +1131,7 @@ a == 3; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, long, long>) + `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, bool, long, long>) +-(language::name:a:NameProcessor) `-(language::integer:3:ValueProcessor) )"; @@ -1134,7 +1147,7 @@ a == 3; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, double, double>) + `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, bool, double, double>) +-(language::real:2.3:ValueProcessor) `-(language::real:1.2:ValueProcessor) )"; @@ -1152,7 +1165,7 @@ a == 3; std::string result = R"( (root:ASTNodeListProcessor) - `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, )" + + `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, bool, )" + string_name + ", " + string_name + R"( >) +-(language::literal:"foo":ValueProcessor) `-(language::literal:"bar":ValueProcessor) @@ -1177,7 +1190,7 @@ x==y; +-(language::eq_op:AffectationProcessor<language::eq_op, TinyVector<1ul, double>, long>) | +-(language::name:y:NameProcessor) | `-(language::integer:2:ValueProcessor) - `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, TinyVector<1ul, double>, TinyVector<1ul, double> >) + `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, bool, TinyVector<1ul, double>, TinyVector<1ul, double> >) +-(language::name:x:NameProcessor) `-(language::name:y:NameProcessor) )"; @@ -1205,7 +1218,7 @@ x==y; | `-(language::expression_list:ASTNodeExpressionListProcessor) | +-(language::real:0.3:ValueProcessor) | `-(language::real:0.7:ValueProcessor) - `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, TinyVector<2ul, double>, TinyVector<2ul, double> >) + `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, bool, TinyVector<2ul, double>, TinyVector<2ul, double> >) +-(language::name:x:NameProcessor) `-(language::name:y:NameProcessor) )"; @@ -1235,7 +1248,7 @@ x==y; | +-(language::integer:4:ValueProcessor) | +-(language::integer:3:ValueProcessor) | `-(language::integer:2:ValueProcessor) - `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, TinyVector<3ul, double>, TinyVector<3ul, double> >) + `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, bool, TinyVector<3ul, double>, TinyVector<3ul, double> >) +-(language::name:x:NameProcessor) `-(language::name:y:NameProcessor) )"; @@ -1255,7 +1268,7 @@ b != true; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, bool, bool>) + `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, bool, bool, bool>) +-(language::name:b:NameProcessor) `-(language::true_kw:ValueProcessor) )"; @@ -1273,7 +1286,7 @@ n != m; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, unsigned long, unsigned long>) + `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, bool, unsigned long, unsigned long>) +-(language::name:n:NameProcessor) `-(language::name:m:NameProcessor) )"; @@ -1290,7 +1303,7 @@ a != 3; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, long, long>) + `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, bool, long, long>) +-(language::name:a:NameProcessor) `-(language::integer:3:ValueProcessor) )"; @@ -1306,7 +1319,7 @@ a != 3; std::string_view result = R"( (root:ASTNodeListProcessor) - `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, double, double>) + `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, bool, double, double>) +-(language::real:2.3:ValueProcessor) `-(language::real:1.2:ValueProcessor) )"; @@ -1330,7 +1343,7 @@ x!=y; +-(language::eq_op:AffectationProcessor<language::eq_op, TinyVector<1ul, double>, long>) | +-(language::name:y:NameProcessor) | `-(language::integer:2:ValueProcessor) - `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, TinyVector<1ul, double>, TinyVector<1ul, double> >) + `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, bool, TinyVector<1ul, double>, TinyVector<1ul, double> >) +-(language::name:x:NameProcessor) `-(language::name:y:NameProcessor) )"; @@ -1358,7 +1371,7 @@ x!=y; | `-(language::expression_list:ASTNodeExpressionListProcessor) | +-(language::real:0.3:ValueProcessor) | `-(language::real:0.7:ValueProcessor) - `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, TinyVector<2ul, double>, TinyVector<2ul, double> >) + `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, bool, TinyVector<2ul, double>, TinyVector<2ul, double> >) +-(language::name:x:NameProcessor) `-(language::name:y:NameProcessor) )"; @@ -1388,7 +1401,7 @@ x!=y; | +-(language::integer:4:ValueProcessor) | +-(language::integer:3:ValueProcessor) | `-(language::integer:2:ValueProcessor) - `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, TinyVector<3ul, double>, TinyVector<3ul, double> >) + `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, bool, TinyVector<3ul, double>, TinyVector<3ul, double> >) +-(language::name:x:NameProcessor) `-(language::name:y:NameProcessor) )"; @@ -1406,7 +1419,7 @@ x!=y; std::string result = R"( (root:ASTNodeListProcessor) - `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, )" + + `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, bool, )" + string_name + ", " + string_name + R"( >) +-(language::literal:"foo":ValueProcessor) `-(language::literal:"bar":ValueProcessor) @@ -1422,6 +1435,11 @@ x!=y; SECTION("Invalid binary operator type") { auto ast = std::make_unique<ASTNode>(); + ast->set_type<language::ignored>(); + ast->children.emplace_back(std::make_unique<ASTNode>()); + ast->children.emplace_back(std::make_unique<ASTNode>()); + ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); + ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "unexpected error: undefined binary operator"); } @@ -1437,7 +1455,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: void * Z"); } SECTION("left string multiply") @@ -1449,7 +1467,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: string * Z"); } SECTION("right string multiply") @@ -1461,7 +1479,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: Z * string"); } SECTION("lhs bad divide") @@ -1473,7 +1491,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: void / Z"); } SECTION("left string divide") @@ -1485,7 +1503,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: string / Z"); } SECTION("right string divide") @@ -1497,7 +1515,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: Z / string"); } SECTION("lhs bad plus") @@ -1509,7 +1527,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: void + Z"); } SECTION("left string plus bad rhs") @@ -1521,7 +1539,8 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: string + void"); } SECTION("right string plus") @@ -1533,7 +1552,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: Z + string"); } SECTION("lhs bad minus") @@ -1545,7 +1564,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: void - Z"); } SECTION("left string minus") @@ -1557,7 +1576,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: string - Z"); } SECTION("right string minus") @@ -1569,7 +1588,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: Z - string"); } SECTION("lhs bad or") @@ -1581,7 +1600,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: void or Z"); } SECTION("left string or") @@ -1593,7 +1612,8 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: string or Z"); } SECTION("right string or") @@ -1605,7 +1625,8 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: Z or string"); } SECTION("lhs bad and") @@ -1617,7 +1638,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: void and Z"); } SECTION("left string and") @@ -1629,7 +1650,8 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: string and Z"); } SECTION("right string and") @@ -1641,7 +1663,8 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: Z and string"); } SECTION("lhs bad xor") @@ -1653,7 +1676,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: void xor Z"); } SECTION("left string xor") @@ -1665,7 +1688,8 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: string xor Z"); } SECTION("right string xor") @@ -1677,7 +1701,8 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: Z xor string"); } SECTION("lhs bad >") @@ -1689,7 +1714,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: void > Z"); } SECTION("left string >") @@ -1701,7 +1726,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: string > Z"); } SECTION("right string >") @@ -1713,7 +1738,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: Z > string"); } SECTION("lhs bad <") @@ -1725,7 +1750,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: void < Z"); } SECTION("left string <") @@ -1737,7 +1762,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: string < Z"); } SECTION("right string <") @@ -1749,7 +1774,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: Z < string"); } SECTION("lhs bad >=") @@ -1761,7 +1786,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: void >= Z"); } SECTION("left string >=") @@ -1773,7 +1798,8 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: string >= Z"); } SECTION("right string >=") @@ -1785,7 +1811,8 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: Z >= string"); } SECTION("lhs bad <=") @@ -1797,7 +1824,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: void <= Z"); } SECTION("left string <=") @@ -1809,7 +1836,8 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: string <= Z"); } SECTION("right string <=") @@ -1821,7 +1849,8 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: Z <= string"); } SECTION("lhs bad ==") @@ -1833,7 +1862,7 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: void == Z"); } SECTION("left string ==") @@ -1845,7 +1874,8 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: string == Z"); } SECTION("right string ==") @@ -1857,7 +1887,8 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: Z == string"); } SECTION("lhs bad !=") @@ -1869,10 +1900,10 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined binary operator type: void != Z"); } - SECTION("left string ==") + SECTION("left string !=") { auto ast = std::make_unique<ASTNode>(); ast->set_type<language::not_eq_op>(); @@ -1881,10 +1912,11 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: string != Z"); } - SECTION("right string ==") + SECTION("right string !=") { auto ast = std::make_unique<ASTNode>(); ast->set_type<language::not_eq_op>(); @@ -1893,7 +1925,8 @@ x!=y; ast->children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); ast->children[1]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); - REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, "undefined operand type for binary operator"); + REQUIRE_THROWS_WITH(ASTNodeBinaryOperatorExpressionBuilder{*ast}, + "undefined binary operator type: Z != string"); } } @@ -1907,7 +1940,10 @@ let y : R^1, y = 0; x > y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^1 and R^1)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^1 >= R^1") @@ -1918,7 +1954,10 @@ let y : R^1, y = 0; x >= y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^1 and R^1)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^1 < R^1") @@ -1929,7 +1968,10 @@ let y : R^1, y = 0; x < y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^1 and R^1)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^1 <= R^1") @@ -1940,7 +1982,10 @@ let y : R^1, y = 1; x <= y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^1 and R^1)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^1 * R^1") @@ -1951,7 +1996,10 @@ let y : R^1, y = 0; x * y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^1 and R^1)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^1 / R^1") @@ -1962,7 +2010,10 @@ let y : R^1, y = 0; x / y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^1 and R^1)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^2 > R^2") @@ -1973,7 +2024,10 @@ let y : R^2, y = 0; x > y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^2 and R^2)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^2 >= R^2") @@ -1984,7 +2038,10 @@ let y : R^2, y = 0; x >= y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^2 and R^2)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^2 < R^2") @@ -1995,7 +2052,10 @@ let y : R^2, y = 0; x < y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^2 and R^2)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^2 <= R^2") @@ -2006,7 +2066,10 @@ let y : R^2, y = 0; x <= y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^2 and R^2)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^2 * R^2") @@ -2017,7 +2080,10 @@ let y : R^2, y = 0; x * y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^2 and R^2)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^2 / R^2") @@ -2028,7 +2094,10 @@ let y : R^2, y = 0; x / y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^2 and R^2)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^3 > R^3") @@ -2039,7 +2108,10 @@ let y : R^3, y = 0; x > y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^3 and R^3)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^3 >= R^3") @@ -2050,7 +2122,10 @@ let y : R^3, y = 0; x >= y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^3 and R^3)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^3 < R^3") @@ -2061,7 +2136,10 @@ let y : R^3, y = 0; x < y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^3 and R^3)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^3 <= R^3") @@ -2072,7 +2150,10 @@ let y : R^3, y = 0; x <= y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^3 and R^3)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^3 * R^3") @@ -2083,7 +2164,10 @@ let y : R^3, y = 0; x * y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^3 and R^3)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("invalid operator R^3 / R^3") @@ -2094,7 +2178,10 @@ let y : R^3, y = 0; x / y; )"; - REQUIRE_AST_THROWS_WITH(data, "invalid binary operator"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^3 and R^3)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } } @@ -2108,7 +2195,10 @@ let y : R^1, y = 0; x + y; )"; - REQUIRE_AST_THROWS_WITH(data, "incompatible dimensions of operands"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^3 and R^1)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("incompatible operand dimensions") @@ -2119,7 +2209,10 @@ let y : R^2, y = 0; x - y; )"; - REQUIRE_AST_THROWS_WITH(data, "incompatible dimensions of operands"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^1 and R^2)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("incompatible operand dimensions") @@ -2130,7 +2223,10 @@ let y : R^2, y = 0; x == y; )"; - REQUIRE_AST_THROWS_WITH(data, "incompatible dimensions of operands"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^3 and R^2)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } SECTION("incompatible operand dimensions") @@ -2141,7 +2237,10 @@ let y : R^2, y = 0; x != y; )"; - REQUIRE_AST_THROWS_WITH(data, "incompatible dimensions of operands"); + const std::string error_mesh = R"(undefined binary operator +note: incompatible operand types R^1 and R^2)"; + + REQUIRE_AST_THROWS_WITH(data, error_mesh); } } } diff --git a/tests/test_ASTNodeDataType.cpp b/tests/test_ASTNodeDataType.cpp index 3d4ea9b6954363cdd9007679e425d5f4f4c74c36..2e6e9afb4715b86c67fa2511e7472418e912f8e8 100644 --- a/tests/test_ASTNodeDataType.cpp +++ b/tests/test_ASTNodeDataType.cpp @@ -2,7 +2,7 @@ #include <language/PEGGrammar.hpp> #include <language/ast/ASTNode.hpp> -#include <language/ast/ASTNodeDataType.hpp> +#include <language/utils/ASTNodeDataType.hpp> namespace language { diff --git a/tests/test_ASTNodeDataTypeBuilder.cpp b/tests/test_ASTNodeDataTypeBuilder.cpp index dd206297d82c52bbbf7dda7e304d6b3966524d4f..6c37b1afe9a7c411e2c1643ac1bd1e3cb1a72aeb 100644 --- a/tests/test_ASTNodeDataTypeBuilder.cpp +++ b/tests/test_ASTNodeDataTypeBuilder.cpp @@ -894,7 +894,7 @@ x = f(x); | `-(language::expression_list:list(Z*Z)) | +-(language::integer:1:Z) | `-(language::integer:2:Z) - `-(language::eq_op:R^2) + `-(language::eq_op:void) +-(language::name:x:R^2) `-(language::function_evaluation:R^2) +-(language::name:f:function) @@ -1285,7 +1285,7 @@ a = 1; +-(language::var_declaration:void) | +-(language::name:a:N) | `-(language::N_set:typename(N)) - `-(language::eq_op:N) + `-(language::eq_op:void) +-(language::name:a:N) `-(language::integer:1:Z) )"; @@ -1307,7 +1307,7 @@ a *= 1.2; | +-(language::N_set:typename(N)) | +-(language::name:a:N) | `-(language::integer:1:Z) - `-(language::multiplyeq_op:N) + `-(language::multiplyeq_op:void) +-(language::name:a:N) `-(language::real:1.2:R) )"; @@ -1329,7 +1329,7 @@ a /= 2; | +-(language::R_set:typename(R)) | +-(language::name:a:R) | `-(language::integer:3:Z) - `-(language::divideeq_op:R) + `-(language::divideeq_op:void) +-(language::name:a:R) `-(language::integer:2:Z) )"; @@ -1351,7 +1351,7 @@ a += 2; | +-(language::Z_set:typename(Z)) | +-(language::name:a:Z) | `-(language::integer:3:Z) - `-(language::pluseq_op:Z) + `-(language::pluseq_op:void) +-(language::name:a:Z) `-(language::integer:2:Z) )"; @@ -1373,7 +1373,7 @@ a -= 2; | +-(language::Z_set:typename(Z)) | +-(language::name:a:Z) | `-(language::integer:1:Z) - `-(language::minuseq_op:Z) + `-(language::minuseq_op:void) +-(language::name:a:Z) `-(language::integer:2:Z) )"; @@ -1416,10 +1416,10 @@ for (let i:Z, i=0; i<3; i += 1) { i += 2; } +-(language::lesser_op:B) | +-(language::name:i:Z) | `-(language::integer:3:Z) - +-(language::pluseq_op:Z) + +-(language::pluseq_op:void) | +-(language::name:i:Z) | `-(language::integer:1:Z) - `-(language::pluseq_op:Z) + `-(language::pluseq_op:void) +-(language::name:i:Z) `-(language::integer:2:Z) )"; diff --git a/tests/test_ASTNodeExpressionBuilder.cpp b/tests/test_ASTNodeExpressionBuilder.cpp index 956b5a2527e8e80bb1cef2287f9b2c72a16768aa..3b09a0bb554e6692fe1f741229e9ea43725782af 100644 --- a/tests/test_ASTNodeExpressionBuilder.cpp +++ b/tests/test_ASTNodeExpressionBuilder.cpp @@ -373,7 +373,10 @@ let n:N; SECTION("unary not") { - CHECK_AST_THROWS_WITH(R"(not 1;)", "invalid implicit conversion: Z -> B"); + std::string error_message = R"(undefined unary operator +note: unexpected operand type Z)"; + + CHECK_AST_THROWS_WITH(R"(not 1;)", error_message); } SECTION("pre-increment operator") @@ -486,7 +489,7 @@ x[2]; std::string result = R"( (root:ASTNodeListProcessor) - `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, long, long>) + `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, long, long, long>) +-(language::integer:1:ValueProcessor) `-(language::integer:2:ValueProcessor) )"; @@ -502,7 +505,7 @@ x[2]; std::string result = R"( (root:ASTNodeListProcessor) - `-(language::divide_op:BinaryExpressionProcessor<language::divide_op, long, long>) + `-(language::divide_op:BinaryExpressionProcessor<language::divide_op, long, long, long>) +-(language::integer:1:ValueProcessor) `-(language::integer:2:ValueProcessor) )"; @@ -518,7 +521,7 @@ x[2]; std::string result = R"( (root:ASTNodeListProcessor) - `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, long, long>) + `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, long, long, long>) +-(language::integer:1:ValueProcessor) `-(language::integer:2:ValueProcessor) )"; @@ -534,7 +537,7 @@ x[2]; std::string result = R"( (root:ASTNodeListProcessor) - `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, long, long>) + `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, long, long, long>) +-(language::integer:1:ValueProcessor) `-(language::integer:2:ValueProcessor) )"; @@ -544,17 +547,26 @@ x[2]; SECTION("or") { - CHECK_AST_THROWS_WITH(R"(1 or 2;)", "invalid implicit conversion: Z -> B"); + const std::string error_message = R"(undefined binary operator +note: incompatible operand types Z and Z)"; + + CHECK_AST_THROWS_WITH(R"(1 or 2;)", error_message); } SECTION("and") { - CHECK_AST_THROWS_WITH(R"(1 and 2;)", "invalid implicit conversion: Z -> B"); + const std::string error_message = R"(undefined binary operator +note: incompatible operand types Z and Z)"; + + CHECK_AST_THROWS_WITH(R"(1 and 2;)", error_message); } SECTION("xor") { - CHECK_AST_THROWS_WITH(R"(1 xor 2;)", "invalid implicit conversion: Z -> B"); + const std::string error_message = R"(undefined binary operator +note: incompatible operand types Z and Z)"; + + CHECK_AST_THROWS_WITH(R"(1 xor 2;)", error_message); } SECTION("lesser") @@ -565,7 +577,7 @@ x[2]; std::string result = R"( (root:ASTNodeListProcessor) - `-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, long, long>) + `-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, bool, long, long>) +-(language::integer:1:ValueProcessor) `-(language::integer:2:ValueProcessor) )"; @@ -581,7 +593,7 @@ x[2]; std::string result = R"( (root:ASTNodeListProcessor) - `-(language::lesser_or_eq_op:BinaryExpressionProcessor<language::lesser_or_eq_op, long, long>) + `-(language::lesser_or_eq_op:BinaryExpressionProcessor<language::lesser_or_eq_op, bool, long, long>) +-(language::integer:1:ValueProcessor) `-(language::integer:2:ValueProcessor) )"; @@ -597,7 +609,7 @@ x[2]; std::string result = R"( (root:ASTNodeListProcessor) - `-(language::greater_op:BinaryExpressionProcessor<language::greater_op, long, long>) + `-(language::greater_op:BinaryExpressionProcessor<language::greater_op, bool, long, long>) +-(language::integer:1:ValueProcessor) `-(language::integer:2:ValueProcessor) )"; @@ -613,7 +625,7 @@ x[2]; std::string result = R"( (root:ASTNodeListProcessor) - `-(language::greater_or_eq_op:BinaryExpressionProcessor<language::greater_or_eq_op, long, long>) + `-(language::greater_or_eq_op:BinaryExpressionProcessor<language::greater_or_eq_op, bool, long, long>) +-(language::integer:1:ValueProcessor) `-(language::integer:2:ValueProcessor) )"; @@ -629,7 +641,7 @@ x[2]; std::string result = R"( (root:ASTNodeListProcessor) - `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, long, long>) + `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, bool, long, long>) +-(language::integer:1:ValueProcessor) `-(language::integer:2:ValueProcessor) )"; @@ -645,7 +657,7 @@ x[2]; std::string result = R"( (root:ASTNodeListProcessor) - `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, long, long>) + `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, bool, long, long>) +-(language::integer:1:ValueProcessor) `-(language::integer:2:ValueProcessor) )"; @@ -763,7 +775,7 @@ for(let i:N, i=0; i<10; ++i); +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>) | +-(language::name:i:NameProcessor) | `-(language::integer:0:ValueProcessor) - +-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, unsigned long, long>) + +-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, bool, unsigned long, long>) | +-(language::name:i:NameProcessor) | `-(language::integer:10:ValueProcessor) +-(language::unary_plusplus:IncDecExpressionProcessor<language::unary_plusplus, unsigned long>) @@ -788,7 +800,7 @@ for(; i<10; ++i); | `-(language::integer:0:ValueProcessor) `-(language::for_statement:ForProcessor) +-(language::for_init:FakeProcessor) - +-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, unsigned long, long>) + +-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, bool, unsigned long, long>) | +-(language::name:i:NameProcessor) | `-(language::integer:10:ValueProcessor) +-(language::unary_plusplus:IncDecExpressionProcessor<language::unary_plusplus, unsigned long>) @@ -832,7 +844,7 @@ for(let i:N, i=0; i<10;); +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>) | +-(language::name:i:NameProcessor) | `-(language::integer:0:ValueProcessor) - +-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, unsigned long, long>) + +-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, bool, unsigned long, long>) | +-(language::name:i:NameProcessor) | `-(language::integer:10:ValueProcessor) +-(language::for_post:FakeProcessor) diff --git a/tests/test_ASTNodeIncDecExpressionBuilder.cpp b/tests/test_ASTNodeIncDecExpressionBuilder.cpp index 627d6f96606a13a97907d01d314339f846049892..2b64fcd03c2aeedb6ab3902cf374791205344815 100644 --- a/tests/test_ASTNodeIncDecExpressionBuilder.cpp +++ b/tests/test_ASTNodeIncDecExpressionBuilder.cpp @@ -8,6 +8,7 @@ #include <language/ast/ASTNodeTypeCleaner.hpp> #include <language/ast/ASTSymbolTableBuilder.hpp> #include <language/utils/ASTPrinter.hpp> +#include <language/utils/OperatorRepository.hpp> #include <utils/Demangle.hpp> #include <pegtl/string_input.hpp> @@ -299,11 +300,11 @@ x--; SECTION("Errors") { - SECTION("Invalid operator type") + SECTION("Undefined operator") { - auto ast = std::make_unique<ASTNode>(); - REQUIRE_THROWS_WITH(ASTNodeIncDecExpressionBuilder{*ast}, - "unexpected error: undefined increment/decrement operator"); + auto& operator_repository = OperatorRepository::instance(); + auto optional_value_type = operator_repository.getIncDecOperatorValueType("string ++"); + REQUIRE(not optional_value_type.has_value()); } SECTION("Invalid operand type") @@ -314,7 +315,8 @@ x--; ast->children.emplace_back(std::make_unique<ASTNode>()); - REQUIRE_THROWS_WITH(ASTNodeIncDecExpressionBuilder{*ast}, "invalid operand type for unary operator"); + REQUIRE_THROWS_WITH(ASTNodeIncDecExpressionBuilder{*ast}, + "invalid operand type. ++/-- operators only apply to variables"); } SECTION("Invalid data type") @@ -325,8 +327,7 @@ x--; ast->children.emplace_back(std::make_unique<ASTNode>()); ast->children[0]->set_type<language::name>(); - REQUIRE_THROWS_WITH(ASTNodeIncDecExpressionBuilder{*ast}, - "unexpected error: undefined data type for unary operator"); + REQUIRE_THROWS_WITH(ASTNodeIncDecExpressionBuilder{*ast}, "undefined affectation type: ++ undefined"); } SECTION("Not allowed chained ++/--") @@ -337,7 +338,7 @@ x--; 1 ++ ++; )"; - std::string error_message = R"(chaining ++ or -- operators is not allowed)"; + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; DISALLOWED_CHAINED_AST(data, error_message) } @@ -348,7 +349,7 @@ x--; 1 ++ --; )"; - std::string error_message = R"(chaining ++ or -- operators is not allowed)"; + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; DISALLOWED_CHAINED_AST(data, error_message) } @@ -359,7 +360,7 @@ x--; 1 -- ++; )"; - std::string error_message = R"(chaining ++ or -- operators is not allowed)"; + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; DISALLOWED_CHAINED_AST(data, error_message) } @@ -370,7 +371,7 @@ x--; 1 -- --; )"; - std::string error_message = R"(chaining ++ or -- operators is not allowed)"; + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; DISALLOWED_CHAINED_AST(data, error_message) } @@ -381,7 +382,7 @@ x--; ++ ++ 1; )"; - std::string error_message = R"(chaining ++ or -- operators is not allowed)"; + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; DISALLOWED_CHAINED_AST(data, error_message) } @@ -392,7 +393,7 @@ x--; ++ -- 1; )"; - std::string error_message = R"(chaining ++ or -- operators is not allowed)"; + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; DISALLOWED_CHAINED_AST(data, error_message) } @@ -403,7 +404,7 @@ x--; -- ++ 1; )"; - std::string error_message = R"(chaining ++ or -- operators is not allowed)"; + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; DISALLOWED_CHAINED_AST(data, error_message) } @@ -414,7 +415,7 @@ x--; -- -- 1; )"; - std::string error_message = R"(chaining ++ or -- operators is not allowed)"; + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; DISALLOWED_CHAINED_AST(data, error_message) } @@ -425,7 +426,7 @@ x--; ++ 1 ++; )"; - std::string error_message = R"(chaining ++ or -- operators is not allowed)"; + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; DISALLOWED_CHAINED_AST(data, error_message) } @@ -436,7 +437,7 @@ x--; ++ 1 --; )"; - std::string error_message = R"(chaining ++ or -- operators is not allowed)"; + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; DISALLOWED_CHAINED_AST(data, error_message) } @@ -447,7 +448,7 @@ x--; -- 1 ++; )"; - std::string error_message = R"(chaining ++ or -- operators is not allowed)"; + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; DISALLOWED_CHAINED_AST(data, error_message) } @@ -458,7 +459,7 @@ x--; -- 1 --; )"; - std::string error_message = R"(chaining ++ or -- operators is not allowed)"; + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; DISALLOWED_CHAINED_AST(data, error_message) } diff --git a/tests/test_ASTNodeUnaryOperatorExpressionBuilder.cpp b/tests/test_ASTNodeUnaryOperatorExpressionBuilder.cpp index cc31b56706d9bdf952bcfdb5b4ab6e209e2be1df..2ebe22cab68dc735836054b58ca4382340e09030 100644 --- a/tests/test_ASTNodeUnaryOperatorExpressionBuilder.cpp +++ b/tests/test_ASTNodeUnaryOperatorExpressionBuilder.cpp @@ -191,35 +191,27 @@ not b; SECTION("Errors") { - SECTION("Invalid unary operator") - { - auto ast = std::make_unique<ASTNode>(); - - REQUIRE_THROWS_WITH(ASTNodeUnaryOperatorExpressionBuilder{*ast}, "unexpected error: undefined unary operator"); - } - - SECTION("Invalid unary operator") - { - auto ast = std::make_unique<ASTNode>(); - - REQUIRE_THROWS_WITH(ASTNodeUnaryOperatorExpressionBuilder{*ast}, "unexpected error: undefined unary operator"); - } - SECTION("Invalid value type for unary minus") { auto ast = std::make_unique<ASTNode>(); ast->set_type<language::unary_minus>(); ast->children.emplace_back(std::make_unique<ASTNode>()); - REQUIRE_THROWS_WITH(ASTNodeUnaryOperatorExpressionBuilder{*ast}, "undefined value type for unary operator"); + REQUIRE_THROWS_WITH(ASTNodeUnaryOperatorExpressionBuilder{*ast}, "undefined unary operator type: - undefined"); } SECTION("errors") { - CHECK_AST_THROWS_WITH(R"(let n:N; not n;)", "invalid implicit conversion: N -> B"); - CHECK_AST_THROWS_WITH(R"(not 2;)", "invalid implicit conversion: Z -> B"); - CHECK_AST_THROWS_WITH(R"(not -2.3;)", "invalid implicit conversion: R -> B"); - CHECK_AST_THROWS_WITH(R"(not "foo";)", "invalid implicit conversion: string -> B"); + auto error_message = [](std::string type_name) { + return std::string{R"(undefined unary operator +note: unexpected operand type )"} + + type_name; + }; + + CHECK_AST_THROWS_WITH(R"(let n:N; not n;)", error_message("N")); + CHECK_AST_THROWS_WITH(R"(not 2;)", error_message("Z")); + CHECK_AST_THROWS_WITH(R"(not -2.3;)", error_message("R")); + CHECK_AST_THROWS_WITH(R"(not "foo";)", error_message("string")); } SECTION("Invalid value type for unary not") @@ -228,18 +220,7 @@ not b; ast->set_type<language::unary_not>(); ast->children.emplace_back(std::make_unique<ASTNode>()); - REQUIRE_THROWS_WITH(ASTNodeUnaryOperatorExpressionBuilder{*ast}, "undefined value type for unary operator"); - } - - SECTION("Invalid data type for unary operator") - { - auto ast = std::make_unique<ASTNode>(); - ast->set_type<language::unary_minus>(); - ast->m_data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>(); - ast->children.emplace_back(std::make_unique<ASTNode>()); - - REQUIRE_THROWS_WITH(ASTNodeUnaryOperatorExpressionBuilder{*ast}, - "unexpected error: invalid operand type for unary operator"); + REQUIRE_THROWS_WITH(ASTNodeUnaryOperatorExpressionBuilder{*ast}, "undefined unary operator type: not undefined"); } } } diff --git a/tests/test_BinaryExpressionProcessor_logic.cpp b/tests/test_BinaryExpressionProcessor_logic.cpp index f53d8557cc48551a9abe630c3bbda43aed9ae366..a0d6c12e7cbef0e5e90dc1ed0ec6bb57a6a7d406 100644 --- a/tests/test_BinaryExpressionProcessor_logic.cpp +++ b/tests/test_BinaryExpressionProcessor_logic.cpp @@ -42,32 +42,121 @@ TEST_CASE("BinaryExpressionProcessor logic", "[language]") { SECTION("and") { - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(let n:N, n=1; n and true;)", "invalid implicit conversion: N -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(let n:N, n=2; false and n;)", "invalid implicit conversion: N -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(1 and true;)", "invalid implicit conversion: Z -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(false and 2;)", "invalid implicit conversion: Z -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(1.1 and true;)", "invalid implicit conversion: R -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(false and 2e-2;)", "invalid implicit conversion: R -> B"); + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types N and B)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(let n:N, n=1; n and true;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types B and N)"; + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(let n:N, n=2; false and n;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types Z and B)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(1 and true;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types B and Z)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(false and 2;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types R and B)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(1.1 and true;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types B and R)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(false and 2e-2;)", error_message); + } } SECTION("or") { - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(let n:N, n=1; n or true;)", "invalid implicit conversion: N -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(let n:N, n=2; false or n;)", "invalid implicit conversion: N -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(1 or true;)", "invalid implicit conversion: Z -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(false or 2;)", "invalid implicit conversion: Z -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(1.1 or true;)", "invalid implicit conversion: R -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(false or 2e-2;)", "invalid implicit conversion: R -> B"); + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types N and B)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(let n:N, n=1; n or true;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types B and N)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(let n:N, n=2; false or n;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types Z and B)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(1 or true;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types B and Z)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(false or 2;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types R and B)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(1.1 or true;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types B and R)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(false or 2e-2;)", error_message); + } } SECTION("xor") { - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(let n:N, n=1; n xor true;)", "invalid implicit conversion: N -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(let n:N, n=2; false xor n;)", "invalid implicit conversion: N -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(1 xor true;)", "invalid implicit conversion: Z -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(false xor 2;)", "invalid implicit conversion: Z -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(1.1 xor true;)", "invalid implicit conversion: R -> B"); - CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(false xor 2e-2;)", "invalid implicit conversion: R -> B"); + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types N and B)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(let n:N, n=1; n xor true;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types B and N)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(let n:N, n=2; false xor n;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types Z and B)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(1 xor true;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types B and Z)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(false xor 2;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types R and B)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(1.1 xor true;)", error_message); + } + { + const std::string error_message = R"(undefined binary operator +note: incompatible operand types B and R)"; + + CHECK_BINARY_EXPRESSION_THROWS_WITH(R"(false xor 2e-2;)", error_message); + } } } } diff --git a/tests/test_ConcatExpressionProcessor.cpp b/tests/test_ConcatExpressionProcessor.cpp index adc5f49e0360b2e1ea3e784ea83fae60cd157d69..57b68c4e7206c9eebd59942cddf2829f2fe236ab 100644 --- a/tests/test_ConcatExpressionProcessor.cpp +++ b/tests/test_ConcatExpressionProcessor.cpp @@ -71,4 +71,28 @@ TEST_CASE("ConcatExpressionProcessor", "[language]") { CHECK_CONCAT_EXPRESSION_RESULT(R"(let s:string, s = "foo_"; s = s+true;)", "s", std::string{"foo_1"}); } + + SECTION("string + R^1") + { + std::ostringstream os; + os << "foo_" << TinyVector<1>{1}; + + CHECK_CONCAT_EXPRESSION_RESULT(R"(let x:R^1, x = 1; let s:string, s = "foo_"; s = s+x;)", "s", os.str()); + } + + SECTION("string + R^2") + { + std::ostringstream os; + os << "foo_" << TinyVector<2>{1, 2}; + + CHECK_CONCAT_EXPRESSION_RESULT(R"(let x:R^2, x = (1,2); let s:string, s = "foo_"; s = s+x;)", "s", os.str()); + } + + SECTION("string + R^3") + { + std::ostringstream os; + os << "foo_" << TinyVector<3>{1, 2, 3}; + + CHECK_CONCAT_EXPRESSION_RESULT(R"(let x:R^3, x = (1,2,3); let s:string, s = "foo_"; s = s+x;)", "s", os.str()); + } } diff --git a/tests/test_IncDecExpressionProcessor.cpp b/tests/test_IncDecExpressionProcessor.cpp index ca13dbde2c33330515300b1fa19ba163a771c5f2..7525ca9ff5cf796ecbe3a183f570793b4ed614fb 100644 --- a/tests/test_IncDecExpressionProcessor.cpp +++ b/tests/test_IncDecExpressionProcessor.cpp @@ -40,6 +40,16 @@ REQUIRE(value == expected_value); \ } +#define CHECK_INCDEC_EXPRESSION_THROWS_WITH(data, error_message) \ + { \ + string_input input{data, "test.pgs"}; \ + auto ast = ASTBuilder::build(input); \ + \ + ASTSymbolTableBuilder{*ast}; \ + \ + REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast}, error_message); \ + } + // clazy:excludeall=non-pod-global-static TEST_CASE("IncDecExpressionProcessor", "[language]") @@ -127,4 +137,51 @@ TEST_CASE("IncDecExpressionProcessor", "[language]") CHECK_INC_DEC_RESULT(R"(let r:R, r = 2; let s:R, s = r--;)", "s", 2.); } } + + SECTION("errors") + { + SECTION("undefined pre -- operator") + { + auto error_message = [](std::string type_name) { + return std::string{R"(undefined increment/decrement operator +note: unexpected operand type )"} + + type_name; + }; + + CHECK_INCDEC_EXPRESSION_THROWS_WITH(R"(--"foo";)", error_message("string")); + } + + SECTION("undefined pre ++ operator") + { + auto error_message = [](std::string type_name) { + return std::string{R"(undefined increment/decrement operator +note: unexpected operand type )"} + + type_name; + }; + + CHECK_INCDEC_EXPRESSION_THROWS_WITH(R"(++true;)", error_message("B")); + } + + SECTION("undefined post -- operator") + { + auto error_message = [](std::string type_name) { + return std::string{R"(undefined increment/decrement operator +note: unexpected operand type )"} + + type_name; + }; + + CHECK_INCDEC_EXPRESSION_THROWS_WITH(R"(true--;)", error_message("B")); + } + + SECTION("undefined post ++ operator") + { + auto error_message = [](std::string type_name) { + return std::string{R"(undefined increment/decrement operator +note: unexpected operand type )"} + + type_name; + }; + + CHECK_INCDEC_EXPRESSION_THROWS_WITH(R"("bar"++;)", error_message("string")); + } + } } diff --git a/tests/test_Timer.cpp b/tests/test_Timer.cpp index adbbd69cbb8aaa4aaad8695b5ce5c0d1ec623f9e..bf85f15653eec2ba4bd6914873e6305cedaf4829 100644 --- a/tests/test_Timer.cpp +++ b/tests/test_Timer.cpp @@ -2,7 +2,9 @@ #include <utils/Timer.hpp> +#include <chrono> #include <sstream> +#include <thread> // clazy:excludeall=non-pod-global-static @@ -15,10 +17,12 @@ TEST_CASE("Timer", "[utils]") REQUIRE(t.status() == Timer::Status::running); double seconds = t.seconds(); + std::this_thread::sleep_for(std::chrono::microseconds(5)); REQUIRE(t.seconds() > seconds); t.start(); seconds = t.seconds(); + std::this_thread::sleep_for(std::chrono::microseconds(5)); REQUIRE(t.status() == Timer::Status::running); REQUIRE(t.seconds() > seconds); @@ -31,9 +35,9 @@ TEST_CASE("Timer", "[utils]") REQUIRE(t1.status() == Timer::Status::running); t1.pause(); - REQUIRE(t1.status() == Timer::Status::paused); const double seconds = t1.seconds(); - + REQUIRE(t1.status() == Timer::Status::paused); + std::this_thread::sleep_for(std::chrono::microseconds(5)); REQUIRE(t1.seconds() == seconds); std::stringstream os1; @@ -47,6 +51,7 @@ TEST_CASE("Timer", "[utils]") REQUIRE(t1.seconds() == t2.seconds()); t1.start(); + std::this_thread::sleep_for(std::chrono::microseconds(5)); REQUIRE(t1.status() == Timer::Status::running); REQUIRE(t1.seconds() > t2.seconds()); @@ -60,7 +65,9 @@ TEST_CASE("Timer", "[utils]") Timer t; REQUIRE(t.status() == Timer::Status::running); + std::this_thread::sleep_for(std::chrono::microseconds(5)); const double seconds = t.seconds(); + REQUIRE(seconds > 0); t.stop(); @@ -68,6 +75,7 @@ TEST_CASE("Timer", "[utils]") REQUIRE(t.seconds() == 0); t.start(); + std::this_thread::sleep_for(std::chrono::microseconds(5)); REQUIRE(t.status() == Timer::Status::running); REQUIRE(t.seconds() > 0); } diff --git a/tests/test_UnaryExpressionProcessor.cpp b/tests/test_UnaryExpressionProcessor.cpp index e933902adaefd968cc3036c8bbf007b29d054f39..b309d6dd13c0791a909ab30e164325ac7d365e00 100644 --- a/tests/test_UnaryExpressionProcessor.cpp +++ b/tests/test_UnaryExpressionProcessor.cpp @@ -68,12 +68,29 @@ TEST_CASE("UnaryExpressionProcessor", "[language]") SECTION("errors") { - SECTION("bad implicit conversions") + SECTION("undefined not operator") { - CHECK_UNARY_EXPRESSION_THROWS_WITH(R"(let n:N, n = 0; not n;)", "invalid implicit conversion: N -> B"); - CHECK_UNARY_EXPRESSION_THROWS_WITH(R"(not 1;)", "invalid implicit conversion: Z -> B"); - CHECK_UNARY_EXPRESSION_THROWS_WITH(R"(not 1.3;)", "invalid implicit conversion: R -> B"); - CHECK_UNARY_EXPRESSION_THROWS_WITH(R"(not "foo";)", "invalid implicit conversion: string -> B"); + auto error_message = [](std::string type_name) { + return std::string{R"(undefined unary operator +note: unexpected operand type )"} + + type_name; + }; + + CHECK_UNARY_EXPRESSION_THROWS_WITH(R"(let n:N, n = 0; not n;)", error_message("N")); + CHECK_UNARY_EXPRESSION_THROWS_WITH(R"(not 1;)", error_message("Z")); + CHECK_UNARY_EXPRESSION_THROWS_WITH(R"(not 1.3;)", error_message("R")); + CHECK_UNARY_EXPRESSION_THROWS_WITH(R"(not "foo";)", error_message("string")); + } + + SECTION("undefined unary minus operator") + { + auto error_message = [](std::string type_name) { + return std::string{R"(undefined unary operator +note: unexpected operand type )"} + + type_name; + }; + + CHECK_UNARY_EXPRESSION_THROWS_WITH(R"(-"foo";)", error_message("string")); } } } diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 74f695682992ad951c3b2c33e3c8c0f6b53b657a..b2703a5950eeabe8eea33ba61cab4fc2e2f9157a 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -4,6 +4,7 @@ #include <Kokkos_Core.hpp> #include <algebra/PETScWrapper.hpp> +#include <language/utils/OperatorRepository.hpp> #include <mesh/DiamondDualConnectivityManager.hpp> #include <mesh/DiamondDualMeshManager.hpp> #include <mesh/MeshDataManager.hpp> @@ -38,8 +39,12 @@ main(int argc, char* argv[]) MeshDataBaseForTests::create(); + OperatorRepository::create(); + result = session.run(); + OperatorRepository::destroy(); + MeshDataBaseForTests::destroy(); DiamondDualMeshManager::destroy();