rufus-lua-moon 0.2.0 → 0.2.2

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.
@@ -3,9 +3,11 @@ local types = require("moonscript.types")
3
3
  local util = require("moonscript.util")
4
4
  local data = require("moonscript.data")
5
5
  local reversed = util.reversed
6
- local ntype, build, smart_node, is_slice = types.ntype, types.build, types.smart_node, types.is_slice
6
+ local ntype, build, smart_node, is_slice, value_is_singular = types.ntype, types.build, types.smart_node, types.is_slice, types.value_is_singular
7
7
  local insert = table.insert
8
- LocalName = (function()
8
+ local mtype = util.moon.type
9
+ local implicitly_return
10
+ do
9
11
  local _parent_0 = nil
10
12
  local _base_0 = {
11
13
  get_name = function(self)
@@ -40,9 +42,12 @@ LocalName = (function()
40
42
  end
41
43
  })
42
44
  _base_0.__class = _class_0
43
- return _class_0
44
- end)()
45
- NameProxy = (function()
45
+ if _parent_0 and _parent_0.__inherited then
46
+ _parent_0.__inherited(_parent_0, _class_0)
47
+ end
48
+ LocalName = _class_0
49
+ end
50
+ do
46
51
  local _parent_0 = nil
47
52
  local _base_0 = {
48
53
  get_name = function(self, scope)
@@ -127,9 +132,12 @@ NameProxy = (function()
127
132
  end
128
133
  })
129
134
  _base_0.__class = _class_0
130
- return _class_0
131
- end)()
132
- Run = (function()
135
+ if _parent_0 and _parent_0.__inherited then
136
+ _parent_0.__inherited(_parent_0, _class_0)
137
+ end
138
+ NameProxy = _class_0
139
+ end
140
+ do
133
141
  local _parent_0 = nil
134
142
  local _base_0 = {
135
143
  call = function(self, state)
@@ -164,8 +172,11 @@ Run = (function()
164
172
  end
165
173
  })
166
174
  _base_0.__class = _class_0
167
- return _class_0
168
- end)()
175
+ if _parent_0 and _parent_0.__inherited then
176
+ _parent_0.__inherited(_parent_0, _class_0)
177
+ end
178
+ Run = _class_0
179
+ end
169
180
  local apply_to_last
170
181
  apply_to_last = function(stms, fn)
171
182
  local last_exp_id = 0
@@ -205,9 +216,136 @@ is_singular = function(body)
205
216
  return true
206
217
  end
207
218
  end
219
+ local find_assigns
220
+ find_assigns = function(body, out)
221
+ if out == nil then
222
+ out = { }
223
+ end
224
+ local _list_0 = body
225
+ for _index_0 = 1, #_list_0 do
226
+ local thing = _list_0[_index_0]
227
+ local _exp_0 = thing[1]
228
+ if "group" == _exp_0 then
229
+ find_assigns(thing[2], out)
230
+ elseif "assign" == _exp_0 then
231
+ table.insert(out, thing[2])
232
+ end
233
+ end
234
+ return out
235
+ end
236
+ local hoist_declarations
237
+ hoist_declarations = function(body)
238
+ local assigns = { }
239
+ local _list_0 = find_assigns(body)
240
+ for _index_0 = 1, #_list_0 do
241
+ local names = _list_0[_index_0]
242
+ local _list_1 = names
243
+ for _index_1 = 1, #_list_1 do
244
+ local name = _list_1[_index_1]
245
+ if type(name) == "string" then
246
+ table.insert(assigns, name)
247
+ end
248
+ end
249
+ end
250
+ local idx = 1
251
+ while mtype(body[idx]) == Run do
252
+ idx = idx + 1
253
+ end
254
+ return table.insert(body, idx, {
255
+ "declare",
256
+ assigns
257
+ })
258
+ end
259
+ local expand_elseif_assign
260
+ expand_elseif_assign = function(ifstm)
261
+ for i = 4, #ifstm do
262
+ local case = ifstm[i]
263
+ if ntype(case) == "elseif" and ntype(case[2]) == "assign" then
264
+ local split = {
265
+ unpack(ifstm, 1, i - 1)
266
+ }
267
+ insert(split, {
268
+ "else",
269
+ {
270
+ {
271
+ "if",
272
+ case[2],
273
+ case[3],
274
+ unpack(ifstm, i + 1)
275
+ }
276
+ }
277
+ })
278
+ return split
279
+ end
280
+ end
281
+ return ifstm
282
+ end
208
283
  local constructor_name = "new"
284
+ local with_continue_listener
285
+ with_continue_listener = function(body)
286
+ local continue_name = nil
287
+ return {
288
+ Run(function(self)
289
+ return self:listen("continue", function()
290
+ if not (continue_name) then
291
+ continue_name = NameProxy("continue")
292
+ self:put_name(continue_name)
293
+ end
294
+ return continue_name
295
+ end)
296
+ end),
297
+ build.group(body),
298
+ Run(function(self)
299
+ if not (continue_name) then
300
+ return
301
+ end
302
+ self:put_name(continue_name, nil)
303
+ return self:splice(function(lines)
304
+ return {
305
+ {
306
+ "assign",
307
+ {
308
+ continue_name
309
+ },
310
+ {
311
+ "false"
312
+ }
313
+ },
314
+ {
315
+ "repeat",
316
+ "true",
317
+ {
318
+ lines,
319
+ {
320
+ "assign",
321
+ {
322
+ continue_name
323
+ },
324
+ {
325
+ "true"
326
+ }
327
+ }
328
+ }
329
+ },
330
+ {
331
+ "if",
332
+ {
333
+ "not",
334
+ continue_name
335
+ },
336
+ {
337
+ {
338
+ "break"
339
+ }
340
+ }
341
+ }
342
+ }
343
+ end)
344
+ end)
345
+ }
346
+ end
209
347
  local Transformer
210
- Transformer = (function()
348
+ do
211
349
  local _parent_0 = nil
212
350
  local _base_0 = {
213
351
  transform = function(self, scope, node, ...)
@@ -228,12 +366,15 @@ Transformer = (function()
228
366
  end
229
367
  node = res
230
368
  end
369
+ return node
231
370
  end,
232
- __call = function(self, node, ...)
233
- return self:transform(self.scope, node, ...)
371
+ bind = function(self, scope)
372
+ return function(...)
373
+ return self:transform(scope, ...)
374
+ end
234
375
  end,
235
- instance = function(self, scope)
236
- return Transformer(self.transformers, scope)
376
+ __call = function(self, ...)
377
+ return self:transform(...)
237
378
  end,
238
379
  can_transform = function(self, node)
239
380
  return self.transformers[ntype(node)] ~= nil
@@ -244,9 +385,11 @@ Transformer = (function()
244
385
  setmetatable(_base_0, _parent_0.__base)
245
386
  end
246
387
  local _class_0 = setmetatable({
247
- __init = function(self, transformers, scope)
248
- self.transformers, self.scope = transformers, scope
249
- self.seen_nodes = { }
388
+ __init = function(self, transformers)
389
+ self.transformers = transformers
390
+ self.seen_nodes = setmetatable({ }, {
391
+ __mode = "k"
392
+ })
250
393
  end,
251
394
  __base = _base_0,
252
395
  __name = "Transformer",
@@ -267,23 +410,30 @@ Transformer = (function()
267
410
  end
268
411
  })
269
412
  _base_0.__class = _class_0
270
- return _class_0
271
- end)()
413
+ if _parent_0 and _parent_0.__inherited then
414
+ _parent_0.__inherited(_parent_0, _class_0)
415
+ end
416
+ Transformer = _class_0
417
+ end
272
418
  local construct_comprehension
273
419
  construct_comprehension = function(inner, clauses)
274
420
  local current_stms = inner
275
421
  for _, clause in reversed(clauses) do
276
422
  local t = clause[1]
277
423
  if t == "for" then
278
- local _, names, iter = unpack(clause)
424
+ local names, iter
425
+ _, names, iter = unpack(clause)
279
426
  current_stms = {
280
427
  "foreach",
281
428
  names,
282
- iter,
429
+ {
430
+ iter
431
+ },
283
432
  current_stms
284
433
  }
285
434
  elseif t == "when" then
286
- local _, cond = unpack(clause)
435
+ local cond
436
+ _, cond = unpack(clause)
287
437
  current_stms = {
288
438
  "if",
289
439
  cond,
@@ -299,33 +449,56 @@ construct_comprehension = function(inner, clauses)
299
449
  return current_stms[1]
300
450
  end
301
451
  Statement = Transformer({
452
+ root_stms = function(self, body)
453
+ return apply_to_last(body, implicitly_return(self))
454
+ end,
302
455
  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
456
+ local names, values = unpack(node, 2)
457
+ local transformed
458
+ if #values == 1 then
459
+ local value = values[1]
460
+ local t = ntype(value)
461
+ if t == "decorated" then
462
+ value = self.transform.statement(value)
463
+ t = ntype(value)
464
+ end
465
+ if types.cascading[t] then
466
+ local ret
467
+ ret = function(stm)
468
+ if types.is_value(stm) then
469
+ return {
470
+ "assign",
471
+ names,
472
+ {
473
+ stm
474
+ }
313
475
  }
314
- }
315
- else
316
- return stm
476
+ else
477
+ return stm
478
+ end
317
479
  end
318
- end)
319
- return build.group({
320
- {
321
- "declare",
322
- names
323
- },
324
- values[1]
325
- })
326
- else
327
- return node
480
+ transformed = build.group({
481
+ {
482
+ "declare",
483
+ names
484
+ },
485
+ self.transform.statement(value, ret, node)
486
+ })
487
+ end
328
488
  end
489
+ return transformed or node
490
+ end,
491
+ continue = function(self, node)
492
+ local continue_name = self:send("continue")
493
+ if not (continue_name) then
494
+ error("continue must be inside of a loop")
495
+ end
496
+ return build.group({
497
+ build.assign_one(continue_name, "true"),
498
+ {
499
+ "break"
500
+ }
501
+ })
329
502
  end,
330
503
  export = function(self, node)
331
504
  if #node > 2 then
@@ -359,6 +532,12 @@ Statement = Transformer({
359
532
  if not op_final then
360
533
  error("Unknown op: " .. op)
361
534
  end
535
+ if not (value_is_singular(exp)) then
536
+ exp = {
537
+ "parens",
538
+ exp
539
+ }
540
+ end
362
541
  return build.assign_one(name, {
363
542
  "exp",
364
543
  name,
@@ -461,7 +640,100 @@ Statement = Transformer({
461
640
  end
462
641
  return construct_comprehension(action(exp), clauses)
463
642
  end,
643
+ ["do"] = function(self, node, ret)
644
+ if ret then
645
+ node[2] = apply_to_last(node[2], ret)
646
+ end
647
+ return node
648
+ end,
649
+ decorated = function(self, node)
650
+ local stm, dec = unpack(node, 2)
651
+ local wrapped
652
+ local _exp_0 = dec[1]
653
+ if "if" == _exp_0 then
654
+ local cond, fail = unpack(dec, 2)
655
+ if fail then
656
+ fail = {
657
+ "else",
658
+ {
659
+ fail
660
+ }
661
+ }
662
+ end
663
+ wrapped = {
664
+ "if",
665
+ cond,
666
+ {
667
+ stm
668
+ },
669
+ fail
670
+ }
671
+ elseif "unless" == _exp_0 then
672
+ wrapped = {
673
+ "unless",
674
+ dec[2],
675
+ {
676
+ stm
677
+ }
678
+ }
679
+ elseif "comprehension" == _exp_0 then
680
+ wrapped = {
681
+ "comprehension",
682
+ stm,
683
+ dec[2]
684
+ }
685
+ else
686
+ wrapped = error("Unknown decorator " .. dec[1])
687
+ end
688
+ if ntype(stm) == "assign" then
689
+ wrapped = build.group({
690
+ build.declare({
691
+ names = (function()
692
+ local _accum_0 = { }
693
+ local _len_0 = 0
694
+ local _list_0 = stm[2]
695
+ for _index_0 = 1, #_list_0 do
696
+ local name = _list_0[_index_0]
697
+ if type(name) == "string" then
698
+ _len_0 = _len_0 + 1
699
+ _accum_0[_len_0] = name
700
+ end
701
+ end
702
+ return _accum_0
703
+ end)()
704
+ }),
705
+ wrapped
706
+ })
707
+ end
708
+ return wrapped
709
+ end,
710
+ unless = function(self, node)
711
+ return {
712
+ "if",
713
+ {
714
+ "not",
715
+ {
716
+ "parens",
717
+ node[2]
718
+ }
719
+ },
720
+ unpack(node, 3)
721
+ }
722
+ end,
464
723
  ["if"] = function(self, node, ret)
724
+ if ntype(node[2]) == "assign" then
725
+ local _, assign, body = unpack(node)
726
+ local name = assign[2][1]
727
+ return build["do"]({
728
+ assign,
729
+ {
730
+ "if",
731
+ name,
732
+ unpack(node, 3)
733
+ }
734
+ })
735
+ end
736
+ node = expand_elseif_assign(node)
465
737
  if ret then
466
738
  smart_node(node)
467
739
  node['then'] = apply_to_last(node['then'], ret)
@@ -476,11 +748,26 @@ Statement = Transformer({
476
748
  with = function(self, node, ret)
477
749
  local _, exp, block = unpack(node)
478
750
  local scope_name = NameProxy("with")
751
+ local named_assign
752
+ if ntype(exp) == "assign" then
753
+ local names, values = unpack(exp, 2)
754
+ local assign_name = names[1]
755
+ exp = values[1]
756
+ values[1] = scope_name
757
+ named_assign = {
758
+ "assign",
759
+ names,
760
+ values
761
+ }
762
+ end
479
763
  return build["do"]({
480
- build.assign_one(scope_name, exp),
481
764
  Run(function(self)
482
765
  return self:set("scope_var", scope_name)
483
766
  end),
767
+ build.assign_one(scope_name, exp),
768
+ build.group({
769
+ named_assign
770
+ }),
484
771
  build.group(block),
485
772
  (function()
486
773
  if ret then
@@ -491,8 +778,9 @@ Statement = Transformer({
491
778
  end,
492
779
  foreach = function(self, node)
493
780
  smart_node(node)
494
- if ntype(node.iter) == "unpack" then
495
- local list = node.iter[2]
781
+ local source = unpack(node.iter)
782
+ if ntype(source) == "unpack" then
783
+ local list = source[2]
496
784
  local index_name = NameProxy("index")
497
785
  local list_name = NameProxy("list")
498
786
  local slice_var = nil
@@ -554,6 +842,15 @@ Statement = Transformer({
554
842
  })
555
843
  })
556
844
  end
845
+ node.body = with_continue_listener(node.body)
846
+ end,
847
+ ["while"] = function(self, node)
848
+ smart_node(node)
849
+ node.body = with_continue_listener(node.body)
850
+ end,
851
+ ["for"] = function(self, node)
852
+ smart_node(node)
853
+ node.body = with_continue_listener(node.body)
557
854
  end,
558
855
  switch = function(self, node, ret)
559
856
  local _, exp, conds = unpack(node)
@@ -602,7 +899,7 @@ Statement = Transformer({
602
899
  if_stm
603
900
  })
604
901
  end,
605
- class = function(self, node)
902
+ class = function(self, node, ret, parent_assign)
606
903
  local _, name, parent_val, body = unpack(node)
607
904
  local statements = { }
608
905
  local properties = { }
@@ -614,9 +911,13 @@ Statement = Transformer({
614
911
  insert(statements, item[2])
615
912
  elseif "props" == _exp_0 then
616
913
  local _list_1 = item
617
- for _index_0 = 2, #_list_1 do
618
- local tuple = _list_1[_index_0]
619
- insert(properties, tuple)
914
+ for _index_1 = 2, #_list_1 do
915
+ local tuple = _list_1[_index_1]
916
+ if ntype(tuple[1]) == "self" then
917
+ insert(statements, build.assign_one(unpack(tuple)))
918
+ else
919
+ insert(properties, tuple)
920
+ end
620
921
  end
621
922
  end
622
923
  end
@@ -627,8 +928,9 @@ Statement = Transformer({
627
928
  local _list_1 = properties
628
929
  for _index_0 = 1, #_list_1 do
629
930
  local tuple = _list_1[_index_0]
931
+ local key = tuple[1]
630
932
  local _value_0
631
- if tuple[1] == constructor_name then
933
+ if key[1] == "key_literal" and key[2] == constructor_name then
632
934
  constructor = tuple[2]
633
935
  _value_0 = nil
634
936
  else
@@ -674,6 +976,31 @@ Statement = Transformer({
674
976
  smart_node(constructor)
675
977
  constructor.arrow = "fat"
676
978
  end
979
+ local real_name = name or parent_assign and parent_assign[2][1]
980
+ local _exp_0 = ntype(real_name)
981
+ if "chain" == _exp_0 then
982
+ local last = real_name[#real_name]
983
+ local _exp_1 = ntype(last)
984
+ if "dot" == _exp_1 then
985
+ real_name = {
986
+ "string",
987
+ '"',
988
+ last[2]
989
+ }
990
+ elseif "index" == _exp_1 then
991
+ real_name = last[2]
992
+ else
993
+ real_name = "nil"
994
+ end
995
+ elseif "nil" == _exp_0 then
996
+ real_name = "nil"
997
+ else
998
+ real_name = {
999
+ "string",
1000
+ '"',
1001
+ real_name
1002
+ }
1003
+ end
677
1004
  local cls = build.table({
678
1005
  {
679
1006
  "__init",
@@ -685,11 +1012,7 @@ Statement = Transformer({
685
1012
  },
686
1013
  {
687
1014
  "__name",
688
- {
689
- "string",
690
- '"',
691
- name
692
- }
1015
+ real_name
693
1016
  },
694
1017
  {
695
1018
  "__parent",
@@ -792,8 +1115,11 @@ Statement = Transformer({
792
1115
  local value = nil
793
1116
  do
794
1117
  local _with_0 = build
795
- value = _with_0.block_exp({
1118
+ local out_body = {
796
1119
  Run(function(self)
1120
+ if name then
1121
+ self:put_name(name)
1122
+ end
797
1123
  return self:set("super", function(block, chain)
798
1124
  if chain then
799
1125
  local slice = (function()
@@ -815,8 +1141,8 @@ Statement = Transformer({
815
1141
  if head == nil then
816
1142
  return parent_cls_name
817
1143
  end
818
- local _exp_0 = head[1]
819
- if "call" == _exp_0 then
1144
+ local _exp_1 = head[1]
1145
+ if "call" == _exp_1 then
820
1146
  local calling_name = block:get("current_block")
821
1147
  slice[1] = {
822
1148
  "call",
@@ -825,17 +1151,18 @@ Statement = Transformer({
825
1151
  unpack(head[2])
826
1152
  }
827
1153
  }
828
- local act
829
- if ntype(calling_name) ~= "value" then
830
- act = "index"
1154
+ if ntype(calling_name) == "key_literal" then
1155
+ insert(new_chain, {
1156
+ "dot",
1157
+ calling_name[2]
1158
+ })
831
1159
  else
832
- act = "dot"
1160
+ insert(new_chain, {
1161
+ "index",
1162
+ calling_name
1163
+ })
833
1164
  end
834
- insert(new_chain, {
835
- act,
836
- calling_name
837
- })
838
- elseif "colon" == _exp_0 then
1165
+ elseif "colon" == _exp_1 then
839
1166
  local call = head[3]
840
1167
  insert(new_chain, {
841
1168
  "dot",
@@ -866,7 +1193,7 @@ Statement = Transformer({
866
1193
  properties
867
1194
  }),
868
1195
  _with_0.assign_one(base_name:chain("__index"), base_name),
869
- build["if"]({
1196
+ _with_0["if"]({
870
1197
  cond = parent_cls_name,
871
1198
  ["then"] = {
872
1199
  _with_0.chain({
@@ -895,33 +1222,59 @@ Statement = Transformer({
895
1222
  _with_0.assign_one(LocalName("self"), cls_name),
896
1223
  _with_0.group(statements)
897
1224
  }
898
- else
899
- return { }
900
1225
  end
901
1226
  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
1227
+ _with_0["if"]({
1228
+ cond = {
1229
+ "exp",
1230
+ parent_cls_name,
1231
+ "and",
1232
+ parent_cls_name:chain("__inherited")
913
1233
  },
914
- values = {
915
- value
1234
+ ["then"] = {
1235
+ parent_cls_name:chain("__inherited", {
1236
+ "call",
1237
+ {
1238
+ parent_cls_name,
1239
+ cls_name
1240
+ }
1241
+ })
916
1242
  }
917
- })
1243
+ }),
1244
+ _with_0.group((function()
1245
+ if name then
1246
+ return {
1247
+ _with_0.assign_one(name, cls_name)
1248
+ }
1249
+ end
1250
+ end)()),
1251
+ (function()
1252
+ if ret then
1253
+ return ret(cls_name)
1254
+ end
1255
+ end)()
1256
+ }
1257
+ hoist_declarations(out_body)
1258
+ value = _with_0.group({
1259
+ _with_0.group((function()
1260
+ if ntype(name) == "value" then
1261
+ return {
1262
+ _with_0.declare({
1263
+ names = {
1264
+ name
1265
+ }
1266
+ })
1267
+ }
1268
+ end
1269
+ end)()),
1270
+ _with_0["do"](out_body)
918
1271
  })
919
1272
  end
920
1273
  return value
921
1274
  end
922
1275
  })
923
1276
  local Accumulator
924
- Accumulator = (function()
1277
+ do
925
1278
  local _parent_0 = nil
926
1279
  local _base_0 = {
927
1280
  body_idx = {
@@ -955,7 +1308,19 @@ Accumulator = (function()
955
1308
  end
956
1309
  else
957
1310
  body = apply_to_last(body, function(n)
958
- return build.assign_one(self.value_name, n)
1311
+ if types.is_value(n) then
1312
+ return build.assign_one(self.value_name, n)
1313
+ else
1314
+ return build.group({
1315
+ {
1316
+ "declare",
1317
+ {
1318
+ self.value_name
1319
+ }
1320
+ },
1321
+ n
1322
+ })
1323
+ end
959
1324
  end)
960
1325
  val = self.value_name
961
1326
  end
@@ -1013,21 +1378,33 @@ Accumulator = (function()
1013
1378
  end
1014
1379
  })
1015
1380
  _base_0.__class = _class_0
1016
- return _class_0
1017
- end)()
1381
+ if _parent_0 and _parent_0.__inherited then
1382
+ _parent_0.__inherited(_parent_0, _class_0)
1383
+ end
1384
+ Accumulator = _class_0
1385
+ end
1018
1386
  local default_accumulator
1019
1387
  default_accumulator = function(self, node)
1020
1388
  return Accumulator():convert(node)
1021
1389
  end
1022
- local implicitly_return
1023
1390
  implicitly_return = function(scope)
1391
+ local is_top = true
1024
1392
  local fn
1025
1393
  fn = function(stm)
1026
1394
  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
1395
+ if t == "decorated" then
1396
+ stm = scope.transform.statement(stm)
1397
+ t = ntype(stm)
1398
+ end
1399
+ if types.cascading[t] then
1400
+ is_top = false
1030
1401
  return scope.transform.statement(stm, fn)
1402
+ elseif types.manual_return[t] or not types.is_value(stm) then
1403
+ if is_top and t == "return" and stm[2] == "" then
1404
+ return nil
1405
+ else
1406
+ return stm
1407
+ end
1031
1408
  else
1032
1409
  if t == "comprehension" and not types.comprehension_has_value(stm) then
1033
1410
  return stm
@@ -1045,6 +1422,58 @@ Value = Transformer({
1045
1422
  ["for"] = default_accumulator,
1046
1423
  ["while"] = default_accumulator,
1047
1424
  foreach = default_accumulator,
1425
+ ["do"] = function(self, node)
1426
+ return build.block_exp(node[2])
1427
+ end,
1428
+ decorated = function(self, node)
1429
+ return self.transform.statement(node)
1430
+ end,
1431
+ class = function(self, node)
1432
+ return build.block_exp({
1433
+ node
1434
+ })
1435
+ end,
1436
+ string = function(self, node)
1437
+ local delim = node[2]
1438
+ local convert_part
1439
+ convert_part = function(part)
1440
+ if type(part) == "string" or part == nil then
1441
+ return {
1442
+ "string",
1443
+ delim,
1444
+ part or ""
1445
+ }
1446
+ else
1447
+ return build.chain({
1448
+ base = "tostring",
1449
+ {
1450
+ "call",
1451
+ {
1452
+ part[2]
1453
+ }
1454
+ }
1455
+ })
1456
+ end
1457
+ end
1458
+ if #node <= 3 then
1459
+ return (function()
1460
+ if type(node[3]) == "string" then
1461
+ return node
1462
+ else
1463
+ return convert_part(node[3])
1464
+ end
1465
+ end)()
1466
+ end
1467
+ local e = {
1468
+ "exp",
1469
+ convert_part(node[3])
1470
+ }
1471
+ for i = 4, #node do
1472
+ insert(e, "..")
1473
+ insert(e, convert_part(node[i]))
1474
+ end
1475
+ return e
1476
+ end,
1048
1477
  comprehension = function(self, node)
1049
1478
  local a = Accumulator()
1050
1479
  node = self.transform.statement(node, function(exp)
@@ -1055,27 +1484,58 @@ Value = Transformer({
1055
1484
  return a:wrap(node)
1056
1485
  end,
1057
1486
  tblcomprehension = function(self, node)
1058
- local _, key_exp, value_exp, clauses = unpack(node)
1487
+ local _, explist, clauses = unpack(node)
1488
+ local key_exp, value_exp = unpack(explist)
1059
1489
  local accum = NameProxy("tbl")
1060
- local dest = build.chain({
1061
- base = accum,
1062
- {
1063
- "index",
1064
- key_exp
1490
+ local inner
1491
+ if value_exp then
1492
+ local dest = build.chain({
1493
+ base = accum,
1494
+ {
1495
+ "index",
1496
+ key_exp
1497
+ }
1498
+ })
1499
+ inner = {
1500
+ build.assign_one(dest, value_exp)
1065
1501
  }
1066
- })
1067
- local inner = build.assign_one(dest, value_exp)
1502
+ else
1503
+ local key_name, val_name = NameProxy("key"), NameProxy("val")
1504
+ local dest = build.chain({
1505
+ base = accum,
1506
+ {
1507
+ "index",
1508
+ key_name
1509
+ }
1510
+ })
1511
+ inner = {
1512
+ build.assign({
1513
+ names = {
1514
+ key_name,
1515
+ val_name
1516
+ },
1517
+ values = {
1518
+ key_exp
1519
+ }
1520
+ }),
1521
+ build.assign_one(dest, val_name)
1522
+ }
1523
+ end
1068
1524
  return build.block_exp({
1069
1525
  build.assign_one(accum, build.table()),
1070
- construct_comprehension({
1071
- inner
1072
- }, clauses),
1526
+ construct_comprehension(inner, clauses),
1073
1527
  accum
1074
1528
  })
1075
1529
  end,
1076
1530
  fndef = function(self, node)
1077
1531
  smart_node(node)
1078
1532
  node.body = apply_to_last(node.body, implicitly_return(self))
1533
+ node.body = {
1534
+ Run(function(self)
1535
+ return self:listen("varargs", function() end)
1536
+ end),
1537
+ unpack(node.body)
1538
+ }
1079
1539
  return node
1080
1540
  end,
1081
1541
  ["if"] = function(self, node)
@@ -1083,6 +1543,11 @@ Value = Transformer({
1083
1543
  node
1084
1544
  })
1085
1545
  end,
1546
+ unless = function(self, node)
1547
+ return build.block_exp({
1548
+ node
1549
+ })
1550
+ end,
1086
1551
  with = function(self, node)
1087
1552
  return build.block_exp({
1088
1553
  node
@@ -1095,7 +1560,25 @@ Value = Transformer({
1095
1560
  end,
1096
1561
  chain = function(self, node)
1097
1562
  local stub = node[#node]
1098
- if type(stub) == "table" and stub[1] == "colon_stub" then
1563
+ for i = 3, #node do
1564
+ local part = node[i]
1565
+ if ntype(part) == "dot" and data.lua_keywords[part[2]] then
1566
+ node[i] = {
1567
+ "index",
1568
+ {
1569
+ "string",
1570
+ '"',
1571
+ part[2]
1572
+ }
1573
+ }
1574
+ end
1575
+ end
1576
+ if ntype(node[2]) == "string" then
1577
+ node[2] = {
1578
+ "parens",
1579
+ node[2]
1580
+ }
1581
+ elseif type(stub) == "table" and stub[1] == "colon_stub" then
1099
1582
  table.remove(node, #node)
1100
1583
  local base_name = NameProxy("base")
1101
1584
  local fn_name = NameProxy("fn")
@@ -1149,16 +1632,19 @@ Value = Transformer({
1149
1632
  local _, body = unpack(node)
1150
1633
  local fn = nil
1151
1634
  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
1635
  fn = smart_node(build.fndef({
1161
- body = body
1636
+ body = {
1637
+ Run(function(self)
1638
+ return self:listen("varargs", function()
1639
+ insert(arg_list, "...")
1640
+ insert(fn.args, {
1641
+ "..."
1642
+ })
1643
+ return self:unlisten("varargs")
1644
+ end)
1645
+ end),
1646
+ unpack(body)
1647
+ }
1162
1648
  }))
1163
1649
  return build.chain({
1164
1650
  base = {