@@ -1624,14 +1624,17 @@ class exports.Assign extends Node
16241624 else if (ret or len > 1 ) and (not ID .test rite .to-string ! or left .assigns rite .to-string !)
16251625 cache = sn(this , (rref = o .scope.temporary!), " = " , rite )
16261626 rite = rref
1627- list = @"rend#{ left.constructor.display-name }" o , items , rite
1627+ if rite .to-string ! is \arguments and not ret
1628+ arg = true
1629+ if left not instanceof Arr then @carp 'arguments can only destructure to array'
1630+ list = @"rend#{ left.constructor.display-name }" o , items , rite , arg
16281631 o .scope.free rref if rref
16291632 list .unshift cache if cache
16301633 list .push rite if ret or not list .length
16311634 code = []
1635+ sep = if arg then '; ' else ', '
16321636 for item in list
1633- code .push item
1634- code .push ", "
1637+ code .push item , sep
16351638 code .pop!
16361639 if list .length < 2 or o .level < LEVEL_LIST then sn(this , ...code) else sn(this , "(" , ...code, ")" )
16371640
@@ -1644,25 +1647,38 @@ class exports.Assign extends Node
16441647 .add Index (Key \concat ), \. true .add Call [right -node ])]; right ]
16451648 .compile o , LEVEL_LIST ))
16461649
1647- rendArr : (o , nodes , rite ) ->
1650+ rendArr : (o , nodes , rite , arg ) ->
1651+ ~function arg -slice(begin , end )
1652+ # [&[..] for from (begin) til (end)]
1653+ new For {+ref , from : begin , op : \til , to : end }
1654+ .make-comprehension (Chain Var \arguments .add Index Literal \..), []
16481655 for node , i in nodes
16491656 continue if node .is -empty !
16501657 if node instanceof Splat
16511658 len and node .carp 'multiple splat in an assignment'
16521659 skip = (node .=it ).is -empty !
16531660 if i +1 is len = nodes .length
16541661 break if skip
1655- val = Arr .wrap JS do
1656- util(\slice ) + \.call( + rite + if i then ", #i)" else \)
1662+ if arg
1663+ val = arg -slice do # from i to &length
1664+ Literal(i )
1665+ (Chain Var \arguments .add Index Key \length )
1666+ else
1667+ val = Arr .wrap JS do
1668+ util(\slice ) + \.call( + rite + if i then ", #i)" else \)
16571669 else
16581670 val = ivar = "#rite.length - #{ len - i - 1 }"
16591671 # Optimize `[..., a] = b`.
16601672 continue if skip and i +2 is len
16611673 start = i +1
1662- @temps = [ ivar = o .scope.temporary \i ]
1674+ @.[] temps .push ivar = o .scope.temporary \i
16631675 val = switch
16641676 | skip
16651677 Arr .wrap JS "#i < (#ivar = #val) ? #i : (#ivar = #i)"
1678+ | arg
1679+ arg -slice do
1680+ JS "#i < (#ivar = #val) ? #i : (#ivar = #i)"
1681+ Var ivar
16661682 | _
16671683 Arr .wrap JS do
16681684 "#i < (#ivar = #val)
@@ -1673,7 +1689,7 @@ class exports.Assign extends Node
16731689 val = Chain rcache ||=Literal(rite ), [Index JS inc || i ]
16741690 if node instanceof Assign
16751691 node = Binary node .op, node .left, node .right, (node .logic or true )
1676- (this with {left : node , right : val , +void })compile o , LEVEL_PAREN
1692+ (this with {left : node , right : val , +void })compile o , if arg then LEVEL_TOP else LEVEL_PAREN
16771693
16781694 rendObj : (o , nodes , rite ) ->
16791695 for node in nodes
@@ -1899,7 +1915,7 @@ class exports.Fun extends Node
18991915 # `(a = x) ->` => `(a ? x) ->`
19001916 else if p .op is \=
19011917 params [i ] = Binary (p .logic or \?), p .left, p .right
1902- # `(a, ...b, c) ->` => `(a) -> [[] ...b, c] = @@ `
1918+ # `(a, ...b, c) ->` => `(a) -> [[] ...b, c] = & `
19031919 if splace ?
19041920 rest = params .splice splace , 9e9
19051921 else if @accessor
@@ -1908,30 +1924,28 @@ class exports.Fun extends Node
19081924 params .0 = Var \it if body .traverse-children -> it .value is \it or null
19091925 names = []
19101926 assigns = []
1911- if params .length
1912- dic = {}
1913- for p in params
1914- vr = p
1915- vr .=first if df = vr .get-default !
1916- if vr .is -empty !
1917- vr = Var scope .temporary \arg
1918- else if vr .value is \..
1919- vr = Var o .ref = scope .temporary!
1920- else if vr not instanceof Var
1921- unaries = []
1922- while vr instanceof Unary
1923- has -unary = true
1924- unaries .push vr
1925- vr .=it
1926- v = Var delete (vr .it || vr )name || vr .var-name ! || scope .temporary \arg
1927- assigns .push Assign vr , switch
1928- | df => Binary p .op, v , p .second
1929- | has -unary => fold ((x , y ) -> y .it = x ; y ), v , unaries .reverse!
1930- | otherwise => v
1931- vr = v
1932- else if df
1933- assigns .push Assign vr , p .second, \=, p .op, true
1934- names .push (scope .add vr .value, \arg , p ), ', '
1927+ for p in params
1928+ vr = p
1929+ vr .=first if df = vr .get-default !
1930+ if vr .is -empty !
1931+ vr = Var scope .temporary \arg
1932+ else if vr .value is \..
1933+ vr = Var o .ref = scope .temporary!
1934+ else if vr not instanceof Var
1935+ unaries = []
1936+ while vr instanceof Unary
1937+ has -unary = true
1938+ unaries .push vr
1939+ vr .=it
1940+ v = Var delete (vr .it || vr )name || vr .var-name ! || scope .temporary \arg
1941+ assigns .push Assign vr , switch
1942+ | df => Binary p .op, v , p .second
1943+ | has -unary => fold ((x , y ) -> y .it = x ; y ), v , unaries .reverse!
1944+ | otherwise => v
1945+ vr = v
1946+ else if df
1947+ assigns .push Assign vr , p .second, \=, p .op, true
1948+ names .push (scope .add vr .value, \arg , p ), ', '
19351949 if rest
19361950 while splace -- then rest .unshift Arr !
19371951 assigns .push Assign Arr(rest ), Literal \arguments
0 commit comments