mirror of
https://github.com/leafo/moonscript.git
synced 2024-11-22 02:44:23 +00:00
basic class syntax
This commit is contained in:
parent
c6aa90bcbc
commit
858608a04d
@ -6,7 +6,12 @@ require("moonscript.compile.format")
|
||||
local reversed = util.reversed
|
||||
local ntype = data.ntype
|
||||
local concat, insert = table.concat, table.insert
|
||||
local constructor_name = "new"
|
||||
line_compile = {
|
||||
raw = function(self, node)
|
||||
local _, text = unpack(node)
|
||||
return self:add_line(text)
|
||||
end,
|
||||
assign = function(self, node)
|
||||
local _, names, values = unpack(node)
|
||||
local undeclared = self:declare(names)
|
||||
@ -204,7 +209,7 @@ line_compile = {
|
||||
return nil
|
||||
end,
|
||||
["class"] = function(self, node)
|
||||
local _, name, table = unpack(node)
|
||||
local _, name, tbl = unpack(node)
|
||||
local mt_name = "_" .. name .. "_mt"
|
||||
self:add_line("local", concat(self:declare({ name, mt_name }), ", "))
|
||||
local constructor = nil
|
||||
@ -213,7 +218,7 @@ line_compile = {
|
||||
local overloaded_index = value
|
||||
local find_special
|
||||
find_special = function(name, value)
|
||||
if name == "constructor" then
|
||||
if name == constructor_name then
|
||||
constructor = value
|
||||
elseif name:match("^__%a") then
|
||||
insert(meta_methods, { name, value })
|
||||
@ -224,7 +229,7 @@ line_compile = {
|
||||
return insert(final_properties, { name, value })
|
||||
end
|
||||
end
|
||||
local _item_0 = table[2]
|
||||
local _item_0 = tbl[2]
|
||||
for _index_0=1,#_item_0 do
|
||||
local entry = _item_0[_index_0]
|
||||
find_special(unpack(entry))
|
||||
@ -232,9 +237,6 @@ line_compile = {
|
||||
if not overloaded_index then
|
||||
insert(meta_methods, { "__index", { "table", final_properties } })
|
||||
end
|
||||
print(util.dump(constructor))
|
||||
print(util.dump(meta_methods))
|
||||
print(util.dump(final_properties))
|
||||
self:stm({ "assign", { mt_name }, { { "table", meta_methods } } })
|
||||
if not constructor then
|
||||
constructor = {
|
||||
@ -262,7 +264,22 @@ line_compile = {
|
||||
end
|
||||
return _moon_0
|
||||
end)()
|
||||
print(util.dump(constructor))
|
||||
constructor[3] = "slim"
|
||||
local body = constructor[4]
|
||||
local dests = (function()
|
||||
local _moon_0 = {}
|
||||
local _item_0 = self_args
|
||||
for _index_0=1,#_item_0 do
|
||||
local name = _item_0[_index_0]
|
||||
table.insert(_moon_0, { "self", name })
|
||||
end
|
||||
return _moon_0
|
||||
end)()
|
||||
if #self_args > 0 then
|
||||
insert(body, 1, { "assign", dests, self_args })
|
||||
end
|
||||
insert(body, 1, { "raw", ("local self = setmetatable({}, %s)"):format(mt_name) })
|
||||
insert(body, { "return", "self" })
|
||||
return self:stm({ "assign", { name }, { constructor } })
|
||||
end,
|
||||
comprehension = function(self, node, action)
|
||||
|
@ -12,7 +12,12 @@ import concat, insert from table
|
||||
|
||||
export line_compile
|
||||
|
||||
constructor_name = "new"
|
||||
|
||||
line_compile =
|
||||
raw: (node) =>
|
||||
_, text = unpack node
|
||||
@add_line text
|
||||
assign: (node) =>
|
||||
_, names, values = unpack node
|
||||
|
||||
@ -156,7 +161,7 @@ line_compile =
|
||||
nil
|
||||
|
||||
["class"]: (node) =>
|
||||
_, name, table = unpack node
|
||||
_, name, tbl = unpack node
|
||||
mt_name = "_"..name.."_mt"
|
||||
@add_line "local", concat @declare({ name, mt_name }), ", "
|
||||
|
||||
@ -167,7 +172,7 @@ line_compile =
|
||||
overloaded_index = value
|
||||
|
||||
find_special = (name, value) ->
|
||||
if name == "constructor"
|
||||
if name == constructor_name
|
||||
constructor = value
|
||||
elseif name:match("^__%a")
|
||||
insert meta_methods, {name, value}
|
||||
@ -175,15 +180,11 @@ line_compile =
|
||||
else
|
||||
insert final_properties, {name, value}
|
||||
|
||||
find_special unpack entry for entry in *table[2]
|
||||
find_special unpack entry for entry in *tbl[2]
|
||||
|
||||
if not overloaded_index
|
||||
insert meta_methods, {"__index", {"table", final_properties}}
|
||||
|
||||
print util.dump constructor
|
||||
print util.dump meta_methods
|
||||
print util.dump final_properties
|
||||
|
||||
@stm {"assign", {mt_name}, {{"table", meta_methods}}}
|
||||
|
||||
-- synthesize constructor
|
||||
@ -199,8 +200,14 @@ line_compile =
|
||||
arg
|
||||
|
||||
constructor[2] = [get_initializers arg for arg in *constructor[2]]
|
||||
constructor[3] = "slim"
|
||||
body = constructor[4]
|
||||
|
||||
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"}
|
||||
|
||||
print util.dump constructor
|
||||
@stm {"assign", {name}, {constructor}}
|
||||
|
||||
comprehension: (node, action) =>
|
||||
|
@ -227,7 +227,7 @@ local build_grammar = wrap(function()
|
||||
Block = Ct(Line * (Break^1 * Line)^0),
|
||||
Line = Cmt(Indent, check_indent) * Statement + _Space * Comment,
|
||||
|
||||
Statement = (Import + While + For + Export + BreakLoop + Ct(ExpList) / flatten_or_mark"explist" * Space) * (
|
||||
Statement = (Import + While + For + ClassDecl + Export + BreakLoop + Ct(ExpList) / flatten_or_mark"explist" * Space) * (
|
||||
-- statement decorators
|
||||
key"if" * Exp * (key"else" * Exp)^-1 * Space / mark"if" +
|
||||
CompInner / mark"comprehension"
|
||||
|
14
tests/inputs/class.moon
Normal file
14
tests/inputs/class.moon
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
class Hello
|
||||
new: (@test, @world) =>
|
||||
print "creating object.."
|
||||
hello: =>
|
||||
print @test, @world
|
||||
__tostring: => "hello world"
|
||||
|
||||
x = Hello 1,2
|
||||
x:hello()
|
||||
|
||||
print x
|
||||
|
||||
|
11
tests/outputs/class.lua
Normal file
11
tests/outputs/class.lua
Normal file
@ -0,0 +1,11 @@
|
||||
local Hello, _Hello_mt
|
||||
_Hello_mt = { __tostring = function(self) return "hello world" end, __index = { hello = function(self) return print(self.test, self.world) end } }
|
||||
Hello = function(test, world)
|
||||
local self = setmetatable({}, _Hello_mt)
|
||||
self.test, self.world = test, world
|
||||
print("creating object..")
|
||||
return self
|
||||
end
|
||||
local x = Hello(1, 2)
|
||||
x:hello()
|
||||
print(x)
|
Loading…
Reference in New Issue
Block a user