mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-02-18 19:34:27 -05:00
Added the ability for function declaration to have a splat at an arbitrary position, not just at the end. Still restrict their number to 1. Adjusted tests accordingly.
This commit is contained in:
50
lib/nodes.js
50
lib/nodes.js
@@ -918,7 +918,7 @@
|
|||||||
// arrow, generates a wrapper that saves the current value of `this` through
|
// arrow, generates a wrapper that saves the current value of `this` through
|
||||||
// a closure.
|
// a closure.
|
||||||
CodeNode.prototype.compile_node = function compile_node(o) {
|
CodeNode.prototype.compile_node = function compile_node(o) {
|
||||||
var _a, _b, _c, _d, _e, _f, _g, code, func, inner, name_part, param, params, shared_scope, splat, top;
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, code, func, i, inner, name_part, param, params, shared_scope, splat, top;
|
||||||
shared_scope = del(o, 'shared_scope');
|
shared_scope = del(o, 'shared_scope');
|
||||||
top = del(o, 'top');
|
top = del(o, 'top');
|
||||||
o.scope = shared_scope || new Scope(o.scope, this.body, this);
|
o.scope = shared_scope || new Scope(o.scope, this.body, this);
|
||||||
@@ -927,22 +927,35 @@
|
|||||||
o.indent = this.idt(this.bound ? 2 : 1);
|
o.indent = this.idt(this.bound ? 2 : 1);
|
||||||
del(o, 'no_wrap');
|
del(o, 'no_wrap');
|
||||||
del(o, 'globals');
|
del(o, 'globals');
|
||||||
if (this.params[this.params.length - 1] instanceof SplatNode) {
|
i = 0;
|
||||||
splat = this.params.pop();
|
splat = undefined;
|
||||||
splat.index = this.params.length;
|
params = [];
|
||||||
this.body.unshift(splat);
|
_a = this.params;
|
||||||
|
for (_b = 0, _c = _a.length; _b < _c; _b++) {
|
||||||
|
param = _a[_b];
|
||||||
|
if (param instanceof SplatNode && !(typeof splat !== "undefined" && splat !== null)) {
|
||||||
|
splat = param;
|
||||||
|
splat.index = i;
|
||||||
|
this.body.unshift(splat);
|
||||||
|
splat.trailings = [];
|
||||||
|
} else if ((typeof splat !== "undefined" && splat !== null)) {
|
||||||
|
splat.trailings.push(param);
|
||||||
|
} else {
|
||||||
|
params.push(param);
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
}
|
}
|
||||||
params = (function() {
|
params = (function() {
|
||||||
_a = []; _b = this.params;
|
_d = []; _e = params;
|
||||||
for (_c = 0, _d = _b.length; _c < _d; _c++) {
|
for (_f = 0, _g = _e.length; _f < _g; _f++) {
|
||||||
param = _b[_c];
|
param = _e[_f];
|
||||||
_a.push(param.compile(o));
|
_d.push(param.compile(o));
|
||||||
}
|
}
|
||||||
return _a;
|
return _d;
|
||||||
}).call(this);
|
}).call(this);
|
||||||
_e = params;
|
_h = params;
|
||||||
for (_f = 0, _g = _e.length; _f < _g; _f++) {
|
for (_i = 0, _j = _h.length; _i < _j; _i++) {
|
||||||
param = _e[_f];
|
param = _h[_i];
|
||||||
(o.scope.parameter(param));
|
(o.scope.parameter(param));
|
||||||
}
|
}
|
||||||
code = this.body.expressions.length ? "\n" + (this.body.compile_with_declarations(o)) + "\n" : '';
|
code = this.body.expressions.length ? "\n" + (this.body.compile_with_declarations(o)) + "\n" : '';
|
||||||
@@ -1011,10 +1024,17 @@
|
|||||||
// Compiling a parameter splat means recovering the parameters that succeed
|
// Compiling a parameter splat means recovering the parameters that succeed
|
||||||
// the splat in the parameter list, by slicing the arguments object.
|
// the splat in the parameter list, by slicing the arguments object.
|
||||||
SplatNode.prototype.compile_param = function compile_param(o) {
|
SplatNode.prototype.compile_param = function compile_param(o) {
|
||||||
var name;
|
var _a, _b, _c, i, name, trailing;
|
||||||
name = this.name.compile(o);
|
name = this.name.compile(o);
|
||||||
o.scope.find(name);
|
o.scope.find(name);
|
||||||
return '' + name + " = Array.prototype.slice.call(arguments, " + this.index + ")";
|
i = 0;
|
||||||
|
_a = this.trailings;
|
||||||
|
for (_b = 0, _c = _a.length; _b < _c; _b++) {
|
||||||
|
trailing = _a[_b];
|
||||||
|
o.scope.assign(trailing.compile(o), "arguments[arguments.length - " + this.trailings.length + " + " + i + "]");
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
return '' + name + " = Array.prototype.slice.call(arguments, " + this.index + ", arguments.length - " + (this.trailings.length) + ")";
|
||||||
};
|
};
|
||||||
// A compiling a splat as a destructuring assignment means slicing arguments
|
// A compiling a splat as a destructuring assignment means slicing arguments
|
||||||
// from the right-hand-side's corresponding array.
|
// from the right-hand-side's corresponding array.
|
||||||
|
|||||||
@@ -717,11 +717,21 @@ exports.CodeNode: class CodeNode extends BaseNode
|
|||||||
o.indent: @idt(if @bound then 2 else 1)
|
o.indent: @idt(if @bound then 2 else 1)
|
||||||
del o, 'no_wrap'
|
del o, 'no_wrap'
|
||||||
del o, 'globals'
|
del o, 'globals'
|
||||||
if @params[@params.length - 1] instanceof SplatNode
|
i: 0
|
||||||
splat: @params.pop()
|
splat: undefined
|
||||||
splat.index: @params.length
|
params: []
|
||||||
@body.unshift(splat)
|
for param in @params
|
||||||
params: (param.compile(o) for param in @params)
|
if param instanceof SplatNode and not splat?
|
||||||
|
splat: param
|
||||||
|
splat.index: i
|
||||||
|
@body.unshift(splat)
|
||||||
|
splat.trailings: []
|
||||||
|
else if splat?
|
||||||
|
splat.trailings.push(param)
|
||||||
|
else
|
||||||
|
params.push(param)
|
||||||
|
i += 1
|
||||||
|
params: (param.compile(o) for param in params)
|
||||||
(o.scope.parameter(param)) for param in params
|
(o.scope.parameter(param)) for param in params
|
||||||
code: if @body.expressions.length then "\n${ @body.compile_with_declarations(o) }\n" else ''
|
code: if @body.expressions.length then "\n${ @body.compile_with_declarations(o) }\n" else ''
|
||||||
name_part: if @name then ' ' + @name else ''
|
name_part: if @name then ' ' + @name else ''
|
||||||
@@ -768,7 +778,11 @@ exports.SplatNode: class SplatNode extends BaseNode
|
|||||||
compile_param: (o) ->
|
compile_param: (o) ->
|
||||||
name: @name.compile(o)
|
name: @name.compile(o)
|
||||||
o.scope.find name
|
o.scope.find name
|
||||||
"$name = Array.prototype.slice.call(arguments, $@index)"
|
i: 0
|
||||||
|
for trailing in @trailings
|
||||||
|
o.scope.assign(trailing.compile(o), "arguments[arguments.length - $@trailings.length + $i]")
|
||||||
|
i += 1
|
||||||
|
"$name = Array.prototype.slice.call(arguments, $@index, arguments.length - ${@trailings.length})"
|
||||||
|
|
||||||
# A compiling a splat as a destructuring assignment means slicing arguments
|
# A compiling a splat as a destructuring assignment means slicing arguments
|
||||||
# from the right-hand-side's corresponding array.
|
# from the right-hand-side's corresponding array.
|
||||||
|
|||||||
@@ -6,13 +6,14 @@ result: func 1, 2, 3, 4, 5
|
|||||||
ok result is "3 4 5"
|
ok result is "3 4 5"
|
||||||
|
|
||||||
|
|
||||||
gold: silver: bronze: the_field: null
|
gold: silver: bronze: the_field: last: null
|
||||||
|
|
||||||
medalists: (first, second, third, rest...) ->
|
medalists: (first, second, third, rest..., unlucky) ->
|
||||||
gold: first
|
gold: first
|
||||||
silver: second
|
silver: second
|
||||||
bronze: third
|
bronze: third
|
||||||
the_field: rest
|
the_field: rest.concat([last])
|
||||||
|
last: unlucky
|
||||||
|
|
||||||
contenders: [
|
contenders: [
|
||||||
"Michael Phelps"
|
"Michael Phelps"
|
||||||
@@ -32,6 +33,7 @@ medalists "Mighty Mouse", contenders...
|
|||||||
ok gold is "Mighty Mouse"
|
ok gold is "Mighty Mouse"
|
||||||
ok silver is "Michael Phelps"
|
ok silver is "Michael Phelps"
|
||||||
ok bronze is "Liu Xiang"
|
ok bronze is "Liu Xiang"
|
||||||
|
ok last is "Usain Bolt"
|
||||||
ok the_field.length is 8
|
ok the_field.length is 8
|
||||||
|
|
||||||
contenders.reverse()
|
contenders.reverse()
|
||||||
@@ -40,6 +42,7 @@ medalists contenders[0...2]..., "Mighty Mouse", contenders[2...contenders.length
|
|||||||
ok gold is "Usain Bolt"
|
ok gold is "Usain Bolt"
|
||||||
ok silver is "Asafa Powell"
|
ok silver is "Asafa Powell"
|
||||||
ok bronze is "Mighty Mouse"
|
ok bronze is "Mighty Mouse"
|
||||||
|
ok last is "Michael Phelps"
|
||||||
ok the_field.length is 8
|
ok the_field.length is 8
|
||||||
|
|
||||||
obj: {
|
obj: {
|
||||||
|
|||||||
Reference in New Issue
Block a user