fixing more bugs in balance/interpolate/regexp/string/etc

This commit is contained in:
Jeremy Ashkenas 2010-03-08 22:25:06 -05:00
parent 4b97b15c0c
commit b33b688373
4 changed files with 22 additions and 11 deletions

View File

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

View File

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

View File

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

View File

@ -9,4 +9,6 @@ y: 4
x: 2
g: 1
ok y / x/g is 2
ok y / x/g is 2
ok 'http://google.com'.match(/:\/\/goog/)