Bläddra i källkod

LibJS: Unescape strings in Token::string_value()

Stephan Unverwerth 5 år sedan
förälder
incheckning
3389021291
2 ändrade filer med 59 tillägg och 9 borttagningar
  1. 10 5
      Base/home/anon/js/strings.js
  2. 49 4
      Libraries/LibJS/Token.cpp

+ 10 - 5
Base/home/anon/js/strings.js

@@ -1,7 +1,12 @@
-var d = "Double quoted string";
-var s = 'Single quoted string';
-var e = "Escaped characters \n \" \t \\"
+var d = "Double quoted string\n";
+print(d);
+var s = 'Single quoted string\n';
+print(s)
+var e = "Escaped characters \b \f \n \r \t \v \' \" \\ \n";
+print(e)
 var u = "Unterminated string
-        this is not possible in js"
+        this is not possible in js\n";
+print(u);
 
-var u2 = 'This is neither
+var u2 = 'This is neither\n
+print(u2);

+ 49 - 4
Libraries/LibJS/Token.cpp

@@ -26,6 +26,7 @@
 
 #include "Token.h"
 #include <AK/Assertions.h>
+#include <AK/StringBuilder.h>
 
 namespace JS {
 
@@ -209,6 +210,7 @@ const char* Token::name() const
 
 double Token::double_value() const
 {
+    ASSERT(type() == TokenType::NumericLiteral);
     // FIXME: need to parse double instead of int
     bool ok;
     return m_value.to_int(ok);
@@ -216,15 +218,58 @@ double Token::double_value() const
 
 String Token::string_value() const
 {
-    if (m_value.length() >= 2 && m_value[0] == '"' && m_value[m_value.length() - 1]) {
-        return m_value.substring_view(1, m_value.length() - 2);
+    ASSERT(type() == TokenType::StringLiteral);
+    StringBuilder builder;
+    for (size_t i = 1; i < m_value.length() - 1; ++i) {
+        if (m_value[i] == '\\' && i + 1 < m_value.length() - 1) {
+            i++;
+            switch (m_value[i]) {
+            case 'b':
+                builder.append('\b');
+                break;
+            case 'f':
+                builder.append('\f');
+                break;
+            case 'n':
+                builder.append('\n');
+                break;
+            case 'r':
+                builder.append('\r');
+                break;
+            case 't':
+                builder.append('\t');
+                break;
+            case 'v':
+                builder.append('\v');
+                break;
+            case '0':
+                builder.append((char)0);
+                break;
+            case '\'':
+                builder.append('\'');
+                break;
+            case '"':
+                builder.append('"');
+                break;
+            case '\\':
+                builder.append('\\');
+                break;
+            default:
+                // FIXME: Also parse octal, hex and unicode sequences
+                // should anything else generate a syntax error?
+                builder.append(m_value[i]);
+            }
+
+        } else {
+            builder.append(m_value[i]);
+        }
     }
-    // FIXME: unescape the string and remove quotes
-    return m_value;
+    return builder.to_string();
 }
 
 bool Token::bool_value() const
 {
+    ASSERT(type() == TokenType::BoolLiteral);
     return m_value == "true";
 }