Skip to content

Commit 1fa83e1

Browse files
committed
copy value before making accumlator for unpack foreach
1 parent 9a66192 commit 1fa83e1

File tree

8 files changed

+55
-24
lines changed

8 files changed

+55
-24
lines changed

moonscript/compile/value.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ local value_compilers = {
4646
do
4747
local _with_0 = self:line()
4848
_with_0:append_list((function()
49+
local _list_0 = node
4950
local _accum_0 = { }
5051
local _len_0 = 1
51-
local _list_0 = node
5252
for _index_0 = 2, #_list_0 do
5353
local v = _list_0[_index_0]
5454
_accum_0[_len_0] = self:value(v)

moonscript/errors.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ truncate_traceback = function(traceback, chunk_func)
4242
end
4343
stop = stop - 1
4444
end
45+
local _list_0 = traceback
4546
traceback = { }
4647
local _len_0 = 1
47-
local _list_0 = traceback
4848
local _max_0 = stop
4949
for _index_0 = 1, _max_0 < 0 and #_list_0 + _max_0 or _max_0 do
5050
local t = _list_0[_index_0]

moonscript/transform.lua

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -349,11 +349,13 @@ Statement = Transformer({
349349
if "comprehension" == _exp_0 then
350350
local first_name = names[1]
351351
local a = Accumulator(first_name)
352-
node = self.transform.statement(first_value, function(exp)
352+
local action
353+
action = function(exp)
353354
return a:mutate_body({
354355
exp
355356
})
356-
end)
357+
end
358+
node = self.transform.statement(first_value, action, node)
357359
return a:wrap(node, "group")
358360
end
359361
end
@@ -585,9 +587,9 @@ Statement = Transformer({
585587
wrapped = build.group({
586588
build.declare({
587589
names = (function()
590+
local _list_0 = stm[2]
588591
local _accum_0 = { }
589592
local _len_0 = 1
590-
local _list_0 = stm[2]
591593
for _index_0 = 1, #_list_0 do
592594
local name = _list_0[_index_0]
593595
if type(name) == "string" then
@@ -699,7 +701,7 @@ Statement = Transformer({
699701
end)()
700702
})
701703
end,
702-
foreach = function(self, node)
704+
foreach = function(self, node, _, parent_assign)
703705
smart_node(node)
704706
local source = unpack(node.iter)
705707
local destructures = { }
@@ -727,7 +729,11 @@ Statement = Transformer({
727729
if ntype(source) == "unpack" then
728730
local list = source[2]
729731
local index_name = NameProxy("index")
730-
local list_name = self:is_local(list) and list or NameProxy("list")
732+
local assign_name
733+
if parent_assign then
734+
assign_name = parent_assign[2][1]
735+
end
736+
local list_name = assign_name ~= list and self:is_local(list) and list or NameProxy("list")
731737
local slice_var = nil
732738
local bounds
733739
if is_slice(list) then
@@ -768,7 +774,7 @@ Statement = Transformer({
768774
}
769775
}
770776
end
771-
return build.group({
777+
local out = build.group({
772778
list_name ~= list and build.assign_one(list_name, list) or NOOP,
773779
slice_var or NOOP,
774780
build["for"]({
@@ -786,6 +792,8 @@ Statement = Transformer({
786792
}
787793
})
788794
})
795+
out.has_unpack_copy = true
796+
return out
789797
end
790798
node.body = with_continue_listener(node.body)
791799
end,
@@ -1085,9 +1093,9 @@ Statement = Transformer({
10851093
end
10861094
return self:set("super", function(block, chain)
10871095
if chain then
1096+
local _list_0 = chain
10881097
local slice = { }
10891098
local _len_0 = 1
1090-
local _list_0 = chain
10911099
for _index_0 = 3, #_list_0 do
10921100
local item = _list_0[_index_0]
10931101
slice[_len_0] = item
@@ -1244,7 +1252,16 @@ do
12441252
if group_type == nil then
12451253
group_type = "block_exp"
12461254
end
1255+
local copy_list
1256+
if rawget(node, "has_unpack_copy") then
1257+
do
1258+
local _with_0 = node[2][1]
1259+
node[2][1] = NOOP
1260+
copy_list = _with_0
1261+
end
1262+
end
12471263
return build[group_type]({
1264+
copy_list or NOOP,
12481265
build.assign_one(self.accum_name, build.table()),
12491266
build.assign_one(self.len_name, 1),
12501267
node,

moonscript/transform.moon

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,8 @@ Statement = Transformer {
181181
first_name = names[1]
182182

183183
a = Accumulator first_name
184-
node = @transform.statement first_value, (exp) ->
185-
a\mutate_body { exp }
184+
action = (exp) -> a\mutate_body { exp }
185+
node = @transform.statement first_value, action, node
186186

187187
return a\wrap node, "group"
188188

@@ -389,7 +389,7 @@ Statement = Transformer {
389389
ret scope_name
390390
}
391391

392-
foreach: (node) =>
392+
foreach: (node, _, parent_assign) =>
393393
smart_node node
394394
source = unpack node.iter
395395

@@ -409,7 +409,8 @@ Statement = Transformer {
409409
list = source[2]
410410

411411
index_name = NameProxy "index"
412-
list_name = @is_local(list) and list or NameProxy "list"
412+
assign_name = parent_assign[2][1] if parent_assign
413+
list_name = assign_name != list and @is_local(list) and list or NameProxy "list"
413414

414415
slice_var = nil
415416
bounds = if is_slice list
@@ -430,7 +431,7 @@ Statement = Transformer {
430431
else
431432
{1, {"length", list_name}}
432433

433-
return build.group {
434+
out = build.group {
434435
list_name != list and build.assign_one(list_name, list) or NOOP
435436
slice_var or NOOP
436437
build["for"] {
@@ -443,6 +444,9 @@ Statement = Transformer {
443444
}
444445
}
445446

447+
out.has_unpack_copy = true
448+
return out
449+
446450
node.body = with_continue_listener node.body
447451

448452
while: (node) =>
@@ -721,7 +725,12 @@ class Accumulator
721725

722726
-- wrap the node into a block_exp
723727
wrap: (node, group_type="block_exp") =>
728+
copy_list = if rawget node, "has_unpack_copy"
729+
with node[2][1]
730+
node[2][1] = NOOP
731+
724732
build[group_type] {
733+
copy_list or NOOP
725734
build.assign_one @accum_name, build.table!
726735
build.assign_one @len_name, 1
727736
node

moonscript/types.lua

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
local util = require("moonscript.util")
2-
local data = require("moonscript.data")
2+
local Set
3+
do
4+
local _table_0 = require("moonscript.data")
5+
Set = _table_0.Set
6+
end
37
local insert = table.insert
48
local unpack = util.unpack
5-
local manual_return = data.Set({
9+
local manual_return = Set({
610
"foreach",
711
"for",
812
"while",
913
"return"
1014
})
11-
local cascading = data.Set({
15+
local cascading = Set({
1216
"if",
1317
"unless",
1418
"with",

moonscript/types.moon

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11

22
util = require "moonscript.util"
3-
data = require "moonscript.data"
3+
import Set from require "moonscript.data"
44

55
import insert from table
66
import unpack from util
77

88
-- implicit return does not work on these statements
9-
manual_return = data.Set{"foreach", "for", "while", "return"}
9+
manual_return = Set{"foreach", "for", "while", "return"}
1010

1111
-- Assigns and returns are bubbled into their bodies.
1212
-- All cascading statement transform functions accept a second arugment that
1313
-- is the transformation to apply to the last statement in their body
14-
cascading = data.Set{ "if", "unless", "with", "switch", "class", "do" }
14+
cascading = Set{ "if", "unless", "with", "switch", "class", "do" }
1515

1616
-- type of node as string
1717
ntype = (node) ->

spec/outputs/bubbling.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ end)()
4040
local m
4141
m = function(...)
4242
return (function(...)
43-
local _accum_0 = { }
44-
local _len_1 = 1
4543
local _list_0 = {
4644
...
4745
}
46+
local _accum_0 = { }
47+
local _len_1 = 1
4848
for _index_0 = 1, #_list_0 do
4949
local x = _list_0[_index_0]
5050
if f(...) > 4 then
@@ -68,11 +68,11 @@ local x = (function(...)
6868
end
6969
return _accum_0
7070
end)(...)
71-
local y = { }
72-
local _len_1 = 1
7371
local _list_0 = {
7472
...
7573
}
74+
local y = { }
75+
local _len_1 = 1
7676
for _index_0 = 1, #_list_0 do
7777
x = _list_0[_index_0]
7878
y[_len_1] = x

thoughts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,5 @@ x = for thing in *things
3737
if is_important thing
3838
break thing
3939

40+
-- all function literals have a string that is their function definition
4041

0 commit comments

Comments
 (0)