From 176bcede178cbf76124883254e405d4a81e352b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com>
Date: Mon, 1 Mar 2021 15:28:18 +0100
Subject: [PATCH] Change the way AffectationProcessors are built

Now the left- and right-hand-side are given explicitly to
getNodeProcessor function and thus to the processor constructors. The
aim of this change is to break the dependency on the affectation node
itself and thus to allow their use in list affectations.
---
 .../ASTNodeAffectationExpressionBuilder.cpp   |  25 ++-
 .../node_processor/AffectationProcessor.hpp   | 193 ++++++++----------
 .../utils/AffectationProcessorBuilder.hpp     |  36 ++--
 .../utils/IAffectationProcessorBuilder.hpp    |   2 +-
 4 files changed, 117 insertions(+), 139 deletions(-)

diff --git a/src/language/ast/ASTNodeAffectationExpressionBuilder.cpp b/src/language/ast/ASTNodeAffectationExpressionBuilder.cpp
index 884711c08..a97c13443 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/node_processor/AffectationProcessor.hpp b/src/language/node_processor/AffectationProcessor.hpp
index 959578619..db5d0fc75 100644
--- a/src/language/node_processor/AffectationProcessor.hpp
+++ b/src/language/node_processor/AffectationProcessor.hpp
@@ -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
   }
@@ -371,7 +371,7 @@ 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;
 
@@ -379,16 +379,16 @@ class AffectationProcessor final : public INodeProcessor
   DataVariant
   execute(ExecutionPolicy& exec_policy)
   {
-    m_affectation_executor->affect(exec_policy, m_node.children[1]->execute(exec_policy));
+    m_affectation_executor->affect(exec_policy, m_rhs_node.execute(exec_policy));
 
     return {};
   }
 
-  AffectationProcessor(ASTNode& node) : m_node{node}
+  AffectationProcessor(ASTNode& lhs_node, ASTNode& rhs_node) : m_rhs_node{rhs_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 +397,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];
+      m_affectation_executor     = 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: {
@@ -423,7 +421,7 @@ class AffectationProcessor final : public INodeProcessor
           }
           using AffectationExecutorT = VectorComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>;
           m_affectation_executor =
-            std::make_unique<AffectationExecutorT>(node, std::get<ArrayTypeT>(value), index_expression);
+            std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index_expression);
           break;
         }
         case 2: {
@@ -433,7 +431,7 @@ class AffectationProcessor final : public INodeProcessor
           }
           using AffectationExecutorT = VectorComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>;
           m_affectation_executor =
-            std::make_unique<AffectationExecutorT>(node, std::get<ArrayTypeT>(value), index_expression);
+            std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index_expression);
           break;
         }
         case 3: {
@@ -443,22 +441,21 @@ class AffectationProcessor final : public INodeProcessor
           }
           using AffectationExecutorT = VectorComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>;
           m_affectation_executor =
-            std::make_unique<AffectationExecutorT>(node, std::get<ArrayTypeT>(value), index_expression);
+            std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index_expression);
           break;
         }
           // 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,7 +464,8 @@ 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),
+
+          m_affectation_executor = std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value),
                                                                           index0_expression, index1_expression);
           break;
         }
@@ -477,7 +475,8 @@ 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),
+
+          m_affectation_executor = std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value),
                                                                           index0_expression, index1_expression);
           break;
         }
@@ -487,14 +486,14 @@ 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),
+
+          m_affectation_executor = std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value),
                                                                           index0_expression, index1_expression);
           break;
         }
           // 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 +504,41 @@ 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
     }
   }
 };
 
+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 +552,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 +563,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 +593,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 +605,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 +647,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 +661,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 +705,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 +722,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 +739,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 +757,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 +799,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 +819,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 +844,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 8d11599a0..0e4b7ace6 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 6d5f8540d..cc0ca85f6 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;
 };
-- 
GitLab