Browse files

Another attempt to fix #1150

Here's how the algorithm in balancedString() was modified.  When we
encounter a slash in an interpolation, we:

    * try to find a heregex right after it; if found---skip it.  Three
      slashes always terminate a heregex, no matter if there is an open
      "#{" before them or not, so we don't have to bother about
      sub-interpolations inside the heregex.

    * try to find a regex right after it; if found---skip it.  Simple
      regexen can't contain interpolations.

    * otherwise, assume that the slash means division and carry on.
  • Loading branch information...
1 parent 25e7eea commit 5ce7984a2ba50fd71c2817227ff9a1ea3f98b7d1 @ngn ngn committed Jun 19, 2011
Showing with 18 additions and 1 deletion.
  1. +3 −1 lib/lexer.js
  2. +2 −0 src/lexer.coffee
  3. +13 −0 test/interpolation.coffee
View
4 lib/lexer.js
@@ -461,7 +461,7 @@
throw SyntaxError("Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned");
};
Lexer.prototype.balancedString = function(str, end) {
- var i, letter, prev, stack, _ref2;
+ var i, letter, match, prev, stack, _ref2;
stack = [end];
for (i = 1, _ref2 = str.length; 1 <= _ref2 ? i < _ref2 : i > _ref2; 1 <= _ref2 ? i++ : i--) {
switch (letter = str.charAt(i)) {
@@ -478,6 +478,8 @@
}
if (end === '}' && (letter === '"' || letter === "'")) {
stack.push(end = letter);
+ } else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) {
+ i += match[0].length - 1;
} else if (end === '}' && letter === '{') {
stack.push(end = '}');
} else if (end === '"' && prev === '#' && letter === '{') {
View
2 src/lexer.coffee
@@ -414,6 +414,8 @@ exports.Lexer = class Lexer
continue
if end is '}' and letter in ['"', "'"]
stack.push end = letter
+ else if end is '}' and letter is '/' and match = (HEREGEX.exec(str.slice i) or REGEX.exec(str.slice i))
+ i += match[0].length - 1
else if end is '}' and letter is '{'
stack.push end = '}'
else if end is '"' and prev is '#' and letter is '{'
View
13 test/interpolation.coffee
@@ -20,6 +20,19 @@ eq "#{ "{" }", "{"
eq "#{ '#{}}' } }", '#{}} }'
eq "#{"'#{ ({a: "b#{1}"}['a']) }'"}", "'b1'"
+# Issue #1150: String interpolation regression
+eq "#{'"/'}", '"/'
+eq "#{"/'"}", "/'"
+eq "#{/'"/}", '/\'"/'
+eq "#{"'/" + '/"' + /"'/}", '\'//"/"\'/'
+eq "#{"'/"}#{'/"'}#{/"'/}", '\'//"/"\'/'
+eq "#{6 / 2}", '3'
+eq "#{6 / 2}#{6 / 2}", '33' # parsed as division
+eq "#{6 + /2}#{6/ + 2}", '6/2}#{6/2' # parsed as a regex
+eq "#{6/2}
+ #{6/2}", '3 3' # newline cannot be part of a regex, so it's division
+eq "#{/// "'/'"/" ///}", '/"\'\\/\'"\\/"/' # heregex, stuffed with spicy characters
+
hello = 'Hello'
world = 'World'
ok '#{hello} #{world}!' is '#{hello} #{world}!'

0 comments on commit 5ce7984

Please sign in to comment.