mirror of
https://github.com/leafo/moonscript.git
synced 2025-01-09 00:04:22 +00:00
list comprehension, self operator, all binary ops
This commit is contained in:
parent
08c3eee854
commit
1f821c19d4
@ -37,6 +37,20 @@ local compiler_index = {
|
|||||||
self._indent = self._indent + amount
|
self._indent = self._indent + amount
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
pretty = function(self, tbl)
|
||||||
|
local out = {}
|
||||||
|
for _, line in ipairs(tbl) do
|
||||||
|
if type(line) == "table" then
|
||||||
|
self:indent(1)
|
||||||
|
table.insert(out, indent_char..self:pretty(line))
|
||||||
|
self:indent(-1)
|
||||||
|
else
|
||||||
|
table.insert(out, line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return table.concat(out, "\n"..self:ichar())
|
||||||
|
end,
|
||||||
|
|
||||||
has_name = function(self, name)
|
has_name = function(self, name)
|
||||||
for i = #self._scope,1,-1 do
|
for i = #self._scope,1,-1 do
|
||||||
if self._scope[i][name] then return true end
|
if self._scope[i][name] then return true end
|
||||||
@ -110,10 +124,13 @@ local compiler_index = {
|
|||||||
local to_bind = {}
|
local to_bind = {}
|
||||||
local final_names = {}
|
local final_names = {}
|
||||||
for _, name in ipairs(names) do
|
for _, name in ipairs(names) do
|
||||||
if type(name) == "table" then
|
if ntype(name) == ":" then
|
||||||
name = name[2]
|
name = self:value(name[2])
|
||||||
to_bind[name] = true
|
to_bind[name] = true
|
||||||
|
else
|
||||||
|
name = self:value(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(final_names, name)
|
table.insert(final_names, name)
|
||||||
self:put_name(name)
|
self:put_name(name)
|
||||||
end
|
end
|
||||||
@ -211,6 +228,33 @@ local compiler_index = {
|
|||||||
return ("while %s do\n%s\n%send"):format(self:value(cond), self:block(block, 1), ichr)
|
return ("while %s do\n%s\n%send"):format(self:value(cond), self:block(block, 1), ichr)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
name_list = function(self, node)
|
||||||
|
return table.concat(self:values(node), ", ")
|
||||||
|
end,
|
||||||
|
|
||||||
|
comprehension = function(self, node)
|
||||||
|
local _, exp, names, iter, when = unpack(node)
|
||||||
|
local insert = ("table.insert(tmp, %s)"):format(self:value(exp))
|
||||||
|
|
||||||
|
if when then
|
||||||
|
insert = {
|
||||||
|
("if %s then"):format(self:value(when)), {
|
||||||
|
insert
|
||||||
|
}, "end"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return self:pretty{
|
||||||
|
"(function()", {
|
||||||
|
"local tmp = {}",
|
||||||
|
("for %s in %s do"):format(self:name_list(names), self:value(iter)),
|
||||||
|
type(insert) == "table" and insert or {insert},
|
||||||
|
"end",
|
||||||
|
"return tmp"
|
||||||
|
}, "end)()"
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
|
||||||
block = function(self, node, inc)
|
block = function(self, node, inc)
|
||||||
self:push()
|
self:push()
|
||||||
if inc then self:indent(inc) end
|
if inc then self:indent(inc) end
|
||||||
@ -302,6 +346,9 @@ local compiler_index = {
|
|||||||
exp = function(self, node)
|
exp = function(self, node)
|
||||||
local values = {}
|
local values = {}
|
||||||
for i = 2, #node do
|
for i = 2, #node do
|
||||||
|
if i % 2 == 1 and node[i] == "!=" then
|
||||||
|
node[i] = "~="
|
||||||
|
end
|
||||||
table.insert(values, self:value(node[i]))
|
table.insert(values, self:value(node[i]))
|
||||||
end
|
end
|
||||||
return table.concat(values, " ")
|
return table.concat(values, " ")
|
||||||
@ -329,6 +376,11 @@ local compiler_index = {
|
|||||||
return node
|
return node
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
self = function(self, node)
|
||||||
|
local _, val = unpack(node)
|
||||||
|
return "self."..self:value(val)
|
||||||
|
end,
|
||||||
|
|
||||||
-- a list of values
|
-- a list of values
|
||||||
values = function(self, items, start)
|
values = function(self, items, start)
|
||||||
start = start or 1
|
start = start or 1
|
||||||
|
@ -124,6 +124,14 @@ local build_grammar = wrap(function()
|
|||||||
return Space * word
|
return Space * word
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function op(word)
|
||||||
|
if word:match("^%w*$") then
|
||||||
|
keywords[word] = true
|
||||||
|
end
|
||||||
|
return Space * C(word)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local function sym(chars)
|
local function sym(chars)
|
||||||
return Space * chars
|
return Space * chars
|
||||||
end
|
end
|
||||||
@ -160,6 +168,8 @@ local build_grammar = wrap(function()
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local Name = sym"@" * Name / mark"self" + Name
|
||||||
|
|
||||||
-- make sure name is not a keyword
|
-- make sure name is not a keyword
|
||||||
local Name = Cmt(Name, function(str, pos, name)
|
local Name = Cmt(Name, function(str, pos, name)
|
||||||
if keywords[name] then return false end
|
if keywords[name] then return false end
|
||||||
@ -187,7 +197,7 @@ local build_grammar = wrap(function()
|
|||||||
OutBlock = Cmt("", pop_indent),
|
OutBlock = Cmt("", pop_indent),
|
||||||
|
|
||||||
Import = key"import"* Ct(ImportNameList) * key"from" * Exp / mark"import",
|
Import = key"import"* Ct(ImportNameList) * key"from" * Exp / mark"import",
|
||||||
ImportName = (Ct(C(sym":") * Name) + Name),
|
ImportName = (Ct(sym":" / trim * Name) + Name),
|
||||||
ImportNameList = ImportName * (sym"," * ImportName)^0,
|
ImportNameList = ImportName * (sym"," * ImportName)^0,
|
||||||
|
|
||||||
NameList = Name * (sym"," * Name)^0,
|
NameList = Name * (sym"," * Name)^0,
|
||||||
@ -198,14 +208,24 @@ 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) *
|
||||||
|
key"in" * Exp *
|
||||||
|
(key"when" * Exp)^-1 *
|
||||||
|
sym"]" / mark"comprehension",
|
||||||
|
|
||||||
Assign = Ct(AssignableList) * sym"=" * Ct(TableBlock + ExpList) / mark"assign",
|
Assign = Ct(AssignableList) * sym"=" * Ct(TableBlock + ExpList) / mark"assign",
|
||||||
|
|
||||||
|
-- we can ignore precedence for now
|
||||||
|
OtherOps = op"or" + op"and" + op"<=" + op">=" + op"~=" + op"!=" + op"==" + op".." + op"<" + op">",
|
||||||
|
|
||||||
Assignable = Cmt(Chain, check_assignable) + Name,
|
Assignable = Cmt(Chain, check_assignable) + Name,
|
||||||
AssignableList = Assignable * (sym"," * Assignable)^0,
|
AssignableList = Assignable * (sym"," * Assignable)^0,
|
||||||
Exp = Ct(Term * (FactorOp * Term)^0) / flatten_or_mark"exp",
|
Exp = Ct(Factor * (OtherOps * Factor)^0) / flatten_or_mark"exp",
|
||||||
|
Factor = Ct(Term * (FactorOp * Term)^0) / flatten_or_mark"exp",
|
||||||
Term = Ct(Value * (TermOp * Value)^0) / flatten_or_mark"exp",
|
Term = Ct(Value * (TermOp * Value)^0) / flatten_or_mark"exp",
|
||||||
|
|
||||||
Value = TableLit +
|
Value = TableLit +
|
||||||
|
Comprehension +
|
||||||
ColonChain +
|
ColonChain +
|
||||||
Ct(KeyValueList) / mark"table" +
|
Ct(KeyValueList) / mark"table" +
|
||||||
Assign + FunLit + String +
|
Assign + FunLit + String +
|
||||||
@ -297,48 +317,17 @@ local build_grammar = wrap(function()
|
|||||||
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local grammar = build_grammar()
|
|
||||||
|
|
||||||
-- parse a string
|
-- parse a string
|
||||||
-- returns tree, or nil and error message
|
-- returns tree, or nil and error message
|
||||||
function string(str)
|
function string(str)
|
||||||
local g = build_grammar()
|
local g = build_grammar()
|
||||||
return grammar:match(str)
|
return g:match(str)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local program = [[
|
|
||||||
if two_dads
|
|
||||||
do something
|
|
||||||
if yum
|
|
||||||
heckyes 23
|
|
||||||
|
|
||||||
print 2
|
|
||||||
|
|
||||||
print dadas
|
|
||||||
|
|
||||||
{1,2,3,4}
|
|
||||||
|
|
||||||
(a,b) ->
|
|
||||||
throw nuts
|
|
||||||
|
|
||||||
print 100
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
local program = [[
|
|
||||||
|
|
||||||
hi = (a) -> print a
|
|
||||||
|
|
||||||
if true
|
|
||||||
hi 100
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
local program3 = [[
|
local program3 = [[
|
||||||
-- hello
|
-- hello
|
||||||
class Hello
|
class Hello
|
||||||
@something = 2323
|
@something: 2323
|
||||||
|
|
||||||
hello: () ->
|
hello: () ->
|
||||||
print 200
|
print 200
|
||||||
|
13
tests/inputs/lists.moon
Normal file
13
tests/inputs/lists.moon
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
hi = [x*2 for _, x in ipairs{1,2,3,4}]
|
||||||
|
|
||||||
|
items = {1,2,3,4,5,6}
|
||||||
|
|
||||||
|
mm = [@x for @x in ipairs items]
|
||||||
|
|
||||||
|
[z for z in ipairs items when z > 4]
|
||||||
|
|
||||||
|
rad = [{a} for a in ipairs {
|
||||||
|
1,2,3,4,5,6,
|
||||||
|
} when good_number a]
|
||||||
|
|
52
tests/outputs/lists.lua
Normal file
52
tests/outputs/lists.lua
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
local hi = (function()
|
||||||
|
local tmp = {}
|
||||||
|
for _, x in ipairs({
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
}) do
|
||||||
|
table.insert(tmp, x * 2)
|
||||||
|
end
|
||||||
|
return tmp
|
||||||
|
end)()
|
||||||
|
local items = {
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6
|
||||||
|
}
|
||||||
|
local mm = (function()
|
||||||
|
local tmp = {}
|
||||||
|
for self.x in ipairs(items) do
|
||||||
|
table.insert(tmp, self.x)
|
||||||
|
end
|
||||||
|
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)()
|
||||||
|
local rad = (function()
|
||||||
|
local tmp = {}
|
||||||
|
for a in ipairs({
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6
|
||||||
|
}) do
|
||||||
|
if good_number(a) then
|
||||||
|
table.insert(tmp, { a })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return tmp
|
||||||
|
end)()
|
Loading…
Reference in New Issue
Block a user