copy value before making accumlator for unpack foreach

This commit is contained in:
leaf corcoran 2013-06-28 23:17:23 -07:00
parent 9a6619214d
commit 1fa83e1e9c
8 changed files with 55 additions and 24 deletions

View File

@ -46,9 +46,9 @@ local value_compilers = {
do
local _with_0 = self:line()
_with_0:append_list((function()
local _list_0 = node
local _accum_0 = { }
local _len_0 = 1
local _list_0 = node
for _index_0 = 2, #_list_0 do
local v = _list_0[_index_0]
_accum_0[_len_0] = self:value(v)

View File

@ -42,9 +42,9 @@ truncate_traceback = function(traceback, chunk_func)
end
stop = stop - 1
end
local _list_0 = traceback
traceback = { }
local _len_0 = 1
local _list_0 = traceback
local _max_0 = stop
for _index_0 = 1, _max_0 < 0 and #_list_0 + _max_0 or _max_0 do
local t = _list_0[_index_0]

View File

@ -349,11 +349,13 @@ Statement = Transformer({
if "comprehension" == _exp_0 then
local first_name = names[1]
local a = Accumulator(first_name)
node = self.transform.statement(first_value, function(exp)
local action
action = function(exp)
return a:mutate_body({
exp
})
end)
end
node = self.transform.statement(first_value, action, node)
return a:wrap(node, "group")
end
end
@ -585,9 +587,9 @@ Statement = Transformer({
wrapped = build.group({
build.declare({
names = (function()
local _list_0 = stm[2]
local _accum_0 = { }
local _len_0 = 1
local _list_0 = stm[2]
for _index_0 = 1, #_list_0 do
local name = _list_0[_index_0]
if type(name) == "string" then
@ -699,7 +701,7 @@ Statement = Transformer({
end)()
})
end,
foreach = function(self, node)
foreach = function(self, node, _, parent_assign)
smart_node(node)
local source = unpack(node.iter)
local destructures = { }
@ -727,7 +729,11 @@ Statement = Transformer({
if ntype(source) == "unpack" then
local list = source[2]
local index_name = NameProxy("index")
local list_name = self:is_local(list) and list or NameProxy("list")
local assign_name
if parent_assign then
assign_name = parent_assign[2][1]
end
local list_name = assign_name ~= list and self:is_local(list) and list or NameProxy("list")
local slice_var = nil
local bounds
if is_slice(list) then
@ -768,7 +774,7 @@ Statement = Transformer({
}
}
end
return build.group({
local out = build.group({
list_name ~= list and build.assign_one(list_name, list) or NOOP,
slice_var or NOOP,
build["for"]({
@ -786,6 +792,8 @@ Statement = Transformer({
}
})
})
out.has_unpack_copy = true
return out
end
node.body = with_continue_listener(node.body)
end,
@ -1085,9 +1093,9 @@ Statement = Transformer({
end
return self:set("super", function(block, chain)
if chain then
local _list_0 = chain
local slice = { }
local _len_0 = 1
local _list_0 = chain
for _index_0 = 3, #_list_0 do
local item = _list_0[_index_0]
slice[_len_0] = item
@ -1244,7 +1252,16 @@ do
if group_type == nil then
group_type = "block_exp"
end
local copy_list
if rawget(node, "has_unpack_copy") then
do
local _with_0 = node[2][1]
node[2][1] = NOOP
copy_list = _with_0
end
end
return build[group_type]({
copy_list or NOOP,
build.assign_one(self.accum_name, build.table()),
build.assign_one(self.len_name, 1),
node,

View File

@ -181,8 +181,8 @@ Statement = Transformer {
first_name = names[1]
a = Accumulator first_name
node = @transform.statement first_value, (exp) ->
a\mutate_body { exp }
action = (exp) -> a\mutate_body { exp }
node = @transform.statement first_value, action, node
return a\wrap node, "group"
@ -389,7 +389,7 @@ Statement = Transformer {
ret scope_name
}
foreach: (node) =>
foreach: (node, _, parent_assign) =>
smart_node node
source = unpack node.iter
@ -409,7 +409,8 @@ Statement = Transformer {
list = source[2]
index_name = NameProxy "index"
list_name = @is_local(list) and list or NameProxy "list"
assign_name = parent_assign[2][1] if parent_assign
list_name = assign_name != list and @is_local(list) and list or NameProxy "list"
slice_var = nil
bounds = if is_slice list
@ -430,7 +431,7 @@ Statement = Transformer {
else
{1, {"length", list_name}}
return build.group {
out = build.group {
list_name != list and build.assign_one(list_name, list) or NOOP
slice_var or NOOP
build["for"] {
@ -443,6 +444,9 @@ Statement = Transformer {
}
}
out.has_unpack_copy = true
return out
node.body = with_continue_listener node.body
while: (node) =>
@ -721,7 +725,12 @@ class Accumulator
-- wrap the node into a block_exp
wrap: (node, group_type="block_exp") =>
copy_list = if rawget node, "has_unpack_copy"
with node[2][1]
node[2][1] = NOOP
build[group_type] {
copy_list or NOOP
build.assign_one @accum_name, build.table!
build.assign_one @len_name, 1
node

View File

@ -1,14 +1,18 @@
local util = require("moonscript.util")
local data = require("moonscript.data")
local Set
do
local _table_0 = require("moonscript.data")
Set = _table_0.Set
end
local insert = table.insert
local unpack = util.unpack
local manual_return = data.Set({
local manual_return = Set({
"foreach",
"for",
"while",
"return"
})
local cascading = data.Set({
local cascading = Set({
"if",
"unless",
"with",

View File

@ -1,17 +1,17 @@
util = require "moonscript.util"
data = require "moonscript.data"
import Set from require "moonscript.data"
import insert from table
import unpack from util
-- implicit return does not work on these statements
manual_return = data.Set{"foreach", "for", "while", "return"}
manual_return = Set{"foreach", "for", "while", "return"}
-- Assigns and returns are bubbled into their bodies.
-- All cascading statement transform functions accept a second arugment that
-- is the transformation to apply to the last statement in their body
cascading = data.Set{ "if", "unless", "with", "switch", "class", "do" }
cascading = Set{ "if", "unless", "with", "switch", "class", "do" }
-- type of node as string
ntype = (node) ->

View File

@ -40,11 +40,11 @@ end)()
local m
m = function(...)
return (function(...)
local _accum_0 = { }
local _len_1 = 1
local _list_0 = {
...
}
local _accum_0 = { }
local _len_1 = 1
for _index_0 = 1, #_list_0 do
local x = _list_0[_index_0]
if f(...) > 4 then
@ -68,11 +68,11 @@ local x = (function(...)
end
return _accum_0
end)(...)
local y = { }
local _len_1 = 1
local _list_0 = {
...
}
local y = { }
local _len_1 = 1
for _index_0 = 1, #_list_0 do
x = _list_0[_index_0]
y[_len_1] = x

View File

@ -37,4 +37,5 @@ x = for thing in *things
if is_important thing
break thing
-- all function literals have a string that is their function definition