Skip to content

Commit 5f08b2f

Browse files
committed
transformers are instanced for for root blocks
1 parent 44167c3 commit 5f08b2f

File tree

4 files changed

+156
-108
lines changed

4 files changed

+156
-108
lines changed

moonscript/compile.lua

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ Block = (function()
317317
return self:value(node)
318318
end,
319319
value = function(self, node, ...)
320-
node = transform.Value(node)
320+
node = self.root.transform.value(node)
321321
local action
322322
if type(node) ~= "table" then
323323
action = "raw_value"
@@ -353,7 +353,7 @@ Block = (function()
353353
if not node then
354354
return
355355
end
356-
node = transform.Statement(node)
356+
node = self.root.transform.statement(node)
357357
local fn = line_compile[ntype(node)]
358358
if not fn then
359359
if has_value(node) then
@@ -403,6 +403,7 @@ Block = (function()
403403
self._names = { }
404404
self._state = { }
405405
if self.parent then
406+
self.root = self.parent.root
406407
self.indent = self.parent.indent + 1
407408
return setmetatable(self._state, {
408409
__index = self.parent._state
@@ -426,6 +427,9 @@ local RootBlock
426427
RootBlock = (function()
427428
local _parent_0 = Block
428429
local _base_0 = {
430+
__tostring = function(self)
431+
return "RootBlock<>"
432+
end,
429433
render = function(self)
430434
self:_insert_breaks()
431435
return concat(self._lines, "\n")
@@ -437,9 +441,12 @@ RootBlock = (function()
437441
end
438442
local _class_0 = setmetatable({
439443
__init = function(self, ...)
440-
if _parent_0 then
441-
return _parent_0.__init(self, ...)
442-
end
444+
self.root = self
445+
self.transform = {
446+
value = transform.Value:instance(self),
447+
statement = transform.Statement:instance(self)
448+
}
449+
return _parent_0.__init(self, ...)
443450
end
444451
}, {
445452
__index = _base_0,

moonscript/compile.moon

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class Block
6464
@_state = {}
6565

6666
if @parent
67+
@root = @parent.root
6768
@indent = @parent.indent + 1
6869
setmetatable @_state, { __index: @parent._state }
6970
else
@@ -226,7 +227,7 @@ class Block
226227
-- line wise compile functions
227228
name: (node) => @value node
228229
value: (node, ...) =>
229-
node = transform.Value node
230+
node = @root.transform.value node
230231
action = if type(node) != "table"
231232
"raw_value"
232233
else
@@ -244,7 +245,7 @@ class Block
244245

245246
stm: (node, ...) =>
246247
return if not node -- slip blank statements
247-
node = transform.Statement node
248+
node = @root.transform.statement node
248249
fn = line_compile[ntype(node)]
249250
if not fn
250251
-- coerce value into statement
@@ -264,6 +265,16 @@ class Block
264265
nil
265266

266267
class RootBlock extends Block
268+
new: (...) =>
269+
@root = self
270+
@transform = {
271+
value: transform.Value\instance self
272+
statement: transform.Statement\instance self
273+
}
274+
super ...
275+
276+
__tostring: => "RootBlock<>"
277+
267278
render: =>
268279
@_insert_breaks!
269280
concat @_lines, "\n"

moonscript/transform.lua

Lines changed: 75 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ local ntype, build, smart_node, is_slice = types.ntype, types.build, types.smart
77
local insert = table.insert
88
local is_value
99
is_value = function(stm)
10-
return moonscript.compile.Block:is_value(stm) or Value.can_transform(stm)
10+
return moonscript.compile.Block:is_value(stm) or Value:can_transform(stm)
1111
end
1212
NameProxy = (function()
1313
local _parent_0 = nil
@@ -154,43 +154,63 @@ is_singular = function(body)
154154
end
155155
local constructor_name = "new"
156156
local Transformer
157-
Transformer = function(transformers)
158-
local seen_nodes = { }
159-
local tf = {
160-
transform = function(n, ...)
161-
if seen_nodes[n] then
162-
return n
157+
Transformer = (function()
158+
local _parent_0 = nil
159+
local _base_0 = {
160+
transform = function(self, scope, node, ...)
161+
if self.seen_nodes[node] then
162+
return node
163163
end
164-
seen_nodes[n] = true
164+
self.seen_nodes[node] = true
165165
while true do
166-
local transformer = transformers[ntype(n)]
166+
local transformer = self.transformers[ntype(node)]
167167
local res
168168
if transformer then
169-
res = transformer(n, ...) or n
169+
res = transformer(scope, node, ...) or node
170170
else
171-
res = n
171+
res = node
172172
end
173-
if res == n then
174-
return n
173+
if res == node then
174+
return node
175175
end
176-
n = res
176+
node = res
177177
end
178178
end,
179-
can_transform = function(node)
180-
return transformers[ntype(node)] ~= nil
179+
__call = function(self, node, ...)
180+
return self:transform(self.scope, node, ...)
181+
end,
182+
instance = function(self, scope)
183+
return Transformer(self.transformers, scope)
184+
end,
185+
can_transform = function(self, node)
186+
return self.transformers[ntype(node)] ~= nil
181187
end
182188
}
183-
return setmetatable(tf, {
184-
__call = function(self, ...)
185-
return self.transform(...)
189+
_base_0.__index = _base_0
190+
if _parent_0 then
191+
setmetatable(_base_0, getmetatable(_parent_0).__index)
192+
end
193+
local _class_0 = setmetatable({
194+
__init = function(self, transformers, scope)
195+
self.transformers, self.scope = transformers, scope
196+
self.seen_nodes = { }
197+
end
198+
}, {
199+
__index = _base_0,
200+
__call = function(cls, ...)
201+
local _self_0 = setmetatable({}, _base_0)
202+
cls.__init(_self_0, ...)
203+
return _self_0
186204
end
187205
})
188-
end
206+
_base_0.__class = _class_0
207+
return _class_0
208+
end)()
189209
Statement = Transformer({
190-
assign = function(node)
210+
assign = function(self, node)
191211
local _, names, values = unpack(node)
192212
if #values == 1 and types.cascading[ntype(values[1])] then
193-
values[1] = Statement(values[1], function(stm)
213+
values[1] = self.transform.statement(values[1], function(stm)
194214
local t = ntype(stm)
195215
if is_value(stm) then
196216
return {
@@ -215,7 +235,7 @@ Statement = Transformer({
215235
return node
216236
end
217237
end,
218-
export = function(node)
238+
export = function(self, node)
219239
if #node > 2 then
220240
if node[2] == "class" then
221241
local cls = smart_node(node[3])
@@ -241,7 +261,7 @@ Statement = Transformer({
241261
return nil
242262
end
243263
end,
244-
update = function(node)
264+
update = function(self, node)
245265
local _, name, op, exp = unpack(node)
246266
local op_final = op:match("^(.+)=$")
247267
if not op_final then
@@ -254,7 +274,7 @@ Statement = Transformer({
254274
exp
255275
})
256276
end,
257-
import = function(node)
277+
import = function(self, node)
258278
local _, names, source = unpack(node)
259279
local stubs = (function()
260280
local _accum_0 = { }
@@ -340,7 +360,7 @@ Statement = Transformer({
340360
})
341361
end
342362
end,
343-
comprehension = function(node, action)
363+
comprehension = function(self, node, action)
344364
local _, exp, clauses = unpack(node)
345365
action = action or function(exp)
346366
return {
@@ -376,7 +396,7 @@ Statement = Transformer({
376396
end
377397
return current_stms[1]
378398
end,
379-
["if"] = function(node, ret)
399+
["if"] = function(self, node, ret)
380400
if ret then
381401
smart_node(node)
382402
node['then'] = apply_to_last(node['then'], ret)
@@ -388,7 +408,7 @@ Statement = Transformer({
388408
end
389409
return node
390410
end,
391-
with = function(node, ret)
411+
with = function(self, node, ret)
392412
local _, exp, block = unpack(node)
393413
local scope_name = NameProxy("with")
394414
return build["do"]({
@@ -404,7 +424,7 @@ Statement = Transformer({
404424
end)()
405425
})
406426
end,
407-
foreach = function(node)
427+
foreach = function(self, node)
408428
smart_node(node)
409429
if ntype(node.iter) == "unpack" then
410430
local list = node.iter[2]
@@ -470,7 +490,7 @@ Statement = Transformer({
470490
})
471491
end
472492
end,
473-
class = function(node)
493+
class = function(self, node)
474494
local _, name, parent_val, tbl = unpack(node)
475495
local constructor = nil
476496
local properties = (function()
@@ -766,58 +786,62 @@ Accumulator = (function()
766786
return _class_0
767787
end)()
768788
local default_accumulator
769-
default_accumulator = function(node)
789+
default_accumulator = function(self, node)
770790
return Accumulator():convert(node)
771791
end
772792
local implicitly_return
773-
implicitly_return = function(stm)
774-
local t = ntype(stm)
775-
if types.manual_return[t] or not is_value(stm) then
776-
return stm
777-
elseif types.cascading[t] then
778-
return Statement(stm, implicitly_return)
779-
else
780-
return {
781-
"return",
782-
stm
783-
}
793+
implicitly_return = function(scope)
794+
local fn
795+
fn = function(stm)
796+
local t = ntype(stm)
797+
if types.manual_return[t] or not is_value(stm) then
798+
return stm
799+
elseif types.cascading[t] then
800+
return scope.transform.statement(stm, fn)
801+
else
802+
return {
803+
"return",
804+
stm
805+
}
806+
end
784807
end
808+
return fn
785809
end
786810
Value = Transformer({
787811
["for"] = default_accumulator,
788812
["while"] = default_accumulator,
789813
foreach = default_accumulator,
790-
comprehension = function(node)
814+
comprehension = function(self, node)
791815
local a = Accumulator()
792-
node = Statement(node, function(exp)
816+
node = self.transform.statement(node, function(exp)
793817
return a:mutate_body({
794818
exp
795819
}, false)
796820
end)
797821
return a:wrap(node)
798822
end,
799-
fndef = function(node)
823+
fndef = function(self, node)
800824
smart_node(node)
801-
node.body = apply_to_last(node.body, implicitly_return)
825+
node.body = apply_to_last(node.body, implicitly_return(self))
802826
return node
803827
end,
804-
["if"] = function(node)
828+
["if"] = function(self, node)
805829
return build.block_exp({
806830
node
807831
})
808832
end,
809-
with = function(node)
833+
with = function(self, node)
810834
return build.block_exp({
811835
node
812836
})
813837
end,
814-
chain = function(node)
838+
chain = function(self, node)
815839
local stub = node[#node]
816840
if type(stub) == "table" and stub[1] == "colon_stub" then
817841
table.remove(node, #node)
818842
local base_name = NameProxy("base")
819843
local fn_name = NameProxy("fn")
820-
return Value(build.block_exp({
844+
return self.transform.value(build.block_exp({
821845
build.assign({
822846
names = {
823847
base_name
@@ -862,7 +886,7 @@ Value = Transformer({
862886
}))
863887
end
864888
end,
865-
block_exp = function(node)
889+
block_exp = function(self, node)
866890
local _, body = unpack(node)
867891
local fn = nil
868892
local arg_list = { }

0 commit comments

Comments
 (0)