From ae54f832f19fe6b8c6f81bfc46fbbf551719f1ad Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Wed, 5 Feb 2020 15:06:49 +0100
Subject: [PATCH] Introduce the notion of l-value list

This is a preparation development to take into account list affectations
containing vector component
---
 src/language/ASTBuilder.cpp                     | 7 ++++---
 src/language/ASTNodeDataTypeBuilder.cpp         | 3 ++-
 src/language/ASTNodeExpressionBuilder.cpp       | 4 ++--
 src/language/ASTSymbolInitializationChecker.cpp | 2 +-
 src/language/PEGGrammar.hpp                     | 8 ++++++--
 5 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/src/language/ASTBuilder.cpp b/src/language/ASTBuilder.cpp
index 686a7208b..18d560aec 100644
--- a/src/language/ASTBuilder.cpp
+++ b/src/language/ASTBuilder.cpp
@@ -140,8 +140,8 @@ struct ASTBuilder::simplify_node_list : parse_tree::apply<ASTBuilder::simplify_n
   static void
   transform(std::unique_ptr<ASTNode>& n, States&&... st)
   {
-    if (n->is_type<language::name_list>() or n->is_type<language::function_argument_list>() or
-        n->is_type<language::expression_list>()) {
+    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>()) {
       if (n->children.size() == 1) {
         n = std::move(n->children.back());
         transform(n, st...);
@@ -304,7 +304,8 @@ using selector = parse_tree::selector<
                                  language::post_plusplus>,
   ASTBuilder::simplify_for_statement_block::on<language::for_statement_block>,
   parse_tree::discard_empty::on<language::ignored, language::semicol, language::block>,
-  ASTBuilder::simplify_node_list::on<language::name_list, language::function_argument_list, language::expression_list>,
+  ASTBuilder::simplify_node_list::
+    on<language::name_list, language::lvalue_list, language::function_argument_list, language::expression_list>,
   ASTBuilder::simplify_statement_block::on<language::statement_block>,
   ASTBuilder::simplify_for_init::on<language::for_init>,
   ASTBuilder::simplify_for_test::on<language::for_test>,
diff --git a/src/language/ASTNodeDataTypeBuilder.cpp b/src/language/ASTNodeDataTypeBuilder.cpp
index 58e982fd0..f979a3768 100644
--- a/src/language/ASTNodeDataTypeBuilder.cpp
+++ b/src/language/ASTNodeDataTypeBuilder.cpp
@@ -429,7 +429,8 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
                n.is_type<language::R_set>() or n.is_type<language::string_type>() or
                n.is_type<language::vector_type>()) {
       n.m_data_type = ASTNodeDataType::typename_t;
-    } else if (n.is_type<language::name_list>() or n.is_type<language::function_argument_list>()) {
+    } else if (n.is_type<language::name_list>() or n.is_type<language::lvalue_list>() or
+               n.is_type<language::function_argument_list>()) {
       n.m_data_type = ASTNodeDataType::void_t;
     } else if (n.is_type<language::expression_list>()) {
       n.m_data_type = ASTNodeDataType::list_t;
diff --git a/src/language/ASTNodeExpressionBuilder.cpp b/src/language/ASTNodeExpressionBuilder.cpp
index cc20137ed..55d2db53a 100644
--- a/src/language/ASTNodeExpressionBuilder.cpp
+++ b/src/language/ASTNodeExpressionBuilder.cpp
@@ -34,7 +34,7 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& 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>())) {
-    if (n.children[0]->is_type<language::name_list>()) {
+    if (n.children[0]->is_type<language::name_list>() or n.children[0]->is_type<language::lvalue_list>()) {
       ASTNodeListAffectationExpressionBuilder{n};
     } else {
       ASTNodeAffectationExpressionBuilder{n};
@@ -81,7 +81,7 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n)
   } else if ((n.is_type<language::function_argument_list>()) or (n.is_type<language::expression_list>())) {
     n.m_node_processor = std::make_unique<ASTNodeExpressionListProcessor>(n);
 
-  } else if (n.is_type<language::name_list>()) {
+  } else if (n.is_type<language::name_list>() or n.is_type<language::lvalue_list>()) {
     n.m_node_processor = std::make_unique<FakeProcessor>();
 
   } else if (n.is_type<language::name>()) {
diff --git a/src/language/ASTSymbolInitializationChecker.cpp b/src/language/ASTSymbolInitializationChecker.cpp
index 038e9da4a..7a81547e3 100644
--- a/src/language/ASTSymbolInitializationChecker.cpp
+++ b/src/language/ASTSymbolInitializationChecker.cpp
@@ -54,7 +54,7 @@ ASTSymbolInitializationChecker::_checkSymbolInitialization(ASTNode& node)
 
     if (node.children[0]->is_type<language::name>()) {
       set_is_initialized(*node.children[0]);
-    } else if (node.children[0]->is_type<language::name_list>()) {
+    } else if (node.children[0]->is_type<language::name_list>() or node.children[0]->is_type<language::lvalue_list>()) {
       ASTNode& name_list_node = *node.children[0];
       for (auto& child_node : name_list_node.children) {
         set_is_initialized(*child_node);
diff --git a/src/language/PEGGrammar.hpp b/src/language/PEGGrammar.hpp
index 2baa69521..2a8ea0374 100644
--- a/src/language/PEGGrammar.hpp
+++ b/src/language/PEGGrammar.hpp
@@ -226,9 +226,13 @@ struct affect_op : sor< eq_op, multiplyeq_op, divideeq_op, pluseq_op, minuseq_op
 
 struct name_subscript_expression : seq< NAME, plus< subscript_expression > >{};
 
-struct name_list;
+struct lvalue_expression : sor< name_subscript_expression, NAME >{};
+
+struct lvalue_list : seq< open_parent, list_must< lvalue_expression, COMMA >, close_parent >{};
 
-struct affectation : seq< sor< name_subscript_expression, NAME, name_list >, if_must< affect_op,  sor< expression_list, expression > > >{};
+struct affectation : seq< sor< lvalue_expression, lvalue_list >, if_must< affect_op,  sor< expression_list, expression > > >{};
+
+struct name_list;
 
 struct declaration : if_must< TYPE_EXPRESSION, sor< NAME, name_list>, opt< if_must< seq< one< '=' >, ignored >, sor< expression_list, expression > > > >{};
 
-- 
GitLab