merging master changes into symbology

This commit is contained in:
Jeremy Ashkenas 2010-07-25 00:15:12 -07:00
parent a0b2b78962
commit 6b0418a74a
14 changed files with 339 additions and 355 deletions

View File

@ -1,4 +1,4 @@
(function(){
(function() {
var CoffeeScript, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks;
fs = require('fs');
path = require('path');
@ -17,12 +17,11 @@
action = _a[0];
description = _a[1];
}
tasks[name] = {
return (tasks[name] = {
name: name,
description: description,
action: action
};
return tasks[name];
});
},
option: function(letter, flag, description) {
return switches.push([letter, flag, description]);

View File

@ -1,4 +1,4 @@
(function(){
(function() {
var Lexer, compile, helpers, lexer, parser, path, processScripts;
if (typeof process !== "undefined" && process !== null) {
path = require('path');
@ -51,8 +51,7 @@
},
setInput: function(tokens) {
this.tokens = tokens;
this.pos = 0;
return this.pos;
return (this.pos = 0);
},
upcomingInput: function() {
return "";

View File

@ -1,4 +1,4 @@
(function(){
(function() {
var BANNER, CoffeeScript, SWITCHES, _a, compileOptions, compileScript, compileScripts, compileStdio, exec, fs, lint, optionParser, options, optparse, parseOptions, path, printTokens, sources, spawn, usage, version, watch, writeJs;
fs = require('fs');
path = require('path');
@ -195,8 +195,7 @@
options.compile = options.compile || !!o.output;
options.run = !(o.compile || o.print || o.lint);
options.print = !!(o.print || (o.eval || o.stdio && o.compile));
sources = options.arguments;
return sources;
return (sources = options.arguments);
};
compileOptions = function(source) {
var o;

View File

@ -1,4 +1,4 @@
(function(){
(function() {
var Parser, _a, _b, _c, _d, _e, _f, _g, _h, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
var __hasProp = Object.prototype.hasOwnProperty;
Parser = require('jison').Parser;

View File

@ -1,4 +1,4 @@
(function(){
(function() {
var compact, count, del, ends, extend, flatten, helpers, include, indexOf, merge, starts;
if (!(typeof process !== "undefined" && process !== null)) {
this.exports = this;

View File

@ -1,4 +1,4 @@
(function(){
(function() {
var _a, key, val;
var __hasProp = Object.prototype.hasOwnProperty;
_a = require('./coffee-script');

View File

@ -1,4 +1,4 @@
(function(){
(function() {
var ASSIGNED, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, CONVERSIONS, HEREDOC, HEREDOC_INDENT, IDENTIFIER, INTERPOLATION, JS_CLEANER, JS_FORBIDDEN, JS_KEYWORDS, LAST_DENT, LAST_DENTS, LINE_BREAK, Lexer, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX_END, REGEX_ESCAPE, REGEX_INTERPOLATION, REGEX_START, RESERVED, Rewriter, STRING_NEWLINES, WHITESPACE, _a, _b, _c, compact, count, helpers, include, starts;
var __slice = Array.prototype.slice;
if (typeof process !== "undefined" && process !== null) {
@ -219,8 +219,7 @@
};
Lexer.prototype.balancedToken = function() {
var delimited;
var _d = arguments.length, _e = _d >= 1;
delimited = __slice.call(arguments, 0, _d - 0);
delimited = __slice.call(arguments, 0);
return this.balancedString(this.chunk, delimited);
};
Lexer.prototype.lineToken = function() {
@ -387,8 +386,7 @@
} else if (_d === ')') {
tok[0] = 'PARAM_END';
} else if (_d === '(' || _d === 'CALL_START') {
tok[0] = 'PARAM_START';
return tok[0];
return (tok[0] = 'PARAM_START');
}
}
return true;
@ -543,8 +541,7 @@
return null;
}
if (typeof newTag !== "undefined" && newTag !== null) {
tok[0] = newTag;
return tok[0];
return (tok[0] = newTag);
}
return tok[0];
};
@ -554,8 +551,7 @@
return null;
}
if (typeof val !== "undefined" && val !== null) {
tok[1] = val;
return tok[1];
return (tok[1] = val);
}
return tok[1];
};

View File

@ -1,7 +1,7 @@
(function(){
(function() {
var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, CommentNode, DOUBLE_PARENS, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IS_STRING, IfNode, InNode, IndexNode, LiteralNode, NUMBER, ObjectNode, OpNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, SIMPLENUM, Scope, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, UTILITIES, ValueNode, WhileNode, _a, compact, del, ends, flatten, helpers, include, indexOf, literal, merge, starts, utility;
var __extends = function(child, parent) {
var ctor = function(){ };
var ctor = function(){};
ctor.prototype = parent.prototype;
child.prototype = new ctor();
child.prototype.constructor = child;
@ -203,11 +203,6 @@
this.expressions[idx] = last.makeReturn();
return this;
};
Expressions.prototype.rewriteThis = function() {
return this.traverseChildren(false, function(child) {
return child instanceof ValueNode && child.base.value === 'this' ? (child.base = literal('_this')) : null;
});
};
Expressions.prototype.compile = function(o) {
o = o || {};
return o.scope ? Expressions.__superClass__.compile.call(this, o) : this.compileRoot(o);
@ -230,7 +225,7 @@
code = this.compileWithDeclarations(o);
code = code.replace(TRAILING_WHITESPACE, '');
code = code.replace(DOUBLE_PARENS, '($1)');
return o.noWrap ? code : ("(function(){\n" + code + "\n})();\n");
return o.noWrap ? code : ("(function() {\n" + code + "\n})();\n");
};
Expressions.prototype.compileWithDeclarations = function(o) {
var code;
@ -399,8 +394,7 @@
part = prop.compile(o);
baseline += part;
complete += part;
this.last = part;
return this.last;
return (this.last = part);
}
}).call(this);
}
@ -452,7 +446,7 @@
CallNode.prototype.superReference = function(o) {
var meth, methname;
methname = o.scope.method.name;
meth = (function() {
return (meth = (function() {
if (o.scope.method.proto) {
return "" + (o.scope.method.proto) + ".__superClass__." + methname;
} else if (methname) {
@ -460,8 +454,7 @@
} else {
throw new Error("cannot call super on an anonymous function.");
}
})();
return meth;
})());
};
CallNode.prototype.compileNode = function(o) {
var _b, _c, _d, _e, _f, _g, _h, arg, args, compilation;
@ -500,7 +493,7 @@
}
if (this.isNew) {
utility('extends');
return "(function() {\n" + (this.idt(1)) + "var ctor = function(){ };\n" + (this.idt(1)) + "__extends(ctor, " + meth + ");\n" + (this.idt(1)) + "return " + (meth) + ".apply(new ctor, " + (this.compileSplatArguments(o)) + ");\n" + this.tab + "}).call(this)";
return "(function() {\n" + (this.idt(1)) + "var ctor = function(){};\n" + (this.idt(1)) + "__extends(ctor, " + meth + ");\n" + (this.idt(1)) + "return " + (meth) + ".apply(new ctor, " + (this.compileSplatArguments(o)) + ");\n" + this.tab + "}).call(this)";
} else {
return "" + (this.prefix()) + (meth) + ".apply(" + obj + ", " + (this.compileSplatArguments(o)) + ")";
}
@ -641,7 +634,7 @@
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);
return "(function(){" + (pre) + "\n" + (idt) + "for (" + body + ")" + post + "}).call(this)";
return "(function() {" + (pre) + "\n" + (idt) + "for (" + body + ")" + post + "}).call(this)";
};
return RangeNode;
})();
@ -841,7 +834,11 @@
return this.variable instanceof ValueNode;
};
AssignNode.prototype.makeReturn = function() {
return new Expressions([this, new ReturnNode(this.variable)]);
if (this.isStatement()) {
return new Expressions([this, new ReturnNode(this.variable)]);
} else {
return AssignNode.__superClass__.makeReturn.call(this);
}
};
AssignNode.prototype.isStatement = function() {
return this.isValue() && (this.variable.isArray() || this.variable.isObject());
@ -952,7 +949,7 @@
top = del(o, 'top');
o.scope = sharedScope || new Scope(o.scope, this.body, this);
o.top = true;
o.indent = this.idt(this.bound ? 2 : 1);
o.indent = this.idt(1);
del(o, 'noWrap');
del(o, 'globals');
i = 0;
@ -983,23 +980,17 @@
return _e;
})();
this.body.makeReturn();
if (this.bound) {
this.body.rewriteThis();
}
_j = params;
for (_i = 0, _k = _j.length; _i < _k; _i++) {
param = _j[_i];
(o.scope.parameter(param));
}
code = this.body.expressions.length ? ("\n" + (this.body.compileWithDeclarations(o)) + "\n") : '';
func = ("function(" + (params.join(', ')) + ") {" + code + (code && this.idt(this.bound ? 1 : 0)) + "}");
if (top && !this.bound) {
func = ("(" + func + ")");
func = ("function(" + (params.join(', ')) + ") {" + code + (code && this.tab) + "}");
if (this.bound) {
return ("" + (utility('bind')) + "(" + func + ", this)");
}
if (!(this.bound)) {
return func;
}
return "(function(_this) {\n" + (this.idt(1)) + "return " + func + "\n" + this.tab + "})(this)";
return top ? ("(" + func + ")") : func;
};
CodeNode.prototype.topSensitive = function() {
return true;
@ -1040,20 +1031,24 @@
return (typeof (_b = this.index) !== "undefined" && _b !== null) ? this.compileParam(o) : this.name.compile(o);
};
SplatNode.prototype.compileParam = function(o) {
var _b, _c, idx, len, name, pos, trailing, variadic;
var _b, _c, end, idx, len, name, pos, trailing, variadic;
name = this.name.compile(o);
o.scope.find(name);
len = o.scope.freeVariable();
o.scope.assign(len, "arguments.length");
variadic = o.scope.freeVariable();
o.scope.assign(variadic, ("" + len + " >= " + this.arglength));
_b = this.trailings;
for (idx = 0, _c = _b.length; idx < _c; idx++) {
trailing = _b[idx];
pos = this.trailings.length - idx;
o.scope.assign(trailing.compile(o), ("arguments[" + variadic + " ? " + len + " - " + pos + " : " + (this.index + idx) + "]"));
end = '';
if (this.trailings.length) {
len = o.scope.freeVariable();
o.scope.assign(len, "arguments.length");
variadic = o.scope.freeVariable();
o.scope.assign(variadic, ("" + len + " >= " + this.arglength));
end = this.trailings.length ? (", " + len + " - " + (this.trailings.length)) : null;
_b = this.trailings;
for (idx = 0, _c = _b.length; idx < _c; idx++) {
trailing = _b[idx];
pos = this.trailings.length - idx;
o.scope.assign(trailing.compile(o), ("arguments[" + variadic + " ? " + len + " - " + pos + " : " + (this.index + idx) + "]"));
}
}
return "" + name + " = " + (utility('slice')) + ".call(arguments, " + this.index + ", " + len + " - " + (this.trailings.length) + ")";
return "" + name + " = " + (utility('slice')) + ".call(arguments, " + this.index + end + ")";
};
SplatNode.prototype.compileValue = function(o, name, index, trailings) {
var trail;
@ -1681,7 +1676,8 @@
}
});
UTILITIES = {
'extends': "function(child, parent) {\n var ctor = function(){ };\n ctor.prototype = parent.prototype;\n child.prototype = new ctor();\n child.prototype.constructor = child;\n if (typeof parent.extended === \"function\") parent.extended(child);\n child.__superClass__ = parent.prototype;\n }",
'extends': "function(child, parent) {\n var ctor = function(){};\n ctor.prototype = parent.prototype;\n child.prototype = new ctor();\n child.prototype.constructor = child;\n if (typeof parent.extended === \"function\") parent.extended(child);\n child.__superClass__ = parent.prototype;\n }",
bind: "function(func, context) {\n return function(){ return func.apply(context, arguments); };\n }",
hasProp: 'Object.prototype.hasOwnProperty',
slice: 'Array.prototype.slice'
};

View File

@ -1,4 +1,4 @@
(function(){
(function() {
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments;
exports.OptionParser = (function() {
OptionParser = function(rules, banner) {

View File

@ -1,4 +1,4 @@
(function(){
(function() {
var CoffeeScript, helpers, readline, repl, run, stdio;
CoffeeScript = require('./coffee-script');
helpers = require('./helpers').helpers;

View File

@ -1,6 +1,8 @@
(function(){
(function() {
var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, INVERSES, Rewriter, SINGLE_CLOSERS, SINGLE_LINERS, _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, helpers, include, pair;
var __hasProp = Object.prototype.hasOwnProperty;
var __bind = function(func, context) {
return function(){ return func.apply(context, arguments); };
}, __hasProp = Object.prototype.hasOwnProperty;
if (typeof process !== "undefined" && process !== null) {
_a = require('./helpers');
helpers = _a.helpers;
@ -38,30 +40,28 @@
return true;
};
Rewriter.prototype.adjustComments = function() {
return this.scanTokens((function(_this) {
return function(prev, token, post, i) {
var _c, _d, after, before;
if (!(token[0] === 'HERECOMMENT')) {
return 1;
}
_c = [_this.tokens[i - 2], _this.tokens[i + 2]];
before = _c[0];
after = _c[1];
if (after && after[0] === 'INDENT') {
_this.tokens.splice(i + 2, 1);
before && before[0] === 'OUTDENT' && post && (prev[0] === post[0]) && (post[0] === 'TERMINATOR') ? _this.tokens.splice(i - 2, 1) : _this.tokens.splice(i, 0, after);
} else if (prev && !('TERMINATOR' === (_d = prev[0]) || 'INDENT' === _d || 'OUTDENT' === _d)) {
if (post && post[0] === 'TERMINATOR' && after && after[0] === 'OUTDENT') {
_this.tokens.splice.apply(_this.tokens, [i + 2, 0].concat(_this.tokens.splice(i, 2)));
_this.tokens[i + 2][0] !== 'TERMINATOR' ? _this.tokens.splice(i + 2, 0, ['TERMINATOR', "\n", prev[2]]) : null;
} else {
_this.tokens.splice(i, 0, ['TERMINATOR', "\n", prev[2]]);
}
return 2;
}
return this.scanTokens(__bind(function(prev, token, post, i) {
var _c, _d, after, before;
if (!(token[0] === 'HERECOMMENT')) {
return 1;
}
})(this));
_c = [this.tokens[i - 2], this.tokens[i + 2]];
before = _c[0];
after = _c[1];
if (after && after[0] === 'INDENT') {
this.tokens.splice(i + 2, 1);
before && before[0] === 'OUTDENT' && post && (prev[0] === post[0]) && (post[0] === 'TERMINATOR') ? this.tokens.splice(i - 2, 1) : this.tokens.splice(i, 0, after);
} else if (prev && !('TERMINATOR' === (_d = prev[0]) || 'INDENT' === _d || 'OUTDENT' === _d)) {
if (post && post[0] === 'TERMINATOR' && after && after[0] === 'OUTDENT') {
this.tokens.splice.apply(this.tokens, [i + 2, 0].concat(this.tokens.splice(i, 2)));
this.tokens[i + 2][0] !== 'TERMINATOR' ? this.tokens.splice(i + 2, 0, ['TERMINATOR', "\n", prev[2]]) : null;
} else {
this.tokens.splice(i, 0, ['TERMINATOR', "\n", prev[2]]);
}
return 2;
}
return 1;
}, this));
};
Rewriter.prototype.removeLeadingNewlines = function() {
var _c;
@ -72,242 +72,226 @@
return _c;
};
Rewriter.prototype.removeMidExpressionNewlines = function() {
return this.scanTokens((function(_this) {
return function(prev, token, post, i) {
if (!(post && include(EXPRESSION_CLOSE, post[0]) && token[0] === 'TERMINATOR')) {
return 1;
}
_this.tokens.splice(i, 1);
return 0;
return this.scanTokens(__bind(function(prev, token, post, i) {
if (!(post && include(EXPRESSION_CLOSE, post[0]) && token[0] === 'TERMINATOR')) {
return 1;
}
})(this));
this.tokens.splice(i, 1);
return 0;
}, this));
};
Rewriter.prototype.closeOpenCallsAndIndexes = function() {
var brackets, parens;
parens = [0];
brackets = [0];
return this.scanTokens((function(_this) {
return function(prev, token, post, i) {
var _c;
if ((_c = token[0]) === 'CALL_START') {
parens.push(0);
} else if (_c === 'INDEX_START') {
brackets.push(0);
} else if (_c === '(') {
parens[parens.length - 1] += 1;
} else if (_c === '[') {
brackets[brackets.length - 1] += 1;
} else if (_c === ')') {
if (parens[parens.length - 1] === 0) {
parens.pop();
token[0] = 'CALL_END';
} else {
parens[parens.length - 1] -= 1;
}
} else if (_c === ']') {
if (brackets[brackets.length - 1] === 0) {
brackets.pop();
token[0] = 'INDEX_END';
} else {
brackets[brackets.length - 1] -= 1;
}
return this.scanTokens(__bind(function(prev, token, post, i) {
var _c;
if ((_c = token[0]) === 'CALL_START') {
parens.push(0);
} else if (_c === 'INDEX_START') {
brackets.push(0);
} else if (_c === '(') {
parens[parens.length - 1] += 1;
} else if (_c === '[') {
brackets[brackets.length - 1] += 1;
} else if (_c === ')') {
if (parens[parens.length - 1] === 0) {
parens.pop();
token[0] = 'CALL_END';
} else {
parens[parens.length - 1] -= 1;
}
} else if (_c === ']') {
if (brackets[brackets.length - 1] === 0) {
brackets.pop();
token[0] = 'INDEX_END';
} else {
brackets[brackets.length - 1] -= 1;
}
return 1;
}
})(this));
return 1;
}, this));
};
Rewriter.prototype.addImplicitBraces = function() {
var closeBrackets, stack;
stack = [0];
closeBrackets = (function(_this) {
return function(i) {
var _c, len, size, tmp;
len = stack.length - 1;
_c = stack[len];
for (tmp = 0; (0 <= _c ? tmp < _c : tmp > _c); (0 <= _c ? tmp += 1 : tmp -= 1)) {
_this.tokens.splice(i, 0, ['}', '}', _this.tokens[i][2]]);
closeBrackets = __bind(function(i) {
var _c, len, size, tmp;
len = stack.length - 1;
_c = stack[len];
for (tmp = 0; (0 <= _c ? tmp < _c : tmp > _c); (0 <= _c ? tmp += 1 : tmp -= 1)) {
this.tokens.splice(i, 0, ['}', '}', this.tokens[i][2]]);
}
size = stack[len] + 1;
stack[len] = 0;
return size;
}, this);
return this.scanTokens(__bind(function(prev, token, post, i) {
var after, before, idx, len, open, size, tag;
tag = token[0];
len = stack.length - 1;
before = this.tokens[i - 2];
after = this.tokens[i + 2];
open = stack[len] > 0;
if (include(EXPRESSION_START, tag)) {
stack.push(tag === '{' ? 1 : 0);
if (tag === '{' && post && post[0] === 'INDENT') {
return 2;
}
size = stack[len] + 1;
stack[len] = 0;
} else if (include(EXPRESSION_END, tag)) {
if (tag === 'OUTDENT' && post && post[0] === '}') {
return 1;
}
stack[len - 1] += stack.pop();
if (tag === '}') {
stack[len - 1] -= 1;
}
} else if (tag === ':' && !open) {
idx = before && before[0] === '@' ? i - 2 : i - 1;
this.tokens.splice(idx, 0, ['{', '{', token[2]]);
stack[stack.length - 1] += 1;
return 2;
} else if (tag === 'TERMINATOR' && !((after && after[0] === ':') || (post && post[0] === '@' && this.tokens[i + 3] && this.tokens[i + 3][0] === ':'))) {
size = closeBrackets(i);
return size;
}
})(this);
return this.scanTokens((function(_this) {
return function(prev, token, post, i) {
var after, before, idx, len, open, size, tag;
tag = token[0];
len = stack.length - 1;
before = _this.tokens[i - 2];
after = _this.tokens[i + 2];
open = stack[len] > 0;
if (include(EXPRESSION_START, tag)) {
stack.push(tag === '{' ? 1 : 0);
if (tag === '{' && post && post[0] === 'INDENT') {
return 2;
}
} else if (include(EXPRESSION_END, tag)) {
if (tag === 'OUTDENT' && post && post[0] === '}') {
return 1;
}
stack[len - 1] += stack.pop();
if (tag === '}') {
stack[len - 1] -= 1;
}
} else if (tag === ':' && !open) {
idx = before && before[0] === '@' ? i - 2 : i - 1;
_this.tokens.splice(idx, 0, ['{', '{', token[2]]);
stack[stack.length - 1] += 1;
return 2;
} else if (tag === 'TERMINATOR' && !((after && after[0] === ':') || (post && post[0] === '@' && _this.tokens[i + 3] && _this.tokens[i + 3][0] === ':'))) {
size = closeBrackets(i);
return size;
}
return 1;
}
})(this));
return 1;
}, this));
};
Rewriter.prototype.addImplicitParentheses = function() {
var closeCalls, stack;
stack = [0];
closeCalls = (function(_this) {
return function(i) {
var _c, size, tmp;
_c = stack[stack.length - 1];
for (tmp = 0; (0 <= _c ? tmp < _c : tmp > _c); (0 <= _c ? tmp += 1 : tmp -= 1)) {
_this.tokens.splice(i, 0, ['CALL_END', ')', _this.tokens[i][2]]);
}
size = stack[stack.length - 1] + 1;
stack[stack.length - 1] = 0;
return size;
closeCalls = __bind(function(i) {
var _c, size, tmp;
_c = stack[stack.length - 1];
for (tmp = 0; (0 <= _c ? tmp < _c : tmp > _c); (0 <= _c ? tmp += 1 : tmp -= 1)) {
this.tokens.splice(i, 0, ['CALL_END', ')', this.tokens[i][2]]);
}
})(this);
return this.scanTokens((function(_this) {
return function(prev, token, post, i) {
var _c, _d, j, nx, open, size, tag;
tag = token[0];
if (tag === 'OUTDENT') {
stack[stack.length - 2] += stack.pop();
}
open = stack[stack.length - 1] > 0;
if (prev && prev.spaced && include(IMPLICIT_FUNC, prev[0]) && include(IMPLICIT_CALL, tag) && !(tag === '!' && (('IN' === (_c = post[0]) || 'OF' === _c)))) {
_this.tokens.splice(i, 0, ['CALL_START', '(', token[2]]);
stack[stack.length - 1] += 1;
if (include(EXPRESSION_START, tag)) {
stack.push(0);
}
return 2;
}
size = stack[stack.length - 1] + 1;
stack[stack.length - 1] = 0;
return size;
}, this);
return this.scanTokens(__bind(function(prev, token, post, i) {
var _c, _d, j, nx, open, size, tag;
tag = token[0];
if (tag === 'OUTDENT') {
stack[stack.length - 2] += stack.pop();
}
open = stack[stack.length - 1] > 0;
if (prev && prev.spaced && include(IMPLICIT_FUNC, prev[0]) && include(IMPLICIT_CALL, tag) && !(tag === '!' && (('IN' === (_c = post[0]) || 'OF' === _c)))) {
this.tokens.splice(i, 0, ['CALL_START', '(', token[2]]);
stack[stack.length - 1] += 1;
if (include(EXPRESSION_START, tag)) {
if (tag === 'INDENT' && !token.generated && open && !(prev && include(IMPLICIT_BLOCK, prev[0]))) {
size = closeCalls(i);
stack.push(0);
return size;
}
stack.push(0);
return 1;
}
if (open && !token.generated && prev[0] !== ',' && (!post || include(IMPLICIT_END, tag))) {
j = 1;
while ((typeof (_d = (nx = _this.tokens[i + j])) !== "undefined" && _d !== null) && include(IMPLICIT_END, nx[0])) {
j++;
}
if ((typeof nx !== "undefined" && nx !== null) && nx[0] === ',' && _this.tokens[i + j - 1][0] === 'OUTDENT') {
if (tag === 'TERMINATOR') {
_this.tokens.splice(i, 1);
}
} else {
size = closeCalls(i);
if (tag !== 'OUTDENT' && include(EXPRESSION_END, tag)) {
stack.pop();
}
return size;
}
}
if (tag !== 'OUTDENT' && include(EXPRESSION_END, tag)) {
stack[stack.length - 2] += stack.pop();
return 1;
return 2;
}
if (include(EXPRESSION_START, tag)) {
if (tag === 'INDENT' && !token.generated && open && !(prev && include(IMPLICIT_BLOCK, prev[0]))) {
size = closeCalls(i);
stack.push(0);
return size;
}
stack.push(0);
return 1;
}
})(this));
if (open && !token.generated && prev[0] !== ',' && (!post || include(IMPLICIT_END, tag))) {
j = 1;
while ((typeof (_d = (nx = this.tokens[i + j])) !== "undefined" && _d !== null) && include(IMPLICIT_END, nx[0])) {
j++;
}
if ((typeof nx !== "undefined" && nx !== null) && nx[0] === ',' && this.tokens[i + j - 1][0] === 'OUTDENT') {
if (tag === 'TERMINATOR') {
this.tokens.splice(i, 1);
}
} else {
size = closeCalls(i);
if (tag !== 'OUTDENT' && include(EXPRESSION_END, tag)) {
stack.pop();
}
return size;
}
}
if (tag !== 'OUTDENT' && include(EXPRESSION_END, tag)) {
stack[stack.length - 2] += stack.pop();
return 1;
}
return 1;
}, this));
};
Rewriter.prototype.addImplicitIndentation = function() {
return this.scanTokens((function(_this) {
return function(prev, token, post, i) {
var _c, idx, indent, insertion, outdent, parens, pre, starter, tok;
if (token[0] === 'ELSE' && prev[0] !== 'OUTDENT') {
_this.tokens.splice.apply(_this.tokens, [i, 0].concat(_this.indentation(token)));
return 2;
}
if (token[0] === 'CATCH' && (_this.tokens[i + 2][0] === 'TERMINATOR' || _this.tokens[i + 2][0] === 'FINALLY')) {
_this.tokens.splice.apply(_this.tokens, [i + 2, 0].concat(_this.indentation(token)));
return 4;
}
if (!(include(SINGLE_LINERS, token[0]) && post[0] !== 'INDENT' && !(token[0] === 'ELSE' && post[0] === 'IF'))) {
return 1;
}
starter = token[0];
_c = _this.indentation(token);
indent = _c[0];
outdent = _c[1];
indent.generated = (outdent.generated = true);
_this.tokens.splice(i + 1, 0, indent);
idx = i + 1;
parens = 0;
while (true) {
idx += 1;
tok = _this.tokens[idx];
pre = _this.tokens[idx - 1];
if ((!tok || (include(SINGLE_CLOSERS, tok[0]) && tok[1] !== ';' && parens === 0) || (tok[0] === ')' && parens === 0)) && !(tok[0] === 'ELSE' && !('IF' === starter || 'THEN' === starter))) {
insertion = pre[0] === "," ? idx - 1 : idx;
_this.tokens.splice(insertion, 0, outdent);
break;
}
if (tok[0] === '(') {
parens += 1;
}
if (tok[0] === ')') {
parens -= 1;
}
}
if (!(token[0] === 'THEN')) {
return 1;
}
_this.tokens.splice(i, 1);
return 0;
return this.scanTokens(__bind(function(prev, token, post, i) {
var _c, idx, indent, insertion, outdent, parens, pre, starter, tok;
if (token[0] === 'ELSE' && prev[0] !== 'OUTDENT') {
this.tokens.splice.apply(this.tokens, [i, 0].concat(this.indentation(token)));
return 2;
}
})(this));
if (token[0] === 'CATCH' && (this.tokens[i + 2][0] === 'TERMINATOR' || this.tokens[i + 2][0] === 'FINALLY')) {
this.tokens.splice.apply(this.tokens, [i + 2, 0].concat(this.indentation(token)));
return 4;
}
if (!(include(SINGLE_LINERS, token[0]) && post[0] !== 'INDENT' && !(token[0] === 'ELSE' && post[0] === 'IF'))) {
return 1;
}
starter = token[0];
_c = this.indentation(token);
indent = _c[0];
outdent = _c[1];
indent.generated = (outdent.generated = true);
this.tokens.splice(i + 1, 0, indent);
idx = i + 1;
parens = 0;
while (true) {
idx += 1;
tok = this.tokens[idx];
pre = this.tokens[idx - 1];
if ((!tok || (include(SINGLE_CLOSERS, tok[0]) && tok[1] !== ';' && parens === 0) || (tok[0] === ')' && parens === 0)) && !(tok[0] === 'ELSE' && !('IF' === starter || 'THEN' === starter))) {
insertion = pre[0] === "," ? idx - 1 : idx;
this.tokens.splice(insertion, 0, outdent);
break;
}
if (tok[0] === '(') {
parens += 1;
}
if (tok[0] === ')') {
parens -= 1;
}
}
if (!(token[0] === 'THEN')) {
return 1;
}
this.tokens.splice(i, 1);
return 0;
}, this));
};
Rewriter.prototype.ensureBalance = function(pairs) {
var _c, _d, key, levels, line, open, openLine, unclosed, value;
levels = {};
openLine = {};
this.scanTokens((function(_this) {
return function(prev, token, post, i) {
var _c, _d, _e, _f, close, open, pair;
_d = pairs;
for (_c = 0, _e = _d.length; _c < _e; _c++) {
pair = _d[_c];
_f = pair;
open = _f[0];
close = _f[1];
levels[open] = levels[open] || 0;
if (token[0] === open) {
if (levels[open] === 0) {
openLine[open] = token[2];
}
levels[open] += 1;
}
if (token[0] === close) {
levels[open] -= 1;
}
if (levels[open] < 0) {
throw new Error(("too many " + (token[1]) + " on line " + (token[2] + 1)));
this.scanTokens(__bind(function(prev, token, post, i) {
var _c, _d, _e, _f, close, open, pair;
_d = pairs;
for (_c = 0, _e = _d.length; _c < _e; _c++) {
pair = _d[_c];
_f = pair;
open = _f[0];
close = _f[1];
levels[open] = levels[open] || 0;
if (token[0] === open) {
if (levels[open] === 0) {
openLine[open] = token[2];
}
levels[open] += 1;
}
if (token[0] === close) {
levels[open] -= 1;
}
if (levels[open] < 0) {
throw new Error(("too many " + (token[1]) + " on line " + (token[2] + 1)));
}
return 1;
}
})(this));
return 1;
}, this));
unclosed = (function() {
_c = []; _d = levels;
for (key in _d) {
@ -333,41 +317,39 @@
val = _c[key];
(debt[key] = 0);
}
return this.scanTokens((function(_this) {
return function(prev, token, post, i) {
var inv, match, mtag, oppos, tag;
tag = token[0];
inv = INVERSES[token[0]];
if (include(EXPRESSION_START, tag)) {
stack.push(token);
return 1;
} else if (include(EXPRESSION_END, tag)) {
if (debt[inv] > 0) {
debt[inv] -= 1;
_this.tokens.splice(i, 1);
return 0;
} else {
match = stack.pop();
mtag = match[0];
oppos = INVERSES[mtag];
if (tag === oppos) {
return 1;
}
debt[mtag] += 1;
val = [oppos, mtag === 'INDENT' ? match[1] : oppos];
if ((_this.tokens[i + 2] == undefined ? undefined : _this.tokens[i + 2][0]) === mtag) {
_this.tokens.splice(i + 3, 0, val);
stack.push(match);
} else {
_this.tokens.splice(i, 0, val);
}
return this.scanTokens(__bind(function(prev, token, post, i) {
var inv, match, mtag, oppos, tag;
tag = token[0];
inv = INVERSES[token[0]];
if (include(EXPRESSION_START, tag)) {
stack.push(token);
return 1;
} else if (include(EXPRESSION_END, tag)) {
if (debt[inv] > 0) {
debt[inv] -= 1;
this.tokens.splice(i, 1);
return 0;
} else {
match = stack.pop();
mtag = match[0];
oppos = INVERSES[mtag];
if (tag === oppos) {
return 1;
}
} else {
debt[mtag] += 1;
val = [oppos, mtag === 'INDENT' ? match[1] : oppos];
if ((this.tokens[i + 2] == undefined ? undefined : this.tokens[i + 2][0]) === mtag) {
this.tokens.splice(i + 3, 0, val);
stack.push(match);
} else {
this.tokens.splice(i, 0, val);
}
return 1;
}
} else {
return 1;
}
})(this));
}, this));
};
Rewriter.prototype.indentation = function(token) {
return [['INDENT', 2, token[2]], ['OUTDENT', 2, token[2]]];

View File

@ -1,4 +1,4 @@
(function(){
(function() {
var Scope;
var __hasProp = Object.prototype.hasOwnProperty;
if (!(typeof process !== "undefined" && process !== null)) {
@ -41,8 +41,7 @@
return false;
};
Scope.prototype.parameter = function(name) {
this.variables[name] = 'param';
return this.variables[name];
return (this.variables[name] = 'param');
};
Scope.prototype.check = function(name) {
if (this.variables.hasOwnProperty(name)) {
@ -60,11 +59,10 @@
return this.tempVar;
};
Scope.prototype.assign = function(name, value) {
this.variables[name] = {
return (this.variables[name] = {
value: value,
assigned: true
};
return this.variables[name];
});
};
Scope.prototype.hasDeclarations = function(body) {
return body === this.expressions && this.any(function(k, val) {

View File

@ -185,12 +185,6 @@ exports.Expressions = class Expressions extends BaseNode
@expressions[idx] = last.makeReturn()
this
# A bound function uses a local `_this` variable instead of the real `this`.
rewriteThis: ->
@traverseChildren false, (child) ->
if child instanceof ValueNode and child.base.value is 'this'
child.base = literal '_this'
# An **Expressions** is the only node that can serve as the root.
compile: (o) ->
o or= {}
@ -204,12 +198,12 @@ exports.Expressions = class Expressions extends BaseNode
# It would be better not to generate them in the first place, but for now,
# clean up obvious double-parentheses.
compileRoot: (o) ->
o.indent = @tab = if o.noWrap then '' else TAB
o.scope = new Scope(null, this, null)
code = @compileWithDeclarations(o)
code = code.replace(TRAILING_WHITESPACE, '')
code = code.replace(DOUBLE_PARENS, '($1)')
if o.noWrap then code else "(function(){\n$code\n})();\n"
o.indent = @tab = if o.noWrap then '' else TAB
o.scope = new Scope(null, this, null)
code = @compileWithDeclarations(o)
code = code.replace(TRAILING_WHITESPACE, '')
code = code.replace(DOUBLE_PARENS, '($1)')
if o.noWrap then code else "(function() {\n$code\n})();\n"
# Compile the expressions body for the contents of a function, with
# declarations of all inner variables pushed up to the top.
@ -459,7 +453,7 @@ exports.CallNode = class CallNode extends BaseNode
utility 'extends'
"""
(function() {
${@idt(1)}var ctor = function(){ };
${@idt(1)}var ctor = function(){};
${@idt(1)}__extends(ctor, $meth);
${@idt(1)}return ${meth}.apply(new ctor, ${ @compileSplatArguments(o) });
$@tab}).call(this)
@ -589,8 +583,8 @@ exports.RangeNode = class RangeNode extends BaseNode
else
clause = "$@fromVar <= $@toVar ?"
body = "var $i = $@fromVar; $clause $i <$@equals $@toVar : $i >$@equals $@toVar; $clause $i += 1 : $i -= 1"
post = "{ ${result}.push($i) };\n${idt}return $result;\n$o.indent"
"(function(){${pre}\n${idt}for ($body)$post}).call(this)"
post = "{ ${result}.push($i) };\n${idt}return $result;\n$o.indent"
"(function() {${pre}\n${idt}for ($body)$post}).call(this)"
#### SliceNode
@ -764,7 +758,10 @@ exports.AssignNode = class AssignNode extends BaseNode
@variable instanceof ValueNode
makeReturn: ->
return new Expressions [this, new ReturnNode(@variable)]
if @isStatement()
return new Expressions [this, new ReturnNode(@variable)]
else
super()
isStatement: ->
@isValue() and (@variable.isArray() or @variable.isObject())
@ -866,7 +863,7 @@ exports.CodeNode = class CodeNode extends BaseNode
top = del o, 'top'
o.scope = sharedScope or new Scope(o.scope, @body, this)
o.top = true
o.indent = @idt(if @bound then 2 else 1)
o.indent = @idt(1)
del o, 'noWrap'
del o, 'globals'
i = 0
@ -886,13 +883,11 @@ exports.CodeNode = class CodeNode extends BaseNode
i += 1
params = (param.compile(o) for param in params)
@body.makeReturn()
@body.rewriteThis() if @bound
(o.scope.parameter(param)) for param in params
code = if @body.expressions.length then "\n${ @body.compileWithDeclarations(o) }\n" else ''
func = "function(${ params.join(', ') }) {$code${ code and @idt(if @bound then 1 else 0) }}"
func = "($func)" if top and not @bound
return func unless @bound
"(function(_this) {\n${@idt(1)}return $func\n$@tab})(this)"
func = "function(${ params.join(', ') }) {$code${ code and @tab }}"
return "${utility('bind')}($func, this)" if @bound
if top then "($func)" else func
topSensitive: ->
true
@ -927,14 +922,17 @@ exports.SplatNode = class SplatNode extends BaseNode
compileParam: (o) ->
name = @name.compile(o)
o.scope.find name
len = o.scope.freeVariable()
o.scope.assign len, "arguments.length"
variadic = o.scope.freeVariable()
o.scope.assign variadic, "$len >= $@arglength"
for trailing, idx in @trailings
pos = @trailings.length - idx
o.scope.assign(trailing.compile(o), "arguments[$variadic ? $len - $pos : ${@index + idx}]")
"$name = ${utility('slice')}.call(arguments, $@index, $len - ${@trailings.length})"
end = ''
if @trailings.length
len = o.scope.freeVariable()
o.scope.assign len, "arguments.length"
variadic = o.scope.freeVariable()
o.scope.assign variadic, "$len >= $@arglength"
end = if @trailings.length then ", $len - ${@trailings.length}"
for trailing, idx in @trailings
pos = @trailings.length - idx
o.scope.assign(trailing.compile(o), "arguments[$variadic ? $len - $pos : ${@index + idx}]")
"$name = ${utility('slice')}.call(arguments, $@index$end)"
# A compiling a splat as a destructuring assignment means slicing arguments
# from the right-hand-side's corresponding array.
@ -1487,7 +1485,7 @@ UTILITIES = {
# [goog.inherits](http://closure-library.googlecode.com/svn/docs/closureGoogBase.js.source.html#line1206).
extends: """
function(child, parent) {
var ctor = function(){ };
var ctor = function(){};
ctor.prototype = parent.prototype;
child.prototype = new ctor();
child.prototype.constructor = child;
@ -1496,6 +1494,13 @@ UTILITIES = {
}
"""
# Create a function bound to the current value of "this".
bind: """
function(func, context) {
return function(){ return func.apply(context, arguments); };
}
"""
# Shortcuts to speed up the lookup time for native functions.
hasProp: 'Object.prototype.hasOwnProperty'
slice: 'Array.prototype.slice'

View File

@ -19,17 +19,27 @@ ok y.x() is 3
obj = {
name: "Fred"
name: 'Fred'
bound: ->
(=> ok(this.name is "Fred"))()
(=> ok(this.name is 'Fred'))()
unbound: ->
(-> ok(!this.name?))()
nested: ->
(=>
(=>
(=>
ok this.name is 'Fred'
)()
)()
)()
}
obj.unbound()
obj.bound()
obj.nested()
# Python decorator style wrapper that memoizes any function