1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

slightly nicer implementation of SplatNode.compileSplattedArray

This commit is contained in:
Jeremy Ashkenas 2010-07-13 22:16:19 -04:00
parent 8c34aff1c5
commit 0b87387fab
5 changed files with 43 additions and 28 deletions

View file

@ -1,5 +1,5 @@
(function(){
var compact, count, del, extend, flatten, helpers, include, indexOf, merge, starts;
var compact, count, del, ends, extend, flatten, helpers, include, indexOf, merge, starts;
var __hasProp = Object.prototype.hasOwnProperty;
if (!(typeof process !== "undefined" && process !== null)) {
this.exports = this;
@ -25,6 +25,11 @@
helpers.starts = (starts = function(string, literal, start) {
return string.substring(start, (start || 0) + literal.length) === literal;
});
helpers.ends = (ends = function(string, literal, back) {
var start;
start = string.length - literal.length - ((typeof back !== "undefined" && back !== null) ? back : 0);
return string.substring(start, start + literal.length) === literal;
});
helpers.compact = (compact = function(array) {
var _a, _b, _c, _d, item;
_a = []; _c = array;

View file

@ -1,5 +1,5 @@
(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, Scope, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, UTILITIES, ValueNode, WhileNode, _a, compact, del, flatten, helpers, include, indexOf, literal, merge, starts, utility;
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, 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(){ };
ctor.prototype = parent.prototype;
@ -23,6 +23,7 @@
include = _a.include;
indexOf = _a.indexOf;
starts = _a.starts;
ends = _a.ends;
exports.BaseNode = (function() {
BaseNode = function() { };
BaseNode.prototype.compile = function(o) {
@ -419,7 +420,7 @@
this.variable = this.isSuper ? null : variable;
this.args = (args || []);
this.compileSplatArguments = function(o) {
return SplatNode.compileMixedArray.call(this, this.args, o);
return SplatNode.compileSplattedArray.call(this, this.args, o);
};
return this;
};
@ -670,7 +671,7 @@
ArrayNode = function(objects) {
this.objects = objects || [];
this.compileSplatLiteral = function(o) {
return SplatNode.compileMixedArray.call(this, this.objects, o);
return SplatNode.compileSplattedArray.call(this, this.objects, o);
};
return this;
};
@ -1015,28 +1016,26 @@
trail = trailings ? (", " + (name) + ".length - " + trailings) : '';
return "" + (utility('slice')) + ".call(" + name + ", " + index + trail + ")";
};
SplatNode.compileMixedArray = function(list, o) {
var _b, _c, _d, arg, args, code, i, prev;
SplatNode.compileSplattedArray = function(list, o) {
var _b, _c, arg, args, code, i, last, prev;
args = [];
i = 0;
_c = list;
for (_b = 0, _d = _c.length; _b < _d; _b++) {
arg = _c[_b];
_b = list;
for (i = 0, _c = _b.length; i < _c; i++) {
arg = _b[i];
code = arg.compile(o);
prev = args[(last = args.length - 1)];
if (!(arg instanceof SplatNode)) {
prev = args[i - 1];
if (i === 1 && prev.substr(0, 1) === '[' && prev.substr(prev.length - 1, 1) === ']') {
args[i - 1] = ("" + (prev.substr(0, prev.length - 1)) + ", " + code + "]");
if (prev && starts(prev, '[') && ends(prev, ']')) {
args[last] = ("" + (prev.substr(0, prev.length - 1)) + ", " + code + "]");
continue;
} else if (i > 1 && prev.substr(0, 9) === '.concat([' && prev.substr(prev.length - 2, 2) === '])') {
args[i - 1] = ("" + (prev.substr(0, prev.length - 2)) + ", " + code + "])");
} else if (prev && starts(prev, '.concat([') && ends(prev, '])')) {
args[last] = ("" + (prev.substr(0, prev.length - 2)) + ", " + code + "])");
continue;
} else {
code = ("[" + code + "]");
}
}
args.push(i === 0 ? code : (".concat(" + code + ")"));
i += 1;
}
return args.join('');
};

View file

@ -22,6 +22,11 @@ helpers.include: include: (list, value) ->
helpers.starts: starts: (string, literal, start) ->
string.substring(start, (start or 0) + literal.length) is literal
# Peek at the end of a given string to see if it matches a sequence.
helpers.ends: ends: (string, literal, back) ->
start: string.length - literal.length - (back ? 0)
string.substring(start, start + literal.length) is literal
# Trim out all falsy values from an array.
helpers.compact: compact: (array) -> item for item in array when item

View file

@ -14,7 +14,7 @@ else
Scope: this.Scope
# Import the helpers we plan to use.
{compact, flatten, merge, del, include, indexOf, starts}: helpers
{compact, flatten, merge, del, include, indexOf, starts, ends}: helpers
#### BaseNode
@ -403,7 +403,7 @@ exports.CallNode: class CallNode extends BaseNode
@variable: if @isSuper then null else variable
@args: (args or [])
@compileSplatArguments: (o) ->
SplatNode.compileMixedArray.call(this, @args, o)
SplatNode.compileSplattedArray.call(this, @args, o)
# Tag this invocation as creating a new instance.
newInstance: ->
@ -625,7 +625,7 @@ exports.ArrayNode: class ArrayNode extends BaseNode
constructor: (objects) ->
@objects: objects or []
@compileSplatLiteral: (o) ->
SplatNode.compileMixedArray.call(this, @objects, o)
SplatNode.compileSplattedArray.call(this, @objects, o)
compileNode: (o) ->
o.indent: @idt 1
@ -921,23 +921,21 @@ exports.SplatNode: class SplatNode extends BaseNode
# Utility function that converts arbitrary number of elements, mixed with
# splats, to a proper array
@compileMixedArray: (list, o) ->
@compileSplattedArray: (list, o) ->
args: []
i: 0
for arg in list
for arg, i in list
code: arg.compile o
prev: args[last: args.length - 1]
if not (arg instanceof SplatNode)
prev: args[i - 1]
if i is 1 and prev.substr(0, 1) is '[' and prev.substr(prev.length - 1, 1) is ']'
args[i - 1]: "${prev.substr(0, prev.length - 1)}, $code]"
if prev and starts(prev, '[') and ends(prev, ']')
args[last]: "${prev.substr(0, prev.length - 1)}, $code]"
continue
else if i > 1 and prev.substr(0, 9) is '.concat([' and prev.substr(prev.length - 2, 2) is '])'
args[i - 1]: "${prev.substr(0, prev.length - 2)}, $code])"
else if prev and starts(prev, '.concat([') and ends(prev, '])')
args[last]: "${prev.substr(0, prev.length - 2)}, $code])"
continue
else
code: "[$code]"
args.push(if i is 0 then code else ".concat($code)")
i: + 1
args.join('')
#### WhileNode

View file

@ -105,3 +105,11 @@ ok pen is 2
method 1, 2
ok pen is 2
# Array splat expansions with assigns.
nums: [1, 2, 3]
list: [a: 0, nums..., b: 4]
ok a is 0
ok b is 4
ok list.join(' ') is '0 1 2 3 4'