mirror of
https://github.com/leafo/moonscript.git
synced 2024-11-22 02:44:23 +00:00
new class system
This commit is contained in:
parent
858608a04d
commit
65fdf7e6b2
@ -210,21 +210,12 @@ line_compile = {
|
||||
end,
|
||||
["class"] = function(self, node)
|
||||
local _, name, tbl = unpack(node)
|
||||
local mt_name = "_" .. name .. "_mt"
|
||||
self:add_line("local", concat(self:declare({ name, mt_name }), ", "))
|
||||
local constructor = nil
|
||||
local meta_methods = { }
|
||||
local final_properties = { }
|
||||
local overloaded_index = value
|
||||
local find_special
|
||||
find_special = function(name, value)
|
||||
if name == constructor_name then
|
||||
constructor = value
|
||||
elseif name:match("^__%a") then
|
||||
insert(meta_methods, { name, value })
|
||||
if name == "__index" then
|
||||
overloaded_index = value
|
||||
end
|
||||
else
|
||||
return insert(final_properties, { name, value })
|
||||
end
|
||||
@ -234,15 +225,12 @@ line_compile = {
|
||||
local entry = _item_0[_index_0]
|
||||
find_special(unpack(entry))
|
||||
end
|
||||
if not overloaded_index then
|
||||
insert(meta_methods, { "__index", { "table", final_properties } })
|
||||
end
|
||||
self:stm({ "assign", { mt_name }, { { "table", meta_methods } } })
|
||||
tbl[2] = final_properties
|
||||
if not constructor then
|
||||
constructor = {
|
||||
"fndef",
|
||||
{ },
|
||||
"slim",
|
||||
"fat",
|
||||
{ }
|
||||
}
|
||||
end
|
||||
@ -264,7 +252,7 @@ line_compile = {
|
||||
end
|
||||
return _moon_0
|
||||
end)()
|
||||
constructor[3] = "slim"
|
||||
constructor[3] = "fat"
|
||||
local body = constructor[4]
|
||||
local dests = (function()
|
||||
local _moon_0 = {}
|
||||
@ -278,9 +266,20 @@ line_compile = {
|
||||
if #self_args > 0 then
|
||||
insert(body, 1, { "assign", dests, self_args })
|
||||
end
|
||||
insert(body, 1, { "raw", ("local self = setmetatable({}, %s)"):format(mt_name) })
|
||||
insert(body, { "return", "self" })
|
||||
return self:stm({ "assign", { name }, { constructor } })
|
||||
local def_scope = self:block()
|
||||
local base_name = def_scope:free_name("base")
|
||||
def_scope:add_line(("local %s ="):format(base_name), def_scope:value(tbl))
|
||||
def_scope:add_line(("%s.__index = %s"):format(base_name, base_name))
|
||||
local cls = def_scope:value({ "table", { { "__init", constructor } } })
|
||||
local cls_mt = def_scope:value({ "table", { { "__index", base_name }, { "__call", {
|
||||
"fndef",
|
||||
{ "mt", "..." },
|
||||
"slim",
|
||||
{ { "raw", ("local self = setmetatable({}, %s)"):format(base_name) }, { "chain", "mt.__init", { "call", { "self", "..." } } }, "self" }
|
||||
} } } })
|
||||
def_scope:add_line(("return setmetatable(%s, %s)"):format(cls, cls_mt))
|
||||
local def = concat({ "(function()\n", (def_scope:render()), "\nend)()" })
|
||||
return self:stm({ "assign", { name }, { def } })
|
||||
end,
|
||||
comprehension = function(self, node, action)
|
||||
local _, exp, clauses = unpack(node)
|
||||
|
@ -162,35 +162,24 @@ line_compile =
|
||||
|
||||
["class"]: (node) =>
|
||||
_, name, tbl = unpack node
|
||||
mt_name = "_"..name.."_mt"
|
||||
@add_line "local", concat @declare({ name, mt_name }), ", "
|
||||
|
||||
constructor = nil
|
||||
meta_methods = {}
|
||||
final_properties = {}
|
||||
|
||||
overloaded_index = value
|
||||
|
||||
find_special = (name, value) ->
|
||||
if name == constructor_name
|
||||
constructor = value
|
||||
elseif name:match("^__%a")
|
||||
insert meta_methods, {name, value}
|
||||
overloaded_index = value if name == "__index"
|
||||
else
|
||||
insert final_properties, {name, value}
|
||||
|
||||
find_special unpack entry for entry in *tbl[2]
|
||||
|
||||
if not overloaded_index
|
||||
insert meta_methods, {"__index", {"table", final_properties}}
|
||||
|
||||
@stm {"assign", {mt_name}, {{"table", meta_methods}}}
|
||||
tbl[2] = final_properties
|
||||
|
||||
-- synthesize constructor
|
||||
if not constructor
|
||||
constructor = {"fndef", {}, "slim", {}}
|
||||
constructor = {"fndef", {}, "fat", {}}
|
||||
|
||||
-- organize constructor
|
||||
-- extract self arguments
|
||||
self_args = {}
|
||||
get_initializers = (arg) ->
|
||||
@ -200,15 +189,37 @@ line_compile =
|
||||
arg
|
||||
|
||||
constructor[2] = [get_initializers arg for arg in *constructor[2]]
|
||||
constructor[3] = "slim"
|
||||
constructor[3] = "fat"
|
||||
body = constructor[4]
|
||||
|
||||
dests = [{"self", name} for name in *self_args]
|
||||
insert body, 1, {"assign", dests, self_args} if #self_args > 0
|
||||
insert body, 1, {"raw", ("local self = setmetatable({}, %s)"):format(mt_name)}
|
||||
insert body, {"return", "self"}
|
||||
|
||||
@stm {"assign", {name}, {constructor}}
|
||||
-- insert body, 1, {"raw", ("local self = setmetatable({}, %s)"):format(mt_name)}
|
||||
-- insert body, {"return", "self"}
|
||||
|
||||
def_scope = @block()
|
||||
base_name = def_scope:free_name "base"
|
||||
def_scope:add_line ("local %s ="):format(base_name), def_scope:value tbl
|
||||
def_scope:add_line ("%s.__index = %s"):format(base_name, base_name)
|
||||
|
||||
cls = def_scope:value {"table", {
|
||||
{"__init", constructor}
|
||||
}}
|
||||
|
||||
cls_mt = def_scope:value {"table", {
|
||||
{"__index", base_name}
|
||||
{"__call", {"fndef", {"mt", "..."}, "slim", {
|
||||
{"raw", ("local self = setmetatable({}, %s)"):format(base_name)}
|
||||
{"chain", "mt.__init", {"call", {"self", "..."}}}
|
||||
"self"
|
||||
}}}
|
||||
}}
|
||||
|
||||
def_scope:add_line ("return setmetatable(%s, %s)"):format(cls, cls_mt)
|
||||
|
||||
def = concat { "(function()\n", (def_scope:render()), "\nend)()" }
|
||||
@stm {"assign", {name}, {def}}
|
||||
|
||||
comprehension: (node, action) =>
|
||||
_, exp, clauses = unpack node
|
||||
|
@ -340,7 +340,7 @@ local build_grammar = wrap(function()
|
||||
|
||||
TableBlock = Break * #Cmt(Indent, advance_indent) * TableBlockInner * OutBlock / mark"table",
|
||||
|
||||
ClassDecl = key"class" * Name * TableBlock / mark"class",
|
||||
ClassDecl = key"class" * Name * (key"extends" * Name)^-1 * TableBlock / mark"class",
|
||||
|
||||
Export = key"export" * Ct(NameList) / mark"export",
|
||||
|
||||
|
@ -1,11 +1,15 @@
|
||||
local Hello, _Hello_mt
|
||||
_Hello_mt = { __tostring = function(self) return "hello world" end, __index = { hello = function(self) return print(self.test, self.world) end } }
|
||||
Hello = function(test, world)
|
||||
local self = setmetatable({}, _Hello_mt)
|
||||
self.test, self.world = test, world
|
||||
print("creating object..")
|
||||
return self
|
||||
end
|
||||
local Hello = (function()
|
||||
local _base_0 = { hello = function(self) return print(self.test, self.world) end, __tostring = function(self) return "hello world" end }
|
||||
_base_0.__index = _base_0
|
||||
return setmetatable({ __init = function(self, test, world)
|
||||
self.test, self.world = test, world
|
||||
return print("creating object..")
|
||||
end }, { __index = _base_0, __call = function(mt, ...)
|
||||
local self = setmetatable({}, _base_0)
|
||||
mt.__init(self, ...)
|
||||
return self
|
||||
end })
|
||||
end)()
|
||||
local x = Hello(1, 2)
|
||||
x:hello()
|
||||
print(x)
|
Loading…
Reference in New Issue
Block a user