Select Git revision
AffectationProcessorBuilder.hpp
AffectationProcessorBuilder.hpp 3.62 KiB
#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