add numeric for loop comprehensions/decorator, fixes #45

This commit is contained in:
leaf corcoran 2013-01-12 15:09:17 -08:00
parent c4217982e0
commit 0cf96b97f6
8 changed files with 177 additions and 30 deletions

View File

@ -415,6 +415,12 @@ Using multiple `for` clauses is the same as using nested loops:
points = [{x,y} for x in *x_coords for y in *y_coords] points = [{x,y} for x in *x_coords for y in *y_coords]
``` ```
Numeric for loops can also be used in comprehensions:
```moon
evens = [i for i=1,100 when i % 2 == 0]
```
### Table Comprehensions ### Table Comprehensions
The syntax for table comprehensions is very similar, only differing by using `{` and The syntax for table comprehensions is very similar, only differing by using `{` and

View File

@ -447,9 +447,10 @@ local build_grammar = wrap_env(function()
TblComprehension = sym"{" * Ct(Exp * (sym"," * Exp)^-1) * CompInner * sym"}" / mark"tblcomprehension", TblComprehension = sym"{" * Ct(Exp * (sym"," * Exp)^-1) * CompInner * sym"}" / mark"tblcomprehension",
CompInner = Ct(CompFor * CompClause^0), CompInner = Ct((CompForEach + CompFor) * CompClause^0),
CompFor = key"for" * Ct(NameList) * key"in" * (sym"*" * Exp / mark"unpack" + Exp) / mark"for", CompForEach = key"for" * Ct(NameList) * key"in" * (sym"*" * Exp / mark"unpack" + Exp) / mark"foreach",
CompClause = CompFor + key"when" * Exp / mark"when", CompFor = key "for" * Name * sym"=" * Ct(Exp * sym"," * Exp * (sym"," * Exp)^-1) / mark"for",
CompClause = CompFor + CompForEach + key"when" * Exp / mark"when",
Assign = sym"=" * (Ct(With + If + Switch) + Ct(TableBlock + ExpListLow)) / mark"assign", Assign = sym"=" * (Ct(With + If + Switch) + Ct(TableBlock + ExpListLow)) / mark"assign",
Update = ((sym"..=" + sym"+=" + sym"-=" + sym"*=" + sym"/=" + sym"%=" + sym"or=" + sym"and=") / trim) * Exp / mark"update", Update = ((sym"..=" + sym"+=" + sym"-=" + sym"*=" + sym"/=" + sym"%=" + sym"or=" + sym"and=") / trim) * Exp / mark"update",

View File

@ -66,12 +66,16 @@ apply_to_last = function(stms, fn)
local _accum_0 = { } local _accum_0 = { }
local _len_0 = 1 local _len_0 = 1
for i, stm in ipairs(stms) do for i, stm in ipairs(stms) do
local _value_0
if i == last_exp_id then if i == last_exp_id then
_accum_0[_len_0] = fn(stm) _value_0 = fn(stm)
else else
_accum_0[_len_0] = stm _value_0 = stm
end
if _value_0 ~= nil then
_accum_0[_len_0] = _value_0
_len_0 = _len_0 + 1
end end
_len_0 = _len_0 + 1
end end
return _accum_0 return _accum_0
end)() end)()
@ -291,9 +295,25 @@ construct_comprehension = function(inner, clauses)
local current_stms = inner local current_stms = inner
for _, clause in reversed(clauses) do for _, clause in reversed(clauses) do
local t = clause[1] local t = clause[1]
if t == "for" then local _exp_0 = t
if "for" == _exp_0 then
local name, bounds
do
local _obj_0 = clause
_, name, bounds = _obj_0[1], _obj_0[2], _obj_0[3]
end
current_stms = {
"for",
name,
bounds,
current_stms
}
elseif "foreach" == _exp_0 then
local names, iter local names, iter
_, names, iter = unpack(clause) do
local _obj_0 = clause
_, names, iter = _obj_0[1], _obj_0[2], _obj_0[3]
end
current_stms = { current_stms = {
"foreach", "foreach",
names, names,
@ -302,9 +322,12 @@ construct_comprehension = function(inner, clauses)
}, },
current_stms current_stms
} }
elseif t == "when" then elseif "when" == _exp_0 then
local cond local cond
_, cond = unpack(clause) do
local _obj_0 = clause
_, cond = _obj_0[1], _obj_0[2]
end
current_stms = { current_stms = {
"if", "if",
cond, cond,
@ -440,15 +463,19 @@ local Statement = Transformer({
local _list_0 = names local _list_0 = names
for _index_0 = 1, #_list_0 do for _index_0 = 1, #_list_0 do
local name = _list_0[_index_0] local name = _list_0[_index_0]
local _value_0
if type(name) == "table" then if type(name) == "table" then
_accum_0[_len_0] = name _value_0 = name
else else
_accum_0[_len_0] = { _value_0 = {
"dot", "dot",
name name
} }
end end
_len_0 = _len_0 + 1 if _value_0 ~= nil then
_accum_0[_len_0] = _value_0
_len_0 = _len_0 + 1
end
end end
return _accum_0 return _accum_0
end)() end)()
@ -458,8 +485,11 @@ local Statement = Transformer({
local _list_0 = names local _list_0 = names
for _index_0 = 1, #_list_0 do for _index_0 = 1, #_list_0 do
local name = _list_0[_index_0] local name = _list_0[_index_0]
_accum_0[_len_0] = type(name) == "table" and name[2] or name local _value_0 = type(name) == "table" and name[2] or name
_len_0 = _len_0 + 1 if _value_0 ~= nil then
_accum_0[_len_0] = _value_0
_len_0 = _len_0 + 1
end
end end
return _accum_0 return _accum_0
end)() end)()
@ -681,17 +711,21 @@ local Statement = Transformer({
local _accum_0 = { } local _accum_0 = { }
local _len_0 = 1 local _len_0 = 1
for i, name in ipairs(node.names) do for i, name in ipairs(node.names) do
local _value_0
if ntype(name) == "table" then if ntype(name) == "table" then
do do
local _with_0 = NameProxy("des") local _with_0 = NameProxy("des")
local proxy = _with_0 local proxy = _with_0
insert(destructures, destructure.build_assign(name, proxy)) insert(destructures, destructure.build_assign(name, proxy))
_accum_0[_len_0] = _with_0 _value_0 = _with_0
end end
else else
_accum_0[_len_0] = name _value_0 = name
end
if _value_0 ~= nil then
_accum_0[_len_0] = _value_0
_len_0 = _len_0 + 1
end end
_len_0 = _len_0 + 1
end end
return _accum_0 return _accum_0
end)() end)()
@ -872,8 +906,10 @@ local Statement = Transformer({
else else
_value_0 = tuple _value_0 = tuple
end end
_accum_0[_len_0] = _value_0 if _value_0 ~= nil then
_len_0 = _len_0 + 1 _accum_0[_len_0] = _value_0
_len_0 = _len_0 + 1
end
_continue_0 = true _continue_0 = true
until true until true
if not _continue_0 then if not _continue_0 then

View File

@ -140,14 +140,19 @@ construct_comprehension = (inner, clauses) ->
current_stms = inner current_stms = inner
for _, clause in reversed clauses for _, clause in reversed clauses
t = clause[1] t = clause[1]
current_stms = if t == "for" current_stms = switch t
_, names, iter = unpack clause when "for"
{"foreach", names, {iter}, current_stms} {_, name, bounds} = clause
elseif t == "when" {"for", name, bounds, current_stms}
_, cond = unpack clause when "foreach"
{"if", cond, current_stms} {_, names, iter} = clause
else {"foreach", names, {iter}, current_stms}
error "Unknown comprehension clause: "..t when "when"
{_, cond} = clause
{"if", cond, current_stms}
else
error "Unknown comprehension clause: "..t
current_stms = {current_stms} current_stms = {current_stms}
current_stms[1] current_stms[1]

View File

@ -17,3 +17,17 @@ copy = {k,v for k,v in pairs x when k != "okay"}
{ xxxx for x in yes } { xxxx for x in yes }
{ unpack [a*i for i, a in ipairs x] for x in *{{1,2}, {3,4}} } { unpack [a*i for i, a in ipairs x] for x in *{{1,2}, {3,4}} }
--
n1 = [i for i=1,10]
n2 = [i for i=1,10 when i % 2 == 1]
aa = [{x,y} for x=1,10 for y=5,14]
bb = [y for thing in y for i=1,10]
cc = [y for i=1,10 for thing in y]
dd = [y for i=1,10 when cool for thing in y when x > 3 when c + 3]
{"hello", "world" for i=1,10}
nil

View File

@ -104,6 +104,7 @@ x = -[x for x in x]
print "hello" if cool print "hello" if cool
print "hello" unless cool print "hello" unless cool
print "hello" unless 1212 and 3434 -- hello print "hello" unless 1212 and 3434 -- hello
print "hello" for i=1,10
print "nutjob" print "nutjob"

View File

@ -52,7 +52,7 @@ _ = (function()
end end
return _tbl_0 return _tbl_0
end)() end)()
return (function() _ = (function()
local _tbl_0 = { } local _tbl_0 = { }
local _list_0 = { local _list_0 = {
{ {
@ -79,3 +79,84 @@ return (function()
end end
return _tbl_0 return _tbl_0
end)() end)()
local n1 = (function()
local _accum_0 = { }
local _len_0 = 1
for i = 1, 10 do
_accum_0[_len_0] = i
_len_0 = _len_0 + 1
end
return _accum_0
end)()
local n2 = (function()
local _accum_0 = { }
local _len_0 = 1
for i = 1, 10 do
if i % 2 == 1 then
_accum_0[_len_0] = i
_len_0 = _len_0 + 1
end
end
return _accum_0
end)()
local aa = (function()
local _accum_0 = { }
local _len_0 = 1
for x = 1, 10 do
for y = 5, 14 do
_accum_0[_len_0] = {
x,
y
}
_len_0 = _len_0 + 1
end
end
return _accum_0
end)()
local bb = (function()
local _accum_0 = { }
local _len_0 = 1
for thing in y do
for i = 1, 10 do
_accum_0[_len_0] = y
_len_0 = _len_0 + 1
end
end
return _accum_0
end)()
local cc = (function()
local _accum_0 = { }
local _len_0 = 1
for i = 1, 10 do
for thing in y do
_accum_0[_len_0] = y
_len_0 = _len_0 + 1
end
end
return _accum_0
end)()
local dd = (function()
local _accum_0 = { }
local _len_0 = 1
for i = 1, 10 do
if cool then
for thing in y do
if x > 3 then
if c + 3 then
_accum_0[_len_0] = y
_len_0 = _len_0 + 1
end
end
end
end
end
return _accum_0
end)()
_ = (function()
local _tbl_0 = { }
for i = 1, 10 do
_tbl_0["hello"] = "world"
end
return _tbl_0
end)()
return nil

View File

@ -107,6 +107,9 @@ end
if not (1212 and 3434) then if not (1212 and 3434) then
print("hello") print("hello")
end end
for i = 1, 10 do
print("hello")
end
print("nutjob") print("nutjob")
if hello then if hello then
_ = 343 _ = 343