classes can be expressions, classes don't require name or body anymore

This commit is contained in:
leaf corcoran 2012-11-01 08:56:54 -07:00
parent bcb4327fd8
commit 97394fbbc9
7 changed files with 288 additions and 49 deletions

View File

@ -383,7 +383,7 @@ local build_grammar = wrap_env(function()
Line = (CheckIndent * Statement + Space * #Stop),
Statement = pos(
Import + While + With + For + ForEach + Switch + Return + ClassDecl +
Import + While + With + For + ForEach + Switch + Return +
Local + Export + BreakLoop +
Ct(ExpList) * (Update + Assign)^-1 / format_assign
) * Space * ((
@ -467,6 +467,7 @@ local build_grammar = wrap_env(function()
If + Unless +
Switch +
With +
ClassDecl +
ForEach + For + While +
Cmt(Do, check_do) +
sym"-" * -SomeSpace * Exp / mark"minus" +
@ -552,10 +553,10 @@ 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" * Assignable * (key"extends" * PreventIndent * ensure(Exp, PopIndent) + C"")^-1 * ClassBlock / mark"class",
ClassDecl = key"class" * (Assignable + Cc(nil)) * (key"extends" * PreventIndent * ensure(Exp, PopIndent) + C"")^-1 * (ClassBlock + Ct("")) / mark"class",
ClassBlock = SpaceBreak^1 * Advance *
Ct(ClassLine * (SpaceBreak^1 * ClassLine)^0) * PopIndent,
Ct(ClassLine * (SpaceBreak^1 * ClassLine)^0) * PopIndent,
ClassLine = CheckIndent * ((
KeyValueList / mark"props" +
Statement / mark"stm" +

View File

@ -975,20 +975,23 @@ Statement = Transformer({
constructor.arrow = "fat"
end
local real_name
if ntype(name) == "chain" then
local _exp_0 = ntype(name)
if "chain" == _exp_0 then
local last = name[#name]
local _exp_0 = ntype(last)
if "dot" == _exp_0 then
local _exp_1 = ntype(last)
if "dot" == _exp_1 then
real_name = {
"string",
'"',
last[2]
}
elseif "index" == _exp_0 then
elseif "index" == _exp_1 then
real_name = last[2]
else
real_name = "nil"
end
elseif "nil" == _exp_0 then
real_name = "nil"
else
real_name = {
"string",
@ -1112,7 +1115,9 @@ Statement = Transformer({
local _with_0 = build
local out_body = {
Run(function(self)
self:put_name(name)
if name then
self:put_name(name)
end
return self:set("super", function(block, chain)
if chain then
local slice = (function()
@ -1134,8 +1139,8 @@ Statement = Transformer({
if head == nil then
return parent_cls_name
end
local _exp_0 = head[1]
if "call" == _exp_0 then
local _exp_1 = head[1]
if "call" == _exp_1 then
local calling_name = block:get("current_block")
slice[1] = {
"call",
@ -1155,7 +1160,7 @@ Statement = Transformer({
calling_name
})
end
elseif "colon" == _exp_0 then
elseif "colon" == _exp_1 then
local call = head[3]
insert(new_chain, {
"dot",
@ -1186,7 +1191,7 @@ Statement = Transformer({
properties
}),
_with_0.assign_one(base_name:chain("__index"), base_name),
build["if"]({
_with_0["if"]({
cond = parent_cls_name,
["then"] = {
_with_0.chain({
@ -1215,11 +1220,9 @@ Statement = Transformer({
_with_0.assign_one(LocalName("self"), cls_name),
_with_0.group(statements)
}
else
return { }
end
end)()),
build["if"]({
_with_0["if"]({
cond = {
"exp",
parent_cls_name,
@ -1236,7 +1239,13 @@ Statement = Transformer({
})
}
}),
_with_0.assign_one(name, cls_name),
_with_0.group((function()
if name then
return {
_with_0.assign_one(name, cls_name)
}
end
end)()),
(function()
if ret then
return ret(cls_name)
@ -1245,15 +1254,17 @@ Statement = Transformer({
}
hoist_declarations(out_body)
value = _with_0.group({
(function()
_with_0.group((function()
if ntype(name) == "value" then
return _with_0.declare({
names = {
name
}
})
return {
_with_0.declare({
names = {
name
}
})
}
end
end)(),
end)()),
_with_0["do"](out_body)
})
end
@ -1415,6 +1426,11 @@ Value = Transformer({
decorated = function(self, node)
return self.transform.statement(node)
end,
class = function(self, node)
return build.block_exp({
node
})
end,
string = function(self, node)
local delim = node[2]
local convert_part

View File

@ -505,17 +505,20 @@ 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}
real_name = switch ntype(name)
when "chain"
last = name[#name]
switch ntype last
when "dot"
{"string", '"', last[2]}
when "index"
last[2]
else
"nil"
when "nil"
"nil"
else
{"string", '"', name}
cls = build.table {
{"__init", constructor}
@ -569,7 +572,7 @@ Statement = Transformer {
out_body = {
Run =>
-- make sure we don't assign the class to a local inside the do
@put_name name
@put_name name if name
@set "super", (block, chain) ->
if chain
@ -608,7 +611,7 @@ Statement = Transformer {
.assign_one base_name, {"table", properties}
.assign_one base_name\chain"__index", base_name
build["if"] {
.if {
cond: parent_cls_name
then: {
.chain {
@ -624,13 +627,13 @@ Statement = Transformer {
.assign_one cls_name, cls
.assign_one base_name\chain"__class", cls_name
.group if #statements > 0 {
.group if #statements > 0 then {
.assign_one LocalName"self", cls_name
.group statements
} else {}
}
-- run the inherited callback
build["if"] {
.if {
cond: {"exp",
parent_cls_name, "and", parent_cls_name\chain "__inherited"
}
@ -641,7 +644,10 @@ Statement = Transformer {
}
}
.assign_one name, cls_name
.group if name then {
.assign_one name, cls_name
}
if ret
ret cls_name
}
@ -649,8 +655,9 @@ Statement = Transformer {
hoist_declarations out_body
value = .group {
if ntype(name) == "value"
.group if ntype(name) == "value" then {
.declare names: {name}
}
.do out_body
}
@ -755,6 +762,9 @@ Value = Transformer {
decorated: (node) =>
@transform.statement node
class: (node) =>
build.block_exp { node }
string: (node) =>
delim = node[2]

View File

@ -24,10 +24,13 @@ comprehension_has_value = function(comp)
return is_value(comp[2])
end
ntype = function(node)
if type(node) ~= "table" then
return "value"
else
local _exp_0 = type(node)
if "nil" == _exp_0 then
return "nil"
elseif "table" == _exp_0 then
return node[1]
else
return "value"
end
end
value_is_singular = function(node)
@ -175,6 +178,9 @@ end
build = nil
build = setmetatable({
group = function(body)
if body == nil then
body = { }
end
return {
"group",
body

View File

@ -25,10 +25,13 @@ comprehension_has_value = (comp) ->
-- type of node as string
ntype = (node) ->
if type(node) != "table"
"value"
else
node[1]
switch type node
when "nil"
"nil"
when "table"
node[1]
else
"value"
value_is_singular = (node) ->
type(node) != "table" or node[1] != "exp" or #node == 2
@ -102,7 +105,7 @@ make_builder = (name) ->
build = nil
build = setmetatable {
group: (body) ->
group: (body={}) ->
{"group", body}
do: (body) ->
{"do", body}

View File

@ -146,7 +146,14 @@ class a.b["hello"]
class (-> require "moon")!.Something extends Hello.World
nil
--
a = class
b = class Something
c = class Something extends Hello
d = class extends World
print (class WhatsUp).__name
--

View File

@ -753,6 +753,202 @@ do
return require("moon")
end)().Something = _class_0
end
local a
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 = nil,
__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
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
a = _class_0
end
local b
local Something
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 = "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
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Something = _class_0
b = _class_0
end
local c
do
local _parent_0 = Hello
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
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Something = _class_0
c = _class_0
end
local d
do
local _parent_0 = 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 = nil,
__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
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
d = _class_0
end
print(((function()
local WhatsUp
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 = "WhatsUp",
__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
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
WhatsUp = _class_0
return _class_0
end
end)()).__name)
do
local _parent_0 = nil
local _base_0 = { }