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.
This commit is contained in:
ngn 2011-06-19 20:01:01 +03:00
parent 25e7eeac8f
commit 5ce7984a2b
3 changed files with 18 additions and 1 deletions

View File

@ -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 File

@ -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 File

@ -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}!'