varargs bubbling moved to block_exp

This commit is contained in:
leaf corcoran 2011-10-09 15:58:39 -07:00
parent 9c8828e8fa
commit 0131786390
8 changed files with 156 additions and 98 deletions

View File

@ -18,11 +18,9 @@ do
end
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 bubble_names = {
"has_varargs"
}
local Line
Line = (function(_parent_0)
Line = (function()
local _parent_0 = nil
local _base_0 = {
_append_single = function(self, item)
if util.moon.type(item) == Line then
@ -85,17 +83,18 @@ Line = (function(_parent_0)
end
}, {
__index = _base_0,
__call = function(mt, ...)
local self = setmetatable({}, _base_0)
mt.__init(self, ...)
return self
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
return _self_0
end
})
_base_0.__class = _class_0
return _class_0
end)()
local Block_
Block_ = (function(_parent_0)
Block_ = (function()
local _parent_0 = nil
local _base_0 = {
header = "do",
footer = "end",
@ -251,15 +250,6 @@ Block_ = (function(_parent_0)
if t == "string" then
self:add_line_text(line)
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))
elseif t == Line then
self:add_line_tables(line)
@ -396,24 +386,30 @@ Block_ = (function(_parent_0)
if not ret then
ret = default_return
end
local i = 1
while i < #stms do
self:stm(stms[i])
i = i + 1
local last_exp_id = 0
for i = #stms, 1, -1 do
local stm = stms[i]
if stm and util.moon.type(stm) ~= transform.Run then
last_exp_id = i
break
end
end
local last_exp = stms[i]
if last_exp then
if cascading[ntype(last_exp)] then
self:stm(last_exp, ret)
elseif self:is_value(last_exp) then
local line = ret(stms[i])
if self:is_stm(line) then
self:stm(line)
for i, stm in ipairs(stms) do
if i == last_exp_id then
if cascading[ntype(stm)] then
self:stm(stm, ret)
elseif self:is_value(stm) then
local line = ret(stms[i])
if self:is_stm(line) then
self:stm(line)
else
error("got a value from implicit return")
end
else
error("got a value from implicit return")
self:stm(stm)
end
else
self:stm(last_exp)
self:stm(stm)
end
end
return nil
@ -456,17 +452,18 @@ Block_ = (function(_parent_0)
end
}, {
__index = _base_0,
__call = function(mt, ...)
local self = setmetatable({}, _base_0)
mt.__init(self, ...)
return self
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
return _self_0
end
})
_base_0.__class = _class_0
return _class_0
end)()
local RootBlock
RootBlock = (function(_parent_0)
RootBlock = (function()
local _parent_0 = Block_
local _base_0 = {
render = function(self)
self:_insert_breaks()
@ -485,15 +482,15 @@ RootBlock = (function(_parent_0)
end
}, {
__index = _base_0,
__call = function(mt, ...)
local self = setmetatable({}, _base_0)
mt.__init(self, ...)
return self
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
return _self_0
end
})
_base_0.__class = _class_0
return _class_0
end)(Block_)
end)()
Block = Block_
format_error = function(msg, pos, file_str)
local line = pos_to_line(file_str, pos)

View File

@ -19,8 +19,6 @@ import pos_to_line, get_closest_line, trim from util
export tree, value, format_error
export Block
bubble_names = { "has_varargs" }
-- buffer for building up a line
class Line
_append_single: (item) =>
@ -167,9 +165,6 @@ class Block_
if t == "string"
@add_line_text line
elseif t == Block
for name in *bubble_names
self[name] = line.name if line[name]
@add @line line
elseif t == Line
@add_line_tables line
@ -262,26 +257,29 @@ class Block_
if not ret
ret = default_return
-- wow I really need a for loop
i = 1
while i < #stms
@stm stms[i]
i = i + 1
-- find last exp for explicit return
last_exp_id = 0
for i = #stms, 1, -1
stm = stms[i]
if stm and util.moon.type(stm) != transform.Run
last_exp_id = i
break
last_exp = stms[i]
if last_exp
if cascading[ntype(last_exp)]
@stm last_exp, ret
elseif @is_value last_exp
line = ret stms[i]
if @is_stm line
@stm line
for i, stm in ipairs stms
if i == last_exp_id
if cascading[ntype(stm)]
@stm stm, ret
elseif @is_value stm
line = ret stms[i]
if @is_stm line
@stm line
else
error "got a value from implicit return"
else
error "got a value from implicit return"
-- nothing we can do with a statement except show it
@stm stm
else
-- nothing we can do with a statement except show it
@stm last_exp
@stm stm
nil

View File

@ -201,6 +201,13 @@ value_compile = {
return error("Unknown chain action: " .. t)
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
do
local _with_0 = self:line()
@ -213,13 +220,6 @@ value_compile = {
end
actions = _with_0
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)
end,
fndef = function(self, node)
@ -258,7 +258,7 @@ value_compile = {
insert(arg_names, 1, "self")
end
do
local _with_0 = self:block("function(" .. concat(arg_names, ", ") .. ")")
local _with_0 = self:block()
if #whitelist > 0 then
_with_0:whitelist_names(whitelist)
end
@ -320,6 +320,25 @@ value_compile = {
})
end
_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
end
end,

View File

@ -105,6 +105,7 @@ value_compile =
chain_item = (node) ->
t, arg = unpack node
if t == "call"
-- print arg, util.dump arg
"(", @values(arg), ")"
elseif t == "index"
"[", @value(arg), "]"
@ -117,15 +118,15 @@ value_compile =
else
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"
callee[1] = "self_colon"
callee_value = @name callee
callee_value = @value callee
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
fndef: (node) =>
@ -147,7 +148,7 @@ value_compile =
if arrow == "fat"
insert arg_names, 1, "self"
with @block "function("..concat(arg_names, ", ")..")"
with @block!
if #whitelist > 0
\whitelist_names whitelist
@ -166,6 +167,11 @@ value_compile =
\stm {"assign", self_args, self_arg_values} if #self_args > 0
\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) =>
_, items = unpack node

View File

@ -73,7 +73,6 @@ NameProxy = (function(_parent_0)
_base_0.__class = _class_0
return _class_0
end)()
local Run
Run = (function(_parent_0)
local _base_0 = {
call = function(self, state)
@ -104,11 +103,18 @@ local constructor_name = "new"
local transformer
transformer = function(transformers)
return function(n)
transformer = transformers[ntype(n)]
if transformer then
return transformer(n) or n
else
return n
while true do
transformer = transformers[ntype(n)]
local res
if transformer then
res = transformer(n) or n
else
res = n
end
if res == n then
return n
end
n = res
end
end
end
@ -334,7 +340,7 @@ value = transformer({
table.remove(node, #node)
local base_name = NameProxy("base")
local fn_name = NameProxy("fn")
return build.block_exp({
return value(build.block_exp({
build.assign({
names = {
base_name
@ -376,14 +382,24 @@ value = transformer({
})
}
})
})
}))
end
end,
block_exp = function(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
})
}))
return build.chain({
base = {
"parens",
@ -391,7 +407,7 @@ value = transformer({
},
{
"call",
{ }
arg_list
}
})
end

View File

@ -8,7 +8,7 @@ data = require "moonscript.data"
import ntype, build, smart_node from types
import insert from table
export stm, value, NameProxy
export stm, value, NameProxy, Run
class NameProxy
new: (@prefix) =>
@ -49,11 +49,14 @@ constructor_name = "new"
transformer = (transformers) ->
(n) ->
transformer = transformers[ntype n]
if transformer
transformer(n) or n
else
n
while true
transformer = transformers[ntype n]
res = if transformer
transformer(n) or n
else
n
return n if res == n
n = res
stm = transformer {
class: (node using nil) ->
@ -176,7 +179,7 @@ value = transformer {
base_name = NameProxy "base"
fn_name = NameProxy "fn"
build.block_exp {
value build.block_exp {
build.assign {
names: {base_name}
values: {node}
@ -201,7 +204,16 @@ value = transformer {
block_exp: (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} }
}

View File

@ -11,3 +11,6 @@ print fn!
print x\val!
-- ... should be bubbled up anon functions
x = hello(...)\world

View File

@ -12,4 +12,11 @@ local fn = (function()
end
end)()
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)(...)