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
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- these are always expressions, never statements, must be sent into temp variable
|
||||||
local must_return = data.Set{ 'parens', 'exp', 'value', 'string', 'table', 'fndef' }
|
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 = {
|
local compiler_index = {
|
||||||
push = function(self) self._scope:push{} end,
|
push = function(self) self._scope:push{} end,
|
||||||
pop = function(self) self._scope:pop() end,
|
pop = function(self) self._scope:pop() end,
|
||||||
@ -264,25 +270,29 @@ local compiler_index = {
|
|||||||
return table.concat(self:values(node), ", ")
|
return table.concat(self:values(node), ", ")
|
||||||
end,
|
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 _, 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
|
for i = #clauses,1,-1 do
|
||||||
local c = clauses[i]
|
local c = clauses[i]
|
||||||
|
|
||||||
if "for" == c[1] then
|
if "for" == c[1] then
|
||||||
local _, names, iter = unpack(c)
|
local _, names, iter = unpack(c)
|
||||||
insert = {
|
action = {
|
||||||
("for %s in %s do"):format(self:name_list(names), self:value(iter)),
|
("for %s in %s do"):format(self:name_list(names), self:value(iter)),
|
||||||
insert,
|
action,
|
||||||
"end"
|
"end"
|
||||||
}
|
}
|
||||||
elseif "when" == c[1] then
|
elseif "when" == c[1] then
|
||||||
local _, when = unpack(c)
|
local _, when = unpack(c)
|
||||||
insert = {
|
action = {
|
||||||
("if %s then"):format(self:value(when)),
|
("if %s then"):format(self:value(when)),
|
||||||
insert,
|
action,
|
||||||
"end"
|
"end"
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -290,13 +300,17 @@ local compiler_index = {
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if return_value then
|
||||||
return self:pretty{
|
return self:pretty{
|
||||||
"(function()",
|
"(function()",
|
||||||
{ "local tmp = {}", },
|
{ "local tmp = {}", },
|
||||||
insert,
|
action,
|
||||||
{ "return tmp" },
|
{ "return tmp" },
|
||||||
"end)()"
|
"end)()"
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return self:pretty(action)
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- returns list of compiled statements
|
-- returns list of compiled statements
|
||||||
@ -430,7 +444,7 @@ local compiler_index = {
|
|||||||
return delim..inner..(delim_end or delim)
|
return delim..inner..(delim_end or delim)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
value = function(self, node, ...)
|
value = function(self, node, return_value, ...)
|
||||||
if return_value == nil then return_value = true end
|
if return_value == nil then return_value = true end
|
||||||
|
|
||||||
if type(node) == "table" then
|
if type(node) == "table" then
|
||||||
@ -438,7 +452,7 @@ local compiler_index = {
|
|||||||
if not fn then
|
if not fn then
|
||||||
error("Unknown op: "..tostring(node[1]))
|
error("Unknown op: "..tostring(node[1]))
|
||||||
end
|
end
|
||||||
return fn(self, node, ...)
|
return fn(self, node, return_value, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
return node
|
return node
|
||||||
|
@ -191,6 +191,23 @@ local build_grammar = wrap(function()
|
|||||||
return stm
|
return stm
|
||||||
end
|
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)
|
local function check_lua_string(str, pos, right, left)
|
||||||
return #left == #right
|
return #left == #right
|
||||||
end
|
end
|
||||||
@ -201,8 +218,11 @@ local build_grammar = wrap(function()
|
|||||||
Block = Ct(Line * (Break^1 * Line)^0),
|
Block = Ct(Line * (Break^1 * Line)^0),
|
||||||
Line = Cmt(Indent, check_indent) * Statement + _Space * Comment,
|
Line = Cmt(Indent, check_indent) * Statement + _Space * Comment,
|
||||||
|
|
||||||
Statement = (Import + If + While + Exp * Space) *
|
Statement = (Import + If + While + Exp * Space) * (
|
||||||
(key"if" * Exp * (key"else" * Exp)^-1 * Space / mark"if")^-1 / wrap_if,
|
-- statement decorators
|
||||||
|
key"if" * Exp * (key"else" * Exp)^-1 * Space / mark"if" +
|
||||||
|
CompInner / mark"comprehension"
|
||||||
|
)^-1 / wrap_decorator,
|
||||||
|
|
||||||
Body = Break * InBlock + Ct(Statement),
|
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) *
|
Ct((key"for" * Ct(NameList) * key"in" * Exp / mark"for") * CompClause^0) *
|
||||||
sym"]" / mark"comprehension",
|
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",
|
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]
|
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"
|
y = #"hello"
|
||||||
|
|
||||||
x = #{#{},#{1},#{1,2}}
|
x = #{#{},#{1},#{1,2}}
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,16 +24,12 @@ local mm = (function()
|
|||||||
table.insert(tmp, self.x)
|
table.insert(tmp, self.x)
|
||||||
end
|
end
|
||||||
return tmp
|
return tmp
|
||||||
end)();
|
|
||||||
(function()
|
|
||||||
local tmp = {}
|
|
||||||
for z in ipairs(items) do
|
|
||||||
if z > 4 then
|
|
||||||
table.insert(tmp, z)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return tmp
|
|
||||||
end)()
|
end)()
|
||||||
|
for z in ipairs(items) do
|
||||||
|
if z > 4 then
|
||||||
|
local _ = z
|
||||||
|
end
|
||||||
|
end
|
||||||
local rad = (function()
|
local rad = (function()
|
||||||
local tmp = {}
|
local tmp = {}
|
||||||
for a in ipairs({
|
for a in ipairs({
|
||||||
@ -49,18 +45,14 @@ local rad = (function()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
return tmp
|
return tmp
|
||||||
end)();
|
end)()
|
||||||
(function()
|
for z in items do
|
||||||
local tmp = {}
|
|
||||||
for z in items do
|
|
||||||
for j in list do
|
for j in list do
|
||||||
if z > 4 then
|
if z > 4 then
|
||||||
table.insert(tmp, z)
|
_ = z
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return tmp
|
|
||||||
end)()
|
|
||||||
require("util")
|
require("util")
|
||||||
local dump = function(x) print(util.dump(x)) end
|
local dump = function(x) print(util.dump(x)) end
|
||||||
local range = function(count)
|
local range = function(count)
|
||||||
@ -103,3 +95,30 @@ local things = (function()
|
|||||||
end
|
end
|
||||||
return tmp
|
return tmp
|
||||||
end)()
|
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)()
|
end)()
|
||||||
if cool then
|
if cool then
|
||||||
print("hello")
|
print("hello")
|
||||||
else
|
|
||||||
_ = cool
|
|
||||||
end
|
end
|
||||||
print("nutjob")
|
print("nutjob")
|
||||||
if hello then
|
if hello then
|
||||||
@ -81,7 +79,7 @@ end
|
|||||||
if cool then
|
if cool then
|
||||||
print("what")
|
print("what")
|
||||||
else
|
else
|
||||||
_ = cool
|
_ = whack
|
||||||
end
|
end
|
||||||
local arg = { ... }
|
local arg = { ... }
|
||||||
x = function(...) dump({ ... }) end
|
x = function(...) dump({ ... }) end
|
||||||
|
Loading…
Reference in New Issue
Block a user