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
data/kernel/doc.ay ADDED
@@ -0,0 +1,453 @@
1
+ namespace(atomy)
2
+
3
+ title"Pretty-Printing"
4
+
5
+ data(Doc):
6
+ Empty
7
+ Beside(@left, @right, @space?)
8
+ Above(@above, @below, @overlap?)
9
+ Nest(@body, @depth)
10
+ Text(@value)
11
+
12
+ section("Documents"):
13
+ doc"
14
+ A document is a structural collection of text. The following are the \
15
+ various types of documents, usually created with various combinators \
16
+ provided below.
17
+ "
18
+
19
+ doc"
20
+ The empty document, with a height and width of \hl{0}.
21
+ " spec { => "Class" } for: "Empty"
22
+
23
+ doc"
24
+ A document comprised of two documents positioned beside each other, with \
25
+ an optional space in-between.
26
+ " spec { => "Class" } for: "Beside(@left, @right, @space?)"
27
+
28
+ doc"
29
+ A document comprised of two documents positioned above and below each \
30
+ other, optionally overlapping if possible.
31
+ " spec { => "Class" } for: "Above(@above, @below, @overlap?)"
32
+
33
+ doc"
34
+ A document indented to a given depth.
35
+ " spec { => "Class" } for: "Nest(@body, @depth)"
36
+
37
+ doc"
38
+ A document containing arbitrary text, with a height of \hl{1}.
39
+ " spec { => "Class" } for: "Text(@value)"
40
+
41
+ doc"
42
+ Trivial emptiness check. \hl{true} for \hl{Empty}, \hl{false} for \
43
+ everything else.
44
+ " spec {
45
+ => "Boolean"
46
+ } for {
47
+ "Doc empty?"
48
+
49
+ Doc empty? := false
50
+ Empty empty? := true
51
+ } examples:
52
+ "doc { empty } empty?"
53
+ "doc { text(\"abc\") } empty?"
54
+ "doc { text(\"\") } empty?"
55
+
56
+
57
+ doc"
58
+ Calculate the width of the document, in characters.
59
+ " spec {
60
+ => "Integer"
61
+ } for {
62
+ "Doc width"
63
+
64
+ Empty width := 0
65
+ Text width := @value size
66
+ Beside width :=
67
+ if(@space?)
68
+ then: 1 + @left width + @right width
69
+ else: @left width + @right width
70
+ Nest width := (@body width + @depth)
71
+ Above width := [@above width, @below width] max
72
+ } examples:
73
+ "doc { empty } width"
74
+ "doc { text(\"abc\") } width"
75
+
76
+
77
+ doc"
78
+ Calculate the height of the document, in lines.
79
+
80
+ Note that an empty document has a height of 0.
81
+ " spec {
82
+ => "Integer"
83
+ } for {
84
+ "Doc height"
85
+
86
+ Empty height := 0
87
+ Text height := 1
88
+ Beside height := [@left height, @right height] max
89
+ Above height :=
90
+ if(@overlap? && @below kind-of?(Nest)
91
+ && @below depth > @above width)
92
+ then: @above height + @below height
93
+ else: 1 + @above height + @below height
94
+ Nest height := @body height
95
+ } examples:
96
+ "doc { empty } height"
97
+ "doc { text(\"abc\") } height"
98
+
99
+
100
+ doc"
101
+ Render the document as a \hl{String}.
102
+ " spec {
103
+ => "String"
104
+ } for {
105
+ "Doc render"
106
+
107
+ Text render := @value
108
+ Empty render := ""
109
+ Beside render :=
110
+ if(@space?)
111
+ then: @left render + " " + @right render
112
+ else: @left render + @right render
113
+ Above render := do:
114
+ a = @above render
115
+ b = @below render
116
+
117
+ if(@overlap? && @below kind-of?(Nest) &&
118
+ @below depth > @above width)
119
+ then:
120
+ b slice!(0, a size)
121
+ a + b
122
+ else:
123
+ a + "\n" + b
124
+ Nest render := do:
125
+ b = @body render
126
+ x = ""
127
+ b each-line [l]:
128
+ x << " " * @depth + l
129
+ x
130
+ } examples:
131
+ "doc { empty } render"
132
+ "doc { text(\"abc\") } render"
133
+ "'(1 + 1) pretty render"
134
+
135
+
136
+ section("Constructing"):
137
+ doc"
138
+ Position one document beside another, separated by a space, unless either\
139
+ side is empty.
140
+ " spec {
141
+ => "Doc"
142
+ } for {
143
+ "(left: Doc) <+> (right: Doc)"
144
+
145
+ (l: Doc) <+> (r: Doc) := Beside new(l, r, true)
146
+ (d: Doc) <+> Empty := d
147
+ Empty <+> (d: Doc) := d
148
+ (l: Doc) <+> (n: Nest) := (l <+> n body)
149
+ (l: Doc) <+> (a: Above) := do:
150
+ first = l <+> a above
151
+ rest = a below nest(l width + 1)
152
+ Above new(first, rest, a overlap?)
153
+ } examples:
154
+ "doc { text(\"x\") <+> value(42) }"
155
+ "doc { empty <+> value(42) }"
156
+
157
+
158
+ doc"
159
+ Position one document beside another unless either side is empty.
160
+ " spec {
161
+ => "Doc"
162
+ } for {
163
+ "(left: Doc) <> (right: Doc)"
164
+
165
+ (l: Doc) <> (r: Doc) := Beside new(l, r, false)
166
+ (d: Doc) <> Empty := d
167
+ Empty <> (d: Doc) := d
168
+ (l: Doc) <> (n: Nest) := l <> n body
169
+ (l: Doc) <> (a: Above) := do:
170
+ first = l <> a above
171
+ rest = a below nest(l width)
172
+ Above new(first, rest, a overlap?)
173
+ } examples:
174
+ "doc { text(\"x\") <> value(42) }"
175
+ "doc { empty <> value(42) }"
176
+
177
+
178
+ doc"
179
+ Position one document above another, unless either are empty.
180
+
181
+ If the last line of the first argument stops at least one position before\
182
+ the first line of the second begins, these two lines are overlapped.
183
+ " spec {
184
+ => "Doc"
185
+ } for {
186
+ "(above: Doc) // (below: Doc)"
187
+
188
+ (a: Doc) // (b: Doc) := Above new(a, b, true)
189
+ (a: Doc) // Empty := a
190
+ Empty // (b: Doc) := b
191
+ } examples:
192
+ "doc { text(\"hi\") // text(\"there\") nest(1) }"
193
+ "doc { text(\"hi\") // text(\"there\") nest(5) }"
194
+
195
+
196
+ doc"
197
+ Position one document above another, without overlapping, unless either \
198
+ are empty.
199
+ " spec {
200
+ => "Doc"
201
+ } for {
202
+ "(above: Doc) /+/ (below: Doc)"
203
+
204
+ (a: Doc) /+/ (b: Doc) := Above new(a, b, false)
205
+ (a: Doc) /+/ Empty := a
206
+ Empty /+/ (b: Doc) := b
207
+ } examples:
208
+ "doc { text(\"hi\") /+/ text(\"there\") nest(1) }"
209
+ "doc { text(\"hi\") /+/ text(\"there\") nest(5) }"
210
+
211
+
212
+ doc"
213
+ Indent the document to the given \hl{depth}. For \hl{Nest}, this just \
214
+ increases its indentation level.
215
+ " spec {
216
+ "depth is-a?(Integer)"
217
+ => "Doc"
218
+ } for {
219
+ "Doc nest(depth)"
220
+
221
+ Nest nest(i) := Nest new(@body, @depth + i)
222
+ (d: Doc) nest(i) := Nest new(d, i)
223
+ } examples:
224
+ "doc { text(\"hi\") nest(5) }"
225
+ "doc { text(\"hi\") nest(5) nest(6) }"
226
+
227
+
228
+ doc"
229
+ Intersperse \hl{delimiter} document through \hl{documents}.
230
+ " spec {
231
+ "documents all?(&#is-a?(Doc))"
232
+ => "List"
233
+ } for {
234
+ "(delimiter: Doc) punctuate(documents: List)"
235
+
236
+ Doc punctuate([]) := []
237
+ Doc punctuate([d]) := [d]
238
+ (delim: Doc) punctuate(d . ds) :=
239
+ (delim punctuate(ds)) unshift(d <> delim)
240
+ } examples:
241
+ "doc { semi punctuate([value(1), value(2), value(3)]) }"
242
+ "doc { hsep(semi punctuate([value(1), value(2), value(3)])) }"
243
+
244
+
245
+ section("Helpers"):
246
+ doc"
247
+ Shortcut for \hl{Doc onto(&body)}. This provides the various helper \
248
+ methods below, which are also available in the \hl{Pretty} module.
249
+ " for:
250
+ "doc(&body)"
251
+ macro(doc(&body)):
252
+ `(Doc onto(&~body))
253
+
254
+ module(Pretty):
255
+ section("Shortcuts"):
256
+ doc"
257
+ These shortcuts are primarily for quickly creating \hl{Text} \
258
+ documents, especially for things commonly found in syntax.
259
+ "
260
+
261
+ doc"
262
+ Create a \hl{Text} document with the given contents.
263
+ " spec {
264
+ "s is-a?(String)"
265
+ => "Doc"
266
+ } for:
267
+ "text(s)"
268
+ text(s) := Text new(s)
269
+
270
+ doc"
271
+ Create a \hl{Text} document with \hl{x inspect}.
272
+ " spec {
273
+ => "Doc"
274
+ } for:
275
+ "value(x)"
276
+ value(x) := Text new(x inspect)
277
+
278
+ doc"
279
+ Shortcut for \hl{text(\";\")}.
280
+ " spec {
281
+ => "Doc"
282
+ } for:
283
+ "semi"
284
+ semi := text(";")
285
+
286
+ doc"
287
+ Shortcut for \hl{text(\",\")}.
288
+ " spec {
289
+ => "Doc"
290
+ } for:
291
+ "comma"
292
+ comma := text(",")
293
+
294
+ doc"
295
+ Shortcut for \hl{text(\":\")}.
296
+ " spec {
297
+ => "Doc"
298
+ } for:
299
+ "colon"
300
+ colon := text(":")
301
+
302
+ doc"
303
+ Shortcut for \hl{text(\" \")}.
304
+ " spec {
305
+ => "Doc"
306
+ } for:
307
+ "space"
308
+ space := text(" ")
309
+
310
+ doc"
311
+ Shortcut for \hl{text(\"=\")}.
312
+ " spec {
313
+ => "Doc"
314
+ } for:
315
+ "equals"
316
+ equals := text("=")
317
+
318
+ doc"
319
+ Shortcut for \hl{text(\"(\")}.
320
+ " spec {
321
+ => "Doc"
322
+ } for:
323
+ "lparen"
324
+ lparen := text("(")
325
+
326
+ doc"
327
+ Shortcut for \hl{text(\")\")}.
328
+ " spec {
329
+ => "Doc"
330
+ } for:
331
+ "rparen"
332
+ rparen := text(")")
333
+
334
+ doc"
335
+ Shortcut for \hl{text(\"[\")}.
336
+ " spec {
337
+ => "Doc"
338
+ } for:
339
+ "lbrack"
340
+ lbrack := text("[")
341
+
342
+ doc"
343
+ Shortcut for \hl{text(\"]\")}.
344
+ " spec {
345
+ => "Doc"
346
+ } for:
347
+ "rbrack"
348
+ rbrack := text("]")
349
+
350
+ doc"
351
+ Shortcut for \hl{text(\"\{\")}.
352
+ " spec {
353
+ => "Doc"
354
+ } for:
355
+ "lbrace"
356
+ lbrace := text("{")
357
+
358
+ doc"
359
+ Shortcut for \hl{text(\"\}\")}.
360
+ " spec {
361
+ => "Doc"
362
+ } for:
363
+ "rbrace"
364
+ rbrace := text("}")
365
+
366
+ section("Wrapping"):
367
+ doc"
368
+ More shortcuts for common cases in pretty-printing, dealing with \
369
+ wrapping a document in delimiters.
370
+ "
371
+
372
+ doc"
373
+ Wrap a document in parentheses.
374
+ " spec {
375
+ => "Doc"
376
+ } for:
377
+ "parens(d)"
378
+ parens(d) := lparen <> d <> rparen
379
+
380
+ doc"
381
+ Wrap a document in brackets (\code{[]}).
382
+ " spec {
383
+ => "Doc"
384
+ } for:
385
+ "brackets(d: Doc)"
386
+ brackets(d) := lbrack <> d <> rbrack
387
+
388
+ doc"
389
+ Wrap a document in braces (\code{\{\}}).
390
+ " spec {
391
+ => "Doc"
392
+ } for:
393
+ "braces(d: Doc)"
394
+ braces(d) := lbrace <> d <> rbrace
395
+
396
+ doc"
397
+ Wrap a document in single-quotes.
398
+ " spec {
399
+ => "Doc"
400
+ } for:
401
+ "quotes(d: Doc)"
402
+ quotes(d) := text("'") <> d <> text("'")
403
+
404
+ doc"
405
+ Wrap a document in double-quotes.
406
+ " spec {
407
+ => "Doc"
408
+ } for:
409
+ "double-quotes(d: Doc)"
410
+ double-quotes(d) := text("\"") <> d <> text("\"")
411
+
412
+ section("Combining"):
413
+ doc"
414
+ Helpers for creating a single document from many.
415
+ "
416
+
417
+ doc"
418
+ An empty document. The identity for \hl{<>}, \hl{<+>}, \hl{//}, \
419
+ \hl{/+/}, and anywhere in the following methods.
420
+ " spec {
421
+ => "Doc"
422
+ } for:
423
+ "empty"
424
+ empty := Empty new
425
+
426
+ doc"
427
+ Reduce a list of documents with \hl{<>}.
428
+ " spec {
429
+ "ds all?(&#is-a?(Doc))"
430
+ => "Doc"
431
+ } for:
432
+ "hcat(ds)"
433
+ hcat(ds) := ds inject(empty) [a, b]: a <> b
434
+
435
+ doc"
436
+ Reduce a list of documents with \hl{<+>}.
437
+ " spec {
438
+ "ds all?(&#is-a?(Doc))"
439
+ => "Doc"
440
+ } for:
441
+ "hsep(ds)"
442
+ hsep(ds) := ds inject(empty) [a, b]: a <+> b
443
+
444
+ doc"
445
+ Reduce a list of documents with \hl{//}.
446
+ " spec {
447
+ "ds all?(&#is-a?(Doc))"
448
+ => "Doc"
449
+ } for:
450
+ "vcat(ds)"
451
+ vcat(ds) := ds inject(empty) [a, b]: a // b
452
+
453
+ Doc extend(Pretty)