From 0bdc93d9057faefdaa0a3c58de24f242f2c6b2d1 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Mon, 21 Oct 2019 11:42:31 +0200
Subject: [PATCH] Simplify language::name_list to language::name when building
 the AST

This allows a cleaner function declaration and simplify evaluation
---
 src/language/ASTBuilder.cpp                   | 18 +++++++++++++-
 src/language/ASTBuilder.hpp                   |  1 +
 src/language/ASTNodeDataTypeBuilder.cpp       | 24 +++++++++----------
 .../ASTNodeFunctionExpressionBuilder.cpp      |  6 +----
 4 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/src/language/ASTBuilder.cpp b/src/language/ASTBuilder.cpp
index 56ebc43fa..0583dcffd 100644
--- a/src/language/ASTBuilder.cpp
+++ b/src/language/ASTBuilder.cpp
@@ -123,6 +123,22 @@ struct ASTBuilder::simplify_unary : parse_tree::apply<ASTBuilder::simplify_unary
   }
 };
 
+struct ASTBuilder::simplify_name_list : parse_tree::apply<ASTBuilder::simplify_name_list>
+{
+  template <typename... States>
+  static void
+  transform(std::unique_ptr<ASTNode>& n, States&&... st)
+  {
+    if (n->is_type<language::name_list>()) {
+      if (n->children.size() == 1) {
+        n->remove_content();
+        n = std::move(n->children.back());
+        transform(n, st...);
+      }
+    }
+  }
+};
+
 struct ASTBuilder::simplify_statement_block : parse_tree::apply<ASTBuilder::simplify_statement_block>
 {
   template <typename... States>
@@ -222,7 +238,6 @@ using selector = parse_tree::selector<
                                 real,
                                 literal,
                                 name,
-                                name_list,
                                 expression_list,
                                 B_set,
                                 N_set,
@@ -270,6 +285,7 @@ using selector = parse_tree::selector<
                                  post_plusplus>,
   ASTBuilder::simplify_for_statement_block::on<for_statement_block>,
   parse_tree::discard_empty::on<ignored, semicol, block>,
+  ASTBuilder::simplify_name_list::on<name_list>,
   ASTBuilder::simplify_statement_block::on<statement_block>,
   ASTBuilder::simplify_for_init::on<for_init>,
   ASTBuilder::simplify_for_test::on<for_test>,
diff --git a/src/language/ASTBuilder.hpp b/src/language/ASTBuilder.hpp
index d7f0b57b1..703f46bc1 100644
--- a/src/language/ASTBuilder.hpp
+++ b/src/language/ASTBuilder.hpp
@@ -9,6 +9,7 @@ struct ASTBuilder
  private:
   struct rearrange;
   struct simplify_unary;
+  struct simplify_name_list;
   struct simplify_statement_block;
   struct simplify_for_statement_block;
   struct simplify_for_init;
diff --git a/src/language/ASTNodeDataTypeBuilder.cpp b/src/language/ASTNodeDataTypeBuilder.cpp
index 350e22622..c22373b04 100644
--- a/src/language/ASTNodeDataTypeBuilder.cpp
+++ b/src/language/ASTNodeDataTypeBuilder.cpp
@@ -98,6 +98,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n)
         }
 
         auto simple_type_allocator = [&](const ASTNode& type_node, ASTNode& symbol_node) {
+          Assert(symbol_node.is_type<language::name>());
           ASTNodeDataType data_type{ASTNodeDataType::undefined_t};
           if (type_node.is_type<language::B_set>()) {
             data_type = ASTNodeDataType::bool_t;
@@ -124,11 +125,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n)
         };
 
         if (parameters_domain_node.children.size() == 0) {
-          if (parameters_name_node.is_type<language::name_list>()) {
-            simple_type_allocator(parameters_domain_node, *parameters_name_node.children[0]);
-          } else {
-            simple_type_allocator(parameters_domain_node, parameters_name_node);
-          }
+          simple_type_allocator(parameters_domain_node, parameters_name_node);
         } else {
           for (size_t i = 0; i < function_descriptor.domainMappingNode().children.size(); ++i) {
             simple_type_allocator(*parameters_domain_node.children[i], *parameters_name_node.children[i]);
@@ -164,12 +161,14 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n)
 
     if (n.is_type<language::break_kw>() or n.is_type<language::continue_kw>()) {
       n.m_data_type = ASTNodeDataType::void_t;
-    } else if (n.is_type<language::eq_op>() or n.is_type<language::multiplyeq_op>() or n.is_type<language::divideeq_op>() or
-               n.is_type<language::pluseq_op>() or n.is_type<language::minuseq_op>()) {
+    } else if (n.is_type<language::eq_op>() or n.is_type<language::multiplyeq_op>() or
+               n.is_type<language::divideeq_op>() or n.is_type<language::pluseq_op>() or
+               n.is_type<language::minuseq_op>()) {
       n.m_data_type = n.children[0]->m_data_type;
     } else if (n.is_type<language::type_mapping>() or n.is_type<language::function_definition>()) {
       n.m_data_type = ASTNodeDataType::void_t;
-    } else if (n.is_type<language::for_post>() or n.is_type<language::for_init>() or n.is_type<language::for_statement_block>()) {
+    } else if (n.is_type<language::for_post>() or n.is_type<language::for_init>() or
+               n.is_type<language::for_statement_block>()) {
       n.m_data_type = ASTNodeDataType::void_t;
     } else if (n.is_type<language::for_test>()) {
       n.m_data_type = ASTNodeDataType::bool_t;
@@ -197,8 +196,9 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n)
                 << std::ends;
         throw parse_error(message.str(), n.children[1]->begin());
       }
-    } else if (n.is_type<language::unary_not>() or n.is_type<language::lesser_op>() or n.is_type<language::lesser_or_eq_op>() or
-               n.is_type<language::greater_op>() or n.is_type<language::greater_or_eq_op>() or n.is_type<language::eqeq_op>() or
+    } else if (n.is_type<language::unary_not>() or n.is_type<language::lesser_op>() or
+               n.is_type<language::lesser_or_eq_op>() or n.is_type<language::greater_op>() or
+               n.is_type<language::greater_or_eq_op>() or n.is_type<language::eqeq_op>() or
                n.is_type<language::not_eq_op>() or n.is_type<language::and_op>() or n.is_type<language::or_op>() or
                n.is_type<language::xor_op>()) {
       n.m_data_type = ASTNodeDataType::bool_t;
@@ -213,8 +213,8 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n)
     } else if (n.is_type<language::unary_plusplus>() or n.is_type<language::unary_minusminus>() or
                n.is_type<language::post_plusplus>() or n.is_type<language::post_minusminus>()) {
       n.m_data_type = n.children[0]->m_data_type;
-    } else if (n.is_type<language::plus_op>() or n.is_type<language::minus_op>() or n.is_type<language::multiply_op>() or
-               n.is_type<language::divide_op>()) {
+    } else if (n.is_type<language::plus_op>() or n.is_type<language::minus_op>() or
+               n.is_type<language::multiply_op>() or n.is_type<language::divide_op>()) {
       const ASTNodeDataType type_0 = n.children[0]->m_data_type;
       const ASTNodeDataType type_1 = n.children[1]->m_data_type;
       if ((type_0 == ASTNodeDataType::bool_t) and (type_1 == ASTNodeDataType::bool_t)) {
diff --git a/src/language/ASTNodeFunctionExpressionBuilder.cpp b/src/language/ASTNodeFunctionExpressionBuilder.cpp
index 4e89c79eb..bb846e1a5 100644
--- a/src/language/ASTNodeFunctionExpressionBuilder.cpp
+++ b/src/language/ASTNodeFunctionExpressionBuilder.cpp
@@ -100,11 +100,7 @@ ASTNodeFunctionExpressionBuilder::_buildArgumentProcessors(FunctionDescriptor& f
       this->_storeArgumentProcessor(parameter_variable, argument_node, function_processor);
     }
   } else {
-    if (parameter_variables.is_type<language::name_list>()) {
-      this->_storeArgumentProcessor(*parameter_variables.children[0], argument_nodes, function_processor);
-    } else {
-      this->_storeArgumentProcessor(parameter_variables, argument_nodes, function_processor);
-    }
+    this->_storeArgumentProcessor(parameter_variables, argument_nodes, function_processor);
   }
 }
 
-- 
GitLab