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.
- data/COPYING +30 -0
- data/README.md +1 -0
- data/bin/atomy +134 -0
- data/kernel/block.ay +30 -0
- data/kernel/boot.ay +10 -0
- data/kernel/comparison.ay +61 -0
- data/kernel/concurrency.ay +84 -0
- data/kernel/condition.ay +277 -0
- data/kernel/control-flow.ay +222 -0
- data/kernel/cosmetics.ay +3 -0
- data/kernel/data-delta.ay +105 -0
- data/kernel/data.ay +56 -0
- data/kernel/define.ay +93 -0
- data/kernel/doc.ay +453 -0
- data/kernel/documentation.ay +135 -0
- data/kernel/dynamic.ay +42 -0
- data/kernel/errors.ay +6 -0
- data/kernel/format.ay +13 -0
- data/kernel/format/data.ay +89 -0
- data/kernel/format/formatter.ay +345 -0
- data/kernel/format/parser.ay +13 -0
- data/kernel/hashes.ay +39 -0
- data/kernel/io.ay +244 -0
- data/kernel/namespaces.ay +63 -0
- data/kernel/node.ay +48 -0
- data/kernel/operators.ay +28 -0
- data/kernel/particles.ay +53 -0
- data/kernel/patterns.ay +256 -0
- data/kernel/precision.ay +148 -0
- data/kernel/pretty.ay +283 -0
- data/kernel/repl.ay +140 -0
- data/kernel/therie.ay +204 -0
- data/lib/ast/binary_send.rb +44 -0
- data/lib/ast/block.rb +268 -0
- data/lib/ast/constant.rb +88 -0
- data/lib/ast/internal/assign.rb +19 -0
- data/lib/ast/internal/block_pass.rb +21 -0
- data/lib/ast/internal/catch.rb +247 -0
- data/lib/ast/internal/class.rb +30 -0
- data/lib/ast/internal/class_variable.rb +23 -0
- data/lib/ast/internal/define.rb +174 -0
- data/lib/ast/internal/ensure.rb +135 -0
- data/lib/ast/internal/file.rb +14 -0
- data/lib/ast/internal/global_variable.rb +20 -0
- data/lib/ast/internal/if_then_else.rb +24 -0
- data/lib/ast/internal/instance_variable.rb +17 -0
- data/lib/ast/internal/let_macro.rb +35 -0
- data/lib/ast/internal/macro_quote.rb +23 -0
- data/lib/ast/internal/match.rb +53 -0
- data/lib/ast/internal/module.rb +30 -0
- data/lib/ast/internal/pattern.rb +17 -0
- data/lib/ast/internal/return.rb +29 -0
- data/lib/ast/internal/set.rb +19 -0
- data/lib/ast/internal/singleton_class.rb +18 -0
- data/lib/ast/internal/splat.rb +14 -0
- data/lib/ast/internal/when.rb +24 -0
- data/lib/ast/list.rb +25 -0
- data/lib/ast/macro.rb +37 -0
- data/lib/ast/node.rb +599 -0
- data/lib/ast/operator.rb +21 -0
- data/lib/ast/particle.rb +13 -0
- data/lib/ast/primitive.rb +20 -0
- data/lib/ast/quasi_quote.rb +20 -0
- data/lib/ast/quote.rb +13 -0
- data/lib/ast/send.rb +104 -0
- data/lib/ast/splice.rb +32 -0
- data/lib/ast/string.rb +23 -0
- data/lib/ast/unary.rb +44 -0
- data/lib/ast/unquote.rb +45 -0
- data/lib/ast/variable.rb +64 -0
- data/lib/atomy.kpeg.rb +3995 -0
- data/lib/code_loader.rb +137 -0
- data/lib/compiler/compiler.rb +155 -0
- data/lib/compiler/stages.rb +81 -0
- data/lib/formatter.kpeg.rb +1394 -0
- data/lib/macros.rb +317 -0
- data/lib/method.rb +261 -0
- data/lib/namespace.rb +236 -0
- data/lib/parser.rb +28 -0
- data/lib/patterns.rb +276 -0
- data/lib/patterns/any.rb +21 -0
- data/lib/patterns/attribute.rb +59 -0
- data/lib/patterns/block_pass.rb +54 -0
- data/lib/patterns/constant.rb +33 -0
- data/lib/patterns/default.rb +44 -0
- data/lib/patterns/head_tail.rb +63 -0
- data/lib/patterns/list.rb +77 -0
- data/lib/patterns/match.rb +45 -0
- data/lib/patterns/named.rb +55 -0
- data/lib/patterns/named_class.rb +46 -0
- data/lib/patterns/named_global.rb +46 -0
- data/lib/patterns/named_instance.rb +46 -0
- data/lib/patterns/particle.rb +29 -0
- data/lib/patterns/quasi_quote.rb +184 -0
- data/lib/patterns/quote.rb +33 -0
- data/lib/patterns/singleton_class.rb +31 -0
- data/lib/patterns/splat.rb +57 -0
- data/lib/util.rb +37 -0
- 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)
|