rufus-lua-moon 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ })