From 07a1b0a35f76daa75d7ea9f29bc79343df62f4f5 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Tue, 25 Jun 2019 01:08:47 +0200
Subject: [PATCH] Complete string literals parsing reading and printing

---
 src/language/PugsParser.cpp | 113 +++++++++++++++++++++++++++++++++++-
 1 file changed, 110 insertions(+), 3 deletions(-)

diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp
index 991348322..cfbe4646c 100644
--- a/src/language/PugsParser.cpp
+++ b/src/language/PugsParser.cpp
@@ -358,10 +358,65 @@ build_node_values(Node& n, std::shared_ptr<SymbolTable>& symbol_table)
         ss >> v;
         n.m_value = v;
       } else if (n.is<language::literal>()) {
-        std::string value(&n.string()[1], n.string().size() - 2);
-        n.m_value = value;
-        std::cout << std::get<std::string>(n.m_value) << '\n';
+        const std::string& node_string = n.string();
+        std::stringstream ss;
+        for (size_t i = 1; i < node_string.size() - 1; ++i) {
+          char c = node_string[i];
+          if (c == '\\') {
+            ++i;
+            char next = node_string[i];
+            switch (next) {
+            case '\'': {
+              ss << '\'';
+              break;
+            }
+            case '"': {
+              ss << '\"';
+              break;
+            }
+            case '?': {
+              ss << '\?';
+              break;
+            }
+            case '\\': {
+              ss << '\\';
+              break;
+            }
+            case 'a': {
+              ss << '\a';
+              break;
+            }
+            case 'b': {
+              ss << '\b';
+              break;
+            }
+            case 'f': {
+              ss << '\f';
+              break;
+            }
+            case 'n': {
+              ss << '\n';
+              break;
+            }
+            case 'r': {
+              ss << '\r';
+              break;
+            }
+            case 't': {
+              ss << '\t';
+              break;
+            }
+            case 'v': {
+              ss << '\v';
+              break;
+            }
+            }
+          } else {
+            ss << node_string[i];
+          }
+        }
 
+        n.m_value = ss.str();
       } else if (n.is<language::for_test>()) {
         // if AST contains a for_test statement, it means that no test were
         // given to the for-loop, so its value is always true
@@ -501,6 +556,58 @@ print(const Node& n)
       using T = std::decay_t<decltype(value)>;
       if constexpr (std::is_same_v<T, std::monostate>) {
         std::cout << "--";
+      } else if constexpr (std::is_same_v<T, std::string>) {
+        const std::string& node_string = value;
+        std::stringstream ss;
+        for (size_t i = 0; i < node_string.size(); ++i) {
+          char c = node_string[i];
+          switch (c) {
+          case '\\': {
+            ss << R"(\\)";
+            break;
+          }
+          case '\"': {
+            ss << R"(\")";
+            break;
+          }
+          case '?': {
+            ss << R"(\?)";
+            break;
+          }
+          case '\a': {
+            ss << R"(\a)";
+            break;
+          }
+          case '\b': {
+            ss << R"(\b)";
+            break;
+          }
+          case '\f': {
+            ss << R"(\f)";
+            break;
+          }
+          case '\n': {
+            ss << R"(\n)";
+            break;
+          }
+          case '\r': {
+            ss << R"(\r)";
+            break;
+          }
+          case '\t': {
+            ss << R"(\t)";
+            break;
+          }
+          case '\v': {
+            ss << R"(\v)";
+            break;
+          }
+          default: {
+            ss << c;
+          }
+          }
+        }
+        std::cout << '\"' << ss.str() << '\"';
       } else {
         std::cout << value;
       }
-- 
GitLab