diff --git a/lib/nodes.js b/lib/nodes.js index 8b0c961e..4400601f 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -1,5 +1,5 @@ (function(){ - var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, CommentNode, CurryNode, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IfNode, IndexNode, LiteralNode, ObjectNode, OpNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, Scope, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, UTILITIES, ValueNode, WhileNode, compact, del, flatten, helpers, literal, merge, statement, utility; + var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, CommentNode, CurryNode, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IS_STRING, IfNode, IndexNode, LiteralNode, ObjectNode, OpNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, Scope, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, UTILITIES, ValueNode, WhileNode, compact, del, flatten, helpers, literal, merge, statement, utility; var __extends = function(child, parent) { var ctor = function(){ }; ctor.prototype = parent.prototype; @@ -927,7 +927,7 @@ // See the [ECMAScript Harmony Wiki](http://wiki.ecmascript.org/doku.php?id=harmony:destructuring) // for details. AssignNode.prototype.compile_pattern_match = function compile_pattern_match(o) { - var _a, _b, _c, access_class, assigns, code, i, idx, obj, oindex, olength, splat, val, val_var, value; + var _a, _b, _c, access_class, assigns, code, i, idx, is_string, obj, oindex, olength, splat, val, val_var, value; val_var = o.scope.free_variable(); value = this.value.is_statement() ? ClosureNode.wrap(this.value) : this.value; assigns = [("" + this.tab + val_var + " = " + (value.compile(o)) + ";")]; @@ -943,7 +943,8 @@ obj = _c[0]; idx = _c[1]; } - access_class = this.variable.is_array() ? IndexNode : AccessorNode; + is_string = idx.value && idx.value.match(IS_STRING); + access_class = is_string || this.variable.is_array() ? IndexNode : AccessorNode; if (obj instanceof SplatNode && !splat) { val = literal(obj.compile_value(o, val_var, (oindex = this.variable.base.objects.indexOf(obj)), (olength = this.variable.base.objects.length) - oindex - 1)); splat = true; @@ -1755,6 +1756,8 @@ TRAILING_WHITESPACE = /\s+$/gm; // Keep this identifier regex in sync with the Lexer. IDENTIFIER = /^[a-zA-Z\$_](\w|\$)*$/; + // Is a literal value a string? + IS_STRING = /^['"]/; // Utility Functions // ----------------- // Handy helper for a generating LiteralNode. diff --git a/src/nodes.coffee b/src/nodes.coffee index 739f4a21..f8c938a2 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -692,7 +692,8 @@ exports.AssignNode: class AssignNode extends BaseNode for obj, i in @variable.base.objects idx: i [obj, idx]: [obj.value, obj.variable.base] if @variable.is_object() - access_class: if @variable.is_array() then IndexNode else AccessorNode + is_string: idx.value and idx.value.match IS_STRING + access_class: if is_string or @variable.is_array() then IndexNode else AccessorNode if obj instanceof SplatNode and not splat val: literal(obj.compile_value(o, val_var, (oindex: @variable.base.objects.indexOf(obj)), @@ -1331,6 +1332,9 @@ TRAILING_WHITESPACE: /\s+$/gm # Keep this identifier regex in sync with the Lexer. IDENTIFIER: /^[a-zA-Z\$_](\w|\$)*$/ +# Is a literal value a string? +IS_STRING: /^['"]/ + # Utility Functions # ----------------- diff --git a/test/test_pattern_matching.coffee b/test/test_pattern_matching.coffee index e82edccc..b6959830 100644 --- a/test/test_pattern_matching.coffee +++ b/test/test_pattern_matching.coffee @@ -56,7 +56,7 @@ ok c is 30 person: { name: "Moe" family: { - brother: { + 'elder-brother': { addresses: [ "first" { @@ -68,7 +68,7 @@ person: { } } -{name: a, family: {brother: {addresses: [one, {city: b}]}}}: person +{name: a, family: {'elder-brother': {addresses: [one, {city: b}]}}}: person ok a is "Moe" ok b is "Moquasset NY, 10021"