Permalink
Browse files

optimized `[...[x]]`

  • Loading branch information...
satyr committed Mar 9, 2012
1 parent b0016bd commit e2f40fd193ac9fa48ff538ab47f72d34350969a8
Showing with 34 additions and 16 deletions.
  1. +21 −10 lib/ast.js
  2. +13 −5 src/ast.co
  3. +0 −1 test/function.co
View
@@ -2348,17 +2348,12 @@ exports.Splat = Splat = (function(superclass){
return this.carp('invalid splat');
};
Splat.compileArray = function(o, list, apply){
- var index, node, args, atoms, __i, __ref, __len;
- index = -1;
- while (node = list[++index]) {
+ var index, node, args, atoms, __len, __i, __ref;
+ expand(list);
+ for (index = 0, __len = list.length; index < __len; ++index) {
+ node = list[index];
if (node instanceof Splat) {
- if (apply && node.filler) {
- return '';
- }
- if (!node.it.isEmpty()) {
- break;
- }
- list.splice(index--, 1);
+ break;
}
}
if (index >= list.length) {
@@ -2387,6 +2382,22 @@ exports.Splat = Splat = (function(superclass){
? Arr(list)
: args.shift()).compile(o, LEVEL_CALL) + (".concat(" + List.compile(o, args) + ")");
};
+ function expand(nodes){
+ var index, node, it;
+ index = -1;
+ while (node = nodes[++index]) {
+ if (node instanceof Splat) {
+ it = node.it;
+ if (it.isEmpty()) {
+ nodes.splice(index--, 1);
+ } else if (it instanceof Arr) {
+ nodes.splice.apply(nodes, [index, 1].concat(__slice.call(expand(it.items))));
+ index += it.items.length - 1;
+ }
+ }
+ }
+ return nodes;
+ }
function ensureArray(node){
if (node.isArray()) {
return node;
View
@@ -1439,11 +1439,8 @@ class exports.Splat extends Node
# Compiles a list of nodes mixed with splats to a proper array.
@compileArray = (o, list, apply) ->
- index = -1
- while node = list[++index] then if node instanceof Splat
- return '' if apply and node.filler
- break unless node.it.isEmpty()
- list.splice index-- 1
+ expand list
+ break if node instanceof Splat for node, index of list
return '' if index >= list.length
unless list.1
return (if apply then Object else ensureArray) list.0.it
@@ -1458,6 +1455,17 @@ class exports.Splat extends Node
(if index then Arr list else args.shift())compile(o, LEVEL_CALL) +
".concat(#{ List.compile o, args })"
+ function expand nodes
+ index = -1
+ while node = nodes[++index] then if node instanceof Splat
+ {it} = node
+ if it.isEmpty!
+ nodes.splice index-- 1
+ else if it instanceof Arr
+ nodes.splice index, 1, ...expand it.items
+ index += it.items.length - 1
+ nodes
+
function ensureArray node
return node if node.isArray()
Call.make JS(utility(\slice) + \.call), [node]
View
@@ -449,7 +449,6 @@ f = (x, y) -> [this, x, y]
with 0 then let x = 1, y = 2
eq '0,1,2' ''+ f ...
eq ',' ''+ f(...[])slice 1
-throws 'invalid splat on line 1' -> Coco.compile 'f ..., a'
### do-`not`-return

0 comments on commit e2f40fd

Please sign in to comment.