exteneded list comprehension

This commit is contained in:
leaf corcoran 2011-05-27 23:21:29 -07:00
parent 1f821c19d4
commit 708e0dd35f
4 changed files with 101 additions and 18 deletions

View File

@ -233,25 +233,37 @@ local compiler_index = {
end, end,
comprehension = function(self, node) comprehension = function(self, node)
local _, exp, names, iter, when = unpack(node) local _, exp, clauses = unpack(node)
local insert = ("table.insert(tmp, %s)"):format(self:value(exp)) local insert = { ("table.insert(tmp, %s)"):format(self:value(exp)) }
if when then for i = #clauses,1,-1 do
local c = clauses[i]
if "for" == c[1] then
local _, names, iter = unpack(c)
insert = { insert = {
("if %s then"):format(self:value(when)), { ("for %s in %s do"):format(self:name_list(names), self:value(iter)),
insert insert,
}, "end" "end"
} }
elseif "when" == c[1] then
local _, when = unpack(c)
insert = {
("if %s then"):format(self:value(when)),
insert,
"end"
}
else
error("Unknown clause type :"..tostring(c[1]))
end
end end
return self:pretty{ return self:pretty{
"(function()", { "(function()",
"local tmp = {}", { "local tmp = {}", },
("for %s in %s do"):format(self:name_list(names), self:value(iter)), insert,
type(insert) == "table" and insert or {insert}, { "return tmp" },
"end", "end)()"
"return tmp"
}, "end)()"
} }
end, end,

View File

@ -208,11 +208,12 @@ local build_grammar = wrap(function()
While = key"while" * Exp * key"do"^-1 * Body / mark"while", While = key"while" * Exp * key"do"^-1 * Body / mark"while",
Comprehension = sym"[" * Exp * key"for" * Ct(NameList) * Comprehension = sym"[" * Exp *
key"in" * Exp * Ct((key"for" * Ct(NameList) * key"in" * Exp / mark"for") * CompClause^0) *
(key"when" * Exp)^-1 *
sym"]" / mark"comprehension", sym"]" / mark"comprehension",
CompClause = key"for" * Ct(NameList) * key"in" * Exp / mark"for" + key"when" * Exp / mark"when",
Assign = Ct(AssignableList) * sym"=" * Ct(TableBlock + ExpList) / mark"assign", Assign = Ct(AssignableList) * sym"=" * Ct(TableBlock + ExpList) / mark"assign",
-- we can ignore precedence for now -- we can ignore precedence for now

View File

@ -11,3 +11,22 @@ rad = [{a} for a in ipairs {
1,2,3,4,5,6, 1,2,3,4,5,6,
} when good_number a] } when good_number a]
[z for z in items for j in list when z > 4]
require "util"
dump = (x) -> print util.dump x
range = (count) ->
i = 0
return coroutine.wrap ->
while i < count
coroutine.yield i
i = i + 1
dump [x for x in range 10]
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]

View File

@ -49,4 +49,55 @@ local rad = (function()
end end
end end
return tmp return tmp
end)();
(function()
local tmp = {}
for z in items do
for j in list do
if z > 4 then
table.insert(tmp, z)
end
end
end
return tmp
end)()
require("util")
local dump = function(x) print(util.dump(x)) end
local range = function(count)
local i = 0
return(coroutine.wrap(function() while i < count do
coroutine.yield(i)
i = i + 1
end end))
end
dump((function()
local tmp = {}
for x in range(10) do
table.insert(tmp, x)
end
return tmp
end)())
dump((function()
local tmp = {}
for x in range(5) do
if x > 2 then
for y in range(5) do
table.insert(tmp, { x, y })
end
end
end
return tmp
end)())
local things = (function()
local tmp = {}
for x in range(10) do
if x > 5 then
for y in range(10) do
if y > 7 then
table.insert(tmp, x + y)
end
end
end
end
return tmp
end)() end)()