atomy 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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/patterns.ay
ADDED
@@ -0,0 +1,256 @@
|
|
1
|
+
namespace(atomy)
|
2
|
+
|
3
|
+
module(Atomy::Patterns):
|
4
|
+
export:
|
5
|
+
class(RuntimeClass < Pattern):
|
6
|
+
initialize(@body, @name) := #ok
|
7
|
+
|
8
|
+
construct(g) := do:
|
9
|
+
get(g)
|
10
|
+
@body construct(g)
|
11
|
+
@body compile(g)
|
12
|
+
g send(#name, 0)
|
13
|
+
g send(#new, 2)
|
14
|
+
|
15
|
+
(== b) :=
|
16
|
+
b kind-of?(RuntimeClass) &&
|
17
|
+
@body == b body &&
|
18
|
+
@name == b name
|
19
|
+
|
20
|
+
target(g) :=
|
21
|
+
@body compile(g)
|
22
|
+
|
23
|
+
matches?(g) := do:
|
24
|
+
Atomy const-from-string(g, @name)
|
25
|
+
g swap
|
26
|
+
g kind-of
|
27
|
+
|
28
|
+
class(Predicate < Pattern):
|
29
|
+
initialize(@pattern, @test) := #ok
|
30
|
+
|
31
|
+
construct(g) := do:
|
32
|
+
get(g)
|
33
|
+
@pattern construct(g)
|
34
|
+
@test construct(g)
|
35
|
+
g send(#new, 2)
|
36
|
+
|
37
|
+
(== b) :=
|
38
|
+
b kind-of?(Predicate) &&
|
39
|
+
@pattern == b pattern &&
|
40
|
+
@test == b test
|
41
|
+
|
42
|
+
target(g) := @pattern target(g)
|
43
|
+
|
44
|
+
matches?(g) := do:
|
45
|
+
mismatch = g new-label
|
46
|
+
done = g new-label
|
47
|
+
|
48
|
+
g dup
|
49
|
+
@pattern matches?(g)
|
50
|
+
g gif(mismatch)
|
51
|
+
|
52
|
+
`{ ~@test } bytecode(g)
|
53
|
+
g send(#block, 0)
|
54
|
+
g swap
|
55
|
+
g send(#call-on-instance, 1)
|
56
|
+
g goto(done)
|
57
|
+
|
58
|
+
mismatch set!
|
59
|
+
g pop
|
60
|
+
g push-false
|
61
|
+
|
62
|
+
done set!
|
63
|
+
|
64
|
+
deconstruct(g, locals = Hash new) :=
|
65
|
+
@pattern deconstruct(g, locals)
|
66
|
+
|
67
|
+
local-names := @pattern local-names
|
68
|
+
|
69
|
+
bindings := @pattern bindings
|
70
|
+
|
71
|
+
class(With < Pattern):
|
72
|
+
initialize(@expression, @pattern) := #ok
|
73
|
+
|
74
|
+
construct(g) := do:
|
75
|
+
get(g)
|
76
|
+
@expression construct(g)
|
77
|
+
@pattern construct(g)
|
78
|
+
g send(#new, 2)
|
79
|
+
|
80
|
+
(== b) :=
|
81
|
+
b kind-of?(With) &&
|
82
|
+
@expression == b expression &&
|
83
|
+
@pattern == b pattern
|
84
|
+
|
85
|
+
target(g) := Any new target(g)
|
86
|
+
|
87
|
+
matches?(g) := do:
|
88
|
+
`{ ~@expression } bytecode(g)
|
89
|
+
g send(#block, 0)
|
90
|
+
g swap
|
91
|
+
g send(#call-on-instance, 1)
|
92
|
+
@pattern matches?(g)
|
93
|
+
|
94
|
+
deconstruct(g, locals = Hash new) := do:
|
95
|
+
`{ ~@expression } bytecode(g)
|
96
|
+
g send(#block, 0)
|
97
|
+
g swap
|
98
|
+
g send(#call-on-instance, 1)
|
99
|
+
@pattern deconstruct(g, locals)
|
100
|
+
|
101
|
+
local-names := @pattern local-names
|
102
|
+
|
103
|
+
bindings := @pattern bindings
|
104
|
+
|
105
|
+
class(And < Pattern):
|
106
|
+
initialize(@a, @b) := #ok
|
107
|
+
|
108
|
+
construct(g) := do:
|
109
|
+
get(g)
|
110
|
+
@a construct(g)
|
111
|
+
@b construct(g)
|
112
|
+
g send(#new, 2)
|
113
|
+
|
114
|
+
(== b) :=
|
115
|
+
b kind-of?(And) &&
|
116
|
+
@a == b a &&
|
117
|
+
@b == b b
|
118
|
+
|
119
|
+
target(g) :=
|
120
|
+
@a target(g)
|
121
|
+
|
122
|
+
matches?(g) := do:
|
123
|
+
mismatch = g new-label
|
124
|
+
done = g new-label
|
125
|
+
|
126
|
+
g dup
|
127
|
+
@a matches?(g)
|
128
|
+
g gif(mismatch)
|
129
|
+
|
130
|
+
@b matches?(g)
|
131
|
+
g dup
|
132
|
+
g git(done)
|
133
|
+
|
134
|
+
mismatch set!
|
135
|
+
g pop
|
136
|
+
g push-false
|
137
|
+
|
138
|
+
done set!
|
139
|
+
|
140
|
+
deconstruct(g, locals = Hash new) := do:
|
141
|
+
g dup
|
142
|
+
@a deconstruct(g, locals)
|
143
|
+
@b deconstruct(g, locals)
|
144
|
+
|
145
|
+
local-names := [@a local-names + @b local-names] uniq
|
146
|
+
|
147
|
+
class(Or < Pattern):
|
148
|
+
initialize(@a, @b) := #ok
|
149
|
+
|
150
|
+
construct(g) := do:
|
151
|
+
get(g)
|
152
|
+
@a construct(g)
|
153
|
+
@b construct(g)
|
154
|
+
g send(#new, 2)
|
155
|
+
|
156
|
+
(== b) :=
|
157
|
+
b kind-of?(Or) &&
|
158
|
+
@a == b a &&
|
159
|
+
@b == b b
|
160
|
+
|
161
|
+
target(g) :=
|
162
|
+
@a target(g)
|
163
|
+
|
164
|
+
matches?(g) := do:
|
165
|
+
matched = g new-label
|
166
|
+
done = g new-label
|
167
|
+
|
168
|
+
g dup
|
169
|
+
@a matches?(g)
|
170
|
+
g git(matched)
|
171
|
+
|
172
|
+
@b matches?(g)
|
173
|
+
g dup
|
174
|
+
g gif(done)
|
175
|
+
|
176
|
+
matched set!
|
177
|
+
g pop
|
178
|
+
g push-true
|
179
|
+
|
180
|
+
done set!
|
181
|
+
|
182
|
+
deconstruct(g, locals = #[]) := do:
|
183
|
+
b = g new-label
|
184
|
+
done = g new-label
|
185
|
+
|
186
|
+
g dup
|
187
|
+
g dup
|
188
|
+
@a matches?(g)
|
189
|
+
g gif(b)
|
190
|
+
|
191
|
+
@a deconstruct(g, locals)
|
192
|
+
g pop
|
193
|
+
g goto(done)
|
194
|
+
|
195
|
+
b set!
|
196
|
+
g pop
|
197
|
+
@b deconstruct(g, locals)
|
198
|
+
|
199
|
+
done set!
|
200
|
+
|
201
|
+
local-names := [@a local-names + @b local-names] uniq
|
202
|
+
|
203
|
+
|
204
|
+
-- base patterns
|
205
|
+
module(Atomy::AST):
|
206
|
+
export:
|
207
|
+
Variable pattern :=
|
208
|
+
Atomy::Patterns::Named new $:
|
209
|
+
@name
|
210
|
+
Atomy::Patterns::Any new
|
211
|
+
|
212
|
+
Primitive pattern :=
|
213
|
+
Atomy::Patterns::Match new(@value)
|
214
|
+
|
215
|
+
List pattern :=
|
216
|
+
Atomy::Patterns::List new $:
|
217
|
+
@elements collect [e]: e to-pattern
|
218
|
+
|
219
|
+
Constant pattern :=
|
220
|
+
Atomy::Patterns::Constant new(self)
|
221
|
+
|
222
|
+
ScopedConstant pattern :=
|
223
|
+
Atomy::Patterns::Constant new(self)
|
224
|
+
|
225
|
+
ToplevelConstant pattern :=
|
226
|
+
Atomy::Patterns::Constant new(self)
|
227
|
+
|
228
|
+
Quote pattern :=
|
229
|
+
Atomy::Patterns::Quote new(@expression)
|
230
|
+
|
231
|
+
Block pattern :=
|
232
|
+
Atomy::Patterns::SingletonClass new(self)
|
233
|
+
|
234
|
+
Particle pattern :=
|
235
|
+
Atomy::Patterns::Particle new(@name to-sym)
|
236
|
+
|
237
|
+
QuasiQuote pattern :=
|
238
|
+
Atomy::Patterns::QuasiQuote new(self)
|
239
|
+
|
240
|
+
Send pattern :=
|
241
|
+
if(@block)
|
242
|
+
then:
|
243
|
+
Atomy::Patterns::Named new $:
|
244
|
+
@method-name
|
245
|
+
@block contents [0] to-pattern
|
246
|
+
else:
|
247
|
+
Atomy::Patterns::Attribute new $:
|
248
|
+
@receiver
|
249
|
+
@method-name
|
250
|
+
@arguments
|
251
|
+
|
252
|
+
String pattern :=
|
253
|
+
Atomy::Patterns::Match new(@value)
|
254
|
+
|
255
|
+
Node pattern :=
|
256
|
+
raise("unknown pattern: " + self inspect)
|
data/kernel/precision.ay
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
namespace(atomy)
|
2
|
+
|
3
|
+
export:
|
4
|
+
module(Atomy::Patterns):
|
5
|
+
-- pattern precision hierarchy, from least precise to most
|
6
|
+
[ [ Any, BlockPass, Splat, Attribute,
|
7
|
+
NamedClass, NamedGlobal, NamedInstance
|
8
|
+
]
|
9
|
+
|
10
|
+
[Constant, SingletonClass, RuntimeClass]
|
11
|
+
|
12
|
+
[HeadTail]
|
13
|
+
|
14
|
+
[List, QuasiQuote, Particle]
|
15
|
+
|
16
|
+
[Match, Quote]
|
17
|
+
] each-with-index [ps, i]:
|
18
|
+
ps each [a]:
|
19
|
+
a send(#define-method, #precision):
|
20
|
+
i
|
21
|
+
|
22
|
+
Pattern precision := 0
|
23
|
+
|
24
|
+
Named precision := @pattern precision
|
25
|
+
|
26
|
+
Predicate precision :=
|
27
|
+
@pattern precision + 1
|
28
|
+
|
29
|
+
(a: Pattern) <=> (b: Pattern) :=
|
30
|
+
a precision <=> b precision
|
31
|
+
|
32
|
+
(a: BlockPass) <=> (b: BlockPass) :=
|
33
|
+
a pattern <=> b pattern
|
34
|
+
|
35
|
+
-- if one constant is a subclass of another, it is
|
36
|
+
-- higher precision.
|
37
|
+
(a: Constant) <=> (b: Constant) :=
|
38
|
+
condition:
|
39
|
+
(a ancestors nil? || b ancestors nil?) ->
|
40
|
+
0
|
41
|
+
|
42
|
+
(a ancestors first == b ancestors first) ->
|
43
|
+
0
|
44
|
+
|
45
|
+
b ancestors include?(a ancestors first) ->
|
46
|
+
-1
|
47
|
+
|
48
|
+
a ancestors include?(b ancestors first) ->
|
49
|
+
1
|
50
|
+
|
51
|
+
otherwise ->
|
52
|
+
0
|
53
|
+
|
54
|
+
(a: HeadTail) <=> (b: HeadTail) :=
|
55
|
+
Atomy::Patterns
|
56
|
+
compare([a head, a tail], [b head, b tail])
|
57
|
+
|
58
|
+
(a: List) <=> (b: List) :=
|
59
|
+
Atomy::Patterns
|
60
|
+
compare(a patterns, b patterns)
|
61
|
+
|
62
|
+
(a: Splat) <=> (b: Splat) :=
|
63
|
+
a pattern <=> b pattern
|
64
|
+
|
65
|
+
(a: Default) <=> (b: Default) :=
|
66
|
+
a pattern <=> b pattern
|
67
|
+
(d: Default) <=> (p: Pattern) := d pattern <=> p
|
68
|
+
(p: Pattern) <=> (d: Default) := p <=> d pattern
|
69
|
+
|
70
|
+
(a: Named) <=> (b: Named) :=
|
71
|
+
a pattern <=> b pattern
|
72
|
+
(n: Named) <=> (p: Pattern) :=
|
73
|
+
n pattern <=> p
|
74
|
+
(p: Pattern) <=> (n: Named) :=
|
75
|
+
p <=> n pattern
|
76
|
+
|
77
|
+
|
78
|
+
-- equivalence ignores named patterns
|
79
|
+
(a: Named) =~ (b: Named) :=
|
80
|
+
a pattern =~ b pattern
|
81
|
+
Named =~ (p: Pattern) := pattern =~ p
|
82
|
+
Pattern =~ (n: Named) := (=~ n pattern)
|
83
|
+
|
84
|
+
Any =~ Any := true
|
85
|
+
|
86
|
+
(a: BlockPass) =~ (b: BlockPass) :=
|
87
|
+
a pattern =~ b pattern
|
88
|
+
|
89
|
+
(a: Constant) =~ (b: Constant) :=
|
90
|
+
a constant =~ b constant
|
91
|
+
|
92
|
+
(a: Default) =~ (b: Default) :=
|
93
|
+
a pattern =~ b pattern
|
94
|
+
Default =~ (p: Pattern) := pattern =~ p
|
95
|
+
Pattern =~ (n: Default) := (=~ n pattern)
|
96
|
+
|
97
|
+
(a: HeadTail) =~ (b: HeadTail) :=
|
98
|
+
a head =~ b head && a tail =~ b tail
|
99
|
+
|
100
|
+
(a: List) =~ (b: List) :=
|
101
|
+
a patterns zip(b patterns) all? [[a, b]]:
|
102
|
+
when(a nil? || b nil?):
|
103
|
+
return(false)
|
104
|
+
|
105
|
+
a =~ b
|
106
|
+
|
107
|
+
(a: Match) =~ (b: Match) :=
|
108
|
+
a value == b value
|
109
|
+
|
110
|
+
(a: SingletonClass) =~ (b: SingletonClass) :=
|
111
|
+
a body == b body
|
112
|
+
|
113
|
+
NamedClass =~ NamedClass := true
|
114
|
+
|
115
|
+
NamedGlobal =~ NamedGlobal := true
|
116
|
+
|
117
|
+
NamedInstance =~ NamedInstance := true
|
118
|
+
|
119
|
+
(a: Particle) =~ (b: Particle) :=
|
120
|
+
a value == b value
|
121
|
+
|
122
|
+
(a: QuasiQuote) =~ (b: QuasiQuote) :=
|
123
|
+
-- TODO: go through quotes.
|
124
|
+
a expression == b expression
|
125
|
+
|
126
|
+
(a: Quote) =~ (b: Quote) :=
|
127
|
+
a expression == b expression
|
128
|
+
|
129
|
+
(a: Splat) =~ (b: Splat) :=
|
130
|
+
a pattern =~ b pattern
|
131
|
+
|
132
|
+
(a: Attribute) =~ (b: Attribute) :=
|
133
|
+
a receiver == b receiver &&
|
134
|
+
a name == b name &&
|
135
|
+
a arguments == b arguments
|
136
|
+
|
137
|
+
Pattern =~ Pattern := false
|
138
|
+
|
139
|
+
|
140
|
+
-- helper for comparing aggregate patterns like lists
|
141
|
+
{ self } compare(xs, ys) := do:
|
142
|
+
total = 0
|
143
|
+
|
144
|
+
xs zip(ys) [[x, y]]:
|
145
|
+
unless(x nil? || y nil?):
|
146
|
+
total += x <=> y
|
147
|
+
|
148
|
+
total <=> 0
|
data/kernel/pretty.ay
ADDED
@@ -0,0 +1,283 @@
|
|
1
|
+
namespace(atomy/pretty)
|
2
|
+
|
3
|
+
dynamic(multiline?, false)
|
4
|
+
dynamic(context, #top)
|
5
|
+
dynamic(colored?, false)
|
6
|
+
|
7
|
+
comma-delim(ds) :=
|
8
|
+
hsep(comma punctuate(ds))
|
9
|
+
|
10
|
+
ident(n) := text(n [0, 1] + n [1 .. -1] tr("_", "-") gsub("_ns_", "/"))
|
11
|
+
|
12
|
+
module(Atomy::AST):
|
13
|
+
Block unamb := pretty
|
14
|
+
ClassVariable unamb := pretty
|
15
|
+
Constant unamb := pretty
|
16
|
+
GlobalVariable unamb := pretty
|
17
|
+
(InlinedBody ? @contents size < 2) unamb := pretty
|
18
|
+
InstanceVariable unamb := pretty
|
19
|
+
List unamb := pretty
|
20
|
+
Particle unamb := pretty
|
21
|
+
Primitive unamb := pretty
|
22
|
+
QuasiQuote unamb := pretty
|
23
|
+
Quote unamb := pretty
|
24
|
+
ScopedConstant unamb := pretty
|
25
|
+
Send unamb :=
|
26
|
+
if(from?(#binary, #send))
|
27
|
+
then: pretty
|
28
|
+
else: Doc parens(pretty)
|
29
|
+
Splice unamb := pretty
|
30
|
+
String unamb := pretty
|
31
|
+
ToplevelConstant unamb := pretty
|
32
|
+
Unary unamb := pretty
|
33
|
+
Unquote unamb := pretty
|
34
|
+
Variable unamb := pretty
|
35
|
+
Node unamb := Doc parens(pretty)
|
36
|
+
_ unamb := pretty
|
37
|
+
|
38
|
+
from(*where, &y) :=
|
39
|
+
let(context = where flatten, &y)
|
40
|
+
|
41
|
+
from?(*where) :=
|
42
|
+
[^context, where] match:
|
43
|
+
[(a: Array), (b: Array)] ->
|
44
|
+
a any? [x]: b include?(x)
|
45
|
+
[(a: Array), b] ->
|
46
|
+
a include?(b)
|
47
|
+
[a, (b: Array)] ->
|
48
|
+
b include?(a)
|
49
|
+
[a, b] ->
|
50
|
+
a == b
|
51
|
+
|
52
|
+
export-to(atomy):
|
53
|
+
String pretty := super colored(#yellow)
|
54
|
+
Integer pretty := super colored(#blue)
|
55
|
+
Float pretty := super colored(#blue)
|
56
|
+
TrueClass pretty := super colored(#green)
|
57
|
+
FalseClass pretty := super colored(#red)
|
58
|
+
NilClass pretty := super colored(#black)
|
59
|
+
Object pretty := Doc text(inspect)
|
60
|
+
|
61
|
+
Object show := pretty render
|
62
|
+
|
63
|
+
Doc pretty := self
|
64
|
+
|
65
|
+
Array pretty :=
|
66
|
+
doc: brackets(comma-delim(self all-pretty))
|
67
|
+
|
68
|
+
Particle pretty := doc:
|
69
|
+
wildcard = [c]:
|
70
|
+
if(c equal?(_undefined))
|
71
|
+
then: '_
|
72
|
+
else: c
|
73
|
+
|
74
|
+
operator? = self message to-s !~ r"^[a-z_]"
|
75
|
+
|
76
|
+
args = self arguments collect(&#(wildcard [_]))
|
77
|
+
|
78
|
+
msg+args =
|
79
|
+
if(operator?)
|
80
|
+
then:
|
81
|
+
text(self message to-s) <+> args first unamb
|
82
|
+
else:
|
83
|
+
ident(self message to-s) <>
|
84
|
+
parens(comma-delim(args all-pretty))
|
85
|
+
|
86
|
+
partial =
|
87
|
+
if(self receiver equal?(_undefined))
|
88
|
+
then:
|
89
|
+
if(operator?)
|
90
|
+
then: parens(msg+args)
|
91
|
+
else: msg+args
|
92
|
+
else: parens(self receiver unamb <+> msg+args)
|
93
|
+
|
94
|
+
text("#") <> partial
|
95
|
+
|
96
|
+
Particle to-s := show
|
97
|
+
|
98
|
+
Symbol pretty := do:
|
99
|
+
s = to-s
|
100
|
+
if(s =~ r"^[\p{Ll}_]([\p{L}\d\p{S}!@#%&*\-_\\:.\/\?])*$"(u))
|
101
|
+
then: Doc text("#") <> Doc ident(s)
|
102
|
+
else: Doc text("#") <> s pretty
|
103
|
+
|
104
|
+
Hash pretty := doc:
|
105
|
+
text("#") <>
|
106
|
+
brackets $:
|
107
|
+
comma-delim $:
|
108
|
+
self to-a collect [[k, v]]:
|
109
|
+
k unamb <+> text("->") <+> v unamb
|
110
|
+
|
111
|
+
module(Atomy::AST):
|
112
|
+
Assign pretty :=
|
113
|
+
from(#assign):
|
114
|
+
doc: @lhs unamb <+> text("=") <+> @rhs unamb
|
115
|
+
|
116
|
+
BinarySend pretty :=
|
117
|
+
from(#binary):
|
118
|
+
doc: @lhs unamb <+> text(@operator) <+> @rhs unamb
|
119
|
+
|
120
|
+
Block pretty :=
|
121
|
+
doc:
|
122
|
+
args =
|
123
|
+
if(@arguments empty?)
|
124
|
+
then: empty
|
125
|
+
else: brackets(from(#list): comma-delim(@arguments all-pretty))
|
126
|
+
|
127
|
+
contents = from(#list): comma-delim(@contents all-pretty)
|
128
|
+
if(from?(#send-block) && from?(#top))
|
129
|
+
then: args <> colon <+> contents
|
130
|
+
else: args <+> lbrace <+> contents <+> rbrace
|
131
|
+
|
132
|
+
BlockPass pretty :=
|
133
|
+
from(#unary):
|
134
|
+
doc: text("&") <> @body unamb
|
135
|
+
|
136
|
+
Class pretty := doc:
|
137
|
+
sub =
|
138
|
+
if(@superclass kind-of?(Primitive) && @superclass value == #nil)
|
139
|
+
then: empty
|
140
|
+
else: text("<") <+> from(#binary): @superclass unamb
|
141
|
+
|
142
|
+
name =
|
143
|
+
@name match:
|
144
|
+
Rubinius::AST::ClassName -> text(@name) name to-s
|
145
|
+
_ -> @name unamb
|
146
|
+
|
147
|
+
body = lbrace <+> semi-delim(@body) expressions <+> rbrace
|
148
|
+
|
149
|
+
text("class") <> text("(") <> name <+> sub <> text(")") <+> body
|
150
|
+
|
151
|
+
ClassVariable pretty := doc: ident(name to-s)
|
152
|
+
|
153
|
+
Constant pretty := doc: text(@identifier)
|
154
|
+
|
155
|
+
Define pretty :=
|
156
|
+
from(#define):
|
157
|
+
doc: @lhs unamb <+> text(":=") <+> @body unamb
|
158
|
+
|
159
|
+
GlobalVariable pretty := doc: ident(name to-s)
|
160
|
+
|
161
|
+
InstanceVariable pretty := doc: ident(name to-s)
|
162
|
+
|
163
|
+
List pretty :=
|
164
|
+
from(#list):
|
165
|
+
doc: brackets(comma-delim(@elements all-pretty))
|
166
|
+
|
167
|
+
Macro pretty := doc:
|
168
|
+
text("macro") <+> parens(@pattern pretty) <+> @body pretty
|
169
|
+
|
170
|
+
Particle pretty := doc: text("#") <> ident(@name)
|
171
|
+
|
172
|
+
Primitive pretty := doc:
|
173
|
+
@value match:
|
174
|
+
-- TODO: glitch with #doc/#onto
|
175
|
+
#"self" -> text("self")
|
176
|
+
#true -> text("true")
|
177
|
+
#false -> text("false")
|
178
|
+
#nil -> text("nil")
|
179
|
+
x -> text(x inspect)
|
180
|
+
|
181
|
+
QuasiQuote pretty :=
|
182
|
+
from(#unary):
|
183
|
+
doc: text("`") <> @expression unamb
|
184
|
+
|
185
|
+
Quote pretty :=
|
186
|
+
from(#unary):
|
187
|
+
doc: text("'") <> @expression unamb
|
188
|
+
|
189
|
+
ScopedConstant pretty :=
|
190
|
+
from(#scoped-constant):
|
191
|
+
doc:
|
192
|
+
@parent unamb <> text("::") <> text(@identifier)
|
193
|
+
|
194
|
+
Send pretty :=
|
195
|
+
doc:
|
196
|
+
block =
|
197
|
+
from(#send-block, ^context):
|
198
|
+
if(@block) then: @block unamb; else: empty
|
199
|
+
|
200
|
+
with-block = [x]:
|
201
|
+
condition:
|
202
|
+
^multiline? && @block is-a?(Block) -> do:
|
203
|
+
cs = from(#top): vcat(@block contents all-pretty) nest(2)
|
204
|
+
if(from?(#top))
|
205
|
+
then: x <> colon // cs
|
206
|
+
else: x <+> lbrace // cs // rbrace
|
207
|
+
|
208
|
+
from?(#top) && @block is-a?(Block) && @block arguments empty? ->
|
209
|
+
x <> block
|
210
|
+
|
211
|
+
otherwise ->
|
212
|
+
x <+> block
|
213
|
+
|
214
|
+
args =
|
215
|
+
from(#list):
|
216
|
+
if(@arguments empty?)
|
217
|
+
then: empty
|
218
|
+
else: parens(comma-delim(@arguments all-pretty))
|
219
|
+
|
220
|
+
condition:
|
221
|
+
@receiver kind-of?(Primitive) && @receiver value == #"self" ->
|
222
|
+
with-block [ident(@method-name) <> args]
|
223
|
+
|
224
|
+
otherwise ->
|
225
|
+
with-block [
|
226
|
+
from(#send) { @receiver unamb } <+>
|
227
|
+
ident(@method-name) <> args
|
228
|
+
]
|
229
|
+
|
230
|
+
Splice pretty :=
|
231
|
+
from(#unary):
|
232
|
+
doc: text("~*") <> @expression unamb
|
233
|
+
|
234
|
+
String pretty := Doc text(@value inspect)
|
235
|
+
|
236
|
+
ToplevelConstant pretty := doc: text("::") <> text(@identifier)
|
237
|
+
|
238
|
+
Unary pretty :=
|
239
|
+
from(#unary):
|
240
|
+
doc: text(@operator) <> @receiver unamb
|
241
|
+
|
242
|
+
Unquote pretty :=
|
243
|
+
from(#unary):
|
244
|
+
doc: text("~") <> @expression unamb
|
245
|
+
|
246
|
+
Variable pretty := doc: ident(@name)
|
247
|
+
|
248
|
+
InlinedBody pretty := doc:
|
249
|
+
if(^multiline?)
|
250
|
+
then:
|
251
|
+
from(#top): vcat(@expressions all-pretty)
|
252
|
+
else:
|
253
|
+
from(#list): comma-delim(@expressions all-pretty)
|
254
|
+
|
255
|
+
Or pretty := `(~@a || ~@b) pretty
|
256
|
+
|
257
|
+
And pretty := `(~@a && ~@b) pretty
|
258
|
+
|
259
|
+
Ensure pretty := doc:
|
260
|
+
@body pretty <+> text("ensuring:") <+> @ensure pretty
|
261
|
+
|
262
|
+
|
263
|
+
Array all-pretty := collect [x]: x pretty
|
264
|
+
|
265
|
+
Doc colored(color) := do:
|
266
|
+
-- only makes sense to colorize if we're outputting to a terminal
|
267
|
+
unless(^output-port tty? && ^colored?):
|
268
|
+
return(self)
|
269
|
+
|
270
|
+
codes =
|
271
|
+
[ #black
|
272
|
+
#red
|
273
|
+
#green
|
274
|
+
#yellow
|
275
|
+
#blue
|
276
|
+
#magenta
|
277
|
+
#cyan
|
278
|
+
#white
|
279
|
+
] zip((0 .. 7) to-a)
|
280
|
+
|
281
|
+
hash = Hash [codes]
|
282
|
+
|
283
|
+
Doc text("\e[9" + hash [color] to-s + "m") <> self <> Doc text("\e[0m")
|