mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Added splats positional flexibility to pattern matching
This commit is contained in:
parent
b7519cb834
commit
296808d4d3
3 changed files with 39 additions and 13 deletions
20
lib/nodes.js
20
lib/nodes.js
|
@ -934,12 +934,13 @@
|
||||||
// See the [ECMAScript Harmony Wiki](http://wiki.ecmascript.org/doku.php?id=harmony:destructuring)
|
// See the [ECMAScript Harmony Wiki](http://wiki.ecmascript.org/doku.php?id=harmony:destructuring)
|
||||||
// for details.
|
// for details.
|
||||||
AssignNode.prototype.compile_pattern_match = function compile_pattern_match(o) {
|
AssignNode.prototype.compile_pattern_match = function compile_pattern_match(o) {
|
||||||
var _a, _b, _c, access_class, assigns, code, i, idx, obj, val, val_var, value;
|
var _a, _b, _c, access_class, assigns, code, i, idx, obj, oindex, olength, splatted, val, val_var, value;
|
||||||
val_var = o.scope.free_variable();
|
val_var = o.scope.free_variable();
|
||||||
value = this.value.is_statement() ? ClosureNode.wrap(this.value) : this.value;
|
value = this.value.is_statement() ? ClosureNode.wrap(this.value) : this.value;
|
||||||
assigns = ['' + this.tab + val_var + " = " + (value.compile(o)) + ";"];
|
assigns = ['' + this.tab + val_var + " = " + (value.compile(o)) + ";"];
|
||||||
o.top = true;
|
o.top = true;
|
||||||
o.as_statement = true;
|
o.as_statement = true;
|
||||||
|
splatted = false;
|
||||||
_a = this.variable.base.objects;
|
_a = this.variable.base.objects;
|
||||||
for (i = 0, _b = _a.length; i < _b; i++) {
|
for (i = 0, _b = _a.length; i < _b; i++) {
|
||||||
obj = _a[i];
|
obj = _a[i];
|
||||||
|
@ -950,12 +951,11 @@
|
||||||
idx = _c[1];
|
idx = _c[1];
|
||||||
}
|
}
|
||||||
access_class = this.variable.is_array() ? IndexNode : AccessorNode;
|
access_class = this.variable.is_array() ? IndexNode : AccessorNode;
|
||||||
if (obj instanceof SplatNode) {
|
if (obj instanceof SplatNode && !splatted) {
|
||||||
val = literal(obj.compile_value(o, val_var, this.variable.base.objects.indexOf(obj)));
|
val = literal(obj.compile_value(o, val_var, ((oindex = this.variable.base.objects.indexOf(obj))), ((olength = this.variable.base.objects.length)) - oindex - 1));
|
||||||
|
splatted = true;
|
||||||
} else {
|
} else {
|
||||||
if (!(typeof idx === 'object')) {
|
typeof idx !== 'object' ? splatted ? (idx = literal('' + (val_var) + ".length - " + (olength - idx))) : (idx = literal(idx)) : null;
|
||||||
idx = literal(idx);
|
|
||||||
}
|
|
||||||
val = new ValueNode(literal(val_var), [new access_class(idx)]);
|
val = new ValueNode(literal(val_var), [new access_class(idx)]);
|
||||||
}
|
}
|
||||||
assigns.push(new AssignNode(obj, val).compile(o));
|
assigns.push(new AssignNode(obj, val).compile(o));
|
||||||
|
@ -1123,8 +1123,12 @@
|
||||||
};
|
};
|
||||||
// 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.
|
||||||
SplatNode.prototype.compile_value = function compile_value(o, name, index) {
|
SplatNode.prototype.compile_value = function compile_value(o, name, index, trailings) {
|
||||||
return "Array.prototype.slice.call(" + name + ", " + index + ")";
|
if ((typeof trailings !== "undefined" && trailings !== null)) {
|
||||||
|
return "Array.prototype.slice.call(" + name + ", " + index + ", " + (name) + ".length - " + trailings + ")";
|
||||||
|
} else {
|
||||||
|
return "Array.prototype.slice.call(" + name + ", " + index + ")";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return SplatNode;
|
return SplatNode;
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|
|
@ -708,14 +708,21 @@ exports.AssignNode: class AssignNode extends BaseNode
|
||||||
assigns: ["$@tab$val_var = ${ value.compile(o) };"]
|
assigns: ["$@tab$val_var = ${ value.compile(o) };"]
|
||||||
o.top: true
|
o.top: true
|
||||||
o.as_statement: true
|
o.as_statement: true
|
||||||
|
splatted: false
|
||||||
for obj, i in @variable.base.objects
|
for obj, i in @variable.base.objects
|
||||||
idx: i
|
idx: i
|
||||||
[obj, idx]: [obj.value, obj.variable.base] if @variable.is_object()
|
[obj, idx]: [obj.value, obj.variable.base] if @variable.is_object()
|
||||||
access_class: if @variable.is_array() then IndexNode else AccessorNode
|
access_class: if @variable.is_array() then IndexNode else AccessorNode
|
||||||
if obj instanceof SplatNode
|
if obj instanceof SplatNode and not splatted
|
||||||
val: literal(obj.compile_value(o, val_var, @variable.base.objects.indexOf(obj)))
|
val: literal(obj.compile_value(o, val_var, (oindex: @variable.base.objects.indexOf(obj)),
|
||||||
|
(olength: @variable.base.objects.length) - oindex - 1))
|
||||||
|
splatted: true
|
||||||
else
|
else
|
||||||
idx: literal(idx) unless typeof idx is 'object'
|
if typeof idx isnt 'object'
|
||||||
|
if splatted
|
||||||
|
idx: literal("${val_var}.length - ${olength - idx}")
|
||||||
|
else
|
||||||
|
idx: literal(idx)
|
||||||
val: new ValueNode(literal(val_var), [new access_class(idx)])
|
val: new ValueNode(literal(val_var), [new access_class(idx)])
|
||||||
assigns.push(new AssignNode(obj, val).compile(o))
|
assigns.push(new AssignNode(obj, val).compile(o))
|
||||||
code: assigns.join("\n")
|
code: assigns.join("\n")
|
||||||
|
@ -829,8 +836,9 @@ exports.SplatNode: class SplatNode extends BaseNode
|
||||||
|
|
||||||
# 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.
|
||||||
compile_value: (o, name, index) ->
|
compile_value: (o, name, index, trailings) ->
|
||||||
"Array.prototype.slice.call($name, $index)"
|
if trailings? then "Array.prototype.slice.call($name, $index, ${name}.length - $trailings)" \
|
||||||
|
else "Array.prototype.slice.call($name, $index)"
|
||||||
|
|
||||||
# Utility function that converts arbitrary number of elements, mixed with
|
# Utility function that converts arbitrary number of elements, mixed with
|
||||||
# splats, to a proper array
|
# splats, to a proper array
|
||||||
|
|
|
@ -28,6 +28,20 @@ ok a is 1
|
||||||
ok b is 2
|
ok b is 2
|
||||||
ok c is 3
|
ok c is 3
|
||||||
|
|
||||||
|
[x,y...,z]: [1,2,3,4,5]
|
||||||
|
|
||||||
|
ok x is 1
|
||||||
|
ok y.length is 3
|
||||||
|
ok z is 5
|
||||||
|
|
||||||
|
[x, [y, mids..., last], z..., end]: [1, [10, 20, 30, 40], 2,3,4, 5]
|
||||||
|
|
||||||
|
ok x is 1
|
||||||
|
ok y is 10
|
||||||
|
ok mids.length is 2 and mids[1] is 30
|
||||||
|
ok last is 40
|
||||||
|
ok z.length is 3 and z[2] is 4
|
||||||
|
ok end is 5
|
||||||
|
|
||||||
obj: {x: 10, y: 20, z: 30}
|
obj: {x: 10, y: 20, z: 30}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue