From 34d6a933b43fdf6a1340b1d679c0233cd4b08ae4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com>
Date: Tue, 17 Nov 2020 18:37:55 +0100
Subject: [PATCH] Change increment decrement operators expression builder

One now use OperatorRepository
---
 .../ast/ASTNodeIncDecExpressionBuilder.cpp    | 75 ++++++++-----------
 .../ASTNodeUnaryOperatorExpressionBuilder.cpp |  1 -
 .../utils/AffectationRegisterForB.hpp         |  2 -
 .../utils/AffectationRegisterForN.hpp         |  2 -
 .../utils/AffectationRegisterForR.hpp         |  2 -
 .../utils/AffectationRegisterForR1.hpp        |  2 -
 .../utils/AffectationRegisterForR2.hpp        |  2 -
 .../utils/AffectationRegisterForR3.hpp        |  2 -
 .../utils/AffectationRegisterForString.hpp    |  2 -
 .../utils/AffectationRegisterForZ.hpp         |  2 -
 src/language/utils/CMakeLists.txt             |  3 +
 .../utils/IIncDecOperatorProcessorBuilder.hpp | 17 +++++
 src/language/utils/IncDecOperatorMangler.hpp  | 34 +++++++++
 .../utils/IncDecOperatorProcessorBuilder.hpp  | 24 ++++++
 .../utils/IncDecOperatorRegisterForN.cpp      | 58 ++++++++++++++
 .../utils/IncDecOperatorRegisterForN.hpp      | 16 ++++
 .../utils/IncDecOperatorRegisterForR.cpp      | 58 ++++++++++++++
 .../utils/IncDecOperatorRegisterForR.hpp      | 16 ++++
 .../utils/IncDecOperatorRegisterForZ.cpp      | 57 ++++++++++++++
 .../utils/IncDecOperatorRegisterForZ.hpp      | 16 ++++
 src/language/utils/OperatorRepository.cpp     |  8 ++
 src/language/utils/OperatorRepository.hpp     | 32 +++++++-
 .../utils/UnaryOperatorRegisterForB.hpp       |  2 -
 .../utils/UnaryOperatorRegisterForN.hpp       |  2 -
 .../utils/UnaryOperatorRegisterForR.hpp       |  2 -
 .../utils/UnaryOperatorRegisterForR1.hpp      |  2 -
 .../utils/UnaryOperatorRegisterForR2.hpp      |  2 -
 .../utils/UnaryOperatorRegisterForR3.hpp      |  2 -
 .../utils/UnaryOperatorRegisterForZ.hpp       |  2 -
 tests/test_ASTNodeIncDecExpressionBuilder.cpp | 37 ++++-----
 30 files changed, 383 insertions(+), 99 deletions(-)
 create mode 100644 src/language/utils/IIncDecOperatorProcessorBuilder.hpp
 create mode 100644 src/language/utils/IncDecOperatorMangler.hpp
 create mode 100644 src/language/utils/IncDecOperatorProcessorBuilder.hpp
 create mode 100644 src/language/utils/IncDecOperatorRegisterForN.cpp
 create mode 100644 src/language/utils/IncDecOperatorRegisterForN.hpp
 create mode 100644 src/language/utils/IncDecOperatorRegisterForR.cpp
 create mode 100644 src/language/utils/IncDecOperatorRegisterForR.hpp
 create mode 100644 src/language/utils/IncDecOperatorRegisterForZ.cpp
 create mode 100644 src/language/utils/IncDecOperatorRegisterForZ.hpp

diff --git a/src/language/ast/ASTNodeIncDecExpressionBuilder.cpp b/src/language/ast/ASTNodeIncDecExpressionBuilder.cpp
index 71e5c3c4b..c877d3ca2 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 7781ebae6..bfba2e0f8 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 4064d4988..d6507ff7a 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 56f7699e8..e97a652c0 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 141a0d8ae..3a004a92a 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 04016bd67..27f263f74 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 0c1c5c1fa..cc1fcc9ef 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 09ae3f3e8..7eb551cdd 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 2aa4b319b..b6b6a47d4 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 2f13e10f6..a559c94fd 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 e44c4f664..3efa30bc1 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 000000000..050bb60f3
--- /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 000000000..ed5a84ae4
--- /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 000000000..c3eeb10ba
--- /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 000000000..8e6a6369f
--- /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 000000000..c3e2682d8
--- /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 000000000..503175146
--- /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 000000000..5ede6b999
--- /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 000000000..5a0bc0faa
--- /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 000000000..b4ab27770
--- /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 8bfcda61f..ba91ff3f6 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 7cc0ae241..ae6b2a984 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 8d05dcd0a..49f1f8f4e 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 331c3b0b0..d6a4ff62e 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 53edd6af1..308fe6390 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 4ce6b3de8..2e9d37781 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 9b80db026..bcc78a9d5 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 4c03d46ce..1f9710c0a 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 c4b3e0015..a0e3065b1 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 627d6f966..5dd0f4e37 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)
       }
-- 
GitLab