class inheritance

This commit is contained in:
leaf corcoran 2011-06-15 22:41:17 -07:00
parent 65fdf7e6b2
commit 67a59a9622
5 changed files with 64 additions and 11 deletions

View File

@ -209,7 +209,7 @@ line_compile = {
return nil
end,
["class"] = function(self, node)
local _, name, tbl = unpack(node)
local _, name, parent, tbl = unpack(node)
local constructor = nil
local final_properties = { }
local find_special
@ -277,8 +277,20 @@ line_compile = {
"slim",
{ { "raw", ("local self = setmetatable({}, %s)"):format(base_name) }, { "chain", "mt.__init", { "call", { "self", "..." } } }, "self" }
} } } })
local parent_var = def_scope:free_name("parent")
if parent ~= "" then
def_scope:stm({ "if", parent_var, { { "chain", "setmetatable", { "call", { base_name, {
"chain",
"getmetatable",
{ "call", { parent_var } },
{ "dot", "__index" }
} } } } } })
end
def_scope:add_line(("return setmetatable(%s, %s)"):format(cls, cls_mt))
local def = concat({ "(function()\n", (def_scope:render()), "\nend)()" })
if parent ~= "" then
parent = self:value(parent)
end
local def = concat({ ("(function(%s)\n"):format(parent_var), (def_scope:render()), ("\nend)(%s)"):format(parent) })
return self:stm({ "assign", { name }, { def } })
end,
comprehension = function(self, node, action)

View File

@ -161,7 +161,7 @@ line_compile =
nil
["class"]: (node) =>
_, name, tbl = unpack node
_, name, parent, tbl = unpack node
constructor = nil
final_properties = {}
@ -195,9 +195,6 @@ line_compile =
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"}
def_scope = @block()
base_name = def_scope:free_name "base"
def_scope:add_line ("local %s ="):format(base_name), def_scope:value tbl
@ -216,9 +213,23 @@ line_compile =
}}}
}}
parent_var = def_scope:free_name "parent"
if parent != ""
def_scope:stm {"if", parent_var,
{{"chain", "setmetatable", {"call",
{base_name, {"chain", "getmetatable",
{"call", {parent_var}}, {"dot", "__index"}}}}}}}
def_scope:add_line ("return setmetatable(%s, %s)"):format(cls, cls_mt)
def = concat { "(function()\n", (def_scope:render()), "\nend)()" }
parent = @value parent if parent != ""
def = concat {
("(function(%s)\n"):format(parent_var)
(def_scope:render())
("\nend)(%s)"):format(parent)
}
@stm {"assign", {name}, {def}}
comprehension: (node, action) =>

View File

@ -340,8 +340,7 @@ local build_grammar = wrap(function()
TableBlock = Break * #Cmt(Indent, advance_indent) * TableBlockInner * OutBlock / mark"table",
ClassDecl = key"class" * Name * (key"extends" * Name)^-1 * TableBlock / mark"class",
ClassDecl = key"class" * Name * (key"extends" * Exp + C"")^-1 * TableBlock / mark"class",
Export = key"export" * Ct(NameList) / mark"export",
KeyValue = Ct((Name + sym"[" * Exp * sym"]") * symx":" * (Exp + TableBlock)),

View File

@ -11,4 +11,12 @@ x:hello()
print x
class Simple
cool: => print "cool"
class Yikes extends Simple
new: => print "created hello"
x = Yikes()
x:cool()

View File

@ -1,4 +1,4 @@
local Hello = (function()
local Hello = (function(_parent_0)
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)
@ -12,4 +12,27 @@ local Hello = (function()
end)()
local x = Hello(1, 2)
x:hello()
print(x)
print(x)
local Simple = (function(_parent_0)
local _base_0 = { cool = function(self) return print("cool") end }
_base_0.__index = _base_0
return setmetatable({ __init = function(self) end }, { __index = _base_0, __call = function(mt, ...)
local self = setmetatable({}, _base_0)
mt.__init(self, ...)
return self
end })
end)()
local Yikes = (function(_parent_0)
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, getmetatable(_parent_0).__index)
end
return setmetatable({ __init = function(self) return print("created hello") end }, { __index = _base_0, __call = function(mt, ...)
local self = setmetatable({}, _base_0)
mt.__init(self, ...)
return self
end })
end)(Simple)
x = Yikes()
x:cool()