handing the transformation of decorator with implicit return in all cases

This commit is contained in:
leaf corcoran 2012-10-27 15:51:34 -07:00
parent b404f2d7c8
commit df7ca32a4c
7 changed files with 97 additions and 51 deletions

View File

@ -28,15 +28,9 @@ value = function(op)
return flat_value(op)
end
tree = function(block)
return (function()
local _accum_0 = { }
local _len_0 = 0
local _list_0 = block
for _index_0 = 1, #_list_0 do
value = _list_0[_index_0]
_len_0 = _len_0 + 1
_accum_0[_len_0] = print(flat_value(value))
end
return _accum_0
end)()
local _list_0 = block
for _index_0 = 1, #_list_0 do
value = _list_0[_index_0]
print(flat_value(value))
end
end

View File

@ -376,32 +376,38 @@ construct_comprehension = function(inner, clauses)
end
Statement = Transformer({
assign = function(self, node)
local _, names, values = unpack(node)
if #values == 1 and types.cascading[ntype(values[1])] then
values[1] = self.transform.statement(values[1], function(stm)
local t = ntype(stm)
if types.is_value(stm) then
return {
"assign",
names,
{
stm
}
}
else
return stm
end
end)
return build.group({
{
"declare",
names
},
values[1]
})
else
return node
local names, values = unpack(node, 2)
local transformed
if #values == 1 then
local value = values[1]
local t = ntype(value)
if t == "decorated" then
value = self.transform.statement(value)
t = ntype(value)
end
if types.cascading[t] then
transformed = build.group({
{
"declare",
names
},
self.transform.statement(value, function(stm)
if types.is_value(stm) then
return {
"assign",
names,
{
stm
}
}
else
return stm
end
end)
})
end
end
return transformed or node
end,
export = function(self, node)
if #node > 2 then
@ -1258,6 +1264,9 @@ Value = Transformer({
["for"] = default_accumulator,
["while"] = default_accumulator,
foreach = default_accumulator,
decorated = function(self, node)
return self.transform.statement(node)
end,
string = function(self, node)
local delim = node[2]
local convert_part

View File

@ -160,22 +160,28 @@ construct_comprehension = (inner, clauses) ->
Statement = Transformer {
assign: (node) =>
_, names, values = unpack node
names, values = unpack node, 2
-- bubble cascading assigns
if #values == 1 and types.cascading[ntype values[1]]
values[1] = @transform.statement values[1], (stm) ->
t = ntype stm
if types.is_value stm
{"assign", names, {stm}}
else
stm
transformed = if #values == 1
value = values[1]
t = ntype value
if t == "decorated"
value = @transform.statement value
t = ntype value
if types.cascading[t]
build.group {
{"declare", names}
@transform.statement value, (stm) ->
if types.is_value stm
{"assign", names, {stm}}
else
stm
}
transformed or node
build.group {
{"declare", names}
values[1]
}
else
node
export: (node) =>
-- assign values if they are included
@ -655,6 +661,9 @@ Value = Transformer {
while: default_accumulator
foreach: default_accumulator
decorated: (node) =>
@transform.statement node
string: (node) =>
delim = node[2]

View File

@ -11,7 +11,9 @@ import insert from table
-- implicit return does not work on these statements
manual_return = data.Set{"foreach", "for", "while", "return"}
-- assigns and returns are bubbled into their bodies
-- 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" }
is_value = (stm) ->

View File

@ -71,3 +71,8 @@ print thing for thing in *test
-> a = b for row in *rows
-- testing implicit return
-> x for x in *things
-> [x for x in *things]

View File

@ -279,3 +279,23 @@ _ = function()
a = b
end
end
_ = function()
local _list_9 = things
for _index_0 = 1, #_list_9 do
x = _list_9[_index_0]
_ = x
end
end
_ = function()
return (function()
local _accum_0 = { }
local _len_0 = 0
local _list_9 = things
for _index_0 = 1, #_list_9 do
x = _list_9[_index_0]
_len_0 = _len_0 + 1
_accum_0[_len_0] = x
end
return _accum_0
end)()
end

7
todo
View File

@ -55,3 +55,10 @@ not working right:
* convert tree transformer to be depth first instead of breadth first (lazy)
-- for searching?
x = for thing in *things
if is_important thing
break thing