mirror of
https://github.com/leafo/moonscript.git
synced 2025-01-09 00:04:22 +00:00
add destructuring assignment
This commit is contained in:
parent
3adaed672e
commit
89f4a83f26
@ -5,7 +5,11 @@ require("moonscript.compile.format")
|
|||||||
require("moonscript.compile.statement")
|
require("moonscript.compile.statement")
|
||||||
require("moonscript.compile.value")
|
require("moonscript.compile.value")
|
||||||
local transform = require("moonscript.transform")
|
local transform = require("moonscript.transform")
|
||||||
local NameProxy, LocalName = transform.NameProxy, transform.LocalName
|
local NameProxy, LocalName
|
||||||
|
do
|
||||||
|
local _table_0 = require("moonscript.transform.names")
|
||||||
|
NameProxy, LocalName = _table_0.NameProxy, _table_0.LocalName
|
||||||
|
end
|
||||||
local Set
|
local Set
|
||||||
do
|
do
|
||||||
local _table_0 = require("moonscript.data")
|
local _table_0 = require("moonscript.data")
|
||||||
|
@ -9,7 +9,7 @@ require "moonscript.compile.value"
|
|||||||
|
|
||||||
transform = require "moonscript.transform"
|
transform = require "moonscript.transform"
|
||||||
|
|
||||||
import NameProxy, LocalName from transform
|
import NameProxy, LocalName from require "moonscript.transform.names"
|
||||||
import Set from require "moonscript.data"
|
import Set from require "moonscript.data"
|
||||||
import ntype from require "moonscript.types"
|
import ntype from require "moonscript.types"
|
||||||
|
|
||||||
|
@ -170,7 +170,8 @@ local _chain_assignable = { index = true, dot = true, slice = true }
|
|||||||
local function is_assignable(node)
|
local function is_assignable(node)
|
||||||
local t = ntype(node)
|
local t = ntype(node)
|
||||||
return t == "self" or t == "value" or t == "self_class" or
|
return t == "self" or t == "value" or t == "self_class" or
|
||||||
t == "chain" and _chain_assignable[ntype(node[#node])]
|
t == "chain" and _chain_assignable[ntype(node[#node])] or
|
||||||
|
t == "table"
|
||||||
end
|
end
|
||||||
|
|
||||||
local function check_assignable(str, pos, value)
|
local function check_assignable(str, pos, value)
|
||||||
|
@ -5,6 +5,12 @@ local data = require("moonscript.data")
|
|||||||
local reversed = util.reversed
|
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, build, smart_node, is_slice, value_is_singular = types.ntype, types.build, types.smart_node, types.is_slice, types.value_is_singular
|
||||||
local insert = table.insert
|
local insert = table.insert
|
||||||
|
local NameProxy, LocalName
|
||||||
|
do
|
||||||
|
local _table_0 = require("moonscript.transform.names")
|
||||||
|
NameProxy, LocalName = _table_0.NameProxy, _table_0.LocalName
|
||||||
|
end
|
||||||
|
local destructure = require("moonscript.transform.destructure")
|
||||||
local mtype
|
local mtype
|
||||||
do
|
do
|
||||||
local moon_type = util.moon.type
|
local moon_type = util.moon.type
|
||||||
@ -18,136 +24,6 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
local implicitly_return
|
local implicitly_return
|
||||||
do
|
|
||||||
local _parent_0 = nil
|
|
||||||
local _base_0 = {
|
|
||||||
get_name = function(self)
|
|
||||||
return self.name
|
|
||||||
end
|
|
||||||
}
|
|
||||||
_base_0.__index = _base_0
|
|
||||||
if _parent_0 then
|
|
||||||
setmetatable(_base_0, _parent_0.__base)
|
|
||||||
end
|
|
||||||
local _class_0 = setmetatable({
|
|
||||||
__init = function(self, name)
|
|
||||||
self.name = name
|
|
||||||
self[1] = "temp_name"
|
|
||||||
end,
|
|
||||||
__base = _base_0,
|
|
||||||
__name = "LocalName",
|
|
||||||
__parent = _parent_0
|
|
||||||
}, {
|
|
||||||
__index = function(cls, name)
|
|
||||||
local val = rawget(_base_0, name)
|
|
||||||
if val == nil and _parent_0 then
|
|
||||||
return _parent_0[name]
|
|
||||||
else
|
|
||||||
return val
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
__call = function(cls, ...)
|
|
||||||
local _self_0 = setmetatable({}, _base_0)
|
|
||||||
cls.__init(_self_0, ...)
|
|
||||||
return _self_0
|
|
||||||
end
|
|
||||||
})
|
|
||||||
_base_0.__class = _class_0
|
|
||||||
if _parent_0 and _parent_0.__inherited then
|
|
||||||
_parent_0.__inherited(_parent_0, _class_0)
|
|
||||||
end
|
|
||||||
LocalName = _class_0
|
|
||||||
end
|
|
||||||
do
|
|
||||||
local _parent_0 = nil
|
|
||||||
local _base_0 = {
|
|
||||||
get_name = function(self, scope)
|
|
||||||
if not self.name then
|
|
||||||
self.name = scope:free_name(self.prefix, true)
|
|
||||||
end
|
|
||||||
return self.name
|
|
||||||
end,
|
|
||||||
chain = function(self, ...)
|
|
||||||
local items = {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
items = (function()
|
|
||||||
local _accum_0 = { }
|
|
||||||
local _len_0 = 0
|
|
||||||
local _list_0 = items
|
|
||||||
for _index_0 = 1, #_list_0 do
|
|
||||||
local i = _list_0[_index_0]
|
|
||||||
local _value_0
|
|
||||||
if type(i) == "string" then
|
|
||||||
_value_0 = {
|
|
||||||
"dot",
|
|
||||||
i
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_value_0 = i
|
|
||||||
end
|
|
||||||
if _value_0 ~= nil then
|
|
||||||
_len_0 = _len_0 + 1
|
|
||||||
_accum_0[_len_0] = _value_0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return _accum_0
|
|
||||||
end)()
|
|
||||||
return build.chain({
|
|
||||||
base = self,
|
|
||||||
unpack(items)
|
|
||||||
})
|
|
||||||
end,
|
|
||||||
index = function(self, key)
|
|
||||||
return build.chain({
|
|
||||||
base = self,
|
|
||||||
{
|
|
||||||
"index",
|
|
||||||
key
|
|
||||||
}
|
|
||||||
})
|
|
||||||
end,
|
|
||||||
__tostring = function(self)
|
|
||||||
if self.name then
|
|
||||||
return ("name<%s>"):format(self.name)
|
|
||||||
else
|
|
||||||
return ("name<prefix(%s)>"):format(self.prefix)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
}
|
|
||||||
_base_0.__index = _base_0
|
|
||||||
if _parent_0 then
|
|
||||||
setmetatable(_base_0, _parent_0.__base)
|
|
||||||
end
|
|
||||||
local _class_0 = setmetatable({
|
|
||||||
__init = function(self, prefix)
|
|
||||||
self.prefix = prefix
|
|
||||||
self[1] = "temp_name"
|
|
||||||
end,
|
|
||||||
__base = _base_0,
|
|
||||||
__name = "NameProxy",
|
|
||||||
__parent = _parent_0
|
|
||||||
}, {
|
|
||||||
__index = function(cls, name)
|
|
||||||
local val = rawget(_base_0, name)
|
|
||||||
if val == nil and _parent_0 then
|
|
||||||
return _parent_0[name]
|
|
||||||
else
|
|
||||||
return val
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
__call = function(cls, ...)
|
|
||||||
local _self_0 = setmetatable({}, _base_0)
|
|
||||||
cls.__init(_self_0, ...)
|
|
||||||
return _self_0
|
|
||||||
end
|
|
||||||
})
|
|
||||||
_base_0.__class = _class_0
|
|
||||||
if _parent_0 and _parent_0.__inherited then
|
|
||||||
_parent_0.__inherited(_parent_0, _class_0)
|
|
||||||
end
|
|
||||||
NameProxy = _class_0
|
|
||||||
end
|
|
||||||
do
|
do
|
||||||
local _parent_0 = nil
|
local _parent_0 = nil
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
@ -497,7 +373,11 @@ Statement = Transformer({
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return transformed or node
|
node = transformed or node
|
||||||
|
if destructure.has_destructure(names) then
|
||||||
|
return destructure.split_assign(node)
|
||||||
|
end
|
||||||
|
return node
|
||||||
end,
|
end,
|
||||||
continue = function(self, node)
|
continue = function(self, node)
|
||||||
local continue_name = self:send("continue")
|
local continue_name = self:send("continue")
|
||||||
|
@ -8,6 +8,9 @@ data = require "moonscript.data"
|
|||||||
import reversed from util
|
import reversed from util
|
||||||
import ntype, build, smart_node, is_slice, value_is_singular from types
|
import ntype, build, smart_node, is_slice, value_is_singular from types
|
||||||
import insert from table
|
import insert from table
|
||||||
|
import NameProxy, LocalName from require "moonscript.transform.names"
|
||||||
|
|
||||||
|
destructure = require "moonscript.transform.destructure"
|
||||||
|
|
||||||
mtype = do
|
mtype = do
|
||||||
moon_type = util.moon.type
|
moon_type = util.moon.type
|
||||||
@ -19,48 +22,10 @@ mtype = do
|
|||||||
else
|
else
|
||||||
t
|
t
|
||||||
|
|
||||||
export Statement, Value, NameProxy, LocalName, Run
|
export Statement, Value, Run
|
||||||
|
|
||||||
local implicitly_return
|
local implicitly_return
|
||||||
|
|
||||||
-- always declares as local
|
|
||||||
class LocalName
|
|
||||||
new: (@name) => self[1] = "temp_name"
|
|
||||||
get_name: => @name
|
|
||||||
|
|
||||||
class NameProxy
|
|
||||||
new: (@prefix) =>
|
|
||||||
self[1] = "temp_name"
|
|
||||||
|
|
||||||
get_name: (scope) =>
|
|
||||||
if not @name
|
|
||||||
@name = scope\free_name @prefix, true
|
|
||||||
@name
|
|
||||||
|
|
||||||
chain: (...) =>
|
|
||||||
items = {...} -- todo: fix ... propagation
|
|
||||||
items = for i in *items
|
|
||||||
if type(i) == "string"
|
|
||||||
{"dot", i}
|
|
||||||
else
|
|
||||||
i
|
|
||||||
|
|
||||||
build.chain {
|
|
||||||
base: self
|
|
||||||
unpack items
|
|
||||||
}
|
|
||||||
|
|
||||||
index: (key) =>
|
|
||||||
build.chain {
|
|
||||||
base: self, {"index", key}
|
|
||||||
}
|
|
||||||
|
|
||||||
__tostring: =>
|
|
||||||
if @name
|
|
||||||
("name<%s>")\format @name
|
|
||||||
else
|
|
||||||
("name<prefix(%s)>")\format @prefix
|
|
||||||
|
|
||||||
class Run
|
class Run
|
||||||
new: (@fn) =>
|
new: (@fn) =>
|
||||||
self[1] = "run"
|
self[1] = "run"
|
||||||
@ -228,7 +193,12 @@ Statement = Transformer {
|
|||||||
@transform.statement value, ret, node
|
@transform.statement value, ret, node
|
||||||
}
|
}
|
||||||
|
|
||||||
transformed or node
|
node = transformed or node
|
||||||
|
|
||||||
|
if destructure.has_destructure names
|
||||||
|
return destructure.split_assign node
|
||||||
|
|
||||||
|
node
|
||||||
|
|
||||||
continue: (node) =>
|
continue: (node) =>
|
||||||
continue_name = @send "continue"
|
continue_name = @send "continue"
|
||||||
|
227
moonscript/transform/destructure.lua
Normal file
227
moonscript/transform/destructure.lua
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
local ntype, build
|
||||||
|
do
|
||||||
|
local _table_0 = require("moonscript.types")
|
||||||
|
ntype, build = _table_0.ntype, _table_0.build
|
||||||
|
end
|
||||||
|
local NameProxy
|
||||||
|
do
|
||||||
|
local _table_0 = require("moonscript.transform.names")
|
||||||
|
NameProxy = _table_0.NameProxy
|
||||||
|
end
|
||||||
|
local insert = table.insert
|
||||||
|
local user_error
|
||||||
|
do
|
||||||
|
local _table_0 = require("moonscript.compile")
|
||||||
|
user_error = _table_0.user_error
|
||||||
|
end
|
||||||
|
local join
|
||||||
|
join = function(...)
|
||||||
|
do
|
||||||
|
local _with_0 = { }
|
||||||
|
local out = _with_0
|
||||||
|
local i = 1
|
||||||
|
local _list_0 = {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
for _index_0 = 1, #_list_0 do
|
||||||
|
local tbl = _list_0[_index_0]
|
||||||
|
local _list_1 = tbl
|
||||||
|
for _index_1 = 1, #_list_1 do
|
||||||
|
local v = _list_1[_index_1]
|
||||||
|
out[i] = v
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return _with_0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local has_destructure
|
||||||
|
has_destructure = function(names)
|
||||||
|
local _list_0 = names
|
||||||
|
for _index_0 = 1, #_list_0 do
|
||||||
|
local n = _list_0[_index_0]
|
||||||
|
if ntype(n) == "table" then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local build_assign
|
||||||
|
build_assign = function(extracted_names, receiver)
|
||||||
|
local obj = NameProxy("obj")
|
||||||
|
local names = { }
|
||||||
|
local values = { }
|
||||||
|
local _list_0 = extracted_names
|
||||||
|
for _index_0 = 1, #_list_0 do
|
||||||
|
local tuple = _list_0[_index_0]
|
||||||
|
insert(names, tuple[1])
|
||||||
|
insert(values, obj:chain(unpack(tuple[2])))
|
||||||
|
end
|
||||||
|
return build.group({
|
||||||
|
{
|
||||||
|
"declare",
|
||||||
|
names
|
||||||
|
},
|
||||||
|
build["do"]({
|
||||||
|
build.assign_one(obj, receiver),
|
||||||
|
{
|
||||||
|
"assign",
|
||||||
|
names,
|
||||||
|
values
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
end
|
||||||
|
local extract_assign_names
|
||||||
|
extract_assign_names = function(name, accum, prefix)
|
||||||
|
if accum == nil then
|
||||||
|
accum = { }
|
||||||
|
end
|
||||||
|
if prefix == nil then
|
||||||
|
prefix = { }
|
||||||
|
end
|
||||||
|
local i = 1
|
||||||
|
local _list_0 = name[2]
|
||||||
|
for _index_0 = 1, #_list_0 do
|
||||||
|
local tuple = _list_0[_index_0]
|
||||||
|
local value, suffix
|
||||||
|
if #tuple == 1 then
|
||||||
|
local s = {
|
||||||
|
"index",
|
||||||
|
{
|
||||||
|
"number",
|
||||||
|
i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = i + 1
|
||||||
|
value, suffix = tuple[1], s
|
||||||
|
else
|
||||||
|
local key = tuple[1]
|
||||||
|
local s
|
||||||
|
if ntype(key) == "key_literal" then
|
||||||
|
s = {
|
||||||
|
"dot",
|
||||||
|
key[2]
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s = {
|
||||||
|
"index",
|
||||||
|
key
|
||||||
|
}
|
||||||
|
end
|
||||||
|
value, suffix = tuple[2], s
|
||||||
|
end
|
||||||
|
suffix = join(prefix, {
|
||||||
|
suffix
|
||||||
|
})
|
||||||
|
local t = ntype(value)
|
||||||
|
if t == "value" or t == "chain" or t == "self" then
|
||||||
|
insert(accum, {
|
||||||
|
value,
|
||||||
|
suffix
|
||||||
|
})
|
||||||
|
elseif t == "table" then
|
||||||
|
extract_assign_names(value, accum, suffix)
|
||||||
|
else
|
||||||
|
user_error("Can't destructure value of type: " .. tostring(ntype(value)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return accum
|
||||||
|
end
|
||||||
|
local split_assign
|
||||||
|
split_assign = function(assign)
|
||||||
|
local names, values = unpack(assign, 2)
|
||||||
|
local g = { }
|
||||||
|
local total_names = #names
|
||||||
|
local total_values = #values
|
||||||
|
local start = 1
|
||||||
|
for i, n in ipairs(names) do
|
||||||
|
if ntype(n) == "table" then
|
||||||
|
if i > start then
|
||||||
|
local stop = i - 1
|
||||||
|
insert(g, {
|
||||||
|
"assign",
|
||||||
|
(function()
|
||||||
|
local _accum_0 = { }
|
||||||
|
local _len_0 = 0
|
||||||
|
for i = start, stop do
|
||||||
|
local _value_0 = names[i]
|
||||||
|
if _value_0 ~= nil then
|
||||||
|
_len_0 = _len_0 + 1
|
||||||
|
_accum_0[_len_0] = _value_0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return _accum_0
|
||||||
|
end)(),
|
||||||
|
(function()
|
||||||
|
local _accum_0 = { }
|
||||||
|
local _len_0 = 0
|
||||||
|
for i = start, stop do
|
||||||
|
local _value_0 = values[i]
|
||||||
|
if _value_0 ~= nil then
|
||||||
|
_len_0 = _len_0 + 1
|
||||||
|
_accum_0[_len_0] = _value_0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return _accum_0
|
||||||
|
end)()
|
||||||
|
})
|
||||||
|
end
|
||||||
|
local extracted = extract_assign_names(n)
|
||||||
|
insert(g, build_assign(extracted, values[i]))
|
||||||
|
start = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if total_names >= start or total_values >= start then
|
||||||
|
local name_slice
|
||||||
|
if total_names < start then
|
||||||
|
name_slice = {
|
||||||
|
"_"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
name_slice = (function()
|
||||||
|
local _accum_0 = { }
|
||||||
|
local _len_0 = 0
|
||||||
|
for i = start, total_names do
|
||||||
|
local _value_0 = names[i]
|
||||||
|
if _value_0 ~= nil then
|
||||||
|
_len_0 = _len_0 + 1
|
||||||
|
_accum_0[_len_0] = _value_0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return _accum_0
|
||||||
|
end)()
|
||||||
|
end
|
||||||
|
local value_slice
|
||||||
|
if total_values < start then
|
||||||
|
value_slice = {
|
||||||
|
"nil"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
value_slice = (function()
|
||||||
|
local _accum_0 = { }
|
||||||
|
local _len_0 = 0
|
||||||
|
for i = start, total_values do
|
||||||
|
local _value_0 = values[i]
|
||||||
|
if _value_0 ~= nil then
|
||||||
|
_len_0 = _len_0 + 1
|
||||||
|
_accum_0[_len_0] = _value_0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return _accum_0
|
||||||
|
end)()
|
||||||
|
end
|
||||||
|
insert(g, {
|
||||||
|
"assign",
|
||||||
|
name_slice,
|
||||||
|
value_slice
|
||||||
|
})
|
||||||
|
end
|
||||||
|
return build.group(g)
|
||||||
|
end
|
||||||
|
return {
|
||||||
|
has_destructure = has_destructure,
|
||||||
|
split_assign = split_assign,
|
||||||
|
extract_assign_names = extract_assign_names,
|
||||||
|
build_assign = build_assign
|
||||||
|
}
|
109
moonscript/transform/destructure.moon
Normal file
109
moonscript/transform/destructure.moon
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
|
||||||
|
import ntype, build from require "moonscript.types"
|
||||||
|
import NameProxy from require "moonscript.transform.names"
|
||||||
|
import insert from table
|
||||||
|
|
||||||
|
import user_error from require "moonscript.compile"
|
||||||
|
|
||||||
|
join = (...) ->
|
||||||
|
with out = {}
|
||||||
|
i = 1
|
||||||
|
for tbl in *{...}
|
||||||
|
for v in *tbl
|
||||||
|
out[i] = v
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
has_destructure = (names) ->
|
||||||
|
for n in *names
|
||||||
|
return true if ntype(n) == "table"
|
||||||
|
false
|
||||||
|
|
||||||
|
build_assign = (extracted_names, receiver) ->
|
||||||
|
obj = NameProxy "obj"
|
||||||
|
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}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extract_assign_names = (name, accum={}, prefix={}) ->
|
||||||
|
i = 1
|
||||||
|
for tuple in *name[2]
|
||||||
|
value, suffix = if #tuple == 1
|
||||||
|
s = {"index", {"number", i}}
|
||||||
|
i += 1
|
||||||
|
tuple[1], s
|
||||||
|
else
|
||||||
|
key = tuple[1]
|
||||||
|
s = if ntype(key) == "key_literal"
|
||||||
|
{"dot", key[2]}
|
||||||
|
else
|
||||||
|
{"index", key}
|
||||||
|
|
||||||
|
tuple[2], s
|
||||||
|
|
||||||
|
suffix = join prefix, {suffix}
|
||||||
|
|
||||||
|
t = ntype value
|
||||||
|
if t == "value" or t == "chain" or t == "self"
|
||||||
|
insert accum, {value, suffix}
|
||||||
|
elseif t == "table"
|
||||||
|
extract_assign_names value, accum, suffix
|
||||||
|
else
|
||||||
|
user_error "Can't destructure value of type: #{ntype value}"
|
||||||
|
|
||||||
|
accum
|
||||||
|
|
||||||
|
-- applies to destructuring to a assign node
|
||||||
|
split_assign = (assign) ->
|
||||||
|
names, values = unpack assign, 2
|
||||||
|
|
||||||
|
g = {}
|
||||||
|
total_names = #names
|
||||||
|
total_values = #values
|
||||||
|
|
||||||
|
-- We have to break apart the assign into groups of regular
|
||||||
|
-- assigns, and then the destructuring assignments
|
||||||
|
start = 1
|
||||||
|
for i, n in ipairs names
|
||||||
|
if ntype(n) == "table"
|
||||||
|
if i > start
|
||||||
|
stop = i - 1
|
||||||
|
insert g, {
|
||||||
|
"assign"
|
||||||
|
for i=start,stop
|
||||||
|
names[i]
|
||||||
|
for i=start,stop
|
||||||
|
values[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
extracted = extract_assign_names n
|
||||||
|
insert g, build_assign extracted, values[i]
|
||||||
|
|
||||||
|
start = i + 1
|
||||||
|
|
||||||
|
if total_names >= start or total_values >= start
|
||||||
|
name_slice = if total_names < start
|
||||||
|
{"_"}
|
||||||
|
else
|
||||||
|
for i=start,total_names do names[i]
|
||||||
|
|
||||||
|
value_slice = if total_values < start
|
||||||
|
{"nil"}
|
||||||
|
else
|
||||||
|
for i=start,total_values do values[i]
|
||||||
|
|
||||||
|
insert g, {"assign", name_slice, value_slice}
|
||||||
|
|
||||||
|
build.group g
|
||||||
|
|
||||||
|
{ :has_destructure, :split_assign, :extract_assign_names, :build_assign }
|
140
moonscript/transform/names.lua
Normal file
140
moonscript/transform/names.lua
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
local build
|
||||||
|
do
|
||||||
|
local _table_0 = require("moonscript.types")
|
||||||
|
build = _table_0.build
|
||||||
|
end
|
||||||
|
local LocalName
|
||||||
|
do
|
||||||
|
local _parent_0 = nil
|
||||||
|
local _base_0 = {
|
||||||
|
get_name = function(self)
|
||||||
|
return self.name
|
||||||
|
end
|
||||||
|
}
|
||||||
|
_base_0.__index = _base_0
|
||||||
|
if _parent_0 then
|
||||||
|
setmetatable(_base_0, _parent_0.__base)
|
||||||
|
end
|
||||||
|
local _class_0 = setmetatable({
|
||||||
|
__init = function(self, name)
|
||||||
|
self.name = name
|
||||||
|
self[1] = "temp_name"
|
||||||
|
end,
|
||||||
|
__base = _base_0,
|
||||||
|
__name = "LocalName",
|
||||||
|
__parent = _parent_0
|
||||||
|
}, {
|
||||||
|
__index = function(cls, name)
|
||||||
|
local val = rawget(_base_0, name)
|
||||||
|
if val == nil and _parent_0 then
|
||||||
|
return _parent_0[name]
|
||||||
|
else
|
||||||
|
return val
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
__call = function(cls, ...)
|
||||||
|
local _self_0 = setmetatable({}, _base_0)
|
||||||
|
cls.__init(_self_0, ...)
|
||||||
|
return _self_0
|
||||||
|
end
|
||||||
|
})
|
||||||
|
_base_0.__class = _class_0
|
||||||
|
if _parent_0 and _parent_0.__inherited then
|
||||||
|
_parent_0.__inherited(_parent_0, _class_0)
|
||||||
|
end
|
||||||
|
LocalName = _class_0
|
||||||
|
end
|
||||||
|
local NameProxy
|
||||||
|
do
|
||||||
|
local _parent_0 = nil
|
||||||
|
local _base_0 = {
|
||||||
|
get_name = function(self, scope)
|
||||||
|
if not self.name then
|
||||||
|
self.name = scope:free_name(self.prefix, true)
|
||||||
|
end
|
||||||
|
return self.name
|
||||||
|
end,
|
||||||
|
chain = function(self, ...)
|
||||||
|
local items = (function(...)
|
||||||
|
local _accum_0 = { }
|
||||||
|
local _len_0 = 0
|
||||||
|
local _list_0 = {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
for _index_0 = 1, #_list_0 do
|
||||||
|
local i = _list_0[_index_0]
|
||||||
|
local _value_0
|
||||||
|
if type(i) == "string" then
|
||||||
|
_value_0 = {
|
||||||
|
"dot",
|
||||||
|
i
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_value_0 = i
|
||||||
|
end
|
||||||
|
if _value_0 ~= nil then
|
||||||
|
_len_0 = _len_0 + 1
|
||||||
|
_accum_0[_len_0] = _value_0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return _accum_0
|
||||||
|
end)(...)
|
||||||
|
return build.chain({
|
||||||
|
base = self,
|
||||||
|
unpack(items)
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
index = function(self, key)
|
||||||
|
return build.chain({
|
||||||
|
base = self,
|
||||||
|
{
|
||||||
|
"index",
|
||||||
|
key
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
__tostring = function(self)
|
||||||
|
if self.name then
|
||||||
|
return ("name<%s>"):format(self.name)
|
||||||
|
else
|
||||||
|
return ("name<prefix(%s)>"):format(self.prefix)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
_base_0.__index = _base_0
|
||||||
|
if _parent_0 then
|
||||||
|
setmetatable(_base_0, _parent_0.__base)
|
||||||
|
end
|
||||||
|
local _class_0 = setmetatable({
|
||||||
|
__init = function(self, prefix)
|
||||||
|
self.prefix = prefix
|
||||||
|
self[1] = "temp_name"
|
||||||
|
end,
|
||||||
|
__base = _base_0,
|
||||||
|
__name = "NameProxy",
|
||||||
|
__parent = _parent_0
|
||||||
|
}, {
|
||||||
|
__index = function(cls, name)
|
||||||
|
local val = rawget(_base_0, name)
|
||||||
|
if val == nil and _parent_0 then
|
||||||
|
return _parent_0[name]
|
||||||
|
else
|
||||||
|
return val
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
__call = function(cls, ...)
|
||||||
|
local _self_0 = setmetatable({}, _base_0)
|
||||||
|
cls.__init(_self_0, ...)
|
||||||
|
return _self_0
|
||||||
|
end
|
||||||
|
})
|
||||||
|
_base_0.__class = _class_0
|
||||||
|
if _parent_0 and _parent_0.__inherited then
|
||||||
|
_parent_0.__inherited(_parent_0, _class_0)
|
||||||
|
end
|
||||||
|
NameProxy = _class_0
|
||||||
|
end
|
||||||
|
return {
|
||||||
|
NameProxy = NameProxy,
|
||||||
|
LocalName = LocalName
|
||||||
|
}
|
43
moonscript/transform/names.moon
Normal file
43
moonscript/transform/names.moon
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
import build from require "moonscript.types"
|
||||||
|
|
||||||
|
-- always declares as local
|
||||||
|
class LocalName
|
||||||
|
new: (@name) => self[1] = "temp_name"
|
||||||
|
get_name: => @name
|
||||||
|
|
||||||
|
-- creates a unique name when used
|
||||||
|
class NameProxy
|
||||||
|
new: (@prefix) =>
|
||||||
|
self[1] = "temp_name"
|
||||||
|
|
||||||
|
get_name: (scope) =>
|
||||||
|
if not @name
|
||||||
|
@name = scope\free_name @prefix, true
|
||||||
|
@name
|
||||||
|
|
||||||
|
chain: (...) =>
|
||||||
|
items = for i in *{...}
|
||||||
|
if type(i) == "string"
|
||||||
|
{"dot", i}
|
||||||
|
else
|
||||||
|
i
|
||||||
|
|
||||||
|
build.chain {
|
||||||
|
base: self
|
||||||
|
unpack items
|
||||||
|
}
|
||||||
|
|
||||||
|
index: (key) =>
|
||||||
|
build.chain {
|
||||||
|
base: self, {"index", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
__tostring: =>
|
||||||
|
if @name
|
||||||
|
("name<%s>")\format @name
|
||||||
|
else
|
||||||
|
("name<prefix(%s)>")\format @prefix
|
||||||
|
|
||||||
|
|
||||||
|
{ :NameProxy, :LocalName }
|
45
tests/inputs/destructure.moon
Normal file
45
tests/inputs/destructure.moon
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
{a, b} = hello
|
||||||
|
|
||||||
|
{{a}, b, {c}} = hello
|
||||||
|
|
||||||
|
{ :hello, :world } = value
|
||||||
|
|
||||||
|
{ yes: no, thing } = world
|
||||||
|
|
||||||
|
{:a,:b,:c,:d} = yeah
|
||||||
|
|
||||||
|
{a} = one, two
|
||||||
|
{b}, c = one
|
||||||
|
{d}, e = one, two
|
||||||
|
|
||||||
|
x, {y} = one, two
|
||||||
|
|
||||||
|
xx, yy = 1, 2
|
||||||
|
{yy, xx} = {xx, yy}
|
||||||
|
|
||||||
|
{a, :b, c, :d, e, :f, g} = tbl
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
futurists =
|
||||||
|
sculptor: "Umberto Boccioni"
|
||||||
|
painter: "Vladimir Burliuk"
|
||||||
|
poet:
|
||||||
|
name: "F.T. Marinetti"
|
||||||
|
address: {
|
||||||
|
"Via Roma 42R"
|
||||||
|
"Bellagio, Italy 22021"
|
||||||
|
}
|
||||||
|
|
||||||
|
{poet: {:name, address: {street, city}}} = futurists
|
||||||
|
|
||||||
|
print name, street, city
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
{ @world } = x
|
||||||
|
{ a.b, c.y, func!.z } = x
|
||||||
|
|
||||||
|
{ world: @world } = x
|
||||||
|
|
88
tests/outputs/destructure.lua
Normal file
88
tests/outputs/destructure.lua
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
local a, b
|
||||||
|
do
|
||||||
|
local _obj_0 = hello
|
||||||
|
a, b = _obj_0[1], _obj_0[2]
|
||||||
|
end
|
||||||
|
local c
|
||||||
|
do
|
||||||
|
local _obj_0 = hello
|
||||||
|
a, b, c = _obj_0[1][1], _obj_0[2], _obj_0[3][1]
|
||||||
|
end
|
||||||
|
local hello, world
|
||||||
|
do
|
||||||
|
local _obj_0 = value
|
||||||
|
hello, world = _obj_0.hello, _obj_0.world
|
||||||
|
end
|
||||||
|
local no, thing
|
||||||
|
do
|
||||||
|
local _obj_0 = world
|
||||||
|
no, thing = _obj_0.yes, _obj_0[1]
|
||||||
|
end
|
||||||
|
local d
|
||||||
|
do
|
||||||
|
local _obj_0 = yeah
|
||||||
|
a, b, c, d = _obj_0.a, _obj_0.b, _obj_0.c, _obj_0.d
|
||||||
|
end
|
||||||
|
do
|
||||||
|
local _obj_0 = one
|
||||||
|
a = _obj_0[1]
|
||||||
|
end
|
||||||
|
local _ = two
|
||||||
|
do
|
||||||
|
local _obj_0 = one
|
||||||
|
b = _obj_0[1]
|
||||||
|
end
|
||||||
|
c = nil
|
||||||
|
do
|
||||||
|
local _obj_0 = one
|
||||||
|
d = _obj_0[1]
|
||||||
|
end
|
||||||
|
local e = two
|
||||||
|
local x = one
|
||||||
|
local y
|
||||||
|
do
|
||||||
|
local _obj_0 = two
|
||||||
|
y = _obj_0[1]
|
||||||
|
end
|
||||||
|
local xx, yy = 1, 2
|
||||||
|
do
|
||||||
|
local _obj_0 = {
|
||||||
|
xx,
|
||||||
|
yy
|
||||||
|
}
|
||||||
|
yy, xx = _obj_0[1], _obj_0[2]
|
||||||
|
end
|
||||||
|
local f, g
|
||||||
|
do
|
||||||
|
local _obj_0 = tbl
|
||||||
|
a, b, c, d, e, f, g = _obj_0[1], _obj_0.b, _obj_0[2], _obj_0.d, _obj_0[3], _obj_0.f, _obj_0[4]
|
||||||
|
end
|
||||||
|
local futurists = {
|
||||||
|
sculptor = "Umberto Boccioni",
|
||||||
|
painter = "Vladimir Burliuk",
|
||||||
|
poet = {
|
||||||
|
name = "F.T. Marinetti",
|
||||||
|
address = {
|
||||||
|
"Via Roma 42R",
|
||||||
|
"Bellagio, Italy 22021"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
local name, street, city
|
||||||
|
do
|
||||||
|
local _obj_0 = futurists
|
||||||
|
name, street, city = _obj_0.poet.name, _obj_0.poet.address[1], _obj_0.poet.address[2]
|
||||||
|
end
|
||||||
|
print(name, street, city)
|
||||||
|
do
|
||||||
|
local _obj_0 = x
|
||||||
|
self.world = _obj_0[1]
|
||||||
|
end
|
||||||
|
do
|
||||||
|
local _obj_0 = x
|
||||||
|
a.b, c.y, func().z = _obj_0[1], _obj_0[2], _obj_0[3]
|
||||||
|
end
|
||||||
|
do
|
||||||
|
local _obj_0 = x
|
||||||
|
self.world = _obj_0.world
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user