From 5d3e5b3d5c69f60c503eee6221e5b1135e728809 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Thu, 19 Sep 2019 14:49:28 +0200
Subject: [PATCH] Prepare complex type handling

Grammar allows constructions such as
``
let f : R*R -> R*R, x -> x;
``
This expression does not actually compiles since expression types are not
correctly defined, thus semantic analysis fails
---
 src/language/ASTBuilder.cpp             | 117 ++++++++++++------------
 src/language/ASTNodeDataTypeBuilder.cpp |   2 +-
 src/language/PEGGrammar.hpp             |   6 +-
 3 files changed, 64 insertions(+), 61 deletions(-)

diff --git a/src/language/ASTBuilder.cpp b/src/language/ASTBuilder.cpp
index 984ed5cba..239da703c 100644
--- a/src/language/ASTBuilder.cpp
+++ b/src/language/ASTBuilder.cpp
@@ -62,7 +62,7 @@ struct ASTBuilder::simplify_unary : parse_tree::apply<ASTBuilder::simplify_unary
   transform(std::unique_ptr<ASTNode>& n, States&&... st)
   {
     if (n->children.size() == 1) {
-      if (n->is<unary_expression>()) {
+      if (n->is<unary_expression>() or n->is<type_expression>()) {
         n->remove_content();
         n = std::move(n->children.back());
         transform(n, st...);
@@ -201,63 +201,64 @@ struct ASTBuilder::simplify_stream_statement : parse_tree::apply<ASTBuilder::sim
 };
 
 template <typename Rule>
-using selector = parse_tree::selector<
-  Rule,
-  parse_tree::store_content::on<true_kw,
-                                false_kw,
-                                integer,
-                                real,
-                                literal,
-                                name,
-                                B_set,
-                                N_set,
-                                Z_set,
-                                R_set,
-                                string_type,
-                                cout_kw,
-                                cerr_kw,
-                                clog_kw,
-                                declaration,
-                                let_declaration,
-                                function_domain_mapping,
-                                function_definition,
-                                if_statement,
-                                do_while_statement,
-                                while_statement,
-                                for_statement,
-                                break_kw,
-                                continue_kw>,
-  ASTBuilder::rearrange::on<product, affectation, expression>,
-  ASTBuilder::simplify_unary::on<unary_minus, unary_plus, unary_not, function_evaluation, unary_expression>,
-  parse_tree::remove_content::on<plus_op,
-                                 minus_op,
-                                 multiply_op,
-                                 divide_op,
-                                 lesser_op,
-                                 lesser_or_eq_op,
-                                 greater_op,
-                                 greater_or_eq_op,
-                                 eqeq_op,
-                                 not_eq_op,
-                                 and_op,
-                                 or_op,
-                                 xor_op,
-                                 eq_op,
-                                 multiplyeq_op,
-                                 divideeq_op,
-                                 pluseq_op,
-                                 minuseq_op,
-                                 unary_plusplus,
-                                 unary_minusminus,
-                                 post_minusminus,
-                                 post_plusplus>,
-  ASTBuilder::simplify_for_statement_block::on<for_statement_block>,
-  parse_tree::discard_empty::on<ignored, semicol, block>,
-  ASTBuilder::simplify_statement_block::on<statement_block>,
-  ASTBuilder::simplify_for_init::on<for_init>,
-  ASTBuilder::simplify_for_test::on<for_test>,
-  ASTBuilder::simplify_for_post::on<for_post>,
-  ASTBuilder::simplify_stream_statement::on<ostream_statement>>;
+using selector =
+  parse_tree::selector<Rule,
+                       parse_tree::store_content::on<true_kw,
+                                                     false_kw,
+                                                     integer,
+                                                     real,
+                                                     literal,
+                                                     name,
+                                                     B_set,
+                                                     N_set,
+                                                     Z_set,
+                                                     R_set,
+                                                     string_type,
+                                                     cout_kw,
+                                                     cerr_kw,
+                                                     clog_kw,
+                                                     declaration,
+                                                     let_declaration,
+                                                     type_mapping,
+                                                     function_definition,
+                                                     if_statement,
+                                                     do_while_statement,
+                                                     while_statement,
+                                                     for_statement,
+                                                     break_kw,
+                                                     continue_kw>,
+                       ASTBuilder::rearrange::on<product, affectation, expression>,
+                       ASTBuilder::simplify_unary::
+                         on<unary_minus, unary_plus, unary_not, function_evaluation, type_expression, unary_expression>,
+                       parse_tree::remove_content::on<plus_op,
+                                                      minus_op,
+                                                      multiply_op,
+                                                      divide_op,
+                                                      lesser_op,
+                                                      lesser_or_eq_op,
+                                                      greater_op,
+                                                      greater_or_eq_op,
+                                                      eqeq_op,
+                                                      not_eq_op,
+                                                      and_op,
+                                                      or_op,
+                                                      xor_op,
+                                                      eq_op,
+                                                      multiplyeq_op,
+                                                      divideeq_op,
+                                                      pluseq_op,
+                                                      minuseq_op,
+                                                      unary_plusplus,
+                                                      unary_minusminus,
+                                                      post_minusminus,
+                                                      post_plusplus>,
+                       ASTBuilder::simplify_for_statement_block::on<for_statement_block>,
+                       parse_tree::discard_empty::on<ignored, semicol, block>,
+                       ASTBuilder::simplify_statement_block::on<statement_block>,
+                       ASTBuilder::simplify_for_init::on<for_init>,
+                       ASTBuilder::simplify_for_test::on<for_test>,
+                       ASTBuilder::simplify_for_post::on<for_post>,
+                       ASTBuilder::simplify_stream_statement::on<ostream_statement>>;
 
 template <typename InputT>
 std::unique_ptr<ASTNode>
diff --git a/src/language/ASTNodeDataTypeBuilder.cpp b/src/language/ASTNodeDataTypeBuilder.cpp
index b30adf664..11a812465 100644
--- a/src/language/ASTNodeDataTypeBuilder.cpp
+++ b/src/language/ASTNodeDataTypeBuilder.cpp
@@ -108,7 +108,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n)
     } else if (n.is<language::eq_op>() or n.is<language::multiplyeq_op>() or n.is<language::divideeq_op>() or
                n.is<language::pluseq_op>() or n.is<language::minuseq_op>()) {
       n.m_data_type = n.children[0]->m_data_type;
-    } else if (n.is<language::function_domain_mapping>() or n.is<language::function_definition>()) {
+    } else if (n.is<language::type_mapping>() or n.is<language::function_definition>()) {
       n.m_data_type = ASTNodeDataType::void_t;
     } else if (n.is<language::for_post>() or n.is<language::for_init>() or n.is<language::for_statement_block>()) {
       n.m_data_type = ASTNodeDataType::void_t;
diff --git a/src/language/PEGGrammar.hpp b/src/language/PEGGrammar.hpp
index 3a8eda150..646842bf3 100644
--- a/src/language/PEGGrammar.hpp
+++ b/src/language/PEGGrammar.hpp
@@ -203,10 +203,12 @@ struct affectation : seq< NAME , if_must< affect_op, expression > >{};
 
 struct declaration : if_must< TYPESPECIFIER, NAME, opt< if_must< seq< one< '=' >, ignored >, expression > > >{};
 
-struct function_domain_mapping : seq< TYPESPECIFIER, RIGHT_ARROW, TYPESPECIFIER >{};
+struct type_expression : list_must< TYPESPECIFIER, one< '*' > >{};
+
+struct type_mapping : seq< type_expression, RIGHT_ARROW, type_expression >{};
 struct function_definition : seq< NAME, RIGHT_ARROW, expression >{};
 
-struct let_declaration : if_must< LET, NAME, COLUMN, function_domain_mapping, COMMA, function_definition >{};
+struct let_declaration : if_must< LET, NAME, COLUMN, type_mapping, COMMA, function_definition >{};
 
 struct open_brace : seq< one< '{' >, ignored >{};
 struct close_brace : seq< one< '}' >, ignored >{};
-- 
GitLab