From a59d056ad21c0fafa5241a68d9c63c328324e6f6 Mon Sep 17 00:00:00 2001 From: satyr Date: Sat, 2 Oct 2010 20:53:29 +0900 Subject: [PATCH] `[v] = a` now compiles to `v = a[0]` --- lib/nodes.js | 13 +++++++------ src/nodes.coffee | 13 ++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/nodes.js b/lib/nodes.js index 7dbdd21b..081f6b8c 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -982,19 +982,20 @@ return top || this.parenthetical ? val : ("(" + (val) + ")"); }; AssignNode.prototype.compilePatternMatch = function(o) { - var _len, _ref2, accessClass, assigns, code, i, idx, isObject, obj, objects, oindex, olength, otop, splat, top, val, valVar, value; + var _len, _ref2, accessClass, assigns, code, i, idx, isObject, obj, objects, olength, otop, splat, top, val, valVar, value; if ((value = this.value).isStatement(o)) { value = ClosureNode.wrap(value); } objects = this.variable.base.objects; - if (!(objects.length)) { + if (!(olength = objects.length)) { return value.compile(o); } - if ((isObject = this.variable.isObject()) && objects.length === 1) { - if ((obj = objects[0]) instanceof AssignNode) { + isObject = this.variable.isObject(); + if (olength === 1 && !((obj = objects[0]) instanceof SplatNode)) { + if (obj instanceof AssignNode) { _ref2 = obj, idx = _ref2.variable.base, obj = _ref2.value; } else { - idx = obj; + idx = isObject ? obj : literal(0); } if (!(value instanceof ValueNode)) { value = new ValueNode(value); @@ -1025,7 +1026,7 @@ } accessClass = isObject && IDENTIFIER.test(idx.value) ? AccessorNode : IndexNode; if (!splat && obj instanceof SplatNode) { - val = literal(obj.compileValue(o, valVar, oindex = indexOf(objects, obj), (olength = objects.length) - oindex - 1)); + val = literal(obj.compileValue(o, valVar, i, olength - i - 1)); splat = true; } else { if (typeof idx !== 'object') { diff --git a/src/nodes.coffee b/src/nodes.coffee index f9ce91ee..f5769942 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -875,13 +875,14 @@ exports.AssignNode = class AssignNode extends BaseNode compilePatternMatch: (o) -> if (value = @value).isStatement o then value = ClosureNode.wrap value {objects} = @variable.base - return value.compile o unless objects.length - if (isObject = @variable.isObject()) and objects.length is 1 + return value.compile o unless olength = objects.length + isObject = @variable.isObject() + if olength is 1 and (obj = objects[0]) not instanceof SplatNode # Unroll simplest cases: `{v} = x` -> `v = x.v` - if (obj = objects[0]) instanceof AssignNode + if obj instanceof AssignNode {variable: {base: idx}, value: obj} = obj else - idx = obj + idx = if isObject then obj else literal 0 value = new ValueNode value unless value instanceof ValueNode accessClass = if IDENTIFIER.test idx.value then AccessorNode else IndexNode value.properties.push new accessClass idx @@ -905,9 +906,7 @@ exports.AssignNode = class AssignNode extends BaseNode throw new Error 'pattern matching must use only identifiers on the left-hand side.' accessClass = if isObject and IDENTIFIER.test(idx.value) then AccessorNode else IndexNode if not splat and obj instanceof SplatNode - val = literal obj.compileValue o, valVar, - (oindex = indexOf objects, obj), - (olength = objects.length) - oindex - 1 + val = literal obj.compileValue o, valVar, i, olength - i - 1 splat = true else idx = literal(if splat then "#{valVar}.length - #{olength - idx}" else idx) if typeof idx isnt 'object'