self args can be in any function, default value for self args works

This commit is contained in:
leaf corcoran 2011-09-11 23:18:05 -07:00
parent 2c1b3ab00c
commit d0a92fb1db
7 changed files with 99 additions and 96 deletions

View File

@ -435,7 +435,9 @@ line_compile = {
constructor = { constructor = {
"fndef", "fndef",
{ {
"..." {
"..."
}
}, },
{ }, { },
"fat", "fat",
@ -460,52 +462,7 @@ line_compile = {
} }
end end
smart_node(constructor) smart_node(constructor)
local self_args = { }
local get_initializers
get_initializers = function(arg)
if ntype(arg) == "self" then
arg = arg[2]
insert(self_args, arg)
end
return arg
end
constructor.args = (function()
local _accum_0 = { }
local _len_0 = 0
do
local _item_0 = constructor.args
for _index_0 = 1, #_item_0 do
local arg = _item_0[_index_0]
_len_0 = _len_0 + 1
_accum_0[_len_0] = get_initializers(arg)
end
end
return _accum_0
end)()
constructor.arrow = "fat" constructor.arrow = "fat"
local dests = (function()
local _accum_0 = { }
local _len_0 = 0
do
local _item_0 = self_args
for _index_0 = 1, #_item_0 do
local name = _item_0[_index_0]
_len_0 = _len_0 + 1
_accum_0[_len_0] = {
"self",
name
}
end
end
return _accum_0
end)()
if #self_args > 0 then
insert(constructor.body, 1, {
"assign",
dests,
self_args
})
end
local def_scope local def_scope
do do
local _with_0 = self:block() local _with_0 = self:block()
@ -621,8 +578,12 @@ line_compile = {
{ {
"fndef", "fndef",
{ {
"mt", {
"..." "mt"
},
{
"..."
}
}, },
{ }, { },
"slim", "slim",

View File

@ -223,30 +223,15 @@ line_compile =
-- synthesize constructor if needed -- synthesize constructor if needed
if not constructor if not constructor
constructor = {"fndef", {"..."}, {}, "fat", { constructor = {"fndef", {{"..."}}, {}, "fat", {
{"if", parent_loc, { {"if", parent_loc, {
{"chain", "super", {"call", {"..."}}} {"chain", "super", {"call", {"..."}}}
}} }}
}} }}
smart_node constructor smart_node constructor
-- organize constructor arguments
-- extract self arguments
self_args = {}
get_initializers = (arg) ->
if ntype(arg) == "self"
arg = arg[2]
insert self_args, arg
arg
constructor.args = [get_initializers arg for arg in *constructor.args]
constructor.arrow = "fat" constructor.arrow = "fat"
-- insert self assigning arguments
dests = [{"self", name} for name in *self_args]
insert constructor.body, 1, {"assign", dests, self_args} if #self_args > 0
def_scope = with @block! def_scope = with @block!
parent_val = @value parent_val if parent_val != "" parent_val = @value parent_val if parent_val != ""
\put_name parent_loc \put_name parent_loc
@ -281,7 +266,7 @@ line_compile =
-- the class's meta table, gives us call and access to base methods -- the class's meta table, gives us call and access to base methods
cls_mt = {"table", { cls_mt = {"table", {
{"__index", base_name} {"__index", base_name}
{"__call", {"fndef", {"mt", "..."}, {}, "slim", { {"__call", {"fndef", {{"mt"}, {"..."}}, {}, "slim", {
{"raw", ("local self = setmetatable({}, %s)")\format(base_name)} {"raw", ("local self = setmetatable({}, %s)")\format(base_name)}
{"chain", "mt.__init", {"call", {"self", "..."}}} {"chain", "mt.__init", {"call", {"self", "..."}}}
"self" "self"

View File

@ -221,38 +221,45 @@ value_compile = {
fndef = function(self, node) fndef = function(self, node)
local _, args, whitelist, arrow, block = unpack(node) local _, args, whitelist, arrow, block = unpack(node)
local default_args = { } local default_args = { }
local format_names local self_args = { }
format_names = function(arg) local arg_names = (function()
if type(arg) == "string" then
return arg
else
insert(default_args, arg)
return arg[1]
end
end
args = (function()
local _accum_0 = { } local _accum_0 = { }
local _len_0 = 0 local _len_0 = 0
do do
local _item_0 = args local _item_0 = args
for _index_0 = 1, #_item_0 do for _index_0 = 1, #_item_0 do
local arg = _item_0[_index_0] local arg = _item_0[_index_0]
_len_0 = _len_0 + 1 local name, default_value = unpack(arg)
_accum_0[_len_0] = format_names(arg) if type(name) == "string" then
name = name
else
if name[1] == "self" then
insert(self_args, name)
end
name = name[2]
end
if default_value then
insert(default_args, arg)
end
local _value_0 = name
if _value_0 ~= nil then
_len_0 = _len_0 + 1
_accum_0[_len_0] = _value_0
end
end end
end end
return _accum_0 return _accum_0
end)() end)()
if arrow == "fat" then if arrow == "fat" then
insert(args, 1, "self") insert(arg_names, 1, "self")
end end
do do
local _with_0 = self:block("function(" .. concat(args, ", ") .. ")") local _with_0 = self:block("function(" .. concat(arg_names, ", ") .. ")")
if #whitelist > 0 then if #whitelist > 0 then
_with_0:whitelist_names(whitelist) _with_0:whitelist_names(whitelist)
end end
do do
local _item_0 = args local _item_0 = arg_names
for _index_0 = 1, #_item_0 do for _index_0 = 1, #_item_0 do
local name = _item_0[_index_0] local name = _item_0[_index_0]
_with_0:put_name(name) _with_0:put_name(name)
@ -263,6 +270,9 @@ value_compile = {
for _index_0 = 1, #_item_0 do for _index_0 = 1, #_item_0 do
local default = _item_0[_index_0] local default = _item_0[_index_0]
local name, value = unpack(default) local name, value = unpack(default)
if type(name) == "table" then
name = name[2]
end
_with_0:stm({ _with_0:stm({
'if', 'if',
{ {
@ -285,6 +295,26 @@ value_compile = {
}) })
end end
end end
local self_arg_values = (function()
local _accum_0 = { }
local _len_0 = 0
do
local _item_0 = self_args
for _index_0 = 1, #_item_0 do
local arg = _item_0[_index_0]
_len_0 = _len_0 + 1
_accum_0[_len_0] = arg[2]
end
end
return _accum_0
end)()
if #self_args > 0 then
_with_0:stm({
"assign",
self_args,
self_arg_values
})
end
_with_0:ret_stms(block) _with_0:ret_stms(block)
return _with_0 return _with_0
end end

View File

@ -132,32 +132,39 @@ value_compile =
_, args, whitelist, arrow, block = unpack node _, args, whitelist, arrow, block = unpack node
default_args = {} default_args = {}
format_names = (arg) -> self_args = {}
if type(arg) == "string" arg_names = for arg in *args
arg name, default_value = unpack arg
name = if type(name) == "string"
name
else else
insert default_args, arg if name[1] == "self"
arg[1] insert self_args, name
name[2]
args = [format_names arg for arg in *args] insert default_args, arg if default_value
name
if arrow == "fat" if arrow == "fat"
insert args, 1, "self" insert arg_names, 1, "self"
with @block "function("..concat(args, ", ")..")" with @block "function("..concat(arg_names, ", ")..")"
if #whitelist > 0 if #whitelist > 0
\whitelist_names whitelist \whitelist_names whitelist
\put_name name for name in *args \put_name name for name in *arg_names
for default in *default_args for default in *default_args
name, value = unpack default name, value = unpack default
name = name[2] if type(name) == "table"
\stm { \stm {
'if', {'exp', name, '==', 'nil'}, { 'if', {'exp', name, '==', 'nil'}, {
{'assign', {name}, {value}} {'assign', {name}, {value}}
} }
} }
self_arg_values = [arg[2] for arg in *self_args]
\stm {"assign", self_args, self_arg_values} if #self_args > 0
\ret_stms block \ret_stms block
table: (node) => table: (node) =>

View File

@ -242,11 +242,6 @@ local build_grammar = wrap(function()
return stm return stm
end end
local function wrap_default_arg(name, default)
if not default then return name end
return {name, default}
end
local function check_lua_string(str, pos, right, left) local function check_lua_string(str, pos, right, left)
return #left == #right return #left == #right
end end
@ -416,7 +411,7 @@ local build_grammar = wrap(function()
sym")" + Ct"" * Ct"", sym")" + Ct"" * Ct"",
FnArgDefList = FnArgDef * (sym"," * FnArgDef)^0, FnArgDefList = FnArgDef * (sym"," * FnArgDef)^0,
FnArgDef = Name * (sym"=" * Exp)^-1 / wrap_default_arg, FnArgDef = Ct(Name * (sym"=" * Exp)^-1),
FunLit = FnArgsDef * FunLit = FnArgsDef *
(sym"->" * Cc"slim" + sym"=>" * Cc"fat") * (sym"->" * Cc"slim" + sym"=>" * Cc"fat") *

View File

@ -45,3 +45,10 @@ what! the! heck!
something = (hello=100, world=(x=[[yeah cool]])-> print "eat rice") -> something = (hello=100, world=(x=[[yeah cool]])-> print "eat rice") ->
print hello print hello
(x, y) =>
(@x, @y) =>
(x=1) =>
(@x=1,y,@z="hello world") =>

View File

@ -75,4 +75,22 @@ something = function(hello, world)
end end
end end
return print(hello) return print(hello)
end
_ = function(self, x, y) end
_ = function(self, x, y)
self.x, self.y = x, y
end
_ = function(self, x)
if x == nil then
x = 1
end
end
_ = function(self, x, y, z)
if x == nil then
x = 1
end
if z == nil then
z = "hello world"
end
self.x, self.z = x, z
end end