redo varargs bubbling with send, fix some varargs issues

This commit is contained in:
leaf corcoran 2012-10-28 01:50:22 -07:00
parent ec6b22239a
commit 625a2402b0
8 changed files with 44 additions and 37 deletions

View File

@ -154,13 +154,6 @@ Block = (function()
end end
return "Block<" .. tostring(h) .. "> <- " .. tostring(self.parent) return "Block<" .. tostring(h) .. "> <- " .. tostring(self.parent)
end, end,
bubble = function(self, other)
if other == nil then
other = self.parent
end
local has_varargs = self.has_varargs and not self:has_name("...")
other.has_varargs = other.has_varargs or has_varargs
end,
line_table = function(self) line_table = function(self)
return self._posmap return self._posmap
end, end,
@ -173,6 +166,9 @@ Block = (function()
listen = function(self, name, fn) listen = function(self, name, fn)
self._listeners[name] = fn self._listeners[name] = fn
end, end,
unlisten = function(self, name)
self._listeners[name] = nil
end,
send = function(self, name, ...) send = function(self, name, ...)
do do
local fn = self._listeners[name] local fn = self._listeners[name]

View File

@ -112,11 +112,6 @@ class Block
else else
@indent = 0 @indent = 0
-- bubble properties into parent
bubble: (other=@parent) =>
has_varargs = @has_varargs and not @has_name "..."
other.has_varargs = other.has_varargs or has_varargs
line_table: => line_table: =>
@_posmap @_posmap
@ -129,6 +124,9 @@ class Block
listen: (name, fn) => listen: (name, fn) =>
@_listeners[name] = fn @_listeners[name] = fn
unlisten: (name) =>
@_listeners[name] = nil
send: (name, ...) => send: (name, ...) =>
if fn = @_listeners[name] if fn = @_listeners[name]
fn self, ... fn self, ...

View File

@ -298,7 +298,7 @@ value_compile = {
return self:value(sup(self)) return self:value(sup(self))
end end
if value == "..." then if value == "..." then
self.has_varargs = true self:send("varargs")
end end
return tostring(value) return tostring(value)
end end

View File

@ -192,6 +192,6 @@ value_compile =
return @value sup self return @value sup self
if value == "..." if value == "..."
@has_varargs = true @send "varargs"
tostring value tostring value

View File

@ -1453,6 +1453,12 @@ Value = Transformer({
fndef = function(self, node) fndef = function(self, node)
smart_node(node) smart_node(node)
node.body = apply_to_last(node.body, implicitly_return(self)) node.body = apply_to_last(node.body, implicitly_return(self))
node.body = {
Run(function(self)
return self:listen("varargs", function() end)
end),
unpack(node.body)
}
return node return node
end, end,
["if"] = function(self, node) ["if"] = function(self, node)
@ -1549,16 +1555,19 @@ Value = Transformer({
local _, body = unpack(node) local _, body = unpack(node)
local fn = nil local fn = nil
local arg_list = { } 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({ fn = smart_node(build.fndef({
body = body 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({ return build.chain({
base = { base = {

View File

@ -765,6 +765,11 @@ Value = Transformer {
fndef: (node) => fndef: (node) =>
smart_node node smart_node node
node.body = apply_to_last node.body, implicitly_return self node.body = apply_to_last node.body, implicitly_return self
node.body = {
Run => @listen "varargs", -> -- capture event
unpack node.body
}
node node
if: (node) => build.block_exp { node } if: (node) => build.block_exp { node }
@ -823,12 +828,16 @@ Value = Transformer {
fn = nil fn = nil
arg_list = {} arg_list = {}
insert body, Run => fn = smart_node build.fndef body: {
if @has_varargs Run =>
insert arg_list, "..." @listen "varargs", ->
insert fn.args, {"..."} insert arg_list, "..."
insert fn.args, {"..."}
@unlisten "varargs"
unpack body
}
fn = smart_node build.fndef body: body
build.chain { base: {"parens", fn}, {"call", arg_list} } build.chain { base: {"parens", fn}, {"call", arg_list} }
} }

View File

@ -46,7 +46,7 @@ local j = (function()
end)() end)()
local m local m
m = function(...) m = function(...)
return (function() return (function(...)
local _accum_0 = { } local _accum_0 = { }
local _len_0 = 0 local _len_0 = 0
local _list_0 = { local _list_0 = {
@ -60,7 +60,7 @@ m = function(...)
end end
end end
return _accum_0 return _accum_0
end)() end)(...)
end end
local x = (function(...) local x = (function(...)
local _accum_0 = { } local _accum_0 = { }
@ -114,7 +114,7 @@ local a = (function(...)
end end
return _accum_0 return _accum_0
end)(...) end)(...)
local b = (function(...) local b = (function()
local _accum_0 = { } local _accum_0 = { }
local _len_0 = 0 local _len_0 = 0
for i = 1, 10 do for i = 1, 10 do
@ -128,4 +128,4 @@ local b = (function(...)
end end
end end
return _accum_0 return _accum_0
end)(...) end)()

5
todo
View File

@ -43,11 +43,6 @@ x = for x in y
* any/every keywords for comprehensions? (what about iterators) * any/every keywords for comprehensions? (what about iterators)
not working right:
double_args = (...) ->
[x * 2 for x in *{...}]
* let array items in table be defined without {} when indented * let array items in table be defined without {} when indented