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), Line = (CheckIndent * Statement + Space * #Stop),
Statement = pos( Statement = pos(
Import + While + With + For + ForEach + Switch + Return + ClassDecl + Import + While + With + For + ForEach + Switch + Return +
Local + Export + BreakLoop + Local + Export + BreakLoop +
Ct(ExpList) * (Update + Assign)^-1 / format_assign Ct(ExpList) * (Update + Assign)^-1 / format_assign
) * Space * (( ) * Space * ((
@ -467,6 +467,7 @@ local build_grammar = wrap_env(function()
If + Unless + If + Unless +
Switch + Switch +
With + With +
ClassDecl +
ForEach + For + While + ForEach + For + While +
Cmt(Do, check_do) + Cmt(Do, check_do) +
sym"-" * -SomeSpace * Exp / mark"minus" + sym"-" * -SomeSpace * Exp / mark"minus" +
@ -552,7 +553,7 @@ local build_grammar = wrap_env(function()
TableBlockInner = Ct(KeyValueLine * (SpaceBreak^1 * KeyValueLine)^0), TableBlockInner = Ct(KeyValueLine * (SpaceBreak^1 * KeyValueLine)^0),
TableBlock = SpaceBreak^1 * Advance * ensure(TableBlockInner, PopIndent) / mark"table", 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 * ClassBlock = SpaceBreak^1 * Advance *
Ct(ClassLine * (SpaceBreak^1 * ClassLine)^0) * PopIndent, Ct(ClassLine * (SpaceBreak^1 * ClassLine)^0) * PopIndent,

View File

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

View File

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

View File

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

View File

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

View File

@ -146,7 +146,14 @@ class a.b["hello"]
class (-> require "moon")!.Something extends Hello.World class (-> require "moon")!.Something extends Hello.World
nil 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") return require("moon")
end)().Something = _class_0 end)().Something = _class_0
end 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 do
local _parent_0 = nil local _parent_0 = nil
local _base_0 = { } local _base_0 = { }