pygments.rb 0.2.4 → 0.2.6

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.
Files changed (120) hide show
  1. data/lib/pygments/version.rb +1 -1
  2. data/vendor/pygments-main/AUTHORS +14 -0
  3. data/vendor/pygments-main/CHANGES +34 -3
  4. data/vendor/pygments-main/Makefile +1 -1
  5. data/vendor/pygments-main/docs/generate.py +1 -1
  6. data/vendor/pygments-main/external/markdown-processor.py +1 -1
  7. data/vendor/pygments-main/external/moin-parser.py +1 -1
  8. data/vendor/pygments-main/external/rst-directive-old.py +1 -1
  9. data/vendor/pygments-main/external/rst-directive.py +1 -1
  10. data/vendor/pygments-main/pygments/__init__.py +1 -1
  11. data/vendor/pygments-main/pygments/cmdline.py +4 -1
  12. data/vendor/pygments-main/pygments/console.py +1 -1
  13. data/vendor/pygments-main/pygments/filter.py +1 -1
  14. data/vendor/pygments-main/pygments/filters/__init__.py +1 -1
  15. data/vendor/pygments-main/pygments/formatter.py +1 -1
  16. data/vendor/pygments-main/pygments/formatters/__init__.py +1 -1
  17. data/vendor/pygments-main/pygments/formatters/_mapping.py +1 -1
  18. data/vendor/pygments-main/pygments/formatters/bbcode.py +1 -1
  19. data/vendor/pygments-main/pygments/formatters/html.py +2 -2
  20. data/vendor/pygments-main/pygments/formatters/img.py +1 -1
  21. data/vendor/pygments-main/pygments/formatters/latex.py +3 -2
  22. data/vendor/pygments-main/pygments/formatters/other.py +1 -1
  23. data/vendor/pygments-main/pygments/formatters/rtf.py +1 -1
  24. data/vendor/pygments-main/pygments/formatters/svg.py +1 -1
  25. data/vendor/pygments-main/pygments/formatters/terminal.py +5 -2
  26. data/vendor/pygments-main/pygments/formatters/terminal256.py +5 -2
  27. data/vendor/pygments-main/pygments/lexer.py +29 -10
  28. data/vendor/pygments-main/pygments/lexers/__init__.py +14 -11
  29. data/vendor/pygments-main/pygments/lexers/_asybuiltins.py +1 -1
  30. data/vendor/pygments-main/pygments/lexers/_clbuiltins.py +1 -1
  31. data/vendor/pygments-main/pygments/lexers/_luabuiltins.py +1 -1
  32. data/vendor/pygments-main/pygments/lexers/_mapping.py +41 -23
  33. data/vendor/pygments-main/pygments/lexers/_phpbuiltins.py +1 -1
  34. data/vendor/pygments-main/pygments/lexers/_postgres_builtins.py +1 -1
  35. data/vendor/pygments-main/pygments/lexers/_scilab_builtins.py +29 -0
  36. data/vendor/pygments-main/pygments/lexers/_vimbuiltins.py +3 -3
  37. data/vendor/pygments-main/pygments/lexers/agile.py +148 -443
  38. data/vendor/pygments-main/pygments/lexers/asm.py +5 -3
  39. data/vendor/pygments-main/pygments/lexers/compiled.py +298 -294
  40. data/vendor/pygments-main/pygments/lexers/dotnet.py +40 -34
  41. data/vendor/pygments-main/pygments/lexers/functional.py +723 -4
  42. data/vendor/pygments-main/pygments/lexers/hdl.py +228 -6
  43. data/vendor/pygments-main/pygments/lexers/jvm.py +678 -0
  44. data/vendor/pygments-main/pygments/lexers/math.py +65 -2
  45. data/vendor/pygments-main/pygments/lexers/other.py +875 -481
  46. data/vendor/pygments-main/pygments/lexers/parsers.py +1 -1
  47. data/vendor/pygments-main/pygments/lexers/shell.py +360 -0
  48. data/vendor/pygments-main/pygments/lexers/special.py +1 -1
  49. data/vendor/pygments-main/pygments/lexers/sql.py +565 -0
  50. data/vendor/pygments-main/pygments/lexers/templates.py +1 -1
  51. data/vendor/pygments-main/pygments/lexers/text.py +237 -100
  52. data/vendor/pygments-main/pygments/lexers/web.py +146 -10
  53. data/vendor/pygments-main/pygments/plugin.py +1 -1
  54. data/vendor/pygments-main/pygments/scanner.py +1 -1
  55. data/vendor/pygments-main/pygments/style.py +1 -1
  56. data/vendor/pygments-main/pygments/styles/__init__.py +2 -1
  57. data/vendor/pygments-main/pygments/styles/autumn.py +1 -1
  58. data/vendor/pygments-main/pygments/styles/borland.py +1 -1
  59. data/vendor/pygments-main/pygments/styles/bw.py +1 -1
  60. data/vendor/pygments-main/pygments/styles/colorful.py +1 -1
  61. data/vendor/pygments-main/pygments/styles/default.py +1 -1
  62. data/vendor/pygments-main/pygments/styles/emacs.py +1 -1
  63. data/vendor/pygments-main/pygments/styles/friendly.py +1 -1
  64. data/vendor/pygments-main/pygments/styles/fruity.py +1 -2
  65. data/vendor/pygments-main/pygments/styles/manni.py +1 -1
  66. data/vendor/pygments-main/pygments/styles/monokai.py +1 -1
  67. data/vendor/pygments-main/pygments/styles/murphy.py +1 -1
  68. data/vendor/pygments-main/pygments/styles/native.py +1 -1
  69. data/vendor/pygments-main/pygments/styles/pastie.py +1 -1
  70. data/vendor/pygments-main/pygments/styles/perldoc.py +1 -1
  71. data/vendor/pygments-main/pygments/styles/rrt.py +33 -0
  72. data/vendor/pygments-main/pygments/styles/tango.py +1 -1
  73. data/vendor/pygments-main/pygments/styles/trac.py +1 -1
  74. data/vendor/pygments-main/pygments/styles/vim.py +1 -1
  75. data/vendor/pygments-main/pygments/styles/vs.py +1 -1
  76. data/vendor/pygments-main/pygments/token.py +1 -1
  77. data/vendor/pygments-main/pygments/unistring.py +1 -1
  78. data/vendor/pygments-main/pygments/util.py +2 -2
  79. data/vendor/pygments-main/scripts/check_sources.py +2 -2
  80. data/vendor/pygments-main/scripts/find_codetags.py +1 -1
  81. data/vendor/pygments-main/scripts/find_error.py +5 -2
  82. data/vendor/pygments-main/scripts/get_vimkw.py +9 -4
  83. data/vendor/pygments-main/setup.py +1 -1
  84. data/vendor/pygments-main/tests/examplefiles/classes.dylan +16 -0
  85. data/vendor/pygments-main/tests/examplefiles/coq_RelationClasses +447 -0
  86. data/vendor/pygments-main/tests/examplefiles/example.cls +15 -0
  87. data/vendor/pygments-main/tests/examplefiles/example.moon +629 -0
  88. data/vendor/pygments-main/tests/examplefiles/example.p +34 -0
  89. data/vendor/pygments-main/tests/examplefiles/example.snobol +15 -0
  90. data/vendor/pygments-main/tests/examplefiles/example.u +548 -0
  91. data/vendor/pygments-main/tests/examplefiles/example_elixir.ex +363 -0
  92. data/vendor/pygments-main/tests/examplefiles/foo.sce +6 -0
  93. data/vendor/pygments-main/tests/examplefiles/http_request_example +14 -0
  94. data/vendor/pygments-main/tests/examplefiles/http_response_example +27 -0
  95. data/vendor/pygments-main/tests/examplefiles/irc.lsp +214 -0
  96. data/vendor/pygments-main/tests/examplefiles/markdown.lsp +679 -0
  97. data/vendor/pygments-main/tests/examplefiles/nemerle_sample.n +4 -2
  98. data/vendor/pygments-main/tests/examplefiles/reversi.lsp +427 -0
  99. data/vendor/pygments-main/tests/examplefiles/scilab.sci +30 -0
  100. data/vendor/pygments-main/tests/examplefiles/test.bro +250 -0
  101. data/vendor/pygments-main/tests/examplefiles/test.cs +23 -0
  102. data/vendor/pygments-main/tests/examplefiles/test.dart +23 -0
  103. data/vendor/pygments-main/tests/examplefiles/test.ecl +58 -0
  104. data/vendor/pygments-main/tests/examplefiles/test.fan +818 -0
  105. data/vendor/pygments-main/tests/examplefiles/test.ps1 +108 -0
  106. data/vendor/pygments-main/tests/examplefiles/test.vhdl +161 -0
  107. data/vendor/pygments-main/tests/old_run.py +1 -1
  108. data/vendor/pygments-main/tests/run.py +1 -1
  109. data/vendor/pygments-main/tests/test_basic_api.py +4 -3
  110. data/vendor/pygments-main/tests/test_clexer.py +1 -1
  111. data/vendor/pygments-main/tests/test_cmdline.py +1 -1
  112. data/vendor/pygments-main/tests/test_examplefiles.py +4 -3
  113. data/vendor/pygments-main/tests/test_html_formatter.py +33 -1
  114. data/vendor/pygments-main/tests/test_latex_formatter.py +1 -1
  115. data/vendor/pygments-main/tests/test_perllexer.py +137 -0
  116. data/vendor/pygments-main/tests/test_regexlexer.py +1 -1
  117. data/vendor/pygments-main/tests/test_token.py +1 -1
  118. data/vendor/pygments-main/tests/test_using_api.py +1 -1
  119. data/vendor/pygments-main/tests/test_util.py +35 -5
  120. metadata +30 -4
@@ -0,0 +1,15 @@
1
+ USING Progress.Lang.*.
2
+
3
+ CLASS Test INHERITS Progress.Sucks:
4
+
5
+ DEFINE PRIVATE VARIABLE cTest AS CHAR NO-UNDO.
6
+
7
+ CONSTRUCTOR PUBLIC Test():
8
+ SUPER().
9
+ MESSAGE "Why are you punishing yourself by coding in this language?".
10
+ END CONSTRUCTOR.
11
+
12
+ METHOD PUBLIC LOGICAL Blowup(INPUT iTime AS INT):
13
+ END.
14
+
15
+ END CLASS.
@@ -0,0 +1,629 @@
1
+ -- transform.moon
2
+ -- Leaf Corcoran (leafot@gmail.com) 2011
3
+ --
4
+ -- This is part of the MoonScript compiler. See <http://moonscript.org>
5
+ -- MoonScript is licensed under the MIT License
6
+ --
7
+
8
+ module "moonscript.transform", package.seeall
9
+
10
+ types = require "moonscript.types"
11
+ util = require "moonscript.util"
12
+ data = require "moonscript.data"
13
+
14
+ import reversed from util
15
+ import ntype, build, smart_node, is_slice from types
16
+ import insert from table
17
+
18
+ export Statement, Value, NameProxy, LocalName, Run
19
+
20
+ -- always declares as local
21
+ class LocalName
22
+ new: (@name) => self[1] = "temp_name"
23
+ get_name: => @name
24
+
25
+ class NameProxy
26
+ new: (@prefix) =>
27
+ self[1] = "temp_name"
28
+
29
+ get_name: (scope) =>
30
+ if not @name
31
+ @name = scope\free_name @prefix, true
32
+ @name
33
+
34
+ chain: (...) =>
35
+ items = {...} -- todo: fix ... propagation
36
+ items = for i in *items
37
+ if type(i) == "string"
38
+ {"dot", i}
39
+ else
40
+ i
41
+
42
+ build.chain {
43
+ base: self
44
+ unpack items
45
+ }
46
+
47
+ index: (key) =>
48
+ build.chain {
49
+ base: self, {"index", key}
50
+ }
51
+
52
+ __tostring: =>
53
+ if @name
54
+ ("name<%s>")\format @name
55
+ else
56
+ ("name<prefix(%s)>")\format @prefix
57
+
58
+ class Run
59
+ new: (@fn) =>
60
+ self[1] = "run"
61
+
62
+ call: (state) =>
63
+ self.fn state
64
+
65
+ -- transform the last stm is a list of stms
66
+ -- will puke on group
67
+ apply_to_last = (stms, fn) ->
68
+ -- find last (real) exp
69
+ last_exp_id = 0
70
+ for i = #stms, 1, -1
71
+ stm = stms[i]
72
+ if stm and util.moon.type(stm) != Run
73
+ last_exp_id = i
74
+ break
75
+
76
+ return for i, stm in ipairs stms
77
+ if i == last_exp_id
78
+ fn stm
79
+ else
80
+ stm
81
+
82
+ -- is a body a sindle expression/statement
83
+ is_singular = (body) ->
84
+ return false if #body != 1
85
+ if "group" == ntype body
86
+ is_singular body[2]
87
+ else
88
+ true
89
+
90
+ constructor_name = "new"
91
+
92
+ class Transformer
93
+ new: (@transformers, @scope) =>
94
+ @seen_nodes = {}
95
+
96
+ transform: (scope, node, ...) =>
97
+ -- print scope, node, ...
98
+ return node if @seen_nodes[node]
99
+ @seen_nodes[node] = true
100
+ while true
101
+ transformer = @transformers[ntype node]
102
+ res = if transformer
103
+ transformer(scope, node, ...) or node
104
+ else
105
+ node
106
+ return node if res == node
107
+ node = res
108
+
109
+ __call: (node, ...) =>
110
+ @transform @scope, node, ...
111
+
112
+ instance: (scope) =>
113
+ Transformer @transformers, scope
114
+
115
+ can_transform: (node) =>
116
+ @transformers[ntype node] != nil
117
+
118
+ construct_comprehension = (inner, clauses) ->
119
+ current_stms = inner
120
+ for _, clause in reversed clauses
121
+ t = clause[1]
122
+ current_stms = if t == "for"
123
+ _, names, iter = unpack clause
124
+ {"foreach", names, iter, current_stms}
125
+ elseif t == "when"
126
+ _, cond = unpack clause
127
+ {"if", cond, current_stms}
128
+ else
129
+ error "Unknown comprehension clause: "..t
130
+ current_stms = {current_stms}
131
+
132
+ current_stms[1]
133
+
134
+ Statement = Transformer {
135
+ assign: (node) =>
136
+ _, names, values = unpack node
137
+ -- bubble cascading assigns
138
+ if #values == 1 and types.cascading[ntype values[1]]
139
+ values[1] = @transform.statement values[1], (stm) ->
140
+ t = ntype stm
141
+ if types.is_value stm
142
+ {"assign", names, {stm}}
143
+ else
144
+ stm
145
+
146
+ build.group {
147
+ {"declare", names}
148
+ values[1]
149
+ }
150
+ else
151
+ node
152
+
153
+ export: (node) =>
154
+ -- assign values if they are included
155
+ if #node > 2
156
+ if node[2] == "class"
157
+ cls = smart_node node[3]
158
+ build.group {
159
+ {"export", {cls.name}}
160
+ cls
161
+ }
162
+ else
163
+ build.group {
164
+ node
165
+ build.assign {
166
+ names: node[2]
167
+ values: node[3]
168
+ }
169
+ }
170
+ else
171
+ nil
172
+
173
+ update: (node) =>
174
+ _, name, op, exp = unpack node
175
+ op_final = op\match "^(.+)=$"
176
+ error "Unknown op: "..op if not op_final
177
+ build.assign_one name, {"exp", name, op_final, exp}
178
+
179
+ import: (node) =>
180
+ _, names, source = unpack node
181
+
182
+ stubs = for name in *names
183
+ if type(name) == "table"
184
+ name
185
+ else
186
+ {"dot", name}
187
+
188
+ real_names = for name in *names
189
+ type(name) == "table" and name[2] or name
190
+
191
+ if type(source) == "string"
192
+ build.assign {
193
+ names: real_names
194
+ values: [build.chain { base: source, stub} for stub in *stubs]
195
+ }
196
+ else
197
+ source_name = NameProxy "table"
198
+ build.group {
199
+ {"declare", real_names}
200
+ build["do"] {
201
+ build.assign_one source_name, source
202
+ build.assign {
203
+ names: real_names
204
+ values: [build.chain { base: source_name, stub} for stub in *stubs]
205
+ }
206
+ }
207
+ }
208
+
209
+ comprehension: (node, action) =>
210
+ _, exp, clauses = unpack node
211
+
212
+ action = action or (exp) -> {exp}
213
+ construct_comprehension action(exp), clauses
214
+
215
+ -- handle cascading return decorator
216
+ if: (node, ret) =>
217
+ if ret
218
+ smart_node node
219
+ -- mutate all the bodies
220
+ node['then'] = apply_to_last node['then'], ret
221
+ for i = 4, #node
222
+ case = node[i]
223
+ body_idx = #node[i]
224
+ case[body_idx] = apply_to_last case[body_idx], ret
225
+ node
226
+
227
+ with: (node, ret) =>
228
+ _, exp, block = unpack node
229
+ scope_name = NameProxy "with"
230
+ build["do"] {
231
+ build.assign_one scope_name, exp
232
+ Run => @set "scope_var", scope_name
233
+ build.group block
234
+ if ret
235
+ ret scope_name
236
+ }
237
+
238
+ foreach: (node) =>
239
+ smart_node node
240
+ if ntype(node.iter) == "unpack"
241
+ list = node.iter[2]
242
+
243
+ index_name = NameProxy "index"
244
+ list_name = NameProxy "list"
245
+
246
+ slice_var = nil
247
+ bounds = if is_slice list
248
+ slice = list[#list]
249
+ table.remove list
250
+ table.remove slice, 1
251
+
252
+ slice[2] = if slice[2] and slice[2] != ""
253
+ max_tmp_name = NameProxy "max"
254
+ slice_var = build.assign_one max_tmp_name, slice[2]
255
+ {"exp", max_tmp_name, "<", 0
256
+ "and", {"length", list_name}, "+", max_tmp_name
257
+ "or", max_tmp_name }
258
+ else
259
+ {"length", list_name}
260
+
261
+ slice
262
+ else
263
+ {1, {"length", list_name}}
264
+
265
+ build.group {
266
+ build.assign_one list_name, list
267
+ slice_var
268
+ build["for"] {
269
+ name: index_name
270
+ bounds: bounds
271
+ body: {
272
+ {"assign", node.names, {list_name\index index_name}}
273
+ build.group node.body
274
+ }
275
+ }
276
+ }
277
+
278
+ switch: (node, ret) =>
279
+ _, exp, conds = unpack node
280
+ exp_name = NameProxy "exp"
281
+
282
+ -- convert switch conds into if statment conds
283
+ convert_cond = (cond) ->
284
+ t, case_exp, body = unpack cond
285
+ out = {}
286
+ insert out, t == "case" and "elseif" or "else"
287
+ if t != "else"
288
+ insert out, {"exp", case_exp, "==", exp_name} if t != "else"
289
+ else
290
+ body = case_exp
291
+
292
+ if ret
293
+ body = apply_to_last body, ret
294
+
295
+ insert out, body
296
+
297
+ out
298
+
299
+ first = true
300
+ if_stm = {"if"}
301
+ for cond in *conds
302
+ if_cond = convert_cond cond
303
+ if first
304
+ first = false
305
+ insert if_stm, if_cond[2]
306
+ insert if_stm, if_cond[3]
307
+ else
308
+ insert if_stm, if_cond
309
+
310
+ build.group {
311
+ build.assign_one exp_name, exp
312
+ if_stm
313
+ }
314
+
315
+ class: (node) =>
316
+ _, name, parent_val, body = unpack node
317
+
318
+ -- split apart properties and statements
319
+ statements = {}
320
+ properties = {}
321
+ for item in *body
322
+ switch item[1]
323
+ when "stm"
324
+ insert statements, item[2]
325
+ when "props"
326
+ for tuple in *item[2,]
327
+ insert properties, tuple
328
+
329
+ -- find constructor
330
+ constructor = nil
331
+ properties = for tuple in *properties
332
+ if tuple[1] == constructor_name
333
+ constructor = tuple[2]
334
+ nil
335
+ else
336
+ tuple
337
+
338
+ parent_cls_name = NameProxy "parent"
339
+ base_name = NameProxy "base"
340
+ self_name = NameProxy "self"
341
+ cls_name = NameProxy "class"
342
+
343
+ if not constructor
344
+ constructor = build.fndef {
345
+ args: {{"..."}}
346
+ arrow: "fat"
347
+ body: {
348
+ build["if"] {
349
+ cond: parent_cls_name
350
+ then: {
351
+ build.chain { base: "super", {"call", {"..."}} }
352
+ }
353
+ }
354
+ }
355
+ }
356
+ else
357
+ smart_node constructor
358
+ constructor.arrow = "fat"
359
+
360
+ cls = build.table {
361
+ {"__init", constructor}
362
+ {"__base", base_name}
363
+ {"__name", {"string", '"', name}} -- "quote the string"
364
+ {"__parent", parent_cls_name}
365
+ }
366
+
367
+ -- look up a name in the class object
368
+ class_lookup = build["if"] {
369
+ cond: {"exp", "val", "==", "nil", "and", parent_cls_name}
370
+ then: {
371
+ parent_cls_name\index"name"
372
+ }
373
+ }
374
+ insert class_lookup, {"else", {"val"}}
375
+
376
+ cls_mt = build.table {
377
+ {"__index", build.fndef {
378
+ args: {{"cls"}, {"name"}}
379
+ body: {
380
+ build.assign_one LocalName"val", build.chain {
381
+ base: "rawget", {"call", {base_name, "name"}}
382
+ }
383
+ class_lookup
384
+ }
385
+ }}
386
+ {"__call", build.fndef {
387
+ args: {{"cls"}, {"..."}}
388
+ body: {
389
+ build.assign_one self_name, build.chain {
390
+ base: "setmetatable"
391
+ {"call", {"{}", base_name}}
392
+ }
393
+ build.chain {
394
+ base: "cls.__init"
395
+ {"call", {self_name, "..."}}
396
+ }
397
+ self_name
398
+ }
399
+ }}
400
+ }
401
+
402
+ cls = build.chain {
403
+ base: "setmetatable"
404
+ {"call", {cls, cls_mt}}
405
+ }
406
+
407
+ value = nil
408
+ with build
409
+ value = .block_exp {
410
+ Run =>
411
+ @set "super", (block, chain) ->
412
+ if chain
413
+ slice = [item for item in *chain[3,]]
414
+ new_chain = {"chain", parent_cls_name}
415
+
416
+ head = slice[1]
417
+
418
+ if head == nil
419
+ return parent_cls_name
420
+
421
+ switch head[1]
422
+ -- calling super, inject calling name and self into chain
423
+ when "call"
424
+ calling_name = block\get"current_block"
425
+ slice[1] = {"call", {"self", unpack head[2]}}
426
+ act = if ntype(calling_name) != "value" then "index" else "dot"
427
+ insert new_chain, {act, calling_name}
428
+
429
+ -- colon call on super, replace class with self as first arg
430
+ when "colon"
431
+ call = head[3]
432
+ insert new_chain, {"dot", head[2]}
433
+ slice[1] = { "call", { "self", unpack call[2] } }
434
+
435
+ insert new_chain, item for item in *slice
436
+
437
+ new_chain
438
+ else
439
+ parent_cls_name
440
+
441
+ .assign_one parent_cls_name, parent_val == "" and "nil" or parent_val
442
+ .assign_one base_name, {"table", properties}
443
+ .assign_one base_name\chain"__index", base_name
444
+
445
+ build["if"] {
446
+ cond: parent_cls_name
447
+ then: {
448
+ .chain {
449
+ base: "setmetatable"
450
+ {"call", {
451
+ base_name,
452
+ .chain { base: parent_cls_name, {"dot", "__base"}}
453
+ }}
454
+ }
455
+ }
456
+ }
457
+
458
+ .assign_one cls_name, cls
459
+ .assign_one base_name\chain"__class", cls_name
460
+
461
+ .group if #statements > 0 {
462
+ .assign_one LocalName"self", cls_name
463
+ .group statements
464
+ } else {}
465
+
466
+ cls_name
467
+ }
468
+
469
+ value = .group {
470
+ .declare names: {name}
471
+ .assign {
472
+ names: {name}
473
+ values: {value}
474
+ }
475
+ }
476
+
477
+ value
478
+ }
479
+
480
+ class Accumulator
481
+ body_idx: { for: 4, while: 3, foreach: 4 }
482
+
483
+ new: =>
484
+ @accum_name = NameProxy "accum"
485
+ @value_name = NameProxy "value"
486
+ @len_name = NameProxy "len"
487
+
488
+ -- wraps node and mutates body
489
+ convert: (node) =>
490
+ index = @body_idx[ntype node]
491
+ node[index] = @mutate_body node[index]
492
+ @wrap node
493
+
494
+ -- wrap the node into a block_exp
495
+ wrap: (node) =>
496
+ build.block_exp {
497
+ build.assign_one @accum_name, build.table!
498
+ build.assign_one @len_name, 0
499
+ node
500
+ @accum_name
501
+ }
502
+
503
+ -- mutates the body of a loop construct to save last value into accumulator
504
+ -- can optionally skip nil results
505
+ mutate_body: (body, skip_nil=true) =>
506
+ val = if not skip_nil and is_singular body
507
+ with body[1]
508
+ body = {}
509
+ else
510
+ body = apply_to_last body, (n) ->
511
+ build.assign_one @value_name, n
512
+ @value_name
513
+
514
+ update = {
515
+ {"update", @len_name, "+=", 1}
516
+ build.assign_one @accum_name\index(@len_name), val
517
+ }
518
+
519
+ if skip_nil
520
+ table.insert body, build["if"] {
521
+ cond: {"exp", @value_name, "!=", "nil"}
522
+ then: update
523
+ }
524
+ else
525
+ table.insert body, build.group update
526
+
527
+ body
528
+
529
+ default_accumulator = (node) =>
530
+ Accumulator!\convert node
531
+
532
+
533
+ implicitly_return = (scope) ->
534
+ fn = (stm) ->
535
+ t = ntype stm
536
+ if types.manual_return[t] or not types.is_value stm
537
+ stm
538
+ elseif types.cascading[t]
539
+ scope.transform.statement stm, fn
540
+ else
541
+ if t == "comprehension" and not types.comprehension_has_value stm
542
+ stm
543
+ else
544
+ {"return", stm}
545
+
546
+ fn
547
+
548
+ Value = Transformer {
549
+ for: default_accumulator
550
+ while: default_accumulator
551
+ foreach: default_accumulator
552
+
553
+ comprehension: (node) =>
554
+ a = Accumulator!
555
+ node = @transform.statement node, (exp) ->
556
+ a\mutate_body {exp}, false
557
+ a\wrap node
558
+
559
+ tblcomprehension: (node) =>
560
+ _, key_exp, value_exp, clauses = unpack node
561
+
562
+ accum = NameProxy "tbl"
563
+ dest = build.chain { base: accum, {"index", key_exp} }
564
+ inner = build.assign_one dest, value_exp
565
+
566
+ build.block_exp {
567
+ build.assign_one accum, build.table!
568
+ construct_comprehension {inner}, clauses
569
+ accum
570
+ }
571
+
572
+ fndef: (node) =>
573
+ smart_node node
574
+ node.body = apply_to_last node.body, implicitly_return self
575
+ node
576
+
577
+ if: (node) => build.block_exp { node }
578
+ with: (node) => build.block_exp { node }
579
+ switch: (node) =>
580
+ build.block_exp { node }
581
+
582
+ -- pull out colon chain
583
+ chain: (node) =>
584
+ stub = node[#node]
585
+ if type(stub) == "table" and stub[1] == "colon_stub"
586
+ table.remove node, #node
587
+
588
+ base_name = NameProxy "base"
589
+ fn_name = NameProxy "fn"
590
+
591
+ is_super = node[2] == "super"
592
+ @transform.value build.block_exp {
593
+ build.assign {
594
+ names: {base_name}
595
+ values: {node}
596
+ }
597
+
598
+ build.assign {
599
+ names: {fn_name}
600
+ values: {
601
+ build.chain { base: base_name, {"dot", stub[2]} }
602
+ }
603
+ }
604
+
605
+ build.fndef {
606
+ args: {{"..."}}
607
+ body: {
608
+ build.chain {
609
+ base: fn_name, {"call", {is_super and "self" or base_name, "..."}}
610
+ }
611
+ }
612
+ }
613
+ }
614
+
615
+ block_exp: (node) =>
616
+ _, body = unpack node
617
+
618
+ fn = nil
619
+ arg_list = {}
620
+
621
+ insert body, Run =>
622
+ if @has_varargs
623
+ insert arg_list, "..."
624
+ insert fn.args, {"..."}
625
+
626
+ fn = smart_node build.fndef body: body
627
+ build.chain { base: {"parens", fn}, {"call", arg_list} }
628
+ }
629
+