diff --git a/src/language/ASTNodeExpressionBuilder.cpp b/src/language/ASTNodeExpressionBuilder.cpp
index 6dc2db33cb9252632ee5827ed423f27519c7bc8b..b89fd96c3b828c9f0441e7327208f34b29910e26 100644
--- a/src/language/ASTNodeExpressionBuilder.cpp
+++ b/src/language/ASTNodeExpressionBuilder.cpp
@@ -3,6 +3,7 @@
 #include <ASTNodeAffectationExpressionBuilder.hpp>
 #include <ASTNodeBinaryOperatorExpressionBuilder.hpp>
 #include <ASTNodeIncDecExpressionBuilder.hpp>
+#include <ASTNodeUnaryOperatorExpressionBuilder.hpp>
 
 #include <PEGGrammar.hpp>
 #include <SymbolTable.hpp>
@@ -38,54 +39,6 @@ class NoProcess final : public INodeProcessor
   }
 };
 
-template <typename Op>
-struct UnaryOp;
-
-template <>
-struct UnaryOp<language::unary_minus>
-{
-  template <typename A>
-  PUGS_INLINE A
-  eval(const A& a)
-  {
-    return -a;
-  }
-};
-
-template <>
-struct UnaryOp<language::unary_not>
-{
-  template <typename A>
-  PUGS_INLINE bool
-  eval(const A& a)
-  {
-    return not a;
-  }
-};
-
-template <typename UnaryOpT, typename ValueT, typename DataT>
-class UnaryExpressionProcessor final : public INodeProcessor
-{
-  Node& m_node;
-
- public:
-  PUGS_INLINE ValueT
-  eval(const DataVariant& a)
-  {
-    return UnaryOp<UnaryOpT>().eval(std::get<DataT>(a));
-  }
-
- public:
-  UnaryExpressionProcessor(Node& node) : m_node{node} {}
-
-  void
-  execute(ExecUntilBreakOrContinue& exec_policy)
-  {
-    m_node.children[0]->execute(exec_policy);
-    m_node.m_value = eval(m_node.children[0]->m_value);
-  }
-};
-
 class IfStatement final : public INodeProcessor
 {
   Node& m_node;
@@ -313,61 +266,6 @@ namespace internal
 void
 build_node_type(Node& n)
 {
-  auto set_unary_operator_processor = [](Node& n, const auto& operator_v) {
-    auto set_unary_operator_processor_for_data = [&](const auto& value, const DataType& data_type) {
-      using OperatorT = std::decay_t<decltype(operator_v)>;
-      using ValueT    = std::decay_t<decltype(value)>;
-      switch (data_type) {
-      case DataType::bool_t: {
-        n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, bool>>(n);
-        break;
-      }
-      case DataType::unsigned_int_t: {
-        n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, uint64_t>>(n);
-        break;
-      }
-      case DataType::int_t: {
-        n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, int64_t>>(n);
-        break;
-      }
-      case DataType::double_t: {
-        n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, double>>(n);
-        break;
-      }
-      default: {
-        throw parse_error("undefined operand type for unary operator", std::vector{n.children[0]->begin()});
-      }
-      }
-    };
-
-    auto set_unary_operator_processor_for_value = [&](const DataType& value_type) {
-      const DataType data_type = n.children[0]->m_data_type;
-      switch (value_type) {
-      case DataType::bool_t: {
-        set_unary_operator_processor_for_data(bool{}, data_type);
-        break;
-      }
-      case DataType::unsigned_int_t: {
-        set_unary_operator_processor_for_data(uint64_t{}, data_type);
-        break;
-      }
-      case DataType::int_t: {
-        set_unary_operator_processor_for_data(int64_t{}, data_type);
-        break;
-      }
-      case DataType::double_t: {
-        set_unary_operator_processor_for_data(double{}, data_type);
-        break;
-      }
-      default: {
-        throw parse_error("undefined value type for unary operator", std::vector{n.begin()});
-      }
-      }
-    };
-
-    set_unary_operator_processor_for_value(n.m_data_type);
-  };
-
   if (n.is_root() or n.is<language::bloc>()) {
     n.m_node_processor = std::make_unique<NodeList>(n);
   } else if (n.is<language::declaration>()) {
@@ -386,10 +284,8 @@ build_node_type(Node& n)
   } else if (n.is<language::name>()) {
     n.m_node_processor = std::make_unique<NameExpression>(n);
 
-  } else if (n.is<language::unary_minus>()) {
-    set_unary_operator_processor(n, language::unary_minus{});
-  } else if (n.is<language::unary_not>()) {
-    set_unary_operator_processor(n, language::unary_not{});
+  } else if (n.is<language::unary_minus>() or n.is<language::unary_not>()) {
+    ASTNodeUnaryOperatorExpressionBuilder{n};
 
   } else if (n.is<language::unary_minusminus>() or n.is<language::unary_plusplus>() or
              n.is<language::post_minusminus>() or n.is<language::post_plusplus>()) {
diff --git a/src/language/ASTNodeUnaryOperatorExpressionBuilder.cpp b/src/language/ASTNodeUnaryOperatorExpressionBuilder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c4bdb6f0a9148e63535e45735e9f7a464bb7a543
--- /dev/null
+++ b/src/language/ASTNodeUnaryOperatorExpressionBuilder.cpp
@@ -0,0 +1,120 @@
+#include <ASTNodeUnaryOperatorExpressionBuilder.hpp>
+#include <PEGGrammar.hpp>
+#include <SymbolTable.hpp>
+
+namespace language
+{
+template <typename Op>
+struct UnaryOp;
+
+template <>
+struct UnaryOp<language::unary_minus>
+{
+  template <typename A>
+  PUGS_INLINE A
+  eval(const A& a)
+  {
+    return -a;
+  }
+};
+
+template <>
+struct UnaryOp<language::unary_not>
+{
+  template <typename A>
+  PUGS_INLINE bool
+  eval(const A& a)
+  {
+    return not a;
+  }
+};
+
+template <typename UnaryOpT, typename ValueT, typename DataT>
+class UnaryExpressionProcessor final : public INodeProcessor
+{
+  Node& m_node;
+
+ public:
+  PUGS_INLINE ValueT
+  eval(const DataVariant& a)
+  {
+    return UnaryOp<UnaryOpT>().eval(std::get<DataT>(a));
+  }
+
+ public:
+  UnaryExpressionProcessor(Node& node) : m_node{node} {}
+
+  void
+  execute(ExecUntilBreakOrContinue& exec_policy)
+  {
+    m_node.children[0]->execute(exec_policy);
+    m_node.m_value = eval(m_node.children[0]->m_value);
+  }
+};
+
+ASTNodeUnaryOperatorExpressionBuilder::ASTNodeUnaryOperatorExpressionBuilder(Node& n)
+{
+  auto set_unary_operator_processor = [](Node& n, const auto& operator_v) {
+    auto set_unary_operator_processor_for_data = [&](const auto& value, const DataType& data_type) {
+      using OperatorT = std::decay_t<decltype(operator_v)>;
+      using ValueT    = std::decay_t<decltype(value)>;
+      switch (data_type) {
+      case DataType::bool_t: {
+        n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, bool>>(n);
+        break;
+      }
+      case DataType::unsigned_int_t: {
+        n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, uint64_t>>(n);
+        break;
+      }
+      case DataType::int_t: {
+        n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, int64_t>>(n);
+        break;
+      }
+      case DataType::double_t: {
+        n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, double>>(n);
+        break;
+      }
+      default: {
+        throw parse_error("undefined operand type for unary operator", std::vector{n.children[0]->begin()});
+      }
+      }
+    };
+
+    auto set_unary_operator_processor_for_value = [&](const DataType& value_type) {
+      const DataType data_type = n.children[0]->m_data_type;
+      switch (value_type) {
+      case DataType::bool_t: {
+        set_unary_operator_processor_for_data(bool{}, data_type);
+        break;
+      }
+      case DataType::unsigned_int_t: {
+        set_unary_operator_processor_for_data(uint64_t{}, data_type);
+        break;
+      }
+      case DataType::int_t: {
+        set_unary_operator_processor_for_data(int64_t{}, data_type);
+        break;
+      }
+      case DataType::double_t: {
+        set_unary_operator_processor_for_data(double{}, data_type);
+        break;
+      }
+      default: {
+        throw parse_error("undefined value type for unary operator", std::vector{n.begin()});
+      }
+      }
+    };
+
+    set_unary_operator_processor_for_value(n.m_data_type);
+  };
+
+  if (n.is<language::unary_minus>()) {
+    set_unary_operator_processor(n, language::unary_minus{});
+  } else if (n.is<language::unary_not>()) {
+    set_unary_operator_processor(n, language::unary_not{});
+  } else {
+    throw parse_error("unexpected error: undefined unary operator", std::vector{n.begin()});
+  }
+}
+}   // namespace language
diff --git a/src/language/ASTNodeUnaryOperatorExpressionBuilder.hpp b/src/language/ASTNodeUnaryOperatorExpressionBuilder.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ea58aa7d82e042ab6ff41741651ca2982eb4b69c
--- /dev/null
+++ b/src/language/ASTNodeUnaryOperatorExpressionBuilder.hpp
@@ -0,0 +1,14 @@
+#ifndef AST_NODE_UNARY_OPERATOR_EXPRESSION_BUILDER_HPP
+#define AST_NODE_UNARY_OPERATOR_EXPRESSION_BUILDER_HPP
+
+#include <ASTNode.hpp>
+
+namespace language
+{
+struct ASTNodeUnaryOperatorExpressionBuilder
+{
+  ASTNodeUnaryOperatorExpressionBuilder(Node& node);
+};
+}   // namespace language
+
+#endif   // AST_NODE_UNARY_OPERATOR_EXPRESSION_BUILDER_HPP
diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt
index c9699c103b0720db96f775431f379ec6bb865b21..c84943ca41a9ccc1757e92ad3f7e0ff1e28e5903 100644
--- a/src/language/CMakeLists.txt
+++ b/src/language/CMakeLists.txt
@@ -11,6 +11,7 @@ add_library(
   ASTNodeBinaryOperatorExpressionBuilder.cpp
   ASTNodeExpressionBuilder.cpp
   ASTNodeIncDecExpressionBuilder.cpp
+  ASTNodeUnaryOperatorExpressionBuilder.cpp
   PugsParser.cpp)
 
 #include_directories(${PUGS_SOURCE_DIR}/utils)