diff --git a/src/language/ast/ASTNodeAffectationExpressionBuilder.cpp b/src/language/ast/ASTNodeAffectationExpressionBuilder.cpp index 884711c081ded349d32663f80180c06c4911bfba..a97c13443bd628a2226de54623c673d464916a0c 100644 --- a/src/language/ast/ASTNodeAffectationExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeAffectationExpressionBuilder.cpp @@ -9,24 +9,24 @@ #include <language/utils/ParseError.hpp> #include <utils/Exceptions.hpp> -ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode& n) +ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode& node) { - const ASTNodeDataType& target_data_type = n.children[0]->m_data_type; - const ASTNodeDataType& source_data_type = n.children[1]->m_data_type; + const ASTNodeDataType& target_data_type = node.children[0]->m_data_type; + const ASTNodeDataType& source_data_type = node.children[1]->m_data_type; const std::string affectation_name = [&] { - if (n.is_type<language::eq_op>()) { + if (node.is_type<language::eq_op>()) { return affectationMangler<language::eq_op>(target_data_type, source_data_type); - } else if (n.is_type<language::multiplyeq_op>()) { + } else if (node.is_type<language::multiplyeq_op>()) { return affectationMangler<language::multiplyeq_op>(target_data_type, source_data_type); - } else if (n.is_type<language::divideeq_op>()) { + } else if (node.is_type<language::divideeq_op>()) { return affectationMangler<language::divideeq_op>(target_data_type, source_data_type); - } else if (n.is_type<language::pluseq_op>()) { + } else if (node.is_type<language::pluseq_op>()) { return affectationMangler<language::pluseq_op>(target_data_type, source_data_type); - } else if (n.is_type<language::minuseq_op>()) { + } else if (node.is_type<language::minuseq_op>()) { return affectationMangler<language::minuseq_op>(target_data_type, source_data_type); } else { - throw ParseError("unexpected error: undefined affectation operator", std::vector{n.begin()}); + throw ParseError("unexpected error: undefined affectation operator", std::vector{node.begin()}); } }(); @@ -34,12 +34,15 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode OperatorRepository::instance().getAffectationProcessorBuilder(affectation_name); if (optional_processor_builder.has_value()) { - n.m_node_processor = optional_processor_builder.value()->getNodeProcessor(n); + ASTNode& lhs_node = *node.children[0]; + ASTNode& rhs_node = *node.children[1]; + + node.m_node_processor = optional_processor_builder.value()->getNodeProcessor(lhs_node, rhs_node); } else { 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()}); + throw ParseError(error_message.str(), std::vector{node.begin()}); } } diff --git a/src/language/ast/ASTNodeDataTypeBuilder.cpp b/src/language/ast/ASTNodeDataTypeBuilder.cpp index 018bc94f74160bfcd680df08ac9b2a08c54ba492..b5f65437ce1b45b4a403aaf079317de8f04c0de5 100644 --- a/src/language/ast/ASTNodeDataTypeBuilder.cpp +++ b/src/language/ast/ASTNodeDataTypeBuilder.cpp @@ -333,6 +333,22 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const value_type = getMatrixDataType(image_node); } else if (image_node.is_type<language::string_type>()) { value_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); + } else if (image_node.is_type<language::type_name_id>()) { + const std::string& type_name_id = image_node.string(); + + auto& symbol_table = *image_node.m_symbol_table; + + const auto [i_type_symbol, found] = symbol_table.find(type_name_id, image_node.begin()); + if (not found) { + throw ParseError("undefined type identifier", std::vector{image_node.begin()}); + } else if (i_type_symbol->attributes().dataType() != ASTNodeDataType::type_name_id_t) { + std::ostringstream os; + os << "invalid type identifier, '" << type_name_id << "' was previously defined as a '" + << dataTypeName(i_type_symbol->attributes().dataType()) << '\''; + throw ParseError(os.str(), std::vector{image_node.begin()}); + } + + value_type = ASTNodeDataType::build<ASTNodeDataType::type_id_t>(type_name_id); } // LCOV_EXCL_START @@ -348,7 +364,6 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const } n.m_data_type = ASTNodeDataType::build<ASTNodeDataType::typename_t>( ASTNodeDataType::build<ASTNodeDataType::list_t>(sub_data_type_list)); - } else if (n.is_type<language::for_post>() or n.is_type<language::for_init>() or n.is_type<language::for_statement_block>()) { n.m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); @@ -361,13 +376,11 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const const ASTNode& test_node = *n.children[0]; ASTNodeNaturalConversionChecker{test_node, ASTNodeDataType::build<ASTNodeDataType::bool_t>()}; - } else if (n.is_type<language::do_while_statement>()) { n.m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>(); const ASTNode& test_node = *n.children[1]; ASTNodeNaturalConversionChecker{test_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(); @@ -394,7 +407,6 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const << 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>()) { auto& operator_repository = OperatorRepository::instance(); @@ -428,7 +440,6 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const << 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>() or n.is_type<language::lesser_op>() or n.is_type<language::lesser_or_eq_op>() or @@ -496,7 +507,6 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const << "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/ASTNodeListAffectationExpressionBuilder.cpp b/src/language/ast/ASTNodeListAffectationExpressionBuilder.cpp index b135bbcd3f67127c23c044880d96ad28ee6527c5..6b53db72a1a257f74196a56f6e2c83694531fd5f 100644 --- a/src/language/ast/ASTNodeListAffectationExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeListAffectationExpressionBuilder.cpp @@ -6,6 +6,9 @@ #include <language/utils/ASTNodeNaturalConversionChecker.hpp> #include <language/utils/ParseError.hpp> +#include <language/utils/AffectationMangler.hpp> +#include <language/utils/OperatorRepository.hpp> + template <typename OperatorT> void ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor( @@ -115,6 +118,25 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor( } }; + auto add_affectation_processor_for_embedded_data = [&](const ASTNodeSubDataType& node_sub_data_type) { + if constexpr (std::is_same_v<OperatorT, language::eq_op>) { + switch (node_sub_data_type.m_data_type) { + case ASTNodeDataType::type_id_t: { + list_affectation_processor->template add<EmbeddedData, EmbeddedData>(value_node); + break; + } + // LCOV_EXCL_START + default: { + throw ParseError("unexpected error:invalid operand type for embedded data affectation", + std::vector{node_sub_data_type.m_parent_node.begin()}); + } + // LCOV_EXCL_STOP + } + } else { + throw ParseError("unexpected error: undefined operator type for string affectation", std::vector{m_node.begin()}); + } + }; + auto add_affectation_processor_for_string_data = [&](const ASTNodeSubDataType& node_sub_data_type) { if constexpr (std::is_same_v<OperatorT, language::eq_op>) { switch (node_sub_data_type.m_data_type) { @@ -192,6 +214,10 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor( add_affectation_processor_for_data(double{}, node_sub_data_type); break; } + case ASTNodeDataType::type_id_t: { + add_affectation_processor_for_embedded_data(node_sub_data_type); + break; + } case ASTNodeDataType::vector_t: { switch (value_type.dimension()) { case 1: { @@ -251,7 +277,21 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor( ASTNodeNaturalConversionChecker<AllowRToR1Conversion>(rhs_node_sub_data_type, value_node.m_data_type); - add_affectation_processor_for_value(value_node.m_data_type, rhs_node_sub_data_type); + const std::string affectation_name = + affectationMangler<language::eq_op>(value_node.m_data_type, rhs_node_sub_data_type.m_data_type); + + const auto& optional_processor_builder = + OperatorRepository::instance().getAffectationProcessorBuilder(affectation_name); + + if (optional_processor_builder.has_value()) { + add_affectation_processor_for_value(value_node.m_data_type, rhs_node_sub_data_type); + } else { + 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{m_node.children[0]->begin()}); + } } template <typename OperatorT> diff --git a/src/language/node_processor/AffectationProcessor.hpp b/src/language/node_processor/AffectationProcessor.hpp index 959578619b023bc28236b1ae52141b018aad8c69..07a52de44e09cba57cf5b60aba65e844ff7faa94 100644 --- a/src/language/node_processor/AffectationProcessor.hpp +++ b/src/language/node_processor/AffectationProcessor.hpp @@ -121,7 +121,7 @@ class AffectationExecutor final : public IAffectationExecutor } } else { if constexpr (std::is_same_v<OperatorT, language::eq_op>) { - if constexpr (std::is_convertible_v<ValueT, DataT>) { + if constexpr (std::is_convertible_v<DataT, ValueT>) { m_lhs = std::get<DataT>(rhs); } else if constexpr (std::is_same_v<DataT, AggregateDataVariant>) { const AggregateDataVariant& v = std::get<AggregateDataVariant>(rhs); @@ -222,7 +222,7 @@ class MatrixComponentAffectationExecutor final : public IAffectationExecutor }()}; public: - MatrixComponentAffectationExecutor(ASTNode& node, + MatrixComponentAffectationExecutor(ASTNode& lhs_node, ArrayT& lhs_array, ASTNode& index0_expression, ASTNode& index1_expression) @@ -230,7 +230,7 @@ class MatrixComponentAffectationExecutor final : public IAffectationExecutor { // LCOV_EXCL_START if constexpr (not m_is_defined) { - throw ParseError("unexpected error: invalid operands to affectation expression", std::vector{node.begin()}); + throw ParseError("unexpected error: invalid operands to affectation expression", std::vector{lhs_node.begin()}); } // LCOV_EXCL_STOP } @@ -275,11 +275,8 @@ class MatrixComponentAffectationExecutor final : public IAffectationExecutor } } else { if constexpr (std::is_same_v<OperatorT, language::eq_op>) { - if constexpr (std::is_same_v<ValueT, DataT>) { - m_lhs_array(index0_value, index1_value) = std::get<DataT>(rhs); - } else { - m_lhs_array(index0_value, index1_value) = static_cast<ValueT>(std::get<DataT>(rhs)); - } + static_assert(std::is_convertible_v<DataT, ValueT>, "unexpected types"); + m_lhs_array(index0_value, index1_value) = static_cast<ValueT>(std::get<DataT>(rhs)); } else { AffOp<OperatorT>().eval(m_lhs_array(index0_value, index1_value), std::get<DataT>(rhs)); } @@ -354,11 +351,8 @@ class VectorComponentAffectationExecutor final : public IAffectationExecutor } } else { if constexpr (std::is_same_v<OperatorT, language::eq_op>) { - if constexpr (std::is_same_v<ValueT, DataT>) { - m_lhs_array[index_value] = std::get<DataT>(rhs); - } else { - m_lhs_array[index_value] = static_cast<ValueT>(std::get<DataT>(rhs)); - } + static_assert(std::is_convertible_v<DataT, ValueT>, "incompatible data and value types"); + m_lhs_array[index_value] = static_cast<ValueT>(std::get<DataT>(rhs)); } else { AffOp<OperatorT>().eval(m_lhs_array[index_value], std::get<DataT>(rhs)); } @@ -371,24 +365,16 @@ template <typename OperatorT, typename ValueT, typename DataT> class AffectationProcessor final : public INodeProcessor { private: - ASTNode& m_node; + ASTNode& m_rhs_node; std::unique_ptr<IAffectationExecutor> m_affectation_executor; - public: - DataVariant - execute(ExecutionPolicy& exec_policy) + std::unique_ptr<IAffectationExecutor> + _buildAffectationExecutor(ASTNode& lhs_node) { - m_affectation_executor->affect(exec_policy, m_node.children[1]->execute(exec_policy)); - - return {}; - } - - AffectationProcessor(ASTNode& node) : m_node{node} - { - if (node.children[0]->is_type<language::name>()) { - const std::string& symbol = m_node.children[0]->string(); - auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin()); + if (lhs_node.is_type<language::name>()) { + const std::string& symbol = lhs_node.string(); + auto [i_symbol, found] = lhs_node.m_symbol_table->find(symbol, lhs_node.begin()); Assert(found); DataVariant& value = i_symbol->attributes().value(); @@ -397,23 +383,21 @@ class AffectationProcessor final : public INodeProcessor } using AffectationExecutorT = AffectationExecutor<OperatorT, ValueT, DataT>; - m_affectation_executor = std::make_unique<AffectationExecutorT>(m_node, std::get<ValueT>(value)); - } else if (node.children[0]->is_type<language::subscript_expression>()) { - auto& array_subscript_expression = *node.children[0]; - - auto& array_expression = *array_subscript_expression.children[0]; + return std::make_unique<AffectationExecutorT>(lhs_node, std::get<ValueT>(value)); + } else if (lhs_node.is_type<language::subscript_expression>()) { + auto& array_expression = *lhs_node.children[0]; Assert(array_expression.is_type<language::name>()); const std::string& symbol = array_expression.string(); - auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, array_subscript_expression.begin()); + auto [i_symbol, found] = lhs_node.m_symbol_table->find(symbol, lhs_node.begin()); Assert(found); DataVariant& value = i_symbol->attributes().value(); if (array_expression.m_data_type == ASTNodeDataType::vector_t) { - Assert(array_subscript_expression.children.size() == 2); + Assert(lhs_node.children.size() == 2); - auto& index_expression = *array_subscript_expression.children[1]; + auto& index_expression = *lhs_node.children[1]; switch (array_expression.m_data_type.dimension()) { case 1: { @@ -422,9 +406,8 @@ class AffectationProcessor final : public INodeProcessor value = ArrayTypeT{}; } using AffectationExecutorT = VectorComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - m_affectation_executor = - std::make_unique<AffectationExecutorT>(node, std::get<ArrayTypeT>(value), index_expression); - break; + + return std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index_expression); } case 2: { using ArrayTypeT = TinyVector<2>; @@ -432,9 +415,8 @@ class AffectationProcessor final : public INodeProcessor value = ArrayTypeT{}; } using AffectationExecutorT = VectorComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - m_affectation_executor = - std::make_unique<AffectationExecutorT>(node, std::get<ArrayTypeT>(value), index_expression); - break; + + return std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index_expression); } case 3: { using ArrayTypeT = TinyVector<3>; @@ -442,23 +424,21 @@ class AffectationProcessor final : public INodeProcessor value = ArrayTypeT{}; } using AffectationExecutorT = VectorComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - m_affectation_executor = - std::make_unique<AffectationExecutorT>(node, std::get<ArrayTypeT>(value), index_expression); - break; + + return std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index_expression); } // LCOV_EXCL_START default: { - throw ParseError("unexpected error: invalid vector dimension", - std::vector{array_subscript_expression.begin()}); + throw ParseError("unexpected error: invalid vector dimension", std::vector{lhs_node.begin()}); } // LCOV_EXCL_STOP } } else if (array_expression.m_data_type == ASTNodeDataType::matrix_t) { - Assert(array_subscript_expression.children.size() == 3); + Assert(lhs_node.children.size() == 3); Assert(array_expression.m_data_type.nbRows() == array_expression.m_data_type.nbColumns()); - auto& index0_expression = *array_subscript_expression.children[1]; - auto& index1_expression = *array_subscript_expression.children[2]; + auto& index0_expression = *lhs_node.children[1]; + auto& index1_expression = *lhs_node.children[2]; switch (array_expression.m_data_type.nbRows()) { case 1: { @@ -467,9 +447,9 @@ class AffectationProcessor final : public INodeProcessor value = ArrayTypeT{}; } using AffectationExecutorT = MatrixComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - m_affectation_executor = std::make_unique<AffectationExecutorT>(node, std::get<ArrayTypeT>(value), - index0_expression, index1_expression); - break; + + return std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index0_expression, + index1_expression); } case 2: { using ArrayTypeT = TinyMatrix<2>; @@ -477,9 +457,9 @@ class AffectationProcessor final : public INodeProcessor value = ArrayTypeT{}; } using AffectationExecutorT = MatrixComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - m_affectation_executor = std::make_unique<AffectationExecutorT>(node, std::get<ArrayTypeT>(value), - index0_expression, index1_expression); - break; + + return std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index0_expression, + index1_expression); } case 3: { using ArrayTypeT = TinyMatrix<3>; @@ -487,14 +467,13 @@ class AffectationProcessor final : public INodeProcessor value = ArrayTypeT{}; } using AffectationExecutorT = MatrixComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - m_affectation_executor = std::make_unique<AffectationExecutorT>(node, std::get<ArrayTypeT>(value), - index0_expression, index1_expression); - break; + + return std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index0_expression, + index1_expression); } // LCOV_EXCL_START default: { - throw ParseError("unexpected error: invalid vector dimension", - std::vector{array_subscript_expression.begin()}); + throw ParseError("unexpected error: invalid vector dimension", std::vector{lhs_node.begin()}); } // LCOV_EXCL_STOP } @@ -505,25 +484,54 @@ class AffectationProcessor final : public INodeProcessor } } else { // LCOV_EXCL_START - throw ParseError("unexpected error: invalid lhs", std::vector{node.children[0]->begin()}); + throw ParseError("unexpected error: invalid lhs", std::vector{lhs_node.begin()}); // LCOV_EXCL_STOP } } + + public: + DataVariant + execute(ExecutionPolicy& exec_policy) + { + m_affectation_executor->affect(exec_policy, m_rhs_node.execute(exec_policy)); + + return {}; + } + + AffectationProcessor(ASTNode& lhs_node, ASTNode& rhs_node) + : m_rhs_node{rhs_node}, m_affectation_executor{this->_buildAffectationExecutor(lhs_node)} + {} +}; + +class AffectationToDataVariantProcessorBase : public INodeProcessor +{ + protected: + DataVariant* m_lhs; + + public: + AffectationToDataVariantProcessorBase(ASTNode& lhs_node) + { + const std::string& symbol = lhs_node.string(); + auto [i_symbol, found] = lhs_node.m_symbol_table->find(symbol, lhs_node.begin()); + Assert(found); + + m_lhs = &i_symbol->attributes().value(); + } + + virtual ~AffectationToDataVariantProcessorBase() = default; }; template <typename OperatorT, typename ValueT> -class AffectationToTinyVectorFromListProcessor final : public INodeProcessor +class AffectationToTinyVectorFromListProcessor final : public AffectationToDataVariantProcessorBase { private: - ASTNode& m_node; - - DataVariant* m_lhs; + ASTNode& m_rhs_node; public: DataVariant execute(ExecutionPolicy& exec_policy) { - AggregateDataVariant children_values = std::get<AggregateDataVariant>(m_node.children[1]->execute(exec_policy)); + AggregateDataVariant children_values = std::get<AggregateDataVariant>(m_rhs_node.execute(exec_policy)); static_assert(std::is_same_v<OperatorT, language::eq_op>, "forbidden affection operator for list to vectors"); @@ -537,7 +545,7 @@ class AffectationToTinyVectorFromListProcessor final : public INodeProcessor v[i] = child_value; } else { // LCOV_EXCL_START - throw ParseError("unexpected error: unexpected right hand side type in affectation", m_node.begin()); + throw ParseError("unexpected error: unexpected right hand side type in affectation", m_rhs_node.begin()); // LCOV_EXCL_STOP } }, @@ -548,29 +556,22 @@ class AffectationToTinyVectorFromListProcessor final : public INodeProcessor return {}; } - AffectationToTinyVectorFromListProcessor(ASTNode& node) : m_node{node} - { - const std::string& symbol = m_node.children[0]->string(); - auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin()); - Assert(found); - - m_lhs = &i_symbol->attributes().value(); - } + AffectationToTinyVectorFromListProcessor(ASTNode& lhs_node, ASTNode& rhs_node) + : AffectationToDataVariantProcessorBase(lhs_node), m_rhs_node{rhs_node} + {} }; template <typename OperatorT, typename ValueT> -class AffectationToTinyMatrixFromListProcessor final : public INodeProcessor +class AffectationToTinyMatrixFromListProcessor final : public AffectationToDataVariantProcessorBase { private: - ASTNode& m_node; - - DataVariant* m_lhs; + ASTNode& m_rhs_node; public: DataVariant execute(ExecutionPolicy& exec_policy) { - AggregateDataVariant children_values = std::get<AggregateDataVariant>(m_node.children[1]->execute(exec_policy)); + AggregateDataVariant children_values = std::get<AggregateDataVariant>(m_rhs_node.execute(exec_policy)); static_assert(std::is_same_v<OperatorT, language::eq_op>, "forbidden affection operator for list to vectors"); @@ -585,7 +586,7 @@ class AffectationToTinyMatrixFromListProcessor final : public INodeProcessor v(i, j) = child_value; } else { // LCOV_EXCL_START - throw ParseError("unexpected error: unexpected right hand side type in affectation", m_node.begin()); + throw ParseError("unexpected error: unexpected right hand side type in affectation", m_rhs_node.begin()); // LCOV_EXCL_STOP } }, @@ -597,29 +598,22 @@ class AffectationToTinyMatrixFromListProcessor final : public INodeProcessor return {}; } - AffectationToTinyMatrixFromListProcessor(ASTNode& node) : m_node{node} - { - const std::string& symbol = m_node.children[0]->string(); - auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin()); - Assert(found); - - m_lhs = &i_symbol->attributes().value(); - } + AffectationToTinyMatrixFromListProcessor(ASTNode& lhs_node, ASTNode& rhs_node) + : AffectationToDataVariantProcessorBase(lhs_node), m_rhs_node{rhs_node} + {} }; template <typename ValueT> -class AffectationToTupleProcessor final : public INodeProcessor +class AffectationToTupleProcessor final : public AffectationToDataVariantProcessorBase { private: - ASTNode& m_node; - - DataVariant* m_lhs; + ASTNode& m_rhs_node; public: DataVariant execute(ExecutionPolicy& exec_policy) { - DataVariant value = m_node.children[1]->execute(exec_policy); + DataVariant value = m_rhs_node.execute(exec_policy); std::visit( [&](auto&& v) { @@ -646,12 +640,12 @@ class AffectationToTupleProcessor final : public INodeProcessor *m_lhs = std::vector<ValueT>{ValueT{zero}}; } else { // LCOV_EXCL_START - throw ParseError("unexpected error: unexpected right hand side type in affectation", m_node.begin()); + throw ParseError("unexpected error: unexpected right hand side type in affectation", m_rhs_node.begin()); // LCOV_EXCL_STOP } } else { // LCOV_EXCL_START - throw ParseError("unexpected error: unexpected right hand side type in affectation", m_node.begin()); + throw ParseError("unexpected error: unexpected right hand side type in affectation", m_rhs_node.begin()); // LCOV_EXCL_STOP } }, @@ -660,23 +654,16 @@ class AffectationToTupleProcessor final : public INodeProcessor return {}; } - AffectationToTupleProcessor(ASTNode& node) : m_node{node} - { - const std::string& symbol = m_node.children[0]->string(); - auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin()); - Assert(found); - - m_lhs = &i_symbol->attributes().value(); - } + AffectationToTupleProcessor(ASTNode& lhs_node, ASTNode& rhs_node) + : AffectationToDataVariantProcessorBase(lhs_node), m_rhs_node{rhs_node} + {} }; template <typename ValueT> -class AffectationToTupleFromListProcessor final : public INodeProcessor +class AffectationToTupleFromListProcessor final : public AffectationToDataVariantProcessorBase { private: - ASTNode& m_node; - - DataVariant* m_lhs; + ASTNode& m_rhs_node; void _copyAggregateDataVariant(const AggregateDataVariant& children_values) @@ -711,7 +698,7 @@ class AffectationToTupleFromListProcessor final : public INodeProcessor } else { // LCOV_EXCL_START throw ParseError("unexpected error: unexpected right hand side type in affectation", - m_node.children[1]->children[i]->begin()); + m_rhs_node.children[i]->begin()); // LCOV_EXCL_STOP } }, @@ -728,7 +715,7 @@ class AffectationToTupleFromListProcessor final : public INodeProcessor } else { // LCOV_EXCL_START throw ParseError("unexpected error: unexpected right hand side type in affectation", - m_node.children[1]->children[i]->begin()); + m_rhs_node.children[i]->begin()); // LCOV_EXCL_STOP } } else if constexpr (is_tiny_matrix_v<ValueT>) { @@ -745,7 +732,7 @@ class AffectationToTupleFromListProcessor final : public INodeProcessor } else { // LCOV_EXCL_START throw ParseError("unexpected error: unexpected right hand side type in affectation", - m_node.children[1]->children[i]->begin()); + m_rhs_node.children[i]->begin()); // LCOV_EXCL_STOP } }, @@ -763,13 +750,13 @@ class AffectationToTupleFromListProcessor final : public INodeProcessor } else { // LCOV_EXCL_START throw ParseError("unexpected error: unexpected right hand side type in affectation", - m_node.children[1]->children[i]->begin()); + m_rhs_node.children[i]->begin()); // LCOV_EXCL_STOP } } else { // LCOV_EXCL_START throw ParseError("unexpected error: unexpected right hand side type in affectation", - m_node.children[1]->children[i]->begin()); + m_rhs_node.children[i]->begin()); // LCOV_EXCL_STOP } }, @@ -805,8 +792,7 @@ class AffectationToTupleFromListProcessor final : public INodeProcessor } } else { // LCOV_EXCL_START - throw ParseError("unexpected error: unexpected right hand side type in tuple affectation", - m_node.children[1]->begin()); + throw ParseError("unexpected error: unexpected right hand side type in tuple affectation", m_rhs_node.begin()); // LCOV_EXCL_STOP } @@ -826,34 +812,23 @@ class AffectationToTupleFromListProcessor final : public INodeProcessor this->_copyVector(value_list); } else { // LCOV_EXCL_START - throw ParseError("unexpected error: invalid lhs (expecting list or tuple)", - std::vector{m_node.children[1]->begin()}); + throw ParseError("unexpected error: invalid lhs (expecting list or tuple)", std::vector{m_rhs_node.begin()}); // LCOV_EXCL_STOP } }, - m_node.children[1]->execute(exec_policy)); + m_rhs_node.execute(exec_policy)); return {}; } - AffectationToTupleFromListProcessor(ASTNode& node) : m_node{node} - { - const std::string& symbol = m_node.children[0]->string(); - auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin()); - Assert(found); - - m_lhs = &i_symbol->attributes().value(); - } + AffectationToTupleFromListProcessor(ASTNode& lhs_node, ASTNode& rhs_node) + : AffectationToDataVariantProcessorBase(lhs_node), m_rhs_node{rhs_node} + {} }; template <typename ValueT> -class AffectationFromZeroProcessor final : public INodeProcessor +class AffectationFromZeroProcessor final : public AffectationToDataVariantProcessorBase { - private: - ASTNode& m_node; - - DataVariant* m_lhs; - public: DataVariant execute(ExecutionPolicy&) @@ -862,14 +837,7 @@ class AffectationFromZeroProcessor final : public INodeProcessor return {}; } - AffectationFromZeroProcessor(ASTNode& node) : m_node{node} - { - const std::string& symbol = m_node.children[0]->string(); - auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin()); - Assert(found); - - m_lhs = &i_symbol->attributes().value(); - } + AffectationFromZeroProcessor(ASTNode& lhs_node) : AffectationToDataVariantProcessorBase(lhs_node) {} }; template <typename OperatorT> diff --git a/src/language/utils/AffectationProcessorBuilder.hpp b/src/language/utils/AffectationProcessorBuilder.hpp index 8d11599a01c67566e0f88fcb34cad581bc76de45..0e4b7ace65654b650989e817dbe2e4a545ae320f 100644 --- a/src/language/utils/AffectationProcessorBuilder.hpp +++ b/src/language/utils/AffectationProcessorBuilder.hpp @@ -15,18 +15,18 @@ class AffectationProcessorBuilder final : public IAffectationProcessorBuilder public: AffectationProcessorBuilder() = default; std::unique_ptr<INodeProcessor> - getNodeProcessor(ASTNode& node) const + getNodeProcessor(ASTNode& lhs_node, ASTNode& rhs_node) const final { 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); + 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>>(node); + return std::make_unique<AffectationProcessor<OperatorT, ValueT, DataT>>(lhs_node, rhs_node); } } else { - return std::make_unique<AffectationProcessor<OperatorT, ValueT, DataT>>(node); + return std::make_unique<AffectationProcessor<OperatorT, ValueT, DataT>>(lhs_node, rhs_node); } } }; @@ -37,9 +37,9 @@ class AffectationToTupleProcessorBuilder final : public IAffectationProcessorBui public: AffectationToTupleProcessorBuilder() = default; std::unique_ptr<INodeProcessor> - getNodeProcessor(ASTNode& node) const + getNodeProcessor(ASTNode& lhs_node, ASTNode& rhs_node) const final { - return std::make_unique<AffectationToTupleProcessor<ValueT>>(node); + return std::make_unique<AffectationToTupleProcessor<ValueT>>(lhs_node, rhs_node); } }; @@ -49,10 +49,10 @@ class AffectationToTupleFromListProcessorBuilder final : public IAffectationProc public: AffectationToTupleFromListProcessorBuilder() = default; std::unique_ptr<INodeProcessor> - getNodeProcessor(ASTNode& node) const + getNodeProcessor(ASTNode& lhs_node, ASTNode& rhs_node) const final { - ASTNodeNaturalConversionChecker(*node.children[1], node.children[0]->m_data_type); - return std::make_unique<AffectationToTupleFromListProcessor<ValueT>>(node); + ASTNodeNaturalConversionChecker(rhs_node, lhs_node.m_data_type); + return std::make_unique<AffectationToTupleFromListProcessor<ValueT>>(lhs_node, rhs_node); } }; @@ -62,9 +62,9 @@ class AffectationToTinyVectorFromListProcessorBuilder final : public IAffectatio public: AffectationToTinyVectorFromListProcessorBuilder() = default; std::unique_ptr<INodeProcessor> - getNodeProcessor(ASTNode& node) const + getNodeProcessor(ASTNode& lhs_node, ASTNode& rhs_node) const final { - return std::make_unique<AffectationToTinyVectorFromListProcessor<OperatorT, ValueT>>(node); + return std::make_unique<AffectationToTinyVectorFromListProcessor<OperatorT, ValueT>>(lhs_node, rhs_node); } }; @@ -74,9 +74,9 @@ class AffectationToTinyMatrixFromListProcessorBuilder final : public IAffectatio public: AffectationToTinyMatrixFromListProcessorBuilder() = default; std::unique_ptr<INodeProcessor> - getNodeProcessor(ASTNode& node) const + getNodeProcessor(ASTNode& lhs_node, ASTNode& rhs_node) const final { - return std::make_unique<AffectationToTinyMatrixFromListProcessor<OperatorT, ValueT>>(node); + return std::make_unique<AffectationToTinyMatrixFromListProcessor<OperatorT, ValueT>>(lhs_node, rhs_node); } }; @@ -86,12 +86,12 @@ class AffectationFromZeroProcessorBuilder final : public IAffectationProcessorBu public: AffectationFromZeroProcessorBuilder() = default; std::unique_ptr<INodeProcessor> - getNodeProcessor(ASTNode& node) const + getNodeProcessor(ASTNode& lhs_node, ASTNode& rhs_node) const final { - if (std::stoi(node.children[1]->string()) == 0) { - return std::make_unique<AffectationFromZeroProcessor<ValueT>>(node); + 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{node.children[1]->begin()}); + throw ParseError("invalid integral value (0 is the solely valid value)", std::vector{lhs_node.begin()}); } } }; diff --git a/src/language/utils/IAffectationProcessorBuilder.hpp b/src/language/utils/IAffectationProcessorBuilder.hpp index 6d5f8540df9435bba4b86e6bee22f980b5727d7b..cc0ca85f67ece81b6c1313a13c429dfeb9718cd7 100644 --- a/src/language/utils/IAffectationProcessorBuilder.hpp +++ b/src/language/utils/IAffectationProcessorBuilder.hpp @@ -9,7 +9,7 @@ class INodeProcessor; class IAffectationProcessorBuilder { public: - virtual std::unique_ptr<INodeProcessor> getNodeProcessor(ASTNode& node) const = 0; + virtual std::unique_ptr<INodeProcessor> getNodeProcessor(ASTNode& lhs_node, ASTNode& rhs_node) const = 0; virtual ~IAffectationProcessorBuilder() = default; };