atomy 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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)