mirror of
https://github.com/leafo/moonscript.git
synced 2024-11-22 02:44:23 +00:00
slice shorthand for unpacked list comprehension
This commit is contained in:
parent
2a5a34ac19
commit
361feef825
@ -7,6 +7,8 @@ local reversed = util.reversed
|
||||
local ntype = data.ntype
|
||||
local concat, insert = table.concat, table.insert
|
||||
local constructor_name = "new"
|
||||
local is_slice
|
||||
is_slice = function(node) return ntype(node) == "chain" and ntype(node[#node]) == "slice" end
|
||||
line_compile = {
|
||||
raw = function(self, node)
|
||||
local _, text = unpack(node)
|
||||
@ -341,17 +343,46 @@ line_compile = {
|
||||
end)(), ", ")
|
||||
if ntype(iter) == "unpack" then
|
||||
iter = iter[2]
|
||||
local items_tmp = self:free_name("item")
|
||||
local index_tmp = self:free_name("index")
|
||||
local items_tmp = action:free_name("item")
|
||||
local index_tmp = action:free_name("index")
|
||||
local max_tmp = nil
|
||||
insert(self._lines, 1, ("local %s = %s[%s]"):format(name_list, items_tmp, index_tmp))
|
||||
local min, max, skip = 1, ("#%s"):format(items_tmp, nil)
|
||||
if is_slice(iter) then
|
||||
local slice = iter[#iter]
|
||||
table.remove(iter)
|
||||
min = action:value(slice[2])
|
||||
if slice[3] and slice[3] ~= "" then
|
||||
max_tmp = action:free_name("max", true)
|
||||
action:stm({ "assign", { max_tmp }, { slice[3] } })
|
||||
max = action:value({
|
||||
"exp",
|
||||
max_tmp,
|
||||
"<",
|
||||
0,
|
||||
"and",
|
||||
{
|
||||
"exp",
|
||||
{ "length", items_tmp },
|
||||
"+",
|
||||
max_tmp
|
||||
},
|
||||
"or",
|
||||
max_tmp
|
||||
})
|
||||
end
|
||||
if slice[4] then
|
||||
skip = action:value(slice[4])
|
||||
end
|
||||
end
|
||||
return action:add_lines({
|
||||
("local %s = %s"):format(items_tmp, self:value(iter)),
|
||||
("for %s=1,#%s do"):format(index_tmp, items_tmp),
|
||||
("local %s = %s"):format(items_tmp, action:value(iter)),
|
||||
("for %s=%s do"):format(index_tmp, concat({ min, max, skip }, ",")),
|
||||
self:render(true),
|
||||
"end"
|
||||
})
|
||||
else
|
||||
return action:add_lines({ ("for %s in %s do"):format(name_list, self:value(iter)), self:render(true), "end" })
|
||||
return action:add_lines({ ("for %s in %s do"):format(name_list, action:value(iter)), self:render(true), "end" })
|
||||
end
|
||||
elseif "when" == t then
|
||||
local cond
|
||||
|
@ -14,6 +14,9 @@ export line_compile
|
||||
|
||||
constructor_name = "new"
|
||||
|
||||
is_slice = (node) ->
|
||||
ntype(node) == "chain" and ntype(node[#node]) == "slice"
|
||||
|
||||
line_compile =
|
||||
raw: (node) =>
|
||||
_, text = unpack node
|
||||
@ -260,7 +263,7 @@ line_compile =
|
||||
|
||||
render_clause = (clause) =>
|
||||
t = clause[1]
|
||||
action = @block()
|
||||
action = @block!
|
||||
action\set_indent @indent - 1
|
||||
|
||||
if "for" == t
|
||||
@ -269,20 +272,37 @@ line_compile =
|
||||
|
||||
if ntype(iter) == "unpack"
|
||||
iter = iter[2]
|
||||
items_tmp = @free_name "item"
|
||||
index_tmp = @free_name "index"
|
||||
items_tmp = action\free_name "item"
|
||||
index_tmp = action\free_name "index"
|
||||
max_tmp = nil
|
||||
|
||||
insert self._lines, 1, ("local %s = %s[%s]")\format name_list, items_tmp, index_tmp
|
||||
|
||||
-- slice shortcut
|
||||
min, max, skip = 1, ("#%s")\format items_tmp, nil
|
||||
if is_slice iter
|
||||
slice = iter[#iter]
|
||||
table.remove iter
|
||||
min = action\value slice[2]
|
||||
if slice[3] and slice[3] != ""
|
||||
max_tmp = action\free_name "max", true
|
||||
action\stm {"assign", {max_tmp}, {slice[3]}}
|
||||
max = action\value {"exp", max_tmp, "<", 0
|
||||
"and", {"exp", {"length", items_tmp}, "+", max_tmp}
|
||||
"or", max_tmp
|
||||
}
|
||||
if slice[4]
|
||||
skip = action\value slice[4]
|
||||
|
||||
action\add_lines {
|
||||
("local %s = %s")\format items_tmp, @value iter
|
||||
("for %s=1,#%s do")\format index_tmp, items_tmp
|
||||
("local %s = %s")\format items_tmp, action\value iter
|
||||
("for %s=%s do")\format index_tmp, concat {min, max, skip}, ","
|
||||
@render true
|
||||
"end"
|
||||
}
|
||||
else
|
||||
action\add_lines {
|
||||
("for %s in %s do")\format(name_list, @value iter)
|
||||
("for %s in %s do")\format name_list, action\value iter
|
||||
@render true
|
||||
"end"
|
||||
}
|
||||
|
@ -280,7 +280,7 @@ local build_grammar = wrap(function()
|
||||
-- Factor = Ct(Term * (FactorOp * Term)^0) / flatten_or_mark"exp",
|
||||
-- Term = Ct(Value * (TermOp * Value)^0) / flatten_or_mark"exp",
|
||||
|
||||
Value =
|
||||
SimpleValue =
|
||||
If +
|
||||
sym"-" * -SomeSpace * Exp / mark"minus" +
|
||||
sym"#" * Exp / mark"length" +
|
||||
@ -288,11 +288,19 @@ local build_grammar = wrap(function()
|
||||
TableLit +
|
||||
Comprehension +
|
||||
ColonChain * Ct(ExpList^0) / flatten_func + -- have precedence over open table
|
||||
Ct(KeyValueList) / mark"table" +
|
||||
Assign + Update + FunLit + String +
|
||||
((Chain + DotChain + Callable) * Ct(ExpList^0)) / flatten_func +
|
||||
Num,
|
||||
|
||||
ChainValue =
|
||||
((Chain + DotChain + Callable) * Ct(ExpList^0)) / flatten_func,
|
||||
|
||||
Value =
|
||||
SimpleValue +
|
||||
Ct(KeyValueList) / mark"table" +
|
||||
ChainValue,
|
||||
|
||||
SliceValue = SimpleValue + ChainValue,
|
||||
|
||||
String = Space * DoubleString + Space * SingleString + LuaString,
|
||||
SingleString = simple_string("'"),
|
||||
DoubleString = simple_string('"'),
|
||||
@ -331,7 +339,8 @@ local build_grammar = wrap(function()
|
||||
symx"." * _Name/mark"dot" +
|
||||
ColonCall,
|
||||
|
||||
Slice = symx"[" * Num * sym":" * Num * (sym":" * Num)^-1 *sym"]" / mark"slice",
|
||||
Slice = symx"[" * (SliceValue + Cc(1)) * sym":" * (SliceValue + Cc"") *
|
||||
(sym":" * SliceValue)^-1 *sym"]" / mark"slice",
|
||||
|
||||
ColonCall = symx"\\" * (_Name * Invoke) / mark"colon",
|
||||
ColonSuffix = symx"\\" * _Name / mark"colon_stub",
|
||||
|
@ -49,3 +49,12 @@ hello = [x + y for x in *items for y in *items]
|
||||
|
||||
print z for z in *hello
|
||||
|
||||
|
||||
-- slice
|
||||
x = {1, 2, 3, 4, 5, 6, 7}
|
||||
print y for y in *x[2:-5:2]
|
||||
print y for y in *x[:3]
|
||||
print y for y in *x[2:]
|
||||
print y for y in *x[::2]
|
||||
print y for y in *x[2::2]
|
||||
|
||||
|
@ -167,3 +167,39 @@ for _index_0=1,#_item_0 do
|
||||
local z = _item_0[_index_0]
|
||||
print(z)
|
||||
end
|
||||
x = {
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7
|
||||
}
|
||||
local _max_0 = -5
|
||||
local _item_0 = x
|
||||
for _index_0=2,_max_0 < 0 and #_item_0 + _max_0 or _max_0,2 do
|
||||
local y = _item_0[_index_0]
|
||||
print(y)
|
||||
end
|
||||
local _max_0 = 3
|
||||
local _item_0 = x
|
||||
for _index_0=1,_max_0 < 0 and #_item_0 + _max_0 or _max_0 do
|
||||
local y = _item_0[_index_0]
|
||||
print(y)
|
||||
end
|
||||
local _item_0 = x
|
||||
for _index_0=2,#_item_0 do
|
||||
local y = _item_0[_index_0]
|
||||
print(y)
|
||||
end
|
||||
local _item_0 = x
|
||||
for _index_0=1,#_item_0,2 do
|
||||
local y = _item_0[_index_0]
|
||||
print(y)
|
||||
end
|
||||
local _item_0 = x
|
||||
for _index_0=2,#_item_0,2 do
|
||||
local y = _item_0[_index_0]
|
||||
print(y)
|
||||
end
|
Loading…
Reference in New Issue
Block a user