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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +51 -0
- data/Rakefile +1 -0
- data/lib/rufus/lua/moon/version.rb +12 -0
- data/lib/rufus/lua/moon.rb +18 -0
- data/rufus-lua-moon.gemspec +25 -0
- data/vendor/lua/moon/all.moon +8 -0
- data/vendor/lua/moon/init.moon +136 -0
- data/vendor/lua/moonscript/compile/format.lua +55 -0
- data/vendor/lua/moonscript/compile/statement.lua +217 -0
- data/vendor/lua/moonscript/compile/value.lua +321 -0
- data/vendor/lua/moonscript/compile.lua +549 -0
- data/vendor/lua/moonscript/data.lua +87 -0
- data/vendor/lua/moonscript/dump.lua +42 -0
- data/vendor/lua/moonscript/errors.lua +65 -0
- data/vendor/lua/moonscript/init.lua +90 -0
- data/vendor/lua/moonscript/parse.lua +505 -0
- data/vendor/lua/moonscript/transform.lua +1174 -0
- data/vendor/lua/moonscript/types.lua +237 -0
- data/vendor/lua/moonscript/util.lua +101 -0
- data/vendor/lua/moonscript/version.lua +7 -0
- metadata +109 -0
@@ -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
|
+
})
|