fixing more bugs in balance/interpolate/regexp/string/etc
This commit is contained in:
parent
4b97b15c0c
commit
b33b688373
13
lib/lexer.js
13
lib/lexer.js
|
@ -171,7 +171,7 @@
|
||||||
// to distinguish from division, so we borrow some basic heuristics from
|
// to distinguish from division, so we borrow some basic heuristics from
|
||||||
// JavaScript and Ruby.
|
// JavaScript and Ruby.
|
||||||
Lexer.prototype.regex_token = function regex_token() {
|
Lexer.prototype.regex_token = function regex_token() {
|
||||||
var _a, flags, regex, str;
|
var flags, regex, str;
|
||||||
if (!(this.chunk.match(REGEX_START))) {
|
if (!(this.chunk.match(REGEX_START))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
regex += ((flags = this.chunk.substr(regex.length).match(REGEX_FLAGS)));
|
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 = regex.substring(1).split('/')[0];
|
||||||
str = str.replace(REGEX_ESCAPE, function(escaped) {
|
str = str.replace(REGEX_ESCAPE, function(escaped) {
|
||||||
return '\\' + escaped;
|
return '\\' + escaped;
|
||||||
|
@ -406,8 +406,9 @@
|
||||||
// contents of the string. This method allows us to have strings within
|
// contents of the string. This method allows us to have strings within
|
||||||
// interpolations within strings etc...
|
// interpolations within strings etc...
|
||||||
Lexer.prototype.balanced_string = function balanced_string(str) {
|
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);
|
delimited = Array.prototype.slice.call(arguments, 1);
|
||||||
|
slash = delimited[0][0] === '/';
|
||||||
levels = [];
|
levels = [];
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < str.length) {
|
while (i < str.length) {
|
||||||
|
@ -433,13 +434,13 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(levels.length)) {
|
if (!levels.length || slash && starts(str, '\n', i)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
if (levels.length) {
|
if (levels.length) {
|
||||||
if (delimited[0][0] === '/') {
|
if (slash) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
throw new Error("SyntaxError: Unterminated " + (levels.pop()[0]) + " starting on line " + (this.line + 1));
|
throw new Error("SyntaxError: Unterminated " + (levels.pop()[0]) + " starting on line " + (this.line + 1));
|
||||||
|
@ -606,7 +607,7 @@
|
||||||
ASSIGNMENT = /^(:|=)$/;
|
ASSIGNMENT = /^(:|=)$/;
|
||||||
// Regex-matching-regexes.
|
// Regex-matching-regexes.
|
||||||
REGEX_START = /^\/[^\/ ]/;
|
REGEX_START = /^\/[^\/ ]/;
|
||||||
REGEX_INTERPOLATION = /[^\\]\$[a-zA-Z_@]/;
|
REGEX_INTERPOLATION = /([^\\]\$[a-zA-Z_@]|[^\\]\$\{.*[^\\]\})/;
|
||||||
REGEX_FLAGS = /^[imgy]{0,4}/;
|
REGEX_FLAGS = /^[imgy]{0,4}/;
|
||||||
REGEX_ESCAPE = /\\[^\$]/g;
|
REGEX_ESCAPE = /\\[^\$]/g;
|
||||||
// Token cleaning regexes.
|
// Token cleaning regexes.
|
||||||
|
|
|
@ -130,7 +130,7 @@ exports.Lexer: class Lexer
|
||||||
return false if include NOT_REGEX, @tag()
|
return false if include NOT_REGEX, @tag()
|
||||||
return false unless regex: @balanced_token ['/', '/']
|
return false unless regex: @balanced_token ['/', '/']
|
||||||
regex += (flags: @chunk.substr(regex.length).match(REGEX_FLAGS))
|
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: regex.substring(1).split('/')[0]
|
||||||
str: str.replace REGEX_ESCAPE, (escaped) -> '\\' + escaped
|
str: str.replace REGEX_ESCAPE, (escaped) -> '\\' + escaped
|
||||||
@tokens: @tokens.concat [['(', '('], ['NEW', 'new'], ['IDENTIFIER', 'RegExp'], ['CALL_START', '(']]
|
@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
|
# contents of the string. This method allows us to have strings within
|
||||||
# interpolations within strings etc...
|
# interpolations within strings etc...
|
||||||
balanced_string: (str, delimited...) ->
|
balanced_string: (str, delimited...) ->
|
||||||
|
slash: delimited[0][0] is '/'
|
||||||
levels: []
|
levels: []
|
||||||
i: 0
|
i: 0
|
||||||
while i < str.length
|
while i < str.length
|
||||||
|
@ -324,10 +325,10 @@ exports.Lexer: class Lexer
|
||||||
levels.push(pair)
|
levels.push(pair)
|
||||||
i += open.length - 1
|
i += open.length - 1
|
||||||
break
|
break
|
||||||
break unless levels.length
|
break if not levels.length or slash and starts str, '\n', i
|
||||||
i += 1
|
i += 1
|
||||||
if levels.length
|
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}"
|
throw new Error "SyntaxError: Unterminated ${levels.pop()[0]} starting on line ${@line + 1}"
|
||||||
return false if i is 0
|
return false if i is 0
|
||||||
return str.substring(0, i)
|
return str.substring(0, i)
|
||||||
|
@ -472,7 +473,7 @@ ASSIGNMENT : /^(:|=)$/
|
||||||
|
|
||||||
# Regex-matching-regexes.
|
# Regex-matching-regexes.
|
||||||
REGEX_START : /^\/[^\/ ]/
|
REGEX_START : /^\/[^\/ ]/
|
||||||
REGEX_INTERPOLATION: /[^\\]\$[a-zA-Z_@]/
|
REGEX_INTERPOLATION: /([^\\]\$[a-zA-Z_@]|[^\\]\$\{.*[^\\]\})/
|
||||||
REGEX_FLAGS : /^[imgy]{0,4}/
|
REGEX_FLAGS : /^[imgy]{0,4}/
|
||||||
REGEX_ESCAPE : /\\[^\$]/g
|
REGEX_ESCAPE : /\\[^\$]/g
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,13 @@ money$: 'dollars'
|
||||||
ok money$ is 'dollars'
|
ok money$ is 'dollars'
|
||||||
|
|
||||||
|
|
||||||
|
multiline: "one
|
||||||
|
two
|
||||||
|
three"
|
||||||
|
|
||||||
|
ok multiline is 'one two three'
|
||||||
|
|
||||||
|
|
||||||
ok {a: (num) -> num is 10 }.a 10
|
ok {a: (num) -> num is 10 }.a 10
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,3 +10,5 @@ x: 2
|
||||||
g: 1
|
g: 1
|
||||||
|
|
||||||
ok y / x/g is 2
|
ok y / x/g is 2
|
||||||
|
|
||||||
|
ok 'http://google.com'.match(/:\/\/goog/)
|
Loading…
Reference in New Issue