#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/ASTNodeNaturalConversionChecker.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& lhs_node, ASTNode& rhs_node) const final { if constexpr ((std::is_same_v<ValueT, TinyVector<1>> or std::is_same_v<ValueT, TinyMatrix<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 or 0 -> R^1x1 if ((rhs_node.is_type<language::integer>()) and (std::stoi(rhs_node.string()) == 0)) { return std::make_unique<AffectationFromZeroProcessor<ValueT>>(lhs_node); } else { return std::make_unique<AffectationProcessor<OperatorT, ValueT, DataT>>(lhs_node, rhs_node); } } else { return std::make_unique<AffectationProcessor<OperatorT, ValueT, DataT>>(lhs_node, rhs_node); } } }; template <typename ValueT> class AffectationToTupleProcessorBuilder final : public IAffectationProcessorBuilder { public: AffectationToTupleProcessorBuilder() = default; std::unique_ptr<INodeProcessor> getNodeProcessor(ASTNode& lhs_node, ASTNode& rhs_node) const final { return std::make_unique<AffectationToTupleProcessor<ValueT>>(lhs_node, rhs_node); } }; template <typename ValueT> class AffectationToTupleFromListProcessorBuilder final : public IAffectationProcessorBuilder { public: AffectationToTupleFromListProcessorBuilder() = default; std::unique_ptr<INodeProcessor> getNodeProcessor(ASTNode& lhs_node, ASTNode& rhs_node) const final { ASTNodeNaturalConversionChecker(rhs_node, lhs_node.m_data_type); return std::make_unique<AffectationToTupleFromListProcessor<ValueT>>(lhs_node, rhs_node); } }; template <typename OperatorT, typename ValueT> class AffectationToTinyVectorFromListProcessorBuilder final : public IAffectationProcessorBuilder { public: AffectationToTinyVectorFromListProcessorBuilder() = default; std::unique_ptr<INodeProcessor> getNodeProcessor(ASTNode& lhs_node, ASTNode& rhs_node) const final { return std::make_unique<AffectationToTinyVectorFromListProcessor<OperatorT, ValueT>>(lhs_node, rhs_node); } }; template <typename OperatorT, typename ValueT> class AffectationToTinyMatrixFromListProcessorBuilder final : public IAffectationProcessorBuilder { public: AffectationToTinyMatrixFromListProcessorBuilder() = default; std::unique_ptr<INodeProcessor> getNodeProcessor(ASTNode& lhs_node, ASTNode& rhs_node) const final { return std::make_unique<AffectationToTinyMatrixFromListProcessor<OperatorT, ValueT>>(lhs_node, rhs_node); } }; template <typename OperatorT, typename ValueT> class AffectationFromZeroProcessorBuilder final : public IAffectationProcessorBuilder { public: AffectationFromZeroProcessorBuilder() = default; std::unique_ptr<INodeProcessor> getNodeProcessor(ASTNode& lhs_node, ASTNode& rhs_node) const final { if (std::stoi(rhs_node.string()) == 0) { return std::make_unique<AffectationFromZeroProcessor<ValueT>>(lhs_node); } else { throw ParseError("invalid integral value (0 is the solely valid value)", std::vector{lhs_node.begin()}); } } }; #endif // AFFECTATION_PROCESSOR_BUILDER_HPP