mirror of
https://github.com/leafo/moonscript.git
synced 2024-10-05 05:34:19 +00:00
varargs bubbling moved to block_exp
This commit is contained in:
parent
9c8828e8fa
commit
0131786390
@ -18,11 +18,9 @@ do
|
|||||||
end
|
end
|
||||||
local concat, insert = table.concat, table.insert
|
local concat, insert = table.concat, table.insert
|
||||||
local pos_to_line, get_closest_line, trim = util.pos_to_line, util.get_closest_line, util.trim
|
local pos_to_line, get_closest_line, trim = util.pos_to_line, util.get_closest_line, util.trim
|
||||||
local bubble_names = {
|
|
||||||
"has_varargs"
|
|
||||||
}
|
|
||||||
local Line
|
local Line
|
||||||
Line = (function(_parent_0)
|
Line = (function()
|
||||||
|
local _parent_0 = nil
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
_append_single = function(self, item)
|
_append_single = function(self, item)
|
||||||
if util.moon.type(item) == Line then
|
if util.moon.type(item) == Line then
|
||||||
@ -85,17 +83,18 @@ Line = (function(_parent_0)
|
|||||||
end
|
end
|
||||||
}, {
|
}, {
|
||||||
__index = _base_0,
|
__index = _base_0,
|
||||||
__call = function(mt, ...)
|
__call = function(cls, ...)
|
||||||
local self = setmetatable({}, _base_0)
|
local _self_0 = setmetatable({}, _base_0)
|
||||||
mt.__init(self, ...)
|
cls.__init(_self_0, ...)
|
||||||
return self
|
return _self_0
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
_base_0.__class = _class_0
|
_base_0.__class = _class_0
|
||||||
return _class_0
|
return _class_0
|
||||||
end)()
|
end)()
|
||||||
local Block_
|
local Block_
|
||||||
Block_ = (function(_parent_0)
|
Block_ = (function()
|
||||||
|
local _parent_0 = nil
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
header = "do",
|
header = "do",
|
||||||
footer = "end",
|
footer = "end",
|
||||||
@ -251,15 +250,6 @@ Block_ = (function(_parent_0)
|
|||||||
if t == "string" then
|
if t == "string" then
|
||||||
self:add_line_text(line)
|
self:add_line_text(line)
|
||||||
elseif t == Block then
|
elseif t == Block then
|
||||||
do
|
|
||||||
local _item_0 = bubble_names
|
|
||||||
for _index_0 = 1, #_item_0 do
|
|
||||||
local name = _item_0[_index_0]
|
|
||||||
if line[name] then
|
|
||||||
self[name] = line.name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self:add(self:line(line))
|
self:add(self:line(line))
|
||||||
elseif t == Line then
|
elseif t == Line then
|
||||||
self:add_line_tables(line)
|
self:add_line_tables(line)
|
||||||
@ -396,24 +386,30 @@ Block_ = (function(_parent_0)
|
|||||||
if not ret then
|
if not ret then
|
||||||
ret = default_return
|
ret = default_return
|
||||||
end
|
end
|
||||||
local i = 1
|
local last_exp_id = 0
|
||||||
while i < #stms do
|
for i = #stms, 1, -1 do
|
||||||
self:stm(stms[i])
|
local stm = stms[i]
|
||||||
i = i + 1
|
if stm and util.moon.type(stm) ~= transform.Run then
|
||||||
|
last_exp_id = i
|
||||||
|
break
|
||||||
|
end
|
||||||
end
|
end
|
||||||
local last_exp = stms[i]
|
for i, stm in ipairs(stms) do
|
||||||
if last_exp then
|
if i == last_exp_id then
|
||||||
if cascading[ntype(last_exp)] then
|
if cascading[ntype(stm)] then
|
||||||
self:stm(last_exp, ret)
|
self:stm(stm, ret)
|
||||||
elseif self:is_value(last_exp) then
|
elseif self:is_value(stm) then
|
||||||
local line = ret(stms[i])
|
local line = ret(stms[i])
|
||||||
if self:is_stm(line) then
|
if self:is_stm(line) then
|
||||||
self:stm(line)
|
self:stm(line)
|
||||||
|
else
|
||||||
|
error("got a value from implicit return")
|
||||||
|
end
|
||||||
else
|
else
|
||||||
error("got a value from implicit return")
|
self:stm(stm)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:stm(last_exp)
|
self:stm(stm)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
@ -456,17 +452,18 @@ Block_ = (function(_parent_0)
|
|||||||
end
|
end
|
||||||
}, {
|
}, {
|
||||||
__index = _base_0,
|
__index = _base_0,
|
||||||
__call = function(mt, ...)
|
__call = function(cls, ...)
|
||||||
local self = setmetatable({}, _base_0)
|
local _self_0 = setmetatable({}, _base_0)
|
||||||
mt.__init(self, ...)
|
cls.__init(_self_0, ...)
|
||||||
return self
|
return _self_0
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
_base_0.__class = _class_0
|
_base_0.__class = _class_0
|
||||||
return _class_0
|
return _class_0
|
||||||
end)()
|
end)()
|
||||||
local RootBlock
|
local RootBlock
|
||||||
RootBlock = (function(_parent_0)
|
RootBlock = (function()
|
||||||
|
local _parent_0 = Block_
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
render = function(self)
|
render = function(self)
|
||||||
self:_insert_breaks()
|
self:_insert_breaks()
|
||||||
@ -485,15 +482,15 @@ RootBlock = (function(_parent_0)
|
|||||||
end
|
end
|
||||||
}, {
|
}, {
|
||||||
__index = _base_0,
|
__index = _base_0,
|
||||||
__call = function(mt, ...)
|
__call = function(cls, ...)
|
||||||
local self = setmetatable({}, _base_0)
|
local _self_0 = setmetatable({}, _base_0)
|
||||||
mt.__init(self, ...)
|
cls.__init(_self_0, ...)
|
||||||
return self
|
return _self_0
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
_base_0.__class = _class_0
|
_base_0.__class = _class_0
|
||||||
return _class_0
|
return _class_0
|
||||||
end)(Block_)
|
end)()
|
||||||
Block = Block_
|
Block = Block_
|
||||||
format_error = function(msg, pos, file_str)
|
format_error = function(msg, pos, file_str)
|
||||||
local line = pos_to_line(file_str, pos)
|
local line = pos_to_line(file_str, pos)
|
||||||
|
@ -19,8 +19,6 @@ import pos_to_line, get_closest_line, trim from util
|
|||||||
export tree, value, format_error
|
export tree, value, format_error
|
||||||
export Block
|
export Block
|
||||||
|
|
||||||
bubble_names = { "has_varargs" }
|
|
||||||
|
|
||||||
-- buffer for building up a line
|
-- buffer for building up a line
|
||||||
class Line
|
class Line
|
||||||
_append_single: (item) =>
|
_append_single: (item) =>
|
||||||
@ -167,9 +165,6 @@ class Block_
|
|||||||
if t == "string"
|
if t == "string"
|
||||||
@add_line_text line
|
@add_line_text line
|
||||||
elseif t == Block
|
elseif t == Block
|
||||||
for name in *bubble_names
|
|
||||||
self[name] = line.name if line[name]
|
|
||||||
|
|
||||||
@add @line line
|
@add @line line
|
||||||
elseif t == Line
|
elseif t == Line
|
||||||
@add_line_tables line
|
@add_line_tables line
|
||||||
@ -262,26 +257,29 @@ class Block_
|
|||||||
if not ret
|
if not ret
|
||||||
ret = default_return
|
ret = default_return
|
||||||
|
|
||||||
-- wow I really need a for loop
|
-- find last exp for explicit return
|
||||||
i = 1
|
last_exp_id = 0
|
||||||
while i < #stms
|
for i = #stms, 1, -1
|
||||||
@stm stms[i]
|
stm = stms[i]
|
||||||
i = i + 1
|
if stm and util.moon.type(stm) != transform.Run
|
||||||
|
last_exp_id = i
|
||||||
|
break
|
||||||
|
|
||||||
last_exp = stms[i]
|
for i, stm in ipairs stms
|
||||||
|
if i == last_exp_id
|
||||||
if last_exp
|
if cascading[ntype(stm)]
|
||||||
if cascading[ntype(last_exp)]
|
@stm stm, ret
|
||||||
@stm last_exp, ret
|
elseif @is_value stm
|
||||||
elseif @is_value last_exp
|
line = ret stms[i]
|
||||||
line = ret stms[i]
|
if @is_stm line
|
||||||
if @is_stm line
|
@stm line
|
||||||
@stm line
|
else
|
||||||
|
error "got a value from implicit return"
|
||||||
else
|
else
|
||||||
error "got a value from implicit return"
|
-- nothing we can do with a statement except show it
|
||||||
|
@stm stm
|
||||||
else
|
else
|
||||||
-- nothing we can do with a statement except show it
|
@stm stm
|
||||||
@stm last_exp
|
|
||||||
|
|
||||||
nil
|
nil
|
||||||
|
|
||||||
|
@ -201,6 +201,13 @@ value_compile = {
|
|||||||
return error("Unknown chain action: " .. t)
|
return error("Unknown chain action: " .. t)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if ntype(callee) == "self" and node[3] and ntype(node[3]) == "call" then
|
||||||
|
callee[1] = "self_colon"
|
||||||
|
end
|
||||||
|
local callee_value = self:value(callee)
|
||||||
|
if ntype(callee) == "exp" then
|
||||||
|
callee_value = self:line("(", callee_value, ")")
|
||||||
|
end
|
||||||
local actions
|
local actions
|
||||||
do
|
do
|
||||||
local _with_0 = self:line()
|
local _with_0 = self:line()
|
||||||
@ -213,13 +220,6 @@ value_compile = {
|
|||||||
end
|
end
|
||||||
actions = _with_0
|
actions = _with_0
|
||||||
end
|
end
|
||||||
if ntype(callee) == "self" and node[3] and ntype(node[3]) == "call" then
|
|
||||||
callee[1] = "self_colon"
|
|
||||||
end
|
|
||||||
local callee_value = self:name(callee)
|
|
||||||
if ntype(callee) == "exp" then
|
|
||||||
callee_value = self:line("(", callee_value, ")")
|
|
||||||
end
|
|
||||||
return self:line(callee_value, actions)
|
return self:line(callee_value, actions)
|
||||||
end,
|
end,
|
||||||
fndef = function(self, node)
|
fndef = function(self, node)
|
||||||
@ -258,7 +258,7 @@ value_compile = {
|
|||||||
insert(arg_names, 1, "self")
|
insert(arg_names, 1, "self")
|
||||||
end
|
end
|
||||||
do
|
do
|
||||||
local _with_0 = self:block("function(" .. concat(arg_names, ", ") .. ")")
|
local _with_0 = self:block()
|
||||||
if #whitelist > 0 then
|
if #whitelist > 0 then
|
||||||
_with_0:whitelist_names(whitelist)
|
_with_0:whitelist_names(whitelist)
|
||||||
end
|
end
|
||||||
@ -320,6 +320,25 @@ value_compile = {
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
_with_0:ret_stms(block)
|
_with_0:ret_stms(block)
|
||||||
|
if #args > #arg_names then
|
||||||
|
arg_names = (function()
|
||||||
|
local _accum_0 = { }
|
||||||
|
local _len_0 = 0
|
||||||
|
do
|
||||||
|
local _item_0 = args
|
||||||
|
for _index_0 = 1, #_item_0 do
|
||||||
|
local arg = _item_0[_index_0]
|
||||||
|
local _value_0 = arg[1]
|
||||||
|
if _value_0 ~= nil then
|
||||||
|
_len_0 = _len_0 + 1
|
||||||
|
_accum_0[_len_0] = _value_0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return _accum_0
|
||||||
|
end)()
|
||||||
|
end
|
||||||
|
_with_0.header = "function(" .. concat(arg_names, ", ") .. ")"
|
||||||
return _with_0
|
return _with_0
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
@ -105,6 +105,7 @@ value_compile =
|
|||||||
chain_item = (node) ->
|
chain_item = (node) ->
|
||||||
t, arg = unpack node
|
t, arg = unpack node
|
||||||
if t == "call"
|
if t == "call"
|
||||||
|
-- print arg, util.dump arg
|
||||||
"(", @values(arg), ")"
|
"(", @values(arg), ")"
|
||||||
elseif t == "index"
|
elseif t == "index"
|
||||||
"[", @value(arg), "]"
|
"[", @value(arg), "]"
|
||||||
@ -117,15 +118,15 @@ value_compile =
|
|||||||
else
|
else
|
||||||
error "Unknown chain action: "..t
|
error "Unknown chain action: "..t
|
||||||
|
|
||||||
actions = with @line!
|
|
||||||
\append chain_item action for action in *node[3:]
|
|
||||||
|
|
||||||
if ntype(callee) == "self" and node[3] and ntype(node[3]) == "call"
|
if ntype(callee) == "self" and node[3] and ntype(node[3]) == "call"
|
||||||
callee[1] = "self_colon"
|
callee[1] = "self_colon"
|
||||||
|
|
||||||
callee_value = @name callee
|
callee_value = @value callee
|
||||||
callee_value = @line "(", callee_value, ")" if ntype(callee) == "exp"
|
callee_value = @line "(", callee_value, ")" if ntype(callee) == "exp"
|
||||||
|
|
||||||
|
actions = with @line!
|
||||||
|
\append chain_item action for action in *node[3:]
|
||||||
|
|
||||||
@line callee_value, actions
|
@line callee_value, actions
|
||||||
|
|
||||||
fndef: (node) =>
|
fndef: (node) =>
|
||||||
@ -147,7 +148,7 @@ value_compile =
|
|||||||
if arrow == "fat"
|
if arrow == "fat"
|
||||||
insert arg_names, 1, "self"
|
insert arg_names, 1, "self"
|
||||||
|
|
||||||
with @block "function("..concat(arg_names, ", ")..")"
|
with @block!
|
||||||
if #whitelist > 0
|
if #whitelist > 0
|
||||||
\whitelist_names whitelist
|
\whitelist_names whitelist
|
||||||
|
|
||||||
@ -166,6 +167,11 @@ value_compile =
|
|||||||
\stm {"assign", self_args, self_arg_values} if #self_args > 0
|
\stm {"assign", self_args, self_arg_values} if #self_args > 0
|
||||||
|
|
||||||
\ret_stms block
|
\ret_stms block
|
||||||
|
if #args > #arg_names -- will only work for simple adjustments
|
||||||
|
arg_names = for arg in *args
|
||||||
|
arg[1]
|
||||||
|
|
||||||
|
.header = "function("..concat(arg_names, ", ")..")"
|
||||||
|
|
||||||
table: (node) =>
|
table: (node) =>
|
||||||
_, items = unpack node
|
_, items = unpack node
|
||||||
|
@ -73,7 +73,6 @@ NameProxy = (function(_parent_0)
|
|||||||
_base_0.__class = _class_0
|
_base_0.__class = _class_0
|
||||||
return _class_0
|
return _class_0
|
||||||
end)()
|
end)()
|
||||||
local Run
|
|
||||||
Run = (function(_parent_0)
|
Run = (function(_parent_0)
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
call = function(self, state)
|
call = function(self, state)
|
||||||
@ -104,11 +103,18 @@ local constructor_name = "new"
|
|||||||
local transformer
|
local transformer
|
||||||
transformer = function(transformers)
|
transformer = function(transformers)
|
||||||
return function(n)
|
return function(n)
|
||||||
transformer = transformers[ntype(n)]
|
while true do
|
||||||
if transformer then
|
transformer = transformers[ntype(n)]
|
||||||
return transformer(n) or n
|
local res
|
||||||
else
|
if transformer then
|
||||||
return n
|
res = transformer(n) or n
|
||||||
|
else
|
||||||
|
res = n
|
||||||
|
end
|
||||||
|
if res == n then
|
||||||
|
return n
|
||||||
|
end
|
||||||
|
n = res
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -334,7 +340,7 @@ value = transformer({
|
|||||||
table.remove(node, #node)
|
table.remove(node, #node)
|
||||||
local base_name = NameProxy("base")
|
local base_name = NameProxy("base")
|
||||||
local fn_name = NameProxy("fn")
|
local fn_name = NameProxy("fn")
|
||||||
return build.block_exp({
|
return value(build.block_exp({
|
||||||
build.assign({
|
build.assign({
|
||||||
names = {
|
names = {
|
||||||
base_name
|
base_name
|
||||||
@ -376,14 +382,24 @@ value = transformer({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
}))
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
block_exp = function(node)
|
block_exp = function(node)
|
||||||
local _, body = unpack(node)
|
local _, body = unpack(node)
|
||||||
local fn = build.fndef({
|
local fn = nil
|
||||||
|
local arg_list = { }
|
||||||
|
insert(body, Run(function(self)
|
||||||
|
if self.has_varargs then
|
||||||
|
insert(arg_list, "...")
|
||||||
|
return insert(fn.args, {
|
||||||
|
"..."
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end))
|
||||||
|
fn = smart_node(build.fndef({
|
||||||
body = body
|
body = body
|
||||||
})
|
}))
|
||||||
return build.chain({
|
return build.chain({
|
||||||
base = {
|
base = {
|
||||||
"parens",
|
"parens",
|
||||||
@ -391,7 +407,7 @@ value = transformer({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"call",
|
"call",
|
||||||
{ }
|
arg_list
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
@ -8,7 +8,7 @@ data = require "moonscript.data"
|
|||||||
import ntype, build, smart_node from types
|
import ntype, build, smart_node from types
|
||||||
import insert from table
|
import insert from table
|
||||||
|
|
||||||
export stm, value, NameProxy
|
export stm, value, NameProxy, Run
|
||||||
|
|
||||||
class NameProxy
|
class NameProxy
|
||||||
new: (@prefix) =>
|
new: (@prefix) =>
|
||||||
@ -49,11 +49,14 @@ constructor_name = "new"
|
|||||||
|
|
||||||
transformer = (transformers) ->
|
transformer = (transformers) ->
|
||||||
(n) ->
|
(n) ->
|
||||||
transformer = transformers[ntype n]
|
while true
|
||||||
if transformer
|
transformer = transformers[ntype n]
|
||||||
transformer(n) or n
|
res = if transformer
|
||||||
else
|
transformer(n) or n
|
||||||
n
|
else
|
||||||
|
n
|
||||||
|
return n if res == n
|
||||||
|
n = res
|
||||||
|
|
||||||
stm = transformer {
|
stm = transformer {
|
||||||
class: (node using nil) ->
|
class: (node using nil) ->
|
||||||
@ -176,7 +179,7 @@ value = transformer {
|
|||||||
base_name = NameProxy "base"
|
base_name = NameProxy "base"
|
||||||
fn_name = NameProxy "fn"
|
fn_name = NameProxy "fn"
|
||||||
|
|
||||||
build.block_exp {
|
value build.block_exp {
|
||||||
build.assign {
|
build.assign {
|
||||||
names: {base_name}
|
names: {base_name}
|
||||||
values: {node}
|
values: {node}
|
||||||
@ -201,7 +204,16 @@ value = transformer {
|
|||||||
|
|
||||||
block_exp: (node) ->
|
block_exp: (node) ->
|
||||||
_, body = unpack node
|
_, body = unpack node
|
||||||
fn = build.fndef body: body
|
|
||||||
build.chain { base: {"parens", fn}, {"call", {}} }
|
fn = nil
|
||||||
|
arg_list = {}
|
||||||
|
|
||||||
|
insert body, Run =>
|
||||||
|
if @has_varargs
|
||||||
|
insert arg_list, "..."
|
||||||
|
insert fn.args, {"..."}
|
||||||
|
|
||||||
|
fn = smart_node build.fndef body: body
|
||||||
|
build.chain { base: {"parens", fn}, {"call", arg_list} }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,3 +11,6 @@ print fn!
|
|||||||
print x\val!
|
print x\val!
|
||||||
|
|
||||||
|
|
||||||
|
-- ... should be bubbled up anon functions
|
||||||
|
x = hello(...)\world
|
||||||
|
|
||||||
|
@ -12,4 +12,11 @@ local fn = (function()
|
|||||||
end
|
end
|
||||||
end)()
|
end)()
|
||||||
print(fn())
|
print(fn())
|
||||||
print(x:val())
|
print(x:val())
|
||||||
|
x = (function(...)
|
||||||
|
local _base_0 = hello(...)
|
||||||
|
local _fn_0 = _base_0.world
|
||||||
|
return function(...)
|
||||||
|
return _fn_0(_base_0, ...)
|
||||||
|
end
|
||||||
|
end)(...)
|
Loading…
Reference in New Issue
Block a user