got about as far as I think I can with operator nodes for now, without zach's optimizations

This commit is contained in:
Jeremy Ashkenas
2010-02-10 00:05:56 -05:00
parent 9339058fc3
commit 76dac9c09c
5 changed files with 223 additions and 122 deletions

View File

@@ -1,5 +1,5 @@
(function(){
var AccessorNode, ArrayNode, AssignNode, CallNode, ClosureNode, CodeNode, CommentNode, Expressions, ExtendsNode, IndexNode, LiteralNode, Node, ObjectNode, OpNode, PushNode, RangeNode, ReturnNode, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThisNode, ValueNode, WhileNode, any, compact, del, dup, flatten, inherit, merge, statement;
var AccessorNode, ArrayNode, AssignNode, CallNode, ClosureNode, CodeNode, CommentNode, Expressions, ExtendsNode, IDENTIFIER, IndexNode, LiteralNode, Node, ObjectNode, OpNode, PushNode, RangeNode, ReturnNode, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThisNode, ValueNode, WhileNode, any, compact, del, dup, flatten, inherit, merge, statement;
var __hasProp = Object.prototype.hasOwnProperty;
process.mixin(require('./scope'));
// The abstract base class for all CoffeeScript nodes.
@@ -151,6 +151,8 @@
// Tabs are two spaces for pretty printing.
TAB = ' ';
TRAILING_WHITESPACE = /\s+$/g;
// Keep the identifier regex in sync with the Lexer.
IDENTIFIER = /^[a-zA-Z$_](\w|\$)*$/;
// Flatten nested arrays recursively.
flatten = function flatten(list) {
var __a, __b, item, memo;
@@ -842,8 +844,6 @@
});
// Setting the value of a local variable, or the value of an object property.
AssignNode = (exports.AssignNode = inherit(Node, {
// Keep the identifier regex in sync with the Lexer.
IDENTIFIER: /^([a-zA-Z$_](\w|\$)*)/,
PROTO_ASSIGN: /^(\S+)\.prototype/,
LEADING_DOT: /^\.(prototype\.)?/,
constructor: function constructor(variable, value, context) {
@@ -875,7 +875,7 @@
match = name.match(this.PROTO_ASSIGN);
proto = match && match[1];
if (this.value instanceof CodeNode) {
if (last.match(this.IDENTIFIER)) {
if (last.match(IDENTIFIER)) {
this.value.name = last;
}
if (proto) {
@@ -1058,9 +1058,60 @@
return this.CHAINABLE.indexOf(this.operator) >= 0;
},
compile_node: function compile_node(o) {
if (this.is_chainable() && (this.first.unwrap() instanceof OpNode) && this.first.unwrap().is_chainable()) {
if (this.is_chainable() && this.first.unwrap() instanceof OpNode && this.first.unwrap().is_chainable()) {
return this.compile_chain(o);
}
if (this.ASSIGNMENT.indexOf(this.operator) >= 0) {
return this.compile_assignment(o);
}
if (this.is_unary()) {
return this.compile_unary(o);
}
if (this.operator === '?') {
return this.compile_existence(o);
}
return this.first.compile(o) + ' ' + this.operator + ' ' + this.second.compile(o);
},
// Mimic Python's chained comparisons. See:
// http://docs.python.org/reference/expressions.html#notin
compile_chain: function compile_chain(o) {
var __a, shared;
shared = this.first.unwrap().second;
if (shared instanceof CallNode) {
__a = shared.compile_reference(o);
this.first.second = __a[0];
shared = __a[1];
}
return '(' + this.first.compile(o) + ') && (' + shared.compile(o) + ' ' + this.operator + ' ' + this.second.compile(o) + ')';
},
compile_assignment: function compile_assignment(o) {
var __a, first, second;
__a = [this.first.compile(o), this.second.compile(o)];
first = __a[0];
second = __a[1];
if (this.first.unwrap.match(IDENTIFIER)) {
o.scope.find(first);
}
if (this.operator === '?=') {
return first + ' = ' + ExistenceNode.compile_test(o, this.first) + ' ? ' + first + ' : ' + second;
}
return first + ' = ' + first + ' ' + this.operator.substr(0, 2) + ' ' + second;
},
compile_existence: function compile_existence(o) {
var __a, first, second;
__a = [this.first.compile(o), this.second.compile(o)];
first = __a[0];
second = __a[1];
return ExistenceNode.compile_test(o, this.first) + ' ? ' + first + ' : ' + second;
},
compile_unary: function compile_unary(o) {
var parts, space;
space = this.PREFIX_OPERATORS.indexOf(this.operator) >= 0 ? ' ' : '';
parts = [this.operator, space, this.first.compile(o)];
if (this.flip) {
parts = parts.reverse();
}
return parts.join('');
}
}));
})();