Got the DRY object pattern matching style working properly, from Harmony. {name, age}: person now works correctly.

This commit is contained in:
Jeremy Ashkenas 2010-04-25 22:21:53 -04:00
parent 328a14014c
commit a894db35fd
6 changed files with 223 additions and 183 deletions

View File

@ -127,7 +127,11 @@
],
// Assignment when it happens within an object literal. The difference from
// the ordinary **Assign** is that these allow numbers and strings as keys.
AssignObj: [o("Identifier ASSIGN Expression", function() {
AssignObj: [o("Identifier", function() {
return new ValueNode($1);
}), o("AlphaNumeric", function() {
return new ValueNode($1);
}), o("Identifier ASSIGN Expression", function() {
return new AssignNode(new ValueNode($1), $3, 'object');
}), o("AlphaNumeric ASSIGN Expression", function() {
return new AssignNode(new ValueNode($1), $3, 'object');

View File

@ -937,11 +937,18 @@
_a = this.variable.base.objects;
for (i = 0, _b = _a.length; i < _b; i++) {
obj = _a[i];
// A regular array pattern-match.
idx = i;
if (this.variable.is_object()) {
_c = [obj.value, obj.variable.base];
obj = _c[0];
idx = _c[1];
if (obj instanceof AssignNode) {
// A regular object pattern-match.
_c = [obj.value, obj.variable.base];
obj = _c[0];
idx = _c[1];
} else {
// A shorthand `{a, b, c}: val` pattern-match.
idx = obj;
}
}
if (!(obj instanceof ValueNode || obj instanceof SplatNode)) {
throw new Error('pattern matching must use only identifiers on the left-hand side.');

File diff suppressed because one or more lines are too long

View File

@ -147,6 +147,8 @@ grammar: {
# Assignment when it happens within an object literal. The difference from
# the ordinary **Assign** is that these allow numbers and strings as keys.
AssignObj: [
o "Identifier", -> new ValueNode $1
o "AlphaNumeric", -> new ValueNode $1
o "Identifier ASSIGN Expression", -> new AssignNode new ValueNode($1), $3, 'object'
o "AlphaNumeric ASSIGN Expression", -> new AssignNode new ValueNode($1), $3, 'object'
o "Comment"
@ -448,7 +450,7 @@ grammar: {
o "IN Expression WHEN Expression", -> {source: $2, filter: $4}
o "OF Expression WHEN Expression", -> {source: $2, filter: $4, object: true}
o "IN Expression BY Expression", -> {source: $2, step: $4}
o "IN Expression WHEN Expression BY Expression", -> {source: $2, filter: $4; step: $6}
o "IN Expression WHEN Expression BY Expression", -> {source: $2, filter: $4, step: $6}
o "IN Expression BY Expression WHEN Expression", -> {source: $2, step: $4, filter: $6}
]

View File

@ -690,8 +690,15 @@ exports.AssignNode: class AssignNode extends BaseNode
o.as_statement: true
splat: false
for obj, i in @variable.base.objects
# A regular array pattern-match.
idx: i
[obj, idx]: [obj.value, obj.variable.base] if @variable.is_object()
if @variable.is_object()
if obj instanceof AssignNode
# A regular object pattern-match.
[obj, idx]: [obj.value, obj.variable.base]
else
# A shorthand `{a, b, c}: val` pattern-match.
idx: obj
if not (obj instanceof ValueNode or obj instanceof SplatNode)
throw new Error 'pattern matching must use only identifiers on the left-hand side.'
is_string: idx.value and idx.value.match IS_STRING

View File

@ -89,8 +89,24 @@ test: {
ok addr.join(', ') is "Street 101, Apt 101, City 101"
# Destructuring against an expression.
# Pattern matching against an expression.
[a, b]: if true then [2, 1] else [1, 2]
ok a is 2
ok b is 1
# Pattern matching with object shorthand.
person: {
name: "Bob"
age: 26
dogs: ["Prince", "Bowie"]
}
{name, age, dogs: [first, second]}: person
ok name is "Bob"
ok age is 26
ok first is "Prince"
ok second is "Bowie"