From ab824ca55f2591c97e2764988a4b42689e16c034 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Wed, 2 Oct 2019 19:12:30 +0200
Subject: [PATCH] Prepare function processor splitting

This will allow multiple argument casting and processing; and then vector
function treatment
---
 .../ASTNodeFunctionExpressionBuilder.cpp      | 22 ++++++++---
 .../node_processor/FunctionProcessor.hpp      | 38 ++++++++++++++++++-
 2 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/src/language/ASTNodeFunctionExpressionBuilder.cpp b/src/language/ASTNodeFunctionExpressionBuilder.cpp
index e3238d45b..e65df46e5 100644
--- a/src/language/ASTNodeFunctionExpressionBuilder.cpp
+++ b/src/language/ASTNodeFunctionExpressionBuilder.cpp
@@ -15,27 +15,35 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node
   FunctionDescriptor& function_descriptor = node.m_symbol_table->functionTable()[function_id];
 
 #warning compute the right value type
-  const ASTNodeDataType return_value_type     = ASTNodeDataType::double_t;
+  const ASTNodeDataType return_value_type = ASTNodeDataType::double_t;
+
+  if (function_descriptor.definitionNode().children[1]->is<language::expression_list>()) {
+    throw parse_error("unexpected error: function expression list is not implemented yet",
+                      std::vector{function_descriptor.definitionNode().children[1]->begin()});
+  }
+
   const ASTNodeDataType expression_value_type = function_descriptor.definitionNode().children[1]->m_data_type;
 
+  std::unique_ptr<INodeProcessor> function_expression_processor;
+
   auto set_function_processor = [&](ASTNode& node) {
     auto set_function_processor_for_expression_value = [&](const auto& return_v) {
       using ReturnT = std::decay_t<decltype(return_v)>;
       switch (expression_value_type) {
       case ASTNodeDataType::bool_t: {
-        node.m_node_processor = std::make_unique<FunctionProcessor<ReturnT, bool>>(node);
+        function_expression_processor = std::make_unique<FunctionExpressionProcessor<ReturnT, bool>>(node);
         break;
       }
       case ASTNodeDataType::unsigned_int_t: {
-        node.m_node_processor = std::make_unique<FunctionProcessor<ReturnT, uint64_t>>(node);
+        function_expression_processor = std::make_unique<FunctionExpressionProcessor<ReturnT, uint64_t>>(node);
         break;
       }
       case ASTNodeDataType::int_t: {
-        node.m_node_processor = std::make_unique<FunctionProcessor<ReturnT, int64_t>>(node);
+        function_expression_processor = std::make_unique<FunctionExpressionProcessor<ReturnT, int64_t>>(node);
         break;
       }
       case ASTNodeDataType::double_t: {
-        node.m_node_processor = std::make_unique<FunctionProcessor<ReturnT, double>>(node);
+        function_expression_processor = std::make_unique<FunctionExpressionProcessor<ReturnT, double>>(node);
         break;
       }
       default: {
@@ -73,4 +81,8 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node
   };
 
   set_function_processor(node);
+
+  std::unique_ptr function_processor = std::make_unique<FunctionProcessor>();
+  function_processor->addFunctionExpressionProcessor(std::move(function_expression_processor));
+  node.m_node_processor = std::move(function_processor);
 }
diff --git a/src/language/node_processor/FunctionProcessor.hpp b/src/language/node_processor/FunctionProcessor.hpp
index 57394f993..2fae6c16d 100644
--- a/src/language/node_processor/FunctionProcessor.hpp
+++ b/src/language/node_processor/FunctionProcessor.hpp
@@ -11,7 +11,7 @@
 #include <node_processor/INodeProcessor.hpp>
 
 template <typename ReturnType, typename ExpressionValueType>
-class FunctionProcessor final : public INodeProcessor
+class FunctionExpressionProcessor final : public INodeProcessor
 {
  private:
   ASTNode& m_node;
@@ -62,7 +62,7 @@ class FunctionProcessor final : public INodeProcessor
     }
   }
 
-  FunctionProcessor(ASTNode& node)
+  FunctionExpressionProcessor(ASTNode& node)
     : m_node{node}, m_function_descriptor{[&]() -> FunctionDescriptor& {
         auto [i_symbol, found] = m_node.m_symbol_table->find(m_node.children[0]->string(), m_node.begin());
         Assert(found);
@@ -73,4 +73,38 @@ class FunctionProcessor final : public INodeProcessor
   {}
 };
 
+class FunctionProcessor : public INodeProcessor
+{
+ private:
+  std::vector<std::unique_ptr<INodeProcessor>> m_argument_processors;
+  std::vector<std::unique_ptr<INodeProcessor>> m_function_expression_processors;
+
+ public:
+  void
+  addArgumentProcessor(std::unique_ptr<INodeProcessor>&& argument_processor)
+  {
+    m_argument_processors.emplace_back(std::move(argument_processor));
+  }
+
+  void
+  addFunctionExpressionProcessor(std::unique_ptr<INodeProcessor>&& function_processor)
+  {
+    m_function_expression_processors.emplace_back(std::move(function_processor));
+  }
+
+  void
+  execute(ExecUntilBreakOrContinue& exec_policy)
+  {
+    for (auto& argument_processor : m_argument_processors) {
+      argument_processor->execute(exec_policy);
+    }
+
+    for (auto& function_expression_processor : m_function_expression_processors) {
+      function_expression_processor->execute(exec_policy);
+    }
+  }
+
+  FunctionProcessor() = default;
+};
+
 #endif   // FUNCTION_PROCESSOR_HPP
-- 
GitLab