mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-02-17 11:01:25 -05:00
Self-compiler: array slice literals.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
(function(){
|
||||
var AccessorNode, CallNode, CommentNode, Expressions, ExtendsNode, IndexNode, LiteralNode, Node, ReturnNode, TAB, TRAILING_WHITESPACE, ThisNode, ValueNode, any, compact, del, dup, flatten, inherit, merge, statement;
|
||||
var AccessorNode, CallNode, CommentNode, Expressions, ExtendsNode, IndexNode, LiteralNode, Node, RangeNode, ReturnNode, SliceNode, TAB, TRAILING_WHITESPACE, ThisNode, ValueNode, 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.
|
||||
@@ -690,10 +690,68 @@
|
||||
// A this-reference, using '@'.
|
||||
ThisNode = (exports.ThisNode = inherit(Node, {
|
||||
constructor: function constructor(property) {
|
||||
return this.property = property || null;
|
||||
this.property = property || null;
|
||||
return this;
|
||||
},
|
||||
compile_node: function compile_node(o) {
|
||||
return 'this' + (this.property ? '.' + this.property : '');
|
||||
}
|
||||
}));
|
||||
// A range literal. Ranges can be used to extract portions (slices) of arrays,
|
||||
// or to specify a range for list comprehensions.
|
||||
RangeNode = (exports.RangeNode = inherit(Node, {
|
||||
constructor: function constructor(from, to, exclusive) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.children = [from, to];
|
||||
this.exclusive = !!exclusive;
|
||||
return this;
|
||||
},
|
||||
compile_variables: function compile_variables(o) {
|
||||
this.indent = o.indent;
|
||||
this.from_var = o.scope.free_variable();
|
||||
this.to_var = o.scope.free_variable();
|
||||
return this.from_var + ' = ' + this.from.compile(o) + '; ' + this.to_var + ' = ' + this.to.compile(o) + ";\n" + this.idt();
|
||||
},
|
||||
compile_node: function compile_node(o) {
|
||||
var compare, equals, idx, incr, intro, step;
|
||||
if (!(o.index)) {
|
||||
return this.compile_array(o);
|
||||
}
|
||||
idx = del(o, 'index');
|
||||
step = del(o, 'step');
|
||||
equals = this.exclusive ? '' : '=';
|
||||
intro = '(' + this.from_var + ' <= ' + this.to_var + ' ? ' + idx;
|
||||
compare = intro + ' <' + equals + ' ' + this.to_var + ' : ' + idx + ' >' + equals + ' ' + this.to_var + ')';
|
||||
incr = intro + ' += ' + step + ' : ' + idx + ' -= ' + step + ')';
|
||||
return vars + '; ' + compare + '; ' + incr;
|
||||
},
|
||||
// Expand the range into the equivalent array, if it's not being used as
|
||||
// part of a comprehension, slice, or splice.
|
||||
// TODO: This generates pretty ugly code ... shrink it.
|
||||
compile_array: function compile_array(o) {
|
||||
var arr, body;
|
||||
body = Expressions.wrap(new LiteralNode('i'));
|
||||
arr = Expressions.wrap(new ForNode(body, {
|
||||
source: (new ValueNode(this))
|
||||
}, 'i'));
|
||||
return (new ParentheticalNode(new CallNode(new CodeNode([], arr)))).compile(o);
|
||||
}
|
||||
}));
|
||||
// An array slice literal. Unlike JavaScript's Array#slice, the second parameter
|
||||
// specifies the index of the end of the slice (just like the first parameter)
|
||||
// is the index of the beginning.
|
||||
SliceNode = (exports.SliceNode = inherit(Node, {
|
||||
constructor: function constructor(range) {
|
||||
this.children = [(this.range = range)];
|
||||
return this;
|
||||
},
|
||||
compile_node: function compile_node(o) {
|
||||
var from, plus_part, to;
|
||||
from = this.range.from.compile(o);
|
||||
to = this.range.to.compile(o);
|
||||
plus_part = this.range.exclusive ? '' : ' + 1';
|
||||
return ".slice(" + from + ', ' + to + plus_part + ')';
|
||||
}
|
||||
}));
|
||||
})();
|
||||
Reference in New Issue
Block a user