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,
|
end,
|
||||||
["class"] = function(self, node)
|
["class"] = function(self, node)
|
||||||
local _, name, tbl = unpack(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 constructor = nil
|
||||||
local meta_methods = { }
|
|
||||||
local final_properties = { }
|
local final_properties = { }
|
||||||
local overloaded_index = value
|
|
||||||
local find_special
|
local find_special
|
||||||
find_special = function(name, value)
|
find_special = function(name, value)
|
||||||
if name == constructor_name then
|
if name == constructor_name then
|
||||||
constructor = value
|
constructor = value
|
||||||
elseif name:match("^__%a") then
|
|
||||||
insert(meta_methods, { name, value })
|
|
||||||
if name == "__index" then
|
|
||||||
overloaded_index = value
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
return insert(final_properties, { name, value })
|
return insert(final_properties, { name, value })
|
||||||
end
|
end
|
||||||
@ -234,15 +225,12 @@ line_compile = {
|
|||||||
local entry = _item_0[_index_0]
|
local entry = _item_0[_index_0]
|
||||||
find_special(unpack(entry))
|
find_special(unpack(entry))
|
||||||
end
|
end
|
||||||
if not overloaded_index then
|
tbl[2] = final_properties
|
||||||
insert(meta_methods, { "__index", { "table", final_properties } })
|
|
||||||
end
|
|
||||||
self:stm({ "assign", { mt_name }, { { "table", meta_methods } } })
|
|
||||||
if not constructor then
|
if not constructor then
|
||||||
constructor = {
|
constructor = {
|
||||||
"fndef",
|
"fndef",
|
||||||
{ },
|
{ },
|
||||||
"slim",
|
"fat",
|
||||||
{ }
|
{ }
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
@ -264,7 +252,7 @@ line_compile = {
|
|||||||
end
|
end
|
||||||
return _moon_0
|
return _moon_0
|
||||||
end)()
|
end)()
|
||||||
constructor[3] = "slim"
|
constructor[3] = "fat"
|
||||||
local body = constructor[4]
|
local body = constructor[4]
|
||||||
local dests = (function()
|
local dests = (function()
|
||||||
local _moon_0 = {}
|
local _moon_0 = {}
|
||||||
@ -278,9 +266,20 @@ line_compile = {
|
|||||||
if #self_args > 0 then
|
if #self_args > 0 then
|
||||||
insert(body, 1, { "assign", dests, self_args })
|
insert(body, 1, { "assign", dests, self_args })
|
||||||
end
|
end
|
||||||
insert(body, 1, { "raw", ("local self = setmetatable({}, %s)"):format(mt_name) })
|
local def_scope = self:block()
|
||||||
insert(body, { "return", "self" })
|
local base_name = def_scope:free_name("base")
|
||||||
return self:stm({ "assign", { name }, { constructor } })
|
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,
|
end,
|
||||||
comprehension = function(self, node, action)
|
comprehension = function(self, node, action)
|
||||||
local _, exp, clauses = unpack(node)
|
local _, exp, clauses = unpack(node)
|
||||||
|
@ -162,35 +162,24 @@ line_compile =
|
|||||||
|
|
||||||
["class"]: (node) =>
|
["class"]: (node) =>
|
||||||
_, name, tbl = unpack node
|
_, name, tbl = unpack node
|
||||||
mt_name = "_"..name.."_mt"
|
|
||||||
@add_line "local", concat @declare({ name, mt_name }), ", "
|
|
||||||
|
|
||||||
constructor = nil
|
constructor = nil
|
||||||
meta_methods = {}
|
|
||||||
final_properties = {}
|
final_properties = {}
|
||||||
|
|
||||||
overloaded_index = value
|
|
||||||
|
|
||||||
find_special = (name, value) ->
|
find_special = (name, value) ->
|
||||||
if name == constructor_name
|
if name == constructor_name
|
||||||
constructor = value
|
constructor = value
|
||||||
elseif name:match("^__%a")
|
|
||||||
insert meta_methods, {name, value}
|
|
||||||
overloaded_index = value if name == "__index"
|
|
||||||
else
|
else
|
||||||
insert final_properties, {name, value}
|
insert final_properties, {name, value}
|
||||||
|
|
||||||
find_special unpack entry for entry in *tbl[2]
|
find_special unpack entry for entry in *tbl[2]
|
||||||
|
tbl[2] = final_properties
|
||||||
if not overloaded_index
|
|
||||||
insert meta_methods, {"__index", {"table", final_properties}}
|
|
||||||
|
|
||||||
@stm {"assign", {mt_name}, {{"table", meta_methods}}}
|
|
||||||
|
|
||||||
-- synthesize constructor
|
-- synthesize constructor
|
||||||
if not constructor
|
if not constructor
|
||||||
constructor = {"fndef", {}, "slim", {}}
|
constructor = {"fndef", {}, "fat", {}}
|
||||||
|
|
||||||
|
-- organize constructor
|
||||||
-- extract self arguments
|
-- extract self arguments
|
||||||
self_args = {}
|
self_args = {}
|
||||||
get_initializers = (arg) ->
|
get_initializers = (arg) ->
|
||||||
@ -200,15 +189,37 @@ line_compile =
|
|||||||
arg
|
arg
|
||||||
|
|
||||||
constructor[2] = [get_initializers arg for arg in *constructor[2]]
|
constructor[2] = [get_initializers arg for arg in *constructor[2]]
|
||||||
constructor[3] = "slim"
|
constructor[3] = "fat"
|
||||||
body = constructor[4]
|
body = constructor[4]
|
||||||
|
|
||||||
dests = [{"self", name} for name in *self_args]
|
dests = [{"self", name} for name in *self_args]
|
||||||
insert body, 1, {"assign", dests, self_args} if #self_args > 0
|
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) =>
|
comprehension: (node, action) =>
|
||||||
_, exp, clauses = unpack node
|
_, exp, clauses = unpack node
|
||||||
|
@ -340,7 +340,7 @@ local build_grammar = wrap(function()
|
|||||||
|
|
||||||
TableBlock = Break * #Cmt(Indent, advance_indent) * TableBlockInner * OutBlock / mark"table",
|
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",
|
Export = key"export" * Ct(NameList) / mark"export",
|
||||||
|
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
local Hello, _Hello_mt
|
local Hello = (function()
|
||||||
_Hello_mt = { __tostring = function(self) return "hello world" end, __index = { hello = function(self) return print(self.test, self.world) end } }
|
local _base_0 = { hello = function(self) return print(self.test, self.world) end, __tostring = function(self) return "hello world" end }
|
||||||
Hello = function(test, world)
|
_base_0.__index = _base_0
|
||||||
local self = setmetatable({}, _Hello_mt)
|
return setmetatable({ __init = function(self, test, world)
|
||||||
self.test, self.world = test, world
|
self.test, self.world = test, world
|
||||||
print("creating object..")
|
return print("creating object..")
|
||||||
return self
|
end }, { __index = _base_0, __call = function(mt, ...)
|
||||||
end
|
local self = setmetatable({}, _base_0)
|
||||||
|
mt.__init(self, ...)
|
||||||
|
return self
|
||||||
|
end })
|
||||||
|
end)()
|
||||||
local x = Hello(1, 2)
|
local x = Hello(1, 2)
|
||||||
x:hello()
|
x:hello()
|
||||||
print(x)
|
print(x)
|
Loading…
Reference in New Issue
Block a user