Aegisub/automation/include/moonscript.lua

6266 lines
165 KiB
Lua
Raw Permalink Normal View History

package.preload['moonscript.transform.comprehension'] = function()
local is_value
is_value = require("moonscript.types").is_value
local construct_comprehension
construct_comprehension = function(inner, clauses)
local current_stms = inner
for i = #clauses, 1, -1 do
local clause = clauses[i]
local t = clause[1]
local _exp_0 = t
if "for" == _exp_0 then
local _, name, bounds
_, name, bounds = clause[1], clause[2], clause[3]
current_stms = {
"for",
name,
bounds,
current_stms
}
elseif "foreach" == _exp_0 then
local _, names, iter
_, names, iter = clause[1], clause[2], clause[3]
current_stms = {
"foreach",
names,
{
iter
},
current_stms
}
elseif "when" == _exp_0 then
local _, cond
_, cond = clause[1], clause[2]
current_stms = {
"if",
cond,
current_stms
}
else
current_stms = error("Unknown comprehension clause: " .. t)
2014-03-07 04:19:12 +01:00
end
current_stms = {
current_stms
}
2014-03-07 04:19:12 +01:00
end
return current_stms[1]
2014-03-07 04:19:12 +01:00
end
local comprehension_has_value
comprehension_has_value = function(comp)
return is_value(comp[2])
2014-03-07 04:19:12 +01:00
end
return {
construct_comprehension = construct_comprehension,
comprehension_has_value = comprehension_has_value
2014-03-07 04:19:12 +01:00
}
end
package.preload['moonscript.transform.value'] = function()
local Transformer
Transformer = require("moonscript.transform.transformer").Transformer
local build, ntype, smart_node
do
local _obj_0 = require("moonscript.types")
build, ntype, smart_node = _obj_0.build, _obj_0.ntype, _obj_0.smart_node
2014-03-07 04:19:12 +01:00
end
local NameProxy
NameProxy = require("moonscript.transform.names").NameProxy
local Accumulator, default_accumulator
do
local _obj_0 = require("moonscript.transform.accumulator")
Accumulator, default_accumulator = _obj_0.Accumulator, _obj_0.default_accumulator
end
local lua_keywords
lua_keywords = require("moonscript.data").lua_keywords
local Run, transform_last_stm, implicitly_return, chain_is_stub
do
local _obj_0 = require("moonscript.transform.statements")
Run, transform_last_stm, implicitly_return, chain_is_stub = _obj_0.Run, _obj_0.transform_last_stm, _obj_0.implicitly_return, _obj_0.chain_is_stub
end
local construct_comprehension
construct_comprehension = require("moonscript.transform.comprehension").construct_comprehension
local insert
insert = table.insert
local unpack
unpack = require("moonscript.util").unpack
return Transformer({
["for"] = default_accumulator,
["while"] = default_accumulator,
foreach = default_accumulator,
["do"] = function(self, node)
return build.block_exp(node[2])
end,
decorated = function(self, node)
return self.transform.statement(node)
end,
class = function(self, node)
return build.block_exp({
node
})
end,
string = function(self, node)
local delim = node[2]
local convert_part
convert_part = function(part)
if type(part) == "string" or part == nil then
return {
"string",
delim,
part or ""
}
else
return build.chain({
base = "tostring",
{
"call",
{
part[2]
}
}
2014-03-07 04:19:12 +01:00
})
end
end
if #node <= 3 then
if type(node[3]) == "string" then
return node
else
return convert_part(node[3])
2014-03-07 04:19:12 +01:00
end
end
local e = {
"exp",
convert_part(node[3])
}
for i = 4, #node do
insert(e, "..")
insert(e, convert_part(node[i]))
2014-03-07 04:19:12 +01:00
end
return e
end,
comprehension = function(self, node)
local a = Accumulator()
node = self.transform.statement(node, function(exp)
return a:mutate_body({
exp
})
end)
return a:wrap(node)
end,
tblcomprehension = function(self, node)
local explist, clauses = unpack(node, 2)
local key_exp, value_exp = unpack(explist)
local accum = NameProxy("tbl")
local inner
if value_exp then
local dest = build.chain({
base = accum,
{
"index",
key_exp
}
})
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),
accum
})
end,
fndef = function(self, node)
smart_node(node)
node.body = transform_last_stm(node.body, implicitly_return(self))
node.body = {
Run(function(self)
return self:listen("varargs", function() end)
end),
unpack(node.body)
}
return node
end,
["if"] = function(self, node)
return build.block_exp({
node
})
end,
unless = function(self, node)
return build.block_exp({
node
})
end,
with = function(self, node)
return build.block_exp({
node
})
end,
switch = function(self, node)
return build.block_exp({
node
})
end,
chain = function(self, node)
for i = 2, #node do
local part = node[i]
if ntype(part) == "dot" and lua_keywords[part[2]] then
node[i] = {
"index",
{
"string",
'"',
part[2]
}
}
2014-03-07 04:19:12 +01:00
end
end
if ntype(node[2]) == "string" then
node[2] = {
"parens",
node[2]
}
2014-03-07 04:19:12 +01:00
end
if chain_is_stub(node) then
local base_name = NameProxy("base")
local fn_name = NameProxy("fn")
local colon = table.remove(node)
local is_super = ntype(node[2]) == "ref" and node[2][2] == "super"
return build.block_exp({
build.assign({
names = {
base_name
},
values = {
node
}
}),
build.assign({
names = {
fn_name
},
values = {
build.chain({
base = base_name,
{
"dot",
colon[2]
}
})
}
}),
build.fndef({
args = {
{
"..."
}
},
body = {
build.chain({
base = fn_name,
{
"call",
{
is_super and "self" or base_name,
"..."
}
}
})
}
})
})
end
end,
block_exp = function(self, node)
local body = unpack(node, 2)
local fn = nil
local arg_list = { }
fn = smart_node(build.fndef({
body = {
Run(function(self)
return self:listen("varargs", function()
insert(arg_list, "...")
insert(fn.args, {
"..."
})
return self:unlisten("varargs")
end)
end),
unpack(body)
}
}))
return build.chain({
base = {
"parens",
fn
},
{
"call",
arg_list
}
})
end
})
2014-03-07 04:19:12 +01:00
end
package.preload['moonscript.transform.class'] = function()
local NameProxy, LocalName
do
local _obj_0 = require("moonscript.transform.names")
NameProxy, LocalName = _obj_0.NameProxy, _obj_0.LocalName
end
local Run
Run = require("moonscript.transform.statements").Run
local CONSTRUCTOR_NAME = "new"
2014-03-07 04:19:12 +01:00
local insert
2015-02-03 18:54:34 +01:00
insert = table.insert
local build, ntype, NOOP
2014-03-07 04:19:12 +01:00
do
local _obj_0 = require("moonscript.types")
build, ntype, NOOP = _obj_0.build, _obj_0.ntype, _obj_0.NOOP
end
local unpack
unpack = require("moonscript.util").unpack
local transform_super
transform_super = function(cls_name, on_base, block, chain)
if on_base == nil then
on_base = true
end
local relative_parent = {
"chain",
cls_name,
{
"dot",
"__parent"
}
2014-03-07 04:19:12 +01:00
}
if not (chain) then
return relative_parent
end
local chain_tail = {
unpack(chain, 3)
}
local head = chain_tail[1]
if head == nil then
return relative_parent
end
local new_chain = relative_parent
local _exp_0 = head[1]
if "call" == _exp_0 then
if on_base then
insert(new_chain, {
"dot",
"__base"
2014-03-07 04:19:12 +01:00
})
end
local calling_name = block:get("current_method")
assert(calling_name, "missing calling name")
chain_tail[1] = {
"call",
{
"self",
unpack(head[2])
}
}
if ntype(calling_name) == "key_literal" then
insert(new_chain, {
"dot",
calling_name[2]
})
else
insert(new_chain, {
"index",
calling_name
2015-02-03 18:54:34 +01:00
})
2014-03-07 04:19:12 +01:00
end
elseif "colon" == _exp_0 then
local call = chain_tail[2]
if call and call[1] == "call" then
chain_tail[1] = {
"dot",
head[2]
}
chain_tail[2] = {
"call",
{
"self",
unpack(call[2])
}
}
end
2014-03-07 04:19:12 +01:00
end
for _index_0 = 1, #chain_tail do
local item = chain_tail[_index_0]
insert(new_chain, item)
2014-03-07 04:19:12 +01:00
end
return new_chain
end
local super_scope
super_scope = function(value, t, key)
local prev_method
return {
"scoped",
Run(function(self)
prev_method = self:get("current_method")
self:set("current_method", key)
return self:set("super", t)
end),
value,
Run(function(self)
return self:set("current_method", prev_method)
end)
}
end
return function(self, node, ret, parent_assign)
local name, parent_val, body = unpack(node, 2)
if parent_val == "" then
parent_val = nil
end
local parent_cls_name = NameProxy("parent")
local base_name = NameProxy("base")
local self_name = NameProxy("self")
local cls_name = NameProxy("class")
local cls_instance_super
cls_instance_super = function(...)
return transform_super(cls_name, true, ...)
end
local cls_super
cls_super = function(...)
return transform_super(cls_name, false, ...)
end
local statements = { }
local properties = { }
for _index_0 = 1, #body do
local item = body[_index_0]
local _exp_0 = item[1]
if "stm" == _exp_0 then
insert(statements, item[2])
elseif "props" == _exp_0 then
for _index_1 = 2, #item do
local tuple = item[_index_1]
if ntype(tuple[1]) == "self" then
local k, v
k, v = tuple[1], tuple[2]
v = super_scope(v, cls_super, {
"key_literal",
k[2]
})
insert(statements, build.assign_one(k, v))
else
insert(properties, tuple)
end
end
end
2014-03-07 04:19:12 +01:00
end
local constructor
2014-03-07 04:19:12 +01:00
do
local _accum_0 = { }
local _len_0 = 1
for _index_0 = 1, #properties do
local _continue_0 = false
repeat
local tuple = properties[_index_0]
local key = tuple[1]
local _value_0
if key[1] == "key_literal" and key[2] == CONSTRUCTOR_NAME then
constructor = tuple[2]
_continue_0 = true
break
else
local val
key, val = tuple[1], tuple[2]
_value_0 = {
key,
super_scope(val, cls_instance_super, key)
}
end
_accum_0[_len_0] = _value_0
_len_0 = _len_0 + 1
_continue_0 = true
until true
if not _continue_0 then
break
2014-03-07 04:19:12 +01:00
end
end
properties = _accum_0
2014-03-07 04:19:12 +01:00
end
if not (constructor) then
if parent_val then
constructor = build.fndef({
args = {
{
"..."
}
},
arrow = "fat",
body = {
build.chain({
base = "super",
{
"call",
{
"..."
}
}
})
}
})
else
constructor = build.fndef()
2014-03-07 04:19:12 +01:00
end
end
local real_name = name or parent_assign and parent_assign[2][1]
local _exp_0 = ntype(real_name)
if "chain" == _exp_0 then
local last = real_name[#real_name]
local _exp_1 = ntype(last)
if "dot" == _exp_1 then
real_name = {
"string",
'"',
last[2]
}
elseif "index" == _exp_1 then
real_name = last[2]
else
real_name = "nil"
2014-03-07 04:19:12 +01:00
end
elseif "nil" == _exp_0 then
real_name = "nil"
else
local name_t = type(real_name)
local flattened_name
if name_t == "string" then
flattened_name = real_name
elseif name_t == "table" and real_name[1] == "ref" then
flattened_name = real_name[2]
else
flattened_name = error("don't know how to extract name from " .. tostring(name_t))
2014-03-07 04:19:12 +01:00
end
real_name = {
"string",
'"',
flattened_name
}
2014-03-07 04:19:12 +01:00
end
local cls = build.table({
{
"__init",
super_scope(constructor, cls_super, {
"key_literal",
"__init"
})
},
{
"__base",
base_name
},
{
"__name",
real_name
},
parent_val and {
"__parent",
parent_cls_name
} or nil
})
local class_index
if parent_val then
local class_lookup = build["if"]({
cond = {
"exp",
{
"ref",
"val"
},
"==",
"nil"
},
["then"] = {
build.assign_one(LocalName("parent"), build.chain({
base = "rawget",
{
"call",
{
{
"ref",
"cls"
},
{
"string",
'"',
"__parent"
}
}
}
})),
build["if"]({
cond = LocalName("parent"),
["then"] = {
build.chain({
base = LocalName("parent"),
{
"index",
"name"
}
})
}
})
}
})
insert(class_lookup, {
"else",
{
"val"
}
})
class_index = build.fndef({
args = {
{
"cls"
},
{
"name"
}
},
body = {
build.assign_one(LocalName("val"), build.chain({
base = "rawget",
{
"call",
{
base_name,
{
"ref",
"name"
}
}
}
})),
class_lookup
}
})
else
class_index = base_name
2014-03-07 04:19:12 +01:00
end
local cls_mt = build.table({
{
"__index",
class_index
},
{
"__call",
build.fndef({
args = {
{
"cls"
},
{
"..."
}
},
body = {
build.assign_one(self_name, build.chain({
base = "setmetatable",
{
"call",
{
"{}",
base_name
}
}
})),
build.chain({
base = "cls.__init",
{
"call",
{
self_name,
"..."
}
}
}),
self_name
}
})
}
})
cls = build.chain({
base = "setmetatable",
{
"call",
{
cls,
cls_mt
}
}
})
local value = nil
do
local out_body = {
Run(function(self)
if name then
return self:put_name(name)
end
end),
{
"declare",
{
cls_name
}
},
{
"declare_glob",
"*"
},
parent_val and build.assign_one(parent_cls_name, parent_val) or NOOP,
build.assign_one(base_name, {
"table",
properties
}),
build.assign_one(base_name:chain("__index"), base_name),
parent_val and build.chain({
base = "setmetatable",
{
"call",
{
base_name,
build.chain({
base = parent_cls_name,
{
"dot",
"__base"
}
})
}
}
}) or NOOP,
build.assign_one(cls_name, cls),
build.assign_one(base_name:chain("__class"), cls_name),
build.group((function()
if #statements > 0 then
return {
build.assign_one(LocalName("self"), cls_name),
build.group(statements)
}
end
end)()),
parent_val and build["if"]({
cond = {
"exp",
parent_cls_name:chain("__inherited")
},
["then"] = {
parent_cls_name:chain("__inherited", {
"call",
{
parent_cls_name,
cls_name
}
})
}
}) or NOOP,
build.group((function()
if name then
return {
build.assign_one(name, cls_name)
}
end
end)()),
(function()
if ret then
return ret(cls_name)
end
end)()
}
value = build.group({
build.group((function()
if ntype(name) == "value" then
return {
build.declare({
names = {
name
}
})
}
end
end)()),
build["do"](out_body)
})
2014-03-07 04:19:12 +01:00
end
return value
2014-03-07 04:19:12 +01:00
end
2013-04-30 15:16:59 +02:00
2015-02-03 18:54:34 +01:00
end
package.preload['moonscript.transform.statements'] = function()
local types = require("moonscript.types")
local ntype, mtype, is_value, NOOP
ntype, mtype, is_value, NOOP = types.ntype, types.mtype, types.is_value, types.NOOP
local comprehension_has_value
comprehension_has_value = require("moonscript.transform.comprehension").comprehension_has_value
local Run
do
local _class_0
local _base_0 = {
call = function(self, state)
return self.fn(state)
end
}
_base_0.__index = _base_0
_class_0 = setmetatable({
__init = function(self, fn)
self.fn = fn
self[1] = "run"
end,
__base = _base_0,
__name = "Run"
}, {
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
return _self_0
end
})
_base_0.__class = _class_0
Run = _class_0
2015-02-03 18:54:34 +01:00
end
local last_stm
last_stm = function(stms)
local last_exp_id = 0
for i = #stms, 1, -1 do
local stm = stms[i]
if stm and mtype(stm) ~= Run then
if ntype(stm) == "group" then
return last_stm(stm[2])
end
last_exp_id = i
break
end
2015-02-03 18:54:34 +01:00
end
return stms[last_exp_id], last_exp_id, stms
2015-02-03 18:54:34 +01:00
end
local transform_last_stm
transform_last_stm = function(stms, fn)
local _, last_idx, _stms = last_stm(stms)
if _stms ~= stms then
error("cannot transform last node in group")
2015-02-03 18:54:34 +01:00
end
return (function()
local _accum_0 = { }
local _len_0 = 1
for i, stm in ipairs(stms) do
if i == last_idx then
_accum_0[_len_0] = {
"transform",
stm,
fn
}
else
_accum_0[_len_0] = stm
2015-02-03 18:54:34 +01:00
end
_len_0 = _len_0 + 1
2015-02-03 18:54:34 +01:00
end
return _accum_0
end)()
2015-02-03 18:54:34 +01:00
end
local chain_is_stub
chain_is_stub = function(chain)
local stub = chain[#chain]
return stub and ntype(stub) == "colon"
2015-02-03 18:54:34 +01:00
end
local implicitly_return
implicitly_return = function(scope)
local is_top = true
local fn
fn = function(stm)
local t = ntype(stm)
if t == "decorated" then
stm = scope.transform.statement(stm)
t = ntype(stm)
2015-02-03 18:54:34 +01:00
end
if types.cascading[t] then
is_top = false
return scope.transform.statement(stm, fn)
elseif types.manual_return[t] or not is_value(stm) then
if is_top and t == "return" and stm[2] == "" then
return NOOP
else
return stm
end
else
if t == "comprehension" and not comprehension_has_value(stm) then
return stm
else
return {
"return",
stm
}
end
2015-02-03 18:54:34 +01:00
end
end
return fn
2015-02-03 18:54:34 +01:00
end
return {
Run = Run,
last_stm = last_stm,
transform_last_stm = transform_last_stm,
chain_is_stub = chain_is_stub,
implicitly_return = implicitly_return
2015-02-03 18:54:34 +01:00
}
2013-04-30 15:16:59 +02:00
end
package.preload['moonscript.transform.destructure'] = function()
local ntype, mtype, build
2013-07-04 01:11:42 +02:00
do
local _obj_0 = require("moonscript.types")
ntype, mtype, build = _obj_0.ntype, _obj_0.mtype, _obj_0.build
2013-04-30 15:16:59 +02:00
end
local NameProxy
NameProxy = require("moonscript.transform.names").NameProxy
local insert
insert = table.insert
local unpack
unpack = require("moonscript.util").unpack
local user_error
user_error = require("moonscript.errors").user_error
local join
join = function(...)
do
local out = { }
local i = 1
local _list_0 = {
...
}
2013-04-30 15:16:59 +02:00
for _index_0 = 1, #_list_0 do
local tbl = _list_0[_index_0]
for _index_1 = 1, #tbl do
local v = tbl[_index_1]
out[i] = v
i = i + 1
end
2013-04-30 15:16:59 +02:00
end
return out
end
end
local has_destructure
has_destructure = function(names)
for _index_0 = 1, #names do
local n = names[_index_0]
if ntype(n) == "table" then
return true
end
end
return false
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
local key_name = key[2]
if ntype(key_name) == "colon" then
s = key_name
else
s = {
"dot",
key_name
}
end
else
s = {
"index",
key
}
2013-04-30 15:16:59 +02:00
end
value, suffix = tuple[2], s
2013-04-30 15:16:59 +02:00
end
suffix = join(prefix, {
suffix
})
local _exp_0 = ntype(value)
if "value" == _exp_0 or "ref" == _exp_0 or "chain" == _exp_0 or "self" == _exp_0 then
insert(accum, {
value,
suffix
})
elseif "table" == _exp_0 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 build_assign
build_assign = function(scope, destruct_literal, receiver)
local extracted_names = extract_assign_names(destruct_literal)
local names = { }
local values = { }
local inner = {
"assign",
names,
values
}
local obj
if scope:is_local(receiver) or #extracted_names == 1 then
obj = receiver
else
2013-04-30 15:16:59 +02:00
do
obj = NameProxy("obj")
inner = build["do"]({
build.assign_one(obj, receiver),
{
"assign",
names,
values
}
})