mirror of
https://github.com/leafo/moonscript.git
synced 2024-11-22 02:44:23 +00:00
allow destructure in for in names
This commit is contained in:
parent
7498a52aee
commit
25b997e71f
@ -435,7 +435,7 @@ local build_grammar = wrap_env(function()
|
||||
For = key"for" * DisableDo * ensure(Name * sym"=" * Ct(Exp * sym"," * Exp * (sym"," * Exp)^-1), PopDo) *
|
||||
key"do"^-1 * Body / mark"for",
|
||||
|
||||
ForEach = key"for" * Ct(NameList) * key"in" * DisableDo * ensure(Ct(sym"*" * Exp / mark"unpack" + ExpList), PopDo) * key"do"^-1 * Body / mark"foreach",
|
||||
ForEach = key"for" * Ct(AssignableNameList) * key"in" * DisableDo * ensure(Ct(sym"*" * Exp / mark"unpack" + ExpList), PopDo) * key"do"^-1 * Body / mark"foreach",
|
||||
|
||||
Do = key"do" * Body / mark"do",
|
||||
|
||||
@ -575,7 +575,7 @@ local build_grammar = wrap_env(function()
|
||||
(key"using" * Ct(NameList + Space * "nil") + Ct"") *
|
||||
sym")" + Ct"" * Ct"",
|
||||
|
||||
FnArgDefList = FnArgDef * (sym"," * FnArgDef)^0,
|
||||
FnArgDefList = FnArgDef * (sym"," * FnArgDef)^0,
|
||||
FnArgDef = Ct(Name * (sym"=" * Exp)^-1),
|
||||
|
||||
FunLit = FnArgsDef *
|
||||
@ -583,6 +583,9 @@ local build_grammar = wrap_env(function()
|
||||
(Body + Ct"") / mark"fndef",
|
||||
|
||||
NameList = Name * (sym"," * Name)^0,
|
||||
NameOrDestructure = Name + TableLit,
|
||||
AssignableNameList = NameOrDestructure * (sym"," * NameOrDestructure)^0,
|
||||
|
||||
ExpList = Exp * (sym"," * Exp)^0,
|
||||
ExpListLow = Exp * ((sym"," + sym";") * Exp)^0,
|
||||
|
||||
|
@ -2,7 +2,7 @@ local types = require("moonscript.types")
|
||||
local util = require("moonscript.util")
|
||||
local data = require("moonscript.data")
|
||||
local reversed = util.reversed
|
||||
local ntype, build, smart_node, is_slice, value_is_singular = types.ntype, types.build, types.smart_node, types.is_slice, types.value_is_singular
|
||||
local ntype, mtype, build, smart_node, is_slice, value_is_singular = types.ntype, types.mtype, types.build, types.smart_node, types.is_slice, types.value_is_singular
|
||||
local insert = table.insert
|
||||
local NameProxy, LocalName
|
||||
do
|
||||
@ -10,18 +10,6 @@ do
|
||||
NameProxy, LocalName = _table_0.NameProxy, _table_0.LocalName
|
||||
end
|
||||
local destructure = require("moonscript.transform.destructure")
|
||||
local mtype
|
||||
do
|
||||
local moon_type = util.moon.type
|
||||
mtype = function(val)
|
||||
local t = type(val)
|
||||
if "table" == t and rawget(val, "__class") then
|
||||
return moon_type(val)
|
||||
else
|
||||
return t
|
||||
end
|
||||
end
|
||||
end
|
||||
local implicitly_return
|
||||
local Run
|
||||
do
|
||||
@ -670,6 +658,34 @@ local Statement = Transformer({
|
||||
foreach = function(self, node)
|
||||
smart_node(node)
|
||||
local source = unpack(node.iter)
|
||||
local destructures = { }
|
||||
node.names = (function()
|
||||
local _accum_0 = { }
|
||||
local _len_0 = 0
|
||||
for i, name in ipairs(node.names) do
|
||||
local _value_0
|
||||
if ntype(name) == "table" then
|
||||
do
|
||||
local _with_0 = NameProxy("des")
|
||||
local proxy = _with_0
|
||||
local extracted = destructure.extract_assign_names(name)
|
||||
insert(destructures, destructure.build_assign(extracted, proxy))
|
||||
_value_0 = _with_0
|
||||
end
|
||||
else
|
||||
_value_0 = name
|
||||
end
|
||||
if _value_0 ~= nil then
|
||||
_len_0 = _len_0 + 1
|
||||
_accum_0[_len_0] = _value_0
|
||||
end
|
||||
end
|
||||
return _accum_0
|
||||
end)()
|
||||
if next(destructures) then
|
||||
insert(destructures, build.group(node.body))
|
||||
node.body = destructures
|
||||
end
|
||||
if ntype(source) == "unpack" then
|
||||
local list = source[2]
|
||||
local index_name = NameProxy("index")
|
||||
|
@ -4,22 +4,12 @@ util = require "moonscript.util"
|
||||
data = require "moonscript.data"
|
||||
|
||||
import reversed from util
|
||||
import ntype, build, smart_node, is_slice, value_is_singular from types
|
||||
import ntype, mtype, build, smart_node, is_slice, value_is_singular from types
|
||||
import insert from table
|
||||
import NameProxy, LocalName from require "moonscript.transform.names"
|
||||
|
||||
destructure = require "moonscript.transform.destructure"
|
||||
|
||||
mtype = do
|
||||
moon_type = util.moon.type
|
||||
-- lets us check a smart node without throwing an error
|
||||
(val) ->
|
||||
t = type(val)
|
||||
if "table" == t and rawget(val, "__class")
|
||||
moon_type val
|
||||
else
|
||||
t
|
||||
|
||||
local implicitly_return
|
||||
|
||||
class Run
|
||||
@ -347,6 +337,19 @@ Statement = Transformer {
|
||||
smart_node node
|
||||
source = unpack node.iter
|
||||
|
||||
destructures = {}
|
||||
node.names = for i, name in ipairs node.names
|
||||
if ntype(name) == "table"
|
||||
with proxy = NameProxy "des"
|
||||
extracted = destructure.extract_assign_names name
|
||||
insert destructures, destructure.build_assign extracted, proxy
|
||||
else
|
||||
name
|
||||
|
||||
if next destructures
|
||||
insert destructures, build.group node.body
|
||||
node.body = destructures
|
||||
|
||||
if ntype(source) == "unpack"
|
||||
list = source[2]
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
local ntype, build
|
||||
local ntype, mtype, build
|
||||
do
|
||||
local _table_0 = require("moonscript.types")
|
||||
ntype, build = _table_0.ntype, _table_0.build
|
||||
ntype, mtype, build = _table_0.ntype, _table_0.mtype, _table_0.build
|
||||
end
|
||||
local NameProxy
|
||||
do
|
||||
@ -48,9 +48,31 @@ has_destructure = function(names)
|
||||
end
|
||||
local build_assign
|
||||
build_assign = function(extracted_names, receiver)
|
||||
local obj = NameProxy("obj")
|
||||
local names = { }
|
||||
local values = { }
|
||||
local inner = {
|
||||
"assign",
|
||||
names,
|
||||
values
|
||||
}
|
||||
local obj
|
||||
if mtype(receiver) == NameProxy then
|
||||
obj = receiver
|
||||
else
|
||||
do
|
||||
local _with_0 = NameProxy("obj")
|
||||
obj = _with_0
|
||||
inner = build["do"]({
|
||||
build.assign_one(obj, receiver),
|
||||
{
|
||||
"assign",
|
||||
names,
|
||||
values
|
||||
}
|
||||
})
|
||||
obj = _with_0
|
||||
end
|
||||
end
|
||||
local _list_0 = extracted_names
|
||||
for _index_0 = 1, #_list_0 do
|
||||
local tuple = _list_0[_index_0]
|
||||
@ -62,14 +84,7 @@ build_assign = function(extracted_names, receiver)
|
||||
"declare",
|
||||
names
|
||||
},
|
||||
build["do"]({
|
||||
build.assign_one(obj, receiver),
|
||||
{
|
||||
"assign",
|
||||
names,
|
||||
values
|
||||
}
|
||||
})
|
||||
inner
|
||||
})
|
||||
end
|
||||
local extract_assign_names
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
import ntype, build from require "moonscript.types"
|
||||
import ntype, mtype, build from require "moonscript.types"
|
||||
import NameProxy from require "moonscript.transform.names"
|
||||
import insert from table
|
||||
|
||||
@ -19,20 +19,27 @@ has_destructure = (names) ->
|
||||
false
|
||||
|
||||
build_assign = (extracted_names, receiver) ->
|
||||
obj = NameProxy "obj"
|
||||
names = {}
|
||||
values = {}
|
||||
|
||||
inner = {"assign", names, values}
|
||||
|
||||
obj = if mtype(receiver) == NameProxy
|
||||
receiver
|
||||
else
|
||||
with obj = NameProxy "obj"
|
||||
inner = build.do {
|
||||
build.assign_one obj, receiver
|
||||
{"assign", names, values}
|
||||
}
|
||||
|
||||
for tuple in *extracted_names
|
||||
insert names, tuple[1]
|
||||
insert values, obj\chain unpack tuple[2]
|
||||
|
||||
build.group {
|
||||
{"declare", names}
|
||||
build.do {
|
||||
build.assign_one obj, receiver
|
||||
{"assign", names, values}
|
||||
}
|
||||
inner
|
||||
}
|
||||
|
||||
extract_assign_names = (name, accum={}, prefix={}) ->
|
||||
|
@ -26,6 +26,17 @@ ntype = function(node)
|
||||
return "value"
|
||||
end
|
||||
end
|
||||
local mtype
|
||||
do
|
||||
local moon_type = util.moon.type
|
||||
mtype = function(val)
|
||||
local mt = getmetatable(val)
|
||||
if mt and mt.smart_node then
|
||||
return "table"
|
||||
end
|
||||
return moon_type(val)
|
||||
end
|
||||
end
|
||||
local has_value
|
||||
has_value = function(node)
|
||||
if ntype(node) == "chain" then
|
||||
@ -260,27 +271,32 @@ build = setmetatable({
|
||||
return rawget(self, name)
|
||||
end
|
||||
})
|
||||
local smart_node_mt = setmetatable({ }, {
|
||||
__index = function(self, node_type)
|
||||
local index = key_table[node_type]
|
||||
local mt = {
|
||||
smart_node = true,
|
||||
__index = function(node, key)
|
||||
if index[key] then
|
||||
return rawget(node, index[key])
|
||||
elseif type(key) == "string" then
|
||||
return error("unknown key: `" .. key .. "` on node type: `" .. ntype(node) .. "`")
|
||||
end
|
||||
end,
|
||||
__newindex = function(node, key, value)
|
||||
if index[key] then
|
||||
key = index[key]
|
||||
end
|
||||
return rawset(node, key, value)
|
||||
end
|
||||
}
|
||||
self[node_type] = mt
|
||||
return mt
|
||||
end
|
||||
})
|
||||
local smart_node
|
||||
smart_node = function(node)
|
||||
local index = key_table[ntype(node)]
|
||||
if not index then
|
||||
return node
|
||||
end
|
||||
return setmetatable(node, {
|
||||
__index = function(node, key)
|
||||
if index[key] then
|
||||
return rawget(node, index[key])
|
||||
elseif type(key) == "string" then
|
||||
return error("unknown key: `" .. key .. "` on node type: `" .. ntype(node) .. "`")
|
||||
end
|
||||
end,
|
||||
__newindex = function(node, key, value)
|
||||
if index[key] then
|
||||
key = index[key]
|
||||
end
|
||||
return rawset(node, key, value)
|
||||
end
|
||||
})
|
||||
return setmetatable(node, smart_node_mt[ntype(node)])
|
||||
end
|
||||
return {
|
||||
ntype = ntype,
|
||||
@ -292,5 +308,6 @@ return {
|
||||
cascading = cascading,
|
||||
value_is_singular = value_is_singular,
|
||||
comprehension_has_value = comprehension_has_value,
|
||||
has_value = has_value
|
||||
has_value = has_value,
|
||||
mtype = mtype
|
||||
}
|
||||
|
@ -22,6 +22,14 @@ ntype = (node) ->
|
||||
else
|
||||
"value"
|
||||
|
||||
mtype = do
|
||||
moon_type = util.moon.type
|
||||
-- lets us check a smart node without throwing an error
|
||||
(val) ->
|
||||
mt = getmetatable val
|
||||
return "table" if mt and mt.smart_node
|
||||
moon_type val
|
||||
|
||||
-- does this always return a value
|
||||
has_value = (node) ->
|
||||
if ntype(node) == "chain"
|
||||
@ -142,25 +150,33 @@ build = setmetatable {
|
||||
rawget self, name
|
||||
}
|
||||
|
||||
smart_node_mt = setmetatable {}, {
|
||||
__index: (node_type) =>
|
||||
index = key_table[node_type]
|
||||
mt = {
|
||||
smart_node: true
|
||||
|
||||
__index: (node, key) ->
|
||||
if index[key]
|
||||
rawget node, index[key]
|
||||
elseif type(key) == "string"
|
||||
error "unknown key: `"..key.."` on node type: `"..ntype(node).. "`"
|
||||
|
||||
__newindex: (node, key, value) ->
|
||||
key = index[key] if index[key]
|
||||
rawset node, key, value
|
||||
}
|
||||
self[node_type] = mt
|
||||
mt
|
||||
}
|
||||
|
||||
-- makes it so node properties can be accessed by name instead of index
|
||||
smart_node = (node) ->
|
||||
index = key_table[ntype node]
|
||||
if not index then return node
|
||||
setmetatable node, {
|
||||
__index: (node, key) ->
|
||||
if index[key]
|
||||
rawget node, index[key]
|
||||
elseif type(key) == "string"
|
||||
error "unknown key: `"..key.."` on node type: `"..ntype(node).. "`"
|
||||
|
||||
__newindex: (node, key, value) ->
|
||||
key = index[key] if index[key]
|
||||
rawset node, key, value
|
||||
}
|
||||
|
||||
setmetatable node, smart_node_mt[ntype node]
|
||||
|
||||
{
|
||||
:ntype, :smart_node, :build, :is_value, :is_slice, :manual_return,
|
||||
:cascading, :value_is_singular, :comprehension_has_value, :has_value
|
||||
:cascading, :value_is_singular, :comprehension_has_value, :has_value,
|
||||
:mtype
|
||||
}
|
||||
|
||||
|
@ -43,3 +43,11 @@ print name, street, city
|
||||
|
||||
{ world: @world } = x
|
||||
|
||||
--
|
||||
|
||||
thing = {{1,2}, {3,4}}
|
||||
|
||||
for {x,y} in *thing
|
||||
print x,y
|
||||
|
||||
|
||||
|
@ -85,4 +85,20 @@ end
|
||||
do
|
||||
local _obj_0 = x
|
||||
self.world = _obj_0.world
|
||||
end
|
||||
thing = {
|
||||
{
|
||||
1,
|
||||
2
|
||||
},
|
||||
{
|
||||
3,
|
||||
4
|
||||
}
|
||||
}
|
||||
local _list_0 = thing
|
||||
for _index_0 = 1, #_list_0 do
|
||||
local _des_0 = _list_0[_index_0]
|
||||
x, y = _des_0[1], _des_0[2]
|
||||
print(x, y)
|
||||
end
|
Loading…
Reference in New Issue
Block a user