mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-02-17 19:11:22 -05:00
Merge branch 'master' into newline-splat
Conflicts: lib/lexer.js lib/parser.js src/lexer.coffee
This commit is contained in:
4
Rakefile
4
Rakefile
@@ -2,7 +2,7 @@ require 'erb'
|
|||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
require 'rake/testtask'
|
require 'rake/testtask'
|
||||||
require 'rubygems'
|
require 'rubygems'
|
||||||
require 'closure-compiler'
|
require 'yui/compressor'
|
||||||
|
|
||||||
HEADER = <<-EOS
|
HEADER = <<-EOS
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +42,7 @@ task :browser do
|
|||||||
}
|
}
|
||||||
JS
|
JS
|
||||||
end
|
end
|
||||||
code = Closure::Compiler.new.compress(<<-"JS")
|
code = YUI::JavaScriptCompressor.new.compress(<<-"JS")
|
||||||
this.CoffeeScript = function(){
|
this.CoffeeScript = function(){
|
||||||
function require(path){ return require[path] }
|
function require(path){ return require[path] }
|
||||||
#{ code }
|
#{ code }
|
||||||
|
|||||||
@@ -1309,7 +1309,7 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
|
|||||||
source = $('#repl_source').val()
|
source = $('#repl_source').val()
|
||||||
window.compiled_js = ''
|
window.compiled_js = ''
|
||||||
try
|
try
|
||||||
window.compiled_js = CoffeeScript.compile source, noWrap: true
|
window.compiled_js = CoffeeScript.compile source, wrap: false
|
||||||
$('#repl_results').text window.compiled_js
|
$('#repl_results').text window.compiled_js
|
||||||
$('#error').hide()
|
$('#error').hide()
|
||||||
catch error
|
catch error
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -2170,7 +2170,7 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
|
|||||||
source = $('#repl_source').val()
|
source = $('#repl_source').val()
|
||||||
window.compiled_js = ''
|
window.compiled_js = ''
|
||||||
try
|
try
|
||||||
window.compiled_js = CoffeeScript.compile source, noWrap: true
|
window.compiled_js = CoffeeScript.compile source, wrap: false
|
||||||
$('#repl_results').text window.compiled_js
|
$('#repl_results').text window.compiled_js
|
||||||
$('#error').hide()
|
$('#error').hide()
|
||||||
catch error
|
catch error
|
||||||
|
|||||||
@@ -215,7 +215,7 @@
|
|||||||
o = {
|
o = {
|
||||||
fileName: fileName
|
fileName: fileName
|
||||||
};
|
};
|
||||||
o.noWrap = opts['no-wrap'];
|
o.wrap = !opts['no-wrap'];
|
||||||
return o;
|
return o;
|
||||||
};
|
};
|
||||||
usage = function() {
|
usage = function() {
|
||||||
|
|||||||
@@ -64,12 +64,8 @@
|
|||||||
return new Literal($1);
|
return new Literal($1);
|
||||||
}), o("REGEX", function() {
|
}), o("REGEX", function() {
|
||||||
return new Literal($1);
|
return new Literal($1);
|
||||||
}), o("TRUE", function() {
|
}), o("BOOL", function() {
|
||||||
return new Literal(true);
|
return new Literal($1);
|
||||||
}), o("FALSE", function() {
|
|
||||||
return new Literal(false);
|
|
||||||
}), o("NULL", function() {
|
|
||||||
return new Literal('null');
|
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
Assign: [
|
Assign: [
|
||||||
@@ -130,7 +126,7 @@
|
|||||||
}), o("Param", function() {
|
}), o("Param", function() {
|
||||||
return [$1];
|
return [$1];
|
||||||
}), o("ParamList , Param", function() {
|
}), o("ParamList , Param", function() {
|
||||||
return $1.concat([$3]);
|
return $1.concat($3);
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
Param: [
|
Param: [
|
||||||
@@ -209,9 +205,9 @@
|
|||||||
}), o("AssignObj", function() {
|
}), o("AssignObj", function() {
|
||||||
return [$1];
|
return [$1];
|
||||||
}), o("AssignList , AssignObj", function() {
|
}), o("AssignList , AssignObj", function() {
|
||||||
return $1.concat([$3]);
|
return $1.concat($3);
|
||||||
}), o("AssignList OptComma TERMINATOR AssignObj", function() {
|
}), o("AssignList OptComma TERMINATOR AssignObj", function() {
|
||||||
return $1.concat([$4]);
|
return $1.concat($4);
|
||||||
}), o("AssignList OptComma INDENT AssignList OptComma OUTDENT", function() {
|
}), o("AssignList OptComma INDENT AssignList OptComma OUTDENT", function() {
|
||||||
return $1.concat($4);
|
return $1.concat($4);
|
||||||
})
|
})
|
||||||
@@ -329,9 +325,9 @@
|
|||||||
o("Arg", function() {
|
o("Arg", function() {
|
||||||
return [$1];
|
return [$1];
|
||||||
}), o("ArgList , Arg", function() {
|
}), o("ArgList , Arg", function() {
|
||||||
return $1.concat([$3]);
|
return $1.concat($3);
|
||||||
}), o("ArgList OptComma TERMINATOR Arg", function() {
|
}), o("ArgList OptComma TERMINATOR Arg", function() {
|
||||||
return $1.concat([$4]);
|
return $1.concat($4);
|
||||||
}), o("INDENT ArgList OptComma OUTDENT", function() {
|
}), o("INDENT ArgList OptComma OUTDENT", function() {
|
||||||
return $2;
|
return $2;
|
||||||
}), o("ArgList OptComma INDENT ArgList OptComma OUTDENT", function() {
|
}), o("ArgList OptComma INDENT ArgList OptComma OUTDENT", function() {
|
||||||
@@ -341,7 +337,7 @@
|
|||||||
Arg: [o("Expression"), o("Splat")],
|
Arg: [o("Expression"), o("Splat")],
|
||||||
SimpleArgs: [
|
SimpleArgs: [
|
||||||
o("Expression"), o("SimpleArgs , Expression", function() {
|
o("Expression"), o("SimpleArgs , Expression", function() {
|
||||||
return $1 instanceof Array ? $1.concat([$3]) : [$1].concat([$3]);
|
return [].concat($1, $3);
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
Try: [
|
Try: [
|
||||||
|
|||||||
68
lib/lexer.js
68
lib/lexer.js
@@ -1,10 +1,11 @@
|
|||||||
(function() {
|
(function() {
|
||||||
var ASSIGNED, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LEADING_SPACES, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NEXT_ELLIPSIS, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, _ref, compact, count, include, last, op, starts;
|
var ASSIGNED, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LEADING_SPACES, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NEXT_ELLIPSIS, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, _ref, compact, count, include, last, op, 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() {
|
||||||
Lexer = (function() {
|
Lexer = (function() {
|
||||||
return function Lexer() {};
|
function Lexer() {};
|
||||||
|
return Lexer;
|
||||||
})();
|
})();
|
||||||
Lexer.prototype.tokenize = function(code, options) {
|
Lexer.prototype.tokenize = function(code, options) {
|
||||||
var o;
|
var o;
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
this.seenFor = false;
|
this.seenFor = false;
|
||||||
this.indents = [];
|
this.indents = [];
|
||||||
this.tokens = [];
|
this.tokens = [];
|
||||||
while ((this.chunk = code.slice(this.i))) {
|
while (this.chunk = code.slice(this.i)) {
|
||||||
this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken();
|
this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken();
|
||||||
}
|
}
|
||||||
this.closeIndentation();
|
this.closeIndentation();
|
||||||
@@ -29,17 +30,17 @@
|
|||||||
return (new Rewriter).rewrite(this.tokens);
|
return (new Rewriter).rewrite(this.tokens);
|
||||||
};
|
};
|
||||||
Lexer.prototype.identifierToken = function() {
|
Lexer.prototype.identifierToken = function() {
|
||||||
var forcedIdentifier, id, match, tag;
|
var _ref2, colon, forcedIdentifier, id, input, match, tag;
|
||||||
if (!(match = IDENTIFIER.exec(this.chunk))) {
|
if (!(match = IDENTIFIER.exec(this.chunk))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
id = match[0];
|
_ref2 = match, input = _ref2[0], id = _ref2[1], colon = _ref2[2];
|
||||||
this.i += id.length;
|
this.i += input.length;
|
||||||
if (id === 'all' && this.tag() === 'FOR') {
|
if (id === 'all' && this.tag() === 'FOR') {
|
||||||
this.token('ALL', id);
|
this.token('ALL', id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
forcedIdentifier = this.tagAccessor() || ASSIGNED.test(this.chunk);
|
forcedIdentifier = colon || this.tagAccessor();
|
||||||
tag = 'IDENTIFIER';
|
tag = 'IDENTIFIER';
|
||||||
if (include(JS_KEYWORDS, id) || !forcedIdentifier && include(COFFEE_KEYWORDS, id)) {
|
if (include(JS_KEYWORDS, id) || !forcedIdentifier && include(COFFEE_KEYWORDS, id)) {
|
||||||
tag = id.toUpperCase();
|
tag = id.toUpperCase();
|
||||||
@@ -79,9 +80,15 @@
|
|||||||
tag = 'UNARY';
|
tag = 'UNARY';
|
||||||
} else if (include(LOGIC, id)) {
|
} else if (include(LOGIC, id)) {
|
||||||
tag = 'LOGIC';
|
tag = 'LOGIC';
|
||||||
|
} else if (include(BOOL, tag)) {
|
||||||
|
id = tag.toLowerCase();
|
||||||
|
tag = 'BOOL';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.token(tag, id);
|
this.token(tag, id);
|
||||||
|
if (colon) {
|
||||||
|
this.token(':', ':');
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
Lexer.prototype.numberToken = function() {
|
Lexer.prototype.numberToken = function() {
|
||||||
@@ -330,9 +337,9 @@
|
|||||||
if (!prev[1].reserved && include(JS_FORBIDDEN, prev[1])) {
|
if (!prev[1].reserved && include(JS_FORBIDDEN, prev[1])) {
|
||||||
this.assignmentError();
|
this.assignmentError();
|
||||||
}
|
}
|
||||||
if (('or' === (_ref2 = prev[1]) || 'and' === _ref2)) {
|
if (('||' === (_ref2 = prev[1]) || '&&' === _ref2)) {
|
||||||
prev[0] = 'COMPOUND_ASSIGN';
|
prev[0] = 'COMPOUND_ASSIGN';
|
||||||
prev[1] = COFFEE_ALIASES[prev[1]] + '=';
|
prev[1] += '=';
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -374,25 +381,23 @@
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
Lexer.prototype.tagAccessor = function() {
|
Lexer.prototype.tagAccessor = function() {
|
||||||
var accessor, prev;
|
var prev;
|
||||||
if (!(prev = last(this.tokens)) || prev.spaced) {
|
if (!(prev = last(this.tokens)) || prev.spaced) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
accessor = (function() {
|
if (prev[1] === '::') {
|
||||||
if (prev[1] === '::') {
|
this.tag(0, 'PROTOTYPE_ACCESS');
|
||||||
return this.tag(0, 'PROTOTYPE_ACCESS');
|
} else if (prev[1] === '.' && this.value(1) !== '.') {
|
||||||
} else if (prev[1] === '.' && this.value(1) !== '.') {
|
if (this.tag(1) === '?') {
|
||||||
if (this.tag(1) === '?') {
|
this.tag(0, 'SOAK_ACCESS');
|
||||||
this.tag(0, 'SOAK_ACCESS');
|
this.tokens.splice(-2, 1);
|
||||||
return this.tokens.splice(-2, 1);
|
|
||||||
} else {
|
|
||||||
return this.tag(0, 'PROPERTY_ACCESS');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return prev[0] === '@';
|
this.tag(0, 'PROPERTY_ACCESS');
|
||||||
}
|
}
|
||||||
}).call(this);
|
} else {
|
||||||
return accessor ? 'accessor' : false;
|
return prev[0] === '@';
|
||||||
|
}
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
Lexer.prototype.sanitizeHeredoc = function(doc, options) {
|
Lexer.prototype.sanitizeHeredoc = function(doc, options) {
|
||||||
var _ref2, _ref3, attempt, herecomment, indent, match;
|
var _ref2, _ref3, attempt, herecomment, indent, match;
|
||||||
@@ -422,10 +427,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
i = this.tokens.length;
|
i = this.tokens.length;
|
||||||
while (true) {
|
while (tok = this.tokens[--i]) {
|
||||||
if (!(tok = this.tokens[--i])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (tok[0]) {
|
switch (tok[0]) {
|
||||||
case 'IDENTIFIER':
|
case 'IDENTIFIER':
|
||||||
tok[0] = 'PARAM';
|
tok[0] = 'PARAM';
|
||||||
@@ -435,7 +437,8 @@
|
|||||||
break;
|
break;
|
||||||
case '(':
|
case '(':
|
||||||
case 'CALL_START':
|
case 'CALL_START':
|
||||||
return (tok[0] = 'PARAM_START');
|
tok[0] = 'PARAM_START';
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -444,10 +447,10 @@
|
|||||||
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 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 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, slen;
|
var _i, _len, _ref2, close, i, levels, open, pair, slen;
|
||||||
@@ -596,7 +599,7 @@
|
|||||||
COFFEE_ALIASES['==='] = '==';
|
COFFEE_ALIASES['==='] = '==';
|
||||||
RESERVED = ['case', 'default', 'do', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice'];
|
RESERVED = ['case', 'default', 'do', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice'];
|
||||||
JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED);
|
JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED);
|
||||||
IDENTIFIER = /^[a-zA-Z_$][\w$]*/;
|
IDENTIFIER = /^([$A-Za-z_][$\w]*)([^\n\S]*:(?!:))?/;
|
||||||
NUMBER = /^0x[\da-f]+|^(?:\d+(\.\d+)?|\.\d+)(?:e[+-]?\d+)?/i;
|
NUMBER = /^0x[\da-f]+|^(?:\d+(\.\d+)?|\.\d+)(?:e[+-]?\d+)?/i;
|
||||||
HEREDOC = /^("""|''')([\s\S]*?)(?:\n[ \t]*)?\1/;
|
HEREDOC = /^("""|''')([\s\S]*?)(?:\n[ \t]*)?\1/;
|
||||||
OPERATOR = /^(?:-[-=>]?|\+[+=]?|\.\.\.?|[*&|\/%=<>^:!?]+)/;
|
OPERATOR = /^(?:-[-=>]?|\+[+=]?|\.\.\.?|[*&|\/%=<>^:!?]+)/;
|
||||||
@@ -624,7 +627,8 @@
|
|||||||
COMPARE = ['<=', '<', '>', '>='];
|
COMPARE = ['<=', '<', '>', '>='];
|
||||||
MATH = ['*', '/', '%'];
|
MATH = ['*', '/', '%'];
|
||||||
RELATION = ['IN', 'OF', 'INSTANCEOF'];
|
RELATION = ['IN', 'OF', 'INSTANCEOF'];
|
||||||
NOT_REGEX = ['NUMBER', 'REGEX', '++', '--', 'FALSE', 'NULL', 'TRUE', ']'];
|
BOOL = ['TRUE', 'FALSE', 'NULL'];
|
||||||
|
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', '++', '--', ']'];
|
||||||
CALLABLE = ['IDENTIFIER', 'SUPER', ')', ']', '}', 'STRING', '@', 'THIS', '?', '::'];
|
CALLABLE = ['IDENTIFIER', 'SUPER', ')', ']', '}', 'STRING', '@', 'THIS', '?', '::'];
|
||||||
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
|
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|||||||
222
lib/nodes.js
222
lib/nodes.js
@@ -1,5 +1,5 @@
|
|||||||
(function() {
|
(function() {
|
||||||
var Accessor, ArrayLiteral, Assign, Base, Call, Class, Closure, Code, Comment, Existence, Expressions, Extends, For, IDENTIFIER, IS_STRING, If, In, Index, Literal, NO, NUMBER, ObjectLiteral, Op, Param, Parens, Push, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, TRAILING_WHITESPACE, Throw, Try, UTILITIES, Value, While, YES, _ref, compact, del, ends, flatten, include, indexOf, last, merge, starts, utility;
|
var Accessor, ArrayLiteral, Assign, Base, Call, Class, Closure, Code, Comment, Existence, Expressions, Extends, For, IDENTIFIER, IS_STRING, If, In, Index, Literal, NO, NUMBER, ObjectLiteral, Op, Param, Parens, Push, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, TRAILING_WHITESPACE, Throw, Try, UTILITIES, Value, While, YES, _ref, compact, del, ends, flatten, include, last, merge, starts, utility;
|
||||||
var __extends = function(child, parent) {
|
var __extends = function(child, parent) {
|
||||||
var ctor = function() {};
|
var ctor = function() {};
|
||||||
ctor.prototype = parent.prototype;
|
ctor.prototype = parent.prototype;
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
child.__super__ = parent.prototype;
|
child.__super__ = parent.prototype;
|
||||||
};
|
};
|
||||||
Scope = require('./scope').Scope;
|
Scope = require('./scope').Scope;
|
||||||
_ref = require('./helpers'), compact = _ref.compact, flatten = _ref.flatten, merge = _ref.merge, del = _ref.del, include = _ref.include, indexOf = _ref.indexOf, starts = _ref.starts, ends = _ref.ends, last = _ref.last;
|
_ref = require('./helpers'), compact = _ref.compact, flatten = _ref.flatten, merge = _ref.merge, del = _ref.del, include = _ref.include, starts = _ref.starts, ends = _ref.ends, last = _ref.last;
|
||||||
YES = function() {
|
YES = function() {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@@ -21,10 +21,11 @@
|
|||||||
};
|
};
|
||||||
exports.Base = (function() {
|
exports.Base = (function() {
|
||||||
Base = (function() {
|
Base = (function() {
|
||||||
return function Base() {
|
function Base() {
|
||||||
this.tags = {};
|
this.tags = {};
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Base;
|
||||||
})();
|
})();
|
||||||
Base.prototype.compile = function(o) {
|
Base.prototype.compile = function(o) {
|
||||||
var closure, code, top;
|
var closure, code, top;
|
||||||
@@ -141,9 +142,12 @@
|
|||||||
if (func(child) === false) {
|
if (func(child) === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return child instanceof Base && (crossScope || !(child instanceof Code)) ? child.traverseChildren(crossScope, func) : undefined;
|
return crossScope || !(child instanceof Code) ? child.traverseChildren(crossScope, func) : undefined;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
Base.prototype.invert = function() {
|
||||||
|
return new Op('!', this);
|
||||||
|
};
|
||||||
Base.prototype.children = [];
|
Base.prototype.children = [];
|
||||||
Base.prototype.unwrap = THIS;
|
Base.prototype.unwrap = THIS;
|
||||||
Base.prototype.isStatement = NO;
|
Base.prototype.isStatement = NO;
|
||||||
@@ -154,11 +158,12 @@
|
|||||||
})();
|
})();
|
||||||
exports.Expressions = (function() {
|
exports.Expressions = (function() {
|
||||||
Expressions = (function() {
|
Expressions = (function() {
|
||||||
return function Expressions(nodes) {
|
function Expressions(nodes) {
|
||||||
Expressions.__super__.constructor.call(this);
|
Expressions.__super__.constructor.call(this);
|
||||||
this.expressions = compact(flatten(nodes || []));
|
this.expressions = compact(flatten(nodes || []));
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Expressions;
|
||||||
})();
|
})();
|
||||||
__extends(Expressions, Base);
|
__extends(Expressions, Base);
|
||||||
Expressions.prototype.children = ['expressions'];
|
Expressions.prototype.children = ['expressions'];
|
||||||
@@ -204,12 +209,13 @@
|
|||||||
}).call(this).join("\n");
|
}).call(this).join("\n");
|
||||||
};
|
};
|
||||||
Expressions.prototype.compileRoot = function(o) {
|
Expressions.prototype.compileRoot = function(o) {
|
||||||
var code;
|
var code, wrap;
|
||||||
o.indent = (this.tab = o.noWrap ? '' : TAB);
|
wrap = (o.wrap != null) ? o.wrap : true;
|
||||||
|
o.indent = (this.tab = wrap ? TAB : '');
|
||||||
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 wrap ? ("(function() {\n" + code + "\n}).call(this);\n") : code;
|
||||||
};
|
};
|
||||||
Expressions.prototype.compileWithDeclarations = function(o) {
|
Expressions.prototype.compileWithDeclarations = function(o) {
|
||||||
var code;
|
var code;
|
||||||
@@ -240,11 +246,12 @@
|
|||||||
};
|
};
|
||||||
exports.Literal = (function() {
|
exports.Literal = (function() {
|
||||||
Literal = (function() {
|
Literal = (function() {
|
||||||
return function Literal(_arg) {
|
function Literal(_arg) {
|
||||||
this.value = _arg;
|
this.value = _arg;
|
||||||
Literal.__super__.constructor.call(this);
|
Literal.__super__.constructor.call(this);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Literal;
|
||||||
})();
|
})();
|
||||||
__extends(Literal, Base);
|
__extends(Literal, Base);
|
||||||
Literal.prototype.makeReturn = function() {
|
Literal.prototype.makeReturn = function() {
|
||||||
@@ -273,11 +280,12 @@
|
|||||||
})();
|
})();
|
||||||
exports.Return = (function() {
|
exports.Return = (function() {
|
||||||
Return = (function() {
|
Return = (function() {
|
||||||
return function Return(_arg) {
|
function Return(_arg) {
|
||||||
this.expression = _arg;
|
this.expression = _arg;
|
||||||
Return.__super__.constructor.call(this);
|
Return.__super__.constructor.call(this);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Return;
|
||||||
})();
|
})();
|
||||||
__extends(Return, Base);
|
__extends(Return, Base);
|
||||||
Return.prototype.isStatement = YES;
|
Return.prototype.isStatement = YES;
|
||||||
@@ -307,7 +315,7 @@
|
|||||||
})();
|
})();
|
||||||
exports.Value = (function() {
|
exports.Value = (function() {
|
||||||
Value = (function() {
|
Value = (function() {
|
||||||
return function Value(_arg, _arg2, tag) {
|
function Value(_arg, _arg2, tag) {
|
||||||
this.properties = _arg2;
|
this.properties = _arg2;
|
||||||
this.base = _arg;
|
this.base = _arg;
|
||||||
Value.__super__.constructor.call(this);
|
Value.__super__.constructor.call(this);
|
||||||
@@ -317,6 +325,7 @@
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Value;
|
||||||
})();
|
})();
|
||||||
__extends(Value, Base);
|
__extends(Value, Base);
|
||||||
Value.prototype.children = ['base', 'properties'];
|
Value.prototype.children = ['base', 'properties'];
|
||||||
@@ -439,11 +448,12 @@
|
|||||||
}).call(this);
|
}).call(this);
|
||||||
exports.Comment = (function() {
|
exports.Comment = (function() {
|
||||||
Comment = (function() {
|
Comment = (function() {
|
||||||
return function Comment(_arg) {
|
function Comment(_arg) {
|
||||||
this.comment = _arg;
|
this.comment = _arg;
|
||||||
Comment.__super__.constructor.call(this);
|
Comment.__super__.constructor.call(this);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Comment;
|
||||||
})();
|
})();
|
||||||
__extends(Comment, Base);
|
__extends(Comment, Base);
|
||||||
Comment.prototype.isStatement = YES;
|
Comment.prototype.isStatement = YES;
|
||||||
@@ -455,7 +465,7 @@
|
|||||||
})();
|
})();
|
||||||
exports.Call = (function() {
|
exports.Call = (function() {
|
||||||
Call = (function() {
|
Call = (function() {
|
||||||
return function Call(variable, _arg, _arg2) {
|
function Call(variable, _arg, _arg2) {
|
||||||
this.exist = _arg2;
|
this.exist = _arg2;
|
||||||
this.args = _arg;
|
this.args = _arg;
|
||||||
Call.__super__.constructor.call(this);
|
Call.__super__.constructor.call(this);
|
||||||
@@ -465,6 +475,7 @@
|
|||||||
this.args || (this.args = []);
|
this.args || (this.args = []);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Call;
|
||||||
})();
|
})();
|
||||||
__extends(Call, Base);
|
__extends(Call, Base);
|
||||||
Call.prototype.children = ['variable', 'args'];
|
Call.prototype.children = ['variable', 'args'];
|
||||||
@@ -602,12 +613,13 @@
|
|||||||
})();
|
})();
|
||||||
exports.Extends = (function() {
|
exports.Extends = (function() {
|
||||||
Extends = (function() {
|
Extends = (function() {
|
||||||
return function Extends(_arg, _arg2) {
|
function Extends(_arg, _arg2) {
|
||||||
this.parent = _arg2;
|
this.parent = _arg2;
|
||||||
this.child = _arg;
|
this.child = _arg;
|
||||||
Extends.__super__.constructor.call(this);
|
Extends.__super__.constructor.call(this);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Extends;
|
||||||
})();
|
})();
|
||||||
__extends(Extends, Base);
|
__extends(Extends, Base);
|
||||||
Extends.prototype.children = ['child', 'parent'];
|
Extends.prototype.children = ['child', 'parent'];
|
||||||
@@ -620,13 +632,14 @@
|
|||||||
})();
|
})();
|
||||||
exports.Accessor = (function() {
|
exports.Accessor = (function() {
|
||||||
Accessor = (function() {
|
Accessor = (function() {
|
||||||
return function Accessor(_arg, tag) {
|
function Accessor(_arg, tag) {
|
||||||
this.name = _arg;
|
this.name = _arg;
|
||||||
Accessor.__super__.constructor.call(this);
|
Accessor.__super__.constructor.call(this);
|
||||||
this.prototype = tag === 'prototype' ? '.prototype' : '';
|
this.prototype = tag === 'prototype' ? '.prototype' : '';
|
||||||
this.soakNode = tag === 'soak';
|
this.soakNode = tag === 'soak';
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Accessor;
|
||||||
})();
|
})();
|
||||||
__extends(Accessor, Base);
|
__extends(Accessor, Base);
|
||||||
Accessor.prototype.children = ['name'];
|
Accessor.prototype.children = ['name'];
|
||||||
@@ -641,11 +654,12 @@
|
|||||||
})();
|
})();
|
||||||
exports.Index = (function() {
|
exports.Index = (function() {
|
||||||
Index = (function() {
|
Index = (function() {
|
||||||
return function Index(_arg) {
|
function Index(_arg) {
|
||||||
this.index = _arg;
|
this.index = _arg;
|
||||||
Index.__super__.constructor.call(this);
|
Index.__super__.constructor.call(this);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Index;
|
||||||
})();
|
})();
|
||||||
__extends(Index, Base);
|
__extends(Index, Base);
|
||||||
Index.prototype.children = ['index'];
|
Index.prototype.children = ['index'];
|
||||||
@@ -662,7 +676,7 @@
|
|||||||
})();
|
})();
|
||||||
exports.Range = (function() {
|
exports.Range = (function() {
|
||||||
Range = (function() {
|
Range = (function() {
|
||||||
return function Range(_arg, _arg2, tag) {
|
function Range(_arg, _arg2, tag) {
|
||||||
this.to = _arg2;
|
this.to = _arg2;
|
||||||
this.from = _arg;
|
this.from = _arg;
|
||||||
Range.__super__.constructor.call(this);
|
Range.__super__.constructor.call(this);
|
||||||
@@ -670,6 +684,7 @@
|
|||||||
this.equals = this.exclusive ? '' : '=';
|
this.equals = this.exclusive ? '' : '=';
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Range;
|
||||||
})();
|
})();
|
||||||
__extends(Range, Base);
|
__extends(Range, Base);
|
||||||
Range.prototype.children = ['from', 'to'];
|
Range.prototype.children = ['from', 'to'];
|
||||||
@@ -749,11 +764,12 @@
|
|||||||
})();
|
})();
|
||||||
exports.Slice = (function() {
|
exports.Slice = (function() {
|
||||||
Slice = (function() {
|
Slice = (function() {
|
||||||
return function Slice(_arg) {
|
function Slice(_arg) {
|
||||||
this.range = _arg;
|
this.range = _arg;
|
||||||
Slice.__super__.constructor.call(this);
|
Slice.__super__.constructor.call(this);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Slice;
|
||||||
})();
|
})();
|
||||||
__extends(Slice, Base);
|
__extends(Slice, Base);
|
||||||
Slice.prototype.children = ['range'];
|
Slice.prototype.children = ['range'];
|
||||||
@@ -771,11 +787,12 @@
|
|||||||
})();
|
})();
|
||||||
exports.ObjectLiteral = (function() {
|
exports.ObjectLiteral = (function() {
|
||||||
ObjectLiteral = (function() {
|
ObjectLiteral = (function() {
|
||||||
return function ObjectLiteral(props) {
|
function ObjectLiteral(props) {
|
||||||
ObjectLiteral.__super__.constructor.call(this);
|
ObjectLiteral.__super__.constructor.call(this);
|
||||||
this.objects = (this.properties = props || []);
|
this.objects = (this.properties = props || []);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return ObjectLiteral;
|
||||||
})();
|
})();
|
||||||
__extends(ObjectLiteral, Base);
|
__extends(ObjectLiteral, Base);
|
||||||
ObjectLiteral.prototype.children = ['properties'];
|
ObjectLiteral.prototype.children = ['properties'];
|
||||||
@@ -826,12 +843,13 @@
|
|||||||
})();
|
})();
|
||||||
exports.ArrayLiteral = (function() {
|
exports.ArrayLiteral = (function() {
|
||||||
ArrayLiteral = (function() {
|
ArrayLiteral = (function() {
|
||||||
return function ArrayLiteral(_arg) {
|
function ArrayLiteral(_arg) {
|
||||||
this.objects = _arg;
|
this.objects = _arg;
|
||||||
ArrayLiteral.__super__.constructor.call(this);
|
ArrayLiteral.__super__.constructor.call(this);
|
||||||
this.objects || (this.objects = []);
|
this.objects || (this.objects = []);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return ArrayLiteral;
|
||||||
})();
|
})();
|
||||||
__extends(ArrayLiteral, Base);
|
__extends(ArrayLiteral, Base);
|
||||||
ArrayLiteral.prototype.children = ['objects'];
|
ArrayLiteral.prototype.children = ['objects'];
|
||||||
@@ -839,30 +857,28 @@
|
|||||||
return Splat.compileSplattedArray(this.objects, o);
|
return Splat.compileSplattedArray(this.objects, o);
|
||||||
};
|
};
|
||||||
ArrayLiteral.prototype.compileNode = function(o) {
|
ArrayLiteral.prototype.compileNode = function(o) {
|
||||||
var _len, _ref2, code, i, obj, objects;
|
var _i, _len, _len2, _ref2, _ref3, code, i, obj, objects;
|
||||||
o.indent = this.idt(1);
|
o.indent = this.idt(1);
|
||||||
objects = [];
|
for (_i = 0, _len = (_ref2 = this.objects).length; _i < _len; _i++) {
|
||||||
for (i = 0, _len = (_ref2 = this.objects).length; i < _len; i++) {
|
obj = _ref2[_i];
|
||||||
obj = _ref2[i];
|
|
||||||
code = obj.compile(o);
|
|
||||||
if (obj instanceof Splat) {
|
if (obj instanceof Splat) {
|
||||||
return this.compileSplatLiteral(o);
|
return this.compileSplatLiteral(o);
|
||||||
} else if (obj instanceof Comment) {
|
|
||||||
objects.push("\n" + code + "\n" + (o.indent));
|
|
||||||
} else if (i === this.objects.length - 1) {
|
|
||||||
objects.push(code);
|
|
||||||
} else {
|
|
||||||
objects.push("" + code + ", ");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
objects = [];
|
||||||
|
for (i = 0, _len2 = (_ref3 = this.objects).length; i < _len2; i++) {
|
||||||
|
obj = _ref3[i];
|
||||||
|
code = obj.compile(o);
|
||||||
|
objects.push(obj instanceof Comment ? ("\n" + code + "\n" + (o.indent)) : (i === this.objects.length - 1 ? code : code + ', '));
|
||||||
|
}
|
||||||
objects = objects.join('');
|
objects = objects.join('');
|
||||||
return indexOf(objects, '\n') >= 0 ? ("[\n" + (this.idt(1)) + objects + "\n" + (this.tab) + "]") : ("[" + objects + "]");
|
return 0 < objects.indexOf('\n') ? ("[\n" + (o.indent) + objects + "\n" + (this.tab) + "]") : ("[" + objects + "]");
|
||||||
};
|
};
|
||||||
return ArrayLiteral;
|
return ArrayLiteral;
|
||||||
})();
|
})();
|
||||||
exports.Class = (function() {
|
exports.Class = (function() {
|
||||||
Class = (function() {
|
Class = (function() {
|
||||||
return function Class(variable, _arg, _arg2) {
|
function Class(variable, _arg, _arg2) {
|
||||||
this.properties = _arg2;
|
this.properties = _arg2;
|
||||||
this.parent = _arg;
|
this.parent = _arg;
|
||||||
Class.__super__.constructor.call(this);
|
Class.__super__.constructor.call(this);
|
||||||
@@ -871,6 +887,7 @@
|
|||||||
this.returns = false;
|
this.returns = false;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Class;
|
||||||
})();
|
})();
|
||||||
__extends(Class, Base);
|
__extends(Class, Base);
|
||||||
Class.prototype.children = ['variable', 'parent', 'properties'];
|
Class.prototype.children = ['variable', 'parent', 'properties'];
|
||||||
@@ -915,7 +932,7 @@
|
|||||||
func.name = className;
|
func.name = className;
|
||||||
func.body.push(new Return(new Literal('this')));
|
func.body.push(new Return(new Literal('this')));
|
||||||
variable = new Value(variable);
|
variable = new Value(variable);
|
||||||
variable.namespaced = include(func.name, '.');
|
variable.namespaced = 0 < className.indexOf('.');
|
||||||
constructor = func;
|
constructor = func;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -956,13 +973,14 @@
|
|||||||
})();
|
})();
|
||||||
exports.Assign = (function() {
|
exports.Assign = (function() {
|
||||||
Assign = (function() {
|
Assign = (function() {
|
||||||
return function Assign(_arg, _arg2, _arg3) {
|
function Assign(_arg, _arg2, _arg3) {
|
||||||
this.context = _arg3;
|
this.context = _arg3;
|
||||||
this.value = _arg2;
|
this.value = _arg2;
|
||||||
this.variable = _arg;
|
this.variable = _arg;
|
||||||
Assign.__super__.constructor.call(this);
|
Assign.__super__.constructor.call(this);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Assign;
|
||||||
})();
|
})();
|
||||||
__extends(Assign, Base);
|
__extends(Assign, Base);
|
||||||
Assign.prototype.METHOD_DEF = /^(?:(\S+)\.prototype\.)?([$A-Za-z_][$\w]*)$/;
|
Assign.prototype.METHOD_DEF = /^(?:(\S+)\.prototype\.)?([$A-Za-z_][$\w]*)$/;
|
||||||
@@ -972,7 +990,7 @@
|
|||||||
return this.variable instanceof Value;
|
return this.variable instanceof Value;
|
||||||
};
|
};
|
||||||
Assign.prototype.compileNode = function(o) {
|
Assign.prototype.compileNode = function(o) {
|
||||||
var isValue, match, name, node, stmt, top, val;
|
var ifn, isValue, match, name, stmt, top, val;
|
||||||
if (isValue = this.isValue()) {
|
if (isValue = this.isValue()) {
|
||||||
if (this.variable.isArray() || this.variable.isObject()) {
|
if (this.variable.isArray() || this.variable.isObject()) {
|
||||||
return this.compilePatternMatch(o);
|
return this.compilePatternMatch(o);
|
||||||
@@ -980,8 +998,9 @@
|
|||||||
if (this.variable.isSplice()) {
|
if (this.variable.isSplice()) {
|
||||||
return this.compileSplice(o);
|
return this.compileSplice(o);
|
||||||
}
|
}
|
||||||
if (node = Value.unfoldSoak(o, this, 'variable')) {
|
if (ifn = Value.unfoldSoak(o, this, 'variable')) {
|
||||||
return node.compile(o);
|
delete o.top;
|
||||||
|
return ifn.compile(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
top = del(o, 'top');
|
top = del(o, 'top');
|
||||||
@@ -1080,7 +1099,7 @@
|
|||||||
})();
|
})();
|
||||||
exports.Code = (function() {
|
exports.Code = (function() {
|
||||||
Code = (function() {
|
Code = (function() {
|
||||||
return function Code(_arg, _arg2, tag) {
|
function Code(_arg, _arg2, tag) {
|
||||||
this.body = _arg2;
|
this.body = _arg2;
|
||||||
this.params = _arg;
|
this.params = _arg;
|
||||||
Code.__super__.constructor.call(this);
|
Code.__super__.constructor.call(this);
|
||||||
@@ -1092,6 +1111,7 @@
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Code;
|
||||||
})();
|
})();
|
||||||
__extends(Code, Base);
|
__extends(Code, Base);
|
||||||
Code.prototype.children = ['params', 'body'];
|
Code.prototype.children = ['params', 'body'];
|
||||||
@@ -1103,7 +1123,7 @@
|
|||||||
o.top = true;
|
o.top = true;
|
||||||
o.indent = this.idt(1);
|
o.indent = this.idt(1);
|
||||||
empty = this.body.expressions.length === 0;
|
empty = this.body.expressions.length === 0;
|
||||||
del(o, 'noWrap');
|
del(o, 'wrap');
|
||||||
del(o, 'globals');
|
del(o, 'globals');
|
||||||
splat = undefined;
|
splat = undefined;
|
||||||
params = [];
|
params = [];
|
||||||
@@ -1152,8 +1172,8 @@
|
|||||||
o.indent = this.idt(2);
|
o.indent = this.idt(2);
|
||||||
}
|
}
|
||||||
code = this.body.expressions.length ? ("\n" + (this.body.compileWithDeclarations(o)) + "\n") : '';
|
code = this.body.expressions.length ? ("\n" + (this.body.compileWithDeclarations(o)) + "\n") : '';
|
||||||
open = this.className ? ("(function() {\n" + (this.idt(1)) + "return function " + (this.className) + "(") : "function(";
|
open = this.className ? ("(function() {\n" + (this.idt(1)) + "function " + (this.className) + "(") : "function(";
|
||||||
close = this.className ? ("" + (code && this.idt(1)) + "};\n" + (this.tab) + "})()") : ("" + (code && this.tab) + "}");
|
close = this.className ? ("" + (code && this.idt(1)) + "};\n" + (this.idt(1)) + "return " + (this.className) + ";\n" + (this.tab) + "})()") : ("" + (code && this.tab) + "}");
|
||||||
func = ("" + open + (params.join(', ')) + ") {" + code + close);
|
func = ("" + open + (params.join(', ')) + ") {" + code + close);
|
||||||
o.scope.endLevel();
|
o.scope.endLevel();
|
||||||
if (this.bound) {
|
if (this.bound) {
|
||||||
@@ -1169,7 +1189,7 @@
|
|||||||
})();
|
})();
|
||||||
exports.Param = (function() {
|
exports.Param = (function() {
|
||||||
Param = (function() {
|
Param = (function() {
|
||||||
return function Param(_arg, _arg2, _arg3) {
|
function Param(_arg, _arg2, _arg3) {
|
||||||
this.splat = _arg3;
|
this.splat = _arg3;
|
||||||
this.attach = _arg2;
|
this.attach = _arg2;
|
||||||
this.name = _arg;
|
this.name = _arg;
|
||||||
@@ -1177,6 +1197,7 @@
|
|||||||
this.value = new Literal(this.name);
|
this.value = new Literal(this.name);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Param;
|
||||||
})();
|
})();
|
||||||
__extends(Param, Base);
|
__extends(Param, Base);
|
||||||
Param.prototype.children = ['name'];
|
Param.prototype.children = ['name'];
|
||||||
@@ -1198,7 +1219,7 @@
|
|||||||
})();
|
})();
|
||||||
exports.Splat = (function() {
|
exports.Splat = (function() {
|
||||||
Splat = (function() {
|
Splat = (function() {
|
||||||
return function Splat(name) {
|
function Splat(name) {
|
||||||
Splat.__super__.constructor.call(this);
|
Splat.__super__.constructor.call(this);
|
||||||
if (!name.compile) {
|
if (!name.compile) {
|
||||||
name = new Literal(name);
|
name = new Literal(name);
|
||||||
@@ -1206,6 +1227,7 @@
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Splat;
|
||||||
})();
|
})();
|
||||||
__extends(Splat, Base);
|
__extends(Splat, Base);
|
||||||
Splat.prototype.children = ['name'];
|
Splat.prototype.children = ['name'];
|
||||||
@@ -1268,18 +1290,13 @@
|
|||||||
}).call(this);
|
}).call(this);
|
||||||
exports.While = (function() {
|
exports.While = (function() {
|
||||||
While = (function() {
|
While = (function() {
|
||||||
return function While(condition, opts) {
|
function While(condition, opts) {
|
||||||
While.__super__.constructor.call(this);
|
While.__super__.constructor.call(this);
|
||||||
if (((opts != null) ? opts.invert : undefined)) {
|
this.condition = ((opts != null) ? opts.invert : undefined) ? condition.invert() : condition;
|
||||||
if (condition instanceof Op) {
|
|
||||||
condition = new Parens(condition);
|
|
||||||
}
|
|
||||||
condition = new Op('!', condition);
|
|
||||||
}
|
|
||||||
this.condition = condition;
|
|
||||||
this.guard = ((opts != null) ? opts.guard : undefined);
|
this.guard = ((opts != null) ? opts.guard : undefined);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return While;
|
||||||
})();
|
})();
|
||||||
__extends(While, Base);
|
__extends(While, Base);
|
||||||
While.prototype.children = ['condition', 'guard', 'body'];
|
While.prototype.children = ['condition', 'guard', 'body'];
|
||||||
@@ -1297,9 +1314,9 @@
|
|||||||
var cond, post, pre, rvar, set, top;
|
var cond, post, pre, rvar, set, top;
|
||||||
top = del(o, 'top') && !this.returns;
|
top = del(o, 'top') && !this.returns;
|
||||||
o.indent = this.idt(1);
|
o.indent = this.idt(1);
|
||||||
o.top = true;
|
|
||||||
this.condition.parenthetical = true;
|
this.condition.parenthetical = true;
|
||||||
cond = this.condition.compile(o);
|
cond = this.condition.compile(o);
|
||||||
|
o.top = true;
|
||||||
set = '';
|
set = '';
|
||||||
if (!top) {
|
if (!top) {
|
||||||
rvar = o.scope.freeVariable('result');
|
rvar = o.scope.freeVariable('result');
|
||||||
@@ -1325,7 +1342,7 @@
|
|||||||
})();
|
})();
|
||||||
exports.Op = (function() {
|
exports.Op = (function() {
|
||||||
Op = (function() {
|
Op = (function() {
|
||||||
return function Op(_arg, _arg2, _arg3, flip) {
|
function Op(_arg, _arg2, _arg3, flip) {
|
||||||
this.second = _arg3;
|
this.second = _arg3;
|
||||||
this.first = _arg2;
|
this.first = _arg2;
|
||||||
this.operator = _arg;
|
this.operator = _arg;
|
||||||
@@ -1343,6 +1360,7 @@
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Op;
|
||||||
})();
|
})();
|
||||||
__extends(Op, Base);
|
__extends(Op, Base);
|
||||||
Op.prototype.CONVERSIONS = {
|
Op.prototype.CONVERSIONS = {
|
||||||
@@ -1361,10 +1379,6 @@
|
|||||||
Op.prototype.isUnary = function() {
|
Op.prototype.isUnary = function() {
|
||||||
return !this.second;
|
return !this.second;
|
||||||
};
|
};
|
||||||
Op.prototype.isInvertible = function() {
|
|
||||||
var _ref2;
|
|
||||||
return ('===' === (_ref2 = this.operator) || '!==' === _ref2);
|
|
||||||
};
|
|
||||||
Op.prototype.isComplex = function() {
|
Op.prototype.isComplex = function() {
|
||||||
return this.operator !== '!' || this.first.isComplex();
|
return this.operator !== '!' || this.first.isComplex();
|
||||||
};
|
};
|
||||||
@@ -1376,7 +1390,11 @@
|
|||||||
return include(this.CHAINABLE, this.operator);
|
return include(this.CHAINABLE, this.operator);
|
||||||
};
|
};
|
||||||
Op.prototype.invert = function() {
|
Op.prototype.invert = function() {
|
||||||
return (this.operator = this.INVERSIONS[this.operator]);
|
var _ref2;
|
||||||
|
if (('===' === (_ref2 = this.operator) || '!==' === _ref2)) {
|
||||||
|
this.operator = this.INVERSIONS[this.operator];
|
||||||
|
return this;
|
||||||
|
} else return this.second ? new Parens(this).invert() : Op.__super__.invert.call(this);
|
||||||
};
|
};
|
||||||
Op.prototype.toString = function(idt) {
|
Op.prototype.toString = function(idt) {
|
||||||
return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator);
|
return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator);
|
||||||
@@ -1385,7 +1403,7 @@
|
|||||||
if (this.isChainable() && this.first.unwrap() instanceof Op && this.first.unwrap().isChainable()) {
|
if (this.isChainable() && this.first.unwrap() instanceof Op && this.first.unwrap().isChainable()) {
|
||||||
return this.compileChain(o);
|
return this.compileChain(o);
|
||||||
}
|
}
|
||||||
if (indexOf(this.ASSIGNMENT, this.operator) >= 0) {
|
if (include(this.ASSIGNMENT, this.operator)) {
|
||||||
return this.compileAssignment(o);
|
return this.compileAssignment(o);
|
||||||
}
|
}
|
||||||
if (this.isUnary()) {
|
if (this.isUnary()) {
|
||||||
@@ -1428,23 +1446,21 @@
|
|||||||
};
|
};
|
||||||
Op.prototype.compileUnary = function(o) {
|
Op.prototype.compileUnary = function(o) {
|
||||||
var parts, space;
|
var parts, space;
|
||||||
space = indexOf(this.PREFIX_OPERATORS, this.operator) >= 0 ? ' ' : '';
|
space = include(this.PREFIX_OPERATORS, this.operator) ? ' ' : '';
|
||||||
parts = [this.operator, space, this.first.compile(o)];
|
parts = [this.operator, space, this.first.compile(o)];
|
||||||
if (this.flip) {
|
return (this.flip ? parts.reverse() : parts).join('');
|
||||||
parts = parts.reverse();
|
|
||||||
}
|
|
||||||
return parts.join('');
|
|
||||||
};
|
};
|
||||||
return Op;
|
return Op;
|
||||||
})();
|
})();
|
||||||
exports.In = (function() {
|
exports.In = (function() {
|
||||||
In = (function() {
|
In = (function() {
|
||||||
return function In(_arg, _arg2) {
|
function In(_arg, _arg2) {
|
||||||
this.array = _arg2;
|
this.array = _arg2;
|
||||||
this.object = _arg;
|
this.object = _arg;
|
||||||
In.__super__.constructor.call(this);
|
In.__super__.constructor.call(this);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return In;
|
||||||
})();
|
})();
|
||||||
__extends(In, Base);
|
__extends(In, Base);
|
||||||
In.prototype.children = ['object', 'array'];
|
In.prototype.children = ['object', 'array'];
|
||||||
@@ -1483,7 +1499,7 @@
|
|||||||
})();
|
})();
|
||||||
exports.Try = (function() {
|
exports.Try = (function() {
|
||||||
Try = (function() {
|
Try = (function() {
|
||||||
return function Try(_arg, _arg2, _arg3, _arg4) {
|
function Try(_arg, _arg2, _arg3, _arg4) {
|
||||||
this.ensure = _arg4;
|
this.ensure = _arg4;
|
||||||
this.recovery = _arg3;
|
this.recovery = _arg3;
|
||||||
this.error = _arg2;
|
this.error = _arg2;
|
||||||
@@ -1491,6 +1507,7 @@
|
|||||||
Try.__super__.constructor.call(this);
|
Try.__super__.constructor.call(this);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Try;
|
||||||
})();
|
})();
|
||||||
__extends(Try, Base);
|
__extends(Try, Base);
|
||||||
Try.prototype.children = ['attempt', 'recovery', 'ensure'];
|
Try.prototype.children = ['attempt', 'recovery', 'ensure'];
|
||||||
@@ -1518,11 +1535,12 @@
|
|||||||
})();
|
})();
|
||||||
exports.Throw = (function() {
|
exports.Throw = (function() {
|
||||||
Throw = (function() {
|
Throw = (function() {
|
||||||
return function Throw(_arg) {
|
function Throw(_arg) {
|
||||||
this.expression = _arg;
|
this.expression = _arg;
|
||||||
Throw.__super__.constructor.call(this);
|
Throw.__super__.constructor.call(this);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Throw;
|
||||||
})();
|
})();
|
||||||
__extends(Throw, Base);
|
__extends(Throw, Base);
|
||||||
Throw.prototype.children = ['expression'];
|
Throw.prototype.children = ['expression'];
|
||||||
@@ -1535,11 +1553,12 @@
|
|||||||
})();
|
})();
|
||||||
exports.Existence = (function() {
|
exports.Existence = (function() {
|
||||||
Existence = (function() {
|
Existence = (function() {
|
||||||
return function Existence(_arg) {
|
function Existence(_arg) {
|
||||||
this.expression = _arg;
|
this.expression = _arg;
|
||||||
Existence.__super__.constructor.call(this);
|
Existence.__super__.constructor.call(this);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Existence;
|
||||||
})();
|
})();
|
||||||
__extends(Existence, Base);
|
__extends(Existence, Base);
|
||||||
Existence.prototype.children = ['expression'];
|
Existence.prototype.children = ['expression'];
|
||||||
@@ -1553,11 +1572,12 @@
|
|||||||
})();
|
})();
|
||||||
exports.Parens = (function() {
|
exports.Parens = (function() {
|
||||||
Parens = (function() {
|
Parens = (function() {
|
||||||
return function Parens(_arg) {
|
function Parens(_arg) {
|
||||||
this.expression = _arg;
|
this.expression = _arg;
|
||||||
Parens.__super__.constructor.call(this);
|
Parens.__super__.constructor.call(this);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Parens;
|
||||||
})();
|
})();
|
||||||
__extends(Parens, Base);
|
__extends(Parens, Base);
|
||||||
Parens.prototype.children = ['expression'];
|
Parens.prototype.children = ['expression'];
|
||||||
@@ -1588,7 +1608,7 @@
|
|||||||
})();
|
})();
|
||||||
exports.For = (function() {
|
exports.For = (function() {
|
||||||
For = (function() {
|
For = (function() {
|
||||||
return function For(_arg, source, _arg2, _arg3) {
|
function For(_arg, source, _arg2, _arg3) {
|
||||||
var _ref2, _ref3;
|
var _ref2, _ref3;
|
||||||
this.index = _arg3;
|
this.index = _arg3;
|
||||||
this.name = _arg2;
|
this.name = _arg2;
|
||||||
@@ -1607,6 +1627,7 @@
|
|||||||
this.returns = false;
|
this.returns = false;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return For;
|
||||||
})();
|
})();
|
||||||
__extends(For, Base);
|
__extends(For, Base);
|
||||||
For.prototype.children = ['body', 'source', 'guard'];
|
For.prototype.children = ['body', 'source', 'guard'];
|
||||||
@@ -1723,7 +1744,7 @@
|
|||||||
})();
|
})();
|
||||||
exports.Switch = (function() {
|
exports.Switch = (function() {
|
||||||
Switch = (function() {
|
Switch = (function() {
|
||||||
return function Switch(_arg, _arg2, _arg3) {
|
function Switch(_arg, _arg2, _arg3) {
|
||||||
this.otherwise = _arg3;
|
this.otherwise = _arg3;
|
||||||
this.cases = _arg2;
|
this.cases = _arg2;
|
||||||
this.subject = _arg;
|
this.subject = _arg;
|
||||||
@@ -1732,6 +1753,7 @@
|
|||||||
this.subject || (this.subject = new Literal('true'));
|
this.subject || (this.subject = new Literal('true'));
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Switch;
|
||||||
})();
|
})();
|
||||||
__extends(Switch, Base);
|
__extends(Switch, Base);
|
||||||
Switch.prototype.children = ['subject', 'cases', 'otherwise'];
|
Switch.prototype.children = ['subject', 'cases', 'otherwise'];
|
||||||
@@ -1778,27 +1800,16 @@
|
|||||||
})();
|
})();
|
||||||
exports.If = (function() {
|
exports.If = (function() {
|
||||||
If = (function() {
|
If = (function() {
|
||||||
return function If(condition, _arg, _arg2) {
|
function If(condition, _arg, _arg2) {
|
||||||
var op;
|
|
||||||
this.tags = _arg2;
|
this.tags = _arg2;
|
||||||
this.body = _arg;
|
this.body = _arg;
|
||||||
this.tags || (this.tags = {});
|
this.tags || (this.tags = {});
|
||||||
if (this.tags.invert) {
|
this.condition = this.tags.invert ? condition.invert() : condition;
|
||||||
op = condition instanceof Op;
|
|
||||||
if (op && condition.isInvertible()) {
|
|
||||||
condition.invert();
|
|
||||||
} else {
|
|
||||||
if (op && !condition.isUnary()) {
|
|
||||||
condition = new Parens(condition);
|
|
||||||
}
|
|
||||||
condition = new Op('!', condition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.condition = condition;
|
|
||||||
this.elseBody = null;
|
this.elseBody = null;
|
||||||
this.isChain = false;
|
this.isChain = false;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return If;
|
||||||
})();
|
})();
|
||||||
__extends(If, Base);
|
__extends(If, Base);
|
||||||
If.prototype.children = ['condition', 'body', 'elseBody', 'assigner'];
|
If.prototype.children = ['condition', 'body', 'elseBody', 'assigner'];
|
||||||
@@ -1811,9 +1822,9 @@
|
|||||||
var _ref2;
|
var _ref2;
|
||||||
return (((_ref2 = this.elseBody) != null) ? _ref2.unwrap() : undefined);
|
return (((_ref2 = this.elseBody) != null) ? _ref2.unwrap() : undefined);
|
||||||
};
|
};
|
||||||
If.prototype.addElse = function(elseBody, statement) {
|
If.prototype.addElse = function(elseBody) {
|
||||||
if (this.isChain) {
|
if (this.isChain) {
|
||||||
this.elseBodyNode().addElse(elseBody, statement);
|
this.elseBodyNode().addElse(elseBody);
|
||||||
} else {
|
} else {
|
||||||
this.isChain = elseBody instanceof If;
|
this.isChain = elseBody instanceof If;
|
||||||
this.elseBody = this.ensureExpressions(elseBody);
|
this.elseBody = this.ensureExpressions(elseBody);
|
||||||
@@ -1821,22 +1832,12 @@
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
If.prototype.isStatement = function(o) {
|
If.prototype.isStatement = function(o) {
|
||||||
return this.statement || (this.statement = !!((o && o.top) || this.bodyNode().isStatement(o) || (this.elseBody && this.elseBodyNode().isStatement(o))));
|
var _ref2;
|
||||||
|
return this.statement || (this.statement = ((o != null) ? o.top : undefined) || this.bodyNode().isStatement(o) || (((_ref2 = this.elseBodyNode()) != null) ? _ref2.isStatement(o) : undefined));
|
||||||
};
|
};
|
||||||
If.prototype.compileCondition = function(o) {
|
If.prototype.compileCondition = function(o) {
|
||||||
var _i, _len, _result, cond, conditions;
|
this.condition.parenthetical = true;
|
||||||
conditions = flatten([this.condition]);
|
return this.condition.compile(o);
|
||||||
if (conditions.length === 1) {
|
|
||||||
conditions[0].parenthetical = true;
|
|
||||||
}
|
|
||||||
return (function() {
|
|
||||||
_result = [];
|
|
||||||
for (_i = 0, _len = conditions.length; _i < _len; _i++) {
|
|
||||||
cond = conditions[_i];
|
|
||||||
_result.push(cond.compile(o));
|
|
||||||
}
|
|
||||||
return _result;
|
|
||||||
})().join(' || ');
|
|
||||||
};
|
};
|
||||||
If.prototype.compileNode = function(o) {
|
If.prototype.compileNode = function(o) {
|
||||||
return this.isStatement(o) ? this.compileStatement(o) : this.compileExpression(o);
|
return this.isStatement(o) ? this.compileStatement(o) : this.compileExpression(o);
|
||||||
@@ -1854,24 +1855,23 @@
|
|||||||
return node instanceof Expressions ? node : new Expressions([node]);
|
return node instanceof Expressions ? node : new Expressions([node]);
|
||||||
};
|
};
|
||||||
If.prototype.compileStatement = function(o) {
|
If.prototype.compileStatement = function(o) {
|
||||||
var body, child, comDent, condO, elsePart, ifDent, ifPart, top;
|
var child, condO, ifPart, top;
|
||||||
top = del(o, 'top');
|
top = del(o, 'top');
|
||||||
child = del(o, 'chainChild');
|
child = del(o, 'chainChild');
|
||||||
condO = merge(o);
|
condO = merge(o);
|
||||||
o.indent = this.idt(1);
|
o.indent = this.idt(1);
|
||||||
o.top = true;
|
o.top = true;
|
||||||
ifDent = child || (top && !this.isStatement(o)) ? '' : this.idt();
|
ifPart = ("if (" + (this.compileCondition(condO)) + ") {\n" + (this.body.compile(o)) + "\n" + (this.tab) + "}");
|
||||||
comDent = child ? this.idt() : '';
|
if (!child) {
|
||||||
body = this.body.compile(o);
|
ifPart = this.tab + ifPart;
|
||||||
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, {
|
return ifPart + (this.isChain ? ' else ' + this.elseBodyNode().compile(merge(o, {
|
||||||
indent: this.idt(),
|
indent: this.tab,
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
If.prototype.compileExpression = function(o) {
|
If.prototype.compileExpression = function(o) {
|
||||||
var code, elsePart, ifPart;
|
var code, elsePart, ifPart;
|
||||||
|
|||||||
@@ -2,11 +2,12 @@
|
|||||||
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments;
|
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments;
|
||||||
exports.OptionParser = (function() {
|
exports.OptionParser = (function() {
|
||||||
OptionParser = (function() {
|
OptionParser = (function() {
|
||||||
return function OptionParser(rules, banner) {
|
function OptionParser(rules, banner) {
|
||||||
this.banner = banner;
|
this.banner = banner;
|
||||||
this.rules = buildRules(rules);
|
this.rules = buildRules(rules);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return OptionParser;
|
||||||
})();
|
})();
|
||||||
OptionParser.prototype.parse = function(args) {
|
OptionParser.prototype.parse = function(args) {
|
||||||
var _i, _len, _len2, _ref, arg, i, isOption, matchedRule, options, rule, value;
|
var _i, _len, _len2, _ref, arg, i, isOption, matchedRule, options, rule, value;
|
||||||
|
|||||||
364
lib/parser.js
364
lib/parser.js
File diff suppressed because one or more lines are too long
@@ -13,7 +13,7 @@
|
|||||||
var val;
|
var val;
|
||||||
try {
|
try {
|
||||||
val = CoffeeScript.eval(buffer.toString(), {
|
val = CoffeeScript.eval(buffer.toString(), {
|
||||||
noWrap: true,
|
wrap: false,
|
||||||
globals: true,
|
globals: true,
|
||||||
fileName: 'repl'
|
fileName: 'repl'
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, _i, _len, _ref, include, left, rite;
|
var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, _i, _len, _ref, include, left, rite;
|
||||||
include = require('./helpers').include;
|
include = require('./helpers').include;
|
||||||
exports.Rewriter = (function() {
|
exports.Rewriter = (function() {
|
||||||
return function Rewriter() {};
|
function Rewriter() {};
|
||||||
|
return Rewriter;
|
||||||
})();
|
})();
|
||||||
exports.Rewriter.prototype.rewrite = function(_arg) {
|
exports.Rewriter.prototype.rewrite = function(_arg) {
|
||||||
this.tokens = _arg;
|
this.tokens = _arg;
|
||||||
@@ -365,7 +366,7 @@
|
|||||||
}
|
}
|
||||||
EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
|
EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
|
||||||
IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
|
IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
|
||||||
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'NULL', 'UNARY', 'TRUE', 'FALSE', '@', '->', '=>', '[', '(', '{'];
|
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'UNARY', '@', '->', '=>', '[', '(', '{'];
|
||||||
IMPLICIT_BLOCK = ['->', '=>', '{', '[', ','];
|
IMPLICIT_BLOCK = ['->', '=>', '{', '[', ','];
|
||||||
IMPLICIT_END = ['POST_IF', 'POST_UNLESS', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'TERMINATOR', 'INDENT'];
|
IMPLICIT_END = ['POST_IF', 'POST_UNLESS', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'TERMINATOR', 'INDENT'];
|
||||||
SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN'];
|
SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN'];
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
_ref = require('./helpers'), extend = _ref.extend, last = _ref.last;
|
_ref = require('./helpers'), extend = _ref.extend, last = _ref.last;
|
||||||
exports.Scope = (function() {
|
exports.Scope = (function() {
|
||||||
Scope = (function() {
|
Scope = (function() {
|
||||||
return function Scope(_arg, _arg2, _arg3) {
|
function Scope(_arg, _arg2, _arg3) {
|
||||||
this.method = _arg3;
|
this.method = _arg3;
|
||||||
this.expressions = _arg2;
|
this.expressions = _arg2;
|
||||||
this.parent = _arg;
|
this.parent = _arg;
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
return Scope;
|
||||||
})();
|
})();
|
||||||
Scope.root = null;
|
Scope.root = null;
|
||||||
Scope.prototype.startLevel = function() {
|
Scope.prototype.startLevel = function() {
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ parseOptions = ->
|
|||||||
# The compile-time options to pass to the CoffeeScript compiler.
|
# The compile-time options to pass to the CoffeeScript compiler.
|
||||||
compileOptions = (fileName) ->
|
compileOptions = (fileName) ->
|
||||||
o = {fileName}
|
o = {fileName}
|
||||||
o.noWrap = opts['no-wrap']
|
o.wrap = !opts['no-wrap']
|
||||||
o
|
o
|
||||||
|
|
||||||
# Print the `--help` usage message and exit.
|
# Print the `--help` usage message and exit.
|
||||||
|
|||||||
@@ -130,9 +130,7 @@ grammar =
|
|||||||
o "AlphaNumeric"
|
o "AlphaNumeric"
|
||||||
o "JS", -> new Literal $1
|
o "JS", -> new Literal $1
|
||||||
o "REGEX", -> new Literal $1
|
o "REGEX", -> new Literal $1
|
||||||
o "TRUE", -> new Literal true
|
o "BOOL", -> new Literal $1
|
||||||
o "FALSE", -> new Literal false
|
|
||||||
o "NULL", -> new Literal 'null'
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Assignment of a variable, property, or index to a value.
|
# Assignment of a variable, property, or index to a value.
|
||||||
@@ -195,7 +193,7 @@ grammar =
|
|||||||
ParamList: [
|
ParamList: [
|
||||||
o "", -> []
|
o "", -> []
|
||||||
o "Param", -> [$1]
|
o "Param", -> [$1]
|
||||||
o "ParamList , Param", -> $1.concat [$3]
|
o "ParamList , Param", -> $1.concat $3
|
||||||
]
|
]
|
||||||
|
|
||||||
# A single parameter in a function definition can be ordinary, or a splat
|
# A single parameter in a function definition can be ordinary, or a splat
|
||||||
@@ -265,8 +263,8 @@ grammar =
|
|||||||
AssignList: [
|
AssignList: [
|
||||||
o "", -> []
|
o "", -> []
|
||||||
o "AssignObj", -> [$1]
|
o "AssignObj", -> [$1]
|
||||||
o "AssignList , AssignObj", -> $1.concat [$3]
|
o "AssignList , AssignObj", -> $1.concat $3
|
||||||
o "AssignList OptComma TERMINATOR AssignObj", -> $1.concat [$4]
|
o "AssignList OptComma TERMINATOR AssignObj", -> $1.concat $4
|
||||||
o "AssignList OptComma INDENT AssignList OptComma OUTDENT", -> $1.concat $4
|
o "AssignList OptComma INDENT AssignList OptComma OUTDENT", -> $1.concat $4
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -363,8 +361,8 @@ grammar =
|
|||||||
# (i.e. comma-separated expressions). Newlines work as well.
|
# (i.e. comma-separated expressions). Newlines work as well.
|
||||||
ArgList: [
|
ArgList: [
|
||||||
o "Arg", -> [$1]
|
o "Arg", -> [$1]
|
||||||
o "ArgList , Arg", -> $1.concat [$3]
|
o "ArgList , Arg", -> $1.concat $3
|
||||||
o "ArgList OptComma TERMINATOR Arg", -> $1.concat [$4]
|
o "ArgList OptComma TERMINATOR Arg", -> $1.concat $4
|
||||||
o "INDENT ArgList OptComma OUTDENT", -> $2
|
o "INDENT ArgList OptComma OUTDENT", -> $2
|
||||||
o "ArgList OptComma INDENT ArgList OptComma OUTDENT", -> $1.concat $4
|
o "ArgList OptComma INDENT ArgList OptComma OUTDENT", -> $1.concat $4
|
||||||
]
|
]
|
||||||
@@ -380,8 +378,7 @@ grammar =
|
|||||||
# having the newlines wouldn't make sense.
|
# having the newlines wouldn't make sense.
|
||||||
SimpleArgs: [
|
SimpleArgs: [
|
||||||
o "Expression"
|
o "Expression"
|
||||||
o "SimpleArgs , Expression", ->
|
o "SimpleArgs , Expression", -> [].concat $1, $3
|
||||||
if $1 instanceof Array then $1.concat([$3]) else [$1].concat([$3])
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# The variants of *try/catch/finally* exception handling blocks.
|
# The variants of *try/catch/finally* exception handling blocks.
|
||||||
@@ -527,8 +524,8 @@ grammar =
|
|||||||
# rules are necessary.
|
# rules are necessary.
|
||||||
Operation: [
|
Operation: [
|
||||||
o "UNARY Expression", -> new Op $1, $2
|
o "UNARY Expression", -> new Op $1, $2
|
||||||
o("- Expression", (-> new Op('-', $2)), {prec: 'UNARY'})
|
o "- Expression", (-> new Op '-', $2), prec: 'UNARY'
|
||||||
o("+ Expression", (-> new Op('+', $2)), {prec: 'UNARY'})
|
o "+ Expression", (-> new Op '+', $2), prec: 'UNARY'
|
||||||
|
|
||||||
o "-- Expression", -> new Op '--', $2
|
o "-- Expression", -> new Op '--', $2
|
||||||
o "++ Expression", -> new Op '++', $2
|
o "++ Expression", -> new Op '++', $2
|
||||||
|
|||||||
@@ -73,12 +73,12 @@ exports.Lexer = class Lexer
|
|||||||
# though `is` means `===` otherwise.
|
# though `is` means `===` otherwise.
|
||||||
identifierToken: ->
|
identifierToken: ->
|
||||||
return false unless match = IDENTIFIER.exec @chunk
|
return false unless match = IDENTIFIER.exec @chunk
|
||||||
id = match[0]
|
[input, id, colon] = match
|
||||||
@i += id.length
|
@i += input.length
|
||||||
if id is 'all' and @tag() is 'FOR'
|
if id is 'all' and @tag() is 'FOR'
|
||||||
@token 'ALL', id
|
@token 'ALL', id
|
||||||
return true
|
return true
|
||||||
forcedIdentifier = @tagAccessor() or ASSIGNED.test @chunk
|
forcedIdentifier = colon or @tagAccessor()
|
||||||
tag = 'IDENTIFIER'
|
tag = 'IDENTIFIER'
|
||||||
if include(JS_KEYWORDS, id) or
|
if include(JS_KEYWORDS, id) or
|
||||||
not forcedIdentifier and include(COFFEE_KEYWORDS, id)
|
not forcedIdentifier and include(COFFEE_KEYWORDS, id)
|
||||||
@@ -103,7 +103,7 @@ exports.Lexer = class Lexer
|
|||||||
tag = 'IDENTIFIER'
|
tag = 'IDENTIFIER'
|
||||||
id = new String id
|
id = new String id
|
||||||
id.reserved = yes
|
id.reserved = yes
|
||||||
else if include(RESERVED, id)
|
else if include RESERVED, id
|
||||||
@identifierError id
|
@identifierError id
|
||||||
unless forcedIdentifier
|
unless forcedIdentifier
|
||||||
tag = id = COFFEE_ALIASES[id] if COFFEE_ALIASES.hasOwnProperty id
|
tag = id = COFFEE_ALIASES[id] if COFFEE_ALIASES.hasOwnProperty id
|
||||||
@@ -111,7 +111,11 @@ exports.Lexer = class Lexer
|
|||||||
tag = 'UNARY'
|
tag = 'UNARY'
|
||||||
else if include LOGIC, id
|
else if include LOGIC, id
|
||||||
tag = 'LOGIC'
|
tag = 'LOGIC'
|
||||||
|
else if include BOOL, tag
|
||||||
|
id = tag.toLowerCase()
|
||||||
|
tag = 'BOOL'
|
||||||
@token tag, id
|
@token tag, id
|
||||||
|
@token ':', ':' if colon
|
||||||
true
|
true
|
||||||
|
|
||||||
# Matches numbers, including decimals, hex, and exponential notation.
|
# Matches numbers, including decimals, hex, and exponential notation.
|
||||||
@@ -311,9 +315,9 @@ exports.Lexer = class Lexer
|
|||||||
prev = last @tokens
|
prev = last @tokens
|
||||||
if value is '='
|
if value is '='
|
||||||
@assignmentError() if not prev[1].reserved and include JS_FORBIDDEN, prev[1]
|
@assignmentError() if not prev[1].reserved and include JS_FORBIDDEN, prev[1]
|
||||||
if prev[1] in ['or', 'and']
|
if prev[1] in ['||', '&&']
|
||||||
prev[0] = 'COMPOUND_ASSIGN'
|
prev[0] = 'COMPOUND_ASSIGN'
|
||||||
prev[1] = COFFEE_ALIASES[prev[1]] + '='
|
prev[1] += '='
|
||||||
return true
|
return true
|
||||||
if ';' is value then tag = 'TERMINATOR'
|
if ';' is value then tag = 'TERMINATOR'
|
||||||
else if include LOGIC , value then tag = 'LOGIC'
|
else if include LOGIC , value then tag = 'LOGIC'
|
||||||
@@ -343,17 +347,17 @@ exports.Lexer = class Lexer
|
|||||||
# is the previous token.
|
# is the previous token.
|
||||||
tagAccessor: ->
|
tagAccessor: ->
|
||||||
return false if not (prev = last @tokens) or prev.spaced
|
return false if not (prev = last @tokens) or prev.spaced
|
||||||
accessor = if prev[1] is '::'
|
if prev[1] is '::'
|
||||||
@tag 0, 'PROTOTYPE_ACCESS'
|
@tag 0, 'PROTOTYPE_ACCESS'
|
||||||
else if prev[1] is '.' and @value(1) isnt '.'
|
else if prev[1] is '.' and @value(1) isnt '.'
|
||||||
if @tag(1) is '?'
|
if @tag(1) is '?'
|
||||||
@tag(0, 'SOAK_ACCESS')
|
@tag 0, 'SOAK_ACCESS'
|
||||||
@tokens.splice(-2, 1)
|
@tokens.splice(-2, 1)
|
||||||
else
|
else
|
||||||
@tag 0, 'PROPERTY_ACCESS'
|
@tag 0, 'PROPERTY_ACCESS'
|
||||||
else
|
else
|
||||||
prev[0] is '@'
|
return prev[0] is '@'
|
||||||
if accessor then 'accessor' else false
|
true
|
||||||
|
|
||||||
# Sanitize a heredoc or herecomment by
|
# Sanitize a heredoc or herecomment by
|
||||||
# erasing all external indentation on the left-hand side.
|
# erasing all external indentation on the left-hand side.
|
||||||
@@ -374,12 +378,11 @@ exports.Lexer = class Lexer
|
|||||||
tagParameters: ->
|
tagParameters: ->
|
||||||
return if @tag() isnt ')'
|
return if @tag() isnt ')'
|
||||||
i = @tokens.length
|
i = @tokens.length
|
||||||
loop
|
while tok = @tokens[--i]
|
||||||
return unless tok = @tokens[--i]
|
|
||||||
switch tok[0]
|
switch tok[0]
|
||||||
when 'IDENTIFIER' then tok[0] = 'PARAM'
|
when 'IDENTIFIER' then tok[0] = 'PARAM'
|
||||||
when ')' then tok[0] = 'PARAM_END'
|
when ')' then tok[0] = 'PARAM_END'
|
||||||
when '(', 'CALL_START' then return tok[0] = 'PARAM_START'
|
when '(', 'CALL_START' then tok[0] = 'PARAM_START'; return true
|
||||||
true
|
true
|
||||||
|
|
||||||
# Close up all remaining open blocks at the end of the file.
|
# Close up all remaining open blocks at the end of the file.
|
||||||
@@ -389,12 +392,12 @@ exports.Lexer = class Lexer
|
|||||||
# The error for when you try to use a forbidden word in JavaScript as
|
# The error for when you try to use a forbidden word in JavaScript as
|
||||||
# an identifier.
|
# an identifier.
|
||||||
identifierError: (word) ->
|
identifierError: (word) ->
|
||||||
throw new Error "SyntaxError: Reserved word \"#{word}\" on line #{@line + 1}"
|
throw SyntaxError "Reserved word \"#{word}\" on line #{@line + 1}"
|
||||||
|
|
||||||
# The error for when you try to assign to a reserved word in JavaScript,
|
# The error for when you try to assign to a reserved word in JavaScript,
|
||||||
# like "function" or "default".
|
# like "function" or "default".
|
||||||
assignmentError: ->
|
assignmentError: ->
|
||||||
throw new Error "SyntaxError: Reserved word \"#{@value()}\" on line #{@line + 1} can't be assigned"
|
throw SyntaxError "Reserved word \"#{@value()}\" on line #{@line + 1} can't be assigned"
|
||||||
|
|
||||||
# Matches a balanced group such as a single or double-quoted string. Pass in
|
# Matches a balanced group such as a single or double-quoted string. Pass in
|
||||||
# a series of delimiters, all of which must be nested correctly within the
|
# a series of delimiters, all of which must be nested correctly within the
|
||||||
@@ -545,7 +548,10 @@ RESERVED = [
|
|||||||
JS_FORBIDDEN = JS_KEYWORDS.concat RESERVED
|
JS_FORBIDDEN = JS_KEYWORDS.concat RESERVED
|
||||||
|
|
||||||
# Token matching regexes.
|
# Token matching regexes.
|
||||||
IDENTIFIER = /^[a-zA-Z_$][\w$]*/
|
IDENTIFIER = /// ^
|
||||||
|
( [$A-Za-z_][$\w]* )
|
||||||
|
( [^\n\S]* : (?!:) )? # Is this a property name?
|
||||||
|
///
|
||||||
NUMBER = /^0x[\da-f]+|^(?:\d+(\.\d+)?|\.\d+)(?:e[+-]?\d+)?/i
|
NUMBER = /^0x[\da-f]+|^(?:\d+(\.\d+)?|\.\d+)(?:e[+-]?\d+)?/i
|
||||||
HEREDOC = /^("""|''')([\s\S]*?)(?:\n[ \t]*)?\1/
|
HEREDOC = /^("""|''')([\s\S]*?)(?:\n[ \t]*)?\1/
|
||||||
OPERATOR = /// ^ (?: -[-=>]? | \+[+=]? | \.\.\.? | [*&|/%=<>^:!?]+ ) ///
|
OPERATOR = /// ^ (?: -[-=>]? | \+[+=]? | \.\.\.? | [*&|/%=<>^:!?]+ ) ///
|
||||||
@@ -606,13 +612,16 @@ MATH = ['*', '/', '%']
|
|||||||
# Relational tokens that are negatable with `not` prefix.
|
# Relational tokens that are negatable with `not` prefix.
|
||||||
RELATION = ['IN', 'OF', 'INSTANCEOF']
|
RELATION = ['IN', 'OF', 'INSTANCEOF']
|
||||||
|
|
||||||
|
# Boolean tokens.
|
||||||
|
BOOL = ['TRUE', 'FALSE', 'NULL']
|
||||||
|
|
||||||
# Tokens which a regular expression will never immediately follow, but which
|
# Tokens which a regular expression will never immediately follow, but which
|
||||||
# a division operator might.
|
# a division operator might.
|
||||||
#
|
#
|
||||||
# See: http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions
|
# See: http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions
|
||||||
#
|
#
|
||||||
# Our list is shorter, due to sans-parentheses method calls.
|
# Our list is shorter, due to sans-parentheses method calls.
|
||||||
NOT_REGEX = ['NUMBER', 'REGEX', '++', '--', 'FALSE', 'NULL', 'TRUE', ']']
|
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', '++', '--', ']']
|
||||||
|
|
||||||
# Tokens which could legitimately be invoked or indexed. A opening
|
# Tokens which could legitimately be invoked or indexed. A opening
|
||||||
# parentheses or bracket following these tokens will be recorded as the start
|
# parentheses or bracket following these tokens will be recorded as the start
|
||||||
|
|||||||
115
src/nodes.coffee
115
src/nodes.coffee
@@ -6,7 +6,7 @@
|
|||||||
{Scope} = require './scope'
|
{Scope} = require './scope'
|
||||||
|
|
||||||
# Import the helpers we plan to use.
|
# Import the helpers we plan to use.
|
||||||
{compact, flatten, merge, del, include, indexOf, starts, ends, last} = require './helpers'
|
{compact, flatten, merge, del, include, starts, ends, last} = require './helpers'
|
||||||
|
|
||||||
# Constant functions for nodes that don't need customization.
|
# Constant functions for nodes that don't need customization.
|
||||||
YES = -> yes
|
YES = -> yes
|
||||||
@@ -128,10 +128,11 @@ exports.Base = class Base
|
|||||||
traverseChildren: (crossScope, func) ->
|
traverseChildren: (crossScope, func) ->
|
||||||
@eachChild (child) ->
|
@eachChild (child) ->
|
||||||
return false if func(child) is false
|
return false if func(child) is false
|
||||||
if child instanceof Base and
|
if crossScope or child not instanceof Code
|
||||||
(crossScope or child not instanceof Code)
|
|
||||||
child.traverseChildren crossScope, func
|
child.traverseChildren crossScope, func
|
||||||
|
|
||||||
|
invert: -> new Op '!', this
|
||||||
|
|
||||||
# Default implementations of the common node properties and methods. Nodes
|
# Default implementations of the common node properties and methods. Nodes
|
||||||
# will override these with custom logic, if needed.
|
# will override these with custom logic, if needed.
|
||||||
children: []
|
children: []
|
||||||
@@ -197,24 +198,21 @@ exports.Expressions = class Expressions extends Base
|
|||||||
# It would be better not to generate them in the first place, but for now,
|
# It would be better not to generate them in the first place, but for now,
|
||||||
# clean up obvious double-parentheses.
|
# clean up obvious double-parentheses.
|
||||||
compileRoot: (o) ->
|
compileRoot: (o) ->
|
||||||
o.indent = @tab = if o.noWrap then '' else TAB
|
wrap = if o.wrap? then o.wrap else true
|
||||||
|
o.indent = @tab = if wrap then TAB else ''
|
||||||
o.scope = new Scope(null, this, null)
|
o.scope = new Scope(null, this, null)
|
||||||
code = @compileWithDeclarations(o)
|
code = @compileWithDeclarations(o)
|
||||||
code = code.replace(TRAILING_WHITESPACE, '')
|
code = code.replace(TRAILING_WHITESPACE, '')
|
||||||
if o.noWrap then code else "(function() {\n#{code}\n}).call(this);\n"
|
if wrap then "(function() {\n#{code}\n}).call(this);\n" else code
|
||||||
|
|
||||||
# Compile the expressions body for the contents of a function, with
|
# Compile the expressions body for the contents of a function, with
|
||||||
# declarations of all inner variables pushed up to the top.
|
# declarations of all inner variables pushed up to the top.
|
||||||
compileWithDeclarations: (o) ->
|
compileWithDeclarations: (o) ->
|
||||||
code = @compileNode(o)
|
code = @compileNode(o)
|
||||||
code = """
|
if o.scope.hasAssignments this
|
||||||
#{@tab}var #{ o.scope.compiledAssignments().replace /\n/g, '$&' + @tab };
|
code = "#{@tab}var #{ o.scope.compiledAssignments().replace /\n/g, '$&' + @tab };\n#{code}"
|
||||||
#{code}
|
if not o.globals and o.scope.hasDeclarations this
|
||||||
""" if o.scope.hasAssignments this
|
code = "#{@tab}var #{o.scope.compiledDeclarations()};\n#{code}"
|
||||||
code = """
|
|
||||||
#{@tab}var #{o.scope.compiledDeclarations()};
|
|
||||||
#{code}
|
|
||||||
""" if not o.globals and o.scope.hasDeclarations this
|
|
||||||
code
|
code
|
||||||
|
|
||||||
# Compiles a single expression within the expressions body. If we need to
|
# Compiles a single expression within the expressions body. If we need to
|
||||||
@@ -736,20 +734,21 @@ exports.ArrayLiteral = class ArrayLiteral extends Base
|
|||||||
|
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
o.indent = @idt 1
|
o.indent = @idt 1
|
||||||
|
for obj in @objects when obj instanceof Splat
|
||||||
|
return @compileSplatLiteral o
|
||||||
objects = []
|
objects = []
|
||||||
for obj, i in @objects
|
for obj, i in @objects
|
||||||
code = obj.compile(o)
|
code = obj.compile o
|
||||||
if obj instanceof Splat
|
objects.push (if obj instanceof Comment
|
||||||
return @compileSplatLiteral o
|
"\n#{code}\n#{o.indent}"
|
||||||
else if obj instanceof Comment
|
|
||||||
objects.push "\n#{code}\n#{o.indent}"
|
|
||||||
else if i is @objects.length - 1
|
else if i is @objects.length - 1
|
||||||
objects.push code
|
code
|
||||||
else
|
else
|
||||||
objects.push "#{code}, "
|
code + ', '
|
||||||
objects = objects.join('')
|
)
|
||||||
if indexOf(objects, '\n') >= 0
|
objects = objects.join ''
|
||||||
"[\n#{@idt(1)}#{objects}\n#{@tab}]"
|
if 0 < objects.indexOf '\n'
|
||||||
|
"[\n#{o.indent}#{objects}\n#{@tab}]"
|
||||||
else
|
else
|
||||||
"[#{objects}]"
|
"[#{objects}]"
|
||||||
|
|
||||||
@@ -806,7 +805,7 @@ exports.Class = class Class extends Base
|
|||||||
func.name = className
|
func.name = className
|
||||||
func.body.push new Return new Literal 'this'
|
func.body.push new Return new Literal 'this'
|
||||||
variable = new Value variable
|
variable = new Value variable
|
||||||
variable.namespaced = include func.name, '.'
|
variable.namespaced = 0 < className.indexOf '.'
|
||||||
constructor = func
|
constructor = func
|
||||||
continue
|
continue
|
||||||
if func instanceof Code and func.bound
|
if func instanceof Code and func.bound
|
||||||
@@ -860,7 +859,9 @@ exports.Assign = class Assign extends Base
|
|||||||
if isValue = @isValue()
|
if isValue = @isValue()
|
||||||
return @compilePatternMatch(o) if @variable.isArray() or @variable.isObject()
|
return @compilePatternMatch(o) if @variable.isArray() or @variable.isObject()
|
||||||
return @compileSplice(o) if @variable.isSplice()
|
return @compileSplice(o) if @variable.isSplice()
|
||||||
return node.compile o if node = Value.unfoldSoak o, this, 'variable'
|
if ifn = Value.unfoldSoak o, this, 'variable'
|
||||||
|
delete o.top
|
||||||
|
return ifn.compile o
|
||||||
top = del o, 'top'
|
top = del o, 'top'
|
||||||
stmt = del o, 'asStatement'
|
stmt = del o, 'asStatement'
|
||||||
name = @variable.compile(o)
|
name = @variable.compile(o)
|
||||||
@@ -964,7 +965,7 @@ exports.Code = class Code extends Base
|
|||||||
o.top = true
|
o.top = true
|
||||||
o.indent = @idt(1)
|
o.indent = @idt(1)
|
||||||
empty = @body.expressions.length is 0
|
empty = @body.expressions.length is 0
|
||||||
del o, 'noWrap'
|
del o, 'wrap'
|
||||||
del o, 'globals'
|
del o, 'globals'
|
||||||
splat = undefined
|
splat = undefined
|
||||||
params = []
|
params = []
|
||||||
@@ -993,8 +994,8 @@ exports.Code = class Code extends Base
|
|||||||
(o.scope.parameter(param)) for param in params
|
(o.scope.parameter(param)) for param in params
|
||||||
o.indent = @idt 2 if @className
|
o.indent = @idt 2 if @className
|
||||||
code = if @body.expressions.length then "\n#{ @body.compileWithDeclarations(o) }\n" else ''
|
code = if @body.expressions.length then "\n#{ @body.compileWithDeclarations(o) }\n" else ''
|
||||||
open = if @className then "(function() {\n#{@idt(1)}return function #{@className}(" else "function("
|
open = if @className then "(function() {\n#{@idt(1)}function #{@className}(" else "function("
|
||||||
close = if @className then "#{code and @idt(1)}};\n#{@tab}})()" else "#{code and @tab}}"
|
close = if @className then "#{code and @idt(1)}};\n#{@idt(1)}return #{@className};\n#{@tab}})()" else "#{code and @tab}}"
|
||||||
func = "#{open}#{ params.join(', ') }) {#{code}#{close}"
|
func = "#{open}#{ params.join(', ') }) {#{code}#{close}"
|
||||||
o.scope.endLevel()
|
o.scope.endLevel()
|
||||||
return "#{utility 'bind'}(#{func}, #{@context})" if @bound
|
return "#{utility 'bind'}(#{func}, #{@context})" if @bound
|
||||||
@@ -1102,10 +1103,7 @@ exports.While = class While extends Base
|
|||||||
|
|
||||||
constructor: (condition, opts) ->
|
constructor: (condition, opts) ->
|
||||||
super()
|
super()
|
||||||
if opts?.invert
|
@condition = if opts?.invert then condition.invert() else condition
|
||||||
condition = new Parens condition if condition instanceof Op
|
|
||||||
condition = new Op('!', condition)
|
|
||||||
@condition = condition
|
|
||||||
@guard = opts?.guard
|
@guard = opts?.guard
|
||||||
|
|
||||||
addBody: (body) ->
|
addBody: (body) ->
|
||||||
@@ -1124,9 +1122,9 @@ exports.While = class While extends Base
|
|||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
top = del(o, 'top') and not @returns
|
top = del(o, 'top') and not @returns
|
||||||
o.indent = @idt 1
|
o.indent = @idt 1
|
||||||
o.top = true
|
|
||||||
@condition.parenthetical = yes
|
@condition.parenthetical = yes
|
||||||
cond = @condition.compile(o)
|
cond = @condition.compile(o)
|
||||||
|
o.top = true
|
||||||
set = ''
|
set = ''
|
||||||
unless top
|
unless top
|
||||||
rvar = o.scope.freeVariable 'result'
|
rvar = o.scope.freeVariable 'result'
|
||||||
@@ -1183,9 +1181,6 @@ exports.Op = class Op extends Base
|
|||||||
isUnary: ->
|
isUnary: ->
|
||||||
not @second
|
not @second
|
||||||
|
|
||||||
isInvertible: ->
|
|
||||||
@operator in ['===', '!==']
|
|
||||||
|
|
||||||
isComplex: -> @operator isnt '!' or @first.isComplex()
|
isComplex: -> @operator isnt '!' or @first.isComplex()
|
||||||
|
|
||||||
isMutator: ->
|
isMutator: ->
|
||||||
@@ -1195,14 +1190,20 @@ exports.Op = class Op extends Base
|
|||||||
include(@CHAINABLE, @operator)
|
include(@CHAINABLE, @operator)
|
||||||
|
|
||||||
invert: ->
|
invert: ->
|
||||||
@operator = @INVERSIONS[@operator]
|
if @operator in ['===', '!==']
|
||||||
|
@operator = @INVERSIONS[@operator]
|
||||||
|
this
|
||||||
|
else if @second
|
||||||
|
new Parens(this).invert()
|
||||||
|
else
|
||||||
|
super()
|
||||||
|
|
||||||
toString: (idt) ->
|
toString: (idt) ->
|
||||||
super(idt, @constructor.name + ' ' + @operator)
|
super(idt, @constructor.name + ' ' + @operator)
|
||||||
|
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
return @compileChain(o) if @isChainable() and @first.unwrap() instanceof Op and @first.unwrap().isChainable()
|
return @compileChain(o) if @isChainable() and @first.unwrap() instanceof Op and @first.unwrap().isChainable()
|
||||||
return @compileAssignment(o) if indexOf(@ASSIGNMENT, @operator) >= 0
|
return @compileAssignment(o) if include @ASSIGNMENT, @operator
|
||||||
return @compileUnary(o) if @isUnary()
|
return @compileUnary(o) if @isUnary()
|
||||||
return @compileExistence(o) if @operator is '?'
|
return @compileExistence(o) if @operator is '?'
|
||||||
@first = new Parens @first if @first instanceof Op and @first.isMutator()
|
@first = new Parens @first if @first instanceof Op and @first.isMutator()
|
||||||
@@ -1239,10 +1240,9 @@ exports.Op = class Op extends Base
|
|||||||
|
|
||||||
# Compile a unary **Op**.
|
# Compile a unary **Op**.
|
||||||
compileUnary: (o) ->
|
compileUnary: (o) ->
|
||||||
space = if indexOf(@PREFIX_OPERATORS, @operator) >= 0 then ' ' else ''
|
space = if include @PREFIX_OPERATORS, @operator then ' ' else ''
|
||||||
parts = [@operator, space, @first.compile(o)]
|
parts = [@operator, space, @first.compile(o)]
|
||||||
parts = parts.reverse() if @flip
|
(if @flip then parts.reverse() else parts).join ''
|
||||||
parts.join('')
|
|
||||||
|
|
||||||
#### In
|
#### In
|
||||||
exports.In = class In extends Base
|
exports.In = class In extends Base
|
||||||
@@ -1516,14 +1516,7 @@ exports.If = class If extends Base
|
|||||||
|
|
||||||
constructor: (condition, @body, @tags) ->
|
constructor: (condition, @body, @tags) ->
|
||||||
@tags or= {}
|
@tags or= {}
|
||||||
if @tags.invert
|
@condition = if @tags.invert then condition.invert() else condition
|
||||||
op = condition instanceof Op
|
|
||||||
if op and condition.isInvertible()
|
|
||||||
condition.invert()
|
|
||||||
else
|
|
||||||
condition = new Parens condition if op and not condition.isUnary()
|
|
||||||
condition = new Op '!', condition
|
|
||||||
@condition = condition
|
|
||||||
@elseBody = null
|
@elseBody = null
|
||||||
@isChain = false
|
@isChain = false
|
||||||
|
|
||||||
@@ -1531,23 +1524,22 @@ exports.If = class If extends Base
|
|||||||
elseBodyNode: -> @elseBody?.unwrap()
|
elseBodyNode: -> @elseBody?.unwrap()
|
||||||
|
|
||||||
# Rewrite a chain of **Ifs** to add a default case as the final *else*.
|
# Rewrite a chain of **Ifs** to add a default case as the final *else*.
|
||||||
addElse: (elseBody, statement) ->
|
addElse: (elseBody) ->
|
||||||
if @isChain
|
if @isChain
|
||||||
@elseBodyNode().addElse elseBody, statement
|
@elseBodyNode().addElse elseBody
|
||||||
else
|
else
|
||||||
@isChain = elseBody instanceof If
|
@isChain = elseBody instanceof If
|
||||||
@elseBody = @ensureExpressions elseBody
|
@elseBody = @ensureExpressions elseBody
|
||||||
this
|
this
|
||||||
|
|
||||||
# The **If** only compiles into a statement if either of its bodies needs
|
# The **If** only compiles into a statement if either of its bodies needs
|
||||||
# to be a statement. Otherwise a conditional operator is safe.
|
# to be a statement. Otherwise a conditional operator is safe.
|
||||||
isStatement: (o) ->
|
isStatement: (o) ->
|
||||||
@statement or= !!((o and o.top) or @bodyNode().isStatement(o) or (@elseBody and @elseBodyNode().isStatement(o)))
|
@statement or= o?.top or @bodyNode().isStatement(o) or @elseBodyNode()?.isStatement(o)
|
||||||
|
|
||||||
compileCondition: (o) ->
|
compileCondition: (o) ->
|
||||||
conditions = flatten [@condition]
|
@condition.parenthetical = yes
|
||||||
conditions[0].parenthetical = yes if conditions.length is 1
|
@condition.compile o
|
||||||
(cond.compile(o) for cond in conditions).join(' || ')
|
|
||||||
|
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
if @isStatement o then @compileStatement o else @compileExpression o
|
if @isStatement o then @compileStatement o else @compileExpression o
|
||||||
@@ -1571,16 +1563,13 @@ exports.If = class If extends Base
|
|||||||
condO = merge o
|
condO = merge o
|
||||||
o.indent = @idt 1
|
o.indent = @idt 1
|
||||||
o.top = true
|
o.top = true
|
||||||
ifDent = if child or (top and not @isStatement(o)) then '' else @idt()
|
ifPart = "if (#{ @compileCondition condO }) {\n#{ @body.compile o }\n#{@tab}}"
|
||||||
comDent = if child then @idt() else ''
|
ifPart = @tab + ifPart unless child
|
||||||
body = @body.compile(o)
|
|
||||||
ifPart = "#{ifDent}if (#{ @compileCondition(condO) }) {\n#{body}\n#{@tab}}"
|
|
||||||
return ifPart unless @elseBody
|
return ifPart unless @elseBody
|
||||||
elsePart = if @isChain
|
ifPart + if @isChain
|
||||||
' else ' + @elseBodyNode().compile(merge(o, {indent: @idt(), chainChild: true}))
|
' else ' + @elseBodyNode().compile merge o, indent: @tab, chainChild: true
|
||||||
else
|
else
|
||||||
" else {\n#{ @elseBody.compile(o) }\n#{@tab}}"
|
" else {\n#{ @elseBody.compile(o) }\n#{@tab}}"
|
||||||
"#{ifPart}#{elsePart}"
|
|
||||||
|
|
||||||
# Compile the If as a conditional operator.
|
# Compile the If as a conditional operator.
|
||||||
compileExpression: (o) ->
|
compileExpression: (o) ->
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ helpers.extend global, quit: -> process.exit(0)
|
|||||||
# of exiting.
|
# of exiting.
|
||||||
run = (buffer) ->
|
run = (buffer) ->
|
||||||
try
|
try
|
||||||
val = CoffeeScript.eval buffer.toString(), noWrap: true, globals: true, fileName: 'repl'
|
val = CoffeeScript.eval buffer.toString(), wrap: false, globals: true, fileName: 'repl'
|
||||||
puts inspect val if val isnt undefined
|
puts inspect val if val isnt undefined
|
||||||
catch err
|
catch err
|
||||||
puts err.stack or err.toString()
|
puts err.stack or err.toString()
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@
|
|||||||
# If preceded by an `IMPLICIT_FUNC`, indicates a function invocation.
|
# If preceded by an `IMPLICIT_FUNC`, indicates a function invocation.
|
||||||
IMPLICIT_CALL = [
|
IMPLICIT_CALL = [
|
||||||
'IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS'
|
'IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS'
|
||||||
'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'NULL', 'UNARY', 'TRUE', 'FALSE'
|
'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'UNARY',
|
||||||
'@', '->', '=>', '[', '(', '{'
|
'@', '->', '=>', '[', '(', '{'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -27,3 +27,7 @@ tester = ->
|
|||||||
this
|
this
|
||||||
|
|
||||||
ok tester().example() is 'example function'
|
ok tester().example() is 'example function'
|
||||||
|
|
||||||
|
|
||||||
|
try throw CoffeeScript.tokens 'in = 1'
|
||||||
|
catch e then eq e.message, 'Reserved word "in" on line 1 can\'t be assigned'
|
||||||
|
|||||||
@@ -2,17 +2,17 @@
|
|||||||
CoffeeScript = require('./../lib/coffee-script')
|
CoffeeScript = require('./../lib/coffee-script')
|
||||||
Lexer = require('./../lib/lexer')
|
Lexer = require('./../lib/lexer')
|
||||||
|
|
||||||
js = CoffeeScript.compile("one\r\ntwo", {noWrap: on})
|
js = CoffeeScript.compile("one\r\ntwo", {wrap: off})
|
||||||
|
|
||||||
ok js is "one;\ntwo;"
|
ok js is "one;\ntwo;"
|
||||||
|
|
||||||
|
|
||||||
global.resultArray = []
|
global.resultArray = []
|
||||||
CoffeeScript.run("resultArray.push i for i of global", {noWrap: on, globals: on, fileName: 'tests'})
|
CoffeeScript.run("resultArray.push i for i of global", {wrap: off, globals: on, fileName: 'tests'})
|
||||||
|
|
||||||
ok 'setInterval' in global.resultArray
|
ok 'setInterval' in global.resultArray
|
||||||
|
|
||||||
ok 'passed' is CoffeeScript.eval '"passed"', noWrap: on, globals: on, fileName: 'tests'
|
ok 'passed' is CoffeeScript.eval '"passed"', wrap: off, globals: on, fileName: 'tests'
|
||||||
|
|
||||||
#750
|
#750
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -47,3 +47,7 @@ loop
|
|||||||
list.push i * 2
|
list.push i * 2
|
||||||
|
|
||||||
ok list.join(' ') is '8 6 4 2'
|
ok list.join(' ') is '8 6 4 2'
|
||||||
|
|
||||||
|
|
||||||
|
#759: `if` within `while` condition
|
||||||
|
2 while if 1 then 0
|
||||||
|
|||||||
Reference in New Issue
Block a user