diff --git a/src/language/ASTNode.hpp b/src/language/ASTNode.hpp
index e8ef09b3af830bbf78f5f218ab0cfa020392f13b..31b12b1e5ecfe6be2f90901923b49e6aa9b791ac 100644
--- a/src/language/ASTNode.hpp
+++ b/src/language/ASTNode.hpp
@@ -7,8 +7,8 @@
 #include <ASTNodeDataType.hpp>
 #include <ASTNodeDataVariant.hpp>
 
-#include <ExecUntilBreakOrContinue.hpp>
-#include <INodeProcessor.hpp>
+#include <node_processor/ExecUntilBreakOrContinue.hpp>
+#include <node_processor/INodeProcessor.hpp>
 
 #include <pegtl/contrib/parse_tree.hpp>
 
diff --git a/src/language/ASTNodeExpressionBuilder.cpp b/src/language/ASTNodeExpressionBuilder.cpp
index 8eb9b8995692a76654d7a1ab36131409cae354b0..ceeb6eaacab100e6d2c3b5a17abc29fb015ee6f0 100644
--- a/src/language/ASTNodeExpressionBuilder.cpp
+++ b/src/language/ASTNodeExpressionBuilder.cpp
@@ -5,321 +5,18 @@
 #include <ASTNodeIncDecExpressionBuilder.hpp>
 #include <ASTNodeUnaryOperatorExpressionBuilder.hpp>
 
-#include <PEGGrammar.hpp>
-#include <SymbolTable.hpp>
-
-#include <Demangle.hpp>
-
-class ASTNodeListProcessor final : public INodeProcessor
-{
-  ASTNode& m_node;
-
- public:
-  std::string
-  describe() const
-  {
-    return demangle<decltype(*this)>();
-  }
-
-  void
-  execute(ExecUntilBreakOrContinue& exec_policy)
-  {
-    for (auto& child : m_node.children) {
-      child->execute(exec_policy);
-    }
-  }
-
-  ASTNodeListProcessor(ASTNode& node) : m_node{node} {}
-};
-
-class FakeProcessor final : public INodeProcessor
-{
- public:
-  std::string
-  describe() const
-  {
-    return demangle<decltype(*this)>();
-  }
-
-  PUGS_INLINE
-  void
-  execute(ExecUntilBreakOrContinue&)
-  {
-    ;
-  }
-
-  FakeProcessor() = default;
-};
-
-class IfProcessor final : public INodeProcessor
-{
-  ASTNode& m_node;
-
- public:
-  std::string
-  describe() const
-  {
-    return demangle<decltype(*this)>();
-  }
-
-  void
-  execute(ExecUntilBreakOrContinue& exec_policy)
-  {
-    m_node.children[0]->execute(exec_policy);
-    const bool is_true = static_cast<bool>(std::visit(
-      [](const auto& value) -> bool {
-        using T = std::decay_t<decltype(value)>;
-        if constexpr (std::is_arithmetic_v<T>) {
-          return value;
-        } else {
-          return false;
-        }
-      },
-      m_node.children[0]->m_value));
-    if (is_true) {
-      Assert(m_node.children[1] != nullptr);
-      m_node.children[1]->execute(exec_policy);
-    } else {
-      if (m_node.children.size() == 3) {
-        // else statement
-        Assert(m_node.children[2] != nullptr);
-        m_node.children[2]->execute(exec_policy);
-      }
-    }
-  }
-
-  IfProcessor(ASTNode& node) : m_node{node} {}
-};
-
-class DoWhileProcessor final : public INodeProcessor
-{
-  ASTNode& m_node;
-
- public:
-  std::string
-  describe() const
-  {
-    return demangle<decltype(*this)>();
-  }
-
-  void
-  execute(ExecUntilBreakOrContinue& exec_policy)
-  {
-    bool continuation_test = true;
-    ExecUntilBreakOrContinue exec_until_jump;
-    do {
-      m_node.children[0]->execute(exec_until_jump);
-      if (not exec_until_jump.exec()) {
-        if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::break_jump) {
-          break;
-        } else if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::continue_jump) {
-          exec_until_jump = ExecUntilBreakOrContinue{};   // getting ready for next loop traversal
-        }
-      }
-      m_node.children[1]->execute(exec_policy);
-      continuation_test = static_cast<bool>(std::visit(
-        [](const auto& value) -> bool {
-          using T = std::decay_t<decltype(value)>;
-          if constexpr (std::is_arithmetic_v<T>) {
-            return value;
-          } else {
-            return false;
-          }
-        },
-        m_node.children[1]->m_value));
-    } while (continuation_test);
-  }
-
-  DoWhileProcessor(ASTNode& node) : m_node{node} {}
-};
-
-class WhileProcessor final : public INodeProcessor
-{
-  ASTNode& m_node;
-
- public:
-  std::string
-  describe() const
-  {
-    return demangle<decltype(*this)>();
-  }
-
-  void
-  execute(ExecUntilBreakOrContinue& exec_policy)
-  {
-    ExecUntilBreakOrContinue exec_until_jump;
-    while ([&]() {
-      m_node.children[0]->execute(exec_policy);
-      return static_cast<bool>(std::visit(
-        [](const auto& value) -> bool {
-          using T = std::decay_t<decltype(value)>;
-          if constexpr (std::is_arithmetic_v<T>) {
-            return value;
-          } else {
-            return false;
-          }
-        },
-        m_node.children[0]->m_value));
-    }()) {
-      m_node.children[1]->execute(exec_until_jump);
-      if (not exec_until_jump.exec()) {
-        if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::break_jump) {
-          break;
-        } else if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::continue_jump) {
-          exec_until_jump = ExecUntilBreakOrContinue{};   // getting ready for next loop traversal
-        }
-      }
-    }
-  }
-
-  WhileProcessor(ASTNode& node) : m_node{node} {}
-};
+#include <node_processor/ASTNodeListProcessor.hpp>
+#include <node_processor/BreakProcessor.hpp>
+#include <node_processor/ContinueProcessor.hpp>
+#include <node_processor/DoWhileProcessor.hpp>
+#include <node_processor/FakeProcessor.hpp>
+#include <node_processor/ForProcessor.hpp>
+#include <node_processor/IfProcessor.hpp>
+#include <node_processor/NameProcessor.hpp>
+#include <node_processor/OStreamProcessor.hpp>
+#include <node_processor/WhileProcessor.hpp>
 
-class ForProcessor final : public INodeProcessor
-{
-  ASTNode& m_node;
-
- public:
-  std::string
-  describe() const
-  {
-    return demangle<decltype(*this)>();
-  }
-
-  void
-  execute(ExecUntilBreakOrContinue& exec_policy)
-  {
-    ExecUntilBreakOrContinue exec_until_jump;
-    m_node.children[0]->execute(exec_policy);
-    while ([&]() {
-      m_node.children[1]->execute(exec_policy);
-      return static_cast<bool>(std::visit(
-        [](const auto& value) -> bool {
-          using T = std::decay_t<decltype(value)>;
-          if constexpr (std::is_arithmetic_v<T>) {
-            return value;
-          } else {
-            return false;
-          }
-        },
-        m_node.children[1]->m_value));
-    }()) {
-      m_node.children[3]->execute(exec_until_jump);
-      if (not exec_until_jump.exec()) {
-        if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::break_jump) {
-          break;
-        } else if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::continue_jump) {
-          exec_until_jump = ExecUntilBreakOrContinue{};   // getting ready for next loop traversal
-        }
-      }
-
-      m_node.children[2]->execute(exec_policy);
-    }
-  }
-
-  ForProcessor(ASTNode& node) : m_node{node} {}
-};
-
-class NameProcessor final : public INodeProcessor
-{
-  ASTNode& m_node;
-  ASTNodeDataVariant* p_value{nullptr};
-
- public:
-  std::string
-  describe() const
-  {
-    return demangle<decltype(*this)>();
-  }
-
-  void
-  execute(ExecUntilBreakOrContinue&)
-  {
-    m_node.m_value = *p_value;
-  }
-
-  NameProcessor(ASTNode& node) : m_node{node}
-  {
-    const std::string& symbol = m_node.string();
-    auto [i_symbol, found]    = m_node.m_symbol_table->find(symbol, m_node.begin());
-    Assert(found);
-    p_value = &(i_symbol->second.value());
-  }
-};
-
-class BreakProcessor final : public INodeProcessor
-{
- public:
-  std::string
-  describe() const
-  {
-    return demangle<decltype(*this)>();
-  }
-
-  void
-  execute(ExecUntilBreakOrContinue& exec_policy)
-  {
-    exec_policy = ExecUntilBreakOrContinue(ExecUntilBreakOrContinue::JumpType::break_jump);
-  }
-
-  BreakProcessor() = default;
-};
-
-class ContinueProcessor final : public INodeProcessor
-{
- public:
-  std::string
-  describe() const
-  {
-    return demangle<decltype(*this)>();
-  }
-
-  void
-  execute(ExecUntilBreakOrContinue& exec_policy)
-  {
-    exec_policy = ExecUntilBreakOrContinue(ExecUntilBreakOrContinue::JumpType::continue_jump);
-  }
-
-  ContinueProcessor() = default;
-};
-
-class OStreamProcessor final : public INodeProcessor
-{
-  ASTNode& m_node;
-  std::ostream& m_os;
-
- public:
-  std::string
-  describe() const
-  {
-    return demangle<decltype(*this)>();
-  }
-
-  void
-  execute(ExecUntilBreakOrContinue& exec_policy)
-  {
-    for (size_t i = 0; i < m_node.children.size(); ++i) {
-      m_node.children[i]->execute(exec_policy);
-      std::visit(
-        [&](auto&& value) {
-          using ValueT = std::decay_t<decltype(value)>;
-          if constexpr (not std::is_same_v<std::monostate, ValueT>) {
-            if constexpr (std::is_same_v<bool, ValueT>) {
-              m_os << std::boolalpha << value;
-            } else {
-              m_os << value;
-            }
-          }
-        },
-        m_node.children[i]->m_value);
-    }
-  }
-
-  OStreamProcessor(ASTNode& node, std::ostream& os) : m_node{node}, m_os(os)
-  {
-    ;
-  }
-};
+#include <PEGGrammar.hpp>
 
 void
 ASTNodeExpressionBuilder::_buildExpression(ASTNode& n)
diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt
index 7b440e23ea1e62f0a9545e64a08f9bf3dab49c64..9910dd47004d805e153e0bd8a8dcf0c23c057af5 100644
--- a/src/language/CMakeLists.txt
+++ b/src/language/CMakeLists.txt
@@ -3,6 +3,8 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 # ------------------- Source files --------------------
 
+add_subdirectory(node_processor)
+
 add_library(
   PugsLanguage
   ASTBuilder.cpp
@@ -24,8 +26,6 @@ add_library(
   ASTSymbolInitializationChecker.cpp
   PugsParser.cpp)
 
-#include_directories(${PUGS_SOURCE_DIR}/utils)
-
 # Additional dependencies
 add_dependencies(PugsLanguage
   PugsUtils)
diff --git a/src/language/node_processor/ASTNodeListProcessor.hpp b/src/language/node_processor/ASTNodeListProcessor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..0eb6590b58d6444c5d013399a64994bc5bb6d99f
--- /dev/null
+++ b/src/language/node_processor/ASTNodeListProcessor.hpp
@@ -0,0 +1,30 @@
+#ifndef AST_NODE_LIST_PROCESSOR_HPP
+#define AST_NODE_LIST_PROCESSOR_HPP
+
+#include <node_processor/INodeProcessor.hpp>
+
+#include <Demangle.hpp>
+
+class ASTNodeListProcessor final : public INodeProcessor
+{
+  ASTNode& m_node;
+
+ public:
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
+
+  void
+  execute(ExecUntilBreakOrContinue& exec_policy)
+  {
+    for (auto& child : m_node.children) {
+      child->execute(exec_policy);
+    }
+  }
+
+  ASTNodeListProcessor(ASTNode& node) : m_node{node} {}
+};
+
+#endif   // AST_NODE_LIST_PROCESSOR_HPP
diff --git a/src/language/node_processor/BreakProcessor.hpp b/src/language/node_processor/BreakProcessor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7046f2342db53823e5edfb1e0caa6487d69a4154
--- /dev/null
+++ b/src/language/node_processor/BreakProcessor.hpp
@@ -0,0 +1,26 @@
+#ifndef BREAK_PROCESSOR_HPP
+#define BREAK_PROCESSOR_HPP
+
+#include <node_processor/INodeProcessor.hpp>
+
+#include <Demangle.hpp>
+
+class BreakProcessor final : public INodeProcessor
+{
+ public:
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
+
+  void
+  execute(ExecUntilBreakOrContinue& exec_policy)
+  {
+    exec_policy = ExecUntilBreakOrContinue(ExecUntilBreakOrContinue::JumpType::break_jump);
+  }
+
+  BreakProcessor() = default;
+};
+
+#endif   // BREAK_PROCESSOR_HPP
diff --git a/src/language/node_processor/CMakeLists.txt b/src/language/node_processor/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..adc3b3876b851016dfe5031f2eb939d4cbeff6aa
--- /dev/null
+++ b/src/language/node_processor/CMakeLists.txt
@@ -0,0 +1,5 @@
+# ------------------- Source files --------------------
+
+#add_library(
+#  PugsLanguageNodeProcessor
+#)
diff --git a/src/language/node_processor/ContinueProcessor.hpp b/src/language/node_processor/ContinueProcessor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c3185da9dbc00eb62cbe3376f9aa5a27ba0c9c81
--- /dev/null
+++ b/src/language/node_processor/ContinueProcessor.hpp
@@ -0,0 +1,26 @@
+#ifndef CONTINUE_PROCESSOR_HPP
+#define CONTINUE_PROCESSOR_HPP
+
+#include <node_processor/INodeProcessor.hpp>
+
+#include <Demangle.hpp>
+
+class ContinueProcessor final : public INodeProcessor
+{
+ public:
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
+
+  void
+  execute(ExecUntilBreakOrContinue& exec_policy)
+  {
+    exec_policy = ExecUntilBreakOrContinue(ExecUntilBreakOrContinue::JumpType::continue_jump);
+  }
+
+  ContinueProcessor() = default;
+};
+
+#endif   // CONTINUE_PROCESSOR_HPP
diff --git a/src/language/node_processor/DoWhileProcessor.hpp b/src/language/node_processor/DoWhileProcessor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..52961c30675a3f48f4bc63af7368de6501486674
--- /dev/null
+++ b/src/language/node_processor/DoWhileProcessor.hpp
@@ -0,0 +1,50 @@
+#ifndef DO_WHILE_PROCESSOR_HPP
+#define DO_WHILE_PROCESSOR_HPP
+
+#include <node_processor/INodeProcessor.hpp>
+
+#include <Demangle.hpp>
+
+class DoWhileProcessor final : public INodeProcessor
+{
+  ASTNode& m_node;
+
+ public:
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
+
+  void
+  execute(ExecUntilBreakOrContinue& exec_policy)
+  {
+    bool continuation_test = true;
+    ExecUntilBreakOrContinue exec_until_jump;
+    do {
+      m_node.children[0]->execute(exec_until_jump);
+      if (not exec_until_jump.exec()) {
+        if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::break_jump) {
+          break;
+        } else if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::continue_jump) {
+          exec_until_jump = ExecUntilBreakOrContinue{};   // getting ready for next loop traversal
+        }
+      }
+      m_node.children[1]->execute(exec_policy);
+      continuation_test = static_cast<bool>(std::visit(
+        [](const auto& value) -> bool {
+          using T = std::decay_t<decltype(value)>;
+          if constexpr (std::is_arithmetic_v<T>) {
+            return value;
+          } else {
+            return false;
+          }
+        },
+        m_node.children[1]->m_value));
+    } while (continuation_test);
+  }
+
+  DoWhileProcessor(ASTNode& node) : m_node{node} {}
+};
+
+#endif   // DO_WHILE_PROCESSOR_HPP
diff --git a/src/language/ExecUntilBreakOrContinue.hpp b/src/language/node_processor/ExecUntilBreakOrContinue.hpp
similarity index 100%
rename from src/language/ExecUntilBreakOrContinue.hpp
rename to src/language/node_processor/ExecUntilBreakOrContinue.hpp
diff --git a/src/language/node_processor/FakeProcessor.hpp b/src/language/node_processor/FakeProcessor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4eb170cbd64eced75c916dd6f05932703a588988
--- /dev/null
+++ b/src/language/node_processor/FakeProcessor.hpp
@@ -0,0 +1,27 @@
+#ifndef FAKE_PROCESSOR_HPP
+#define FAKE_PROCESSOR_HPP
+
+#include <node_processor/INodeProcessor.hpp>
+
+#include <Demangle.hpp>
+
+class FakeProcessor final : public INodeProcessor
+{
+ public:
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
+
+  PUGS_INLINE
+  void
+  execute(ExecUntilBreakOrContinue&)
+  {
+    ;
+  }
+
+  FakeProcessor() = default;
+};
+
+#endif   // FAKE_PROCESSOR_HPP
diff --git a/src/language/node_processor/ForProcessor.hpp b/src/language/node_processor/ForProcessor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a342a45d68090ce4cbd25c84c8b96ed16a9933b0
--- /dev/null
+++ b/src/language/node_processor/ForProcessor.hpp
@@ -0,0 +1,53 @@
+#ifndef FOR_PROCESSOR_HPP
+#define FOR_PROCESSOR_HPP
+
+#include <node_processor/INodeProcessor.hpp>
+
+#include <Demangle.hpp>
+
+class ForProcessor final : public INodeProcessor
+{
+  ASTNode& m_node;
+
+ public:
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
+
+  void
+  execute(ExecUntilBreakOrContinue& exec_policy)
+  {
+    ExecUntilBreakOrContinue exec_until_jump;
+    m_node.children[0]->execute(exec_policy);
+    while ([&]() {
+      m_node.children[1]->execute(exec_policy);
+      return static_cast<bool>(std::visit(
+        [](const auto& value) -> bool {
+          using T = std::decay_t<decltype(value)>;
+          if constexpr (std::is_arithmetic_v<T>) {
+            return value;
+          } else {
+            return false;
+          }
+        },
+        m_node.children[1]->m_value));
+    }()) {
+      m_node.children[3]->execute(exec_until_jump);
+      if (not exec_until_jump.exec()) {
+        if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::break_jump) {
+          break;
+        } else if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::continue_jump) {
+          exec_until_jump = ExecUntilBreakOrContinue{};   // getting ready for next loop traversal
+        }
+      }
+
+      m_node.children[2]->execute(exec_policy);
+    }
+  }
+
+  ForProcessor(ASTNode& node) : m_node{node} {}
+};
+
+#endif   // FOR_PROCESSOR_HPP
diff --git a/src/language/INodeProcessor.hpp b/src/language/node_processor/INodeProcessor.hpp
similarity index 87%
rename from src/language/INodeProcessor.hpp
rename to src/language/node_processor/INodeProcessor.hpp
index c664d57d929f7aa468a41e671ba310429958b848..36156510540cb86870a9bd98d9727be4774c6774 100644
--- a/src/language/INodeProcessor.hpp
+++ b/src/language/node_processor/INodeProcessor.hpp
@@ -1,7 +1,7 @@
 #ifndef I_NODE_PROCESSOR_HPP
 #define I_NODE_PROCESSOR_HPP
 
-#include <ExecUntilBreakOrContinue.hpp>
+#include <node_processor/ExecUntilBreakOrContinue.hpp>
 
 #include <string>
 
diff --git a/src/language/node_processor/IfProcessor.hpp b/src/language/node_processor/IfProcessor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..60dabe8da6dfdf3a3ce4979c66f9ee7f44bcc231
--- /dev/null
+++ b/src/language/node_processor/IfProcessor.hpp
@@ -0,0 +1,48 @@
+#ifndef IF_PROCESSOR_HPP
+#define IF_PROCESSOR_HPP
+
+#include <node_processor/INodeProcessor.hpp>
+
+#include <Demangle.hpp>
+
+class IfProcessor final : public INodeProcessor
+{
+  ASTNode& m_node;
+
+ public:
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
+
+  void
+  execute(ExecUntilBreakOrContinue& exec_policy)
+  {
+    m_node.children[0]->execute(exec_policy);
+    const bool is_true = static_cast<bool>(std::visit(
+      [](const auto& value) -> bool {
+        using T = std::decay_t<decltype(value)>;
+        if constexpr (std::is_arithmetic_v<T>) {
+          return value;
+        } else {
+          return false;
+        }
+      },
+      m_node.children[0]->m_value));
+    if (is_true) {
+      Assert(m_node.children[1] != nullptr);
+      m_node.children[1]->execute(exec_policy);
+    } else {
+      if (m_node.children.size() == 3) {
+        // else statement
+        Assert(m_node.children[2] != nullptr);
+        m_node.children[2]->execute(exec_policy);
+      }
+    }
+  }
+
+  IfProcessor(ASTNode& node) : m_node{node} {}
+};
+
+#endif   // IF_PROCESSOR_HPP
diff --git a/src/language/node_processor/NameProcessor.hpp b/src/language/node_processor/NameProcessor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9da2b5b49325e07ba155cf04c32a873e606f06a2
--- /dev/null
+++ b/src/language/node_processor/NameProcessor.hpp
@@ -0,0 +1,37 @@
+#ifndef NODE_PROCESSOR_HPP
+#define NODE_PROCESSOR_HPP
+
+#include <node_processor/INodeProcessor.hpp>
+
+#include <Demangle.hpp>
+
+#include <SymbolTable.hpp>
+
+class NameProcessor final : public INodeProcessor
+{
+  ASTNode& m_node;
+  ASTNodeDataVariant* p_value{nullptr};
+
+ public:
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
+
+  void
+  execute(ExecUntilBreakOrContinue&)
+  {
+    m_node.m_value = *p_value;
+  }
+
+  NameProcessor(ASTNode& node) : m_node{node}
+  {
+    const std::string& symbol = m_node.string();
+    auto [i_symbol, found]    = m_node.m_symbol_table->find(symbol, m_node.begin());
+    Assert(found);
+    p_value = &(i_symbol->second.value());
+  }
+};
+
+#endif   // NODE_PROCESSOR_HPP
diff --git a/src/language/node_processor/OStreamProcessor.hpp b/src/language/node_processor/OStreamProcessor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..752b97650a74f40c210ad1e4d9b8e7679495433a
--- /dev/null
+++ b/src/language/node_processor/OStreamProcessor.hpp
@@ -0,0 +1,46 @@
+#ifndef OSTREAM_PROCESSOR_HPP
+#define OSTREAM_PROCESSOR_HPP
+
+#include <node_processor/INodeProcessor.hpp>
+
+#include <Demangle.hpp>
+
+class OStreamProcessor final : public INodeProcessor
+{
+  ASTNode& m_node;
+  std::ostream& m_os;
+
+ public:
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
+
+  void
+  execute(ExecUntilBreakOrContinue& exec_policy)
+  {
+    for (size_t i = 0; i < m_node.children.size(); ++i) {
+      m_node.children[i]->execute(exec_policy);
+      std::visit(
+        [&](auto&& value) {
+          using ValueT = std::decay_t<decltype(value)>;
+          if constexpr (not std::is_same_v<std::monostate, ValueT>) {
+            if constexpr (std::is_same_v<bool, ValueT>) {
+              m_os << std::boolalpha << value;
+            } else {
+              m_os << value;
+            }
+          }
+        },
+        m_node.children[i]->m_value);
+    }
+  }
+
+  OStreamProcessor(ASTNode& node, std::ostream& os) : m_node{node}, m_os(os)
+  {
+    ;
+  }
+};
+
+#endif   // OSTREAM_PROCESSOR_HPP
diff --git a/src/language/node_processor/WhileProcessor.hpp b/src/language/node_processor/WhileProcessor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ffa877e9ef17d5e733c194bd759f6e874c4b6f56
--- /dev/null
+++ b/src/language/node_processor/WhileProcessor.hpp
@@ -0,0 +1,50 @@
+#ifndef WHILE_PROCESSOR_HPP
+#define WHILE_PROCESSOR_HPP
+
+#include <node_processor/INodeProcessor.hpp>
+
+#include <Demangle.hpp>
+
+class WhileProcessor final : public INodeProcessor
+{
+  ASTNode& m_node;
+
+ public:
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
+
+  void
+  execute(ExecUntilBreakOrContinue& exec_policy)
+  {
+    ExecUntilBreakOrContinue exec_until_jump;
+    while ([&]() {
+      m_node.children[0]->execute(exec_policy);
+      return static_cast<bool>(std::visit(
+        [](const auto& value) -> bool {
+          using T = std::decay_t<decltype(value)>;
+          if constexpr (std::is_arithmetic_v<T>) {
+            return value;
+          } else {
+            return false;
+          }
+        },
+        m_node.children[0]->m_value));
+    }()) {
+      m_node.children[1]->execute(exec_until_jump);
+      if (not exec_until_jump.exec()) {
+        if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::break_jump) {
+          break;
+        } else if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::continue_jump) {
+          exec_until_jump = ExecUntilBreakOrContinue{};   // getting ready for next loop traversal
+        }
+      }
+    }
+  }
+
+  WhileProcessor(ASTNode& node) : m_node{node} {}
+};
+
+#endif   // WHILE_PROCESSOR_HPP