diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp index 9913483227d74bc67be8fb351a28d338daebc6fd..cfbe4646caa01b8ddd59eb59f1cdab99862a6d2f 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; }