Skip to content

Commit 175e1de

Browse files
committed
void/null now work as same as []/{} in LHS
1 parent 0a2ed59 commit 175e1de

File tree

4 files changed

+54
-21
lines changed

4 files changed

+54
-21
lines changed

extras/coco.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/nodes.js

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var Node, Negatable, Lines, Literal, Key, Index, Value, Call, Clone, Obj, Arr, Op, Assign, Import, Of, Existence, Fun, Class, Super, Parens, Splat, Statement, Throw, Return, While, For, Try, Switch, Case, If, Comment, Util, SE, UTILITIES, LEVEL_TOP, LEVEL_PAREN, LEVEL_LIST, LEVEL_COND, LEVEL_OP, LEVEL_ACCESS, TAB, IDENTIFIER, _ref, __extends = function(sub, sup){
1+
var Node, Negatable, Lines, Literal, Key, Index, Value, Call, Clone, List, Obj, Arr, Op, Assign, Import, Of, Existence, Fun, Class, Super, Parens, Splat, Statement, Throw, Return, While, For, Try, Switch, Case, If, Comment, Util, SE, UTILITIES, LEVEL_TOP, LEVEL_PAREN, LEVEL_LIST, LEVEL_COND, LEVEL_OP, LEVEL_ACCESS, TAB, IDENTIFIER, _ref, __extends = function(sub, sup){
22
function ctor(){} ctor.prototype = (sub.superclass = sup).prototype;
33
return (sub.prototype = new ctor).constructor = sub;
44
}, __importAll = function(obj, src){ for (var key in src) obj[key] = src[key]; return obj };
@@ -135,6 +135,7 @@ Node = (function(){
135135
_proto.isComplex = YES;
136136
_proto.isStatement = NO;
137137
_proto.isAssignable = NO;
138+
_proto.isEmpty = NO;
138139
_proto.jumps = NO;
139140
_proto.assigns = NO;
140141
_proto.hasDefault = NO;
@@ -319,6 +320,13 @@ exports.Literal = Literal = (function(_super){
319320
return '"' + this.value + '"';
320321
};
321322
_proto.isComplex = NO;
323+
_proto.isEmpty = function(){
324+
switch (this.value) {
325+
case 'void':
326+
case 'null':
327+
return true;
328+
}
329+
};
322330
_proto.isAssignable = function(){
323331
return IDENTIFIER.test(this.value);
324332
};
@@ -756,6 +764,15 @@ exports.Clone = Clone = (function(_super){
756764
};
757765
return Clone;
758766
}(Node));
767+
List = (function(_super){
768+
var _proto = __extends(List, _super).prototype;
769+
function List(){} List.name = 'List';
770+
_proto.children = ['items'];
771+
_proto.isEmpty = function(){
772+
return !this.items.length;
773+
};
774+
return List;
775+
}(Node));
759776
exports.Obj = Obj = (function(_super){
760777
var _proto = __extends(Obj, _super).prototype;
761778
function _ctor(){} _ctor.prototype = _proto;
@@ -764,7 +781,6 @@ exports.Obj = Obj = (function(_super){
764781
_this.items = items || [];
765782
return _this;
766783
} Obj.name = 'Obj';
767-
_proto.children = ['items'];
768784
_proto.assigns = function(it){
769785
var node, _i, _ref, _len;
770786
for (_i = 0, _len = (_ref = this.items).length; _i < _len; ++_i) {
@@ -829,7 +845,7 @@ exports.Obj = Obj = (function(_super){
829845
}
830846
};
831847
return Obj;
832-
}(Node));
848+
}(List));
833849
exports.Arr = Arr = (function(_super){
834850
var _proto = __extends(Arr, _super).prototype;
835851
function _ctor(){} _ctor.prototype = _proto;
@@ -863,7 +879,7 @@ exports.Arr = Arr = (function(_super){
863879
}
864880
};
865881
return Arr;
866-
}(Obj));
882+
}(List));
867883
exports.Op = Op = (function(_super){
868884
var EQUALITY, COMPARER, _proto = __extends(Op, _super).prototype;
869885
function _ctor(){} _ctor.prototype = _proto;
@@ -1045,7 +1061,11 @@ exports.Assign = Assign = (function(_super){
10451061
};
10461062
METHOD_DEF = /^(?:([\s\S]+)\.prototype(?=\.)|[\s\S]*?)(?:(?:\.|^)([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)|\[(([\"\']).+?\4|\d+)])$/;
10471063
_proto.compileNode = function(o){
1048-
var left, right, name, that, val, code;
1064+
var right, left, name, that, val, code;
1065+
right = this.right;
1066+
if (this.left.isEmpty()) {
1067+
return right.compile(o, LEVEL_ACCESS);
1068+
}
10491069
left = this.transleft(o);
10501070
if (left.items) {
10511071
if (!this.logic) {
@@ -1056,7 +1076,6 @@ exports.Assign = Assign = (function(_super){
10561076
if (this.logic) {
10571077
return this.compileConditional(o, left);
10581078
}
1059-
right = this.right;
10601079
if (left.hasDefault()) {
10611080
right = Op(left.op, right, left.second);
10621081
left = left.first;
@@ -1102,9 +1121,7 @@ exports.Assign = Assign = (function(_super){
11021121
_proto.compileDestructuring = function(o, left){
11031122
var items, len, rite, rref, cache, list, code;
11041123
items = left.items;
1105-
if (!(len = items.length)) {
1106-
return this.right.compile(o, LEVEL_ACCESS);
1107-
}
1124+
len = items.length;
11081125
rite = this.right.compile(o, len === 1 ? LEVEL_ACCESS : LEVEL_LIST);
11091126
if ((len > 1 || o.level) && (!IDENTIFIER.test(rite) || left.assigns(rite))) {
11101127
cache = "" + (rref = o.scope.temporary('ref')) + " = " + rite;
@@ -1133,7 +1150,7 @@ exports.Assign = Assign = (function(_super){
11331150
var i, node, len, val, ivar, start, inc, lr, _len, _results = [];
11341151
for (i = 0, _len = nodes.length; i < _len; ++i) {
11351152
node = nodes[i];
1136-
if (node.items && !node.items.length) {
1153+
if (node.isEmpty()) {
11371154
continue;
11381155
}
11391156
if (node instanceof Splat) {
@@ -1465,7 +1482,9 @@ exports.Fun = Fun = (function(_super){
14651482
} else if (arg instanceof Splat) {
14661483
arg = arg.it;
14671484
}
1468-
if (arg.isComplex()) {
1485+
if (arg.isEmpty()) {
1486+
arg = Literal(scope.temporary('arg'));
1487+
} else if (arg.isComplex()) {
14691488
val = ref = paramName(o, p);
14701489
if (dfv) {
14711490
val = Op(p.op, ref, p.second);

src/nodes.co

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class Node
106106
isComplex : YES
107107
isStatement : NO
108108
isAssignable : NO
109+
isEmpty : NO
109110
# Do I contain a statement that jumps out of me?
110111
jumps: NO
111112
# Do I assign a certain variable?
@@ -225,6 +226,9 @@ class exports.Literal extends Node
225226

226227
isComplex: NO
227228

229+
isEmpty: ->
230+
switch @value case <[ void null ]> then return true
231+
228232
isAssignable : -> IDENTIFIER.test @value
229233
assigns : -> it is @value
230234

@@ -487,13 +491,17 @@ class exports.Clone extends Node
487491
call = Parens call, true if @newed
488492
Import(call, @mixin).compileNode o
489493

494+
#### List
495+
# An abstract node for a list of items.
496+
class List extends Node
497+
children : [\items]
498+
isEmpty : -> not @items.length
499+
490500
#### Obj
491501
# `{x: y}`
492-
class exports.Obj extends Node
502+
class exports.Obj extends List
493503
(@items or []) =>
494504

495-
children: [\items]
496-
497505
assigns: -> return true if node.assigns it for node of @items
498506

499507
compileNode: (o) ->
@@ -530,7 +538,7 @@ class exports.Obj extends Node
530538

531539
#### Arr
532540
# `[x, y]`
533-
class exports.Arr extends Obj
541+
class exports.Arr extends List
534542
(@items or []) =>
535543

536544
compileNode: (o) ->
@@ -665,12 +673,13 @@ class exports.Assign extends Node
665673
$ ///
666674

667675
compileNode: (o) ->
676+
{right} = this
677+
return right.compile o, LEVEL_ACCESS if @left.isEmpty()
668678
left = @transleft o
669679
if left.items
670680
return @compileDestructuring o, left unless @logic
671681
throw SE "\"#{@show()}\" cannot destructure"
672682
return @compileConditional o, left if @logic
673-
{right} = this
674683
if left.hasDefault()
675684
right = Op left.op, right, left.second
676685
left.=first
@@ -703,8 +712,7 @@ class exports.Assign extends Node
703712
# when assigning to an array or object literal.
704713
# See <http://wiki.ecmascript.org/doku.php?id=harmony:destructuring>.
705714
compileDestructuring: (o, left) ->
706-
{items} = left
707-
return @right.compile o, LEVEL_ACCESS unless len = items.length
715+
{items} = left; len = items.length
708716
rite = @right.compile o, if len is 1 then LEVEL_ACCESS else LEVEL_LIST
709717
if (len > 1 or o.level) and
710718
(not IDENTIFIER.test(rite) or left.assigns(rite))
@@ -721,7 +729,7 @@ class exports.Assign extends Node
721729

722730
destructArr: (o, nodes, rite) ->
723731
for node, i of nodes
724-
continue if node.items and not node.items.length
732+
continue if node.isEmpty()
725733
if node instanceof Splat
726734
throw SE 'multiple splats in an assignment' if ivar
727735
len = nodes.length
@@ -928,7 +936,9 @@ class exports.Fun extends Node
928936
arg = p
929937
if dfv = arg.hasDefault() then arg.=first
930938
else if arg instanceof Splat then arg.=it
931-
if arg.isComplex()
939+
if arg.isEmpty()
940+
arg = Literal scope.temporary \arg
941+
else if arg.isComplex()
932942
val = ref = paramName o, p
933943
val = Op p.op, ref, p.second if dfv
934944
asns.push Assign arg, val

test/assignment.co

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,7 @@ new ->
233233

234234
@{a ? 2, \b ? 3, ([\c]) ? 5} = {}
235235
eq @a * @b * @c, 30
236+
237+
238+
[void, null, v] = [1 to 3]
239+
eq v, 3

0 commit comments

Comments
 (0)