From 34d6a933b43fdf6a1340b1d679c0233cd4b08ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com> Date: Tue, 17 Nov 2020 18:37:55 +0100 Subject: [PATCH] Change increment decrement operators expression builder One now use OperatorRepository --- .../ast/ASTNodeIncDecExpressionBuilder.cpp | 75 ++++++++----------- .../ASTNodeUnaryOperatorExpressionBuilder.cpp | 1 - .../utils/AffectationRegisterForB.hpp | 2 - .../utils/AffectationRegisterForN.hpp | 2 - .../utils/AffectationRegisterForR.hpp | 2 - .../utils/AffectationRegisterForR1.hpp | 2 - .../utils/AffectationRegisterForR2.hpp | 2 - .../utils/AffectationRegisterForR3.hpp | 2 - .../utils/AffectationRegisterForString.hpp | 2 - .../utils/AffectationRegisterForZ.hpp | 2 - src/language/utils/CMakeLists.txt | 3 + .../utils/IIncDecOperatorProcessorBuilder.hpp | 17 +++++ src/language/utils/IncDecOperatorMangler.hpp | 34 +++++++++ .../utils/IncDecOperatorProcessorBuilder.hpp | 24 ++++++ .../utils/IncDecOperatorRegisterForN.cpp | 58 ++++++++++++++ .../utils/IncDecOperatorRegisterForN.hpp | 16 ++++ .../utils/IncDecOperatorRegisterForR.cpp | 58 ++++++++++++++ .../utils/IncDecOperatorRegisterForR.hpp | 16 ++++ .../utils/IncDecOperatorRegisterForZ.cpp | 57 ++++++++++++++ .../utils/IncDecOperatorRegisterForZ.hpp | 16 ++++ src/language/utils/OperatorRepository.cpp | 8 ++ src/language/utils/OperatorRepository.hpp | 32 +++++++- .../utils/UnaryOperatorRegisterForB.hpp | 2 - .../utils/UnaryOperatorRegisterForN.hpp | 2 - .../utils/UnaryOperatorRegisterForR.hpp | 2 - .../utils/UnaryOperatorRegisterForR1.hpp | 2 - .../utils/UnaryOperatorRegisterForR2.hpp | 2 - .../utils/UnaryOperatorRegisterForR3.hpp | 2 - .../utils/UnaryOperatorRegisterForZ.hpp | 2 - tests/test_ASTNodeIncDecExpressionBuilder.cpp | 37 ++++----- 30 files changed, 383 insertions(+), 99 deletions(-) create mode 100644 src/language/utils/IIncDecOperatorProcessorBuilder.hpp create mode 100644 src/language/utils/IncDecOperatorMangler.hpp create mode 100644 src/language/utils/IncDecOperatorProcessorBuilder.hpp create mode 100644 src/language/utils/IncDecOperatorRegisterForN.cpp create mode 100644 src/language/utils/IncDecOperatorRegisterForN.hpp create mode 100644 src/language/utils/IncDecOperatorRegisterForR.cpp create mode 100644 src/language/utils/IncDecOperatorRegisterForR.hpp create mode 100644 src/language/utils/IncDecOperatorRegisterForZ.cpp create mode 100644 src/language/utils/IncDecOperatorRegisterForZ.hpp diff --git a/src/language/ast/ASTNodeIncDecExpressionBuilder.cpp b/src/language/ast/ASTNodeIncDecExpressionBuilder.cpp index 71e5c3c4b..c877d3ca2 100644 --- a/src/language/ast/ASTNodeIncDecExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeIncDecExpressionBuilder.cpp @@ -1,54 +1,45 @@ #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 { + throw ParseError("unexpected error: undefined inc/dec operator", std::vector{n.begin()}); } + }(); + + 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/ASTNodeUnaryOperatorExpressionBuilder.cpp b/src/language/ast/ASTNodeUnaryOperatorExpressionBuilder.cpp index 7781ebae6..bfba2e0f8 100644 --- a/src/language/ast/ASTNodeUnaryOperatorExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeUnaryOperatorExpressionBuilder.cpp @@ -1,7 +1,6 @@ #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> diff --git a/src/language/utils/AffectationRegisterForB.hpp b/src/language/utils/AffectationRegisterForB.hpp index 4064d4988..d6507ff7a 100644 --- a/src/language/utils/AffectationRegisterForB.hpp +++ b/src/language/utils/AffectationRegisterForB.hpp @@ -1,8 +1,6 @@ #ifndef AFFECTATION_REGISTER_FOR_B_HPP #define AFFECTATION_REGISTER_FOR_B_HPP -#include <language/utils/OperatorRepository.hpp> - class AffectationRegisterForB { public: diff --git a/src/language/utils/AffectationRegisterForN.hpp b/src/language/utils/AffectationRegisterForN.hpp index 56f7699e8..e97a652c0 100644 --- a/src/language/utils/AffectationRegisterForN.hpp +++ b/src/language/utils/AffectationRegisterForN.hpp @@ -1,8 +1,6 @@ #ifndef AFFECTATION_REGISTER_FOR_N_HPP #define AFFECTATION_REGISTER_FOR_N_HPP -#include <language/utils/OperatorRepository.hpp> - class AffectationRegisterForN { private: diff --git a/src/language/utils/AffectationRegisterForR.hpp b/src/language/utils/AffectationRegisterForR.hpp index 141a0d8ae..3a004a92a 100644 --- a/src/language/utils/AffectationRegisterForR.hpp +++ b/src/language/utils/AffectationRegisterForR.hpp @@ -1,8 +1,6 @@ #ifndef AFFECTATION_REGISTER_FOR_R_HPP #define AFFECTATION_REGISTER_FOR_R_HPP -#include <language/utils/OperatorRepository.hpp> - class AffectationRegisterForR { private: diff --git a/src/language/utils/AffectationRegisterForR1.hpp b/src/language/utils/AffectationRegisterForR1.hpp index 04016bd67..27f263f74 100644 --- a/src/language/utils/AffectationRegisterForR1.hpp +++ b/src/language/utils/AffectationRegisterForR1.hpp @@ -1,8 +1,6 @@ #ifndef AFFECTATION_REGISTER_FOR_R1_HPP #define AFFECTATION_REGISTER_FOR_R1_HPP -#include <language/utils/OperatorRepository.hpp> - class AffectationRegisterForR1 { private: diff --git a/src/language/utils/AffectationRegisterForR2.hpp b/src/language/utils/AffectationRegisterForR2.hpp index 0c1c5c1fa..cc1fcc9ef 100644 --- a/src/language/utils/AffectationRegisterForR2.hpp +++ b/src/language/utils/AffectationRegisterForR2.hpp @@ -1,8 +1,6 @@ #ifndef AFFECTATION_REGISTER_FOR_R2_HPP #define AFFECTATION_REGISTER_FOR_R2_HPP -#include <language/utils/OperatorRepository.hpp> - class AffectationRegisterForR2 { private: diff --git a/src/language/utils/AffectationRegisterForR3.hpp b/src/language/utils/AffectationRegisterForR3.hpp index 09ae3f3e8..7eb551cdd 100644 --- a/src/language/utils/AffectationRegisterForR3.hpp +++ b/src/language/utils/AffectationRegisterForR3.hpp @@ -1,8 +1,6 @@ #ifndef AFFECTATION_REGISTER_FOR_R3_HPP #define AFFECTATION_REGISTER_FOR_R3_HPP -#include <language/utils/OperatorRepository.hpp> - class AffectationRegisterForR3 { private: diff --git a/src/language/utils/AffectationRegisterForString.hpp b/src/language/utils/AffectationRegisterForString.hpp index 2aa4b319b..b6b6a47d4 100644 --- a/src/language/utils/AffectationRegisterForString.hpp +++ b/src/language/utils/AffectationRegisterForString.hpp @@ -1,8 +1,6 @@ #ifndef AFFECTATION_REGISTER_FOR_STRING_HPP #define AFFECTATION_REGISTER_FOR_STRING_HPP -#include <language/utils/OperatorRepository.hpp> - class AffectationRegisterForString { private: diff --git a/src/language/utils/AffectationRegisterForZ.hpp b/src/language/utils/AffectationRegisterForZ.hpp index 2f13e10f6..a559c94fd 100644 --- a/src/language/utils/AffectationRegisterForZ.hpp +++ b/src/language/utils/AffectationRegisterForZ.hpp @@ -1,8 +1,6 @@ #ifndef AFFECTATION_REGISTER_FOR_Z_HPP #define AFFECTATION_REGISTER_FOR_Z_HPP -#include <language/utils/OperatorRepository.hpp> - class AffectationRegisterForZ { private: diff --git a/src/language/utils/CMakeLists.txt b/src/language/utils/CMakeLists.txt index e44c4f664..3efa30bc1 100644 --- a/src/language/utils/CMakeLists.txt +++ b/src/language/utils/CMakeLists.txt @@ -15,6 +15,9 @@ add_library(PugsLanguageUtils ASTPrinter.cpp DataVariant.cpp EmbeddedData.cpp + IncDecOperatorRegisterForN.cpp + IncDecOperatorRegisterForR.cpp + IncDecOperatorRegisterForZ.cpp OperatorRepository.cpp UnaryOperatorRegisterForB.cpp UnaryOperatorRegisterForN.cpp diff --git a/src/language/utils/IIncDecOperatorProcessorBuilder.hpp b/src/language/utils/IIncDecOperatorProcessorBuilder.hpp new file mode 100644 index 000000000..050bb60f3 --- /dev/null +++ b/src/language/utils/IIncDecOperatorProcessorBuilder.hpp @@ -0,0 +1,17 @@ +#ifndef I_INC_DEC_OPERATOR_PROCESSOR_BUILDER_HPP +#define I_INC_DEC_OPERATOR_PROCESSOR_BUILDER_HPP + +class ASTNode; +class INodeProcessor; + +#include <memory> + +class IIncDecOperatorProcessorBuilder +{ + public: + virtual std::unique_ptr<INodeProcessor> getNodeProcessor(ASTNode& node) const = 0; + + virtual ~IIncDecOperatorProcessorBuilder() = default; +}; + +#endif // I_INC_DEC_OPERATOR_PROCESSOR_BUILDER_HPP diff --git a/src/language/utils/IncDecOperatorMangler.hpp b/src/language/utils/IncDecOperatorMangler.hpp new file mode 100644 index 000000000..ed5a84ae4 --- /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 000000000..c3eeb10ba --- /dev/null +++ b/src/language/utils/IncDecOperatorProcessorBuilder.hpp @@ -0,0 +1,24 @@ +#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/IIncDecOperatorProcessorBuilder.hpp> + +#include <type_traits> + +template <typename OperatorT, typename DataT> +class IncDecOperatorProcessorBuilder final : public IIncDecOperatorProcessorBuilder +{ + public: + IncDecOperatorProcessorBuilder() = default; + + 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 000000000..8e6a6369f --- /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 000000000..c3e2682d8 --- /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 000000000..503175146 --- /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 000000000..5ede6b999 --- /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 000000000..5a0bc0faa --- /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 000000000..b4ab27770 --- /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 index 8bfcda61f..ba91ff3f6 100644 --- a/src/language/utils/OperatorRepository.cpp +++ b/src/language/utils/OperatorRepository.cpp @@ -9,6 +9,9 @@ #include <language/utils/AffectationRegisterForR3.hpp> #include <language/utils/AffectationRegisterForString.hpp> #include <language/utils/AffectationRegisterForZ.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> @@ -25,6 +28,7 @@ void OperatorRepository::reset() { m_affectation_builder_list.clear(); + m_inc_dec_operator_builder_list.clear(); m_unary_operator_builder_list.clear(); this->_initialize(); } @@ -57,6 +61,10 @@ OperatorRepository::_initialize() AffectationRegisterForR3{}; AffectationRegisterForString{}; + IncDecOperatorRegisterForN{}; + IncDecOperatorRegisterForR{}; + IncDecOperatorRegisterForZ{}; + UnaryOperatorRegisterForB{}; UnaryOperatorRegisterForN{}; UnaryOperatorRegisterForZ{}; diff --git a/src/language/utils/OperatorRepository.hpp b/src/language/utils/OperatorRepository.hpp index 7cc0ae241..ae6b2a984 100644 --- a/src/language/utils/OperatorRepository.hpp +++ b/src/language/utils/OperatorRepository.hpp @@ -5,7 +5,9 @@ #include <language/utils/ASTNodeDataType.hpp> #include <language/utils/AffectationMangler.hpp> #include <language/utils/IAffectationProcessorBuilder.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> @@ -16,6 +18,8 @@ class OperatorRepository { private: std::unordered_map<std::string, std::shared_ptr<const IAffectationProcessorBuilder>> m_affectation_builder_list; + std::unordered_map<std::string, std::shared_ptr<const IIncDecOperatorProcessorBuilder>> + m_inc_dec_operator_builder_list; std::unordered_map<std::string, std::shared_ptr<const IUnaryOperatorProcessorBuilder>> m_unary_operator_builder_list; void _initialize(); @@ -35,6 +39,16 @@ class OperatorRepository } } + template <typename OperatorTypeT, typename IncDecProcessorBuilderT> + void + addIncDecOperator(const ASTNodeDataType& operand, const std::shared_ptr<IncDecProcessorBuilderT>& processor_builder) + { + const std::string inc_dec_operator_type_name = incDecOperatorMangler<OperatorTypeT>(operand); + if (not m_inc_dec_operator_builder_list.try_emplace(inc_dec_operator_type_name, processor_builder).second) { + throw UnexpectedError(inc_dec_operator_type_name + " has already an entry"); + } + } + template <typename OperatorTypeT, typename UnaryProcessorBuilderT> void addUnaryOperator(const ASTNodeDataType& operand, const std::shared_ptr<UnaryProcessorBuilderT>& processor_builder) @@ -46,19 +60,29 @@ class OperatorRepository } std::optional<std::shared_ptr<const IAffectationProcessorBuilder>> - getAffectationProcessorBuilder(const std::string& affectation_name) const + getAffectationProcessorBuilder(const std::string& name) const { - auto&& processor_builder = m_affectation_builder_list.find(affectation_name); + auto&& processor_builder = m_affectation_builder_list.find(name); if (processor_builder != m_affectation_builder_list.end()) { return processor_builder->second; } return {}; } + 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; + } + return {}; + } + std::optional<std::shared_ptr<const IUnaryOperatorProcessorBuilder>> - getUnaryProcessorBuilder(const std::string& affectation_name) const + getUnaryProcessorBuilder(const std::string& name) const { - auto&& processor_builder = m_unary_operator_builder_list.find(affectation_name); + auto&& processor_builder = m_unary_operator_builder_list.find(name); if (processor_builder != m_unary_operator_builder_list.end()) { return processor_builder->second; } diff --git a/src/language/utils/UnaryOperatorRegisterForB.hpp b/src/language/utils/UnaryOperatorRegisterForB.hpp index 8d05dcd0a..49f1f8f4e 100644 --- a/src/language/utils/UnaryOperatorRegisterForB.hpp +++ b/src/language/utils/UnaryOperatorRegisterForB.hpp @@ -1,8 +1,6 @@ #ifndef UNARY_OPERATOR_REGISTER_FOR_B_HPP #define UNARY_OPERATOR_REGISTER_FOR_B_HPP -#include <language/utils/OperatorRepository.hpp> - class UnaryOperatorRegisterForB { private: diff --git a/src/language/utils/UnaryOperatorRegisterForN.hpp b/src/language/utils/UnaryOperatorRegisterForN.hpp index 331c3b0b0..d6a4ff62e 100644 --- a/src/language/utils/UnaryOperatorRegisterForN.hpp +++ b/src/language/utils/UnaryOperatorRegisterForN.hpp @@ -1,8 +1,6 @@ #ifndef UNARY_OPERATOR_REGISTER_FOR_N_HPP #define UNARY_OPERATOR_REGISTER_FOR_N_HPP -#include <language/utils/OperatorRepository.hpp> - class UnaryOperatorRegisterForN { private: diff --git a/src/language/utils/UnaryOperatorRegisterForR.hpp b/src/language/utils/UnaryOperatorRegisterForR.hpp index 53edd6af1..308fe6390 100644 --- a/src/language/utils/UnaryOperatorRegisterForR.hpp +++ b/src/language/utils/UnaryOperatorRegisterForR.hpp @@ -1,8 +1,6 @@ #ifndef UNARY_OPERATOR_REGISTER_FOR_R_HPP #define UNARY_OPERATOR_REGISTER_FOR_R_HPP -#include <language/utils/OperatorRepository.hpp> - class UnaryOperatorRegisterForR { private: diff --git a/src/language/utils/UnaryOperatorRegisterForR1.hpp b/src/language/utils/UnaryOperatorRegisterForR1.hpp index 4ce6b3de8..2e9d37781 100644 --- a/src/language/utils/UnaryOperatorRegisterForR1.hpp +++ b/src/language/utils/UnaryOperatorRegisterForR1.hpp @@ -1,8 +1,6 @@ #ifndef UNARY_OPERATOR_REGISTER_FOR_R1_HPP #define UNARY_OPERATOR_REGISTER_FOR_R1_HPP -#include <language/utils/OperatorRepository.hpp> - class UnaryOperatorRegisterForR1 { private: diff --git a/src/language/utils/UnaryOperatorRegisterForR2.hpp b/src/language/utils/UnaryOperatorRegisterForR2.hpp index 9b80db026..bcc78a9d5 100644 --- a/src/language/utils/UnaryOperatorRegisterForR2.hpp +++ b/src/language/utils/UnaryOperatorRegisterForR2.hpp @@ -1,8 +1,6 @@ #ifndef UNARY_OPERATOR_REGISTER_FOR_R2_HPP #define UNARY_OPERATOR_REGISTER_FOR_R2_HPP -#include <language/utils/OperatorRepository.hpp> - class UnaryOperatorRegisterForR2 { private: diff --git a/src/language/utils/UnaryOperatorRegisterForR3.hpp b/src/language/utils/UnaryOperatorRegisterForR3.hpp index 4c03d46ce..1f9710c0a 100644 --- a/src/language/utils/UnaryOperatorRegisterForR3.hpp +++ b/src/language/utils/UnaryOperatorRegisterForR3.hpp @@ -1,8 +1,6 @@ #ifndef UNARY_OPERATOR_REGISTER_FOR_R3_HPP #define UNARY_OPERATOR_REGISTER_FOR_R3_HPP -#include <language/utils/OperatorRepository.hpp> - class UnaryOperatorRegisterForR3 { private: diff --git a/src/language/utils/UnaryOperatorRegisterForZ.hpp b/src/language/utils/UnaryOperatorRegisterForZ.hpp index c4b3e0015..a0e3065b1 100644 --- a/src/language/utils/UnaryOperatorRegisterForZ.hpp +++ b/src/language/utils/UnaryOperatorRegisterForZ.hpp @@ -1,8 +1,6 @@ #ifndef UNARY_OPERATOR_REGISTER_FOR_Z_HPP #define UNARY_OPERATOR_REGISTER_FOR_Z_HPP -#include <language/utils/OperatorRepository.hpp> - class UnaryOperatorRegisterForZ { private: diff --git a/tests/test_ASTNodeIncDecExpressionBuilder.cpp b/tests/test_ASTNodeIncDecExpressionBuilder.cpp index 627d6f966..5dd0f4e37 100644 --- a/tests/test_ASTNodeIncDecExpressionBuilder.cpp +++ b/tests/test_ASTNodeIncDecExpressionBuilder.cpp @@ -299,13 +299,6 @@ x--; SECTION("Errors") { - SECTION("Invalid operator type") - { - auto ast = std::make_unique<ASTNode>(); - REQUIRE_THROWS_WITH(ASTNodeIncDecExpressionBuilder{*ast}, - "unexpected error: undefined increment/decrement operator"); - } - SECTION("Invalid operand type") { auto ast = std::make_unique<ASTNode>(); @@ -314,7 +307,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 +319,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 +330,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 +341,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 +352,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 +363,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 +374,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 +385,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 +396,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 +407,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 +418,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 +429,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 +440,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 +451,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) } -- GitLab