From 67b4fac378aa035b24a41ebd8d0ed1d9629cf1e8 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Mon, 29 Jul 2019 19:20:02 +0200
Subject: [PATCH] Begin ASTNodeExpressionBuilder tests

---
 src/language/ASTNode.hpp                      |   8 +-
 .../ASTNodeAffectationExpressionBuilder.cpp   |  42 ++++---
 ...ASTNodeBinaryOperatorExpressionBuilder.cpp |  32 +++--
 src/language/ASTNodeExpressionBuilder.cpp     |  92 +++++++++++---
 .../ASTNodeIncDecExpressionBuilder.cpp        |  23 ++--
 .../ASTNodeUnaryOperatorExpressionBuilder.cpp |  15 ++-
 src/language/ASTPrinter.cpp                   |  13 +-
 src/language/ASTPrinter.hpp                   |   1 +
 src/language/CMakeLists.txt                   |   3 +-
 tests/CMakeLists.txt                          |   2 +-
 tests/test_ASTNodeExpressionBuilder.cpp       | 113 ++++++++++++++----
 11 files changed, 268 insertions(+), 76 deletions(-)

diff --git a/src/language/ASTNode.hpp b/src/language/ASTNode.hpp
index 54e47efc3..53d20e687 100644
--- a/src/language/ASTNode.hpp
+++ b/src/language/ASTNode.hpp
@@ -56,11 +56,13 @@ class INodeProcessor
  public:
   virtual void execute(ExecUntilBreakOrContinue& exec_policy) = 0;
 
-  INodeProcessor(const INodeProcessor& node) = delete;
+  virtual std::string describe() const = 0;
 
-  INodeProcessor() {}
+  INodeProcessor(const INodeProcessor&) = delete;
 
-  virtual ~INodeProcessor() {}
+  INodeProcessor() = default;
+
+  virtual ~INodeProcessor() = default;
 };
 
 class SymbolTable;
diff --git a/src/language/ASTNodeAffectationExpressionBuilder.cpp b/src/language/ASTNodeAffectationExpressionBuilder.cpp
index 89a86a295..5eaa3f785 100644
--- a/src/language/ASTNodeAffectationExpressionBuilder.cpp
+++ b/src/language/ASTNodeAffectationExpressionBuilder.cpp
@@ -2,6 +2,8 @@
 #include <PEGGrammar.hpp>
 #include <SymbolTable.hpp>
 
+#include <Demangle.hpp>
+
 template <typename Op>
 struct AffOp;
 
@@ -77,16 +79,10 @@ class AffectationProcessor final : public INodeProcessor
   }()};
 
  public:
-  AffectationProcessor(ASTNode& node) : m_node{node}
+  std::string
+  describe() const
   {
-    if constexpr (_is_defined) {
-      const std::string& symbol = m_node.children[0]->string();
-      auto [i_symbol, found]    = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin());
-      Assert(found);
-      p_value = &i_symbol->second.value();
-    } else {
-      throw parse_error("invalid operands to binary expression", std::vector{m_node.begin()});
-    }
+    return demangle<decltype(*this)>();
   }
 
   void
@@ -106,6 +102,18 @@ class AffectationProcessor final : public INodeProcessor
       }
     }
   }
+
+  AffectationProcessor(ASTNode& node) : m_node{node}
+  {
+    if constexpr (_is_defined) {
+      const std::string& symbol = m_node.children[0]->string();
+      auto [i_symbol, found]    = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin());
+      Assert(found);
+      p_value = &i_symbol->second.value();
+    } else {
+      throw parse_error("invalid operands to binary expression", std::vector{m_node.begin()});
+    }
+  }
 };
 
 template <typename OperatorT, typename DataT>
@@ -116,12 +124,10 @@ class AffectationToStringProcessor final : public INodeProcessor
   ASTNodeDataVariant* p_value{nullptr};
 
  public:
-  AffectationToStringProcessor(ASTNode& node) : m_node{node}
+  std::string
+  describe() const
   {
-    const std::string& symbol = m_node.children[0]->string();
-    auto [i_symbol, found]    = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin());
-    Assert(found);
-    p_value = &i_symbol->second.value();
+    return demangle<decltype(*this)>();
   }
 
   void
@@ -143,6 +149,14 @@ class AffectationToStringProcessor final : public INodeProcessor
       }
     }
   }
+
+  AffectationToStringProcessor(ASTNode& node) : m_node{node}
+  {
+    const std::string& symbol = m_node.children[0]->string();
+    auto [i_symbol, found]    = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin());
+    Assert(found);
+    p_value = &i_symbol->second.value();
+  }
 };
 
 ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode& n)
diff --git a/src/language/ASTNodeBinaryOperatorExpressionBuilder.cpp b/src/language/ASTNodeBinaryOperatorExpressionBuilder.cpp
index 8309bf1b4..496668c57 100644
--- a/src/language/ASTNodeBinaryOperatorExpressionBuilder.cpp
+++ b/src/language/ASTNodeBinaryOperatorExpressionBuilder.cpp
@@ -2,6 +2,8 @@
 #include <PEGGrammar.hpp>
 #include <SymbolTable.hpp>
 
+#include <Demangle.hpp>
+
 #include <type_traits>
 
 template <typename Op>
@@ -156,7 +158,7 @@ class BinaryExpressionProcessor final : public INodeProcessor
   ASTNode& m_node;
 
   PUGS_INLINE auto
-  eval(const ASTNodeDataVariant& a, const ASTNodeDataVariant& b, ASTNodeDataVariant& value)
+  _eval(const ASTNodeDataVariant& a, const ASTNodeDataVariant& b, ASTNodeDataVariant& value)
   {
     // Add 'signed' when necessary to avoid signed/unsigned comparison warnings
     if constexpr ((not(std::is_same_v<A_DataT, bool> or std::is_same_v<B_DataT, bool>)) and
@@ -194,11 +196,10 @@ class BinaryExpressionProcessor final : public INodeProcessor
   }()};
 
  public:
-  BinaryExpressionProcessor(ASTNode& node) : m_node{node}
+  std::string
+  describe() const
   {
-    if constexpr (not _is_defined) {
-      throw parse_error("invalid operands to binary expression", std::vector{m_node.begin()});
-    }
+    return demangle<decltype(*this)>();
   }
 
   void
@@ -208,7 +209,14 @@ class BinaryExpressionProcessor final : public INodeProcessor
       m_node.children[0]->execute(exec_policy);
       m_node.children[1]->execute(exec_policy);
 
-      this->eval(m_node.children[0]->m_value, m_node.children[1]->m_value, m_node.m_value);
+      this->_eval(m_node.children[0]->m_value, m_node.children[1]->m_value, m_node.m_value);
+    }
+  }
+
+  BinaryExpressionProcessor(ASTNode& node) : m_node{node}
+  {
+    if constexpr (not _is_defined) {
+      throw parse_error("invalid operands to binary expression", std::vector{m_node.begin()});
     }
   }
 };
@@ -219,7 +227,7 @@ class ConcatExpressionProcessor final : public INodeProcessor
   ASTNode& m_node;
 
   PUGS_INLINE auto
-  eval(const std::string& a, const ASTNodeDataVariant& b, ASTNodeDataVariant& value)
+  _eval(const std::string& a, const ASTNodeDataVariant& b, ASTNodeDataVariant& value)
   {
     if constexpr (std::is_same_v<B_DataT, std::string>) {
       value = a + std::get<B_DataT>(b);
@@ -229,7 +237,11 @@ class ConcatExpressionProcessor final : public INodeProcessor
   }
 
  public:
-  ConcatExpressionProcessor(ASTNode& node) : m_node{node} {}
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
 
   void
   execute(ExecUntilBreakOrContinue& exec_policy)
@@ -237,8 +249,10 @@ class ConcatExpressionProcessor final : public INodeProcessor
     m_node.children[0]->execute(exec_policy);
     m_node.children[1]->execute(exec_policy);
 
-    this->eval(std::get<std::string>(m_node.children[0]->m_value), m_node.children[1]->m_value, m_node.m_value);
+    this->_eval(std::get<std::string>(m_node.children[0]->m_value), m_node.children[1]->m_value, m_node.m_value);
   }
+
+  ConcatExpressionProcessor(ASTNode& node) : m_node{node} {}
 };
 
 ASTNodeBinaryOperatorExpressionBuilder::ASTNodeBinaryOperatorExpressionBuilder(ASTNode& n)
diff --git a/src/language/ASTNodeExpressionBuilder.cpp b/src/language/ASTNodeExpressionBuilder.cpp
index 93068490c..5c07d1d5e 100644
--- a/src/language/ASTNodeExpressionBuilder.cpp
+++ b/src/language/ASTNodeExpressionBuilder.cpp
@@ -8,12 +8,18 @@
 #include <PEGGrammar.hpp>
 #include <SymbolTable.hpp>
 
+#include <Demangle.hpp>
+
 class ASTNodeList final : public INodeProcessor
 {
   ASTNode& m_node;
 
  public:
-  ASTNodeList(ASTNode& node) : m_node{node} {}
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
 
   void
   execute(ExecUntilBreakOrContinue& exec_policy)
@@ -22,12 +28,18 @@ class ASTNodeList final : public INodeProcessor
       child->execute(exec_policy);
     }
   }
+
+  ASTNodeList(ASTNode& node) : m_node{node} {}
 };
 
 class NoProcess final : public INodeProcessor
 {
  public:
-  NoProcess() {}
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
 
   PUGS_INLINE
   void
@@ -35,6 +47,8 @@ class NoProcess final : public INodeProcessor
   {
     ;
   }
+
+  NoProcess() = default;
 };
 
 class IfStatement final : public INodeProcessor
@@ -42,7 +56,11 @@ class IfStatement final : public INodeProcessor
   ASTNode& m_node;
 
  public:
-  IfStatement(ASTNode& node) : m_node{node} {}
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
 
   void
   execute(ExecUntilBreakOrContinue& exec_policy)
@@ -69,6 +87,8 @@ class IfStatement final : public INodeProcessor
       }
     }
   }
+
+  IfStatement(ASTNode& node) : m_node{node} {}
 };
 
 class DoWhileStatement final : public INodeProcessor
@@ -76,7 +96,11 @@ class DoWhileStatement final : public INodeProcessor
   ASTNode& m_node;
 
  public:
-  DoWhileStatement(ASTNode& node) : m_node{node} {}
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
 
   void
   execute(ExecUntilBreakOrContinue& exec_policy)
@@ -105,6 +129,8 @@ class DoWhileStatement final : public INodeProcessor
         m_node.children[1]->m_value));
     } while (continuation_test);
   }
+
+  DoWhileStatement(ASTNode& node) : m_node{node} {}
 };
 
 class WhileStatement final : public INodeProcessor
@@ -112,7 +138,11 @@ class WhileStatement final : public INodeProcessor
   ASTNode& m_node;
 
  public:
-  WhileStatement(ASTNode& node) : m_node{node} {}
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
 
   void
   execute(ExecUntilBreakOrContinue& exec_policy)
@@ -141,6 +171,8 @@ class WhileStatement final : public INodeProcessor
       }
     }
   }
+
+  WhileStatement(ASTNode& node) : m_node{node} {}
 };
 
 class ForStatement final : public INodeProcessor
@@ -148,7 +180,11 @@ class ForStatement final : public INodeProcessor
   ASTNode& m_node;
 
  public:
-  ForStatement(ASTNode& node) : m_node{node} {}
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
 
   void
   execute(ExecUntilBreakOrContinue& exec_policy)
@@ -180,6 +216,8 @@ class ForStatement final : public INodeProcessor
       m_node.children[2]->execute(exec_policy);
     }
   }
+
+  ForStatement(ASTNode& node) : m_node{node} {}
 };
 
 class NameExpression final : public INodeProcessor
@@ -188,12 +226,10 @@ class NameExpression final : public INodeProcessor
   ASTNodeDataVariant* p_value{nullptr};
 
  public:
-  NameExpression(ASTNode& node) : m_node{node}
+  std::string
+  describe() const
   {
-    const std::string& symbol = m_node.string();
-    auto [i_symbol, found]    = m_node.m_symbol_table->find(symbol, m_node.begin());
-    Assert(found);
-    p_value = &(i_symbol->second.value());
+    return demangle<decltype(*this)>();
   }
 
   void
@@ -201,30 +237,50 @@ class NameExpression final : public INodeProcessor
   {
     m_node.m_value = *p_value;
   }
+
+  NameExpression(ASTNode& node) : m_node{node}
+  {
+    const std::string& symbol = m_node.string();
+    auto [i_symbol, found]    = m_node.m_symbol_table->find(symbol, m_node.begin());
+    Assert(found);
+    p_value = &(i_symbol->second.value());
+  }
 };
 
 class BreakExpression final : public INodeProcessor
 {
  public:
-  BreakExpression() {}
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
 
   void
   execute(ExecUntilBreakOrContinue& exec_policy)
   {
     exec_policy = ExecUntilBreakOrContinue(ExecUntilBreakOrContinue::JumpType::break_jump);
   }
+
+  BreakExpression() = default;
 };
 
 class ContinueExpression final : public INodeProcessor
 {
  public:
-  ContinueExpression() {}
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
 
   void
   execute(ExecUntilBreakOrContinue& exec_policy)
   {
     exec_policy = ExecUntilBreakOrContinue(ExecUntilBreakOrContinue::JumpType::continue_jump);
   }
+
+  ContinueExpression() = default;
 };
 
 class OStreamObject final : public INodeProcessor
@@ -233,9 +289,10 @@ class OStreamObject final : public INodeProcessor
   std::ostream& m_os;
 
  public:
-  OStreamObject(ASTNode& node, std::ostream& os) : m_node{node}, m_os(os)
+  std::string
+  describe() const
   {
-    ;
+    return demangle<decltype(*this)>();
   }
 
   void
@@ -257,6 +314,11 @@ class OStreamObject final : public INodeProcessor
         m_node.children[i]->m_value);
     }
   }
+
+  OStreamObject(ASTNode& node, std::ostream& os) : m_node{node}, m_os(os)
+  {
+    ;
+  }
 };
 
 void
diff --git a/src/language/ASTNodeIncDecExpressionBuilder.cpp b/src/language/ASTNodeIncDecExpressionBuilder.cpp
index cae715aef..485c5d653 100644
--- a/src/language/ASTNodeIncDecExpressionBuilder.cpp
+++ b/src/language/ASTNodeIncDecExpressionBuilder.cpp
@@ -2,6 +2,8 @@
 #include <PEGGrammar.hpp>
 #include <SymbolTable.hpp>
 
+#include <Demangle.hpp>
+
 template <typename Op>
 struct IncDecOp;
 
@@ -66,6 +68,20 @@ class IncDecExpressionProcessor final : public INodeProcessor
   }()};
 
  public:
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
+
+  void
+  execute(ExecUntilBreakOrContinue&)
+  {
+    if constexpr (_is_defined) {
+      m_node.m_value = IncDecOp<IncDecOpT>().eval(std::get<DataT>(*p_value));
+    }
+  }
+
   IncDecExpressionProcessor(ASTNode& node) : m_node{node}
   {
     if constexpr (_is_defined) {
@@ -79,13 +95,6 @@ class IncDecExpressionProcessor final : public INodeProcessor
       throw parse_error("invalid operand to unary operator", std::vector{m_node.begin()});
     }
   }
-  void
-  execute(ExecUntilBreakOrContinue&)
-  {
-    if constexpr (_is_defined) {
-      m_node.m_value = IncDecOp<IncDecOpT>().eval(std::get<DataT>(*p_value));
-    }
-  }
 };
 
 ASTNodeIncDecExpressionBuilder::ASTNodeIncDecExpressionBuilder(ASTNode& n)
diff --git a/src/language/ASTNodeUnaryOperatorExpressionBuilder.cpp b/src/language/ASTNodeUnaryOperatorExpressionBuilder.cpp
index 9112ad553..8d70f9f65 100644
--- a/src/language/ASTNodeUnaryOperatorExpressionBuilder.cpp
+++ b/src/language/ASTNodeUnaryOperatorExpressionBuilder.cpp
@@ -2,6 +2,8 @@
 #include <PEGGrammar.hpp>
 #include <SymbolTable.hpp>
 
+#include <Demangle.hpp>
+
 template <typename Op>
 struct UnaryOp;
 
@@ -32,22 +34,27 @@ class UnaryExpressionProcessor final : public INodeProcessor
 {
   ASTNode& m_node;
 
- public:
   PUGS_INLINE ValueT
-  eval(const ASTNodeDataVariant& a)
+  _eval(const ASTNodeDataVariant& a)
   {
     return UnaryOp<UnaryOpT>().eval(std::get<DataT>(a));
   }
 
  public:
-  UnaryExpressionProcessor(ASTNode& node) : m_node{node} {}
+  std::string
+  describe() const
+  {
+    return demangle<decltype(*this)>();
+  }
 
   void
   execute(ExecUntilBreakOrContinue& exec_policy)
   {
     m_node.children[0]->execute(exec_policy);
-    m_node.m_value = eval(m_node.children[0]->m_value);
+    m_node.m_value = this->_eval(m_node.children[0]->m_value);
   }
+
+  UnaryExpressionProcessor(ASTNode& node) : m_node{node} {}
 };
 
 ASTNodeUnaryOperatorExpressionBuilder::ASTNodeUnaryOperatorExpressionBuilder(ASTNode& n)
diff --git a/src/language/ASTPrinter.cpp b/src/language/ASTPrinter.cpp
index 3f5b7344a..84e03e38f 100644
--- a/src/language/ASTPrinter.cpp
+++ b/src/language/ASTPrinter.cpp
@@ -39,8 +39,19 @@ ASTPrinter::_print(std::ostream& os, const ASTNode& node) const
         }
       },
       node.m_value);
+    os << rang::fg::reset;
   }
-  os << rang::fg::reset << ")\n";
+
+  if (m_info & static_cast<InfoBaseType>(Info::exec_type)) {
+    if (node.m_node_processor) {
+      os << ':';
+      os << rang::fgB::magenta;
+      os << node.m_node_processor->describe();
+      os << rang::fg::reset;
+    }
+  }
+
+  os << ")\n";
 
   if (not node.children.empty()) {
     _print(os, node.children);
diff --git a/src/language/ASTPrinter.hpp b/src/language/ASTPrinter.hpp
index 464a67435..d8eb0802a 100644
--- a/src/language/ASTPrinter.hpp
+++ b/src/language/ASTPrinter.hpp
@@ -19,6 +19,7 @@ class ASTPrinter
     none       = 0,
     data_type  = 1 << 0,
     data_value = 1 << 1,
+    exec_type  = 1 << 2,
     all        = std::numeric_limits<InfoBaseType>::max()
   };
 
diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt
index 3333d9b76..7b440e23e 100644
--- a/src/language/CMakeLists.txt
+++ b/src/language/CMakeLists.txt
@@ -27,4 +27,5 @@ add_library(
 #include_directories(${PUGS_SOURCE_DIR}/utils)
 
 # Additional dependencies
-#add_dependencies(PugsMesh)
+add_dependencies(PugsLanguage
+  PugsUtils)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 29d77d5d0..569578559 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -32,8 +32,8 @@ add_executable (mpi_unit_tests
   )
 
 target_link_libraries (unit_tests
-  PugsUtils
   PugsLanguage
+  PugsUtils
   kokkos
   Catch2
   )
diff --git a/tests/test_ASTNodeExpressionBuilder.cpp b/tests/test_ASTNodeExpressionBuilder.cpp
index 2ce02e86e..b7a6c82a1 100644
--- a/tests/test_ASTNodeExpressionBuilder.cpp
+++ b/tests/test_ASTNodeExpressionBuilder.cpp
@@ -14,26 +14,29 @@
 
 #include <ASTPrinter.hpp>
 
-#define CHECK_AST(data, expected_output)                                                       \
-  {                                                                                            \
-    static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>);             \
-    static_assert(std::is_same_v<std::decay_t<decltype(expected_output)>, std::string_view>);  \
-                                                                                               \
-    string_input input{data, "test.pgs"};                                                      \
-    auto ast = ASTBuilder::build(input);                                                       \
-                                                                                               \
-    ASTSymbolTableBuilder{*ast};                                                               \
-    ASTNodeDataTypeBuilder{*ast};                                                              \
-    ASTNodeValueBuilder{*ast};                                                                 \
-                                                                                               \
-    ASTNodeDeclarationToAffectationConverter{*ast};                                            \
-    ASTNodeDeclarationCleaner{*ast};                                                           \
-                                                                                               \
-    ASTNodeExpressionBuilder{*ast};                                                            \
-    std::stringstream ast_output;                                                              \
-    ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::none}}; \
-                                                                                               \
-    REQUIRE(ast_output.str() == expected_output);                                              \
+#include <Demangle.hpp>
+
+#define CHECK_AST(data, expected_output)                                                            \
+  {                                                                                                 \
+    static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>);                  \
+    static_assert((std::is_same_v<std::decay_t<decltype(expected_output)>, std::string_view>) or    \
+                  (std::is_same_v<std::decay_t<decltype(expected_output)>, std::string>));          \
+                                                                                                    \
+    string_input input{data, "test.pgs"};                                                           \
+    auto ast = ASTBuilder::build(input);                                                            \
+                                                                                                    \
+    ASTSymbolTableBuilder{*ast};                                                                    \
+    ASTNodeDataTypeBuilder{*ast};                                                                   \
+    ASTNodeValueBuilder{*ast};                                                                      \
+                                                                                                    \
+    ASTNodeDeclarationToAffectationConverter{*ast};                                                 \
+    ASTNodeDeclarationCleaner{*ast};                                                                \
+                                                                                                    \
+    ASTNodeExpressionBuilder{*ast};                                                                 \
+    std::stringstream ast_output;                                                                   \
+    ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::exec_type}}; \
+                                                                                                    \
+    REQUIRE(ast_output.str() == expected_output);                                                   \
   }
 
 TEST_CASE("ASTNodeExpressionBuilder", "[language]")
@@ -44,9 +47,77 @@ TEST_CASE("ASTNodeExpressionBuilder", "[language]")
 )";
 
     std::string_view result = R"(
-(root)
+(root:ASTNodeList)
 )";
 
     CHECK_AST(data, result);
   }
+
+  SECTION("string affectation")
+  {
+    SECTION("from bool")
+    {
+      std::string_view data = R"(
+string s = true;
+)";
+
+      std::string result = R"(
+(root:ASTNodeList)
+ `-(language::eq_op:AffectationToStringProcessor<language::eq_op, bool>)
+     +-(language::name:s:NameExpression)
+     `-(language::true_kw:NoProcess)
+)";
+
+      CHECK_AST(data, result);
+    }
+
+    SECTION("from int")
+    {
+      std::string_view data = R"(
+string s = 0;
+)";
+
+      std::string result = R"(
+(root:ASTNodeList)
+ `-(language::eq_op:AffectationToStringProcessor<language::eq_op, long>)
+     +-(language::name:s:NameExpression)
+     `-(language::integer:0:NoProcess)
+)";
+      CHECK_AST(data, result);
+    }
+
+    SECTION("from unsigned")
+    {
+      std::string_view data = R"(
+N n = 0;
+string s = n;
+)";
+
+      std::string result = R"(
+(root:ASTNodeList)
+ +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
+ |   +-(language::name:n:NameExpression)
+ |   `-(language::integer:0:NoProcess)
+ `-(language::eq_op:AffectationToStringProcessor<language::eq_op, unsigned long>)
+     +-(language::name:s:NameExpression)
+     `-(language::name:n:NameExpression)
+)";
+      CHECK_AST(data, result);
+    }
+
+    SECTION("from real")
+    {
+      std::string_view data = R"(
+string s = 0.;
+)";
+
+      std::string result = R"(
+(root:ASTNodeList)
+ `-(language::eq_op:AffectationToStringProcessor<language::eq_op, double>)
+     +-(language::name:s:NameExpression)
+     `-(language::real:0.:NoProcess)
+)";
+      CHECK_AST(data, result);
+    }
+  }
 }
-- 
GitLab