From c37ed55c0b926d4f55079a461166e2915cb35e48 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Mon, 21 Oct 2019 18:30:51 +0200
Subject: [PATCH] Add language::function_argument_list AST node type

It aims at clarifying function arguments treatment, since
language::expression_list's use could be ambiguous

``
let f: x -> (x+2)/2;
``
would generate a parse error and there was no clean way to fix it considering
just `language::expression` and `language::expression_list`
---
 src/language/ASTBuilder.cpp                   | 24 ++++---------------
 src/language/ASTBuilder.hpp                   |  3 +--
 .../ASTNodeCFunctionExpressionBuilder.cpp     |  3 ++-
 src/language/ASTNodeDataTypeBuilder.cpp       |  3 ++-
 src/language/ASTNodeExpressionBuilder.cpp     | 13 ++++++----
 .../ASTNodeFunctionExpressionBuilder.cpp      |  2 +-
 src/language/PEGGrammar.hpp                   |  6 ++---
 7 files changed, 22 insertions(+), 32 deletions(-)

diff --git a/src/language/ASTBuilder.cpp b/src/language/ASTBuilder.cpp
index 8cbd519d1..6d1b00f89 100644
--- a/src/language/ASTBuilder.cpp
+++ b/src/language/ASTBuilder.cpp
@@ -123,29 +123,14 @@ struct ASTBuilder::simplify_unary : parse_tree::apply<ASTBuilder::simplify_unary
   }
 };
 
-struct ASTBuilder::simplify_name_list : parse_tree::apply<ASTBuilder::simplify_name_list>
+struct ASTBuilder::simplify_node_list : parse_tree::apply<ASTBuilder::simplify_node_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_expression_list : parse_tree::apply<ASTBuilder::simplify_expression_list>
-{
-  template <typename... States>
-  static void
-  transform(std::unique_ptr<ASTNode>& n, States&&... st)
-  {
-    if (n->is_type<language::expression_list>()) {
+    if (n->is_type<language::name_list>() or n->is_type<language::function_argument_list>() or
+        n->is_type<language::expression_list>()) {
       if (n->children.size() == 1) {
         n->remove_content();
         n = std::move(n->children.back());
@@ -300,8 +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_expression_list::on<expression_list>,
+  ASTBuilder::simplify_node_list::on<name_list, function_argument_list, expression_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 bae52ea95..51a1a2f1b 100644
--- a/src/language/ASTBuilder.hpp
+++ b/src/language/ASTBuilder.hpp
@@ -9,8 +9,7 @@ struct ASTBuilder
  private:
   struct rearrange;
   struct simplify_unary;
-  struct simplify_name_list;
-  struct simplify_expression_list;
+  struct simplify_node_list;
   struct simplify_statement_block;
   struct simplify_for_statement_block;
   struct simplify_for_init;
diff --git a/src/language/ASTNodeCFunctionExpressionBuilder.cpp b/src/language/ASTNodeCFunctionExpressionBuilder.cpp
index 90bede031..ec50f7b53 100644
--- a/src/language/ASTNodeCFunctionExpressionBuilder.cpp
+++ b/src/language/ASTNodeCFunctionExpressionBuilder.cpp
@@ -76,7 +76,8 @@ ASTNodeCFunctionExpressionBuilder::_buildArgumentProcessors(ASTNode& node,
 {
   ASTNode& argument_nodes = *node.children[1];
 
-  const size_t arguments_number = argument_nodes.is_type<language::expression_list>() ? argument_nodes.children.size() : 1;
+  const size_t arguments_number =
+    argument_nodes.is_type<language::function_argument_list>() ? argument_nodes.children.size() : 1;
 
   c_function_processor.setNumberOfArguments(arguments_number);
 
diff --git a/src/language/ASTNodeDataTypeBuilder.cpp b/src/language/ASTNodeDataTypeBuilder.cpp
index c22373b04..a42a8d0a8 100644
--- a/src/language/ASTNodeDataTypeBuilder.cpp
+++ b/src/language/ASTNodeDataTypeBuilder.cpp
@@ -286,7 +286,8 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n)
     } else if (n.is_type<language::B_set>() or n.is_type<language::Z_set>() or n.is_type<language::N_set>() or
                n.is_type<language::R_set>() or n.is_type<language::string_type>()) {
       n.m_data_type = ASTNodeDataType::typename_t;
-    } else if (n.is_type<language::name_list>() or n.is_type<language::expression_list>()) {
+    } else if (n.is_type<language::name_list>() or n.is_type<language::expression_list>() or
+               n.is_type<language::function_argument_list>()) {
       n.m_data_type = ASTNodeDataType::void_t;
     }
   }
diff --git a/src/language/ASTNodeExpressionBuilder.cpp b/src/language/ASTNodeExpressionBuilder.cpp
index 7cf1e8d94..d15e7265b 100644
--- a/src/language/ASTNodeExpressionBuilder.cpp
+++ b/src/language/ASTNodeExpressionBuilder.cpp
@@ -24,8 +24,9 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n)
 {
   if (n.is_type<language::block>()) {
     n.m_node_processor = std::make_unique<ASTNodeListProcessor>(n);
-  } 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>())) {
     ASTNodeAffectationExpressionBuilder{n};
 
   } else if (n.is_type<language::function_definition>()) {
@@ -45,6 +46,9 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n)
   } else if (n.is_type<language::false_kw>()) {
     n.m_node_processor = std::make_unique<FakeProcessor>();
 
+  } else if (n.is_type<language::function_argument_list>()) {
+    n.m_node_processor = std::make_unique<FakeProcessor>();
+
   } else if (n.is_type<language::expression_list>()) {
     n.m_node_processor = std::make_unique<FakeProcessor>();
 
@@ -63,8 +67,9 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n)
 
   } else if (n.is_type<language::multiply_op>() or n.is_type<language::divide_op>() or n.is_type<language::plus_op>() or
              n.is_type<language::minus_op>() or n.is_type<language::or_op>() or n.is_type<language::and_op>() or
-             n.is_type<language::xor_op>() or n.is_type<language::greater_op>() or n.is_type<language::greater_or_eq_op>() or
-             n.is_type<language::lesser_op>() or n.is_type<language::lesser_or_eq_op>() or n.is_type<language::eqeq_op>() or
+             n.is_type<language::xor_op>() or n.is_type<language::greater_op>() or
+             n.is_type<language::greater_or_eq_op>() or n.is_type<language::lesser_op>() or
+             n.is_type<language::lesser_or_eq_op>() or n.is_type<language::eqeq_op>() or
              n.is_type<language::not_eq_op>()) {
     ASTNodeBinaryOperatorExpressionBuilder{n};
 
diff --git a/src/language/ASTNodeFunctionExpressionBuilder.cpp b/src/language/ASTNodeFunctionExpressionBuilder.cpp
index bb846e1a5..11183dbad 100644
--- a/src/language/ASTNodeFunctionExpressionBuilder.cpp
+++ b/src/language/ASTNodeFunctionExpressionBuilder.cpp
@@ -82,7 +82,7 @@ ASTNodeFunctionExpressionBuilder::_buildArgumentProcessors(FunctionDescriptor& f
   ASTNode& argument_nodes = *node.children[1];
 
   const size_t arguments_number =
-    argument_nodes.is_type<language::expression_list>() ? argument_nodes.children.size() : 1;
+    argument_nodes.is_type<language::function_argument_list>() ? argument_nodes.children.size() : 1;
   const size_t parameters_number =
     parameter_variables.is_type<language::name_list>() ? parameter_variables.children.size() : 1;
 
diff --git a/src/language/PEGGrammar.hpp b/src/language/PEGGrammar.hpp
index 6e095fcbe..245096229 100644
--- a/src/language/PEGGrammar.hpp
+++ b/src/language/PEGGrammar.hpp
@@ -136,10 +136,10 @@ struct open_parent : seq< one< '(' >, ignored > {};
 struct close_parent : seq< one< ')' >, ignored > {};
 
 struct expression;
-struct parented_expression : if_must< open_parent, expression, close_parent > {};
+struct parented_expression : if_must< open_parent, expression, close_parent >{};
 
-struct expression_list;
-struct function_evaluation : seq< NAME, sor<  expression_list, parented_expression > > {};
+struct function_argument_list : if_must< open_parent, list_must< expression, COMMA >, close_parent >{};
+struct function_evaluation : seq< NAME, function_argument_list > {};
 
 struct primary_expression : sor< BOOL, REAL, INTEGER, LITERAL, function_evaluation, NAME, parented_expression > {};
 
-- 
GitLab