basic class syntax

This commit is contained in:
leaf corcoran 2011-06-14 23:13:33 -07:00
parent c6aa90bcbc
commit 858608a04d
5 changed files with 65 additions and 16 deletions

View File

@ -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)

View File

@ -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) =>

View File

@ -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
View 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
View 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)