mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-02-19 03:44:23 -05:00
disabled interpolations in normal regexes
This commit is contained in:
@@ -63,12 +63,12 @@
|
|||||||
spaces = 20 - name.length;
|
spaces = 20 - name.length;
|
||||||
spaces = spaces > 0 ? Array(spaces + 1).join(' ') : '';
|
spaces = spaces > 0 ? Array(spaces + 1).join(' ') : '';
|
||||||
desc = task.description ? ("# " + (task.description)) : '';
|
desc = task.description ? ("# " + (task.description)) : '';
|
||||||
puts("cake " + (name) + (spaces) + " " + (desc));
|
puts("cake " + name + spaces + " " + desc);
|
||||||
}
|
}
|
||||||
return switches.length ? puts(oparse.help()) : undefined;
|
return switches.length ? puts(oparse.help()) : undefined;
|
||||||
};
|
};
|
||||||
missingTask = function(task) {
|
missingTask = function(task) {
|
||||||
puts("No such task: \"" + (task) + "\"");
|
puts("No such task: \"" + task + "\"");
|
||||||
return process.exit(1);
|
return process.exit(1);
|
||||||
};
|
};
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
compile = function(source, topLevel) {
|
compile = function(source, topLevel) {
|
||||||
return path.exists(source, function(exists) {
|
return path.exists(source, function(exists) {
|
||||||
if (!(exists)) {
|
if (!(exists)) {
|
||||||
throw new Error("File not found: " + (source));
|
throw new Error("File not found: " + source);
|
||||||
}
|
}
|
||||||
return fs.stat(source, function(err, stats) {
|
return fs.stat(source, function(err, stats) {
|
||||||
if (stats.isDirectory()) {
|
if (stats.isDirectory()) {
|
||||||
@@ -168,11 +168,11 @@
|
|||||||
js = ' ';
|
js = ' ';
|
||||||
}
|
}
|
||||||
return fs.writeFile(jsPath, js, function(err) {
|
return fs.writeFile(jsPath, js, function(err) {
|
||||||
return opts.compile && opts.watch ? puts("Compiled " + (source)) : undefined;
|
return opts.compile && opts.watch ? puts("Compiled " + source) : undefined;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return path.exists(dir, function(exists) {
|
return path.exists(dir, function(exists) {
|
||||||
return exists ? compile() : exec("mkdir -p " + (dir), compile);
|
return exists ? compile() : exec("mkdir -p " + dir, compile);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
lint = function(js) {
|
lint = function(js) {
|
||||||
@@ -195,7 +195,7 @@
|
|||||||
token = tokens[_i];
|
token = tokens[_i];
|
||||||
_result.push((function() {
|
_result.push((function() {
|
||||||
_ref2 = [token[0], token[1].toString().replace(/\n/, '\\n')], tag = _ref2[0], value = _ref2[1];
|
_ref2 = [token[0], token[1].toString().replace(/\n/, '\\n')], tag = _ref2[0], value = _ref2[1];
|
||||||
return "[" + (tag) + " " + (value) + "]";
|
return "[" + tag + " " + value + "]";
|
||||||
})());
|
})());
|
||||||
}
|
}
|
||||||
return _result;
|
return _result;
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
if (!(action)) {
|
if (!(action)) {
|
||||||
return [patternString, '$$ = $1;', options];
|
return [patternString, '$$ = $1;', options];
|
||||||
}
|
}
|
||||||
action = (match = (action + '').match(unwrap)) ? match[1] : ("(" + (action) + "())");
|
action = (match = (action + '').match(unwrap)) ? match[1] : ("(" + action + "())");
|
||||||
action = action.replace(/\b(?:[A-Z][a-z]+Node|Expressions)\b/g, 'yy.$&');
|
action = action.replace(/\b(?:[A-Z][a-z]+Node|Expressions)\b/g, 'yy.$&');
|
||||||
return [patternString, ("$$ = " + (action) + ";"), options];
|
return [patternString, ("$$ = " + action + ";"), options];
|
||||||
};
|
};
|
||||||
grammar = {
|
grammar = {
|
||||||
Root: [
|
Root: [
|
||||||
|
|||||||
116
lib/lexer.js
116
lib/lexer.js
@@ -1,5 +1,5 @@
|
|||||||
(function() {
|
(function() {
|
||||||
var ASSIGNED, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, CONVERSIONS, HEREDOC, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LEADING_SPACES, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX_END, REGEX_ESCAPE, REGEX_START, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, _ref, compact, count, include, last, starts;
|
var ASSIGNED, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, CONVERSIONS, HEREDOC, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LEADING_SPACES, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, _ref, compact, count, include, last, starts;
|
||||||
Rewriter = require('./rewriter').Rewriter;
|
Rewriter = require('./rewriter').Rewriter;
|
||||||
_ref = require('./helpers'), include = _ref.include, count = _ref.count, starts = _ref.starts, compact = _ref.compact, last = _ref.last;
|
_ref = require('./helpers'), include = _ref.include, count = _ref.count, starts = _ref.starts, compact = _ref.compact, last = _ref.last;
|
||||||
exports.Lexer = (function() {
|
exports.Lexer = (function() {
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
if (include(JS_FORBIDDEN, id)) {
|
if (include(JS_FORBIDDEN, id)) {
|
||||||
if (forcedIdentifier) {
|
if (forcedIdentifier) {
|
||||||
tag = 'STRING';
|
tag = 'STRING';
|
||||||
id = ("\"" + (id) + "\"");
|
id = ("\"" + id + "\"");
|
||||||
if (forcedIdentifier === 'accessor') {
|
if (forcedIdentifier === 'accessor') {
|
||||||
closeIndex = true;
|
closeIndex = true;
|
||||||
if (this.tag() !== '@') {
|
if (this.tag() !== '@') {
|
||||||
@@ -165,60 +165,55 @@
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
Lexer.prototype.regexToken = function() {
|
Lexer.prototype.regexToken = function() {
|
||||||
var _ref2, end, first, flags, match, regex, str;
|
var match;
|
||||||
if (this.chunk.charAt(0) !== '/') {
|
if (this.chunk.charAt(0) !== '/') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (match = HEREGEX.exec(this.chunk)) {
|
if (match = HEREGEX.exec(this.chunk)) {
|
||||||
return this.heregexToken(match);
|
return this.heregexToken(match);
|
||||||
}
|
}
|
||||||
if (!(first = REGEX_START.exec(this.chunk))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (first[1] === ' ' && !('CALL_START' === (_ref2 = this.tag()) || '=' === _ref2)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (include(NOT_REGEX, this.tag())) {
|
if (include(NOT_REGEX, this.tag())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(regex = this.balancedString(this.chunk, [['/', '/']]))) {
|
if (!(match = REGEX.exec(this.chunk))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(end = this.chunk.slice(regex.length).match(REGEX_END))) {
|
this.token('REGEX', match[0]);
|
||||||
return false;
|
this.i += match[0].length;
|
||||||
}
|
|
||||||
flags = end[0];
|
|
||||||
if (~regex.indexOf('#{')) {
|
|
||||||
str = regex.slice(1, -1);
|
|
||||||
this.tokens.push(['IDENTIFIER', 'RegExp'], ['CALL_START', '(']);
|
|
||||||
this.interpolateString("\"" + (str) + "\"", {
|
|
||||||
regex: true
|
|
||||||
});
|
|
||||||
if (flags) {
|
|
||||||
this.tokens.push([',', ','], ['STRING', ("\"" + (flags) + "\"")]);
|
|
||||||
}
|
|
||||||
this.tokens.push(['CALL_END', ')']);
|
|
||||||
} else {
|
|
||||||
this.token('REGEX', regex + flags);
|
|
||||||
}
|
|
||||||
this.i += regex.length + flags.length;
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
Lexer.prototype.heregexToken = function(match) {
|
Lexer.prototype.heregexToken = function(match) {
|
||||||
var _ref2, body, flags, heregex, re;
|
var _i, _len, _ref2, _ref3, _this, body, flags, heregex, re, tag, tokens, value;
|
||||||
_ref2 = match, heregex = _ref2[0], body = _ref2[1], flags = _ref2[2];
|
_ref2 = match, heregex = _ref2[0], body = _ref2[1], flags = _ref2[2];
|
||||||
this.i += heregex.length;
|
this.i += heregex.length;
|
||||||
if (!(~body.indexOf('#{'))) {
|
if (!(~body.indexOf('#{'))) {
|
||||||
re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/');
|
re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/');
|
||||||
this.token('REGEX', "/" + (re || '(?:)') + "/" + (flags));
|
this.token('REGEX', "/" + (re || '(?:)') + "/" + flags);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
this.token('IDENTIFIER', 'RegExp');
|
this.token('IDENTIFIER', 'RegExp');
|
||||||
this.tokens.push(['CALL_START', '(']);
|
this.tokens.push(['CALL_START', '(']);
|
||||||
this.interpolateString("\"" + (body) + "\"", {
|
tokens = [];
|
||||||
regex: true,
|
_ref2 = this.interpolateString('"' + body + '"', {
|
||||||
heregex: true
|
regex: true
|
||||||
});
|
});
|
||||||
|
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||||
|
_ref3 = _ref2[_i], tag = _ref3[0], value = _ref3[1];
|
||||||
|
if (tag === 'TOKENS') {
|
||||||
|
tokens.push.apply(tokens, value);
|
||||||
|
} else {
|
||||||
|
if (!(value = value.slice(1, -1).replace(HEREGEX_OMIT, ''))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tokens.push(['STRING', '"' + value.replace(/[\\\"]/g, '\\$&') + '"']);
|
||||||
|
}
|
||||||
|
tokens.push(['+', '+']);
|
||||||
|
}
|
||||||
|
tokens.pop();
|
||||||
|
if ((((_ref2 = tokens[0]) != null) ? _ref2[0] !== 'STRING' : undefined)) {
|
||||||
|
this.tokens.push(['STRING', '""'], ['+', '+']);
|
||||||
|
}
|
||||||
|
(_this = this.tokens).push.apply(_this, tokens);
|
||||||
if (flags) {
|
if (flags) {
|
||||||
this.tokens.push([',', ','], ['STRING', '"' + flags + '"']);
|
this.tokens.push([',', ','], ['STRING', '"' + flags + '"']);
|
||||||
}
|
}
|
||||||
@@ -404,7 +399,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (indent) {
|
if (indent) {
|
||||||
doc = doc.replace(RegExp("\\n" + (indent), "g"), '\n');
|
doc = doc.replace(RegExp("\\n" + indent, "g"), '\n');
|
||||||
}
|
}
|
||||||
if (herecomment) {
|
if (herecomment) {
|
||||||
return doc;
|
return doc;
|
||||||
@@ -414,7 +409,7 @@
|
|||||||
doc = doc.replace(/\\([\s\S])/g, function(m, c) {
|
doc = doc.replace(/\\([\s\S])/g, function(m, c) {
|
||||||
return ('\n' === c || quote === c) ? c : m;
|
return ('\n' === c || quote === c) ? c : m;
|
||||||
});
|
});
|
||||||
doc = doc.replace(RegExp("" + (quote), "g"), '\\$&');
|
doc = doc.replace(RegExp("" + quote, "g"), '\\$&');
|
||||||
if (quote === "'") {
|
if (quote === "'") {
|
||||||
doc = this.escapeLines(doc, true);
|
doc = this.escapeLines(doc, true);
|
||||||
}
|
}
|
||||||
@@ -448,15 +443,14 @@
|
|||||||
return this.outdentToken(this.indent);
|
return this.outdentToken(this.indent);
|
||||||
};
|
};
|
||||||
Lexer.prototype.identifierError = function(word) {
|
Lexer.prototype.identifierError = function(word) {
|
||||||
throw new Error("SyntaxError: Reserved word \"" + (word) + "\" on line " + (this.line + 1));
|
throw new Error("SyntaxError: Reserved word \"" + word + "\" on line " + (this.line + 1));
|
||||||
};
|
};
|
||||||
Lexer.prototype.assignmentError = function() {
|
Lexer.prototype.assignmentError = function() {
|
||||||
throw new Error("SyntaxError: Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned");
|
throw new Error("SyntaxError: Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned");
|
||||||
};
|
};
|
||||||
Lexer.prototype.balancedString = function(str, delimited, options) {
|
Lexer.prototype.balancedString = function(str, delimited, options) {
|
||||||
var _i, _len, _ref2, close, i, levels, open, pair, slash, slen;
|
var _i, _len, _ref2, close, i, levels, open, pair, slen;
|
||||||
options || (options = {});
|
options || (options = {});
|
||||||
slash = delimited[0][0] === '/';
|
|
||||||
levels = [];
|
levels = [];
|
||||||
i = 0;
|
i = 0;
|
||||||
slen = str.length;
|
slen = str.length;
|
||||||
@@ -482,21 +476,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!levels.length || slash && str.charAt(i) === '\n') {
|
if (!levels.length) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
if (levels.length) {
|
if (levels.length) {
|
||||||
if (slash) {
|
|
||||||
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));
|
||||||
}
|
}
|
||||||
return !i ? false : str.slice(0, i);
|
return !i ? false : str.slice(0, i);
|
||||||
};
|
};
|
||||||
Lexer.prototype.interpolateString = function(str, options) {
|
Lexer.prototype.interpolateString = function(str, options) {
|
||||||
var _i, _len, _ref2, char, expr, heredoc, i, inner, interpolated, lexer, nested, pi, push, regex, s, tag, tok, tokens, value;
|
var _i, _len, _ref2, _this, char, expr, heredoc, i, inner, interpolated, lexer, nested, pi, regex, tag, tok, tokens, value;
|
||||||
if (str.length < 5) {
|
if (str.length < 5) {
|
||||||
return this.token('STRING', this.escapeLines(str, heredoc));
|
return this.token('STRING', this.escapeLines(str, heredoc));
|
||||||
}
|
}
|
||||||
@@ -514,14 +505,14 @@
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (pi < i) {
|
if (pi < i) {
|
||||||
tokens.push(['STRING', '"' + this.escapeLines(str.slice(pi, i), heredoc) + '"']);
|
tokens.push(['STRING', '"' + str.slice(pi, i) + '"']);
|
||||||
}
|
}
|
||||||
inner = expr.slice(1, -1).replace(LEADING_SPACES, '').replace(TRAILING_SPACES, '');
|
inner = expr.slice(1, -1).replace(LEADING_SPACES, '').replace(TRAILING_SPACES, '');
|
||||||
if (inner.length) {
|
if (inner.length) {
|
||||||
if (heredoc) {
|
if (heredoc) {
|
||||||
inner = inner.replace(/\\\"/g, '"');
|
inner = inner.replace(/\\\"/g, '"');
|
||||||
}
|
}
|
||||||
nested = lexer.tokenize("(" + (inner) + ")", {
|
nested = lexer.tokenize("(" + inner + "\n)", {
|
||||||
line: this.line
|
line: this.line
|
||||||
});
|
});
|
||||||
for (_i = 0, _len = nested.length; _i < _len; _i++) {
|
for (_i = 0, _len = nested.length; _i < _len; _i++) {
|
||||||
@@ -531,43 +522,38 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
nested.pop();
|
nested.pop();
|
||||||
|
if (nested.length < 5) {
|
||||||
|
nested.pop();
|
||||||
|
nested.shift();
|
||||||
|
}
|
||||||
tokens.push(['TOKENS', nested]);
|
tokens.push(['TOKENS', nested]);
|
||||||
} else {
|
|
||||||
tokens.push(['STRING', '""']);
|
|
||||||
}
|
}
|
||||||
i += expr.length;
|
i += expr.length;
|
||||||
pi = i + 1;
|
pi = i + 1;
|
||||||
}
|
}
|
||||||
if ((i > pi) && (pi < str.length - 1)) {
|
if ((i > pi) && (pi < str.length - 1)) {
|
||||||
s = this.escapeLines(str.slice(pi, -1), heredoc);
|
tokens.push(['STRING', '"' + str.slice(pi)]);
|
||||||
tokens.push(['STRING', '"' + s + '"']);
|
|
||||||
}
|
}
|
||||||
if (tokens[0][0] !== 'STRING') {
|
if (regex) {
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
interpolated = tokens.length > 1;
|
||||||
|
if ((((_ref2 = tokens[0]) != null) ? _ref2[0] !== 'STRING' : undefined)) {
|
||||||
tokens.unshift(['STRING', '""']);
|
tokens.unshift(['STRING', '""']);
|
||||||
}
|
}
|
||||||
interpolated = !regex && tokens.length > 1;
|
|
||||||
if (interpolated) {
|
if (interpolated) {
|
||||||
this.token('(', '(');
|
this.token('(', '(');
|
||||||
}
|
}
|
||||||
push = tokens.push;
|
|
||||||
for (i = 0, _len = tokens.length; i < _len; i++) {
|
for (i = 0, _len = tokens.length; i < _len; i++) {
|
||||||
_ref2 = tokens[i], tag = _ref2[0], value = _ref2[1];
|
_ref2 = tokens[i], tag = _ref2[0], value = _ref2[1];
|
||||||
if (i) {
|
if (i) {
|
||||||
this.token('+', '+');
|
this.token('+', '+');
|
||||||
}
|
}
|
||||||
if (tag === 'TOKENS') {
|
if (tag === 'TOKENS') {
|
||||||
push.apply(this.tokens, value);
|
(_this = this.tokens).push.apply(_this, value);
|
||||||
continue;
|
} else {
|
||||||
|
this.token(tag, this.escapeLines(value, heredoc));
|
||||||
}
|
}
|
||||||
if (regex) {
|
|
||||||
value = value.slice(1, -1);
|
|
||||||
value = value.replace(/[\\\"]/g, '\\$&');
|
|
||||||
if (options.heregex) {
|
|
||||||
value = value.replace(HEREGEX_OMIT, '');
|
|
||||||
}
|
|
||||||
value = '"' + value + '"';
|
|
||||||
}
|
|
||||||
this.token(tag, value);
|
|
||||||
}
|
}
|
||||||
if (interpolated) {
|
if (interpolated) {
|
||||||
this.token(')', ')');
|
this.token(')', ')');
|
||||||
@@ -615,9 +601,7 @@
|
|||||||
MULTI_DENT = /^(?:\n[ \t]*)+/;
|
MULTI_DENT = /^(?:\n[ \t]*)+/;
|
||||||
SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/;
|
SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/;
|
||||||
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
|
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
|
||||||
REGEX_START = /^\/([^\/])/;
|
REGEX = /^\/(?!\s)(?:[^[\/\n\\]+|\\.|\[([^\\\]]+|\\.)*])+\/[imgy]{0,4}(?![A-Za-z])/;
|
||||||
REGEX_END = /^[imgy]{0,4}(?![a-zA-Z])/;
|
|
||||||
REGEX_ESCAPE = /\\[^#]/g;
|
|
||||||
HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?![A-Za-z])/;
|
HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?![A-Za-z])/;
|
||||||
HEREGEX_OMIT = /\s+(?:#.*)?/g;
|
HEREGEX_OMIT = /\s+(?:#.*)?/g;
|
||||||
MULTILINER = /\n/g;
|
MULTILINER = /\n/g;
|
||||||
|
|||||||
186
lib/nodes.js
186
lib/nodes.js
@@ -214,16 +214,16 @@
|
|||||||
o.scope = new Scope(null, this, null);
|
o.scope = new Scope(null, this, null);
|
||||||
code = this.compileWithDeclarations(o);
|
code = this.compileWithDeclarations(o);
|
||||||
code = code.replace(TRAILING_WHITESPACE, '');
|
code = code.replace(TRAILING_WHITESPACE, '');
|
||||||
return o.noWrap ? code : ("(function() {\n" + (code) + "\n}).call(this);\n");
|
return o.noWrap ? code : ("(function() {\n" + code + "\n}).call(this);\n");
|
||||||
};
|
};
|
||||||
Expressions.prototype.compileWithDeclarations = function(o) {
|
Expressions.prototype.compileWithDeclarations = function(o) {
|
||||||
var code;
|
var code;
|
||||||
code = this.compileNode(o);
|
code = this.compileNode(o);
|
||||||
if (o.scope.hasAssignments(this)) {
|
if (o.scope.hasAssignments(this)) {
|
||||||
code = ("" + (this.tab) + "var " + (o.scope.compiledAssignments()) + ";\n" + (code));
|
code = ("" + this.tab + "var " + (o.scope.compiledAssignments()) + ";\n" + code);
|
||||||
}
|
}
|
||||||
if (!o.globals && o.scope.hasDeclarations(this)) {
|
if (!o.globals && o.scope.hasDeclarations(this)) {
|
||||||
code = ("" + (this.tab) + "var " + (o.scope.compiledDeclarations()) + ";\n" + (code));
|
code = ("" + this.tab + "var " + (o.scope.compiledDeclarations()) + ";\n" + code);
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
};
|
};
|
||||||
@@ -233,7 +233,7 @@
|
|||||||
compiledNode = node.compile(merge(o, {
|
compiledNode = node.compile(merge(o, {
|
||||||
top: true
|
top: true
|
||||||
}));
|
}));
|
||||||
return node.isStatement(o) ? compiledNode : ("" + (this.idt()) + (compiledNode) + ";");
|
return node.isStatement(o) ? compiledNode : ("" + (this.idt()) + compiledNode + ";");
|
||||||
};
|
};
|
||||||
return Expressions;
|
return Expressions;
|
||||||
})();
|
})();
|
||||||
@@ -295,7 +295,7 @@
|
|||||||
if (this.expression.isStatement(o)) {
|
if (this.expression.isStatement(o)) {
|
||||||
o.asStatement = true;
|
o.asStatement = true;
|
||||||
}
|
}
|
||||||
return "" + (this.tab) + "return " + (this.expression.compile(o)) + ";";
|
return "" + this.tab + "return " + (this.expression.compile(o)) + ";";
|
||||||
};
|
};
|
||||||
return ReturnNode;
|
return ReturnNode;
|
||||||
})();
|
})();
|
||||||
@@ -376,7 +376,7 @@
|
|||||||
}
|
}
|
||||||
code = this.base.compile(o);
|
code = this.base.compile(o);
|
||||||
if (props[0] instanceof AccessorNode && this.isNumber() || o.top && this.base instanceof ObjectNode) {
|
if (props[0] instanceof AccessorNode && this.isNumber() || o.top && this.base instanceof ObjectNode) {
|
||||||
code = ("(" + (code) + ")");
|
code = ("(" + code + ")");
|
||||||
}
|
}
|
||||||
for (_i = 0, _len = props.length; _i < _len; _i++) {
|
for (_i = 0, _len = props.length; _i < _len; _i++) {
|
||||||
prop = props[_i];
|
prop = props[_i];
|
||||||
@@ -477,7 +477,7 @@
|
|||||||
if (!(name)) {
|
if (!(name)) {
|
||||||
throw Error("cannot call super on an anonymous function.");
|
throw Error("cannot call super on an anonymous function.");
|
||||||
}
|
}
|
||||||
return method.klass ? ("" + (method.klass) + ".__super__." + (name)) : ("" + (name) + ".__super__.constructor");
|
return method.klass ? ("" + (method.klass) + ".__super__." + name) : ("" + name + ".__super__.constructor");
|
||||||
};
|
};
|
||||||
CallNode.prototype.unfoldSoak = function(o) {
|
CallNode.prototype.unfoldSoak = function(o) {
|
||||||
var _i, _len, _ref2, call, list, node;
|
var _i, _len, _ref2, call, list, node;
|
||||||
@@ -530,7 +530,7 @@
|
|||||||
}
|
}
|
||||||
left = ("typeof " + (left.compile(o)) + " !== \"function\"");
|
left = ("typeof " + (left.compile(o)) + " !== \"function\"");
|
||||||
rite = rite.compile(o);
|
rite = rite.compile(o);
|
||||||
return ("(" + (left) + " ? undefined : " + (rite) + ")");
|
return ("(" + left + " ? undefined : " + rite + ")");
|
||||||
}
|
}
|
||||||
_ref2 = this.args;
|
_ref2 = this.args;
|
||||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||||
@@ -547,16 +547,16 @@
|
|||||||
}
|
}
|
||||||
return _result;
|
return _result;
|
||||||
}).call(this).join(', ');
|
}).call(this).join(', ');
|
||||||
return this.isSuper ? this.compileSuper(args, o) : ("" + (this.prefix()) + (this.variable.compile(o)) + "(" + (args) + ")");
|
return this.isSuper ? this.compileSuper(args, o) : ("" + (this.prefix()) + (this.variable.compile(o)) + "(" + args + ")");
|
||||||
};
|
};
|
||||||
CallNode.prototype.compileSuper = function(args, o) {
|
CallNode.prototype.compileSuper = function(args, o) {
|
||||||
return "" + (this.superReference(o)) + ".call(this" + (args.length ? ', ' : '') + (args) + ")";
|
return "" + (this.superReference(o)) + ".call(this" + (args.length ? ', ' : '') + args + ")";
|
||||||
};
|
};
|
||||||
CallNode.prototype.compileSplat = function(o) {
|
CallNode.prototype.compileSplat = function(o) {
|
||||||
var _i, _len, _ref2, a, arg, argvar, b, base, c, call, fun, idt, name, ref, splatargs;
|
var _i, _len, _ref2, a, arg, argvar, b, base, c, call, fun, idt, name, ref, splatargs;
|
||||||
splatargs = this.compileSplatArguments(o);
|
splatargs = this.compileSplatArguments(o);
|
||||||
if (this.isSuper) {
|
if (this.isSuper) {
|
||||||
return ("" + (this.superReference(o)) + ".apply(this, " + (splatargs) + ")");
|
return ("" + (this.superReference(o)) + ".apply(this, " + splatargs + ")");
|
||||||
}
|
}
|
||||||
if (!(this.isNew)) {
|
if (!(this.isNew)) {
|
||||||
if (!((base = this.variable) instanceof ValueNode)) {
|
if (!((base = this.variable) instanceof ValueNode)) {
|
||||||
@@ -564,14 +564,14 @@
|
|||||||
}
|
}
|
||||||
if ((name = base.properties.pop()) && base.isComplex()) {
|
if ((name = base.properties.pop()) && base.isComplex()) {
|
||||||
ref = o.scope.freeVariable('this');
|
ref = o.scope.freeVariable('this');
|
||||||
fun = ("(" + (ref) + " = " + (base.compile(o)) + ")" + (name.compile(o)));
|
fun = ("(" + ref + " = " + (base.compile(o)) + ")" + (name.compile(o)));
|
||||||
} else {
|
} else {
|
||||||
fun = (ref = base.compile(o));
|
fun = (ref = base.compile(o));
|
||||||
if (name) {
|
if (name) {
|
||||||
fun += name.compile(o);
|
fun += name.compile(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ("" + (fun) + ".apply(" + (ref) + ", " + (splatargs) + ")");
|
return ("" + fun + ".apply(" + ref + ", " + splatargs + ")");
|
||||||
}
|
}
|
||||||
call = 'call(this)';
|
call = 'call(this)';
|
||||||
argvar = function(n) {
|
argvar = function(n) {
|
||||||
@@ -588,7 +588,7 @@
|
|||||||
a = o.scope.freeVariable('ctor');
|
a = o.scope.freeVariable('ctor');
|
||||||
b = o.scope.freeVariable('ref');
|
b = o.scope.freeVariable('ref');
|
||||||
c = o.scope.freeVariable('result');
|
c = o.scope.freeVariable('result');
|
||||||
return "(function() {\n" + (idt = this.idt(1)) + "var ctor = function() {};\n" + (idt) + (utility('extends')) + "(ctor, " + (a) + " = " + (this.variable.compile(o)) + ");\n" + (idt) + "return typeof (" + (c) + " = " + (a) + ".apply(" + (b) + " = new ctor, " + (splatargs) + ")) === \"object\" ? " + (c) + " : " + (b) + ";\n" + (this.tab) + "})." + (call);
|
return "(function() {\n" + (idt = this.idt(1)) + "var ctor = function() {};\n" + idt + (utility('extends')) + "(ctor, " + a + " = " + (this.variable.compile(o)) + ");\n" + idt + "return typeof (" + c + " = " + a + ".apply(" + b + " = new ctor, " + splatargs + ")) === \"object\" ? " + c + " : " + b + ";\n" + this.tab + "})." + call;
|
||||||
};
|
};
|
||||||
return CallNode;
|
return CallNode;
|
||||||
})();
|
})();
|
||||||
@@ -623,7 +623,7 @@
|
|||||||
AccessorNode.prototype.compileNode = function(o) {
|
AccessorNode.prototype.compileNode = function(o) {
|
||||||
var name, namePart;
|
var name, namePart;
|
||||||
name = this.name.compile(o);
|
name = this.name.compile(o);
|
||||||
namePart = name.match(IS_STRING) ? ("[" + (name) + "]") : ("." + (name));
|
namePart = name.match(IS_STRING) ? ("[" + name + "]") : ("." + name);
|
||||||
return this.prototype + namePart;
|
return this.prototype + namePart;
|
||||||
};
|
};
|
||||||
AccessorNode.prototype.isComplex = NO;
|
AccessorNode.prototype.isComplex = NO;
|
||||||
@@ -642,7 +642,7 @@
|
|||||||
var idx, prefix;
|
var idx, prefix;
|
||||||
idx = this.index.compile(o);
|
idx = this.index.compile(o);
|
||||||
prefix = this.proto ? '.prototype' : '';
|
prefix = this.proto ? '.prototype' : '';
|
||||||
return "" + (prefix) + "[" + (idx) + "]";
|
return "" + prefix + "[" + idx + "]";
|
||||||
};
|
};
|
||||||
IndexNode.prototype.isComplex = function() {
|
IndexNode.prototype.isComplex = function() {
|
||||||
return this.index.isComplex();
|
return this.index.isComplex();
|
||||||
@@ -692,20 +692,20 @@
|
|||||||
}
|
}
|
||||||
idx = del(o, 'index');
|
idx = del(o, 'index');
|
||||||
step = del(o, 'step');
|
step = del(o, 'step');
|
||||||
vars = ("" + (idx) + " = " + (this.fromVar));
|
vars = ("" + idx + " = " + this.fromVar);
|
||||||
intro = ("(" + (this.fromVar) + " <= " + (this.toVar) + " ? " + (idx));
|
intro = ("(" + this.fromVar + " <= " + this.toVar + " ? " + idx);
|
||||||
compare = ("" + (intro) + " <" + (this.equals) + " " + (this.toVar) + " : " + (idx) + " >" + (this.equals) + " " + (this.toVar) + ")");
|
compare = ("" + intro + " <" + this.equals + " " + this.toVar + " : " + idx + " >" + this.equals + " " + this.toVar + ")");
|
||||||
stepPart = step ? step.compile(o) : '1';
|
stepPart = step ? step.compile(o) : '1';
|
||||||
incr = step ? ("" + (idx) + " += " + (stepPart)) : ("" + (intro) + " += " + (stepPart) + " : " + (idx) + " -= " + (stepPart) + ")");
|
incr = step ? ("" + idx + " += " + stepPart) : ("" + intro + " += " + stepPart + " : " + idx + " -= " + stepPart + ")");
|
||||||
return "" + (vars) + "; " + (compare) + "; " + (incr);
|
return "" + vars + "; " + compare + "; " + incr;
|
||||||
};
|
};
|
||||||
RangeNode.prototype.compileSimple = function(o) {
|
RangeNode.prototype.compileSimple = function(o) {
|
||||||
var _ref2, from, idx, step, to;
|
var _ref2, from, idx, step, to;
|
||||||
_ref2 = [+this.fromNum, +this.toNum], from = _ref2[0], to = _ref2[1];
|
_ref2 = [+this.fromNum, +this.toNum], from = _ref2[0], to = _ref2[1];
|
||||||
idx = del(o, 'index');
|
idx = del(o, 'index');
|
||||||
step = del(o, 'step');
|
step = del(o, 'step');
|
||||||
step && (step = ("" + (idx) + " += " + (step.compile(o))));
|
step && (step = ("" + idx + " += " + (step.compile(o))));
|
||||||
return from <= to ? ("" + (idx) + " = " + (from) + "; " + (idx) + " <" + (this.equals) + " " + (to) + "; " + (step || ("" + (idx) + "++"))) : ("" + (idx) + " = " + (from) + "; " + (idx) + " >" + (this.equals) + " " + (to) + "; " + (step || ("" + (idx) + "--")));
|
return from <= to ? ("" + idx + " = " + from + "; " + idx + " <" + this.equals + " " + to + "; " + (step || ("" + idx + "++"))) : ("" + idx + " = " + from + "; " + idx + " >" + this.equals + " " + to + "; " + (step || ("" + idx + "--")));
|
||||||
};
|
};
|
||||||
RangeNode.prototype.compileArray = function(o) {
|
RangeNode.prototype.compileArray = function(o) {
|
||||||
var _i, _ref2, _ref3, _result, body, clause, i, idt, post, pre, range, result, vars;
|
var _i, _ref2, _ref3, _result, body, clause, i, idt, post, pre, range, result, vars;
|
||||||
@@ -726,16 +726,16 @@
|
|||||||
}
|
}
|
||||||
i = o.scope.freeVariable('i');
|
i = o.scope.freeVariable('i');
|
||||||
result = o.scope.freeVariable('result');
|
result = o.scope.freeVariable('result');
|
||||||
pre = ("\n" + (idt) + (result) + " = []; " + (vars));
|
pre = ("\n" + idt + result + " = []; " + vars);
|
||||||
if (this.fromNum && this.toNum) {
|
if (this.fromNum && this.toNum) {
|
||||||
o.index = i;
|
o.index = i;
|
||||||
body = this.compileSimple(o);
|
body = this.compileSimple(o);
|
||||||
} else {
|
} else {
|
||||||
clause = ("" + (this.fromVar) + " <= " + (this.toVar) + " ?");
|
clause = ("" + this.fromVar + " <= " + this.toVar + " ?");
|
||||||
body = ("var " + (i) + " = " + (this.fromVar) + "; " + (clause) + " " + (i) + " <" + (this.equals) + " " + (this.toVar) + " : " + (i) + " >" + (this.equals) + " " + (this.toVar) + "; " + (clause) + " " + (i) + " += 1 : " + (i) + " -= 1");
|
body = ("var " + i + " = " + this.fromVar + "; " + clause + " " + i + " <" + this.equals + " " + this.toVar + " : " + i + " >" + this.equals + " " + this.toVar + "; " + clause + " " + i + " += 1 : " + i + " -= 1");
|
||||||
}
|
}
|
||||||
post = ("{ " + (result) + ".push(" + (i) + "); }\n" + (idt) + "return " + (result) + ";\n" + (o.indent));
|
post = ("{ " + result + ".push(" + i + "); }\n" + idt + "return " + result + ";\n" + (o.indent));
|
||||||
return "(function() {" + (pre) + "\n" + (idt) + "for (" + (body) + ")" + (post) + "}).call(this)";
|
return "(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).call(this)";
|
||||||
};
|
};
|
||||||
return RangeNode;
|
return RangeNode;
|
||||||
})();
|
})();
|
||||||
@@ -756,7 +756,7 @@
|
|||||||
if (to) {
|
if (to) {
|
||||||
to = ', ' + to;
|
to = ', ' + to;
|
||||||
}
|
}
|
||||||
return ".slice(" + (from) + (to) + ")";
|
return ".slice(" + from + to + ")";
|
||||||
};
|
};
|
||||||
return SliceNode;
|
return SliceNode;
|
||||||
})();
|
})();
|
||||||
@@ -808,7 +808,7 @@
|
|||||||
}).call(this);
|
}).call(this);
|
||||||
props = props.join('');
|
props = props.join('');
|
||||||
obj = '{' + (props ? '\n' + props + '\n' + this.idt() : '') + '}';
|
obj = '{' + (props ? '\n' + props + '\n' + this.idt() : '') + '}';
|
||||||
return top ? ("(" + (obj) + ")") : obj;
|
return top ? ("(" + obj + ")") : obj;
|
||||||
};
|
};
|
||||||
return ObjectNode;
|
return ObjectNode;
|
||||||
})();
|
})();
|
||||||
@@ -836,15 +836,15 @@
|
|||||||
if (obj instanceof SplatNode) {
|
if (obj instanceof SplatNode) {
|
||||||
return this.compileSplatLiteral(o);
|
return this.compileSplatLiteral(o);
|
||||||
} else if (obj instanceof CommentNode) {
|
} else if (obj instanceof CommentNode) {
|
||||||
objects.push("\n" + (code) + "\n" + (o.indent));
|
objects.push("\n" + code + "\n" + (o.indent));
|
||||||
} else if (i === this.objects.length - 1) {
|
} else if (i === this.objects.length - 1) {
|
||||||
objects.push(code);
|
objects.push(code);
|
||||||
} else {
|
} else {
|
||||||
objects.push("" + (code) + ", ");
|
objects.push("" + code + ", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
objects = objects.join('');
|
objects = objects.join('');
|
||||||
return indexOf(objects, '\n') >= 0 ? ("[\n" + (this.idt(1)) + (objects) + "\n" + (this.tab) + "]") : ("[" + (objects) + "]");
|
return indexOf(objects, '\n') >= 0 ? ("[\n" + (this.idt(1)) + objects + "\n" + this.tab + "]") : ("[" + objects + "]");
|
||||||
};
|
};
|
||||||
return ArrayNode;
|
return ArrayNode;
|
||||||
})();
|
})();
|
||||||
@@ -909,7 +909,7 @@
|
|||||||
if (constructor.body.empty()) {
|
if (constructor.body.empty()) {
|
||||||
constructor.body.push(new ReturnNode(literal('this')));
|
constructor.body.push(new ReturnNode(literal('this')));
|
||||||
}
|
}
|
||||||
constructor.body.unshift(literal("this." + (pname) + " = function(){ return " + (className) + ".prototype." + (pname) + ".apply(" + (me) + ", arguments); }"));
|
constructor.body.unshift(literal("this." + pname + " = function(){ return " + className + ".prototype." + pname + ".apply(" + me + ", arguments); }"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pvar) {
|
if (pvar) {
|
||||||
@@ -920,7 +920,7 @@
|
|||||||
props.push(prop);
|
props.push(prop);
|
||||||
}
|
}
|
||||||
if (me) {
|
if (me) {
|
||||||
constructor.body.unshift(literal("" + (me) + " = this"));
|
constructor.body.unshift(literal("" + me + " = this"));
|
||||||
}
|
}
|
||||||
construct = this.idt() + (new AssignNode(this.variable, constructor)).compile(merge(o, {
|
construct = this.idt() + (new AssignNode(this.variable, constructor)).compile(merge(o, {
|
||||||
sharedScope: constScope
|
sharedScope: constScope
|
||||||
@@ -970,16 +970,16 @@
|
|||||||
}
|
}
|
||||||
val = this.value.compile(o);
|
val = this.value.compile(o);
|
||||||
if (this.context === 'object') {
|
if (this.context === 'object') {
|
||||||
return ("" + (name) + ": " + (val));
|
return ("" + name + ": " + val);
|
||||||
}
|
}
|
||||||
if (!(isValue && (this.variable.hasProperties() || this.variable.namespaced))) {
|
if (!(isValue && (this.variable.hasProperties() || this.variable.namespaced))) {
|
||||||
o.scope.find(name);
|
o.scope.find(name);
|
||||||
}
|
}
|
||||||
val = ("" + (name) + " = " + (val));
|
val = ("" + name + " = " + val);
|
||||||
if (stmt) {
|
if (stmt) {
|
||||||
return ("" + (this.tab) + (val) + ";");
|
return ("" + this.tab + val + ";");
|
||||||
}
|
}
|
||||||
return top || this.parenthetical ? val : ("(" + (val) + ")");
|
return top || this.parenthetical ? val : ("(" + val + ")");
|
||||||
};
|
};
|
||||||
AssignNode.prototype.compilePatternMatch = function(o) {
|
AssignNode.prototype.compilePatternMatch = function(o) {
|
||||||
var _len, _ref2, accessClass, assigns, code, i, idx, isObject, obj, objects, olength, otop, splat, top, val, valVar, value;
|
var _len, _ref2, accessClass, assigns, code, i, idx, isObject, obj, objects, olength, otop, splat, top, val, valVar, value;
|
||||||
@@ -1009,7 +1009,7 @@
|
|||||||
top: true
|
top: true
|
||||||
});
|
});
|
||||||
valVar = o.scope.freeVariable('ref');
|
valVar = o.scope.freeVariable('ref');
|
||||||
assigns = [("" + (valVar) + " = " + (value.compile(o)))];
|
assigns = [("" + valVar + " = " + (value.compile(o)))];
|
||||||
splat = false;
|
splat = false;
|
||||||
for (i = 0, _len = objects.length; i < _len; i++) {
|
for (i = 0, _len = objects.length; i < _len; i++) {
|
||||||
obj = objects[i];
|
obj = objects[i];
|
||||||
@@ -1030,7 +1030,7 @@
|
|||||||
splat = true;
|
splat = true;
|
||||||
} else {
|
} else {
|
||||||
if (typeof idx !== 'object') {
|
if (typeof idx !== 'object') {
|
||||||
idx = literal(splat ? ("" + (valVar) + ".length - " + (olength - idx)) : idx);
|
idx = literal(splat ? ("" + valVar + ".length - " + (olength - idx)) : idx);
|
||||||
}
|
}
|
||||||
val = new ValueNode(literal(valVar), [new accessClass(idx)]);
|
val = new ValueNode(literal(valVar), [new accessClass(idx)]);
|
||||||
}
|
}
|
||||||
@@ -1040,7 +1040,7 @@
|
|||||||
assigns.push(valVar);
|
assigns.push(valVar);
|
||||||
}
|
}
|
||||||
code = assigns.join(', ');
|
code = assigns.join(', ');
|
||||||
return top || this.parenthetical ? code : ("(" + (code) + ")");
|
return top || this.parenthetical ? code : ("(" + code + ")");
|
||||||
};
|
};
|
||||||
AssignNode.prototype.compileSplice = function(o) {
|
AssignNode.prototype.compileSplice = function(o) {
|
||||||
var from, name, plus, range, ref, to, val;
|
var from, name, plus, range, ref, to, val;
|
||||||
@@ -1048,10 +1048,10 @@
|
|||||||
name = this.variable.compile(o);
|
name = this.variable.compile(o);
|
||||||
plus = range.exclusive ? '' : ' + 1';
|
plus = range.exclusive ? '' : ' + 1';
|
||||||
from = range.from ? range.from.compile(o) : '0';
|
from = range.from ? range.from.compile(o) : '0';
|
||||||
to = range.to ? range.to.compile(o) + ' - ' + from + plus : ("" + (name) + ".length");
|
to = range.to ? range.to.compile(o) + ' - ' + from + plus : ("" + name + ".length");
|
||||||
ref = o.scope.freeVariable('ref');
|
ref = o.scope.freeVariable('ref');
|
||||||
val = this.value.compile(o);
|
val = this.value.compile(o);
|
||||||
return "([].splice.apply(" + (name) + ", [" + (from) + ", " + (to) + "].concat(" + (ref) + " = " + (val) + ")), " + (ref) + ")";
|
return "([].splice.apply(" + name + ", [" + from + ", " + to + "].concat(" + ref + " = " + val + ")), " + ref + ")";
|
||||||
};
|
};
|
||||||
return AssignNode;
|
return AssignNode;
|
||||||
})();
|
})();
|
||||||
@@ -1125,11 +1125,11 @@
|
|||||||
(o.scope.parameter(param));
|
(o.scope.parameter(param));
|
||||||
}
|
}
|
||||||
code = this.body.expressions.length ? ("\n" + (this.body.compileWithDeclarations(o)) + "\n") : '';
|
code = this.body.expressions.length ? ("\n" + (this.body.compileWithDeclarations(o)) + "\n") : '';
|
||||||
func = ("function(" + (params.join(', ')) + ") {" + (code) + (code && this.tab) + "}");
|
func = ("function(" + (params.join(', ')) + ") {" + code + (code && this.tab) + "}");
|
||||||
if (this.bound) {
|
if (this.bound) {
|
||||||
return ("(" + (utility('bind')) + "(" + (func) + ", " + (this.context) + "))");
|
return ("(" + (utility('bind')) + "(" + func + ", " + this.context + "))");
|
||||||
}
|
}
|
||||||
return top ? ("(" + (func) + ")") : func;
|
return top ? ("(" + func + ")") : func;
|
||||||
};
|
};
|
||||||
CodeNode.prototype.topSensitive = YES;
|
CodeNode.prototype.topSensitive = YES;
|
||||||
CodeNode.prototype.traverseChildren = function(crossScope, func) {
|
CodeNode.prototype.traverseChildren = function(crossScope, func) {
|
||||||
@@ -1190,7 +1190,7 @@
|
|||||||
o.scope.assign(len, "arguments.length");
|
o.scope.assign(len, "arguments.length");
|
||||||
variadic = o.scope.freeVariable('result');
|
variadic = o.scope.freeVariable('result');
|
||||||
o.scope.assign(variadic, len + ' >= ' + this.arglength);
|
o.scope.assign(variadic, len + ' >= ' + this.arglength);
|
||||||
end = this.trailings.length ? (", " + (len) + " - " + (this.trailings.length)) : undefined;
|
end = this.trailings.length ? (", " + len + " - " + (this.trailings.length)) : undefined;
|
||||||
_ref2 = this.trailings;
|
_ref2 = this.trailings;
|
||||||
for (idx = 0, _len = _ref2.length; idx < _len; idx++) {
|
for (idx = 0, _len = _ref2.length; idx < _len; idx++) {
|
||||||
trailing = _ref2[idx];
|
trailing = _ref2[idx];
|
||||||
@@ -1200,15 +1200,15 @@
|
|||||||
assign.value = trailing;
|
assign.value = trailing;
|
||||||
}
|
}
|
||||||
pos = this.trailings.length - idx;
|
pos = this.trailings.length - idx;
|
||||||
o.scope.assign(trailing.compile(o), "arguments[" + (variadic) + " ? " + (len) + " - " + (pos) + " : " + (this.index + idx) + "]");
|
o.scope.assign(trailing.compile(o), "arguments[" + variadic + " ? " + len + " - " + pos + " : " + (this.index + idx) + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "" + (name) + " = " + (utility('slice')) + ".call(arguments, " + (this.index) + (end) + ")";
|
return "" + name + " = " + (utility('slice')) + ".call(arguments, " + this.index + end + ")";
|
||||||
};
|
};
|
||||||
SplatNode.prototype.compileValue = function(o, name, index, trailings) {
|
SplatNode.prototype.compileValue = function(o, name, index, trailings) {
|
||||||
var trail;
|
var trail;
|
||||||
trail = trailings ? (", " + (name) + ".length - " + (trailings)) : '';
|
trail = trailings ? (", " + name + ".length - " + trailings) : '';
|
||||||
return "" + (utility('slice')) + ".call(" + (name) + ", " + (index) + (trail) + ")";
|
return "" + (utility('slice')) + ".call(" + name + ", " + index + trail + ")";
|
||||||
};
|
};
|
||||||
SplatNode.compileSplattedArray = function(list, o) {
|
SplatNode.compileSplattedArray = function(list, o) {
|
||||||
var _len, arg, args, code, end, i, prev;
|
var _len, arg, args, code, end, i, prev;
|
||||||
@@ -1220,16 +1220,16 @@
|
|||||||
prev = args[end];
|
prev = args[end];
|
||||||
if (!(arg instanceof SplatNode)) {
|
if (!(arg instanceof SplatNode)) {
|
||||||
if (prev && starts(prev, '[') && ends(prev, ']')) {
|
if (prev && starts(prev, '[') && ends(prev, ']')) {
|
||||||
args[end] = ("" + (prev.slice(0, -1)) + ", " + (code) + "]");
|
args[end] = ("" + (prev.slice(0, -1)) + ", " + code + "]");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (prev && starts(prev, '.concat([') && ends(prev, '])')) {
|
if (prev && starts(prev, '.concat([') && ends(prev, '])')) {
|
||||||
args[end] = ("" + (prev.slice(0, -2)) + ", " + (code) + "])");
|
args[end] = ("" + (prev.slice(0, -2)) + ", " + code + "])");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
code = ("[" + (code) + "]");
|
code = ("[" + code + "]");
|
||||||
}
|
}
|
||||||
args[++end] = i === 0 ? code : (".concat(" + (code) + ")");
|
args[++end] = i === 0 ? code : (".concat(" + code + ")");
|
||||||
}
|
}
|
||||||
return args.join('');
|
return args.join('');
|
||||||
};
|
};
|
||||||
@@ -1271,12 +1271,12 @@
|
|||||||
set = '';
|
set = '';
|
||||||
if (!(top)) {
|
if (!(top)) {
|
||||||
rvar = o.scope.freeVariable('result');
|
rvar = o.scope.freeVariable('result');
|
||||||
set = ("" + (this.tab) + (rvar) + " = [];\n");
|
set = ("" + this.tab + rvar + " = [];\n");
|
||||||
if (this.body) {
|
if (this.body) {
|
||||||
this.body = PushNode.wrap(rvar, this.body);
|
this.body = PushNode.wrap(rvar, this.body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pre = ("" + (set) + (this.tab) + "while (" + (cond) + ")");
|
pre = ("" + set + this.tab + "while (" + cond + ")");
|
||||||
if (this.guard) {
|
if (this.guard) {
|
||||||
this.body = Expressions.wrap([new IfNode(this.guard, this.body)]);
|
this.body = Expressions.wrap([new IfNode(this.guard, this.body)]);
|
||||||
}
|
}
|
||||||
@@ -1287,7 +1287,7 @@
|
|||||||
} else {
|
} else {
|
||||||
post = '';
|
post = '';
|
||||||
}
|
}
|
||||||
return "" + (pre) + " {\n" + (this.body.compile(o)) + "\n" + (this.tab) + "}" + (post);
|
return "" + pre + " {\n" + (this.body.compile(o)) + "\n" + this.tab + "}" + post;
|
||||||
};
|
};
|
||||||
return WhileNode;
|
return WhileNode;
|
||||||
})();
|
})();
|
||||||
@@ -1377,7 +1377,7 @@
|
|||||||
shared = this.first.unwrap().second;
|
shared = this.first.unwrap().second;
|
||||||
_ref2 = shared.compileReference(o), this.first.second = _ref2[0], shared = _ref2[1];
|
_ref2 = shared.compileReference(o), this.first.second = _ref2[0], shared = _ref2[1];
|
||||||
_ref2 = [this.first.compile(o), this.second.compile(o), shared.compile(o)], first = _ref2[0], second = _ref2[1], shared = _ref2[2];
|
_ref2 = [this.first.compile(o), this.second.compile(o), shared.compile(o)], first = _ref2[0], second = _ref2[1], shared = _ref2[2];
|
||||||
return "(" + (first) + ") && (" + (shared) + " " + (this.operator) + " " + (second) + ")";
|
return "(" + first + ") && (" + shared + " " + this.operator + " " + second + ")";
|
||||||
};
|
};
|
||||||
OpNode.prototype.compileAssignment = function(o) {
|
OpNode.prototype.compileAssignment = function(o) {
|
||||||
var _ref2, left, rite;
|
var _ref2, left, rite;
|
||||||
@@ -1394,7 +1394,7 @@
|
|||||||
fst = this.first;
|
fst = this.first;
|
||||||
ref = fst.compile(o);
|
ref = fst.compile(o);
|
||||||
}
|
}
|
||||||
return new ExistenceNode(fst).compile(o) + (" ? " + (ref) + " : " + (this.second.compile(o)));
|
return new ExistenceNode(fst).compile(o) + (" ? " + ref + " : " + (this.second.compile(o)));
|
||||||
};
|
};
|
||||||
OpNode.prototype.compileUnary = function(o) {
|
OpNode.prototype.compileUnary = function(o) {
|
||||||
var parts, space;
|
var parts, space;
|
||||||
@@ -1446,7 +1446,7 @@
|
|||||||
}), this.arr1 = _ref2[0], this.arr2 = _ref2[1];
|
}), this.arr1 = _ref2[0], this.arr2 = _ref2[1];
|
||||||
_ref2 = [o.scope.freeVariable('i'), o.scope.freeVariable('len')], i = _ref2[0], l = _ref2[1];
|
_ref2 = [o.scope.freeVariable('i'), o.scope.freeVariable('len')], i = _ref2[0], l = _ref2[1];
|
||||||
prefix = this.obj1 !== this.obj2 ? this.obj1 + '; ' : '';
|
prefix = this.obj1 !== this.obj2 ? this.obj1 + '; ' : '';
|
||||||
return "(function(){ " + (prefix) + "for (var " + (i) + "=0, " + (l) + "=" + (this.arr1) + ".length; " + (i) + "<" + (l) + "; " + (i) + "++) { if (" + (this.arr2) + "[" + (i) + "] === " + (this.obj2) + ") return true; } return false; }).call(this)";
|
return "(function(){ " + prefix + "for (var " + i + "=0, " + l + "=" + this.arr1 + ".length; " + i + "<" + l + "; " + i + "++) { if (" + this.arr2 + "[" + i + "] === " + this.obj2 + ") return true; } return false; }).call(this)";
|
||||||
};
|
};
|
||||||
return InNode;
|
return InNode;
|
||||||
})();
|
})();
|
||||||
@@ -1478,9 +1478,9 @@
|
|||||||
o.top = true;
|
o.top = true;
|
||||||
attemptPart = this.attempt.compile(o);
|
attemptPart = this.attempt.compile(o);
|
||||||
errorPart = this.error ? (" (" + (this.error.compile(o)) + ") ") : ' ';
|
errorPart = this.error ? (" (" + (this.error.compile(o)) + ") ") : ' ';
|
||||||
catchPart = this.recovery ? (" catch" + (errorPart) + "{\n" + (this.recovery.compile(o)) + "\n" + (this.tab) + "}") : '';
|
catchPart = this.recovery ? (" catch" + errorPart + "{\n" + (this.recovery.compile(o)) + "\n" + this.tab + "}") : '';
|
||||||
finallyPart = (this.ensure || '') && ' finally {\n' + this.ensure.compile(merge(o)) + ("\n" + (this.tab) + "}");
|
finallyPart = (this.ensure || '') && ' finally {\n' + this.ensure.compile(merge(o)) + ("\n" + this.tab + "}");
|
||||||
return "" + (this.tab) + "try {\n" + (attemptPart) + "\n" + (this.tab) + "}" + (catchPart) + (finallyPart);
|
return "" + this.tab + "try {\n" + attemptPart + "\n" + this.tab + "}" + catchPart + finallyPart;
|
||||||
};
|
};
|
||||||
return TryNode;
|
return TryNode;
|
||||||
})();
|
})();
|
||||||
@@ -1496,7 +1496,7 @@
|
|||||||
ThrowNode.prototype.isStatement = YES;
|
ThrowNode.prototype.isStatement = YES;
|
||||||
ThrowNode.prototype.makeReturn = THIS;
|
ThrowNode.prototype.makeReturn = THIS;
|
||||||
ThrowNode.prototype.compileNode = function(o) {
|
ThrowNode.prototype.compileNode = function(o) {
|
||||||
return "" + (this.tab) + "throw " + (this.expression.compile(o)) + ";";
|
return "" + this.tab + "throw " + (this.expression.compile(o)) + ";";
|
||||||
};
|
};
|
||||||
return ThrowNode;
|
return ThrowNode;
|
||||||
})();
|
})();
|
||||||
@@ -1512,8 +1512,8 @@
|
|||||||
ExistenceNode.prototype.compileNode = function(o) {
|
ExistenceNode.prototype.compileNode = function(o) {
|
||||||
var code;
|
var code;
|
||||||
code = this.expression.compile(o);
|
code = this.expression.compile(o);
|
||||||
code = IDENTIFIER.test(code) && !o.scope.check(code) ? ("typeof " + (code) + " !== \"undefined\" && " + (code) + " !== null") : ("" + (code) + " != null");
|
code = IDENTIFIER.test(code) && !o.scope.check(code) ? ("typeof " + code + " !== \"undefined\" && " + code + " !== null") : ("" + code + " != null");
|
||||||
return this.parenthetical ? code : ("(" + (code) + ")");
|
return this.parenthetical ? code : ("(" + code + ")");
|
||||||
};
|
};
|
||||||
return ExistenceNode;
|
return ExistenceNode;
|
||||||
})();
|
})();
|
||||||
@@ -1547,7 +1547,7 @@
|
|||||||
if (this.parenthetical || this.isStatement(o)) {
|
if (this.parenthetical || this.isStatement(o)) {
|
||||||
return top ? this.tab + code + ';' : code;
|
return top ? this.tab + code + ';' : code;
|
||||||
}
|
}
|
||||||
return "(" + (code) + ")";
|
return "(" + code + ")";
|
||||||
};
|
};
|
||||||
return ParentheticalNode;
|
return ParentheticalNode;
|
||||||
})();
|
})();
|
||||||
@@ -1638,20 +1638,20 @@
|
|||||||
sourcePart = '';
|
sourcePart = '';
|
||||||
} else {
|
} else {
|
||||||
ref = scope.freeVariable('ref');
|
ref = scope.freeVariable('ref');
|
||||||
sourcePart = ("" + (ref) + " = " + (svar) + ";");
|
sourcePart = ("" + ref + " = " + svar + ";");
|
||||||
svar = ref;
|
svar = ref;
|
||||||
}
|
}
|
||||||
namePart = this.pattern ? new AssignNode(this.name, literal("" + (svar) + "[" + (ivar) + "]")).compile(merge(o, {
|
namePart = this.pattern ? new AssignNode(this.name, literal("" + svar + "[" + ivar + "]")).compile(merge(o, {
|
||||||
top: true
|
top: true
|
||||||
})) : (name ? ("" + (name) + " = " + (svar) + "[" + (ivar) + "]") : undefined);
|
})) : (name ? ("" + name + " = " + svar + "[" + ivar + "]") : undefined);
|
||||||
if (!(this.object)) {
|
if (!(this.object)) {
|
||||||
lvar = scope.freeVariable('len');
|
lvar = scope.freeVariable('len');
|
||||||
stepPart = this.step ? ("" + (ivar) + " += " + (this.step.compile(o))) : ("" + (ivar) + "++");
|
stepPart = this.step ? ("" + ivar + " += " + (this.step.compile(o))) : ("" + ivar + "++");
|
||||||
forPart = ("" + (ivar) + " = 0, " + (lvar) + " = " + (svar) + ".length; " + (ivar) + " < " + (lvar) + "; " + (stepPart));
|
forPart = ("" + ivar + " = 0, " + lvar + " = " + svar + ".length; " + ivar + " < " + lvar + "; " + stepPart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sourcePart = (rvar ? ("" + (rvar) + " = []; ") : '') + sourcePart;
|
sourcePart = (rvar ? ("" + rvar + " = []; ") : '') + sourcePart;
|
||||||
sourcePart = sourcePart ? ("" + (this.tab) + (sourcePart) + "\n" + (this.tab)) : this.tab;
|
sourcePart = sourcePart ? ("" + this.tab + sourcePart + "\n" + this.tab) : this.tab;
|
||||||
returnResult = this.compileReturnValue(rvar, o);
|
returnResult = this.compileReturnValue(rvar, o);
|
||||||
if (!(topLevel)) {
|
if (!(topLevel)) {
|
||||||
body = PushNode.wrap(rvar, body);
|
body = PushNode.wrap(rvar, body);
|
||||||
@@ -1661,32 +1661,32 @@
|
|||||||
}
|
}
|
||||||
if (codeInBody) {
|
if (codeInBody) {
|
||||||
if (range) {
|
if (range) {
|
||||||
body.unshift(literal("var " + (name) + " = " + (ivar)));
|
body.unshift(literal("var " + name + " = " + ivar));
|
||||||
}
|
}
|
||||||
if (namePart) {
|
if (namePart) {
|
||||||
body.unshift(literal("var " + (namePart)));
|
body.unshift(literal("var " + namePart));
|
||||||
}
|
}
|
||||||
if (index) {
|
if (index) {
|
||||||
body.unshift(literal("var " + (index) + " = " + (ivar)));
|
body.unshift(literal("var " + index + " = " + ivar));
|
||||||
}
|
}
|
||||||
body = ClosureNode.wrap(body, true);
|
body = ClosureNode.wrap(body, true);
|
||||||
} else {
|
} else {
|
||||||
if (namePart) {
|
if (namePart) {
|
||||||
varPart = ("" + (idt1) + (namePart) + ";\n");
|
varPart = ("" + idt1 + namePart + ";\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.object) {
|
if (this.object) {
|
||||||
forPart = ("" + (ivar) + " in " + (svar));
|
forPart = ("" + ivar + " in " + svar);
|
||||||
if (!(this.raw)) {
|
if (!(this.raw)) {
|
||||||
guardPart = ("\n" + (idt1) + "if (!" + (utility('hasProp')) + ".call(" + (svar) + ", " + (ivar) + ")) continue;");
|
guardPart = ("\n" + idt1 + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + ivar + ")) continue;");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
body = body.compile(merge(o, {
|
body = body.compile(merge(o, {
|
||||||
indent: idt1,
|
indent: idt1,
|
||||||
top: true
|
top: true
|
||||||
}));
|
}));
|
||||||
vars = range ? name : ("" + (name) + ", " + (ivar));
|
vars = range ? name : ("" + name + ", " + ivar);
|
||||||
return "" + (sourcePart) + "for (" + (forPart) + ") {" + (guardPart) + "\n" + (varPart) + (body) + "\n" + (this.tab) + "}" + (returnResult);
|
return "" + sourcePart + "for (" + forPart + ") {" + guardPart + "\n" + varPart + body + "\n" + this.tab + "}" + returnResult;
|
||||||
};
|
};
|
||||||
return ForNode;
|
return ForNode;
|
||||||
})();
|
})();
|
||||||
@@ -1720,7 +1720,7 @@
|
|||||||
var _i, _j, _len, _len2, _ref2, _ref3, block, code, condition, conditions, exprs, idt, pair;
|
var _i, _j, _len, _len2, _ref2, _ref3, block, code, condition, conditions, exprs, idt, pair;
|
||||||
idt = (o.indent = this.idt(2));
|
idt = (o.indent = this.idt(2));
|
||||||
o.top = true;
|
o.top = true;
|
||||||
code = ("" + (this.tab) + "switch (" + (this.subject.compile(o)) + ") {");
|
code = ("" + this.tab + "switch (" + (this.subject.compile(o)) + ") {");
|
||||||
_ref2 = this.cases;
|
_ref2 = this.cases;
|
||||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||||
pair = _ref2[_i];
|
pair = _ref2[_i];
|
||||||
@@ -1736,13 +1736,13 @@
|
|||||||
}
|
}
|
||||||
code += ("\n" + (block.compile(o)));
|
code += ("\n" + (block.compile(o)));
|
||||||
if (!(last(exprs) instanceof ReturnNode)) {
|
if (!(last(exprs) instanceof ReturnNode)) {
|
||||||
code += ("\n" + (idt) + "break;");
|
code += ("\n" + idt + "break;");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.otherwise) {
|
if (this.otherwise) {
|
||||||
code += ("\n" + (this.idt(1)) + "default:\n" + (this.otherwise.compile(o)));
|
code += ("\n" + (this.idt(1)) + "default:\n" + (this.otherwise.compile(o)));
|
||||||
}
|
}
|
||||||
code += ("\n" + (this.tab) + "}");
|
code += ("\n" + this.tab + "}");
|
||||||
return code;
|
return code;
|
||||||
};
|
};
|
||||||
return SwitchNode;
|
return SwitchNode;
|
||||||
@@ -1828,15 +1828,15 @@
|
|||||||
ifDent = child || (top && !this.isStatement(o)) ? '' : this.idt();
|
ifDent = child || (top && !this.isStatement(o)) ? '' : this.idt();
|
||||||
comDent = child ? this.idt() : '';
|
comDent = child ? this.idt() : '';
|
||||||
body = this.body.compile(o);
|
body = this.body.compile(o);
|
||||||
ifPart = ("" + (ifDent) + "if (" + (this.compileCondition(condO)) + ") {\n" + (body) + "\n" + (this.tab) + "}");
|
ifPart = ("" + ifDent + "if (" + (this.compileCondition(condO)) + ") {\n" + body + "\n" + this.tab + "}");
|
||||||
if (!(this.elseBody)) {
|
if (!(this.elseBody)) {
|
||||||
return ifPart;
|
return ifPart;
|
||||||
}
|
}
|
||||||
elsePart = this.isChain ? ' else ' + this.elseBodyNode().compile(merge(o, {
|
elsePart = this.isChain ? ' else ' + this.elseBodyNode().compile(merge(o, {
|
||||||
indent: this.idt(),
|
indent: this.idt(),
|
||||||
chainChild: true
|
chainChild: true
|
||||||
})) : (" else {\n" + (this.elseBody.compile(o)) + "\n" + (this.tab) + "}");
|
})) : (" else {\n" + (this.elseBody.compile(o)) + "\n" + this.tab + "}");
|
||||||
return "" + (ifPart) + (elsePart);
|
return "" + ifPart + elsePart;
|
||||||
};
|
};
|
||||||
IfNode.prototype.compileTernary = function(o) {
|
IfNode.prototype.compileTernary = function(o) {
|
||||||
var code, elsePart, ifPart;
|
var code, elsePart, ifPart;
|
||||||
@@ -1846,8 +1846,8 @@
|
|||||||
}
|
}
|
||||||
ifPart = this.condition.compile(o) + ' ? ' + this.bodyNode().compile(o);
|
ifPart = this.condition.compile(o) + ' ? ' + this.bodyNode().compile(o);
|
||||||
elsePart = this.elseBody ? this.elseBodyNode().compile(o) : 'undefined';
|
elsePart = this.elseBody ? this.elseBodyNode().compile(o) : 'undefined';
|
||||||
code = ("" + (ifPart) + " : " + (elsePart));
|
code = ("" + ifPart + " : " + elsePart);
|
||||||
return this.tags.operation ? ("(" + (code) + ")") : code;
|
return this.tags.operation ? ("(" + code + ")") : code;
|
||||||
};
|
};
|
||||||
return IfNode;
|
return IfNode;
|
||||||
})();
|
})();
|
||||||
@@ -1904,7 +1904,7 @@
|
|||||||
};
|
};
|
||||||
utility = function(name) {
|
utility = function(name) {
|
||||||
var ref;
|
var ref;
|
||||||
ref = ("__" + (name));
|
ref = ("__" + name);
|
||||||
Scope.root.assign(ref, UTILITIES[name]);
|
Scope.root.assign(ref, UTILITIES[name]);
|
||||||
return ref;
|
return ref;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isOption && !matchedRule) {
|
if (isOption && !matchedRule) {
|
||||||
throw new Error("unrecognized option: " + (arg));
|
throw new Error("unrecognized option: " + arg);
|
||||||
}
|
}
|
||||||
if (!isOption) {
|
if (!isOption) {
|
||||||
options.arguments = args.slice(i, args.length);
|
options.arguments = args.slice(i, args.length);
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
var _i, _len, _ref, letPart, lines, rule, spaces;
|
var _i, _len, _ref, letPart, lines, rule, spaces;
|
||||||
lines = ['Available options:'];
|
lines = ['Available options:'];
|
||||||
if (this.banner) {
|
if (this.banner) {
|
||||||
lines.unshift("" + (this.banner) + "\n");
|
lines.unshift("" + this.banner + "\n");
|
||||||
}
|
}
|
||||||
_ref = this.rules;
|
_ref = this.rules;
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
|||||||
@@ -116,7 +116,7 @@
|
|||||||
if (!__hasProp.call(_ref2, key)) continue;
|
if (!__hasProp.call(_ref2, key)) continue;
|
||||||
val = _ref2[key];
|
val = _ref2[key];
|
||||||
if (val.assigned) {
|
if (val.assigned) {
|
||||||
_result.push("" + (key) + " = " + (val.value));
|
_result.push("" + key + " = " + (val.value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _result;
|
return _result;
|
||||||
|
|||||||
@@ -171,26 +171,14 @@ exports.Lexer = class Lexer
|
|||||||
|
|
||||||
# Matches regular expression literals. Lexing regular expressions is difficult
|
# Matches regular expression literals. Lexing regular expressions is difficult
|
||||||
# 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, borrow slash balancing from `@balancedString`, and
|
# JavaScript and Ruby.
|
||||||
# borrow interpolation from `@interpolateString`.
|
|
||||||
regexToken: ->
|
regexToken: ->
|
||||||
return false if @chunk.charAt(0) isnt '/'
|
return false if @chunk.charAt(0) isnt '/'
|
||||||
return @heregexToken match if match = HEREGEX.exec @chunk
|
return @heregexToken match if match = HEREGEX.exec @chunk
|
||||||
return false unless first = REGEX_START.exec @chunk
|
|
||||||
return false if first[1] is ' ' and @tag() not in ['CALL_START', '=']
|
|
||||||
return false if include NOT_REGEX, @tag()
|
return false if include NOT_REGEX, @tag()
|
||||||
return false unless regex = @balancedString @chunk, [['/', '/']]
|
return false unless match = REGEX.exec @chunk
|
||||||
return false unless end = @chunk[regex.length..].match REGEX_END
|
@token 'REGEX', match[0]
|
||||||
flags = end[0]
|
@i += match[0].length
|
||||||
if ~regex.indexOf '#{'
|
|
||||||
str = regex.slice 1, -1
|
|
||||||
@tokens.push ['IDENTIFIER', 'RegExp'], ['CALL_START', '(']
|
|
||||||
@interpolateString "\"#{str}\"", regex: yes
|
|
||||||
@tokens.push [',', ','], ['STRING', "\"#{flags}\""] if flags
|
|
||||||
@tokens.push ['CALL_END', ')']
|
|
||||||
else
|
|
||||||
@token 'REGEX', regex + flags
|
|
||||||
@i += regex.length + flags.length
|
|
||||||
true
|
true
|
||||||
|
|
||||||
# Matches experimental, multiline and extended regular expression literals.
|
# Matches experimental, multiline and extended regular expression literals.
|
||||||
@@ -199,11 +187,21 @@ exports.Lexer = class Lexer
|
|||||||
@i += heregex.length
|
@i += heregex.length
|
||||||
unless ~body.indexOf '#{'
|
unless ~body.indexOf '#{'
|
||||||
re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/')
|
re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/')
|
||||||
@token 'REGEX', "/#{ re or '(?:)' }/#{flags}"
|
@token 'REGEX', "/#{ re or '(?:)' }/#{flags}"
|
||||||
return true
|
return true
|
||||||
@token 'IDENTIFIER', 'RegExp'
|
@token 'IDENTIFIER', 'RegExp'
|
||||||
@tokens.push ['CALL_START', '(']
|
@tokens.push ['CALL_START', '(']
|
||||||
@interpolateString "\"#{body}\"", regex: yes, heregex: yes
|
tokens = []
|
||||||
|
for [tag, value] in @interpolateString('"' + body + '"', regex: yes)
|
||||||
|
if tag is 'TOKENS'
|
||||||
|
tokens.push value...
|
||||||
|
else
|
||||||
|
continue unless value = value.slice(1, -1).replace HEREGEX_OMIT, ''
|
||||||
|
tokens.push ['STRING', '"' + value.replace(/[\\\"]/g, '\\$&') + '"']
|
||||||
|
tokens.push ['+', '+']
|
||||||
|
tokens.pop()
|
||||||
|
@tokens.push ['STRING', '""'], ['+', '+'] unless tokens[0]?[0] is 'STRING'
|
||||||
|
@tokens.push tokens...
|
||||||
@tokens.push [',', ','], ['STRING', '"' + flags + '"'] if flags
|
@tokens.push [',', ','], ['STRING', '"' + flags + '"'] if flags
|
||||||
@tokens.push ['CALL_END', ')']
|
@tokens.push ['CALL_END', ')']
|
||||||
true
|
true
|
||||||
@@ -355,12 +353,12 @@ exports.Lexer = class Lexer
|
|||||||
while (match = HEREDOC_INDENT.exec doc)
|
while (match = HEREDOC_INDENT.exec doc)
|
||||||
attempt = match[1]
|
attempt = match[1]
|
||||||
indent = attempt if indent is null or 0 < attempt.length < indent.length
|
indent = attempt if indent is null or 0 < attempt.length < indent.length
|
||||||
doc = doc.replace /\n#{ indent }/g, '\n' if indent
|
doc = doc.replace /// \n #{indent} ///g, '\n' if indent
|
||||||
return doc if herecomment
|
return doc if herecomment
|
||||||
{quote} = options
|
{quote} = options
|
||||||
doc = doc.replace /^\n/, ''
|
doc = doc.replace /^\n/, ''
|
||||||
doc = doc.replace /\\([\s\S])/g, (m, c) -> if c in ['\n', quote] then c else m
|
doc = doc.replace /\\([\s\S])/g, (m, c) -> if c in ['\n', quote] then c else m
|
||||||
doc = doc.replace /#{quote}/g, '\\$&'
|
doc = doc.replace /// #{quote} ///g, '\\$&'
|
||||||
doc = @escapeLines doc, yes if quote is "'"
|
doc = @escapeLines doc, yes if quote is "'"
|
||||||
doc
|
doc
|
||||||
|
|
||||||
@@ -398,7 +396,6 @@ exports.Lexer = class Lexer
|
|||||||
# interpolations within strings, ad infinitum.
|
# interpolations within strings, ad infinitum.
|
||||||
balancedString: (str, delimited, options) ->
|
balancedString: (str, delimited, options) ->
|
||||||
options or= {}
|
options or= {}
|
||||||
slash = delimited[0][0] is '/'
|
|
||||||
levels = []
|
levels = []
|
||||||
i = 0
|
i = 0
|
||||||
slen = str.length
|
slen = str.length
|
||||||
@@ -417,10 +414,9 @@ exports.Lexer = class Lexer
|
|||||||
levels.push(pair)
|
levels.push(pair)
|
||||||
i += open.length - 1
|
i += open.length - 1
|
||||||
break
|
break
|
||||||
break if not levels.length or slash and str.charAt(i) is '\n'
|
break if not levels.length
|
||||||
i += 1
|
i += 1
|
||||||
if levels.length
|
if levels.length
|
||||||
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}"
|
||||||
if not i then false else str[0...i]
|
if not i then false else str[0...i]
|
||||||
|
|
||||||
@@ -446,37 +442,28 @@ exports.Lexer = class Lexer
|
|||||||
unless char is '#' and str.charAt(i+1) is '{' and
|
unless char is '#' and str.charAt(i+1) is '{' and
|
||||||
(expr = @balancedString str[i+1..], [['{', '}']])
|
(expr = @balancedString str[i+1..], [['{', '}']])
|
||||||
continue
|
continue
|
||||||
if pi < i
|
tokens.push ['STRING', '"' + str[pi...i] + '"'] if pi < i
|
||||||
tokens.push ['STRING', '"' + @escapeLines(str[pi...i], heredoc) + '"']
|
|
||||||
inner = expr.slice(1, -1).replace(LEADING_SPACES, '').replace(TRAILING_SPACES, '')
|
inner = expr.slice(1, -1).replace(LEADING_SPACES, '').replace(TRAILING_SPACES, '')
|
||||||
if inner.length
|
if inner.length
|
||||||
inner = inner.replace /\\\"/g, '"' if heredoc
|
inner = inner.replace /\\\"/g, '"' if heredoc
|
||||||
nested = lexer.tokenize "(#{inner})", line: @line
|
nested = lexer.tokenize "(#{inner}\n)", line: @line
|
||||||
(tok[0] = ')') for tok in nested when tok[0] is 'CALL_END'
|
(tok[0] = ')') for tok in nested when tok[0] is 'CALL_END'
|
||||||
nested.pop()
|
nested.pop()
|
||||||
|
if nested.length < 5 then nested.pop(); nested.shift()
|
||||||
tokens.push ['TOKENS', nested]
|
tokens.push ['TOKENS', nested]
|
||||||
else
|
|
||||||
tokens.push ['STRING', '""']
|
|
||||||
i += expr.length
|
i += expr.length
|
||||||
pi = i + 1
|
pi = i + 1
|
||||||
if i > pi < str.length - 1
|
tokens.push ['STRING', '"' + str.slice pi] if i > pi < str.length - 1
|
||||||
s = @escapeLines str.slice(pi, -1), heredoc
|
return tokens if regex
|
||||||
tokens.push ['STRING', '"' + s + '"']
|
interpolated = tokens.length > 1
|
||||||
tokens.unshift ['STRING', '""'] unless tokens[0][0] is 'STRING'
|
tokens.unshift ['STRING', '""'] unless tokens[0]?[0] is 'STRING'
|
||||||
interpolated = not regex and tokens.length > 1
|
|
||||||
@token '(', '(' if interpolated
|
@token '(', '(' if interpolated
|
||||||
{push} = tokens
|
|
||||||
for [tag, value], i in tokens
|
for [tag, value], i in tokens
|
||||||
@token '+', '+' if i
|
@token '+', '+' if i
|
||||||
if tag is 'TOKENS'
|
if tag is 'TOKENS'
|
||||||
push.apply @tokens, value
|
@tokens.push value...
|
||||||
continue
|
else
|
||||||
if regex
|
@token tag, @escapeLines value, heredoc
|
||||||
value = value.slice 1, -1
|
|
||||||
value = value.replace /[\\\"]/g, '\\$&'
|
|
||||||
value = value.replace HEREGEX_OMIT, '' if options.heregex
|
|
||||||
value = '"' + value + '"'
|
|
||||||
@token tag, value
|
|
||||||
@token ')', ')' if interpolated
|
@token ')', ')' if interpolated
|
||||||
tokens
|
tokens
|
||||||
|
|
||||||
@@ -558,10 +545,14 @@ SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/
|
|||||||
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/
|
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/
|
||||||
|
|
||||||
# Regex-matching-regexes.
|
# Regex-matching-regexes.
|
||||||
REGEX_START = /^\/([^\/])/
|
REGEX = /// ^
|
||||||
REGEX_END = /^[imgy]{0,4}(?![a-zA-Z])/
|
/ (?!\s) # disallow leading whitespace
|
||||||
REGEX_ESCAPE = /\\[^#]/g
|
(?: [^ [ / \n \\ ]+ # every other things
|
||||||
|
| \\. # anything escaped
|
||||||
|
| \[ ( [^\\\]]+ | \\. )* ] # character class
|
||||||
|
)+
|
||||||
|
/ [imgy]{0,4} (?![A-Za-z])
|
||||||
|
///
|
||||||
HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?![A-Za-z])/
|
HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?![A-Za-z])/
|
||||||
HEREGEX_OMIT = /\s+(?:#.*)?/g
|
HEREGEX_OMIT = /\s+(?:#.*)?/g
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
# Interpolate regular expressions.
|
|
||||||
name = 'Moe'
|
|
||||||
|
|
||||||
ok not not '"Moe"'.match(/^"#{name}"$/i)
|
|
||||||
ok '"Moe!"'.match(/^"#{name}"$/i) is null
|
|
||||||
|
|
||||||
ok not not 'Moe'.match(/^#{name}$/)
|
|
||||||
ok 'Moe!'.match(/^#{name}/)
|
|
||||||
|
|
||||||
ok 'Moe!'.match(/#{"#{"#{"#{name}"}"}"}/imgy)
|
|
||||||
|
|
||||||
ok '$a$b$c'.match(/\$A\$B\$C/i)
|
|
||||||
|
|
||||||
a = 1
|
|
||||||
b = 2
|
|
||||||
c = 3
|
|
||||||
ok '123'.match(/#{a}#{b}#{c}/i)
|
|
||||||
|
|
||||||
[a, b, c] = [1, 2, /\d+/]
|
|
||||||
ok (/#{a}#{b}#{c}$/i).toString() is '/12/\\d+/$/i'
|
|
||||||
@@ -12,7 +12,7 @@ g = 1
|
|||||||
|
|
||||||
ok y / x/g is 2
|
ok y / x/g is 2
|
||||||
|
|
||||||
ok 'http://google.com'.match(/:\/\/goog/)
|
ok /:\/[/]goog/.test 'http://google.com'
|
||||||
|
|
||||||
obj = {
|
obj = {
|
||||||
width: -> 10
|
width: -> 10
|
||||||
@@ -20,11 +20,6 @@ obj = {
|
|||||||
}
|
}
|
||||||
id = 2
|
id = 2
|
||||||
|
|
||||||
ok ' '.match(/ /)[0] is ' '
|
|
||||||
|
|
||||||
regexp = / /
|
|
||||||
ok ' '.match regexp
|
|
||||||
|
|
||||||
ok (obj.width()/id - obj.height()/id) is -5
|
ok (obj.width()/id - obj.height()/id) is -5
|
||||||
|
|
||||||
eq /^I'm\s+Heregex?\/\/\//gim + '', ///
|
eq /^I'm\s+Heregex?\/\/\//gim + '', ///
|
||||||
@@ -32,8 +27,9 @@ eq /^I'm\s+Heregex?\/\/\//gim + '', ///
|
|||||||
///gim + ''
|
///gim + ''
|
||||||
eq '\\\\#{}', ///
|
eq '\\\\#{}', ///
|
||||||
#{
|
#{
|
||||||
"#{ '\\' }"
|
"#{ '\\' }" # normal comment
|
||||||
}
|
}
|
||||||
|
# regex comment
|
||||||
\#{}
|
\#{}
|
||||||
///.source
|
///.source
|
||||||
eq /// /// + '', '/(?:)/'
|
eq /// /// + '', '/(?:)/'
|
||||||
|
|||||||
Reference in New Issue
Block a user