comprehension decorator, non return value compile for comprehension

This commit is contained in:
leaf corcoran 2011-05-29 14:40:40 -07:00
parent 6cd61d336c
commit d8ff74ccba
6 changed files with 105 additions and 41 deletions

View File

@ -43,8 +43,14 @@ local moonlib = {
end
}
-- these are always expressions, never statements, must be sent into temp variable
local must_return = data.Set{ 'parens', 'exp', 'value', 'string', 'table', 'fndef' }
-- make sure there are no block levels statements in expression
local function validate_expression(block)
-- need to annotate blocks? how do I know where expressions are
end
local compiler_index = {
push = function(self) self._scope:push{} end,
pop = function(self) self._scope:pop() end,
@ -264,25 +270,29 @@ local compiler_index = {
return table.concat(self:values(node), ", ")
end,
comprehension = function(self, node)
-- need to get tmp name instead of using tmp
comprehension = function(self, node, return_value)
local _, exp, clauses = unpack(node)
local insert = { ("table.insert(tmp, %s)"):format(self:value(exp)) }
local action = return_value
and { ("table.insert(tmp, %s)"):format(self:value(exp)) }
or { self:stm(exp) }
for i = #clauses,1,-1 do
local c = clauses[i]
if "for" == c[1] then
local _, names, iter = unpack(c)
insert = {
action = {
("for %s in %s do"):format(self:name_list(names), self:value(iter)),
insert,
action,
"end"
}
elseif "when" == c[1] then
local _, when = unpack(c)
insert = {
action = {
("if %s then"):format(self:value(when)),
insert,
action,
"end"
}
else
@ -290,13 +300,17 @@ local compiler_index = {
end
end
if return_value then
return self:pretty{
"(function()",
{ "local tmp = {}", },
insert,
action,
{ "return tmp" },
"end)()"
}
else
return self:pretty(action)
end
end,
-- returns list of compiled statements
@ -430,7 +444,7 @@ local compiler_index = {
return delim..inner..(delim_end or delim)
end,
value = function(self, node, ...)
value = function(self, node, return_value, ...)
if return_value == nil then return_value = true end
if type(node) == "table" then
@ -438,7 +452,7 @@ local compiler_index = {
if not fn then
error("Unknown op: "..tostring(node[1]))
end
return fn(self, node, ...)
return fn(self, node, return_value, ...)
end
return node

View File

@ -191,6 +191,23 @@ local build_grammar = wrap(function()
return stm
end
local function wrap_decorator(stm, dec)
if not dec then return stm end
local arg = {stm, dec}
if dec[1] == "if" then
local _, cond, fail = unpack(dec)
if fail then fail = {"else", {fail}} end
stm = {"if", cond, {stm}, fail}
elseif dec[1] == "comprehension" then
local _, clauses = unpack(dec)
stm = {"comprehension", stm, clauses}
end
return stm
end
local function check_lua_string(str, pos, right, left)
return #left == #right
end
@ -201,8 +218,11 @@ local build_grammar = wrap(function()
Block = Ct(Line * (Break^1 * Line)^0),
Line = Cmt(Indent, check_indent) * Statement + _Space * Comment,
Statement = (Import + If + While + Exp * Space) *
(key"if" * Exp * (key"else" * Exp)^-1 * Space / mark"if")^-1 / wrap_if,
Statement = (Import + If + While + Exp * Space) * (
-- statement decorators
key"if" * Exp * (key"else" * Exp)^-1 * Space / mark"if" +
CompInner / mark"comprehension"
)^-1 / wrap_decorator,
Body = Break * InBlock + Ct(Statement),
@ -225,7 +245,9 @@ local build_grammar = wrap(function()
Ct((key"for" * Ct(NameList) * key"in" * Exp / mark"for") * CompClause^0) *
sym"]" / mark"comprehension",
CompClause = key"for" * Ct(NameList) * key"in" * Exp / mark"for" + key"when" * Exp / mark"when",
CompInner = Ct(CompFor * CompClause^0),
CompFor = key"for" * Ct(NameList) * key"in" * Exp / mark"for",
CompClause = CompFor + key"when" * Exp / mark"when",
Assign = Ct(AssignableList) * sym"=" * Ct(TableBlock + ExpList) / mark"assign",

View File

@ -30,3 +30,12 @@ dump [{x, y} for x in range 5 when x > 2 for y in range 5]
things = [x + y for x in range 10 when x > 5 for y in range 10 when y > 7]
print x,y for x in ipairs{1,2,4} for y in ipairs{1,2,3} when x != 2
print "hello", x for x in items
[x for x in x]
x = [x for x in x]
print x,y for x in ipairs{1,2,4} for y in ipairs{1,2,3} when x != 2

View File

@ -131,3 +131,5 @@ y = not(5+5)
y = #"hello"
x = #{#{},#{1},#{1,2}}

View File

@ -24,16 +24,12 @@ local mm = (function()
table.insert(tmp, self.x)
end
return tmp
end)();
(function()
local tmp = {}
end)()
for z in ipairs(items) do
if z > 4 then
table.insert(tmp, z)
local _ = z
end
end
return tmp
end)()
local rad = (function()
local tmp = {}
for a in ipairs({
@ -49,18 +45,14 @@ local rad = (function()
end
end
return tmp
end)();
(function()
local tmp = {}
end)()
for z in items do
for j in list do
if z > 4 then
table.insert(tmp, z)
_ = z
end
end
end
return tmp
end)()
require("util")
local dump = function(x) print(util.dump(x)) end
local range = function(count)
@ -103,3 +95,30 @@ local things = (function()
end
return tmp
end)()
for x in ipairs({ 1, 2, 4 }) do
for y in ipairs({ 1, 2, 3 }) do
if x ~= 2 then
print(x, y)
end
end
end
for x in items do
print("hello", x)
end
for x in x do
_ = x
end
local x = (function()
local tmp = {}
for x in x do
table.insert(tmp, x)
end
return tmp
end)()
for x in ipairs({ 1, 2, 4 }) do
for y in ipairs({ 1, 2, 3 }) do
if x ~= 2 then
print(x, y)
end
end
end

View File

@ -71,8 +71,6 @@ x = -(function()
end)()
if cool then
print("hello")
else
_ = cool
end
print("nutjob")
if hello then
@ -81,7 +79,7 @@ end
if cool then
print("what")
else
_ = cool
_ = whack
end
local arg = { ... }
x = function(...) dump({ ... }) end