From b1845b51b17a31f8e0073291e60a5df3c44eae19 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Sun, 24 Feb 2013 21:25:25 +0100 Subject: [PATCH] [util/walk] Add findNodeAfter --- index.html | 34 ++++++++++++++++------------------ util/walk.js | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/index.html b/index.html index 5418270a6d..fe54262cfa 100644 --- a/index.html +++ b/index.html @@ -555,17 +555,15 @@ will return null unless the integer has exactly len di else if (/[89]/.test(str) || strict) raise(start, "Invalid number"); else val = parseInt(str, 8); return finishToken(_num, val); - }

Read a string value, interpreting backslash-escapes.

  var rs_str = [];
-
-  function readString(quote) {
+  }

Read a string value, interpreting backslash-escapes.

  function readString(quote) {
     tokPos++;
-    rs_str.length = 0;
+    var out = "";
     for (;;) {
       if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant");
       var ch = input.charCodeAt(tokPos);
       if (ch === quote) {
         ++tokPos;
-        return finishToken(_string, String.fromCharCode.apply(null, rs_str));
+        return finishToken(_string, out);
       }
       if (ch === 92) { // '\'
         ch = input.charCodeAt(++tokPos);
@@ -576,30 +574,30 @@ will return null unless the integer has exactly len di
         ++tokPos;
         if (octal) {
           if (strict) raise(tokPos - 2, "Octal literal in strict mode");
-          rs_str.push(parseInt(octal, 8));
+          out += String.fromCharCode(parseInt(octal, 8));
           tokPos += octal.length - 1;
         } else {
           switch (ch) {
-          case 110: rs_str.push(10); break; // 'n' -> '\n'
-          case 114: rs_str.push(13); break; // 'r' -> '\r'
-          case 120: rs_str.push(readHexChar(2)); break; // 'x'
-          case 117: rs_str.push(readHexChar(4)); break; // 'u'
-          case 85: rs_str.push(readHexChar(8)); break; // 'U'
-          case 116: rs_str.push(9); break; // 't' -> '\t'
-          case 98: rs_str.push(8); break; // 'b' -> '\b'
-          case 118: rs_str.push(11); break; // 'v' -> '\u000b'
-          case 102: rs_str.push(12); break; // 'f' -> '\f'
-          case 48: rs_str.push(0); break; // 0 -> '\0'
+          case 110: out += "\n"; break; // 'n' -> '\n'
+          case 114: out += "\r"; break; // 'r' -> '\r'
+          case 120: out += String.fromCharCode(readHexChar(2)); break; // 'x'
+          case 117: out += String.fromCharCode(readHexChar(4)); break; // 'u'
+          case 85: out += String.fromCharCode(readHexChar(8)); break; // 'U'
+          case 116: out += "\t"; break; // 't' -> '\t'
+          case 98: out += "\b"; break; // 'b' -> '\b'
+          case 118: out += "\v"; break; // 'v' -> '\u000b'
+          case 102: out += "\f"; break; // 'f' -> '\f'
+          case 48: out += "\0"; break; // 0 -> '\0'
           case 13: if (input.charCodeAt(tokPos) === 10) ++tokPos; // '\r\n'
           case 10: // ' \n'
             if (options.locations) { tokLineStart = tokPos; ++tokCurLine; }
             break;
-          default: rs_str.push(ch); break;
+          default: out += String.fromCharCode(ch); break;
           }
         }
       } else {
         if (ch === 13 || ch === 10 || ch === 8232 || ch === 8329) raise(tokStart, "Unterminated string constant");
-        rs_str.push(ch); // '\'
+        out += String.fromCharCode(ch); // '\'
         ++tokPos;
       }
     }
diff --git a/util/walk.js b/util/walk.js
index cfa7eb0b3f..d6f207440b 100644
--- a/util/walk.js
+++ b/util/walk.js
@@ -95,6 +95,24 @@
     }
   };
 
+  // Find the outermost matching node after a given position.
+  exports.findNodeAfter = function(node, pos, test, base, state) {
+    test = makeTest(test);
+    try {
+      if (!base) base = exports.base;
+      var c = function(node, st, override) {
+        if (node.end < pos) return;
+        var type = override || node.type;
+        if (node.start >= pos && test(node, type)) throw new Found(node, st);
+        base[type](node, st, c);
+      };
+      c(node, state);
+    } catch (e) {
+      if (e instanceof Found) return e;
+      throw e;
+    }
+  };
+
   // Used to create a custom walker. Will fill in all missing node
   // type properties with the defaults.
   exports.make = function(funcs, base) {