diff --git a/lib/lexer.js b/lib/lexer.js index 9a85d642..b80d471a 100644 --- a/lib/lexer.js +++ b/lib/lexer.js @@ -171,7 +171,7 @@ // to distinguish from division, so we borrow some basic heuristics from // JavaScript and Ruby. Lexer.prototype.regex_token = function regex_token() { - var _a, flags, regex, str; + var flags, regex, str; if (!(this.chunk.match(REGEX_START))) { return false; } @@ -182,7 +182,7 @@ return false; } regex += ((flags = this.chunk.substr(regex.length).match(REGEX_FLAGS))); - if (((0 < (_a = regex.indexOf('${'))) && (_a < regex.indexOf('}'))) || regex.match(REGEX_INTERPOLATION)) { + if (regex.match(REGEX_INTERPOLATION)) { str = regex.substring(1).split('/')[0]; str = str.replace(REGEX_ESCAPE, function(escaped) { return '\\' + escaped; @@ -406,8 +406,9 @@ // contents of the string. This method allows us to have strings within // interpolations within strings etc... Lexer.prototype.balanced_string = function balanced_string(str) { - var _a, _b, _c, _d, close, delimited, i, levels, open, pair; + var _a, _b, _c, _d, close, delimited, i, levels, open, pair, slash; delimited = Array.prototype.slice.call(arguments, 1); + slash = delimited[0][0] === '/'; levels = []; i = 0; while (i < str.length) { @@ -433,13 +434,13 @@ break; } } - if (!(levels.length)) { + if (!levels.length || slash && starts(str, '\n', i)) { break; } i += 1; } if (levels.length) { - if (delimited[0][0] === '/') { + if (slash) { return false; } throw new Error("SyntaxError: Unterminated " + (levels.pop()[0]) + " starting on line " + (this.line + 1)); @@ -606,7 +607,7 @@ ASSIGNMENT = /^(:|=)$/; // Regex-matching-regexes. REGEX_START = /^\/[^\/ ]/; - REGEX_INTERPOLATION = /[^\\]\$[a-zA-Z_@]/; + REGEX_INTERPOLATION = /([^\\]\$[a-zA-Z_@]|[^\\]\$\{.*[^\\]\})/; REGEX_FLAGS = /^[imgy]{0,4}/; REGEX_ESCAPE = /\\[^\$]/g; // Token cleaning regexes. diff --git a/src/lexer.coffee b/src/lexer.coffee index 2da32ec7..c2908e43 100644 --- a/src/lexer.coffee +++ b/src/lexer.coffee @@ -130,7 +130,7 @@ exports.Lexer: class Lexer return false if include NOT_REGEX, @tag() return false unless regex: @balanced_token ['/', '/'] regex += (flags: @chunk.substr(regex.length).match(REGEX_FLAGS)) - if (0 < regex.indexOf('${') < regex.indexOf('}')) or regex.match REGEX_INTERPOLATION + if regex.match REGEX_INTERPOLATION str: regex.substring(1).split('/')[0] str: str.replace REGEX_ESCAPE, (escaped) -> '\\' + escaped @tokens: @tokens.concat [['(', '('], ['NEW', 'new'], ['IDENTIFIER', 'RegExp'], ['CALL_START', '(']] @@ -307,6 +307,7 @@ exports.Lexer: class Lexer # contents of the string. This method allows us to have strings within # interpolations within strings etc... balanced_string: (str, delimited...) -> + slash: delimited[0][0] is '/' levels: [] i: 0 while i < str.length @@ -324,10 +325,10 @@ exports.Lexer: class Lexer levels.push(pair) i += open.length - 1 break - break unless levels.length + break if not levels.length or slash and starts str, '\n', i i += 1 if levels.length - return false if delimited[0][0] is '/' + return false if slash throw new Error "SyntaxError: Unterminated ${levels.pop()[0]} starting on line ${@line + 1}" return false if i is 0 return str.substring(0, i) @@ -472,7 +473,7 @@ ASSIGNMENT : /^(:|=)$/ # Regex-matching-regexes. REGEX_START : /^\/[^\/ ]/ -REGEX_INTERPOLATION: /[^\\]\$[a-zA-Z_@]/ +REGEX_INTERPOLATION: /([^\\]\$[a-zA-Z_@]|[^\\]\$\{.*[^\\]\})/ REGEX_FLAGS : /^[imgy]{0,4}/ REGEX_ESCAPE : /\\[^\$]/g diff --git a/test/test_literals.coffee b/test/test_literals.coffee index 03e483b7..1ad0efa9 100644 --- a/test/test_literals.coffee +++ b/test/test_literals.coffee @@ -31,6 +31,13 @@ money$: 'dollars' ok money$ is 'dollars' +multiline: "one + two + three" + +ok multiline is 'one two three' + + ok {a: (num) -> num is 10 }.a 10 diff --git a/test/test_regexps.coffee b/test/test_regexps.coffee index bce336fd..6ef0018f 100644 --- a/test/test_regexps.coffee +++ b/test/test_regexps.coffee @@ -9,4 +9,6 @@ y: 4 x: 2 g: 1 -ok y / x/g is 2 \ No newline at end of file +ok y / x/g is 2 + +ok 'http://google.com'.match(/:\/\/goog/) \ No newline at end of file