From 03a2019e63e24d8ac9249615d9a4abbafa885268 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Wed, 7 Oct 2020 15:17:04 +0200
Subject: [PATCH] Fix list of tuples grammar and its AST simplification

Actually, for instance, list of tuples of R^2 defined as
`((1,2), (2,3))`
were treated correctly but in the case of a single element
`((1,2))` was interpreted as `(1,2)` which is a tuple of natural
integers.
---
 src/language/PEGGrammar.hpp     | 5 ++++-
 src/language/ast/ASTBuilder.cpp | 7 ++++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/language/PEGGrammar.hpp b/src/language/PEGGrammar.hpp
index 61ba912a5..fb3b1d74a 100644
--- a/src/language/PEGGrammar.hpp
+++ b/src/language/PEGGrammar.hpp
@@ -229,7 +229,10 @@ struct expression : logical_or {};
 
 struct tuple_expression : seq< open_parent, expression, plus< if_must< COMMA, expression > >, close_parent >{};
 
-struct expression_list : seq< open_parent, sor< tuple_expression, expression >, plus< if_must< COMMA, sor< tuple_expression, expression > > >, close_parent >{};
+struct expression_list : seq< open_parent, sor< seq< tuple_expression,
+						     star< if_must< COMMA, sor< tuple_expression, expression > > > >,
+						seq< expression,
+						     plus< if_must< COMMA, sor< tuple_expression, expression > >  > > >, close_parent >{};
 
 struct affect_op : sor< eq_op, multiplyeq_op, divideeq_op, pluseq_op, minuseq_op > {};
 
diff --git a/src/language/ast/ASTBuilder.cpp b/src/language/ast/ASTBuilder.cpp
index cef779ffc..57db20497 100644
--- a/src/language/ast/ASTBuilder.cpp
+++ b/src/language/ast/ASTBuilder.cpp
@@ -138,11 +138,16 @@ struct ASTBuilder::simplify_node_list : parse_tree::apply<ASTBuilder::simplify_n
   transform(std::unique_ptr<ASTNode>& n, States&&... st)
   {
     if (n->is_type<language::name_list>() or n->is_type<language::lvalue_list>() or
-        n->is_type<language::function_argument_list>() or n->is_type<language::expression_list>()) {
+        n->is_type<language::function_argument_list>()) {
       if (n->children.size() == 1) {
         n = std::move(n->children.back());
         transform(n, st...);
       }
+    } else if (n->is_type<language::expression_list>()) {
+      if ((n->children.size() == 1) and (not n->children[0]->is_type<language::tuple_expression>())) {
+        n = std::move(n->children.back());
+        transform(n, st...);
+      }
     }
   }
 };
-- 
GitLab