atomy 0.1.1

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 (99) hide show
  1. data/COPYING +30 -0
  2. data/README.md +1 -0
  3. data/bin/atomy +134 -0
  4. data/kernel/block.ay +30 -0
  5. data/kernel/boot.ay +10 -0
  6. data/kernel/comparison.ay +61 -0
  7. data/kernel/concurrency.ay +84 -0
  8. data/kernel/condition.ay +277 -0
  9. data/kernel/control-flow.ay +222 -0
  10. data/kernel/cosmetics.ay +3 -0
  11. data/kernel/data-delta.ay +105 -0
  12. data/kernel/data.ay +56 -0
  13. data/kernel/define.ay +93 -0
  14. data/kernel/doc.ay +453 -0
  15. data/kernel/documentation.ay +135 -0
  16. data/kernel/dynamic.ay +42 -0
  17. data/kernel/errors.ay +6 -0
  18. data/kernel/format.ay +13 -0
  19. data/kernel/format/data.ay +89 -0
  20. data/kernel/format/formatter.ay +345 -0
  21. data/kernel/format/parser.ay +13 -0
  22. data/kernel/hashes.ay +39 -0
  23. data/kernel/io.ay +244 -0
  24. data/kernel/namespaces.ay +63 -0
  25. data/kernel/node.ay +48 -0
  26. data/kernel/operators.ay +28 -0
  27. data/kernel/particles.ay +53 -0
  28. data/kernel/patterns.ay +256 -0
  29. data/kernel/precision.ay +148 -0
  30. data/kernel/pretty.ay +283 -0
  31. data/kernel/repl.ay +140 -0
  32. data/kernel/therie.ay +204 -0
  33. data/lib/ast/binary_send.rb +44 -0
  34. data/lib/ast/block.rb +268 -0
  35. data/lib/ast/constant.rb +88 -0
  36. data/lib/ast/internal/assign.rb +19 -0
  37. data/lib/ast/internal/block_pass.rb +21 -0
  38. data/lib/ast/internal/catch.rb +247 -0
  39. data/lib/ast/internal/class.rb +30 -0
  40. data/lib/ast/internal/class_variable.rb +23 -0
  41. data/lib/ast/internal/define.rb +174 -0
  42. data/lib/ast/internal/ensure.rb +135 -0
  43. data/lib/ast/internal/file.rb +14 -0
  44. data/lib/ast/internal/global_variable.rb +20 -0
  45. data/lib/ast/internal/if_then_else.rb +24 -0
  46. data/lib/ast/internal/instance_variable.rb +17 -0
  47. data/lib/ast/internal/let_macro.rb +35 -0
  48. data/lib/ast/internal/macro_quote.rb +23 -0
  49. data/lib/ast/internal/match.rb +53 -0
  50. data/lib/ast/internal/module.rb +30 -0
  51. data/lib/ast/internal/pattern.rb +17 -0
  52. data/lib/ast/internal/return.rb +29 -0
  53. data/lib/ast/internal/set.rb +19 -0
  54. data/lib/ast/internal/singleton_class.rb +18 -0
  55. data/lib/ast/internal/splat.rb +14 -0
  56. data/lib/ast/internal/when.rb +24 -0
  57. data/lib/ast/list.rb +25 -0
  58. data/lib/ast/macro.rb +37 -0
  59. data/lib/ast/node.rb +599 -0
  60. data/lib/ast/operator.rb +21 -0
  61. data/lib/ast/particle.rb +13 -0
  62. data/lib/ast/primitive.rb +20 -0
  63. data/lib/ast/quasi_quote.rb +20 -0
  64. data/lib/ast/quote.rb +13 -0
  65. data/lib/ast/send.rb +104 -0
  66. data/lib/ast/splice.rb +32 -0
  67. data/lib/ast/string.rb +23 -0
  68. data/lib/ast/unary.rb +44 -0
  69. data/lib/ast/unquote.rb +45 -0
  70. data/lib/ast/variable.rb +64 -0
  71. data/lib/atomy.kpeg.rb +3995 -0
  72. data/lib/code_loader.rb +137 -0
  73. data/lib/compiler/compiler.rb +155 -0
  74. data/lib/compiler/stages.rb +81 -0
  75. data/lib/formatter.kpeg.rb +1394 -0
  76. data/lib/macros.rb +317 -0
  77. data/lib/method.rb +261 -0
  78. data/lib/namespace.rb +236 -0
  79. data/lib/parser.rb +28 -0
  80. data/lib/patterns.rb +276 -0
  81. data/lib/patterns/any.rb +21 -0
  82. data/lib/patterns/attribute.rb +59 -0
  83. data/lib/patterns/block_pass.rb +54 -0
  84. data/lib/patterns/constant.rb +33 -0
  85. data/lib/patterns/default.rb +44 -0
  86. data/lib/patterns/head_tail.rb +63 -0
  87. data/lib/patterns/list.rb +77 -0
  88. data/lib/patterns/match.rb +45 -0
  89. data/lib/patterns/named.rb +55 -0
  90. data/lib/patterns/named_class.rb +46 -0
  91. data/lib/patterns/named_global.rb +46 -0
  92. data/lib/patterns/named_instance.rb +46 -0
  93. data/lib/patterns/particle.rb +29 -0
  94. data/lib/patterns/quasi_quote.rb +184 -0
  95. data/lib/patterns/quote.rb +33 -0
  96. data/lib/patterns/singleton_class.rb +31 -0
  97. data/lib/patterns/splat.rb +57 -0
  98. data/lib/util.rb +37 -0
  99. metadata +164 -0
@@ -0,0 +1,14 @@
1
+ module Atomy
2
+ module AST
3
+ class Splat < Node
4
+ children :value
5
+ generate
6
+
7
+ def bytecode(g)
8
+ pos(g)
9
+ @value.compile(g)
10
+ g.cast_array unless @value.kind_of?(List)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ module Atomy
2
+ module AST
3
+ class When < Node
4
+ children :condition, :then
5
+ generate
6
+
7
+ def bytecode(g)
8
+ done = g.new_label
9
+ nope = g.new_label
10
+
11
+ @condition.compile(g)
12
+ g.gif nope
13
+
14
+ @then.compile(g)
15
+ g.goto done
16
+
17
+ nope.set!
18
+ g.push_nil
19
+
20
+ done.set!
21
+ end
22
+ end
23
+ end
24
+ end
data/lib/ast/list.rb ADDED
@@ -0,0 +1,25 @@
1
+ module Atomy
2
+ module AST
3
+ class List < Node
4
+ children [:elements]
5
+ generate
6
+
7
+ def as_message(send)
8
+ send.dup.tap do |s|
9
+ s.arguments = @elements
10
+ s.method_name = "[]"
11
+ end
12
+ end
13
+
14
+ def bytecode(g)
15
+ pos(g)
16
+
17
+ @elements.each do |e|
18
+ e.compile(g)
19
+ end
20
+
21
+ g.make_array @elements.size
22
+ end
23
+ end
24
+ end
25
+ end
data/lib/ast/macro.rb ADDED
@@ -0,0 +1,37 @@
1
+ module Atomy
2
+ module AST
3
+ class Macro < Node
4
+ children :pattern, :body
5
+ generate
6
+
7
+ def bytecode(g)
8
+ # register macro during compilation too.
9
+ @pattern.register_macro @body
10
+
11
+ done = g.new_label
12
+ skip = g.new_label
13
+
14
+ g.push_cpath_top
15
+ g.find_const :Atomy
16
+ g.find_const :CodeLoader
17
+ g.send :compiled?, 0
18
+ g.git skip
19
+
20
+ load_bytecode(g)
21
+ g.goto done
22
+
23
+ skip.set!
24
+ g.push_nil
25
+
26
+ done.set!
27
+ end
28
+
29
+ def load_bytecode(g)
30
+ pos(g)
31
+ @pattern.construct(g)
32
+ @body.construct(g)
33
+ g.send :register_macro, 1
34
+ end
35
+ end
36
+ end
37
+ end
data/lib/ast/node.rb ADDED
@@ -0,0 +1,599 @@
1
+ module Atomy
2
+ def self.unquote_splice(n)
3
+ n.collect do |x|
4
+ Atomy::AST::Quote.new(x.line, x)
5
+ end.to_node
6
+ end
7
+
8
+ module AST
9
+ module SentientNode
10
+ # hash from attribute to the type of child node it is
11
+ # :normal = normal, required subnode
12
+ # :many = an array of subnodes
13
+ # :optional = optional (might be nil)
14
+ def reset_children
15
+ @@children = {
16
+ :required => [],
17
+ :many => [],
18
+ :optional => []
19
+ }
20
+ end
21
+
22
+ def reset_attributes
23
+ @@attributes = {
24
+ :required => [],
25
+ :many => [],
26
+ :optional => []
27
+ }
28
+ end
29
+
30
+ def reset_slots
31
+ @@slots = {
32
+ :required => [],
33
+ :many => [],
34
+ :optional => []
35
+ }
36
+ end
37
+
38
+ def inherited(sub)
39
+ sub.reset_children
40
+ sub.reset_attributes
41
+ sub.reset_slots
42
+ end
43
+
44
+ def self.extended(sub)
45
+ sub.reset_children
46
+ sub.reset_attributes
47
+ sub.reset_slots
48
+ end
49
+
50
+ def spec(into, specs)
51
+ specs.each do |s|
52
+ if s.kind_of?(Array)
53
+ if s.size == 2
54
+ into[:optional] << s
55
+ else
56
+ into[:many] << s[0]
57
+ end
58
+ elsif s.to_s[-1] == ??
59
+ into[:optional] << [s.to_s[0..-2].to_sym, "nil"]
60
+ else
61
+ into[:required] << s
62
+ end
63
+ end
64
+ end
65
+
66
+ def attributes(*specs)
67
+ spec(@@attributes, specs)
68
+ end
69
+
70
+ def slots(*specs)
71
+ spec(@@slots, specs)
72
+ end
73
+
74
+ def children(*specs)
75
+ spec(@@children, specs)
76
+ end
77
+
78
+ def many_construct(n)
79
+ x = <<END
80
+ spliced = false
81
+ size = 0
82
+ @#{n}.each do |e|
83
+ if e.kind_of?(::Atomy::AST::Splice) && d == 1
84
+ g.make_array size if size > 0
85
+ e.construct(g, d)
86
+ g.send :+, 1 if size > 0 || spliced
87
+ spliced = true
88
+ size = 0
89
+ else
90
+ e.construct(g, d)
91
+ size += 1
92
+ end
93
+ end
94
+
95
+ g.make_array size
96
+
97
+ g.send :+, 1 if spliced
98
+ END
99
+ x
100
+ end
101
+
102
+ def generate
103
+ all = []
104
+ args = ""
105
+ (@@children[:required] + @@children[:many] +
106
+ @@attributes[:required] + @@attributes[:many] +
107
+ @@slots[:required] + @@slots[:many]).each do |x|
108
+ all << x.to_s
109
+ args << ", #{x}_"
110
+ end
111
+
112
+ (@@children[:optional] + @@attributes[:optional]).each do |x, d|
113
+ all << x.to_s
114
+ args << ", #{x}_ = #{d}"
115
+ end
116
+
117
+ non_slots = all.dup
118
+ @@slots[:optional].each do |x, d|
119
+ all << x.to_s
120
+ args << ", #{x}_ = #{d}"
121
+ end
122
+
123
+ class_eval <<EOF
124
+ attr_accessor :line#{all.collect { |a| ", :#{a}" }.join}
125
+ EOF
126
+
127
+ class_eval <<EOF
128
+ def initialize(line#{args})
129
+ @line = line
130
+ #{all.collect { |a| "@#{a} = #{a}_" }.join("; ")}
131
+ end
132
+ EOF
133
+
134
+ class_eval <<EOF
135
+ def construct(g, d = nil)
136
+ get(g)
137
+ g.push_int(@line)
138
+
139
+ #{@@children[:required].collect { |n|
140
+ "@#{n}.construct(g, d)"
141
+ }.join("; ")}
142
+
143
+ #{@@children[:many].collect { |n|
144
+ many_construct(n)
145
+ }.join("; ")}
146
+
147
+ #{@@attributes[:required].collect { |a|
148
+ "g.push_literal(@#{a})"
149
+ }.join("; ")}
150
+
151
+ #{@@attributes[:many].collect { |a|
152
+ "@#{a}.each { |n| g.push_literal n }; g.make_array(@#{a}.size)"
153
+ }.join("; ")}
154
+
155
+ #{@@slots[:required].collect { |a|
156
+ "g.push_literal(@#{a})"
157
+ }.join("; ")}
158
+
159
+ #{@@slots[:many].collect { |a|
160
+ "@#{a}.each { |n| g.push_literal n }; g.make_array(@#{a}.size)"
161
+ }.join("; ")}
162
+
163
+ #{@@children[:optional].collect { |n, _|
164
+ "if @#{n}; @#{n}.construct(g, d); else; g.push_nil; end"
165
+ }.join("; ")}
166
+
167
+ #{@@attributes[:optional].collect { |a, _|
168
+ "g.push_literal(@#{a})"
169
+ }.join("; ")}
170
+
171
+ #{@@slots[:optional].collect { |a, _|
172
+ "g.push_literal(@#{a})"
173
+ }.join("; ")}
174
+
175
+ g.send :new, #{all.size + 1}
176
+ end
177
+ EOF
178
+
179
+ class_eval <<EOF
180
+ def ==(b)
181
+ b.kind_of?(#{self.name}) \\
182
+ #{non_slots.collect { |a| " and @#{a} == b.#{a}" }.join}
183
+ end
184
+ EOF
185
+
186
+ req_cs =
187
+ @@children[:required].collect { |n|
188
+ ", @#{n}.recursively(pre, post, :#{n}, &f)"
189
+ }.join
190
+
191
+ many_cs =
192
+ @@children[:many].collect { |n|
193
+ ", @#{n}.each_with_index.collect { |n, i| n.recursively(pre, post, [:#{n}, i], &f) }"
194
+ }.join
195
+
196
+ opt_cs =
197
+ @@children[:optional].collect { |n, _|
198
+ ", @#{n} ? @#{n}.recursively(pre, post, :#{n}, &f) : nil"
199
+ }.join
200
+
201
+ req_as =
202
+ (@@attributes[:required] + @@attributes[:many]).collect { |a|
203
+ ", @#{a}"
204
+ }.join
205
+
206
+ opt_as = @@attributes[:optional].collect { |a, _|
207
+ ", @#{a}"
208
+ }.join
209
+
210
+ req_ss =
211
+ (@@slots[:required] + @@slots[:many]).collect { |a|
212
+ ", @#{a}"
213
+ }.join
214
+
215
+ opt_ss = @@slots[:optional].collect { |a, _|
216
+ ", @#{a}"
217
+ }.join
218
+
219
+ class_eval <<EOF
220
+ def recursively(pre = nil, post = nil, context = nil, &f)
221
+ if pre and pre.arity == 2
222
+ stop = pre.call(self, context)
223
+ elsif pre
224
+ stop = pre.call(self)
225
+ else
226
+ stop = false
227
+ end
228
+
229
+ if stop
230
+ if f.arity == 2
231
+ res = f.call(self, context)
232
+ post.call(context) if post
233
+ return res
234
+ else
235
+ res = f.call(self)
236
+ post.call(context) if post
237
+ return res
238
+ end
239
+ end
240
+
241
+ recursed = #{self.name}.new(
242
+ @line#{req_cs + many_cs + req_as + req_ss + opt_cs + opt_as + opt_ss}
243
+ )
244
+
245
+ if f.arity == 2
246
+ res = f.call(recursed, context)
247
+ else
248
+ res = f.call(recursed)
249
+ end
250
+
251
+ post.call(context) if post
252
+
253
+ res
254
+ end
255
+ EOF
256
+
257
+ class_eval <<EOF
258
+ def bottom?
259
+ #{@@children.values.flatten(1).empty?.inspect}
260
+ end
261
+ EOF
262
+
263
+ attrs =
264
+ @@attributes[:required] + @@attributes[:many] +
265
+ @@attributes[:optional].collect(&:first)
266
+
267
+ class_eval <<EOF
268
+ def details
269
+ #{attrs.inspect}
270
+ end
271
+ EOF
272
+
273
+ slots =
274
+ @@slots[:required] + @@slots[:many] +
275
+ @@slots[:optional].collect(&:first)
276
+
277
+ class_eval <<EOF
278
+ def slots
279
+ #{slots.inspect}
280
+ end
281
+ EOF
282
+
283
+ required = @@children[:required].collect { |c| ", [:\"#{c}\", @#{c}.to_sexp]" }.join
284
+ many = @@children[:many].collect { |c| ", [:\"#{c}\", @#{c}.collect(&:to_sexp)]" }.join
285
+ optional = @@children[:optional].collect { |c, _| ", [:\"#{c}\", @#{c} && @#{c}.to_sexp]" }.join
286
+
287
+ a_required = @@attributes[:required].collect { |c| ", [:\"#{c}\", @#{c}]" }.join
288
+ a_many = @@attributes[:many].collect { |c| ", [:\"#{c}\", @#{c}]" }.join
289
+ a_optional = @@attributes[:optional].collect { |c, _| ", [:\"#{c}\", @#{c}]" }.join
290
+
291
+ class_eval <<EOF
292
+ def to_sexp
293
+ [:"#{self.name.split("::").last.downcase}"#{required}#{many}#{optional}#{a_required}#{a_many}#{a_optional}]
294
+ end
295
+ EOF
296
+
297
+ end
298
+ end
299
+
300
+ module NodeLike
301
+ attr_accessor :line
302
+
303
+ # yield this node's subnodes to a block recursively, and then itself
304
+ # override this if for nodes with children, ie lists
305
+ #
306
+ # stop = predicate to determine whether to stop at a node before
307
+ # recursing into its children
308
+ def recursively(stop = nil, &f)
309
+ f.call(self)
310
+ end
311
+
312
+ # used to construct this expression in a quasiquote
313
+ # g = generator, d = depth
314
+ #
315
+ # quasiquotes should increase depth, unquotes should decrease
316
+ # an unquote at depth 0 should push the unquote's contents rather
317
+ # than itself
318
+ def construct(g, d)
319
+ raise Rubinius::CompileError, "no #construct for #{self}"
320
+ end
321
+
322
+ def through_quotes(pre_ = nil, post_ = nil, &f)
323
+ depth = 0
324
+
325
+ pre = proc { |x, c|
326
+ (pre_ && pre_.call(*([x, c, depth][0, pre_.arity])) && depth == 0) || \
327
+ x.kind_of?(AST::QuasiQuote) || \
328
+ x.unquote?
329
+ }
330
+
331
+ rpre = proc { |x, c|
332
+ pre_ && pre_.call(*([x, c, 0][0, pre_.arity]))
333
+ }
334
+
335
+ post = proc { post_ && post_.call }
336
+
337
+ action = proc { |e, c|
338
+ if e.unquote?
339
+ depth -= 1
340
+ if depth == 0
341
+ depth += 1
342
+ u = e.expression.recursively(rpre, post_, :unquoted, &f)
343
+ next e.class.new(
344
+ e.line,
345
+ u
346
+ )
347
+ end
348
+
349
+ u = e.expression.recursively(pre, post, :expression, &action)
350
+ depth += 1
351
+ e.class.new(
352
+ e.line,
353
+ u
354
+ )
355
+ elsif e.kind_of?(Atomy::AST::QuasiQuote)
356
+ depth += 1
357
+ q = e.expression.recursively(pre, post, :expression, &action)
358
+ depth -= 1
359
+ Atomy::AST::QuasiQuote.new(
360
+ e.line,
361
+ q
362
+ )
363
+ else
364
+ if depth == 0
365
+ f.call(e)
366
+ else
367
+ e
368
+ end
369
+ end
370
+ }
371
+
372
+ recursively(pre, post, &action)
373
+ end
374
+
375
+ def unquote(d)
376
+ return unless d
377
+ d - 1
378
+ end
379
+
380
+ def quote(d)
381
+ return unless d
382
+ d + 1
383
+ end
384
+
385
+ def get(g)
386
+ g.push_cpath_top
387
+ self.class.name.split("::").each do |n|
388
+ g.find_const n.to_sym
389
+ end
390
+ end
391
+
392
+ def to_node
393
+ self
394
+ end
395
+
396
+ def to_send
397
+ Send.new(
398
+ @line,
399
+ Primitive.new(@line, :self),
400
+ [],
401
+ self,
402
+ nil,
403
+ nil,
404
+ true
405
+ )
406
+ end
407
+
408
+ def method_name
409
+ nil
410
+ end
411
+
412
+ def namespace_symbol
413
+ method_name && method_name.to_sym
414
+ end
415
+
416
+ def unquote?
417
+ false
418
+ end
419
+
420
+ def caller
421
+ Atomy::AST::Send.new(
422
+ @line,
423
+ self,
424
+ [],
425
+ Atomy::AST::Variable.new(@line, "call"),
426
+ nil,
427
+ nil
428
+ )
429
+ end
430
+
431
+ def expand
432
+ Atomy::Macro.expand(self)
433
+ end
434
+
435
+ def evaluate(onto = nil)
436
+ Atomy::Compiler.evaluate_node(self, onto, TOPLEVEL_BINDING)
437
+ end
438
+
439
+ def resolve
440
+ ns = Atomy::Namespace.get
441
+ return self if @namespace || !ns
442
+
443
+ case self
444
+ when Atomy::AST::Send, Atomy::AST::Variable,
445
+ Atomy::AST::BinarySend, Atomy::AST::Unary
446
+ y = dup
447
+ if n = ns.resolve(namespace_symbol)
448
+ y.namespace = n.to_s
449
+ else
450
+ y.namespace = "_"
451
+ end
452
+ y
453
+ else
454
+ self
455
+ end
456
+ end
457
+
458
+ def prepare
459
+ self
460
+ end
461
+
462
+ def compile(g)
463
+ prepare.bytecode(g)
464
+ end
465
+
466
+ def load_bytecode(g)
467
+ compile(g)
468
+ end
469
+
470
+ def to_pattern
471
+ expand.pattern
472
+ end
473
+
474
+ def as_message(send)
475
+ raise "unknown message name: #{self.to_sexp.inspect}"
476
+ end
477
+ end
478
+
479
+ class Node < Rubinius::AST::Node
480
+ include NodeLike
481
+ extend SentientNode
482
+
483
+ def bytecode(g)
484
+ raise "no #bytecode for #{self.class.name}"
485
+ end
486
+ end
487
+
488
+ class Tree
489
+ attr_accessor :nodes
490
+
491
+ def initialize(nodes)
492
+ @nodes = Array(nodes)
493
+ end
494
+
495
+ def bytecode(g)
496
+ @nodes.each { |n| n.compile(g) }
497
+ end
498
+
499
+ def collect
500
+ Tree.new(@nodes.collect { |n| yield n })
501
+ end
502
+ end
503
+
504
+ class Script < Rubinius::AST::Container
505
+ def initialize(body)
506
+ super body
507
+ @name = :__script__
508
+ end
509
+
510
+ def bytecode(g)
511
+ super(g)
512
+
513
+ container_bytecode(g) do
514
+ g.push_state self
515
+
516
+ load = g.new_label
517
+ start = g.new_label
518
+ done = g.new_label
519
+
520
+ g.push_cpath_top
521
+ g.find_const :Atomy
522
+ g.find_const :CodeLoader
523
+ g.send :reason, 0
524
+ g.push_literal :load
525
+ g.send :==, 1
526
+ g.git load
527
+
528
+ start.set!
529
+ @body.bytecode g
530
+ g.goto done
531
+
532
+ load.set!
533
+ Atomy::CodeLoader.when_load.each do |e, c|
534
+ if c
535
+ skip = g.new_label
536
+
537
+ g.push_cpath_top
538
+ g.find_const :Atomy
539
+ g.find_const :CodeLoader
540
+ g.send :compiled?, 0
541
+ g.git skip
542
+
543
+ e.load_bytecode(g)
544
+ g.pop
545
+
546
+ skip.set!
547
+ else
548
+ e.load_bytecode(g)
549
+ g.pop
550
+ end
551
+ end
552
+ g.goto start
553
+
554
+ done.set!
555
+ g.pop
556
+ g.push :true
557
+ g.ret
558
+ g.pop_state
559
+ end
560
+ end
561
+ end
562
+ end
563
+ end
564
+
565
+ class Object
566
+ def to_node
567
+ raise "not a node: #{self.inspect}"
568
+ end
569
+ end
570
+
571
+ class Integer
572
+ def to_node
573
+ Atomy::AST::Primitive.new -1, self
574
+ end
575
+ end
576
+
577
+ class String
578
+ def to_node
579
+ Atomy::AST::String.new -1, self
580
+ end
581
+ end
582
+
583
+ class Array
584
+ def to_node
585
+ Atomy::AST::List.new -1, collect(&:to_node)
586
+ end
587
+ end
588
+
589
+ class NilClass
590
+ def to_node
591
+ Atomy::AST::Primitive.new -1, :nil
592
+ end
593
+ end
594
+
595
+ class Symbol
596
+ def to_node
597
+ Atomy::AST::Particle.new -1, self
598
+ end
599
+ end