class name can be any assignable expression #46

This commit is contained in:
leaf corcoran 2012-10-31 00:07:59 -07:00
parent b6987fe6d8
commit 021d4878a0
5 changed files with 191 additions and 22 deletions

View File

@ -507,7 +507,7 @@ local build_grammar = wrap_env(function()
TableBlockInner = Ct(KeyValueLine * (SpaceBreak^1 * KeyValueLine)^0),
TableBlock = SpaceBreak^1 * Advance * ensure(TableBlockInner, PopIndent) / mark"table",
ClassDecl = key"class" * Name * (key"extends" * PreventIndent * ensure(Exp, PopIndent) + C"")^-1 * ClassBlock / mark"class",
ClassDecl = key"class" * Assignable * (key"extends" * PreventIndent * ensure(Exp, PopIndent) + C"")^-1 * ClassBlock / mark"class",
ClassBlock = SpaceBreak^1 * Advance *
Ct(ClassLine * (SpaceBreak^1 * ClassLine)^0) * PopIndent,

View File

@ -954,6 +954,28 @@ Statement = Transformer({
smart_node(constructor)
constructor.arrow = "fat"
end
local real_name
if ntype(name) == "chain" then
local last = name[#name]
local _exp_0 = ntype(last)
if "dot" == _exp_0 then
real_name = {
"string",
'"',
last[2]
}
elseif "index" == _exp_0 then
real_name = last[2]
else
real_name = "nil"
end
else
real_name = {
"string",
'"',
name
}
end
local cls = build.table({
{
"__init",
@ -965,11 +987,7 @@ Statement = Transformer({
},
{
"__name",
{
"string",
'"',
name
}
real_name
},
{
"__parent",
@ -1197,21 +1215,25 @@ Statement = Transformer({
})
}
}),
_with_0.assign_one(name, cls_name)
_with_0.assign_one(name, cls_name),
(function()
if ret then
return ret(cls_name)
end
end)()
}
hoist_declarations(out_body)
value = _with_0.group({
_with_0.declare({
names = {
name
}
}),
_with_0["do"](out_body),
(function()
if ret then
return ret(name)
if ntype(name) == "value" then
return _with_0.declare({
names = {
name
}
})
end
end)()
end)(),
_with_0["do"](out_body)
})
end
return value

View File

@ -488,10 +488,22 @@ Statement = Transformer {
smart_node constructor
constructor.arrow = "fat"
real_name = if ntype(name) == "chain"
last = name[#name]
switch ntype last
when "dot"
{"string", '"', last[2]}
when "index"
last[2]
else
"nil"
else
{"string", '"', name}
cls = build.table {
{"__init", constructor}
{"__base", base_name}
{"__name", {"string", '"', name}} -- "quote the string"
{"__name", real_name} -- "quote the string"
{"__parent", parent_cls_name}
}
@ -610,16 +622,17 @@ Statement = Transformer {
}
.assign_one name, cls_name
if ret
ret cls_name
}
hoist_declarations out_body
value = .group {
.declare names: {name}
.do out_body
if ntype(name) == "value"
.declare names: {name}
if ret
ret name
.do out_body
}
value

View File

@ -133,3 +133,17 @@ yyy = ->
class Cool
nil
--
class a.b.c.D
nil
class a.b["hello"]
nil
class (-> require "moon")!.Something extends Hello.World
nil

View File

@ -631,6 +631,126 @@ yyy = function()
_parent_0.__inherited(_parent_0, _class_0)
end
Cool = _class_0
return _class_0
end
return Cool
end
do
local _parent_0 = nil
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
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,
__base = _base_0,
__name = "D",
__parent = _parent_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, ...)
return _self_0
end
})
_base_0.__class = _class_0
local self = _class_0
_ = nil
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
a.b.c.D = _class_0
end
do
local _parent_0 = nil
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
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,
__base = _base_0,
__name = "hello",
__parent = _parent_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, ...)
return _self_0
end
})
_base_0.__class = _class_0
local self = _class_0
_ = nil
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
a.b["hello"] = _class_0
end
do
local _parent_0 = Hello.World
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
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,
__base = _base_0,
__name = "Something",
__parent = _parent_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, ...)
return _self_0
end
})
_base_0.__class = _class_0
local self = _class_0
_ = nil
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
(function()
return require("moon")
end)().Something = _class_0
return _class_0
end