rufus-lua-moon 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1174 @@
1
+ module("moonscript.transform", package.seeall)
2
+ local types = require("moonscript.types")
3
+ local util = require("moonscript.util")
4
+ local data = require("moonscript.data")
5
+ local reversed = util.reversed
6
+ local ntype, build, smart_node, is_slice = types.ntype, types.build, types.smart_node, types.is_slice
7
+ local insert = table.insert
8
+ LocalName = (function()
9
+ local _parent_0 = nil
10
+ local _base_0 = {
11
+ get_name = function(self)
12
+ return self.name
13
+ end
14
+ }
15
+ _base_0.__index = _base_0
16
+ if _parent_0 then
17
+ setmetatable(_base_0, _parent_0.__base)
18
+ end
19
+ local _class_0 = setmetatable({
20
+ __init = function(self, name)
21
+ self.name = name
22
+ self[1] = "temp_name"
23
+ end,
24
+ __base = _base_0,
25
+ __name = "LocalName",
26
+ __parent = _parent_0
27
+ }, {
28
+ __index = function(cls, name)
29
+ local val = rawget(_base_0, name)
30
+ if val == nil and _parent_0 then
31
+ return _parent_0[name]
32
+ else
33
+ return val
34
+ end
35
+ end,
36
+ __call = function(cls, ...)
37
+ local _self_0 = setmetatable({}, _base_0)
38
+ cls.__init(_self_0, ...)
39
+ return _self_0
40
+ end
41
+ })
42
+ _base_0.__class = _class_0
43
+ return _class_0
44
+ end)()
45
+ NameProxy = (function()
46
+ local _parent_0 = nil
47
+ local _base_0 = {
48
+ get_name = function(self, scope)
49
+ if not self.name then
50
+ self.name = scope:free_name(self.prefix, true)
51
+ end
52
+ return self.name
53
+ end,
54
+ chain = function(self, ...)
55
+ local items = {
56
+ ...
57
+ }
58
+ items = (function()
59
+ local _accum_0 = { }
60
+ local _len_0 = 0
61
+ local _list_0 = items
62
+ for _index_0 = 1, #_list_0 do
63
+ local i = _list_0[_index_0]
64
+ local _value_0
65
+ if type(i) == "string" then
66
+ _value_0 = {
67
+ "dot",
68
+ i
69
+ }
70
+ else
71
+ _value_0 = i
72
+ end
73
+ if _value_0 ~= nil then
74
+ _len_0 = _len_0 + 1
75
+ _accum_0[_len_0] = _value_0
76
+ end
77
+ end
78
+ return _accum_0
79
+ end)()
80
+ return build.chain({
81
+ base = self,
82
+ unpack(items)
83
+ })
84
+ end,
85
+ index = function(self, key)
86
+ return build.chain({
87
+ base = self,
88
+ {
89
+ "index",
90
+ key
91
+ }
92
+ })
93
+ end,
94
+ __tostring = function(self)
95
+ if self.name then
96
+ return ("name<%s>"):format(self.name)
97
+ else
98
+ return ("name<prefix(%s)>"):format(self.prefix)
99
+ end
100
+ end
101
+ }
102
+ _base_0.__index = _base_0
103
+ if _parent_0 then
104
+ setmetatable(_base_0, _parent_0.__base)
105
+ end
106
+ local _class_0 = setmetatable({
107
+ __init = function(self, prefix)
108
+ self.prefix = prefix
109
+ self[1] = "temp_name"
110
+ end,
111
+ __base = _base_0,
112
+ __name = "NameProxy",
113
+ __parent = _parent_0
114
+ }, {
115
+ __index = function(cls, name)
116
+ local val = rawget(_base_0, name)
117
+ if val == nil and _parent_0 then
118
+ return _parent_0[name]
119
+ else
120
+ return val
121
+ end
122
+ end,
123
+ __call = function(cls, ...)
124
+ local _self_0 = setmetatable({}, _base_0)
125
+ cls.__init(_self_0, ...)
126
+ return _self_0
127
+ end
128
+ })
129
+ _base_0.__class = _class_0
130
+ return _class_0
131
+ end)()
132
+ Run = (function()
133
+ local _parent_0 = nil
134
+ local _base_0 = {
135
+ call = function(self, state)
136
+ return self.fn(state)
137
+ end
138
+ }
139
+ _base_0.__index = _base_0
140
+ if _parent_0 then
141
+ setmetatable(_base_0, _parent_0.__base)
142
+ end
143
+ local _class_0 = setmetatable({
144
+ __init = function(self, fn)
145
+ self.fn = fn
146
+ self[1] = "run"
147
+ end,
148
+ __base = _base_0,
149
+ __name = "Run",
150
+ __parent = _parent_0
151
+ }, {
152
+ __index = function(cls, name)
153
+ local val = rawget(_base_0, name)
154
+ if val == nil and _parent_0 then
155
+ return _parent_0[name]
156
+ else
157
+ return val
158
+ end
159
+ end,
160
+ __call = function(cls, ...)
161
+ local _self_0 = setmetatable({}, _base_0)
162
+ cls.__init(_self_0, ...)
163
+ return _self_0
164
+ end
165
+ })
166
+ _base_0.__class = _class_0
167
+ return _class_0
168
+ end)()
169
+ local apply_to_last
170
+ apply_to_last = function(stms, fn)
171
+ local last_exp_id = 0
172
+ for i = #stms, 1, -1 do
173
+ local stm = stms[i]
174
+ if stm and util.moon.type(stm) ~= Run then
175
+ last_exp_id = i
176
+ break
177
+ end
178
+ end
179
+ return (function()
180
+ local _accum_0 = { }
181
+ local _len_0 = 0
182
+ for i, stm in ipairs(stms) do
183
+ local _value_0
184
+ if i == last_exp_id then
185
+ _value_0 = fn(stm)
186
+ else
187
+ _value_0 = stm
188
+ end
189
+ if _value_0 ~= nil then
190
+ _len_0 = _len_0 + 1
191
+ _accum_0[_len_0] = _value_0
192
+ end
193
+ end
194
+ return _accum_0
195
+ end)()
196
+ end
197
+ local is_singular
198
+ is_singular = function(body)
199
+ if #body ~= 1 then
200
+ return false
201
+ end
202
+ if "group" == ntype(body) then
203
+ return is_singular(body[2])
204
+ else
205
+ return true
206
+ end
207
+ end
208
+ local constructor_name = "new"
209
+ local Transformer
210
+ Transformer = (function()
211
+ local _parent_0 = nil
212
+ local _base_0 = {
213
+ transform = function(self, scope, node, ...)
214
+ if self.seen_nodes[node] then
215
+ return node
216
+ end
217
+ self.seen_nodes[node] = true
218
+ while true do
219
+ local transformer = self.transformers[ntype(node)]
220
+ local res
221
+ if transformer then
222
+ res = transformer(scope, node, ...) or node
223
+ else
224
+ res = node
225
+ end
226
+ if res == node then
227
+ return node
228
+ end
229
+ node = res
230
+ end
231
+ end,
232
+ __call = function(self, node, ...)
233
+ return self:transform(self.scope, node, ...)
234
+ end,
235
+ instance = function(self, scope)
236
+ return Transformer(self.transformers, scope)
237
+ end,
238
+ can_transform = function(self, node)
239
+ return self.transformers[ntype(node)] ~= nil
240
+ end
241
+ }
242
+ _base_0.__index = _base_0
243
+ if _parent_0 then
244
+ setmetatable(_base_0, _parent_0.__base)
245
+ end
246
+ local _class_0 = setmetatable({
247
+ __init = function(self, transformers, scope)
248
+ self.transformers, self.scope = transformers, scope
249
+ self.seen_nodes = { }
250
+ end,
251
+ __base = _base_0,
252
+ __name = "Transformer",
253
+ __parent = _parent_0
254
+ }, {
255
+ __index = function(cls, name)
256
+ local val = rawget(_base_0, name)
257
+ if val == nil and _parent_0 then
258
+ return _parent_0[name]
259
+ else
260
+ return val
261
+ end
262
+ end,
263
+ __call = function(cls, ...)
264
+ local _self_0 = setmetatable({}, _base_0)
265
+ cls.__init(_self_0, ...)
266
+ return _self_0
267
+ end
268
+ })
269
+ _base_0.__class = _class_0
270
+ return _class_0
271
+ end)()
272
+ local construct_comprehension
273
+ construct_comprehension = function(inner, clauses)
274
+ local current_stms = inner
275
+ for _, clause in reversed(clauses) do
276
+ local t = clause[1]
277
+ if t == "for" then
278
+ local _, names, iter = unpack(clause)
279
+ current_stms = {
280
+ "foreach",
281
+ names,
282
+ iter,
283
+ current_stms
284
+ }
285
+ elseif t == "when" then
286
+ local _, cond = unpack(clause)
287
+ current_stms = {
288
+ "if",
289
+ cond,
290
+ current_stms
291
+ }
292
+ else
293
+ current_stms = error("Unknown comprehension clause: " .. t)
294
+ end
295
+ current_stms = {
296
+ current_stms
297
+ }
298
+ end
299
+ return current_stms[1]
300
+ end
301
+ Statement = Transformer({
302
+ assign = function(self, node)
303
+ local _, names, values = unpack(node)
304
+ if #values == 1 and types.cascading[ntype(values[1])] then
305
+ values[1] = self.transform.statement(values[1], function(stm)
306
+ local t = ntype(stm)
307
+ if types.is_value(stm) then
308
+ return {
309
+ "assign",
310
+ names,
311
+ {
312
+ stm
313
+ }
314
+ }
315
+ else
316
+ return stm
317
+ end
318
+ end)
319
+ return build.group({
320
+ {
321
+ "declare",
322
+ names
323
+ },
324
+ values[1]
325
+ })
326
+ else
327
+ return node
328
+ end
329
+ end,
330
+ export = function(self, node)
331
+ if #node > 2 then
332
+ if node[2] == "class" then
333
+ local cls = smart_node(node[3])
334
+ return build.group({
335
+ {
336
+ "export",
337
+ {
338
+ cls.name
339
+ }
340
+ },
341
+ cls
342
+ })
343
+ else
344
+ return build.group({
345
+ node,
346
+ build.assign({
347
+ names = node[2],
348
+ values = node[3]
349
+ })
350
+ })
351
+ end
352
+ else
353
+ return nil
354
+ end
355
+ end,
356
+ update = function(self, node)
357
+ local _, name, op, exp = unpack(node)
358
+ local op_final = op:match("^(.+)=$")
359
+ if not op_final then
360
+ error("Unknown op: " .. op)
361
+ end
362
+ return build.assign_one(name, {
363
+ "exp",
364
+ name,
365
+ op_final,
366
+ exp
367
+ })
368
+ end,
369
+ import = function(self, node)
370
+ local _, names, source = unpack(node)
371
+ local stubs = (function()
372
+ local _accum_0 = { }
373
+ local _len_0 = 0
374
+ local _list_0 = names
375
+ for _index_0 = 1, #_list_0 do
376
+ local name = _list_0[_index_0]
377
+ local _value_0
378
+ if type(name) == "table" then
379
+ _value_0 = name
380
+ else
381
+ _value_0 = {
382
+ "dot",
383
+ name
384
+ }
385
+ end
386
+ if _value_0 ~= nil then
387
+ _len_0 = _len_0 + 1
388
+ _accum_0[_len_0] = _value_0
389
+ end
390
+ end
391
+ return _accum_0
392
+ end)()
393
+ local real_names = (function()
394
+ local _accum_0 = { }
395
+ local _len_0 = 0
396
+ local _list_0 = names
397
+ for _index_0 = 1, #_list_0 do
398
+ local name = _list_0[_index_0]
399
+ local _value_0 = type(name) == "table" and name[2] or name
400
+ if _value_0 ~= nil then
401
+ _len_0 = _len_0 + 1
402
+ _accum_0[_len_0] = _value_0
403
+ end
404
+ end
405
+ return _accum_0
406
+ end)()
407
+ if type(source) == "string" then
408
+ return build.assign({
409
+ names = real_names,
410
+ values = (function()
411
+ local _accum_0 = { }
412
+ local _len_0 = 0
413
+ local _list_0 = stubs
414
+ for _index_0 = 1, #_list_0 do
415
+ local stub = _list_0[_index_0]
416
+ _len_0 = _len_0 + 1
417
+ _accum_0[_len_0] = build.chain({
418
+ base = source,
419
+ stub
420
+ })
421
+ end
422
+ return _accum_0
423
+ end)()
424
+ })
425
+ else
426
+ local source_name = NameProxy("table")
427
+ return build.group({
428
+ {
429
+ "declare",
430
+ real_names
431
+ },
432
+ build["do"]({
433
+ build.assign_one(source_name, source),
434
+ build.assign({
435
+ names = real_names,
436
+ values = (function()
437
+ local _accum_0 = { }
438
+ local _len_0 = 0
439
+ local _list_0 = stubs
440
+ for _index_0 = 1, #_list_0 do
441
+ local stub = _list_0[_index_0]
442
+ _len_0 = _len_0 + 1
443
+ _accum_0[_len_0] = build.chain({
444
+ base = source_name,
445
+ stub
446
+ })
447
+ end
448
+ return _accum_0
449
+ end)()
450
+ })
451
+ })
452
+ })
453
+ end
454
+ end,
455
+ comprehension = function(self, node, action)
456
+ local _, exp, clauses = unpack(node)
457
+ action = action or function(exp)
458
+ return {
459
+ exp
460
+ }
461
+ end
462
+ return construct_comprehension(action(exp), clauses)
463
+ end,
464
+ ["if"] = function(self, node, ret)
465
+ if ret then
466
+ smart_node(node)
467
+ node['then'] = apply_to_last(node['then'], ret)
468
+ for i = 4, #node do
469
+ local case = node[i]
470
+ local body_idx = #node[i]
471
+ case[body_idx] = apply_to_last(case[body_idx], ret)
472
+ end
473
+ end
474
+ return node
475
+ end,
476
+ with = function(self, node, ret)
477
+ local _, exp, block = unpack(node)
478
+ local scope_name = NameProxy("with")
479
+ return build["do"]({
480
+ build.assign_one(scope_name, exp),
481
+ Run(function(self)
482
+ return self:set("scope_var", scope_name)
483
+ end),
484
+ build.group(block),
485
+ (function()
486
+ if ret then
487
+ return ret(scope_name)
488
+ end
489
+ end)()
490
+ })
491
+ end,
492
+ foreach = function(self, node)
493
+ smart_node(node)
494
+ if ntype(node.iter) == "unpack" then
495
+ local list = node.iter[2]
496
+ local index_name = NameProxy("index")
497
+ local list_name = NameProxy("list")
498
+ local slice_var = nil
499
+ local bounds
500
+ if is_slice(list) then
501
+ local slice = list[#list]
502
+ table.remove(list)
503
+ table.remove(slice, 1)
504
+ if slice[2] and slice[2] ~= "" then
505
+ local max_tmp_name = NameProxy("max")
506
+ slice_var = build.assign_one(max_tmp_name, slice[2])
507
+ slice[2] = {
508
+ "exp",
509
+ max_tmp_name,
510
+ "<",
511
+ 0,
512
+ "and",
513
+ {
514
+ "length",
515
+ list_name
516
+ },
517
+ "+",
518
+ max_tmp_name,
519
+ "or",
520
+ max_tmp_name
521
+ }
522
+ else
523
+ slice[2] = {
524
+ "length",
525
+ list_name
526
+ }
527
+ end
528
+ bounds = slice
529
+ else
530
+ bounds = {
531
+ 1,
532
+ {
533
+ "length",
534
+ list_name
535
+ }
536
+ }
537
+ end
538
+ return build.group({
539
+ build.assign_one(list_name, list),
540
+ slice_var,
541
+ build["for"]({
542
+ name = index_name,
543
+ bounds = bounds,
544
+ body = {
545
+ {
546
+ "assign",
547
+ node.names,
548
+ {
549
+ list_name:index(index_name)
550
+ }
551
+ },
552
+ build.group(node.body)
553
+ }
554
+ })
555
+ })
556
+ end
557
+ end,
558
+ switch = function(self, node, ret)
559
+ local _, exp, conds = unpack(node)
560
+ local exp_name = NameProxy("exp")
561
+ local convert_cond
562
+ convert_cond = function(cond)
563
+ local t, case_exp, body = unpack(cond)
564
+ local out = { }
565
+ insert(out, t == "case" and "elseif" or "else")
566
+ if t ~= "else" then
567
+ if t ~= "else" then
568
+ insert(out, {
569
+ "exp",
570
+ case_exp,
571
+ "==",
572
+ exp_name
573
+ })
574
+ end
575
+ else
576
+ body = case_exp
577
+ end
578
+ if ret then
579
+ body = apply_to_last(body, ret)
580
+ end
581
+ insert(out, body)
582
+ return out
583
+ end
584
+ local first = true
585
+ local if_stm = {
586
+ "if"
587
+ }
588
+ local _list_0 = conds
589
+ for _index_0 = 1, #_list_0 do
590
+ local cond = _list_0[_index_0]
591
+ local if_cond = convert_cond(cond)
592
+ if first then
593
+ first = false
594
+ insert(if_stm, if_cond[2])
595
+ insert(if_stm, if_cond[3])
596
+ else
597
+ insert(if_stm, if_cond)
598
+ end
599
+ end
600
+ return build.group({
601
+ build.assign_one(exp_name, exp),
602
+ if_stm
603
+ })
604
+ end,
605
+ class = function(self, node)
606
+ local _, name, parent_val, body = unpack(node)
607
+ local statements = { }
608
+ local properties = { }
609
+ local _list_0 = body
610
+ for _index_0 = 1, #_list_0 do
611
+ local item = _list_0[_index_0]
612
+ local _exp_0 = item[1]
613
+ if "stm" == _exp_0 then
614
+ insert(statements, item[2])
615
+ elseif "props" == _exp_0 then
616
+ local _list_1 = item
617
+ for _index_0 = 2, #_list_1 do
618
+ local tuple = _list_1[_index_0]
619
+ insert(properties, tuple)
620
+ end
621
+ end
622
+ end
623
+ local constructor = nil
624
+ properties = (function()
625
+ local _accum_0 = { }
626
+ local _len_0 = 0
627
+ local _list_1 = properties
628
+ for _index_0 = 1, #_list_1 do
629
+ local tuple = _list_1[_index_0]
630
+ local _value_0
631
+ if tuple[1] == constructor_name then
632
+ constructor = tuple[2]
633
+ _value_0 = nil
634
+ else
635
+ _value_0 = tuple
636
+ end
637
+ if _value_0 ~= nil then
638
+ _len_0 = _len_0 + 1
639
+ _accum_0[_len_0] = _value_0
640
+ end
641
+ end
642
+ return _accum_0
643
+ end)()
644
+ local parent_cls_name = NameProxy("parent")
645
+ local base_name = NameProxy("base")
646
+ local self_name = NameProxy("self")
647
+ local cls_name = NameProxy("class")
648
+ if not constructor then
649
+ constructor = build.fndef({
650
+ args = {
651
+ {
652
+ "..."
653
+ }
654
+ },
655
+ arrow = "fat",
656
+ body = {
657
+ build["if"]({
658
+ cond = parent_cls_name,
659
+ ["then"] = {
660
+ build.chain({
661
+ base = "super",
662
+ {
663
+ "call",
664
+ {
665
+ "..."
666
+ }
667
+ }
668
+ })
669
+ }
670
+ })
671
+ }
672
+ })
673
+ else
674
+ smart_node(constructor)
675
+ constructor.arrow = "fat"
676
+ end
677
+ local cls = build.table({
678
+ {
679
+ "__init",
680
+ constructor
681
+ },
682
+ {
683
+ "__base",
684
+ base_name
685
+ },
686
+ {
687
+ "__name",
688
+ {
689
+ "string",
690
+ '"',
691
+ name
692
+ }
693
+ },
694
+ {
695
+ "__parent",
696
+ parent_cls_name
697
+ }
698
+ })
699
+ local class_lookup = build["if"]({
700
+ cond = {
701
+ "exp",
702
+ "val",
703
+ "==",
704
+ "nil",
705
+ "and",
706
+ parent_cls_name
707
+ },
708
+ ["then"] = {
709
+ parent_cls_name:index("name")
710
+ }
711
+ })
712
+ insert(class_lookup, {
713
+ "else",
714
+ {
715
+ "val"
716
+ }
717
+ })
718
+ local cls_mt = build.table({
719
+ {
720
+ "__index",
721
+ build.fndef({
722
+ args = {
723
+ {
724
+ "cls"
725
+ },
726
+ {
727
+ "name"
728
+ }
729
+ },
730
+ body = {
731
+ build.assign_one(LocalName("val"), build.chain({
732
+ base = "rawget",
733
+ {
734
+ "call",
735
+ {
736
+ base_name,
737
+ "name"
738
+ }
739
+ }
740
+ })),
741
+ class_lookup
742
+ }
743
+ })
744
+ },
745
+ {
746
+ "__call",
747
+ build.fndef({
748
+ args = {
749
+ {
750
+ "cls"
751
+ },
752
+ {
753
+ "..."
754
+ }
755
+ },
756
+ body = {
757
+ build.assign_one(self_name, build.chain({
758
+ base = "setmetatable",
759
+ {
760
+ "call",
761
+ {
762
+ "{}",
763
+ base_name
764
+ }
765
+ }
766
+ })),
767
+ build.chain({
768
+ base = "cls.__init",
769
+ {
770
+ "call",
771
+ {
772
+ self_name,
773
+ "..."
774
+ }
775
+ }
776
+ }),
777
+ self_name
778
+ }
779
+ })
780
+ }
781
+ })
782
+ cls = build.chain({
783
+ base = "setmetatable",
784
+ {
785
+ "call",
786
+ {
787
+ cls,
788
+ cls_mt
789
+ }
790
+ }
791
+ })
792
+ local value = nil
793
+ do
794
+ local _with_0 = build
795
+ value = _with_0.block_exp({
796
+ Run(function(self)
797
+ return self:set("super", function(block, chain)
798
+ if chain then
799
+ local slice = (function()
800
+ local _accum_0 = { }
801
+ local _len_0 = 0
802
+ local _list_1 = chain
803
+ for _index_0 = 3, #_list_1 do
804
+ local item = _list_1[_index_0]
805
+ _len_0 = _len_0 + 1
806
+ _accum_0[_len_0] = item
807
+ end
808
+ return _accum_0
809
+ end)()
810
+ local new_chain = {
811
+ "chain",
812
+ parent_cls_name
813
+ }
814
+ local head = slice[1]
815
+ if head == nil then
816
+ return parent_cls_name
817
+ end
818
+ local _exp_0 = head[1]
819
+ if "call" == _exp_0 then
820
+ local calling_name = block:get("current_block")
821
+ slice[1] = {
822
+ "call",
823
+ {
824
+ "self",
825
+ unpack(head[2])
826
+ }
827
+ }
828
+ local act
829
+ if ntype(calling_name) ~= "value" then
830
+ act = "index"
831
+ else
832
+ act = "dot"
833
+ end
834
+ insert(new_chain, {
835
+ act,
836
+ calling_name
837
+ })
838
+ elseif "colon" == _exp_0 then
839
+ local call = head[3]
840
+ insert(new_chain, {
841
+ "dot",
842
+ head[2]
843
+ })
844
+ slice[1] = {
845
+ "call",
846
+ {
847
+ "self",
848
+ unpack(call[2])
849
+ }
850
+ }
851
+ end
852
+ local _list_1 = slice
853
+ for _index_0 = 1, #_list_1 do
854
+ local item = _list_1[_index_0]
855
+ insert(new_chain, item)
856
+ end
857
+ return new_chain
858
+ else
859
+ return parent_cls_name
860
+ end
861
+ end)
862
+ end),
863
+ _with_0.assign_one(parent_cls_name, parent_val == "" and "nil" or parent_val),
864
+ _with_0.assign_one(base_name, {
865
+ "table",
866
+ properties
867
+ }),
868
+ _with_0.assign_one(base_name:chain("__index"), base_name),
869
+ build["if"]({
870
+ cond = parent_cls_name,
871
+ ["then"] = {
872
+ _with_0.chain({
873
+ base = "setmetatable",
874
+ {
875
+ "call",
876
+ {
877
+ base_name,
878
+ _with_0.chain({
879
+ base = parent_cls_name,
880
+ {
881
+ "dot",
882
+ "__base"
883
+ }
884
+ })
885
+ }
886
+ }
887
+ })
888
+ }
889
+ }),
890
+ _with_0.assign_one(cls_name, cls),
891
+ _with_0.assign_one(base_name:chain("__class"), cls_name),
892
+ _with_0.group((function()
893
+ if #statements > 0 then
894
+ return {
895
+ _with_0.assign_one(LocalName("self"), cls_name),
896
+ _with_0.group(statements)
897
+ }
898
+ else
899
+ return { }
900
+ end
901
+ end)()),
902
+ cls_name
903
+ })
904
+ value = _with_0.group({
905
+ _with_0.declare({
906
+ names = {
907
+ name
908
+ }
909
+ }),
910
+ _with_0.assign({
911
+ names = {
912
+ name
913
+ },
914
+ values = {
915
+ value
916
+ }
917
+ })
918
+ })
919
+ end
920
+ return value
921
+ end
922
+ })
923
+ local Accumulator
924
+ Accumulator = (function()
925
+ local _parent_0 = nil
926
+ local _base_0 = {
927
+ body_idx = {
928
+ ["for"] = 4,
929
+ ["while"] = 3,
930
+ foreach = 4
931
+ },
932
+ convert = function(self, node)
933
+ local index = self.body_idx[ntype(node)]
934
+ node[index] = self:mutate_body(node[index])
935
+ return self:wrap(node)
936
+ end,
937
+ wrap = function(self, node)
938
+ return build.block_exp({
939
+ build.assign_one(self.accum_name, build.table()),
940
+ build.assign_one(self.len_name, 0),
941
+ node,
942
+ self.accum_name
943
+ })
944
+ end,
945
+ mutate_body = function(self, body, skip_nil)
946
+ if skip_nil == nil then
947
+ skip_nil = true
948
+ end
949
+ local val
950
+ if not skip_nil and is_singular(body) then
951
+ do
952
+ local _with_0 = body[1]
953
+ body = { }
954
+ val = _with_0
955
+ end
956
+ else
957
+ body = apply_to_last(body, function(n)
958
+ return build.assign_one(self.value_name, n)
959
+ end)
960
+ val = self.value_name
961
+ end
962
+ local update = {
963
+ {
964
+ "update",
965
+ self.len_name,
966
+ "+=",
967
+ 1
968
+ },
969
+ build.assign_one(self.accum_name:index(self.len_name), val)
970
+ }
971
+ if skip_nil then
972
+ table.insert(body, build["if"]({
973
+ cond = {
974
+ "exp",
975
+ self.value_name,
976
+ "!=",
977
+ "nil"
978
+ },
979
+ ["then"] = update
980
+ }))
981
+ else
982
+ table.insert(body, build.group(update))
983
+ end
984
+ return body
985
+ end
986
+ }
987
+ _base_0.__index = _base_0
988
+ if _parent_0 then
989
+ setmetatable(_base_0, _parent_0.__base)
990
+ end
991
+ local _class_0 = setmetatable({
992
+ __init = function(self)
993
+ self.accum_name = NameProxy("accum")
994
+ self.value_name = NameProxy("value")
995
+ self.len_name = NameProxy("len")
996
+ end,
997
+ __base = _base_0,
998
+ __name = "Accumulator",
999
+ __parent = _parent_0
1000
+ }, {
1001
+ __index = function(cls, name)
1002
+ local val = rawget(_base_0, name)
1003
+ if val == nil and _parent_0 then
1004
+ return _parent_0[name]
1005
+ else
1006
+ return val
1007
+ end
1008
+ end,
1009
+ __call = function(cls, ...)
1010
+ local _self_0 = setmetatable({}, _base_0)
1011
+ cls.__init(_self_0, ...)
1012
+ return _self_0
1013
+ end
1014
+ })
1015
+ _base_0.__class = _class_0
1016
+ return _class_0
1017
+ end)()
1018
+ local default_accumulator
1019
+ default_accumulator = function(self, node)
1020
+ return Accumulator():convert(node)
1021
+ end
1022
+ local implicitly_return
1023
+ implicitly_return = function(scope)
1024
+ local fn
1025
+ fn = function(stm)
1026
+ local t = ntype(stm)
1027
+ if types.manual_return[t] or not types.is_value(stm) then
1028
+ return stm
1029
+ elseif types.cascading[t] then
1030
+ return scope.transform.statement(stm, fn)
1031
+ else
1032
+ if t == "comprehension" and not types.comprehension_has_value(stm) then
1033
+ return stm
1034
+ else
1035
+ return {
1036
+ "return",
1037
+ stm
1038
+ }
1039
+ end
1040
+ end
1041
+ end
1042
+ return fn
1043
+ end
1044
+ Value = Transformer({
1045
+ ["for"] = default_accumulator,
1046
+ ["while"] = default_accumulator,
1047
+ foreach = default_accumulator,
1048
+ comprehension = function(self, node)
1049
+ local a = Accumulator()
1050
+ node = self.transform.statement(node, function(exp)
1051
+ return a:mutate_body({
1052
+ exp
1053
+ }, false)
1054
+ end)
1055
+ return a:wrap(node)
1056
+ end,
1057
+ tblcomprehension = function(self, node)
1058
+ local _, key_exp, value_exp, clauses = unpack(node)
1059
+ local accum = NameProxy("tbl")
1060
+ local dest = build.chain({
1061
+ base = accum,
1062
+ {
1063
+ "index",
1064
+ key_exp
1065
+ }
1066
+ })
1067
+ local inner = build.assign_one(dest, value_exp)
1068
+ return build.block_exp({
1069
+ build.assign_one(accum, build.table()),
1070
+ construct_comprehension({
1071
+ inner
1072
+ }, clauses),
1073
+ accum
1074
+ })
1075
+ end,
1076
+ fndef = function(self, node)
1077
+ smart_node(node)
1078
+ node.body = apply_to_last(node.body, implicitly_return(self))
1079
+ return node
1080
+ end,
1081
+ ["if"] = function(self, node)
1082
+ return build.block_exp({
1083
+ node
1084
+ })
1085
+ end,
1086
+ with = function(self, node)
1087
+ return build.block_exp({
1088
+ node
1089
+ })
1090
+ end,
1091
+ switch = function(self, node)
1092
+ return build.block_exp({
1093
+ node
1094
+ })
1095
+ end,
1096
+ chain = function(self, node)
1097
+ local stub = node[#node]
1098
+ if type(stub) == "table" and stub[1] == "colon_stub" then
1099
+ table.remove(node, #node)
1100
+ local base_name = NameProxy("base")
1101
+ local fn_name = NameProxy("fn")
1102
+ local is_super = node[2] == "super"
1103
+ return self.transform.value(build.block_exp({
1104
+ build.assign({
1105
+ names = {
1106
+ base_name
1107
+ },
1108
+ values = {
1109
+ node
1110
+ }
1111
+ }),
1112
+ build.assign({
1113
+ names = {
1114
+ fn_name
1115
+ },
1116
+ values = {
1117
+ build.chain({
1118
+ base = base_name,
1119
+ {
1120
+ "dot",
1121
+ stub[2]
1122
+ }
1123
+ })
1124
+ }
1125
+ }),
1126
+ build.fndef({
1127
+ args = {
1128
+ {
1129
+ "..."
1130
+ }
1131
+ },
1132
+ body = {
1133
+ build.chain({
1134
+ base = fn_name,
1135
+ {
1136
+ "call",
1137
+ {
1138
+ is_super and "self" or base_name,
1139
+ "..."
1140
+ }
1141
+ }
1142
+ })
1143
+ }
1144
+ })
1145
+ }))
1146
+ end
1147
+ end,
1148
+ block_exp = function(self, node)
1149
+ local _, body = unpack(node)
1150
+ local fn = nil
1151
+ local arg_list = { }
1152
+ insert(body, Run(function(self)
1153
+ if self.has_varargs then
1154
+ insert(arg_list, "...")
1155
+ return insert(fn.args, {
1156
+ "..."
1157
+ })
1158
+ end
1159
+ end))
1160
+ fn = smart_node(build.fndef({
1161
+ body = body
1162
+ }))
1163
+ return build.chain({
1164
+ base = {
1165
+ "parens",
1166
+ fn
1167
+ },
1168
+ {
1169
+ "call",
1170
+ arg_list
1171
+ }
1172
+ })
1173
+ end
1174
+ })