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
|
||||
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)
|
||||
for i = #self._scope,1,-1 do
|
||||
if self._scope[i][name] then return true end
|
||||
@ -110,10 +124,13 @@ local compiler_index = {
|
||||
local to_bind = {}
|
||||
local final_names = {}
|
||||
for _, name in ipairs(names) do
|
||||
if type(name) == "table" then
|
||||
name = name[2]
|
||||
if ntype(name) == ":" then
|
||||
name = self:value(name[2])
|
||||
to_bind[name] = true
|
||||
else
|
||||
name = self:value(name)
|
||||
end
|
||||
|
||||
table.insert(final_names, name)
|
||||
self:put_name(name)
|
||||
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)
|
||||
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)
|
||||
self:push()
|
||||
if inc then self:indent(inc) end
|
||||
@ -302,6 +346,9 @@ local compiler_index = {
|
||||
exp = function(self, node)
|
||||
local values = {}
|
||||
for i = 2, #node do
|
||||
if i % 2 == 1 and node[i] == "!=" then
|
||||
node[i] = "~="
|
||||
end
|
||||
table.insert(values, self:value(node[i]))
|
||||
end
|
||||
return table.concat(values, " ")
|
||||
@ -329,6 +376,11 @@ local compiler_index = {
|
||||
return node
|
||||
end,
|
||||
|
||||
self = function(self, node)
|
||||
local _, val = unpack(node)
|
||||
return "self."..self:value(val)
|
||||
end,
|
||||
|
||||
-- a list of values
|
||||
values = function(self, items, start)
|
||||
start = start or 1
|
||||
|
@ -124,6 +124,14 @@ local build_grammar = wrap(function()
|
||||
return Space * word
|
||||
end
|
||||
|
||||
local function op(word)
|
||||
if word:match("^%w*$") then
|
||||
keywords[word] = true
|
||||
end
|
||||
return Space * C(word)
|
||||
end
|
||||
|
||||
|
||||
local function sym(chars)
|
||||
return Space * chars
|
||||
end
|
||||
@ -160,6 +168,8 @@ local build_grammar = wrap(function()
|
||||
return false
|
||||
end
|
||||
|
||||
local Name = sym"@" * Name / mark"self" + Name
|
||||
|
||||
-- make sure name is not a keyword
|
||||
local Name = Cmt(Name, function(str, pos, name)
|
||||
if keywords[name] then return false end
|
||||
@ -187,7 +197,7 @@ local build_grammar = wrap(function()
|
||||
OutBlock = Cmt("", pop_indent),
|
||||
|
||||
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,
|
||||
|
||||
NameList = Name * (sym"," * Name)^0,
|
||||
@ -198,14 +208,24 @@ local build_grammar = wrap(function()
|
||||
|
||||
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",
|
||||
|
||||
-- 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,
|
||||
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",
|
||||
|
||||
Value = TableLit +
|
||||
Comprehension +
|
||||
ColonChain +
|
||||
Ct(KeyValueList) / mark"table" +
|
||||
Assign + FunLit + String +
|
||||
@ -297,48 +317,17 @@ local build_grammar = wrap(function()
|
||||
|
||||
end)
|
||||
|
||||
local grammar = build_grammar()
|
||||
|
||||
-- parse a string
|
||||
-- returns tree, or nil and error message
|
||||
function string(str)
|
||||
local g = build_grammar()
|
||||
return grammar:match(str)
|
||||
return g:match(str)
|
||||
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 = [[
|
||||
-- hello
|
||||
class Hello
|
||||
@something = 2323
|
||||
@something: 2323
|
||||
|
||||
hello: () ->
|
||||
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