forked from gkz/LiveScript
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix gkz#857 Better handling of splat func arguments
See gkz#857 .
- Loading branch information
Showing
1 changed file
with
47 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1624,14 +1624,17 @@ class exports.Assign extends Node | |
else if (ret or len > 1) and (not ID.test rite.to-string! or left.assigns rite.to-string!) | ||
cache = sn(this, (rref = o.scope.temporary!), " = ", rite) | ||
rite = rref | ||
list = @"rend#{ left.constructor.display-name }" o, items, rite | ||
if rite.to-string! is \arguments and not ret | ||
This comment has been minimized.
Sorry, something went wrong. |
||
arg = true | ||
if left not instanceof Arr then @carp 'arguments can only destructure to array' | ||
list = @"rend#{ left.constructor.display-name }" o, items, rite, arg | ||
o.scope.free rref if rref | ||
list.unshift cache if cache | ||
list.push rite if ret or not list.length | ||
code = [] | ||
sep = if arg then '; ' else ', ' | ||
for item in list | ||
code.push item | ||
code.push ", " | ||
code.push item, sep | ||
code.pop! | ||
if list.length < 2 or o.level < LEVEL_LIST then sn(this, ...code) else sn(this, "(", ...code, ")") | ||
|
||
|
@@ -1644,25 +1647,38 @@ class exports.Assign extends Node | |
.add Index (Key \concat), \. true .add Call [right-node])]; right] | ||
.compile o, LEVEL_LIST)) | ||
|
||
rendArr: (o, nodes, rite) -> | ||
rendArr: (o, nodes, rite, arg) -> | ||
~function arg-slice(begin, end) | ||
# [&[..] for from (begin) til (end)] | ||
This comment has been minimized.
Sorry, something went wrong.
summivox
Author
Owner
|
||
new For {+ref, from: begin, op: \til, to: end} | ||
.make-comprehension (Chain Var \arguments .add Index Literal \..), [] | ||
for node, i in nodes | ||
continue if node.is-empty! | ||
if node instanceof Splat | ||
len and node.carp 'multiple splat in an assignment' | ||
skip = (node.=it).is-empty! | ||
if i+1 is len = nodes.length | ||
break if skip | ||
val = Arr.wrap JS do | ||
util(\slice) + \.call( + rite + if i then ", #i)" else \) | ||
if arg | ||
val = arg-slice do # from i to &length | ||
Literal(i) | ||
(Chain Var \arguments .add Index Key \length) | ||
else | ||
val = Arr.wrap JS do | ||
util(\slice) + \.call( + rite + if i then ", #i)" else \) | ||
else | ||
val = ivar = "#rite.length - #{ len - i - 1 }" | ||
# Optimize `[..., a] = b`. | ||
continue if skip and i+2 is len | ||
start = i+1 | ||
@temps = [ivar = o.scope.temporary \i] | ||
@.[]temps.push ivar = o.scope.temporary \i | ||
This comment has been minimized.
Sorry, something went wrong. |
||
val = switch | ||
| skip | ||
Arr.wrap JS "#i < (#ivar = #val) ? #i : (#ivar = #i)" | ||
| arg | ||
arg-slice do | ||
JS "#i < (#ivar = #val) ? #i : (#ivar = #i)" | ||
Var ivar | ||
| _ | ||
Arr.wrap JS do | ||
"#i < (#ivar = #val) | ||
|
@@ -1673,7 +1689,7 @@ class exports.Assign extends Node | |
val = Chain rcache||=Literal(rite), [Index JS inc || i] | ||
if node instanceof Assign | ||
node = Binary node.op, node.left, node.right, (node.logic or true) | ||
(this with {left: node, right: val, +void})compile o, LEVEL_PAREN | ||
(this with {left: node, right: val, +void})compile o, if arg then LEVEL_TOP else LEVEL_PAREN | ||
|
||
rendObj: (o, nodes, rite) -> | ||
for node in nodes | ||
|
@@ -1899,7 +1915,7 @@ class exports.Fun extends Node | |
# `(a = x) ->` => `(a ? x) ->` | ||
else if p.op is \= | ||
params[i] = Binary (p.logic or \?), p.left, p.right | ||
# `(a, ...b, c) ->` => `(a) -> [[] ...b, c] = @@` | ||
# `(a, ...b, c) ->` => `(a) -> [[] ...b, c] = &` | ||
if splace? | ||
rest = params.splice splace, 9e9 | ||
else if @accessor | ||
|
@@ -1908,30 +1924,28 @@ class exports.Fun extends Node | |
params.0 = Var \it if body.traverse-children -> it.value is \it or null | ||
names = [] | ||
assigns = [] | ||
if params.length | ||
dic = {} | ||
for p in params | ||
vr = p | ||
vr.=first if df = vr.get-default! | ||
if vr.is-empty! | ||
vr = Var scope.temporary \arg | ||
else if vr.value is \.. | ||
vr = Var o.ref = scope.temporary! | ||
else if vr not instanceof Var | ||
unaries = [] | ||
while vr instanceof Unary | ||
has-unary = true | ||
unaries.push vr | ||
vr.=it | ||
v = Var delete (vr.it || vr)name || vr.var-name! || scope.temporary \arg | ||
assigns.push Assign vr, switch | ||
| df => Binary p.op, v, p.second | ||
| has-unary => fold ((x, y) -> y.it = x; y), v, unaries.reverse! | ||
| otherwise => v | ||
vr = v | ||
else if df | ||
assigns.push Assign vr, p.second, \=, p.op, true | ||
names.push (scope.add vr.value, \arg, p), ', ' | ||
for p in params | ||
This comment has been minimized.
Sorry, something went wrong. |
||
vr = p | ||
vr.=first if df = vr.get-default! | ||
if vr.is-empty! | ||
vr = Var scope.temporary \arg | ||
else if vr.value is \.. | ||
vr = Var o.ref = scope.temporary! | ||
else if vr not instanceof Var | ||
unaries = [] | ||
while vr instanceof Unary | ||
has-unary = true | ||
unaries.push vr | ||
vr.=it | ||
v = Var delete (vr.it || vr)name || vr.var-name! || scope.temporary \arg | ||
assigns.push Assign vr, switch | ||
| df => Binary p.op, v, p.second | ||
| has-unary => fold ((x, y) -> y.it = x; y), v, unaries.reverse! | ||
| otherwise => v | ||
vr = v | ||
else if df | ||
assigns.push Assign vr, p.second, \=, p.op, true | ||
names.push (scope.add vr.value, \arg, p), ', ' | ||
if rest | ||
while splace-- then rest.unshift Arr! | ||
assigns.push Assign Arr(rest), Literal \arguments | ||
|
and not ret
So that you can still do stupid things such asin function body, although I wonder what's the point? 😕