diff --git a/src/language/ast/ASTNodeIncDecExpressionBuilder.cpp b/src/language/ast/ASTNodeIncDecExpressionBuilder.cpp index 71e5c3c4b16d8535091b98cab298ff6624661508..c877d3ca2b8f728cf3370ec8bef2fc7aaf7a557e 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 7781ebae60671c84e8d77d7e99798d8107435a0b..bfba2e0f8325986ec08f32167fb162f60e758a57 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 4064d498890563e433c325696e447045e00b495d..d6507ff7a1edf0d48839924a8b3aa051ff441c09 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 56f7699e8874a93823a90c4a2078c1fac7a7eabd..e97a652c094635fbaa54b9b267c37f3a169367a0 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 141a0d8ae86f6c2e6355cd1ca74e801fc00bc0f0..3a004a92a276edad8dc52b015c2802aa4055aa11 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 04016bd6742c9635f2a3599d0852186364a81350..27f263f744dd1ae54aee2c16f3e530407e79fd77 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 0c1c5c1fa51f0282cfb4a63de15b4f0c015d8fd4..cc1fcc9ef0abd3457f2904a6ef259728f8e129d6 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 09ae3f3e85062e9f3e33bf02dac1693558ae49f1..7eb551cdd5d170501b58fc05472954a5276f6588 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 2aa4b319ba1029ebffdc3dcd919f250dd963113e..b6b6a47d4fcfe913f486d1069e73920795e1d451 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 2f13e10f67bd02e7d616a16d271a7ffb14a2351f..a559c94fda9ef5a089d85af9f9773693ce9c9fb4 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 e44c4f66464d46d11980c6f3e69f2d9e2a2c0cf2..3efa30bc1b107d3bbdf31fdcb0f9d06734846f18 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 0000000000000000000000000000000000000000..050bb60f37fd4ada7c7649e6efbd83eb96e90373 --- /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 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..c3eeb10baa44d6668b0ac6e88e9f622aea9a827a --- /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 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 index 8bfcda61f414d4073e2d4d53445c823589b3de7c..ba91ff3f68200f8115a54461edd5f4c1692e77f2 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 7cc0ae2415fe186be096a496c16e6a7ee89c6283..ae6b2a9844fa67fa8cdae7f1a55115c56126a30c 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 8d05dcd0ab09c85f29055d4eda0d834b7cd78632..49f1f8f4e8cf02dab86d1e0b8c7008d03a137546 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 331c3b0b063e42e53e750902a83a037f22fc7724..d6a4ff62ed93e0db85b53f503de096f3dcc527ba 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 53edd6af143331bf52f342a5982526d37f4c37e4..308fe639039da194c2419f3902a1f98868482716 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 4ce6b3de87605d604b7528a7bbdcc5a0012abc5a..2e9d37781218ee820a7731b70fe52c78e6a3addb 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 9b80db0263b89931c97e39120c75df60ce44dc85..bcc78a9d50528360e1905afbbb6b0664c5bf2299 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 4c03d46ce06c26244302cca8973c2d6678623d74..1f9710c0a688f242abc249843a3ea4d03062dadc 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 c4b3e0015f316cdc8b2aae419a2ee7d0e9b03d5a..a0e3065b139a23e1898bc4954b3b76a1df3f7e44 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 627d6f96606a13a97907d01d314339f846049892..5dd0f4e37ab19f852e05d222b703b7cac0eaab0f 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) }