mirror of
https://github.com/leafo/moonscript.git
synced 2025-01-09 00:04:22 +00:00
comprehension decorator, non return value compile for comprehension
This commit is contained in:
parent
6cd61d336c
commit
d8ff74ccba
@ -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
|
||||
|
@ -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",
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -131,3 +131,5 @@ y = not(5+5)
|
||||
y = #"hello"
|
||||
|
||||
x = #{#{},#{1},#{1,2}}
|
||||
|
||||
|
||||
|
@ -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
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user