class level inheritance, changed class representation slightly

Looking up a class property will now search the parent class properties
if parent exists

Classes have a few more built in properties:

  * __name holds the name of the class as it was defined as a string
  * __base holds the instance metatable as it was defined (not dynamic)
  * __parent holds the class's parent class if it exists (not dynamic)

The way class inheritance is handled was CHANGED (uses __base instead of
looking at __index of parents metatable). Make sure you recompile all
your code if using class inheritance because old classes won't work with
new ones.
This commit is contained in:
leaf corcoran 2011-12-03 19:17:06 -08:00
parent e55fa25e6e
commit d1059b8f98
4 changed files with 241 additions and 51 deletions

View File

@ -638,12 +638,69 @@ Statement = Transformer({
{
"__init",
constructor
},
{
"__base",
base_name
},
{
"__name",
{
"string",
'"',
name
}
},
{
"__parent",
parent_cls_name
}
})
local class_lookup = build["if"]({
cond = {
"exp",
"val",
"==",
"nil",
"and",
parent_cls_name
},
["then"] = {
parent_cls_name:index("name")
}
})
insert(class_lookup, {
"else",
{
"val"
}
})
local cls_mt = build.table({
{
"__index",
base_name
build.fndef({
args = {
{
"cls"
},
{
"name"
}
},
body = {
build.assign_one(LocalName("val"), build.chain({
base = "rawget",
{
"call",
{
base_name,
"name"
}
}
})),
class_lookup
}
})
},
{
"__call",
@ -779,16 +836,10 @@ Statement = Transformer({
{
base_name,
_with_0.chain({
base = "getmetatable",
{
"call",
{
parent_cls_name
}
},
base = parent_cls_name,
{
"dot",
"__index"
"__base"
}
})
}

View File

@ -353,10 +353,30 @@ Statement = Transformer {
cls = build.table {
{"__init", constructor}
{"__base", base_name}
{"__name", {"string", '"', name}} -- "quote the string"
{"__parent", parent_cls_name}
}
-- look up a name in the class object
class_lookup = build["if"] {
cond: {"exp", "val", "==", "nil", "and", parent_cls_name}
then: {
parent_cls_name\index"name"
}
}
insert class_lookup, {"else", {"val"}}
cls_mt = build.table {
{"__index", base_name}
{"__index", build.fndef {
args: {{"cls"}, {"name"}}
body: {
build.assign_one LocalName"val", build.chain {
base: "rawget", {"call", {base_name, "name"}}
}
class_lookup
}
}}
{"__call", build.fndef {
args: {{"cls"}, {"..."}}
body: {
@ -421,11 +441,10 @@ Statement = Transformer {
then: {
.chain {
base: "setmetatable"
{"call", {base_name, .chain {
base: "getmetatable"
{"call", {parent_cls_name}}
{"dot", "__index"}
}}}
{"call", {
base_name,
.chain { base: parent_cls_name, {"dot", "__base"}}
}}
}
}
}

View File

@ -11,15 +11,25 @@ Hello = (function()
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, getmetatable(_parent_0).__index)
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, test, world)
self.test, self.world = test, world
return print("creating object..")
end
end,
__base = _base_0,
__name = "Hello",
__parent = _parent_0
}, {
__index = _base_0,
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -42,16 +52,26 @@ Simple = (function()
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, getmetatable(_parent_0).__index)
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end
end,
__base = _base_0,
__name = "Simple",
__parent = _parent_0
}, {
__index = _base_0,
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -67,14 +87,24 @@ Yikes = (function()
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, getmetatable(_parent_0).__index)
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self)
return print("created hello")
end
end,
__base = _base_0,
__name = "Yikes",
__parent = _parent_0
}, {
__index = _base_0,
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -96,14 +126,24 @@ Hi = (function()
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, getmetatable(_parent_0).__index)
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, arg)
return print("init arg", arg)
end
end,
__base = _base_0,
__name = "Hi",
__parent = _parent_0
}, {
__index = _base_0,
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -122,14 +162,24 @@ Simple = (function()
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, getmetatable(_parent_0).__index)
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self)
return _parent_0.__init(self, "man")
end
end,
__base = _base_0,
__name = "Simple",
__parent = _parent_0
}, {
__index = _base_0,
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -150,16 +200,26 @@ Okay = (function()
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, getmetatable(_parent_0).__index)
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end
end,
__base = _base_0,
__name = "Okay",
__parent = _parent_0
}, {
__index = _base_0,
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -181,16 +241,26 @@ Biggie = (function()
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, getmetatable(_parent_0).__index)
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end
end,
__base = _base_0,
__name = "Biggie",
__parent = _parent_0
}, {
__index = _base_0,
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -210,16 +280,26 @@ Yeah = (function()
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, getmetatable(_parent_0).__index)
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end
end,
__base = _base_0,
__name = "Yeah",
__parent = _parent_0
}, {
__index = _base_0,
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -239,16 +319,26 @@ What = (function()
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, getmetatable(_parent_0).__index)
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end
end,
__base = _base_0,
__name = "What",
__parent = _parent_0
}, {
__index = _base_0,
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -274,16 +364,26 @@ Hello = (function()
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, getmetatable(_parent_0).__index)
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end
end,
__base = _base_0,
__name = "Hello",
__parent = _parent_0
}, {
__index = _base_0,
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -315,16 +415,26 @@ CoolSuper = (function()
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, getmetatable(_parent_0).__index)
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end
end,
__base = _base_0,
__name = "CoolSuper",
__parent = _parent_0
}, {
__index = _base_0,
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)

View File

@ -7,16 +7,26 @@ Something = (function()
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, getmetatable(_parent_0).__index)
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end
end,
__base = _base_0,
__name = "Something",
__parent = _parent_0
}, {
__index = _base_0,
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)