table comprehensions support single expression that returns a pair

This commit is contained in:
leaf corcoran 2012-10-03 11:30:23 -07:00
parent 867989b4f7
commit 14db695560
6 changed files with 129 additions and 17 deletions

View File

@ -436,6 +436,18 @@ for a few numbers.
sqrts = {i, math.sqrt i for i in *numbers}
```
The key-value tuple in a table comprehension can also come from a single
expression, in which case the expression should return two values. The
first is used as the key and the second is used as the value:
In this example we convert an array of pairs to a table where the first item in
the pair is the key and the second is the value.
```moon
tuples = {{"hello", "world"}, {"foo", "bar"}}
tbl = {unpack tuple for tuple in *tuples}
```
### Slicing
A special syntax is provided to restrict the items that are iterated over when
@ -480,7 +492,7 @@ There are two for loop forms, just like in Lua. A numeric one and a generic one:
print key, value
```
The slicing and `*` operators can be used, just like with table comprehensions:
The slicing and `*` operators can be used, just like with comprehensions:
```moon
for item in *items[2,4]

View File

@ -413,7 +413,7 @@ local build_grammar = wrap_env(function()
Comprehension = sym"[" * Exp * CompInner * sym"]" / mark"comprehension",
TblComprehension = sym"{" * Exp * (sym"," * Exp)^-1 * CompInner * sym"}" / mark"tblcomprehension",
TblComprehension = sym"{" * Ct(Exp * (sym"," * Exp)^-1) * CompInner * sym"}" / mark"tblcomprehension",
CompInner = Ct(CompFor * CompClause^0),
CompFor = key"for" * Ct(NameList) * key"in" * (sym"*" * Exp / mark"unpack" + Exp) / mark"for",

View File

@ -1231,21 +1231,46 @@ Value = Transformer({
return a:wrap(node)
end,
tblcomprehension = function(self, node)
local _, key_exp, value_exp, clauses = unpack(node)
local _, explist, clauses = unpack(node)
local key_exp, value_exp = unpack(explist)
local accum = NameProxy("tbl")
local dest = build.chain({
base = accum,
{
"index",
key_exp
local inner
if value_exp then
local dest = build.chain({
base = accum,
{
"index",
key_exp
}
})
inner = {
build.assign_one(dest, value_exp)
}
})
local inner = build.assign_one(dest, value_exp)
else
local key_name, val_name = NameProxy("key"), NameProxy("val")
local dest = build.chain({
base = accum,
{
"index",
key_name
}
})
inner = {
build.assign({
names = {
key_name,
val_name
},
values = {
key_exp
}
}),
build.assign_one(dest, val_name)
}
end
return build.block_exp({
build.assign_one(accum, build.table()),
construct_comprehension({
inner
}, clauses),
construct_comprehension(inner, clauses),
accum
})
end,

View File

@ -654,15 +654,27 @@ Value = Transformer {
a\wrap node
tblcomprehension: (node) =>
_, key_exp, value_exp, clauses = unpack node
_, explist, clauses = unpack node
key_exp, value_exp = unpack explist
accum = NameProxy "tbl"
dest = build.chain { base: accum, {"index", key_exp} }
inner = build.assign_one dest, value_exp
inner = if value_exp
dest = build.chain { base: accum, {"index", key_exp} }
{ build.assign_one dest, value_exp }
else
-- If we only have single expression then
-- unpack the result into key and value
key_name, val_name = NameProxy"key", NameProxy"val"
dest = build.chain { base: accum, {"index", key_name} }
{
build.assign names: {key_name, val_name}, values: {key_exp}
build.assign_one dest, val_name
}
build.block_exp {
build.assign_one accum, build.table!
construct_comprehension {inner}, clauses
construct_comprehension inner, clauses
accum
}

View File

@ -1,4 +1,6 @@
-- see lists.moon for list comprehension tests
items = {1,2,3,4,5,6}
out = {k,k*2 for k in items}
@ -7,3 +9,11 @@ x = hello: "world", okay: 2323
copy = {k,v for k,v in pairs x when k != "okay"}
--
{ unpack(x) for x in yes }
{ unpack(x) 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}} }

View File

@ -25,4 +25,57 @@ local copy = (function()
end
end
return _tbl_0
end)()
local _ = (function()
local _tbl_0 = { }
for x in yes do
local _key_0, _val_0 = unpack(x)
_tbl_0[_key_0] = _val_0
end
return _tbl_0
end)()
_ = (function()
local _tbl_0 = { }
local _list_0 = yes
for _index_0 = 1, #_list_0 do
x = _list_0[_index_0]
local _key_0, _val_0 = unpack(x)
_tbl_0[_key_0] = _val_0
end
return _tbl_0
end)()
_ = (function()
local _tbl_0 = { }
for x in yes do
local _key_0, _val_0 = xxxx
_tbl_0[_key_0] = _val_0
end
return _tbl_0
end)()
_ = (function()
local _tbl_0 = { }
local _list_0 = {
{
1,
2
},
{
3,
4
}
}
for _index_0 = 1, #_list_0 do
x = _list_0[_index_0]
local _key_0, _val_0 = unpack((function()
local _accum_0 = { }
local _len_0 = 0
for i, a in ipairs(x) do
_len_0 = _len_0 + 1
_accum_0[_len_0] = a * i
end
return _accum_0
end)())
_tbl_0[_key_0] = _val_0
end
return _tbl_0
end)()