mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-02-18 03:21:20 -05:00
nodes: refactored and removed the notion of o.top in favor of LVL_TOP
This commit is contained in:
376
lib/nodes.js
376
lib/nodes.js
@@ -1,5 +1,5 @@
|
||||
(function() {
|
||||
var Accessor, ArrayLiteral, Assign, Base, Call, Class, Closure, Code, Comment, Existence, Expressions, Extends, For, IDENTIFIER, IS_STRING, If, In, Index, LVL_ACCESS, LVL_ASSIGN, LVL_COND, LVL_LIST, LVL_OP, LVL_PAREN, LVL_TOP, Literal, NO, NUMBER, ObjectLiteral, Op, Param, Parens, Push, Return, SIMPLENUM, Scope, Splat, Switch, TAB, THIS, TRAILING_WHITESPACE, Throw, Try, UTILITIES, Value, While, YES, _ref, compact, del, ends, extend, flatten, last, merge, starts, utility;
|
||||
var Accessor, ArrayLiteral, Assign, Base, Call, Class, Closure, Code, Comment, Existence, Expressions, Extends, For, IDENTIFIER, IS_STRING, If, In, Index, LVL_ACCESS, LVL_COND, LVL_LIST, LVL_OP, LVL_PAREN, LVL_TOP, Literal, NO, NUMBER, ObjectLiteral, Op, Param, Parens, Push, Return, SIMPLENUM, Scope, Splat, Switch, TAB, THIS, TRAILING_WHITESPACE, Throw, Try, UTILITIES, Value, While, YES, _ref, compact, del, ends, extend, flatten, last, merge, multident, starts, utility;
|
||||
var __extends = function(child, parent) {
|
||||
function ctor() { this.constructor = child; }
|
||||
ctor.prototype = parent.prototype;
|
||||
@@ -31,14 +31,14 @@
|
||||
return Base;
|
||||
})();
|
||||
Base.prototype.compile = function(o, lvl) {
|
||||
var top;
|
||||
var node;
|
||||
o = o ? extend({}, o) : {};
|
||||
if (lvl) {
|
||||
if (lvl != null) {
|
||||
o.level = lvl;
|
||||
}
|
||||
top = this.topSensitive ? o.top : del(o, 'top');
|
||||
this.tab = o.indent;
|
||||
return top || o.asStatement || this instanceof Comment || this.isPureStatement() || !this.isStatement(o) ? this.compileNode(o) : this.compileClosure(o);
|
||||
node = this.unfoldSoak(o) || this;
|
||||
node.tab = o.indent;
|
||||
return o.level === LVL_TOP || node.isPureStatement() || !node.isStatement(o) ? node.compileNode(o) : node.compileClosure(o);
|
||||
};
|
||||
Base.prototype.compileClosure = function(o) {
|
||||
if (this.containsPureStatement()) {
|
||||
@@ -60,7 +60,7 @@
|
||||
};
|
||||
Base.prototype.compileLoopReference = function(o, name) {
|
||||
var src, tmp;
|
||||
src = tmp = this.compile(o, LVL_ASSIGN);
|
||||
src = tmp = this.compile(o, LVL_LIST);
|
||||
if (!(NUMBER.test(src) || IDENTIFIER.test(src) && o.scope.check(src, {
|
||||
immediate: true
|
||||
}))) {
|
||||
@@ -98,7 +98,7 @@
|
||||
Base.prototype.toString = function(idt, override) {
|
||||
var _i, _len, _ref2, _result, child, children, klass;
|
||||
idt || (idt = '');
|
||||
children = (function() {
|
||||
children = ((function() {
|
||||
_ref2 = this.collectChildren();
|
||||
_result = [];
|
||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||
@@ -106,7 +106,7 @@
|
||||
_result.push(child.toString(idt + TAB));
|
||||
}
|
||||
return _result;
|
||||
}).call(this).join('');
|
||||
}).call(this)).join('');
|
||||
klass = override || this.constructor.name + (this.soakNode ? '?' : '');
|
||||
return '\n' + idt + klass + children;
|
||||
};
|
||||
@@ -155,7 +155,6 @@
|
||||
Base.prototype.isPureStatement = NO;
|
||||
Base.prototype.isComplex = YES;
|
||||
Base.prototype.isChainable = NO;
|
||||
Base.prototype.topSensitive = false;
|
||||
Base.prototype.unfoldSoak = NO;
|
||||
Base.prototype.assigns = NO;
|
||||
return Base;
|
||||
@@ -204,15 +203,16 @@
|
||||
};
|
||||
Expressions.prototype.compileNode = function(o) {
|
||||
var _i, _len, _ref2, _result, node;
|
||||
return (function() {
|
||||
this.tab = o.indent;
|
||||
return ((function() {
|
||||
_ref2 = this.expressions;
|
||||
_result = [];
|
||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||
node = _ref2[_i];
|
||||
_result.push(this.compileExpression(node, merge(o)));
|
||||
_result.push(this.compileExpression(node, o));
|
||||
}
|
||||
return _result;
|
||||
}).call(this).join('\n');
|
||||
}).call(this)).join('\n');
|
||||
};
|
||||
Expressions.prototype.compileRoot = function(o) {
|
||||
var code;
|
||||
@@ -224,20 +224,25 @@
|
||||
return o.bare ? code : "(function() {\n" + code + "\n}).call(this);\n";
|
||||
};
|
||||
Expressions.prototype.compileWithDeclarations = function(o) {
|
||||
var code;
|
||||
var code, scope;
|
||||
code = this.compileNode(o);
|
||||
if (o.scope.hasAssignments(this)) {
|
||||
code = "" + this.tab + "var " + (o.scope.compiledAssignments().replace(/\n/g, '$&' + this.tab)) + ";\n" + code;
|
||||
scope = o.scope;
|
||||
if (scope.hasAssignments(this)) {
|
||||
code = "" + this.tab + "var " + (multident(scope.compiledAssignments(), this.tab)) + ";\n" + code;
|
||||
}
|
||||
if (!o.globals && o.scope.hasDeclarations(this)) {
|
||||
code = "" + this.tab + "var " + (o.scope.compiledDeclarations()) + ";\n" + code;
|
||||
code = "" + this.tab + "var " + (scope.compiledDeclarations()) + ";\n" + code;
|
||||
}
|
||||
return code;
|
||||
};
|
||||
Expressions.prototype.compileExpression = function(node, o) {
|
||||
var code;
|
||||
o.top = node.tags.front = true;
|
||||
this.tab = o.indent;
|
||||
while (node !== (node = node.unwrap())) {
|
||||
|
||||
}
|
||||
node = node.unfoldSoak(o) || node;
|
||||
node.tags.front = true;
|
||||
o.level = LVL_TOP;
|
||||
code = node.compile(o);
|
||||
return node.isStatement(o) ? code : this.tab + code + ';';
|
||||
};
|
||||
@@ -262,19 +267,16 @@
|
||||
Literal.prototype.makeReturn = function() {
|
||||
return this.isStatement() ? this : Literal.__super__.makeReturn.call(this);
|
||||
};
|
||||
Literal.prototype.isStatement = function() {
|
||||
Literal.prototype.isPureStatement = function() {
|
||||
var _ref2;
|
||||
return (_ref2 = this.value) === 'break' || _ref2 === 'continue' || _ref2 === 'debugger';
|
||||
};
|
||||
Literal.prototype.isPureStatement = Literal.prototype.isStatement;
|
||||
Literal.prototype.isComplex = NO;
|
||||
Literal.prototype.assigns = function(name) {
|
||||
return name === this.value;
|
||||
};
|
||||
Literal.prototype.compileNode = function() {
|
||||
var val;
|
||||
val = this.value.reserved ? "\"" + this.value + "\"" : this.value;
|
||||
return this.isStatement() ? this.tab + val + ';' : val;
|
||||
Literal.prototype.compile = function() {
|
||||
return this.value.reserved ? "\"" + this.value + "\"" : this.value;
|
||||
};
|
||||
Literal.prototype.toString = function() {
|
||||
return ' "' + this.value + '"';
|
||||
@@ -301,15 +303,8 @@
|
||||
return expr && !(expr instanceof Return) ? expr.compile(o, lvl) : Return.__super__.compile.call(this, o, lvl);
|
||||
};
|
||||
Return.prototype.compileNode = function(o) {
|
||||
var expr;
|
||||
expr = '';
|
||||
if (this.expression) {
|
||||
if (this.expression.isStatement(o)) {
|
||||
o.asStatement = true;
|
||||
}
|
||||
expr = ' ' + this.expression.compile(o, LVL_PAREN);
|
||||
}
|
||||
return this.tab + 'return' + expr + ';';
|
||||
o.level = LVL_PAREN;
|
||||
return this.tab + ("return" + (this.expression ? ' ' + this.expression.compile(o) : '') + ";");
|
||||
};
|
||||
return Return;
|
||||
})();
|
||||
@@ -365,7 +360,7 @@
|
||||
return this.properties.length ? this : this.base;
|
||||
};
|
||||
Value.prototype.isStatement = function(o) {
|
||||
return this.base.isStatement(o) && !this.properties.length;
|
||||
return !this.properties.length && this.base.isStatement(o);
|
||||
};
|
||||
Value.prototype.isSimpleNumber = function() {
|
||||
return this.base instanceof Literal && SIMPLENUM.test(this.base.value);
|
||||
@@ -391,23 +386,17 @@
|
||||
}
|
||||
return [base.push(name), new Value(bref || base.base, [nref || name])];
|
||||
};
|
||||
Value.prototype.compile = function(o, lvl) {
|
||||
this.base.tags.front = this.tags.front;
|
||||
return !o.top || this.properties.length ? Value.__super__.compile.call(this, o, lvl) : this.base.compile(o, lvl);
|
||||
};
|
||||
Value.prototype.compileNode = function(o) {
|
||||
var _i, _len, code, ifn, prop, props;
|
||||
if (ifn = this.unfoldSoak(o)) {
|
||||
return ifn.compile(o);
|
||||
}
|
||||
var _i, _len, code, prop, props;
|
||||
this.base.tags.front = this.tags.front;
|
||||
props = this.properties;
|
||||
code = this.base.compile(o, props.length && LVL_ACCESS);
|
||||
code = this.base.compile(o, props.length ? LVL_ACCESS : null);
|
||||
if (props[0] instanceof Accessor && this.isSimpleNumber()) {
|
||||
code = "(" + code + ")";
|
||||
}
|
||||
for (_i = 0, _len = props.length; _i < _len; _i++) {
|
||||
prop = props[_i];
|
||||
(code += prop.compileNode(o));
|
||||
code += prop.compile(o);
|
||||
}
|
||||
return code;
|
||||
};
|
||||
@@ -451,10 +440,10 @@
|
||||
return Comment;
|
||||
})();
|
||||
__extends(Comment, Base);
|
||||
Comment.prototype.isStatement = YES;
|
||||
Comment.prototype.isPureStatement = YES;
|
||||
Comment.prototype.makeReturn = THIS;
|
||||
Comment.prototype.compileNode = function(o) {
|
||||
return this.tab + '/*' + this.comment.replace(/\n/g, '\n' + this.tab) + '*/';
|
||||
return this.tab + '/*' + multident(this.comment, this.tab) + '*/';
|
||||
};
|
||||
return Comment;
|
||||
})();
|
||||
@@ -543,11 +532,10 @@
|
||||
return ifn;
|
||||
};
|
||||
Call.prototype.compileNode = function(o) {
|
||||
var _i, _j, _len, _len2, _ref2, _ref3, _ref4, _result, arg, args, ifn;
|
||||
if (ifn = this.unfoldSoak(o)) {
|
||||
return ifn.compile(o);
|
||||
var _i, _j, _len, _len2, _ref2, _ref3, _ref4, _result, arg, args;
|
||||
if ((_ref2 = this.variable) != null) {
|
||||
_ref2.tags.front = this.tags.front;
|
||||
}
|
||||
(_ref2 = this.variable) != null ? _ref2.tags.front = this.tags.front : undefined;
|
||||
_ref3 = this.args;
|
||||
for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
|
||||
arg = _ref3[_i];
|
||||
@@ -555,7 +543,7 @@
|
||||
return this.compileSplat(o);
|
||||
}
|
||||
}
|
||||
args = (function() {
|
||||
args = ((function() {
|
||||
_ref4 = this.args;
|
||||
_result = [];
|
||||
for (_j = 0, _len2 = _ref4.length; _j < _len2; _j++) {
|
||||
@@ -563,7 +551,7 @@
|
||||
_result.push(arg.compile(o, LVL_LIST));
|
||||
}
|
||||
return _result;
|
||||
}).call(this).join(', ');
|
||||
}).call(this)).join(', ');
|
||||
return this.isSuper ? this.compileSuper(args, o) : (this.isNew ? 'new ' : '') + this.variable.compile(o, LVL_ACCESS) + ("(" + args + ")");
|
||||
};
|
||||
Call.prototype.compileSuper = function(args, o) {
|
||||
@@ -579,11 +567,11 @@
|
||||
base = Value.wrap(this.variable);
|
||||
if ((name = base.properties.pop()) && base.isComplex()) {
|
||||
ref = o.scope.freeVariable('this');
|
||||
fun = "(" + ref + " = " + (base.compile(o, LVL_ASSIGN)) + ")" + (name.compileNode(o));
|
||||
fun = "(" + ref + " = " + (base.compile(o, LVL_LIST)) + ")" + (name.compile(o));
|
||||
} else {
|
||||
fun = ref = base.compile(o, LVL_ACCESS);
|
||||
if (name) {
|
||||
fun += name.compileNode(o);
|
||||
fun += name.compile(o);
|
||||
}
|
||||
}
|
||||
return "" + fun + ".apply(" + ref + ", " + splatargs + ")";
|
||||
@@ -605,7 +593,7 @@
|
||||
})();
|
||||
__extends(Extends, Base);
|
||||
Extends.prototype.children = ['child', 'parent'];
|
||||
Extends.prototype.compileNode = function(o) {
|
||||
Extends.prototype.compile = function(o) {
|
||||
return new Call(new Value(new Literal(utility('extends'))), [this.child, this.parent]).compile(o);
|
||||
};
|
||||
return Extends;
|
||||
@@ -623,7 +611,7 @@
|
||||
})();
|
||||
__extends(Accessor, Base);
|
||||
Accessor.prototype.children = ['name'];
|
||||
Accessor.prototype.compileNode = function(o) {
|
||||
Accessor.prototype.compile = function(o) {
|
||||
var name;
|
||||
name = this.name.compile(o);
|
||||
return this.proto + (IS_STRING.test(name) ? "[" + name + "]" : "." + name);
|
||||
@@ -642,7 +630,7 @@
|
||||
})();
|
||||
__extends(Index, Base);
|
||||
Index.prototype.children = ['index'];
|
||||
Index.prototype.compileNode = function(o) {
|
||||
Index.prototype.compile = function(o) {
|
||||
return (this.proto ? '.prototype' : '') + ("[" + (this.index.compile(o, LVL_PAREN)) + "]");
|
||||
};
|
||||
Index.prototype.isComplex = function() {
|
||||
@@ -662,8 +650,7 @@
|
||||
__extends(ObjectLiteral, Base);
|
||||
ObjectLiteral.prototype.children = ['properties'];
|
||||
ObjectLiteral.prototype.compileNode = function(o) {
|
||||
var _i, _len, _ref2, _result, i, indent, join, lastNoncom, nonComments, obj, prop, props, top;
|
||||
top = del(o, 'top');
|
||||
var _i, _len, _ref2, _result, i, indent, join, lastNoncom, nonComments, obj, prop, props;
|
||||
o.indent = this.idt(1);
|
||||
nonComments = (function() {
|
||||
_ref2 = this.properties;
|
||||
@@ -779,14 +766,13 @@
|
||||
return this;
|
||||
};
|
||||
Class.prototype.compileNode = function(o) {
|
||||
var _i, _len, _ref2, _ref3, access, applied, apply, className, constScope, construct, constructor, extension, func, me, pname, prop, props, pvar, ref, returns, val, variable;
|
||||
var _i, _len, _ref2, _ref3, access, applied, apply, className, constScope, construct, constructor, extension, func, me, pname, prop, props, pvar, ref, val, variable;
|
||||
variable = this.variable;
|
||||
if (variable.value === '__temp__') {
|
||||
variable = new Literal(o.scope.freeVariable('ctor'));
|
||||
}
|
||||
extension = this.parent && new Extends(variable, this.parent);
|
||||
props = new Expressions;
|
||||
o.top = true;
|
||||
me = null;
|
||||
className = variable.compile(o);
|
||||
constScope = null;
|
||||
@@ -847,13 +833,18 @@
|
||||
if (me) {
|
||||
constructor.body.unshift(new Literal("" + me + " = this"));
|
||||
}
|
||||
construct = this.idt() + new Assign(variable, constructor).compile(merge(o, {
|
||||
sharedScope: constScope
|
||||
})) + ';';
|
||||
props = !props.empty() ? '\n' + props.compile(o) : '';
|
||||
extension = extension ? '\n' + this.idt() + extension.compile(o) + ';' : '';
|
||||
returns = this.returns ? '\n' + new Return(variable).compile(o) : '';
|
||||
return construct + extension + props + returns;
|
||||
o.sharedScope = constScope;
|
||||
construct = this.tab + new Assign(variable, constructor).compile(o) + ';';
|
||||
if (extension) {
|
||||
construct += '\n' + this.tab + extension.compile(o) + ';';
|
||||
}
|
||||
if (!props.empty()) {
|
||||
construct += '\n' + props.compile(o);
|
||||
}
|
||||
if (this.returns) {
|
||||
construct += '\n' + new Return(variable).compile(o);
|
||||
}
|
||||
return construct;
|
||||
};
|
||||
return Class;
|
||||
})();
|
||||
@@ -872,29 +863,28 @@
|
||||
Assign.prototype.METHOD_DEF = /^(?:(\S+)\.prototype\.)?([$A-Za-z_][$\w]*)$/;
|
||||
Assign.prototype.CONDITIONAL = ['||=', '&&=', '?='];
|
||||
Assign.prototype.children = ['variable', 'value'];
|
||||
Assign.prototype.topSensitive = true;
|
||||
Assign.prototype.assigns = function(name) {
|
||||
return this[this.context === 'object' ? 'value' : 'variable'].assigns(name);
|
||||
};
|
||||
Assign.prototype.unfoldSoak = function(o) {
|
||||
return If.unfoldSoak(o, this, 'variable');
|
||||
};
|
||||
Assign.prototype.compileNode = function(o) {
|
||||
var _ref2, ifn, isValue, match, name, stmt, top, val;
|
||||
var _ref2, isValue, match, name, val;
|
||||
if (isValue = this.variable instanceof Value) {
|
||||
if (this.variable.isArray() || this.variable.isObject()) {
|
||||
return this.compilePatternMatch(o);
|
||||
}
|
||||
if (ifn = If.unfoldSoak(o, this, 'variable')) {
|
||||
delete o.top;
|
||||
return ifn.compile(o);
|
||||
}
|
||||
if (_ref2 = this.context, __indexOf.call(this.CONDITIONAL, _ref2) >= 0) {
|
||||
return this.compileConditional(o);
|
||||
}
|
||||
}
|
||||
top = del(o, 'top');
|
||||
stmt = del(o, 'asStatement');
|
||||
name = this.variable.compile(o, LVL_ASSIGN);
|
||||
name = this.variable.compile(o, LVL_LIST);
|
||||
if (this.value instanceof Code && (match = this.METHOD_DEF.exec(name))) {
|
||||
this.value.name = match[2];
|
||||
this.value.klass = match[1];
|
||||
}
|
||||
val = this.value.compile(o, LVL_ASSIGN);
|
||||
val = this.value.compile(o, LVL_LIST);
|
||||
if (this.context === 'object') {
|
||||
return "" + name + ": " + val;
|
||||
}
|
||||
@@ -902,17 +892,11 @@
|
||||
o.scope.find(name);
|
||||
}
|
||||
val = name + (" " + (this.context || '=') + " ") + val;
|
||||
if (stmt) {
|
||||
return "" + this.tab + val + ";";
|
||||
}
|
||||
return top || o.level <= LVL_ASSIGN ? val : "(" + val + ")";
|
||||
return o.level <= LVL_LIST ? val : "(" + val + ")";
|
||||
};
|
||||
Assign.prototype.compilePatternMatch = function(o) {
|
||||
var _len, _ref2, _ref3, accessClass, assigns, code, i, idx, isObject, obj, objects, olength, otop, ref, splat, top, val, valVar, value;
|
||||
top = del(o, 'top');
|
||||
otop = merge(o, {
|
||||
top: true
|
||||
});
|
||||
var _len, _ref2, _ref3, _ref4, _ref5, accessClass, assigns, code, i, idx, isObject, obj, objects, olength, ref, splat, top, val, valVar, value;
|
||||
top = o.level === LVL_TOP;
|
||||
value = this.value;
|
||||
objects = this.variable.base.objects;
|
||||
if (!(olength = objects.length)) {
|
||||
@@ -921,15 +905,15 @@
|
||||
isObject = this.variable.isObject();
|
||||
if (top && olength === 1 && !((obj = objects[0]) instanceof Splat)) {
|
||||
if (obj instanceof Assign) {
|
||||
_ref2 = obj, idx = _ref2.variable.base, obj = _ref2.value;
|
||||
_ref2 = obj, (_ref3 = _ref2.variable, idx = _ref3.base, _ref3), obj = _ref2.value;
|
||||
} else {
|
||||
idx = isObject ? obj.tags["this"] ? obj.properties[0].name : obj : new Literal(0);
|
||||
}
|
||||
accessClass = IDENTIFIER.test(idx.value) ? Accessor : Index;
|
||||
(value = Value.wrap(value)).properties.push(new accessClass(idx));
|
||||
return new Assign(obj, value).compile(otop);
|
||||
return new Assign(obj, value).compile(o);
|
||||
}
|
||||
valVar = value.compile(o);
|
||||
valVar = value.compile(o, LVL_LIST);
|
||||
assigns = [];
|
||||
splat = false;
|
||||
if (!IDENTIFIER.test(valVar) || this.variable.assigns(valVar)) {
|
||||
@@ -941,7 +925,7 @@
|
||||
idx = i;
|
||||
if (isObject) {
|
||||
if (obj instanceof Assign) {
|
||||
_ref3 = obj, idx = _ref3.variable.base, obj = _ref3.value;
|
||||
_ref4 = obj, (_ref5 = _ref4.variable, idx = _ref5.base, _ref5), obj = _ref4.value;
|
||||
} else {
|
||||
idx = obj.tags["this"] ? obj.properties[0].name : obj;
|
||||
}
|
||||
@@ -959,22 +943,19 @@
|
||||
}
|
||||
val = new Value(new Literal(valVar), [new accessClass(idx)]);
|
||||
}
|
||||
assigns.push(new Assign(obj, val).compile(otop));
|
||||
assigns.push(new Assign(obj, val).compile(o, LVL_LIST));
|
||||
}
|
||||
if (!top) {
|
||||
assigns.push(valVar);
|
||||
}
|
||||
code = assigns.join(', ');
|
||||
return top || o.level <= LVL_PAREN ? code : "(" + code + ")";
|
||||
return o.level < LVL_LIST ? code : "(" + code + ")";
|
||||
};
|
||||
Assign.prototype.compileConditional = function(o) {
|
||||
var _ref2, left, rite;
|
||||
_ref2 = this.variable.cacheReference(o), left = _ref2[0], rite = _ref2[1];
|
||||
return new Op(this.context.slice(0, -1), left, new Assign(rite, this.value)).compile(o);
|
||||
};
|
||||
Assign.prototype.assigns = function(name) {
|
||||
return this[this.context === 'object' ? 'value' : 'variable'].assigns(name);
|
||||
};
|
||||
return Assign;
|
||||
})();
|
||||
exports.Code = (function() {
|
||||
@@ -996,11 +977,9 @@
|
||||
__extends(Code, Base);
|
||||
Code.prototype.children = ['params', 'body'];
|
||||
Code.prototype.compileNode = function(o) {
|
||||
var _i, _len, _len2, _ref2, _ref3, _result, close, code, comm, empty, func, i, open, param, params, sharedScope, splat, top, value;
|
||||
var _i, _len, _len2, _ref2, _ref3, _result, close, code, comm, empty, func, i, idt, open, param, params, scope, sharedScope, splat, value;
|
||||
sharedScope = del(o, 'sharedScope');
|
||||
top = del(o, 'top');
|
||||
o.scope = sharedScope || new Scope(o.scope, this.body, this);
|
||||
o.top = true;
|
||||
o.scope = scope = sharedScope || new Scope(o.scope, this.body, this);
|
||||
o.indent = this.idt(1);
|
||||
empty = this.body.expressions.length === 0;
|
||||
delete o.bare;
|
||||
@@ -1019,7 +998,7 @@
|
||||
} else {
|
||||
if (param.attach) {
|
||||
value = param.value;
|
||||
_ref3 = [new Literal(o.scope.freeVariable('arg')), param.splat], param = _ref3[0], param.splat = _ref3[1];
|
||||
_ref3 = [new Literal(scope.freeVariable('arg')), param.splat], param = _ref3[0], param.splat = _ref3[1];
|
||||
this.body.unshift(new Assign(new Value(new Literal('this'), [new Accessor(value)]), param));
|
||||
}
|
||||
if (param.splat) {
|
||||
@@ -1033,31 +1012,36 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
o.scope.startLevel();
|
||||
scope.startLevel();
|
||||
if (!(empty || this.noReturn)) {
|
||||
this.body.makeReturn();
|
||||
}
|
||||
params = (function() {
|
||||
_result = [];
|
||||
for (_i = 0, _len2 = params.length; _i < _len2; _i++) {
|
||||
param = params[_i];
|
||||
_result.push(param.compile(o));
|
||||
_result.push((function() {
|
||||
scope.parameter(param = param.compile(o));
|
||||
return param;
|
||||
})());
|
||||
}
|
||||
return _result;
|
||||
})();
|
||||
if (!(empty || this.noReturn)) {
|
||||
this.body.makeReturn();
|
||||
}
|
||||
for (_i = 0, _len2 = params.length; _i < _len2; _i++) {
|
||||
param = params[_i];
|
||||
o.scope.parameter(param);
|
||||
}
|
||||
comm = this.comment ? this.comment.compile(o) + '\n' : '';
|
||||
if (this.className) {
|
||||
o.indent = this.idt(2);
|
||||
}
|
||||
idt = this.idt(1);
|
||||
code = this.body.expressions.length ? "\n" + (this.body.compileWithDeclarations(o)) + "\n" : '';
|
||||
open = this.className ? "(function() {\n" + comm + (this.idt(1)) + "function " + this.className + "(" : "function(";
|
||||
close = this.className ? "" + (code && this.idt(1)) + "};\n" + (this.idt(1)) + "return " + this.className + ";\n" + this.tab + "})()" : "" + (code && this.tab) + "}";
|
||||
if (this.className) {
|
||||
open = "(function() {\n" + comm + idt + "function " + this.className + "(";
|
||||
close = "" + (code && idt) + "};\n" + idt + "return " + this.className + ";\n" + this.tab + "})()";
|
||||
} else {
|
||||
open = "function(";
|
||||
close = "" + (code && this.tab) + "}";
|
||||
}
|
||||
func = "" + open + (params.join(', ')) + ") {" + code + close;
|
||||
o.scope.endLevel();
|
||||
scope.endLevel();
|
||||
if (this.bound) {
|
||||
return "" + (utility('bind')) + "(" + func + ", " + this.context + ")";
|
||||
}
|
||||
@@ -1082,7 +1066,7 @@
|
||||
})();
|
||||
__extends(Param, Base);
|
||||
Param.prototype.children = ['name'];
|
||||
Param.prototype.compileNode = function(o) {
|
||||
Param.prototype.compile = function(o) {
|
||||
return this.value.compile(o, LVL_LIST);
|
||||
};
|
||||
Param.prototype.toString = function() {
|
||||
@@ -1112,7 +1096,7 @@
|
||||
Splat.prototype.assigns = function(name) {
|
||||
return this.name.assigns(name);
|
||||
};
|
||||
Splat.prototype.compileNode = function(o) {
|
||||
Splat.prototype.compile = function(o) {
|
||||
return this.index != null ? this.compileParam(o) : this.name.compile(o);
|
||||
};
|
||||
Splat.prototype.compileParam = function(o) {
|
||||
@@ -1182,7 +1166,6 @@
|
||||
})();
|
||||
__extends(While, Base);
|
||||
While.prototype.children = ['condition', 'guard', 'body'];
|
||||
While.prototype.topSensitive = true;
|
||||
While.prototype.isStatement = YES;
|
||||
While.prototype.addBody = function(body) {
|
||||
this.body = body;
|
||||
@@ -1193,31 +1176,26 @@
|
||||
return this;
|
||||
};
|
||||
While.prototype.compileNode = function(o) {
|
||||
var cond, post, pre, rvar, set, top;
|
||||
top = del(o, 'top') && !this.returns;
|
||||
var body, code, rvar, set;
|
||||
o.indent = this.idt(1);
|
||||
cond = this.condition.compile(o, LVL_PAREN);
|
||||
o.top = true;
|
||||
set = '';
|
||||
if (!top) {
|
||||
body = this.body;
|
||||
if (o.level > LVL_TOP || this.returns) {
|
||||
rvar = o.scope.freeVariable('result');
|
||||
set = "" + this.tab + rvar + " = [];\n";
|
||||
if (this.body) {
|
||||
this.body = Push.wrap(rvar, this.body);
|
||||
if (body) {
|
||||
body = Push.wrap(rvar, body);
|
||||
}
|
||||
}
|
||||
pre = "" + set + this.tab + "while (" + cond + ")";
|
||||
if (this.guard) {
|
||||
this.body = Expressions.wrap([new If(this.guard, this.body)]);
|
||||
body = Expressions.wrap([new If(this.guard, body)]);
|
||||
}
|
||||
code = set + this.tab + ("while (" + (this.condition.compile(o, LVL_PAREN)) + ") {\n" + (body.compile(o, LVL_TOP)) + "\n" + this.tab + "}");
|
||||
if (this.returns) {
|
||||
post = '\n' + new Return(new Literal(rvar)).compile(merge(o, {
|
||||
indent: this.idt()
|
||||
}));
|
||||
} else {
|
||||
post = '';
|
||||
o.indent = this.tab;
|
||||
code += '\n' + new Return(new Literal(rvar)).compile(o);
|
||||
}
|
||||
return "" + pre + " {\n" + (this.body.compile(o)) + "\n" + this.tab + "}" + post;
|
||||
return code;
|
||||
};
|
||||
return While;
|
||||
})();
|
||||
@@ -1278,12 +1256,12 @@
|
||||
Op.prototype.toString = function(idt) {
|
||||
return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator);
|
||||
};
|
||||
Op.prototype.unfoldSoak = function(o) {
|
||||
var _ref2;
|
||||
return (_ref2 = this.operator, __indexOf.call(this.MUTATORS, _ref2) >= 0) && If.unfoldSoak(o, this, 'first');
|
||||
};
|
||||
Op.prototype.compileNode = function(o) {
|
||||
var _ref2, ifn;
|
||||
if (this.isUnary()) {
|
||||
if ((_ref2 = this.operator, __indexOf.call(this.MUTATORS, _ref2) >= 0) && (ifn = If.unfoldSoak(o, this, 'first'))) {
|
||||
return ifn.compile(o);
|
||||
}
|
||||
return this.compileUnary(o);
|
||||
}
|
||||
if (this.isChainable() && this.first.unwrap().isChainable()) {
|
||||
@@ -1309,7 +1287,7 @@
|
||||
fst = this.first;
|
||||
ref = fst.compile(o);
|
||||
}
|
||||
return new Existence(fst).compile(o) + (" ? " + ref + " : " + (this.second.compile(o, LVL_ASSIGN)));
|
||||
return new Existence(fst).compile(o) + (" ? " + ref + " : " + (this.second.compile(o, LVL_LIST)));
|
||||
};
|
||||
Op.prototype.compileUnary = function(o) {
|
||||
var _ref2, parts, space;
|
||||
@@ -1394,14 +1372,11 @@
|
||||
return this;
|
||||
};
|
||||
Try.prototype.compileNode = function(o) {
|
||||
var attemptPart, catchPart, errorPart, finallyPart;
|
||||
var catchPart, errorPart;
|
||||
o.indent = this.idt(1);
|
||||
o.top = true;
|
||||
attemptPart = this.attempt.compile(o);
|
||||
errorPart = this.error ? " (" + (this.error.compile(o)) + ") " : ' ';
|
||||
catchPart = this.recovery ? " catch" + errorPart + "{\n" + (this.recovery.compile(o)) + "\n" + this.tab + "}" : !(this.ensure || this.recovery) ? ' catch (_e) {}' : '';
|
||||
finallyPart = (this.ensure || '') && ' finally {\n' + this.ensure.compile(merge(o)) + ("\n" + this.tab + "}");
|
||||
return "" + this.tab + "try {\n" + attemptPart + "\n" + this.tab + "}" + catchPart + finallyPart;
|
||||
catchPart = this.recovery ? " catch" + errorPart + "{\n" + (this.recovery.compile(o, LVL_TOP)) + "\n" + this.tab + "}" : !(this.ensure || this.recovery) ? ' catch (_e) {}' : undefined;
|
||||
return ("" + this.tab + "try {\n" + (this.attempt.compile(o, LVL_TOP)) + "\n" + this.tab + "}" + (catchPart || '')) + (this.ensure ? " finally {\n" + (this.ensure.compile(o, LVL_TOP)) + "\n" + this.tab + "}" : '');
|
||||
};
|
||||
return Try;
|
||||
})();
|
||||
@@ -1419,7 +1394,7 @@
|
||||
Throw.prototype.isStatement = YES;
|
||||
Throw.prototype.makeReturn = THIS;
|
||||
Throw.prototype.compileNode = function(o) {
|
||||
return "" + this.tab + "throw " + (this.expression.compile(o)) + ";";
|
||||
return this.tab + ("throw " + (this.expression.compile(o)) + ";");
|
||||
};
|
||||
return Throw;
|
||||
})();
|
||||
@@ -1453,9 +1428,8 @@
|
||||
})();
|
||||
__extends(Parens, Base);
|
||||
Parens.prototype.children = ['expression'];
|
||||
Parens.prototype.topSensitive = true;
|
||||
Parens.prototype.isStatement = function(o) {
|
||||
return this.expression.isStatement(o);
|
||||
Parens.prototype.unwrap = function() {
|
||||
return this.expression;
|
||||
};
|
||||
Parens.prototype.isComplex = function() {
|
||||
return this.expression.isComplex();
|
||||
@@ -1464,21 +1438,15 @@
|
||||
return this.expression.makeReturn();
|
||||
};
|
||||
Parens.prototype.compileNode = function(o) {
|
||||
var code, expr, top;
|
||||
top = del(o, 'top');
|
||||
var bare, code, expr;
|
||||
expr = this.expression;
|
||||
if (expr instanceof Value && expr.isAtomic()) {
|
||||
expr.tags.front = this.tags.front;
|
||||
return expr.compile(o);
|
||||
}
|
||||
bare = o.level < LVL_OP && (expr instanceof Op || expr instanceof Call);
|
||||
code = expr.compile(o, LVL_PAREN);
|
||||
if (o.level < LVL_OP && (expr instanceof Op || expr instanceof Call)) {
|
||||
return code;
|
||||
}
|
||||
if (expr.isStatement(o)) {
|
||||
return (top ? this.tab + code + ';' : code);
|
||||
}
|
||||
return "(" + code + ")";
|
||||
return bare ? code : "(" + code + ")";
|
||||
};
|
||||
return Parens;
|
||||
})();
|
||||
@@ -1505,7 +1473,6 @@
|
||||
})();
|
||||
__extends(For, Base);
|
||||
For.prototype.children = ['body', 'source', 'guard', 'step', 'from', 'to'];
|
||||
For.prototype.topSensitive = true;
|
||||
For.prototype.isStatement = YES;
|
||||
For.prototype.makeReturn = function() {
|
||||
this.returns = true;
|
||||
@@ -1521,9 +1488,8 @@
|
||||
return '';
|
||||
};
|
||||
For.prototype.compileNode = function(o) {
|
||||
var _ref2, _ref3, _ref4, _ref5, _ref6, body, cond, defPart, forPart, guardPart, idt, index, ivar, lvar, name, namePart, pvar, resultRet, rvar, scope, sourcePart, step, svar, tail, top, tvar, varPart, vars;
|
||||
var _ref2, _ref3, _ref4, _ref5, _ref6, body, cond, defPart, forPart, guardPart, idt, index, ivar, lvar, name, namePart, pvar, resultRet, rvar, scope, sourcePart, step, svar, tail, tvar, varPart, vars;
|
||||
scope = o.scope;
|
||||
top = del(o, 'top') && !this.returns;
|
||||
name = !this.pattern && ((_ref2 = this.name) != null ? _ref2.compile(o) : undefined);
|
||||
index = (_ref3 = this.index) != null ? _ref3.compile(o) : undefined;
|
||||
ivar = !index ? scope.freeVariable('i') : index;
|
||||
@@ -1554,11 +1520,9 @@
|
||||
if (name) {
|
||||
_ref6 = this.source.compileLoopReference(o, 'ref'), sourcePart = _ref6[0], svar = _ref6[1];
|
||||
} else {
|
||||
sourcePart = svar = this.source.compile(o);
|
||||
sourcePart = svar = this.source.compile(o, LVL_PAREN);
|
||||
}
|
||||
namePart = this.pattern ? new Assign(this.name, new Literal("" + svar + "[" + ivar + "]")).compile(merge(o, {
|
||||
top: true
|
||||
})) : name ? "" + name + " = " + svar + "[" + ivar + "]" : undefined;
|
||||
namePart = this.pattern ? new Assign(this.name, new Literal("" + svar + "[" + ivar + "]")).compile(o, LVL_TOP) : name ? "" + name + " = " + svar + "[" + ivar + "]" : undefined;
|
||||
if (!this.object) {
|
||||
if (0 > pvar && (pvar | 0) === +pvar) {
|
||||
vars = "" + ivar + " = " + svar + ".length - 1";
|
||||
@@ -1581,18 +1545,18 @@
|
||||
if (svar !== sourcePart) {
|
||||
defPart = "" + this.tab + sourcePart + ";\n";
|
||||
}
|
||||
forPart = ("" + vars + "; " + cond + "; ") + (function() {
|
||||
forPart = ("" + vars + "; " + cond + "; ") + ivar + (function() {
|
||||
switch (+pvar) {
|
||||
case 1:
|
||||
return ivar + '++';
|
||||
return '++';
|
||||
case -1:
|
||||
return ivar + '--';
|
||||
return '--';
|
||||
default:
|
||||
return ivar + (pvar < 0 ? ' -= ' + pvar.slice(1) : ' += ' + pvar);
|
||||
return pvar < 0 ? ' -= ' + pvar.slice(1) : ' += ' + pvar;
|
||||
}
|
||||
})();
|
||||
}
|
||||
if (!top) {
|
||||
if (o.level > LVL_TOP || this.returns) {
|
||||
rvar = scope.freeVariable('result');
|
||||
defPart += "" + this.tab + rvar + " = [];\n";
|
||||
resultRet = this.compileReturnValue(rvar, o);
|
||||
@@ -1604,10 +1568,8 @@
|
||||
if (namePart) {
|
||||
varPart = "" + idt + namePart + ";\n";
|
||||
}
|
||||
return "" + (defPart || '') + this.tab + "for (" + forPart + ") {\n" + (guardPart || '') + varPart + (body.compile(merge(o, {
|
||||
indent: idt,
|
||||
top: true
|
||||
}))) + "\n" + this.tab + "}" + (resultRet || '');
|
||||
o.indent = idt;
|
||||
return "" + (defPart || '') + this.tab + "for (" + forPart + ") {\n" + (guardPart || '') + varPart + (body.compile(o, LVL_TOP)) + "\n" + this.tab + "}" + (resultRet || '');
|
||||
};
|
||||
return For;
|
||||
})();
|
||||
@@ -1626,43 +1588,51 @@
|
||||
Switch.prototype.children = ['subject', 'cases', 'otherwise'];
|
||||
Switch.prototype.isStatement = YES;
|
||||
Switch.prototype.makeReturn = function() {
|
||||
var _i, _len, _ref2, pair;
|
||||
var _i, _len, _ref2, _ref3, pair;
|
||||
_ref2 = this.cases;
|
||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||
pair = _ref2[_i];
|
||||
pair[1].makeReturn();
|
||||
}
|
||||
if (this.otherwise) {
|
||||
this.otherwise.makeReturn();
|
||||
if ((_ref3 = this.otherwise) != null) {
|
||||
_ref3.makeReturn();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
Switch.prototype.compileNode = function(o) {
|
||||
var _i, _j, _len, _len2, _ref2, _ref3, _ref4, block, code, condition, conditions, idt1, idt2;
|
||||
var _i, _j, _len, _len2, _ref2, _ref3, _ref4, _ref5, block, code, cond, conditions, expr, i, idt1, idt2;
|
||||
idt1 = this.idt(1);
|
||||
idt2 = o.indent = this.idt(2);
|
||||
o.top = true;
|
||||
code = "" + this.tab + "switch (" + (((_ref2 = this.subject) != null ? _ref2.compile(o) : undefined) || true) + ") {";
|
||||
for (_i = 0, _len = this.cases.length; _i < _len; _i++) {
|
||||
_ref3 = this.cases[_i], conditions = _ref3[0], block = _ref3[1];
|
||||
code = this.tab + ("switch (" + (((_ref2 = this.subject) != null ? _ref2.compile(o, LVL_PAREN) : undefined) || true) + ") {\n");
|
||||
for (i = 0, _len = this.cases.length; i < _len; i++) {
|
||||
_ref3 = this.cases[i], conditions = _ref3[0], block = _ref3[1];
|
||||
_ref4 = flatten([conditions]);
|
||||
for (_j = 0, _len2 = _ref4.length; _j < _len2; _j++) {
|
||||
condition = _ref4[_j];
|
||||
for (_i = 0, _len2 = _ref4.length; _i < _len2; _i++) {
|
||||
cond = _ref4[_i];
|
||||
if (!this.subject) {
|
||||
condition = condition.invert().invert();
|
||||
cond = cond.invert().invert();
|
||||
}
|
||||
code += "\n" + idt1 + "case " + (condition.compile(o)) + ":";
|
||||
code += idt1 + ("case " + (cond.compile(o, LVL_PAREN)) + ":\n");
|
||||
}
|
||||
code += "\n" + (block.compile(o));
|
||||
if (!(last(block.expressions) instanceof Return)) {
|
||||
code += "\n" + idt2 + "break;";
|
||||
code += block.compile(o, LVL_TOP) + '\n';
|
||||
if (i === this.cases.length - 1 && !this.otherwise) {
|
||||
break;
|
||||
}
|
||||
_ref5 = block.expressions;
|
||||
for (_j = _ref5.length - 1; _j >= 0; _j--) {
|
||||
expr = _ref5[_j];
|
||||
if (!(expr instanceof Comment)) {
|
||||
if (!(expr instanceof Return)) {
|
||||
code += idt2 + 'break;\n';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.otherwise) {
|
||||
code += "\n" + idt1 + "default:\n" + (this.otherwise.compile(o));
|
||||
code += idt1 + ("default:\n" + (this.otherwise.compile(o, LVL_TOP)) + "\n");
|
||||
}
|
||||
code += "\n" + this.tab + "}";
|
||||
return code;
|
||||
return code + this.tab + '}';
|
||||
};
|
||||
return Switch;
|
||||
})();
|
||||
@@ -1681,7 +1651,6 @@
|
||||
})();
|
||||
__extends(If, Base);
|
||||
If.prototype.children = ['condition', 'body', 'elseBody'];
|
||||
If.prototype.topSensitive = true;
|
||||
If.prototype.bodyNode = function() {
|
||||
var _ref2;
|
||||
return (_ref2 = this.body) != null ? _ref2.unwrap() : undefined;
|
||||
@@ -1701,7 +1670,7 @@
|
||||
};
|
||||
If.prototype.isStatement = function(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));
|
||||
return (o != null ? o.level : undefined) === LVL_TOP || this.bodyNode().isStatement(o) || ((_ref2 = this.elseBodyNode()) != null ? _ref2.isStatement(o) : undefined);
|
||||
};
|
||||
If.prototype.compileNode = function(o) {
|
||||
return this.isStatement(o) ? this.compileStatement(o) : this.compileExpression(o);
|
||||
@@ -1719,13 +1688,12 @@
|
||||
return node instanceof Expressions ? node : new Expressions([node]);
|
||||
};
|
||||
If.prototype.compileStatement = function(o) {
|
||||
var child, condO, ifPart, top;
|
||||
top = del(o, 'top');
|
||||
var body, child, cond, ifPart;
|
||||
child = del(o, 'chainChild');
|
||||
condO = merge(o);
|
||||
cond = this.condition.compile(o, LVL_PAREN);
|
||||
o.indent = this.idt(1);
|
||||
o.top = true;
|
||||
ifPart = "if (" + (this.condition.compile(condO, LVL_PAREN)) + ") {\n" + (this.body.compile(o)) + "\n" + this.tab + "}";
|
||||
body = this.ensureExpressions(this.body).compile(o);
|
||||
ifPart = "if (" + cond + ") {\n" + body + "\n" + this.tab + "}";
|
||||
if (!child) {
|
||||
ifPart = this.tab + ifPart;
|
||||
}
|
||||
@@ -1735,11 +1703,11 @@
|
||||
return ifPart + ' else ' + (this.isChain ? this.elseBodyNode().compile(merge(o, {
|
||||
indent: this.tab,
|
||||
chainChild: true
|
||||
})) : "{\n" + (this.elseBody.compile(o)) + "\n" + this.tab + "}");
|
||||
})) : "{\n" + (this.elseBody.compile(o, LVL_TOP)) + "\n" + this.tab + "}");
|
||||
};
|
||||
If.prototype.compileExpression = function(o) {
|
||||
var _ref2, code;
|
||||
code = this.condition.compile(o, LVL_COND) + ' ? ' + this.bodyNode().compile(o, LVL_ASSIGN) + ' : ' + ((_ref2 = this.elseBodyNode()) != null ? _ref2.compile(o, LVL_ASSIGN) : undefined);
|
||||
code = this.condition.compile(o, LVL_COND) + ' ? ' + this.bodyNode().compile(o, LVL_LIST) + ' : ' + ((_ref2 = this.elseBodyNode()) != null ? _ref2.compile(o, LVL_LIST) : undefined);
|
||||
return o.level >= LVL_COND ? "(" + code + ")" : code;
|
||||
};
|
||||
If.prototype.unfoldSoak = function() {
|
||||
@@ -1801,10 +1769,9 @@
|
||||
LVL_TOP = 0;
|
||||
LVL_PAREN = 1;
|
||||
LVL_LIST = 2;
|
||||
LVL_ASSIGN = 3;
|
||||
LVL_COND = 4;
|
||||
LVL_OP = 5;
|
||||
LVL_ACCESS = 6;
|
||||
LVL_COND = 3;
|
||||
LVL_OP = 4;
|
||||
LVL_ACCESS = 5;
|
||||
TAB = ' ';
|
||||
TRAILING_WHITESPACE = /[ \t]+$/gm;
|
||||
IDENTIFIER = /^[$A-Za-z_][$\w]*$/;
|
||||
@@ -1817,4 +1784,7 @@
|
||||
Scope.root.assign(ref, UTILITIES[name]);
|
||||
return ref;
|
||||
};
|
||||
multident = function(code, tab) {
|
||||
return code.replace(/\n/g, '$&' + tab);
|
||||
};
|
||||
}).call(this);
|
||||
|
||||
Reference in New Issue
Block a user