mirror of
https://github.com/leafo/moonscript.git
synced 2024-11-22 02:44:23 +00:00
moved class from compiler to tree transformation
This commit is contained in:
parent
c15089ee1c
commit
3fb8682f96
@ -358,6 +358,7 @@ Block_ = (function(_parent_0)
|
||||
end
|
||||
end,
|
||||
stm = function(self, node, ...)
|
||||
node = transform.node(node)
|
||||
local fn = line_compile[ntype(node)]
|
||||
if not fn then
|
||||
if has_value(node) then
|
||||
|
@ -238,6 +238,7 @@ class Block_
|
||||
\append_list [@value v for v in *values], delim
|
||||
|
||||
stm: (node, ...) =>
|
||||
node = transform.node node
|
||||
fn = line_compile[ntype(node)]
|
||||
if not fn
|
||||
-- coerce value into statement
|
||||
|
@ -70,8 +70,12 @@ line_compile = {
|
||||
end
|
||||
do
|
||||
local _with_0 = self:line()
|
||||
local skip_values = false
|
||||
if #undeclared == #names and not has_fndef then
|
||||
_with_0:append(declare)
|
||||
if #values == 0 then
|
||||
skip_values = true
|
||||
end
|
||||
else
|
||||
if #undeclared > 0 then
|
||||
self:add(declare)
|
||||
@ -90,20 +94,22 @@ line_compile = {
|
||||
return _accum_0
|
||||
end)(), ", ")
|
||||
end
|
||||
_with_0:append(" = ")
|
||||
_with_0:append_list((function()
|
||||
local _accum_0 = { }
|
||||
local _len_0 = 0
|
||||
do
|
||||
local _item_0 = values
|
||||
for _index_0 = 1, #_item_0 do
|
||||
local v = _item_0[_index_0]
|
||||
_len_0 = _len_0 + 1
|
||||
_accum_0[_len_0] = self:value(v)
|
||||
if not skip_values then
|
||||
_with_0:append(" = ")
|
||||
_with_0:append_list((function()
|
||||
local _accum_0 = { }
|
||||
local _len_0 = 0
|
||||
do
|
||||
local _item_0 = values
|
||||
for _index_0 = 1, #_item_0 do
|
||||
local v = _item_0[_index_0]
|
||||
_len_0 = _len_0 + 1
|
||||
_accum_0[_len_0] = self:value(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
return _accum_0
|
||||
end)(), ", ")
|
||||
return _accum_0
|
||||
end)(), ", ")
|
||||
end
|
||||
return _with_0
|
||||
end
|
||||
end
|
||||
@ -412,242 +418,6 @@ line_compile = {
|
||||
self:declare(names)
|
||||
return nil
|
||||
end,
|
||||
class = function(self, node)
|
||||
local _, name, parent_val, tbl = unpack(node)
|
||||
local constructor = nil
|
||||
local final_properties = { }
|
||||
do
|
||||
local _item_0 = tbl[2]
|
||||
for _index_0 = 1, #_item_0 do
|
||||
local entry = _item_0[_index_0]
|
||||
if entry[1] == constructor_name then
|
||||
constructor = entry[2]
|
||||
else
|
||||
insert(final_properties, entry)
|
||||
end
|
||||
end
|
||||
end
|
||||
tbl[2] = final_properties
|
||||
local parent_loc = self:free_name("parent", true)
|
||||
if not constructor then
|
||||
constructor = {
|
||||
"fndef",
|
||||
{
|
||||
{
|
||||
"..."
|
||||
}
|
||||
},
|
||||
{ },
|
||||
"fat",
|
||||
{
|
||||
{
|
||||
"if",
|
||||
parent_loc,
|
||||
{
|
||||
{
|
||||
"chain",
|
||||
"super",
|
||||
{
|
||||
"call",
|
||||
{
|
||||
"..."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
smart_node(constructor)
|
||||
constructor.arrow = "fat"
|
||||
local def_scope
|
||||
do
|
||||
local _with_0 = self:block()
|
||||
if parent_val ~= "" then
|
||||
parent_val = self:value(parent_val)
|
||||
end
|
||||
_with_0:put_name(parent_loc)
|
||||
_with_0.header = self:line("(function(", parent_loc, ")")
|
||||
_with_0.footer = self:line("end)(", parent_val, ")")
|
||||
_with_0:set("super", function(block, chain)
|
||||
local calling_name = block:get("current_block")
|
||||
local slice = (function()
|
||||
local _accum_0 = { }
|
||||
local _len_0 = 0
|
||||
do
|
||||
local _item_0 = chain
|
||||
for _index_0 = 3, #_item_0 do
|
||||
local item = _item_0[_index_0]
|
||||
_len_0 = _len_0 + 1
|
||||
_accum_0[_len_0] = item
|
||||
end
|
||||
end
|
||||
return _accum_0
|
||||
end)()
|
||||
slice[1] = {
|
||||
"call",
|
||||
{
|
||||
"self",
|
||||
unpack(slice[1][2])
|
||||
}
|
||||
}
|
||||
local act
|
||||
if ntype(calling_name) ~= "value" then
|
||||
act = "index"
|
||||
else
|
||||
act = "dot"
|
||||
end
|
||||
return {
|
||||
"chain",
|
||||
parent_loc,
|
||||
{
|
||||
act,
|
||||
calling_name
|
||||
},
|
||||
unpack(slice)
|
||||
}
|
||||
end)
|
||||
local base_name = _with_0:init_free_var("base", tbl)
|
||||
_with_0:stm({
|
||||
"assign",
|
||||
{
|
||||
{
|
||||
"chain",
|
||||
base_name,
|
||||
{
|
||||
"dot",
|
||||
"__index"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
base_name
|
||||
}
|
||||
})
|
||||
_with_0:stm({
|
||||
"if",
|
||||
parent_loc,
|
||||
{
|
||||
{
|
||||
"chain",
|
||||
"setmetatable",
|
||||
{
|
||||
"call",
|
||||
{
|
||||
base_name,
|
||||
{
|
||||
"chain",
|
||||
"getmetatable",
|
||||
{
|
||||
"call",
|
||||
{
|
||||
parent_loc
|
||||
}
|
||||
},
|
||||
{
|
||||
"dot",
|
||||
"__index"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
local cls = {
|
||||
"table",
|
||||
{
|
||||
{
|
||||
"__init",
|
||||
constructor
|
||||
}
|
||||
}
|
||||
}
|
||||
local cls_mt = {
|
||||
"table",
|
||||
{
|
||||
{
|
||||
"__index",
|
||||
base_name
|
||||
},
|
||||
{
|
||||
"__call",
|
||||
{
|
||||
"fndef",
|
||||
{
|
||||
{
|
||||
"mt"
|
||||
},
|
||||
{
|
||||
"..."
|
||||
}
|
||||
},
|
||||
{ },
|
||||
"slim",
|
||||
{
|
||||
{
|
||||
"raw",
|
||||
("local self = setmetatable({}, %s)"):format(base_name)
|
||||
},
|
||||
{
|
||||
"chain",
|
||||
"mt.__init",
|
||||
{
|
||||
"call",
|
||||
{
|
||||
"self",
|
||||
"..."
|
||||
}
|
||||
}
|
||||
},
|
||||
"self"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
local cls_name = _with_0:init_free_var("class", {
|
||||
"chain",
|
||||
"setmetatable",
|
||||
{
|
||||
"call",
|
||||
{
|
||||
cls,
|
||||
cls_mt
|
||||
}
|
||||
}
|
||||
})
|
||||
_with_0:stm({
|
||||
"assign",
|
||||
{
|
||||
{
|
||||
"chain",
|
||||
base_name,
|
||||
{
|
||||
"dot",
|
||||
"__class"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
cls_name
|
||||
}
|
||||
})
|
||||
_with_0:stm({
|
||||
"return",
|
||||
cls_name
|
||||
})
|
||||
def_scope = _with_0
|
||||
end
|
||||
self:stm({
|
||||
"declare",
|
||||
{
|
||||
name
|
||||
}
|
||||
})
|
||||
return self:line(name, " = ", def_scope)
|
||||
end,
|
||||
comprehension = function(self, node, action)
|
||||
local _, exp, clauses = unpack(node)
|
||||
if not action then
|
||||
@ -698,5 +468,12 @@ line_compile = {
|
||||
end
|
||||
return _with_0
|
||||
end
|
||||
end,
|
||||
run = function(self, code)
|
||||
code:call(self)
|
||||
return nil
|
||||
end,
|
||||
group = function(self, node)
|
||||
return self:stms(node[2])
|
||||
end
|
||||
}
|
||||
|
@ -48,14 +48,17 @@ line_compile =
|
||||
i = i +1
|
||||
|
||||
with @line!
|
||||
skip_values = false
|
||||
if #undeclared == #names and not has_fndef
|
||||
\append declare
|
||||
skip_values = true if #values == 0
|
||||
else
|
||||
@add declare if #undeclared > 0
|
||||
\append_list [@value name for name in *names], ", "
|
||||
|
||||
\append " = "
|
||||
\append_list [@value v for v in *values], ", "
|
||||
if not skip_values
|
||||
\append " = "
|
||||
\append_list [@value v for v in *values], ", "
|
||||
|
||||
update: (node) =>
|
||||
_, name, op, exp = unpack node
|
||||
@ -197,90 +200,6 @@ line_compile =
|
||||
@declare names
|
||||
nil
|
||||
|
||||
class: (node) =>
|
||||
_, name, parent_val, tbl = unpack node
|
||||
|
||||
constructor = nil
|
||||
final_properties = {}
|
||||
|
||||
-- organize constructor and everything else
|
||||
for entry in *tbl[2]
|
||||
if entry[1] == constructor_name
|
||||
constructor = entry[2]
|
||||
else
|
||||
insert final_properties, entry
|
||||
|
||||
tbl[2] = final_properties
|
||||
|
||||
-- now create the class's initialization block
|
||||
parent_loc = @free_name "parent", true
|
||||
|
||||
-- synthesize constructor if needed
|
||||
if not constructor
|
||||
constructor = {"fndef", {{"..."}}, {}, "fat", {
|
||||
{"if", parent_loc, {
|
||||
{"chain", "super", {"call", {"..."}}}
|
||||
}}
|
||||
}}
|
||||
|
||||
smart_node constructor
|
||||
constructor.arrow = "fat"
|
||||
|
||||
def_scope = with @block!
|
||||
parent_val = @value parent_val if parent_val != ""
|
||||
\put_name parent_loc
|
||||
|
||||
.header = @line "(function(", parent_loc, ")"
|
||||
.footer = @line "end)(", parent_val, ")"
|
||||
|
||||
\set "super", (block, chain) ->
|
||||
calling_name = block\get"current_block"
|
||||
slice = [item for item in *chain[3:]]
|
||||
-- inject self
|
||||
slice[1] = {"call", {"self", unpack slice[1][2]}}
|
||||
|
||||
act = if ntype(calling_name) != "value" then "index" else "dot"
|
||||
{"chain", parent_loc, {act, calling_name}, unpack slice}
|
||||
|
||||
-- the metatable holding all the class methods
|
||||
base_name = \init_free_var "base", tbl
|
||||
\stm {"assign", { {"chain", base_name, {"dot", "__index"}} }, { base_name }}
|
||||
|
||||
-- handle super class if there is one
|
||||
\stm {"if", parent_loc,
|
||||
{{"chain", "setmetatable", {"call",
|
||||
{base_name, {"chain", "getmetatable",
|
||||
{"call", {parent_loc}}, {"dot", "__index"}}}}}}}
|
||||
|
||||
-- the class object that is returned
|
||||
cls = {"table", {
|
||||
{"__init", constructor}
|
||||
}}
|
||||
|
||||
-- the class's meta table, gives us call and access to base methods
|
||||
cls_mt = {"table", {
|
||||
{"__index", base_name}
|
||||
{"__call", {"fndef", {{"mt"}, {"..."}}, {}, "slim", {
|
||||
{"raw", ("local self = setmetatable({}, %s)")\format(base_name)}
|
||||
{"chain", "mt.__init", {"call", {"self", "..."}}}
|
||||
"self"
|
||||
}}}
|
||||
}}
|
||||
|
||||
cls_name = \init_free_var "class", {
|
||||
"chain", "setmetatable", {"call", {cls, cls_mt}}
|
||||
}
|
||||
|
||||
\stm {"assign"
|
||||
{{"chain", base_name, {"dot", "__class"}}}
|
||||
{cls_name}
|
||||
}
|
||||
|
||||
\stm {"return", cls_name}
|
||||
|
||||
@stm {"declare", {name}}
|
||||
@line name, " = ", def_scope
|
||||
|
||||
comprehension: (node, action) =>
|
||||
_, exp, clauses = unpack node
|
||||
|
||||
@ -312,3 +231,10 @@ line_compile =
|
||||
\stms block
|
||||
\stm ret var if ret
|
||||
|
||||
run: (code) =>
|
||||
code\call self
|
||||
nil
|
||||
|
||||
group: (node) =>
|
||||
@stms node[2]
|
||||
|
||||
|
@ -2,7 +2,8 @@ module("moonscript.transform", package.seeall)
|
||||
local types = require("moonscript.types")
|
||||
local util = require("moonscript.util")
|
||||
local data = require("moonscript.data")
|
||||
local ntype, build = types.ntype, types.build
|
||||
local ntype, build, smart_node = types.ntype, types.build, types.smart_node
|
||||
local insert = table.insert
|
||||
NameProxy = (function(_parent_0)
|
||||
local _base_0 = {
|
||||
get_name = function(self, scope)
|
||||
@ -11,6 +12,39 @@ NameProxy = (function(_parent_0)
|
||||
end
|
||||
return self.name
|
||||
end,
|
||||
chain = function(self, ...)
|
||||
local items = {
|
||||
...
|
||||
}
|
||||
items = (function()
|
||||
local _accum_0 = { }
|
||||
local _len_0 = 0
|
||||
do
|
||||
local _item_0 = items
|
||||
for _index_0 = 1, #_item_0 do
|
||||
local i = _item_0[_index_0]
|
||||
local _value_0
|
||||
if type(i) == "string" then
|
||||
_value_0 = {
|
||||
"dot",
|
||||
i
|
||||
}
|
||||
else
|
||||
_value_0 = i
|
||||
end
|
||||
if _value_0 ~= nil then
|
||||
_len_0 = _len_0 + 1
|
||||
_accum_0[_len_0] = _value_0
|
||||
end
|
||||
end
|
||||
end
|
||||
return _accum_0
|
||||
end)()
|
||||
return build.chain({
|
||||
base = self,
|
||||
unpack(items)
|
||||
})
|
||||
end,
|
||||
__tostring = function(self)
|
||||
if self.name then
|
||||
return ("name<%s>"):format(self.name)
|
||||
@ -39,7 +73,244 @@ NameProxy = (function(_parent_0)
|
||||
_base_0.__class = _class_0
|
||||
return _class_0
|
||||
end)()
|
||||
local Run
|
||||
Run = (function(_parent_0)
|
||||
local _base_0 = {
|
||||
call = function(self, state)
|
||||
return self.fn(state)
|
||||
end
|
||||
}
|
||||
_base_0.__index = _base_0
|
||||
if _parent_0 then
|
||||
setmetatable(_base_0, getmetatable(_parent_0).__index)
|
||||
end
|
||||
local _class_0 = setmetatable({
|
||||
__init = function(self, fn)
|
||||
self.fn = fn
|
||||
self[1] = "run"
|
||||
end
|
||||
}, {
|
||||
__index = _base_0,
|
||||
__call = function(mt, ...)
|
||||
local self = setmetatable({}, _base_0)
|
||||
mt.__init(self, ...)
|
||||
return self
|
||||
end
|
||||
})
|
||||
_base_0.__class = _class_0
|
||||
return _class_0
|
||||
end)()
|
||||
local constructor_name = "new"
|
||||
local transformers = {
|
||||
class = function(node)
|
||||
local _, name, parent_val, tbl = unpack(node)
|
||||
local constructor = nil
|
||||
local properties = (function()
|
||||
local _accum_0 = { }
|
||||
local _len_0 = 0
|
||||
do
|
||||
local _item_0 = tbl[2]
|
||||
for _index_0 = 1, #_item_0 do
|
||||
local entry = _item_0[_index_0]
|
||||
local _value_0
|
||||
if entry[1] == constructor_name then
|
||||
constructor = entry[2]
|
||||
_value_0 = nil
|
||||
else
|
||||
_value_0 = entry
|
||||
end
|
||||
if _value_0 ~= nil then
|
||||
_len_0 = _len_0 + 1
|
||||
_accum_0[_len_0] = _value_0
|
||||
end
|
||||
end
|
||||
end
|
||||
return _accum_0
|
||||
end)()
|
||||
tbl[2] = properties
|
||||
local parent_cls_name = NameProxy("parent")
|
||||
local base_name = NameProxy("base")
|
||||
local self_name = NameProxy("self")
|
||||
local cls_name = NameProxy("class")
|
||||
if not constructor then
|
||||
constructor = build.fndef({
|
||||
args = {
|
||||
{
|
||||
"..."
|
||||
}
|
||||
},
|
||||
arrow = "fat",
|
||||
body = {
|
||||
build["if"]({
|
||||
cond = parent_cls_name,
|
||||
["then"] = {
|
||||
build.chain({
|
||||
base = "super",
|
||||
{
|
||||
"call",
|
||||
{
|
||||
"..."
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
else
|
||||
smart_node(constructor)
|
||||
constructor.arrow = "fat"
|
||||
end
|
||||
local cls = build.table({
|
||||
{
|
||||
"__init",
|
||||
constructor
|
||||
}
|
||||
})
|
||||
local cls_mt = build.table({
|
||||
{
|
||||
"__index",
|
||||
base_name
|
||||
},
|
||||
{
|
||||
"__call",
|
||||
build.fndef({
|
||||
args = {
|
||||
{
|
||||
"cls"
|
||||
},
|
||||
{
|
||||
"..."
|
||||
}
|
||||
},
|
||||
body = {
|
||||
build.assign_one(self_name, build.chain({
|
||||
base = "setmetatable",
|
||||
{
|
||||
"call",
|
||||
{
|
||||
"{}",
|
||||
base_name
|
||||
}
|
||||
}
|
||||
})),
|
||||
build.chain({
|
||||
base = "cls.__init",
|
||||
{
|
||||
"call",
|
||||
{
|
||||
self_name,
|
||||
"..."
|
||||
}
|
||||
}
|
||||
}),
|
||||
self_name
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
cls = build.chain({
|
||||
base = "setmetatable",
|
||||
{
|
||||
"call",
|
||||
{
|
||||
cls,
|
||||
cls_mt
|
||||
}
|
||||
}
|
||||
})
|
||||
local value = nil
|
||||
do
|
||||
local _with_0 = build
|
||||
value = _with_0.block_exp({
|
||||
Run(function(self)
|
||||
return self:set("super", function(block, chain)
|
||||
local calling_name = block:get("current_block")
|
||||
local slice = (function()
|
||||
local _accum_0 = { }
|
||||
local _len_0 = 0
|
||||
do
|
||||
local _item_0 = chain
|
||||
for _index_0 = 3, #_item_0 do
|
||||
local item = _item_0[_index_0]
|
||||
_len_0 = _len_0 + 1
|
||||
_accum_0[_len_0] = item
|
||||
end
|
||||
end
|
||||
return _accum_0
|
||||
end)()
|
||||
slice[1] = {
|
||||
"call",
|
||||
{
|
||||
"self",
|
||||
unpack(slice[1][2])
|
||||
}
|
||||
}
|
||||
local act
|
||||
if ntype(calling_name) ~= "value" then
|
||||
act = "index"
|
||||
else
|
||||
act = "dot"
|
||||
end
|
||||
return {
|
||||
"chain",
|
||||
parent_cls_name,
|
||||
{
|
||||
act,
|
||||
calling_name
|
||||
},
|
||||
unpack(slice)
|
||||
}
|
||||
end)
|
||||
end),
|
||||
_with_0.assign_one(parent_cls_name, parent_val == "" and "nil" or parent_val),
|
||||
_with_0.assign_one(base_name, tbl),
|
||||
_with_0.assign_one(base_name:chain("__index"), base_name),
|
||||
build["if"]({
|
||||
cond = parent_cls_name,
|
||||
["then"] = {
|
||||
_with_0.chain({
|
||||
base = "setmetatable",
|
||||
{
|
||||
"call",
|
||||
{
|
||||
base_name,
|
||||
_with_0.chain({
|
||||
base = "getmetatable",
|
||||
{
|
||||
"call",
|
||||
{
|
||||
parent_cls_name
|
||||
}
|
||||
},
|
||||
{
|
||||
"dot",
|
||||
"__index"
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}),
|
||||
_with_0.assign_one(cls_name, cls),
|
||||
_with_0.assign_one(base_name:chain("__class"), cls_name),
|
||||
cls_name
|
||||
})
|
||||
value = _with_0.group({
|
||||
_with_0.assign_one(name),
|
||||
_with_0.assign({
|
||||
names = {
|
||||
name
|
||||
},
|
||||
values = {
|
||||
value
|
||||
}
|
||||
})
|
||||
})
|
||||
end
|
||||
return value
|
||||
end,
|
||||
chain = function(node)
|
||||
local stub = node[#node]
|
||||
if type(stub) == "table" and stub[1] == "colon_stub" then
|
||||
|
@ -5,7 +5,8 @@ types = require "moonscript.types"
|
||||
util = require "moonscript.util"
|
||||
data = require "moonscript.data"
|
||||
|
||||
import ntype, build from types
|
||||
import ntype, build, smart_node from types
|
||||
import insert from table
|
||||
|
||||
export node, NameProxy
|
||||
|
||||
@ -18,13 +19,144 @@ class NameProxy
|
||||
@name = scope\free_name @prefix, true
|
||||
@name
|
||||
|
||||
chain: (...) =>
|
||||
items = {...} -- todo: fix ... propagation
|
||||
items = for i in *items
|
||||
if type(i) == "string"
|
||||
{"dot", i}
|
||||
else
|
||||
i
|
||||
|
||||
build.chain {
|
||||
base: self
|
||||
unpack items
|
||||
}
|
||||
|
||||
__tostring: =>
|
||||
if @name
|
||||
("name<%s>")\format @name
|
||||
else
|
||||
("name<prefix(%s)>")\format @prefix
|
||||
|
||||
class Run
|
||||
new: (@fn) =>
|
||||
self[1] = "run"
|
||||
|
||||
call: (state) =>
|
||||
self.fn state
|
||||
|
||||
constructor_name = "new"
|
||||
|
||||
transformers = {
|
||||
class: (node) ->
|
||||
_, name, parent_val, tbl = unpack node
|
||||
|
||||
constructor = nil
|
||||
properties = for entry in *tbl[2]
|
||||
if entry[1] == constructor_name
|
||||
constructor = entry[2]
|
||||
nil
|
||||
else
|
||||
entry
|
||||
|
||||
tbl[2] = properties
|
||||
|
||||
parent_cls_name = NameProxy "parent"
|
||||
base_name = NameProxy "base"
|
||||
self_name = NameProxy "self"
|
||||
cls_name = NameProxy "class"
|
||||
|
||||
if not constructor
|
||||
constructor = build.fndef {
|
||||
args: {{"..."}}
|
||||
arrow: "fat"
|
||||
body: {
|
||||
build["if"] {
|
||||
cond: parent_cls_name
|
||||
then: {
|
||||
build.chain { base: "super", {"call", {"..."}} }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
smart_node constructor
|
||||
constructor.arrow = "fat"
|
||||
|
||||
cls = build.table {
|
||||
{"__init", constructor}
|
||||
}
|
||||
|
||||
cls_mt = build.table {
|
||||
{"__index", base_name}
|
||||
{"__call", build.fndef {
|
||||
args: {{"cls"}, {"..."}}
|
||||
body: {
|
||||
build.assign_one self_name, build.chain {
|
||||
base: "setmetatable"
|
||||
{"call", {"{}", base_name}}
|
||||
}
|
||||
build.chain {
|
||||
base: "cls.__init"
|
||||
{"call", {self_name, "..."}}
|
||||
}
|
||||
self_name
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
||||
cls = build.chain {
|
||||
base: "setmetatable"
|
||||
{"call", {cls, cls_mt}}
|
||||
}
|
||||
|
||||
value = nil
|
||||
with build
|
||||
value = .block_exp {
|
||||
Run =>
|
||||
@set "super", (block, chain) ->
|
||||
calling_name = block\get"current_block"
|
||||
slice = [item for item in *chain[3:]]
|
||||
-- inject self
|
||||
slice[1] = {"call", {"self", unpack slice[1][2]}}
|
||||
|
||||
act = if ntype(calling_name) != "value" then "index" else "dot"
|
||||
{"chain", parent_cls_name, {act, calling_name}, unpack slice}
|
||||
|
||||
.assign_one parent_cls_name, parent_val == "" and "nil" or parent_val
|
||||
.assign_one base_name, tbl
|
||||
.assign_one base_name\chain"__index", base_name
|
||||
|
||||
build["if"] {
|
||||
cond: parent_cls_name
|
||||
then: {
|
||||
.chain {
|
||||
base: "setmetatable"
|
||||
{"call", {base_name, .chain {
|
||||
base: "getmetatable"
|
||||
{"call", {parent_cls_name}}
|
||||
{"dot", "__index"}
|
||||
}}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.assign_one cls_name, cls
|
||||
.assign_one base_name\chain"__class", cls_name
|
||||
|
||||
cls_name
|
||||
}
|
||||
|
||||
value = .group {
|
||||
.assign_one name
|
||||
.assign {
|
||||
names: {name}
|
||||
values: {value}
|
||||
}
|
||||
}
|
||||
|
||||
value
|
||||
|
||||
-- pull out colon chain
|
||||
chain: (node) ->
|
||||
stub = node[#node]
|
||||
|
@ -38,6 +38,16 @@ local node_types = {
|
||||
"values",
|
||||
t
|
||||
}
|
||||
},
|
||||
["if"] = {
|
||||
{
|
||||
"cond",
|
||||
t
|
||||
},
|
||||
{
|
||||
"then",
|
||||
t
|
||||
}
|
||||
}
|
||||
}
|
||||
local build_table
|
||||
@ -85,6 +95,28 @@ make_builder = function(name)
|
||||
end
|
||||
build = nil
|
||||
build = setmetatable({
|
||||
group = function(body)
|
||||
return {
|
||||
"group",
|
||||
body
|
||||
}
|
||||
end,
|
||||
assign_one = function(name, value)
|
||||
return build.assign({
|
||||
names = {
|
||||
name
|
||||
},
|
||||
values = {
|
||||
value
|
||||
}
|
||||
})
|
||||
end,
|
||||
table = function(tbl)
|
||||
return {
|
||||
"table",
|
||||
tbl
|
||||
}
|
||||
end,
|
||||
block_exp = function(body)
|
||||
local fn = build.fndef({
|
||||
body = body
|
||||
|
@ -26,6 +26,10 @@ node_types = {
|
||||
{"names", t}
|
||||
{"values", t}
|
||||
}
|
||||
if: {
|
||||
{"cond", t}
|
||||
{"then", t}
|
||||
}
|
||||
}
|
||||
|
||||
build_table = ->
|
||||
@ -55,6 +59,15 @@ make_builder = (name) ->
|
||||
|
||||
build = nil
|
||||
build = setmetatable {
|
||||
group: (body) ->
|
||||
{"group", body}
|
||||
assign_one: (name, value) ->
|
||||
build.assign {
|
||||
names: {name}
|
||||
values: {value}
|
||||
}
|
||||
table: (tbl) ->
|
||||
{"table", tbl}
|
||||
block_exp: (body) ->
|
||||
fn = build.fndef body: body
|
||||
build.chain { base: {"parens", fn}, {"call", {}} }
|
||||
|
@ -1,5 +1,6 @@
|
||||
local Hello
|
||||
Hello = (function(_parent_0)
|
||||
Hello = (function()
|
||||
local _parent_0 = nil
|
||||
local _base_0 = {
|
||||
hello = function(self)
|
||||
return print(self.test, self.world)
|
||||
@ -19,10 +20,10 @@ Hello = (function(_parent_0)
|
||||
end
|
||||
}, {
|
||||
__index = _base_0,
|
||||
__call = function(mt, ...)
|
||||
local self = setmetatable({}, _base_0)
|
||||
mt.__init(self, ...)
|
||||
return self
|
||||
__call = function(cls, ...)
|
||||
local _self_0 = setmetatable({}, _base_0)
|
||||
cls.__init(_self_0, ...)
|
||||
return _self_0
|
||||
end
|
||||
})
|
||||
_base_0.__class = _class_0
|
||||
@ -32,7 +33,8 @@ local x = Hello(1, 2)
|
||||
x:hello()
|
||||
print(x)
|
||||
local Simple
|
||||
Simple = (function(_parent_0)
|
||||
Simple = (function()
|
||||
local _parent_0 = nil
|
||||
local _base_0 = {
|
||||
cool = function(self)
|
||||
return print("cool")
|
||||
@ -50,17 +52,18 @@ Simple = (function(_parent_0)
|
||||
end
|
||||
}, {
|
||||
__index = _base_0,
|
||||
__call = function(mt, ...)
|
||||
local self = setmetatable({}, _base_0)
|
||||
mt.__init(self, ...)
|
||||
return self
|
||||
__call = function(cls, ...)
|
||||
local _self_0 = setmetatable({}, _base_0)
|
||||
cls.__init(_self_0, ...)
|
||||
return _self_0
|
||||
end
|
||||
})
|
||||
_base_0.__class = _class_0
|
||||
return _class_0
|
||||
end)()
|
||||
local Yikes
|
||||
Yikes = (function(_parent_0)
|
||||
Yikes = (function()
|
||||
local _parent_0 = Simple
|
||||
local _base_0 = { }
|
||||
_base_0.__index = _base_0
|
||||
if _parent_0 then
|
||||
@ -72,19 +75,20 @@ Yikes = (function(_parent_0)
|
||||
end
|
||||
}, {
|
||||
__index = _base_0,
|
||||
__call = function(mt, ...)
|
||||
local self = setmetatable({}, _base_0)
|
||||
mt.__init(self, ...)
|
||||
return self
|
||||
__call = function(cls, ...)
|
||||
local _self_0 = setmetatable({}, _base_0)
|
||||
cls.__init(_self_0, ...)
|
||||
return _self_0
|
||||
end
|
||||
})
|
||||
_base_0.__class = _class_0
|
||||
return _class_0
|
||||
end)(Simple)
|
||||
end)()
|
||||
x = Yikes()
|
||||
x:cool()
|
||||
local Hi
|
||||
Hi = (function(_parent_0)
|
||||
Hi = (function()
|
||||
local _parent_0 = nil
|
||||
local _base_0 = {
|
||||
cool = function(self, num)
|
||||
return print("num", num)
|
||||
@ -100,16 +104,18 @@ Hi = (function(_parent_0)
|
||||
end
|
||||
}, {
|
||||
__index = _base_0,
|
||||
__call = function(mt, ...)
|
||||
local self = setmetatable({}, _base_0)
|
||||
mt.__init(self, ...)
|
||||
return self
|
||||
__call = function(cls, ...)
|
||||
local _self_0 = setmetatable({}, _base_0)
|
||||
cls.__init(_self_0, ...)
|
||||
return _self_0
|
||||
end
|
||||
})
|
||||
_base_0.__class = _class_0
|
||||
return _class_0
|
||||
end)()
|
||||
Simple = (function(_parent_0)
|
||||
Simple =
|
||||
Simple = (function()
|
||||
local _parent_0 = Hi
|
||||
local _base_0 = {
|
||||
cool = function(self)
|
||||
return _parent_0.cool(self, 120302)
|
||||
@ -125,20 +131,21 @@ Simple = (function(_parent_0)
|
||||
end
|
||||
}, {
|
||||
__index = _base_0,
|
||||
__call = function(mt, ...)
|
||||
local self = setmetatable({}, _base_0)
|
||||
mt.__init(self, ...)
|
||||
return self
|
||||
__call = function(cls, ...)
|
||||
local _self_0 = setmetatable({}, _base_0)
|
||||
cls.__init(_self_0, ...)
|
||||
return _self_0
|
||||
end
|
||||
})
|
||||
_base_0.__class = _class_0
|
||||
return _class_0
|
||||
end)(Hi)
|
||||
end)()
|
||||
x = Simple()
|
||||
x:cool()
|
||||
print(x.__class == Simple)
|
||||
local Okay
|
||||
Okay = (function(_parent_0)
|
||||
Okay = (function()
|
||||
local _parent_0 = nil
|
||||
local _base_0 = {
|
||||
something = 20323
|
||||
}
|
||||
@ -154,10 +161,10 @@ Okay = (function(_parent_0)
|
||||
end
|
||||
}, {
|
||||
__index = _base_0,
|
||||
__call = function(mt, ...)
|
||||
local self = setmetatable({}, _base_0)
|
||||
mt.__init(self, ...)
|
||||
return self
|
||||
__call = function(cls, ...)
|
||||
local _self_0 = setmetatable({}, _base_0)
|
||||
cls.__init(_self_0, ...)
|
||||
return _self_0
|
||||
end
|
||||
})
|
||||
_base_0.__class = _class_0
|
||||
|
Loading…
Reference in New Issue
Block a user