From 713aba1cd7b9cacefa203f0eea4303682925c3c1 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Wed, 19 Feb 2020 17:54:09 +0100
Subject: [PATCH] Prepare use of non-basic types

The goal is to be able to define more high-level types such as `mesh` for
instance that will be defined in modules that will be loaded on-demand.

Now, one can write
``
let m:mesh;
``
It remains to give functions to build and manipulate meshes. A first step is to
improve module management.
---
 src/language/ASTBuilder.cpp             |  1 +
 src/language/ASTNodeDataType.cpp        |  3 +++
 src/language/ASTNodeDataType.hpp        | 10 ++++++++--
 src/language/ASTNodeDataTypeBuilder.cpp |  4 +++-
 src/language/PEGGrammar.hpp             |  6 +++---
 5 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/src/language/ASTBuilder.cpp b/src/language/ASTBuilder.cpp
index 67ef30cd2..7692ed981 100644
--- a/src/language/ASTBuilder.cpp
+++ b/src/language/ASTBuilder.cpp
@@ -244,6 +244,7 @@ using selector = parse_tree::selector<
                                 language::N_set,
                                 language::Z_set,
                                 language::R_set,
+                                language::type_id,
                                 language::tuple_expression,
                                 language::vector_type,
                                 language::string_type,
diff --git a/src/language/ASTNodeDataType.cpp b/src/language/ASTNodeDataType.cpp
index f5a3ff29e..cbbc95fe8 100644
--- a/src/language/ASTNodeDataType.cpp
+++ b/src/language/ASTNodeDataType.cpp
@@ -46,6 +46,9 @@ dataTypeName(const ASTNodeDataType& data_type)
   case ASTNodeDataType::typename_t:
     name = "typename";
     break;
+  case ASTNodeDataType::type_id_t:
+    name = "type_id";
+    break;
   case ASTNodeDataType::function_t:
     name = "function";
     break;
diff --git a/src/language/ASTNodeDataType.hpp b/src/language/ASTNodeDataType.hpp
index 2d220a4d9..af053c4d8 100644
--- a/src/language/ASTNodeDataType.hpp
+++ b/src/language/ASTNodeDataType.hpp
@@ -20,14 +20,16 @@ class ASTNodeDataType
     list_t         = 5,
     string_t       = 6,
     typename_t     = 10,
-    function_t     = 11,
-    c_function_t   = 12,
+    type_id_t      = 20,
+    function_t     = 21,
+    c_function_t   = 22,
     void_t         = std::numeric_limits<int32_t>::max()
   };
 
  private:
   DataType m_data_type;
   size_t m_dimension;
+  std::string_view m_type_name;
 
  public:
   size_t
@@ -47,6 +49,10 @@ class ASTNodeDataType
 
   ASTNodeDataType(DataType data_type, size_t dimension) : m_data_type{data_type}, m_dimension{dimension} {}
 
+  ASTNodeDataType(DataType data_type, std::string_view type_name)
+    : m_data_type{data_type}, m_dimension{1}, m_type_name{type_name}
+  {}
+
   ASTNodeDataType(const ASTNodeDataType&) = default;
 
   ~ASTNodeDataType() = default;
diff --git a/src/language/ASTNodeDataTypeBuilder.cpp b/src/language/ASTNodeDataTypeBuilder.cpp
index 07e32c1f2..bf6ebea68 100644
--- a/src/language/ASTNodeDataTypeBuilder.cpp
+++ b/src/language/ASTNodeDataTypeBuilder.cpp
@@ -41,6 +41,8 @@ ASTNodeDataTypeBuilder::_buildDeclarationNodeDataTypes(ASTNode& type_node, ASTNo
       data_type = getVectorDataType(type_node);
     } else if (type_node.is_type<language::string_type>()) {
       data_type = ASTNodeDataType::string_t;
+    } else if (type_node.is_type<language::type_id>()) {
+      data_type = ASTNodeDataType{ASTNodeDataType::type_id_t, type_node.string_view()};
     }
 
     if (name_node.is_type<language::name_list>()) {
@@ -424,7 +426,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
       }
     } 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>() or
-               n.is_type<language::vector_type>()) {
+               n.is_type<language::vector_type>() or n.is_type<language::type_id>()) {
       n.m_data_type = ASTNodeDataType::typename_t;
     } else if (n.is_type<language::name_list>() or n.is_type<language::lvalue_list>() or
                n.is_type<language::function_argument_list>()) {
diff --git a/src/language/PEGGrammar.hpp b/src/language/PEGGrammar.hpp
index e65f96f10..98724f5fe 100644
--- a/src/language/PEGGrammar.hpp
+++ b/src/language/PEGGrammar.hpp
@@ -71,8 +71,8 @@ struct vector_type : seq< R_set, ignored, one< '^' >, ignored, integer >{};
 
 struct basic_type : sor< scalar_type, string_type >{};
 
-struct type_name;
-struct type_specifier : sor< vector_type, basic_type >{};
+struct type_id;
+struct type_specifier : sor< vector_type, basic_type, type_id >{};
 
 struct TYPE_SPECIFIER : seq< type_specifier, ignored >{};
 
@@ -125,7 +125,7 @@ struct identifier_minus_keyword : minus< identifier, keywork > {};
 struct module_name : identifier_minus_keyword {};
 struct MODULE_NAME : seq< module_name, ignored > {};
 
-struct type_name : identifier_minus_keyword {};
+struct type_id : identifier_minus_keyword {};
 
 struct name : identifier_minus_keyword {};
 struct NAME : seq< name, ignored > {};
-- 
GitLab