From 05e98e1981f9d909e81174f0cce998f83667e680 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Tue, 25 Feb 2020 19:18:51 +0100
Subject: [PATCH] Continue mesh module definition

---
 src/language/ASTBuilder.cpp                   |  2 +-
 .../ASTNodeCFunctionExpressionBuilder.cpp     |  4 +-
 src/language/ASTNodeDataType.cpp              |  6 ++
 src/language/ASTNodeDataType.hpp              | 37 +++++---
 src/language/ASTNodeDataTypeBuilder.cpp       | 48 ++++++++--
 src/language/BuiltinFunctionEmbedder.hpp      | 59 ++++++++++++
 src/language/BuiltinModule.cpp                | 18 +++-
 src/language/BuiltinModule.hpp                | 23 +++--
 src/language/CFunctionEmbedderTable.hpp       | 41 ---------
 src/language/CMakeLists.txt                   |  1 +
 src/language/DataHandler.hpp                  | 41 +++++++++
 src/language/DataVariant.hpp                  |  3 +
 src/language/EmbeddedData.cpp                 | 14 +++
 src/language/EmbeddedData.hpp                 | 51 ++++++++++
 src/language/EmbedderTable.hpp                | 41 +++++++++
 src/language/IModule.hpp                      | 13 ++-
 src/language/MathModule.cpp                   | 92 +++++++++----------
 src/language/MeshModule.cpp                   |  6 +-
 src/language/ModuleRepository.cpp             | 59 +++++-------
 src/language/ModuleRepository.hpp             | 14 +--
 src/language/PEGGrammar.hpp                   |  6 +-
 src/language/SymbolTable.hpp                  | 69 ++++++++------
 src/language/TypeTable.hpp                    | 30 ------
 .../node_processor/OStreamProcessor.hpp       |  3 +-
 ...test_ASTNodeCFunctionExpressionBuilder.cpp |  2 +-
 tests/test_CFunctionEmbedderTable.cpp         |  4 +-
 tests/test_CFunctionProcessor.cpp             |  2 +-
 tests/test_MathModule.cpp                     |  4 +-
 tests/test_SymbolTable.cpp                    |  4 +-
 29 files changed, 459 insertions(+), 238 deletions(-)
 create mode 100644 src/language/BuiltinFunctionEmbedder.hpp
 delete mode 100644 src/language/CFunctionEmbedderTable.hpp
 create mode 100644 src/language/DataHandler.hpp
 create mode 100644 src/language/EmbeddedData.cpp
 create mode 100644 src/language/EmbeddedData.hpp
 create mode 100644 src/language/EmbedderTable.hpp
 delete mode 100644 src/language/TypeTable.hpp

diff --git a/src/language/ASTBuilder.cpp b/src/language/ASTBuilder.cpp
index 7692ed981..704ced95e 100644
--- a/src/language/ASTBuilder.cpp
+++ b/src/language/ASTBuilder.cpp
@@ -244,7 +244,7 @@ using selector = parse_tree::selector<
                                 language::N_set,
                                 language::Z_set,
                                 language::R_set,
-                                language::type_id,
+                                language::type_name_id,
                                 language::tuple_expression,
                                 language::vector_type,
                                 language::string_type,
diff --git a/src/language/ASTNodeCFunctionExpressionBuilder.cpp b/src/language/ASTNodeCFunctionExpressionBuilder.cpp
index 99a1c8ac0..dbd1d0834 100644
--- a/src/language/ASTNodeCFunctionExpressionBuilder.cpp
+++ b/src/language/ASTNodeCFunctionExpressionBuilder.cpp
@@ -117,8 +117,8 @@ ASTNodeCFunctionExpressionBuilder::ASTNodeCFunctionExpressionBuilder(ASTNode& no
 
   uint64_t c_function_id = std::get<uint64_t>(i_function_symbol->attributes().value());
 
-  CFunctionEmbedderTable& c_function_embedder_table = node.m_symbol_table->cFunctionEbedderTable();
-  std::shared_ptr c_function_embedder               = c_function_embedder_table[c_function_id];
+  auto& c_function_embedder_table     = node.m_symbol_table->cFunctionEmbedderTable();
+  std::shared_ptr c_function_embedder = c_function_embedder_table[c_function_id];
 
   std::vector<ASTNodeDataType> c_function_parameter_type_list = c_function_embedder->getParameterDataTypes();
 
diff --git a/src/language/ASTNodeDataType.cpp b/src/language/ASTNodeDataType.cpp
index cbbc95fe8..c6191255b 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_name_id_t:
+    name = "type_name_id";
+    break;
   case ASTNodeDataType::type_id_t:
     name = "type_id";
     break;
@@ -55,6 +58,9 @@ dataTypeName(const ASTNodeDataType& data_type)
   case ASTNodeDataType::c_function_t:
     name = "c_function";
     break;
+  case ASTNodeDataType::builtin_function_t:
+    name = "builtin_function";
+    break;
   case ASTNodeDataType::void_t:
     name = "void";
     break;
diff --git a/src/language/ASTNodeDataType.hpp b/src/language/ASTNodeDataType.hpp
index af053c4d8..ee424e775 100644
--- a/src/language/ASTNodeDataType.hpp
+++ b/src/language/ASTNodeDataType.hpp
@@ -11,19 +11,21 @@ class ASTNodeDataType
  public:
   enum DataType : int32_t
   {
-    undefined_t    = -1,
-    bool_t         = 0,
-    int_t          = 1,
-    unsigned_int_t = 2,
-    double_t       = 3,
-    vector_t       = 4,
-    list_t         = 5,
-    string_t       = 6,
-    typename_t     = 10,
-    type_id_t      = 20,
-    function_t     = 21,
-    c_function_t   = 22,
-    void_t         = std::numeric_limits<int32_t>::max()
+    undefined_t        = -1,
+    bool_t             = 0,
+    int_t              = 1,
+    unsigned_int_t     = 2,
+    double_t           = 3,
+    vector_t           = 4,
+    list_t             = 5,
+    string_t           = 6,
+    typename_t         = 10,
+    type_name_id_t     = 20,
+    type_id_t          = 21,
+    function_t         = 22,
+    c_function_t       = 23,
+    builtin_function_t = 24,
+    void_t             = std::numeric_limits<int32_t>::max()
   };
 
  private:
@@ -38,12 +40,19 @@ class ASTNodeDataType
     return m_dimension;
   }
 
+  std::string_view
+  typeName() const
+  {
+    return m_type_name;
+  }
+
   operator DataType() const
   {
     return m_data_type;
   }
 
   ASTNodeDataType& operator=(const ASTNodeDataType&) = default;
+  ASTNodeDataType& operator=(ASTNodeDataType&&) = default;
 
   constexpr ASTNodeDataType(DataType data_type) : m_data_type{data_type}, m_dimension{1} {}
 
@@ -55,6 +64,8 @@ class ASTNodeDataType
 
   ASTNodeDataType(const ASTNodeDataType&) = default;
 
+  ASTNodeDataType(ASTNodeDataType&&) = default;
+
   ~ASTNodeDataType() = default;
 };
 
diff --git a/src/language/ASTNodeDataTypeBuilder.cpp b/src/language/ASTNodeDataTypeBuilder.cpp
index bf6ebea68..80c24227f 100644
--- a/src/language/ASTNodeDataTypeBuilder.cpp
+++ b/src/language/ASTNodeDataTypeBuilder.cpp
@@ -6,6 +6,7 @@
 #include <PugsAssert.hpp>
 #include <SymbolTable.hpp>
 
+#include <BuiltinFunctionEmbedder.hpp>
 #include <CFunctionEmbedder.hpp>
 
 ASTNodeDataType
@@ -41,26 +42,45 @@ 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()};
+    } else if (type_node.is_type<language::type_name_id>()) {
+      const std::string& type_name_id = type_node.string();
+
+      auto& symbol_table = *type_node.m_symbol_table;
+
+      auto [i_type_symbol, found] = symbol_table.find(type_name_id, type_node.begin());
+      if (not found) {
+        throw parse_error("undefined type identifier", std::vector{type_node.begin()});
+      } else if (i_type_symbol->attributes().dataType() != ASTNodeDataType::type_name_id_t) {
+        std::ostringstream os;
+        os << "invalid type identifier, '" << type_name_id << "' was previously defined as a '"
+           << dataTypeName(i_type_symbol->attributes().dataType()) << "'" << std::ends;
+        throw parse_error(os.str(), std::vector{type_node.begin()});
+      }
+
+      data_type = ASTNodeDataType{ASTNodeDataType::type_name_id_t, type_name_id};
     }
 
     if (name_node.is_type<language::name_list>()) {
-      throw parse_error("unexpected variable list for single space", name_node.begin());
+      throw parse_error("unexpected variable list for single space", std::vector{name_node.begin()});
     }
 
     Assert(name_node.is_type<language::name>());
-    name_node.m_data_type     = data_type;
+    if (data_type == ASTNodeDataType::type_name_id_t) {
+      name_node.m_data_type = ASTNodeDataType{ASTNodeDataType::type_id_t, data_type.typeName()};
+    } else {
+      name_node.m_data_type = data_type;
+    }
+
     const std::string& symbol = name_node.string();
 
     std::shared_ptr<SymbolTable>& symbol_table = name_node.m_symbol_table;
 
     auto [i_symbol, found] = symbol_table->find(symbol, name_node.begin());
     Assert(found);
-    i_symbol->attributes().setDataType(data_type);
+    i_symbol->attributes().setDataType(name_node.m_data_type);
   }
 
-  Assert(data_type != ASTNodeDataType::undefined_t);   // LCOV_EXCL_LINE
+  Assert(data_type != ASTNodeDataType::undefined_t);
   return data_type;
 }
 
@@ -397,10 +417,22 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
         Assert(success);
 
         uint64_t c_function_id   = std::get<uint64_t>(i_symbol->attributes().value());
-        auto c_function_embedder = symbol_table.cFunctionEbedderTable()[c_function_id];
+        auto c_function_embedder = symbol_table.cFunctionEmbedderTable()[c_function_id];
         Assert(c_function_embedder);
 
         n.m_data_type = c_function_embedder->getReturnDataType();
+      } else if (n.children[0]->m_data_type == ASTNodeDataType::builtin_function_t) {
+        const std::string builtin_function_name = n.children[0]->string();
+        auto& symbol_table                      = *n.m_symbol_table;
+
+        auto [i_symbol, success] = symbol_table.find(builtin_function_name, n.begin());
+        Assert(success);
+
+        uint64_t builtin_function_id   = std::get<uint64_t>(i_symbol->attributes().value());
+        auto builtin_function_embedder = symbol_table.builtinFunctionEmbedderTable()[builtin_function_id];
+        Assert(builtin_function_embedder);
+
+        n.m_data_type = builtin_function_embedder->getReturnDataType();
       } else {
         std::ostringstream message;
         message << "invalid function call\n"
@@ -426,7 +458,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>() or n.is_type<language::type_id>()) {
+               n.is_type<language::vector_type>() or n.is_type<language::type_name_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/BuiltinFunctionEmbedder.hpp b/src/language/BuiltinFunctionEmbedder.hpp
new file mode 100644
index 000000000..d1896ede4
--- /dev/null
+++ b/src/language/BuiltinFunctionEmbedder.hpp
@@ -0,0 +1,59 @@
+#ifndef BUILTIN_FUNCTION_EMBEDDER_HPP
+#define BUILTIN_FUNCTION_EMBEDDER_HPP
+
+#include <memory>
+#include <vector>
+
+#include <ASTNodeDataType.hpp>
+#include <DataVariant.hpp>
+
+class IBuiltinFunctionEmbedder
+{
+ public:
+  virtual size_t numberOfParameters() const = 0;
+
+  virtual ASTNodeDataType getReturnDataType() const = 0;
+
+  virtual std::vector<ASTNodeDataType> getParameterDataTypes() const = 0;
+
+  virtual DataVariant apply(const std::vector<DataVariant>& x) const = 0;
+
+  virtual ~IBuiltinFunctionEmbedder() = default;
+};
+
+class BuiltinFunctionEmbedder : public IBuiltinFunctionEmbedder
+{
+ private:
+  ASTNodeDataType m_return_data_type{ASTNodeDataType::type_id_t, "mesh"};
+
+ public:
+  size_t
+  numberOfParameters() const
+  {
+    return 1;
+  }
+
+  ASTNodeDataType
+  getReturnDataType() const
+  {
+    return m_return_data_type;
+  }
+
+  std::vector<ASTNodeDataType>
+  getParameterDataTypes() const
+  {
+    return {ASTNodeDataType::string_t};
+  }
+
+  DataVariant
+  apply(const std::vector<DataVariant>&) const
+  {
+    std::cerr << "NIY\n";
+    return {};
+  }
+
+  BuiltinFunctionEmbedder()  = default;
+  ~BuiltinFunctionEmbedder() = default;
+};
+
+#endif   //  BUILTIN_FUNCTION_EMBEDDER_HPP
diff --git a/src/language/BuiltinModule.cpp b/src/language/BuiltinModule.cpp
index 88967ad75..bea61e9d7 100644
--- a/src/language/BuiltinModule.cpp
+++ b/src/language/BuiltinModule.cpp
@@ -6,7 +6,7 @@
 #include <iostream>
 
 void
-BuiltinModule::_addFunction(const std::string& name, std::shared_ptr<ICFunctionEmbedder> c_function_embedder)
+BuiltinModule::_addCFunction(const std::string& name, std::shared_ptr<ICFunctionEmbedder> c_function_embedder)
 {
   auto [i_function, success] = m_name_cfunction_map.insert(std::make_pair(name, c_function_embedder));
   // LCOV_EXCL_START
@@ -17,10 +17,24 @@ BuiltinModule::_addFunction(const std::string& name, std::shared_ptr<ICFunctionE
   // LCOV_EXCL_STOP
 }
 
+void
+BuiltinModule::_addBuiltinFunction(const std::string& name,
+                                   std::shared_ptr<IBuiltinFunctionEmbedder> builtin_function_embedder)
+{
+  auto [i_builtin_function, success] =
+    m_name_builtin_function_map.insert(std::make_pair(name, builtin_function_embedder));
+  // LCOV_EXCL_START
+  if (not success) {
+    std::cerr << "builtin function " << name << " cannot be added!\n";
+    std::exit(1);
+  }
+  // LCOV_EXCL_STOP
+}
+
 void
 BuiltinModule::_addTypeDescriptor(std::shared_ptr<TypeDescriptor> type_descriptor)
 {
-  auto [i_type, success] = m_type_descriptor_map.insert(std::make_pair(type_descriptor->name(), type_descriptor));
+  auto [i_type, success] = m_name_type_map.insert(std::make_pair(type_descriptor->name(), type_descriptor));
   // LCOV_EXCL_START
   if (not success) {
     std::cerr << "type '" << type_descriptor->name() << "' cannot be added!\n";
diff --git a/src/language/BuiltinModule.hpp b/src/language/BuiltinModule.hpp
index 67adb09e1..7e0d599e9 100644
--- a/src/language/BuiltinModule.hpp
+++ b/src/language/BuiltinModule.hpp
@@ -4,29 +4,40 @@
 #include <IModule.hpp>
 
 class ICFunctionEmbedder;
+class IBuiltinFunctionEmbedder;
 class TypeDescriptor;
 
 class BuiltinModule : public IModule
 {
  protected:
   NameCFunctionMap m_name_cfunction_map;
-  TypeDescriptorMap m_type_descriptor_map;
+  NameBuiltinFunctionMap m_name_builtin_function_map;
+  NameTypeMap m_name_type_map;
 
-  void _addFunction(const std::string& name, std::shared_ptr<ICFunctionEmbedder> c_function_embedder);
+  void _addCFunction(const std::string& name, std::shared_ptr<ICFunctionEmbedder> c_function_embedder);
+
+  void _addBuiltinFunction(const std::string& name,
+                           std::shared_ptr<IBuiltinFunctionEmbedder> builtin_function_embedder);
 
   void _addTypeDescriptor(std::shared_ptr<TypeDescriptor> type_descriptor);
 
  public:
   const NameCFunctionMap&
-  getNameCFunctionsMap() const final
+  getNameCFunctionMap() const final
   {
     return m_name_cfunction_map;
   }
 
-  const TypeDescriptorMap&
-  getTypeDescriptorMap() const final
+  const NameBuiltinFunctionMap&
+  getNameBuiltinFunctionMap() const final
+  {
+    return m_name_builtin_function_map;
+  }
+
+  const NameTypeMap&
+  getNameTypeMap() const final
   {
-    return m_type_descriptor_map;
+    return m_name_type_map;
   }
 
   BuiltinModule() = default;
diff --git a/src/language/CFunctionEmbedderTable.hpp b/src/language/CFunctionEmbedderTable.hpp
deleted file mode 100644
index b67f2afab..000000000
--- a/src/language/CFunctionEmbedderTable.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef CFUNCTION_EMBEDDER_TABLE_HPP
-#define CFUNCTION_EMBEDDER_TABLE_HPP
-
-#include <PugsAssert.hpp>
-
-#include <memory>
-#include <vector>
-
-class ICFunctionEmbedder;
-class CFunctionEmbedderTable
-{
- private:
-  std::vector<std::shared_ptr<ICFunctionEmbedder>> m_c_function_embedder_list;
-
- public:
-  PUGS_INLINE
-  size_t
-  size() const
-  {
-    return m_c_function_embedder_list.size();
-  }
-
-  PUGS_INLINE
-  const std::shared_ptr<ICFunctionEmbedder>&
-  operator[](size_t function_id) const
-  {
-    Assert(function_id < m_c_function_embedder_list.size());
-    return m_c_function_embedder_list[function_id];
-  }
-
-  void
-  add(std::shared_ptr<ICFunctionEmbedder> c_function_embedder)
-  {
-    m_c_function_embedder_list.push_back(c_function_embedder);
-  }
-
-  CFunctionEmbedderTable()  = default;
-  ~CFunctionEmbedderTable() = default;
-};
-
-#endif   // CFUNCTION_EMBEDDER_TABLE_HPP
diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt
index 14f349b46..a68852943 100644
--- a/src/language/CMakeLists.txt
+++ b/src/language/CMakeLists.txt
@@ -32,6 +32,7 @@ add_library(
   ASTSymbolTableBuilder.cpp
   ASTSymbolInitializationChecker.cpp
   BuiltinModule.cpp
+  EmbeddedData.cpp
   MathModule.cpp
   MeshModule.cpp
   ModuleRepository.cpp
diff --git a/src/language/DataHandler.hpp b/src/language/DataHandler.hpp
new file mode 100644
index 000000000..78cf0587d
--- /dev/null
+++ b/src/language/DataHandler.hpp
@@ -0,0 +1,41 @@
+#ifndef DATA_HANDLER_HPP
+#define DATA_HANDLER_HPP
+
+#include <PugsAssert.hpp>
+
+#include <memory>
+
+class IDataHandler
+{
+ public:
+  IDataHandler() = default;
+
+  virtual ~IDataHandler() = default;
+};
+
+template <typename DataT>
+class DataHandler
+{
+ private:
+  std::shared_ptr<DataT> m_data;
+
+ public:
+  DataT&
+  data()
+  {
+    Assert(m_data);
+    return m_data;
+  }
+
+  const DataT&
+  data() const
+  {
+    Assert(m_data);
+    return m_data;
+  }
+
+  DataHandler(std::shared_ptr<DataT> data) : m_data(data) {}
+  ~DataHandler() = default;
+};
+
+#endif   // DATA_HANDLER_HPP
diff --git a/src/language/DataVariant.hpp b/src/language/DataVariant.hpp
index 54abc6692..1aacda650 100644
--- a/src/language/DataVariant.hpp
+++ b/src/language/DataVariant.hpp
@@ -9,6 +9,8 @@
 
 #include <PugsAssert.hpp>
 
+#include <EmbeddedData.hpp>
+
 class AggregateDataVariant;
 
 using DataVariant = std::variant<std::monostate,
@@ -17,6 +19,7 @@ using DataVariant = std::variant<std::monostate,
                                  int64_t,
                                  double,
                                  std::string,
+                                 EmbeddedData,
                                  AggregateDataVariant,
                                  TinyVector<1>,
                                  TinyVector<2>,
diff --git a/src/language/EmbeddedData.cpp b/src/language/EmbeddedData.cpp
new file mode 100644
index 000000000..bdd29bbd3
--- /dev/null
+++ b/src/language/EmbeddedData.cpp
@@ -0,0 +1,14 @@
+#include <EmbeddedData.hpp>
+
+#include <DataHandler.hpp>
+
+std::ostream&
+operator<<(std::ostream& os, const EmbeddedData&)
+{
+  os << "embedded_data";
+  return os;
+}
+
+EmbeddedData::EmbeddedData() {}
+
+EmbeddedData::~EmbeddedData() {}
diff --git a/src/language/EmbeddedData.hpp b/src/language/EmbeddedData.hpp
new file mode 100644
index 000000000..10febc07a
--- /dev/null
+++ b/src/language/EmbeddedData.hpp
@@ -0,0 +1,51 @@
+#ifndef EMBEDDED_DATA_HPP
+#define EMBEDDED_DATA_HPP
+
+#include <iostream>
+#include <memory>
+
+#include <PugsAssert.hpp>
+
+class IDataHandler;
+
+class EmbeddedData
+{
+ private:
+  std::shared_ptr<IDataHandler> m_data_handler{nullptr};
+
+ public:
+  [[nodiscard]] const IDataHandler&
+  get() const
+  {
+    Assert(m_data_handler);
+    return *m_data_handler;
+  }
+
+  void
+  set(const std::shared_ptr<IDataHandler>& data_handler)
+  {
+    m_data_handler = data_handler;
+  }
+
+  void
+  set(std::shared_ptr<IDataHandler>&& data_handler)
+  {
+    m_data_handler = std::move(data_handler);
+  }
+
+  friend std::ostream& operator<<(std::ostream& os, const EmbeddedData&);
+
+  EmbeddedData& operator=(const EmbeddedData&) = default;
+  EmbeddedData& operator=(EmbeddedData&&) = default;
+
+  EmbeddedData(const EmbeddedData&) = default;
+  EmbeddedData(EmbeddedData&&)      = default;
+
+  EmbeddedData(const std::shared_ptr<IDataHandler>& data_handler) : m_data_handler{data_handler} {}
+  EmbeddedData(std::shared_ptr<IDataHandler>&& data_handler) : m_data_handler{std::move(data_handler)} {}
+
+  EmbeddedData();
+  ~EmbeddedData();
+};
+
+#endif   // EMBEDDED_DATA_HPP
diff --git a/src/language/EmbedderTable.hpp b/src/language/EmbedderTable.hpp
new file mode 100644
index 000000000..f12c1843d
--- /dev/null
+++ b/src/language/EmbedderTable.hpp
@@ -0,0 +1,41 @@
+#ifndef EMBEDDER_TABLE_HPP
+#define EMBEDDER_TABLE_HPP
+
+#include <PugsAssert.hpp>
+
+#include <memory>
+#include <vector>
+
+template <typename EmbedderT>
+class EmbedderTable
+{
+ private:
+  std::vector<std::shared_ptr<EmbedderT>> m_embedder_list;
+
+ public:
+  PUGS_INLINE
+  size_t
+  size() const
+  {
+    return m_embedder_list.size();
+  }
+
+  PUGS_INLINE
+  const std::shared_ptr<EmbedderT>&
+  operator[](size_t embedder_id) const
+  {
+    Assert(embedder_id < m_embedder_list.size());
+    return m_embedder_list[embedder_id];
+  }
+
+  void
+  add(std::shared_ptr<EmbedderT> embedder)
+  {
+    m_embedder_list.push_back(embedder);
+  }
+
+  EmbedderTable()  = default;
+  ~EmbedderTable() = default;
+};
+
+#endif   // EMBEDDER_TABLE_HPP
diff --git a/src/language/IModule.hpp b/src/language/IModule.hpp
index 459a914b9..deb485714 100644
--- a/src/language/IModule.hpp
+++ b/src/language/IModule.hpp
@@ -7,20 +7,25 @@
 #include <unordered_map>
 
 class ICFunctionEmbedder;
+class IBuiltinFunctionEmbedder;
 class TypeDescriptor;
 
 class IModule
 {
  public:
-  using NameCFunctionMap  = std::unordered_map<std::string, std::shared_ptr<ICFunctionEmbedder>>;
-  using TypeDescriptorMap = std::unordered_map<std::string, std::shared_ptr<TypeDescriptor>>;
+  using NameCFunctionMap       = std::unordered_map<std::string, std::shared_ptr<ICFunctionEmbedder>>;
+  using NameBuiltinFunctionMap = std::unordered_map<std::string, std::shared_ptr<IBuiltinFunctionEmbedder>>;
+  using NameTypeMap            = std::unordered_map<std::string, std::shared_ptr<TypeDescriptor>>;
 
   IModule()          = default;
   IModule(IModule&&) = default;
   IModule& operator=(IModule&&) = default;
 
-  virtual const NameCFunctionMap& getNameCFunctionsMap() const  = 0;
-  virtual const TypeDescriptorMap& getTypeDescriptorMap() const = 0;
+  virtual const NameCFunctionMap& getNameCFunctionMap() const = 0;
+
+  virtual const NameBuiltinFunctionMap& getNameBuiltinFunctionMap() const = 0;
+
+  virtual const NameTypeMap& getNameTypeMap() const = 0;
 
   virtual std::string_view name() const = 0;
 
diff --git a/src/language/MathModule.cpp b/src/language/MathModule.cpp
index 440ad9290..4f70162ad 100644
--- a/src/language/MathModule.cpp
+++ b/src/language/MathModule.cpp
@@ -4,71 +4,71 @@
 
 MathModule::MathModule()
 {
-  this->_addFunction("sqrt", std::make_shared<CFunctionEmbedder<double, double>>(
-                               std::function<double(double)>{[](double x) -> double { return std::sqrt(x); }}));
+  this->_addCFunction("sqrt", std::make_shared<CFunctionEmbedder<double, double>>(
+                                std::function<double(double)>{[](double x) -> double { return std::sqrt(x); }}));
 
-  this->_addFunction("abs", std::make_shared<CFunctionEmbedder<double, double>>(
-                              std::function<double(double)>{[](double x) -> double { return std::abs(x); }}));
+  this->_addCFunction("abs", std::make_shared<CFunctionEmbedder<double, double>>(
+                               std::function<double(double)>{[](double x) -> double { return std::abs(x); }}));
 
-  this->_addFunction("sin", std::make_shared<CFunctionEmbedder<double, double>>(
-                              std::function<double(double)>{[](double x) -> double { return std::sin(x); }}));
+  this->_addCFunction("sin", std::make_shared<CFunctionEmbedder<double, double>>(
+                               std::function<double(double)>{[](double x) -> double { return std::sin(x); }}));
 
-  this->_addFunction("cos", std::make_shared<CFunctionEmbedder<double, double>>(
-                              std::function<double(double)>{[](double x) -> double { return std::cos(x); }}));
+  this->_addCFunction("cos", std::make_shared<CFunctionEmbedder<double, double>>(
+                               std::function<double(double)>{[](double x) -> double { return std::cos(x); }}));
 
-  this->_addFunction("tan", std::make_shared<CFunctionEmbedder<double, double>>(
-                              std::function<double(double)>{[](double x) -> double { return std::tan(x); }}));
+  this->_addCFunction("tan", std::make_shared<CFunctionEmbedder<double, double>>(
+                               std::function<double(double)>{[](double x) -> double { return std::tan(x); }}));
 
-  this->_addFunction("asin", std::make_shared<CFunctionEmbedder<double, double>>(
-                               std::function<double(double)>{[](double x) -> double { return std::asin(x); }}));
+  this->_addCFunction("asin", std::make_shared<CFunctionEmbedder<double, double>>(
+                                std::function<double(double)>{[](double x) -> double { return std::asin(x); }}));
 
-  this->_addFunction("acos", std::make_shared<CFunctionEmbedder<double, double>>(
-                               std::function<double(double)>{[](double x) -> double { return std::acos(x); }}));
+  this->_addCFunction("acos", std::make_shared<CFunctionEmbedder<double, double>>(
+                                std::function<double(double)>{[](double x) -> double { return std::acos(x); }}));
 
-  this->_addFunction("atan", std::make_shared<CFunctionEmbedder<double, double>>(
-                               std::function<double(double)>{[](double x) -> double { return std::atan(x); }}));
+  this->_addCFunction("atan", std::make_shared<CFunctionEmbedder<double, double>>(
+                                std::function<double(double)>{[](double x) -> double { return std::atan(x); }}));
 
-  this->_addFunction("atan2",
-                     std::make_shared<CFunctionEmbedder<double, double, double>>(std::function<double(double, double)>{
-                       [](double x, double y) -> double { return std::atan2(x, y); }}));
+  this->_addCFunction("atan2",
+                      std::make_shared<CFunctionEmbedder<double, double, double>>(std::function<double(double, double)>{
+                        [](double x, double y) -> double { return std::atan2(x, y); }}));
 
-  this->_addFunction("sinh", std::make_shared<CFunctionEmbedder<double, double>>(
-                               std::function<double(double)>{[](double x) -> double { return std::sinh(x); }}));
+  this->_addCFunction("sinh", std::make_shared<CFunctionEmbedder<double, double>>(
+                                std::function<double(double)>{[](double x) -> double { return std::sinh(x); }}));
 
-  this->_addFunction("cosh", std::make_shared<CFunctionEmbedder<double, double>>(
-                               std::function<double(double)>{[](double x) -> double { return std::cosh(x); }}));
+  this->_addCFunction("cosh", std::make_shared<CFunctionEmbedder<double, double>>(
+                                std::function<double(double)>{[](double x) -> double { return std::cosh(x); }}));
 
-  this->_addFunction("tanh", std::make_shared<CFunctionEmbedder<double, double>>(
-                               std::function<double(double)>{[](double x) -> double { return std::tanh(x); }}));
+  this->_addCFunction("tanh", std::make_shared<CFunctionEmbedder<double, double>>(
+                                std::function<double(double)>{[](double x) -> double { return std::tanh(x); }}));
 
-  this->_addFunction("asinh", std::make_shared<CFunctionEmbedder<double, double>>(
-                                std::function<double(double)>{[](double x) -> double { return std::asinh(x); }}));
+  this->_addCFunction("asinh", std::make_shared<CFunctionEmbedder<double, double>>(
+                                 std::function<double(double)>{[](double x) -> double { return std::asinh(x); }}));
 
-  this->_addFunction("acosh", std::make_shared<CFunctionEmbedder<double, double>>(
-                                std::function<double(double)>{[](double x) -> double { return std::acosh(x); }}));
+  this->_addCFunction("acosh", std::make_shared<CFunctionEmbedder<double, double>>(
+                                 std::function<double(double)>{[](double x) -> double { return std::acosh(x); }}));
 
-  this->_addFunction("atanh", std::make_shared<CFunctionEmbedder<double, double>>(
-                                std::function<double(double)>{[](double x) -> double { return std::atanh(x); }}));
+  this->_addCFunction("atanh", std::make_shared<CFunctionEmbedder<double, double>>(
+                                 std::function<double(double)>{[](double x) -> double { return std::atanh(x); }}));
 
-  this->_addFunction("exp", std::make_shared<CFunctionEmbedder<double, double>>(
-                              std::function<double(double)>{[](double x) -> double { return std::exp(x); }}));
+  this->_addCFunction("exp", std::make_shared<CFunctionEmbedder<double, double>>(
+                               std::function<double(double)>{[](double x) -> double { return std::exp(x); }}));
 
-  this->_addFunction("log", std::make_shared<CFunctionEmbedder<double, double>>(
-                              std::function<double(double)>{[](double x) -> double { return std::log(x); }}));
+  this->_addCFunction("log", std::make_shared<CFunctionEmbedder<double, double>>(
+                               std::function<double(double)>{[](double x) -> double { return std::log(x); }}));
 
-  this->_addFunction("pow",
-                     std::make_shared<CFunctionEmbedder<double, double, double>>(std::function<double(double, double)>{
-                       [](double x, double y) -> double { return std::pow(x, y); }}));
+  this->_addCFunction("pow",
+                      std::make_shared<CFunctionEmbedder<double, double, double>>(std::function<double(double, double)>{
+                        [](double x, double y) -> double { return std::pow(x, y); }}));
 
-  this->_addFunction("ceil", std::make_shared<CFunctionEmbedder<int64_t, double>>(
-                               std::function<int64_t(double)>{[](double x) -> int64_t { return std::ceil(x); }}));
+  this->_addCFunction("ceil", std::make_shared<CFunctionEmbedder<int64_t, double>>(
+                                std::function<int64_t(double)>{[](double x) -> int64_t { return std::ceil(x); }}));
 
-  this->_addFunction("floor", std::make_shared<CFunctionEmbedder<int64_t, double>>(
-                                std::function<int64_t(double)>{[](double x) -> int64_t { return std::floor(x); }}));
+  this->_addCFunction("floor", std::make_shared<CFunctionEmbedder<int64_t, double>>(
+                                 std::function<int64_t(double)>{[](double x) -> int64_t { return std::floor(x); }}));
 
-  this->_addFunction("trunc", std::make_shared<CFunctionEmbedder<int64_t, double>>(
-                                std::function<int64_t(double)>{[](double x) -> int64_t { return std::trunc(x); }}));
+  this->_addCFunction("trunc", std::make_shared<CFunctionEmbedder<int64_t, double>>(
+                                 std::function<int64_t(double)>{[](double x) -> int64_t { return std::trunc(x); }}));
 
-  this->_addFunction("round", std::make_shared<CFunctionEmbedder<int64_t, double>>(
-                                std::function<int64_t(double)>{[](double x) -> int64_t { return std::lround(x); }}));
+  this->_addCFunction("round", std::make_shared<CFunctionEmbedder<int64_t, double>>(
+                                 std::function<int64_t(double)>{[](double x) -> int64_t { return std::lround(x); }}));
 }
diff --git a/src/language/MeshModule.cpp b/src/language/MeshModule.cpp
index 7edad9c35..1b33eedca 100644
--- a/src/language/MeshModule.cpp
+++ b/src/language/MeshModule.cpp
@@ -1,9 +1,11 @@
 #include <MeshModule.hpp>
-#include <TypeDescriptor.hpp>
 
-#include <memory>
+#include <BuiltinFunctionEmbedder.hpp>
+#include <TypeDescriptor.hpp>
 
 MeshModule::MeshModule()
 {
   this->_addTypeDescriptor(std::make_shared<TypeDescriptor>(std::string{"mesh"}));
+
+  this->_addBuiltinFunction("readGmsh", std::make_shared<BuiltinFunctionEmbedder>());
 }
diff --git a/src/language/ModuleRepository.cpp b/src/language/ModuleRepository.cpp
index f6b0b0d8f..bacda2efa 100644
--- a/src/language/ModuleRepository.cpp
+++ b/src/language/ModuleRepository.cpp
@@ -23,16 +23,17 @@ ModuleRepository::ModuleRepository()
   this->_subscribe(std::make_unique<MeshModule>());
 }
 
+template <typename NameEmbedderMapT, typename EmbedderTableT>
 void
-ModuleRepository::_populateCFunctionsEmbedderTable(const IModule& populating_module,
-                                                   const ASTNode& module_name_node,
-                                                   SymbolTable& symbol_table)
+ModuleRepository::_populateEmbedderTableT(const ASTNode& module_name_node,
+                                          const NameEmbedderMapT& name_embedder_map,
+                                          const ASTNodeDataType& data_type,
+                                          SymbolTable& symbol_table,
+                                          EmbedderTableT& embedder_table)
 {
   const std::string& module_name = module_name_node.string();
 
-  CFunctionEmbedderTable& c_function_embedder_table = symbol_table.cFunctionEbedderTable();
-
-  for (auto [symbol_name, c_function] : populating_module.getNameCFunctionsMap()) {
+  for (auto [symbol_name, embedded] : name_embedder_map) {
     auto [i_symbol, success] = symbol_table.add(symbol_name, module_name_node.begin());
 
     if (not success) {
@@ -42,38 +43,11 @@ ModuleRepository::_populateCFunctionsEmbedderTable(const IModule& populating_mod
       throw parse_error(error_message.str(), module_name_node.begin());
     }
 
-    i_symbol->attributes().setDataType(ASTNodeDataType::c_function_t);
+    i_symbol->attributes().setDataType(data_type);
     i_symbol->attributes().setIsInitialized();
-    i_symbol->attributes().value() = c_function_embedder_table.size();
+    i_symbol->attributes().value() = embedder_table.size();
 
-    c_function_embedder_table.add(c_function);
-  }
-}
-
-void
-ModuleRepository::_populateTypeDescriptor(const IModule& populating_module,
-                                          const ASTNode& module_name_node,
-                                          SymbolTable& symbol_table)
-{
-  const std::string& module_name = module_name_node.string();
-
-  TypeTable& type_table = symbol_table.typeTable();
-
-  for (auto [symbol_name, type_descriptor] : populating_module.getTypeDescriptorMap()) {
-    auto [i_symbol, success] = symbol_table.add(symbol_name, module_name_node.begin());
-
-    if (not success) {
-      std::ostringstream error_message;
-      error_message << "importing module '" << module_name << "', cannot add symbol '" << symbol_name
-                    << "', it is already defined!";
-      throw parse_error(error_message.str(), module_name_node.begin());
-    }
-
-    i_symbol->attributes().setDataType(ASTNodeDataType::type_id_t);
-    i_symbol->attributes().setIsInitialized();
-    i_symbol->attributes().value() = type_table.size();
-
-    type_table.add(type_descriptor);
+    embedder_table.add(embedded);
   }
 }
 
@@ -84,8 +58,17 @@ ModuleRepository::populateSymbolTable(const ASTNode& module_name_node, SymbolTab
 
   auto i_module = m_module_set.find(module_name);
   if (i_module != m_module_set.end()) {
-    this->_populateCFunctionsEmbedderTable(*i_module->second, module_name_node, symbol_table);
-    this->_populateTypeDescriptor(*i_module->second, module_name_node, symbol_table);
+    const IModule& populating_module = *i_module->second;
+
+    this->_populateEmbedderTableT(module_name_node, populating_module.getNameCFunctionMap(),
+                                  ASTNodeDataType::c_function_t, symbol_table, symbol_table.cFunctionEmbedderTable());
+
+    this->_populateEmbedderTableT(module_name_node, populating_module.getNameBuiltinFunctionMap(),
+                                  ASTNodeDataType::builtin_function_t, symbol_table,
+                                  symbol_table.builtinFunctionEmbedderTable());
+
+    this->_populateEmbedderTableT(module_name_node, populating_module.getNameTypeMap(), ASTNodeDataType::type_name_id_t,
+                                  symbol_table, symbol_table.typeEmbedderTable());
   } else {
     throw parse_error(std::string{"could not find module "} + module_name, std::vector{module_name_node.begin()});
   }
diff --git a/src/language/ModuleRepository.hpp b/src/language/ModuleRepository.hpp
index e71a56587..93c4fa177 100644
--- a/src/language/ModuleRepository.hpp
+++ b/src/language/ModuleRepository.hpp
@@ -8,6 +8,7 @@
 #include <string>
 
 class ASTNode;
+class ASTNodeDataType;
 class SymbolTable;
 
 class ModuleRepository
@@ -17,13 +18,12 @@ class ModuleRepository
 
   void _subscribe(std::unique_ptr<IModule> a);
 
-  void _populateCFunctionsEmbedderTable(const IModule& populating_module,
-                                        const ASTNode& module_name_node,
-                                        SymbolTable& symbol_table);
-
-  void _populateTypeDescriptor(const IModule& populating_module,
-                               const ASTNode& module_name_node,
-                               SymbolTable& symbol_table);
+  template <typename NameEmbedderMapT, typename EmbedderTableT>
+  void _populateEmbedderTableT(const ASTNode& module_name_node,
+                               const NameEmbedderMapT& name_embedder_map,
+                               const ASTNodeDataType& data_type,
+                               SymbolTable& symbol_table,
+                               EmbedderTableT& embedder_table);
 
  public:
   void populateSymbolTable(const ASTNode& module_name_node, SymbolTable& symbol_table);
diff --git a/src/language/PEGGrammar.hpp b/src/language/PEGGrammar.hpp
index 98724f5fe..12f3bcd49 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_id;
-struct type_specifier : sor< vector_type, basic_type, type_id >{};
+struct type_name_id;
+struct type_specifier : sor< vector_type, basic_type, type_name_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_id : identifier_minus_keyword {};
+struct type_name_id : identifier_minus_keyword {};
 
 struct name : identifier_minus_keyword {};
 struct NAME : seq< name, ignored > {};
diff --git a/src/language/SymbolTable.hpp b/src/language/SymbolTable.hpp
index 4dbbc5b2c..3105957cc 100644
--- a/src/language/SymbolTable.hpp
+++ b/src/language/SymbolTable.hpp
@@ -10,10 +10,13 @@
 
 #include <iostream>
 
-#include <CFunctionEmbedderTable.hpp>
 #include <FunctionTable.hpp>
 
-#include <TypeTable.hpp>
+#include <EmbedderTable.hpp>
+
+class TypeDescriptor;
+class ICFunctionEmbedder;
+class IBuiltinFunctionEmbedder;
 
 class SymbolTable
 {
@@ -89,8 +92,10 @@ class SymbolTable
     {
       if (attributes.m_data_type == ASTNodeDataType::function_t) {
         os << "function_id:";
+      } else if (attributes.m_data_type == ASTNodeDataType::type_name_id_t) {
+        os << "type_name_id:";
       } else if (attributes.m_data_type == ASTNodeDataType::type_id_t) {
-        os << "type_id:";
+        os << attributes.m_data_type.typeName() << ':';
       }
       std::visit(
         [&](const auto& value) {
@@ -198,9 +203,10 @@ class SymbolTable
   std::shared_ptr<Context> m_context;
 
   std::shared_ptr<FunctionTable> m_function_table;
-  std::shared_ptr<CFunctionEmbedderTable> m_c_function_embedder_table;
 
-  std::shared_ptr<TypeTable> m_type_table;
+  std::shared_ptr<EmbedderTable<ICFunctionEmbedder>> m_c_function_embedder_table;
+  std::shared_ptr<EmbedderTable<IBuiltinFunctionEmbedder>> m_builtin_function_embedder_table;
+  std::shared_ptr<EmbedderTable<TypeDescriptor>> m_type_embedder_table;
 
  public:
   bool
@@ -230,32 +236,46 @@ class SymbolTable
     return *m_function_table;
   }
 
-  const CFunctionEmbedderTable&
-  cFunctionEbedderTable() const
+  const auto&
+  cFunctionEmbedderTable() const
   {
     Assert(m_c_function_embedder_table);
     return *m_c_function_embedder_table;
   }
 
-  CFunctionEmbedderTable&
-  cFunctionEbedderTable()
+  auto&
+  cFunctionEmbedderTable()
   {
     Assert(m_c_function_embedder_table);
     return *m_c_function_embedder_table;
   }
 
-  TypeTable&
-  typeTable()
+  const auto&
+  builtinFunctionEmbedderTable() const
+  {
+    Assert(m_builtin_function_embedder_table);
+    return *m_builtin_function_embedder_table;
+  }
+
+  auto&
+  builtinFunctionEmbedderTable()
+  {
+    Assert(m_builtin_function_embedder_table);
+    return *m_builtin_function_embedder_table;
+  }
+
+  auto&
+  typeEmbedderTable()
   {
-    Assert(m_type_table);
-    return *m_type_table;
+    Assert(m_type_embedder_table);
+    return *m_type_embedder_table;
   }
 
-  const TypeTable&
-  typeTable() const
+  const auto&
+  typeEmbedderTable() const
   {
-    Assert(m_type_table);
-    return *m_type_table;
+    Assert(m_type_embedder_table);
+    return *m_type_embedder_table;
   }
 
   friend std::ostream&
@@ -320,17 +340,13 @@ class SymbolTable
       m_context{context},
       m_function_table{parent_table->m_function_table},
       m_c_function_embedder_table{parent_table->m_c_function_embedder_table},
-      m_type_table{parent_table->m_type_table}
+      m_builtin_function_embedder_table{parent_table->m_builtin_function_embedder_table},
+      m_type_embedder_table{parent_table->m_type_embedder_table}
   {
     ;
   }
 
-  SymbolTable(const std::shared_ptr<SymbolTable>& parent_table)
-    : m_parent_table{parent_table},
-      m_context{parent_table->m_context},
-      m_function_table{parent_table->m_function_table},
-      m_c_function_embedder_table{parent_table->m_c_function_embedder_table},
-      m_type_table{parent_table->m_type_table}
+  SymbolTable(const std::shared_ptr<SymbolTable>& parent_table) : SymbolTable{parent_table, parent_table->m_context}
   {
     ;
   }
@@ -339,8 +355,9 @@ class SymbolTable
     : m_parent_table{nullptr},
       m_context{nullptr},
       m_function_table{std::make_shared<FunctionTable>()},
-      m_c_function_embedder_table{std::make_shared<CFunctionEmbedderTable>()},
-      m_type_table{std::make_shared<TypeTable>()}
+      m_c_function_embedder_table{std::make_shared<EmbedderTable<ICFunctionEmbedder>>()},
+      m_builtin_function_embedder_table{std::make_shared<EmbedderTable<IBuiltinFunctionEmbedder>>()},
+      m_type_embedder_table{std::make_shared<EmbedderTable<TypeDescriptor>>()}
   {
     ;
   }
diff --git a/src/language/TypeTable.hpp b/src/language/TypeTable.hpp
deleted file mode 100644
index 059e686e1..000000000
--- a/src/language/TypeTable.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef TYPE_TABLE_HPP
-#define TYPE_TABLE_HPP
-
-#include <TypeDescriptor.hpp>
-
-#include <vector>
-
-class TypeTable
-{
- private:
-  std::vector<std::shared_ptr<TypeDescriptor>> m_type_list;
-
- public:
-  size_t
-  size() const
-  {
-    return m_type_list.size();
-  }
-
-  void
-  add(std::shared_ptr<TypeDescriptor> type_descriptor)
-  {
-    m_type_list.emplace_back(type_descriptor);
-  }
-
-  TypeTable()  = default;
-  ~TypeTable() = default;
-};
-
-#endif   // TYPE_TABLE_HPP
diff --git a/src/language/node_processor/OStreamProcessor.hpp b/src/language/node_processor/OStreamProcessor.hpp
index c0fd17c92..8ef721696 100644
--- a/src/language/node_processor/OStreamProcessor.hpp
+++ b/src/language/node_processor/OStreamProcessor.hpp
@@ -34,7 +34,8 @@ class OStreamProcessor final : public INodeProcessor
   OStreamProcessor(ASTNode& node, std::ostream& os) : m_node{node}, m_os(os)
   {
     for (auto& child : m_node.children) {
-      if ((child->m_data_type == ASTNodeDataType::type_id_t) or (child->m_data_type == ASTNodeDataType::function_t) or
+      if ((child->m_data_type == ASTNodeDataType::type_name_id_t) or
+          (child->m_data_type == ASTNodeDataType::function_t) or
           (child->m_data_type == ASTNodeDataType::c_function_t)) {
         throw parse_error("invalid argument, cannot print a '" + dataTypeName(child->m_data_type) + "'",
                           std::vector{child->begin()});
diff --git a/tests/test_ASTNodeCFunctionExpressionBuilder.cpp b/tests/test_ASTNodeCFunctionExpressionBuilder.cpp
index 8d6534fa6..99deff5cf 100644
--- a/tests/test_ASTNodeCFunctionExpressionBuilder.cpp
+++ b/tests/test_ASTNodeCFunctionExpressionBuilder.cpp
@@ -63,7 +63,7 @@ class CFunctionRegister
   {
     SymbolTable& symbol_table = *root_node.m_symbol_table;
 
-    CFunctionEmbedderTable& c_function_embedder_table = symbol_table.cFunctionEbedderTable();
+    auto& c_function_embedder_table = symbol_table.cFunctionEmbedderTable();
 
     this->_populateNameCFunctionMap();
 
diff --git a/tests/test_CFunctionEmbedderTable.cpp b/tests/test_CFunctionEmbedderTable.cpp
index 797536f42..e75155f76 100644
--- a/tests/test_CFunctionEmbedderTable.cpp
+++ b/tests/test_CFunctionEmbedderTable.cpp
@@ -1,13 +1,13 @@
 #include <catch2/catch.hpp>
 
 #include <CFunctionEmbedder.hpp>
-#include <CFunctionEmbedderTable.hpp>
+#include <EmbedderTable.hpp>
 
 TEST_CASE("CFunctionEmbedderTable", "[language]")
 {
   rang::setControlMode(rang::control::Off);
 
-  CFunctionEmbedderTable table;
+  EmbedderTable<ICFunctionEmbedder> table;
 
   REQUIRE(table.size() == 0);
 
diff --git a/tests/test_CFunctionProcessor.cpp b/tests/test_CFunctionProcessor.cpp
index 0809ca9bd..2a19c7263 100644
--- a/tests/test_CFunctionProcessor.cpp
+++ b/tests/test_CFunctionProcessor.cpp
@@ -260,7 +260,7 @@ let z:Z, z = round(-1.2);
     MathModule math_module;
 
     bool missing_test = false;
-    for (auto [cmath_name, c_function] : math_module.getNameCFunctionsMap()) {
+    for (auto [cmath_name, c_function] : math_module.getNameCFunctionMap()) {
       if (tested_function_set.find(cmath_name) == tested_function_set.end()) {
         UNSCOPED_INFO("function '" << cmath_name << "' is NOT tested");
         missing_test = true;
diff --git a/tests/test_MathModule.cpp b/tests/test_MathModule.cpp
index 5239387a5..69eb53643 100644
--- a/tests/test_MathModule.cpp
+++ b/tests/test_MathModule.cpp
@@ -1,7 +1,7 @@
 #include <catch2/catch.hpp>
 
 #include <CFunctionEmbedder.hpp>
-#include <CFunctionEmbedderTable.hpp>
+#include <EmbedderTable.hpp>
 
 #include <MathModule.hpp>
 
@@ -10,7 +10,7 @@ TEST_CASE("MathModule", "[language]")
   rang::setControlMode(rang::control::Off);
 
   MathModule math_module;
-  const auto& name_cfunction = math_module.getNameCFunctionsMap();
+  const auto& name_cfunction = math_module.getNameCFunctionMap();
 
   REQUIRE(name_cfunction.size() == 22);
 
diff --git a/tests/test_SymbolTable.cpp b/tests/test_SymbolTable.cpp
index 33645f9ef..14b80ee4a 100644
--- a/tests/test_SymbolTable.cpp
+++ b/tests/test_SymbolTable.cpp
@@ -205,10 +205,10 @@ TEST_CASE("SymbolTable", "[language]")
   {
     std::shared_ptr root_st = std::make_shared<SymbolTable>();
 
-    auto& c_function_table = root_st->cFunctionEbedderTable();
+    auto& c_function_table = root_st->cFunctionEmbedderTable();
     REQUIRE(c_function_table.size() == 0);
 
-    const auto& const_c_function_table = static_cast<const SymbolTable&>(*root_st).cFunctionEbedderTable();
+    const auto& const_c_function_table = static_cast<const SymbolTable&>(*root_st).cFunctionEmbedderTable();
     REQUIRE(const_c_function_table.size() == 0);
 
     c_function_table.add(std::make_shared<CFunctionEmbedder<double, double>>(
-- 
GitLab