slice shorthand for unpacked list comprehension

This commit is contained in:
leaf corcoran 2011-06-23 08:42:43 -07:00
parent 2a5a34ac19
commit 361feef825
5 changed files with 132 additions and 27 deletions

View File

@ -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

View File

@ -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"
}

View File

@ -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",

View File

@ -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]

View File

@ -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