more cleanups, added a utility helper function to the codegen

This commit is contained in:
Jeremy Ashkenas
2010-03-30 19:48:37 -04:00
parent 6d7a04228f
commit 998a7c8cb0
4 changed files with 35 additions and 33 deletions

View File

@@ -1,5 +1,5 @@
(function(){
var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, CommentNode, CurryNode, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IfNode, IndexNode, LiteralNode, ObjectNode, OpNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, Scope, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, UTILITIES, ValueNode, WhileNode, compact, del, flatten, helpers, literal, merge, statement;
var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, CommentNode, CurryNode, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IfNode, IndexNode, LiteralNode, ObjectNode, OpNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, Scope, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, UTILITIES, ValueNode, WhileNode, compact, del, flatten, helpers, literal, merge, statement, utility;
var __extend = function(child, parent) {
var ctor = function(){ };
ctor.prototype = parent.prototype;
@@ -596,14 +596,10 @@
};
CurryNode.prototype.compile_node = function compile_node(o) {
var ref;
CurryNode.assign_bind();
ref = new ValueNode(literal('__bind'));
utility('slice');
ref = new ValueNode(literal(utility('bind')));
return (new CallNode(ref, [this.meth, this.context, literal(this.arguments(o))])).compile(o);
};
CurryNode.assign_bind = function assign_bind() {
Scope.root.assign('__slice', UTILITIES['slice']);
return Scope.root.assign('__bind', UTILITIES['bind']);
};
return CurryNode;
}).call(this);
//### ExtendsNode
@@ -620,7 +616,7 @@
// Hooks one constructor into another's prototype chain.
ExtendsNode.prototype.compile_node = function compile_node(o) {
var ref;
ref = new ValueNode(literal(Scope.root.assign('__extend', UTILITIES['extend'])));
ref = new ValueNode(literal(utility('extend')));
return (new CallNode(ref, [this.child, this.parent])).compile(o);
};
return ExtendsNode;
@@ -745,7 +741,7 @@
to = (typeof (_b = this.range.to) !== "undefined" && _b !== null) ? this.range.to : literal('null');
exclusive = this.range.exclusive ? 'true' : 'false';
v = o.scope.free_variable();
rng = new CallNode(new ValueNode(literal(Scope.root.assign('__range', UTILITIES['range']))), [literal(array), from, to, literal(exclusive)]);
rng = new CallNode(new ValueNode(literal(utility('range'))), [literal(array), from, to, literal(exclusive)]);
args = literal("[(" + v + " = " + (rng.compile(o)) + ")[0], " + v + "[1] - " + v + "[0]].concat(" + (replace.compile(o)) + ")");
call = new CallNode(new ValueNode(literal(array), [literal('.splice.apply')]), [literal(array), args]);
return call.compile(o);
@@ -756,7 +752,7 @@
from = (typeof (_a = this.range.from) !== "undefined" && _a !== null) ? this.range.from : literal('null');
to = (typeof (_b = this.range.to) !== "undefined" && _b !== null) ? this.range.to : literal('null');
exclusive = this.range.exclusive ? 'true' : 'false';
rng = new CallNode(new ValueNode(literal(Scope.root.assign('__range', UTILITIES['range']))), [literal(array), from, to, literal(exclusive)]);
rng = new CallNode(new ValueNode(literal(utility('range'))), [literal(array), from, to, literal(exclusive)]);
call = new CallNode(new ValueNode(literal(array), [literal('.slice.apply')]), [literal(array), rng]);
return call.compile(o);
};
@@ -1088,8 +1084,8 @@
if (!(this.bound)) {
return func;
}
CurryNode.assign_bind();
ref = new ValueNode(literal('__bind'));
utility('slice');
ref = new ValueNode(literal(utility('bind')));
return (new CallNode(ref, [literal(func), literal('this')])).compile(o);
};
CodeNode.prototype.top_sensitive = function top_sensitive() {
@@ -1160,15 +1156,14 @@
o.scope.assign(trailing.compile(o), "arguments[arguments.length - " + this.trailings.length + " + " + i + "]");
i += 1;
}
return "" + name + " = " + (Scope.root.assign('__slice', UTILITIES['slice'])) + ".call(arguments, " + this.index + ", arguments.length - " + (this.trailings.length) + ")";
return "" + name + " = " + (utility('slice')) + ".call(arguments, " + this.index + ", arguments.length - " + (this.trailings.length) + ")";
};
// A compiling a splat as a destructuring assignment means slicing arguments
// from the right-hand-side's corresponding array.
SplatNode.prototype.compile_value = function compile_value(o, name, index, trailings) {
var trail;
Scope.root.assign('__slice', UTILITIES['slice']);
trail = trailings ? ", " + (name) + ".length - " + trailings : '';
return "__slice.call(" + name + ", " + index + trail + ")";
return "" + (utility('slice')) + ".call(" + name + ", " + index + trail + ")";
};
// Utility function that converts arbitrary number of elements, mixed with
// splats, to a proper array
@@ -1579,7 +1574,7 @@
body = PushNode.wrap(rvar, body);
}
this.filter ? (body = Expressions.wrap([new IfNode(this.filter, body)])) : null;
this.object ? (for_part = "" + ivar + " in " + svar + ") { if (" + (Scope.root.assign('__hasProp', UTILITIES['hasProp'])) + ".call(" + svar + ", " + ivar + ")") : null;
this.object ? (for_part = "" + ivar + " in " + svar + ") { if (" + (utility('hasProp')) + ".call(" + svar + ", " + ivar + ")") : null;
body = body.compile(merge(o, {
indent: body_dent,
top: true
@@ -1796,4 +1791,11 @@
literal = function literal(name) {
return new LiteralNode(name);
};
// Helper for ensuring that utility functions are assigned at the top level.
utility = function utility(name) {
var ref;
ref = "__" + name;
Scope.root.assign(ref, UTILITIES[name]);
return ref;
};
})();

View File

@@ -85,7 +85,7 @@
value: value,
assigned: true
};
return name;
return this.variables[name];
};
// Does this scope reference any variables that need to be declared in the
// given function body?