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/hashes.ay
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
namespace(atomy)
|
2
|
+
|
3
|
+
macro(#(l: List)):
|
4
|
+
keys = []
|
5
|
+
values = []
|
6
|
+
|
7
|
+
l elements each [p]:
|
8
|
+
p match:
|
9
|
+
`(~k -> ~v) -> do:
|
10
|
+
keys << k
|
11
|
+
values << v
|
12
|
+
|
13
|
+
Atomy::AST::Send -> do:
|
14
|
+
while(p respond-to?(#block) && p block):
|
15
|
+
keys << Atomy::AST::Particle new(p line, p method-name)
|
16
|
+
values << p block contents first
|
17
|
+
p =! p receiver
|
18
|
+
|
19
|
+
Atomy::AST::Hash new(line, keys, values)
|
20
|
+
|
21
|
+
export:
|
22
|
+
class(Atomy::AST::Hash < Atomy::AST::Node):
|
23
|
+
children([#keys], [#values])
|
24
|
+
generate
|
25
|
+
|
26
|
+
bytecode(g) := do:
|
27
|
+
pos(g)
|
28
|
+
|
29
|
+
g push-cpath-top
|
30
|
+
g find-const(#Hash)
|
31
|
+
g push-int(@keys size)
|
32
|
+
g send(#new-from-literal, 1)
|
33
|
+
|
34
|
+
@keys each-with-index [n, i]:
|
35
|
+
g dup
|
36
|
+
n compile(g)
|
37
|
+
@values [i] compile(g)
|
38
|
+
g send("[]=" to-sym, 2)
|
39
|
+
g pop
|
data/kernel/io.ay
ADDED
@@ -0,0 +1,244 @@
|
|
1
|
+
namespace(atomy)
|
2
|
+
|
3
|
+
-- condition kernel not loaded yet; predeclare this
|
4
|
+
symbols(error)
|
5
|
+
|
6
|
+
title"Input & Output"
|
7
|
+
|
8
|
+
doc"Where to write normal output." for:
|
9
|
+
dynamic(output-port, $stdout)
|
10
|
+
|
11
|
+
doc"Where to read input from." for:
|
12
|
+
dynamic(input-port, $stdin)
|
13
|
+
|
14
|
+
doc"Where to write error/warning output." for:
|
15
|
+
dynamic(error-port, $stderr)
|
16
|
+
|
17
|
+
section("Output"):
|
18
|
+
doc"
|
19
|
+
Write \hl{x to-s} to \hl{^output-port}, followed by a linebreak.
|
20
|
+
" spec {
|
21
|
+
=> x
|
22
|
+
} for {
|
23
|
+
x print := x tap: ^output-port puts(x to-s)
|
24
|
+
} examples:
|
25
|
+
1 print
|
26
|
+
"hello" print
|
27
|
+
|
28
|
+
doc"
|
29
|
+
Write \hl{x to-s} to \hl{^output-port}.
|
30
|
+
" spec {
|
31
|
+
=> x
|
32
|
+
} for {
|
33
|
+
x display := x tap: ^output-port send(#print, x to-s)
|
34
|
+
} examples:
|
35
|
+
1 display
|
36
|
+
"hello" display
|
37
|
+
|
38
|
+
doc"
|
39
|
+
Write \hl{x show} to \hl{^output-port}.
|
40
|
+
" spec {
|
41
|
+
=> x
|
42
|
+
} for {
|
43
|
+
x write := x tap: ^output-port puts(x show)
|
44
|
+
} examples:
|
45
|
+
1 write
|
46
|
+
"hello" write
|
47
|
+
|
48
|
+
doc"
|
49
|
+
Set \hl{^output-port} to write output to \hl{filename} for the duration \
|
50
|
+
of \hl{action}, ensuring that the file is closed.
|
51
|
+
|
52
|
+
Returns the result of \hl{action}.
|
53
|
+
" spec {
|
54
|
+
filename is-a?(String)
|
55
|
+
mode is-a?(String)
|
56
|
+
=> any
|
57
|
+
} for {
|
58
|
+
with-output-to((filename: String), mode = "w", &action) :=
|
59
|
+
let(output-port = File open(filename, mode)):
|
60
|
+
action ensuring:
|
61
|
+
^output-port close
|
62
|
+
} examples:
|
63
|
+
with-output-to("foo"):
|
64
|
+
42 print
|
65
|
+
|
66
|
+
with-output-to("foo", "a"):
|
67
|
+
"hello" print
|
68
|
+
|
69
|
+
File open("foo", &#read)
|
70
|
+
|
71
|
+
doc"
|
72
|
+
Set \hl{^output-port} to write to \hl{io} for the duration of \hl{action}.
|
73
|
+
|
74
|
+
Returns the result of \hl{action}.
|
75
|
+
" spec {
|
76
|
+
=> any
|
77
|
+
} for {
|
78
|
+
with-output-to(io, &action) :=
|
79
|
+
let(output-port = io, &action)
|
80
|
+
} examples:
|
81
|
+
require("stringio")
|
82
|
+
x = StringIO new
|
83
|
+
with-output-to(x):
|
84
|
+
"hello!" write
|
85
|
+
x string
|
86
|
+
|
87
|
+
doc"
|
88
|
+
Set \hl{^error-port} to write error output to \hl{filename} for the \
|
89
|
+
duration of \hl{action}, ensuring that the file is closed.
|
90
|
+
|
91
|
+
Returns the result of \hl{action}.
|
92
|
+
" spec {
|
93
|
+
filename is-a?(String)
|
94
|
+
mode is-a?(String)
|
95
|
+
=> any
|
96
|
+
} for {
|
97
|
+
with-error-to((filename: String), mode = "w", &action) :=
|
98
|
+
let(error-port = File open(filename, mode)):
|
99
|
+
action ensuring:
|
100
|
+
^error-port close
|
101
|
+
} examples:
|
102
|
+
with-error-to("foo", "a"):
|
103
|
+
warning(#some-warning)
|
104
|
+
|
105
|
+
File open("foo", &#read)
|
106
|
+
|
107
|
+
doc"
|
108
|
+
Set \hl{^error-port} to write to \hl{io} for the duration of \hl{action}.
|
109
|
+
|
110
|
+
Returns the result of \hl{action}.
|
111
|
+
" spec {
|
112
|
+
=> any
|
113
|
+
} for {
|
114
|
+
with-error-to(io, &action) :=
|
115
|
+
let(error-port = io, &action)
|
116
|
+
} examples:
|
117
|
+
require("stringio")
|
118
|
+
x = StringIO new
|
119
|
+
|
120
|
+
with-error-to(x):
|
121
|
+
warning(#foo)
|
122
|
+
|
123
|
+
x string
|
124
|
+
|
125
|
+
section("Input"):
|
126
|
+
doc"
|
127
|
+
Read a line of text from \hl{^input-port}, signalling \hl{EndOfFile} on \
|
128
|
+
end of file. Lines are separated by \hl{sep}. A separator of \hl{nil} \
|
129
|
+
reads the entire contents, and a zero-length separator reads the input \
|
130
|
+
one paragraph at a time (separated by two linebreaks).
|
131
|
+
" spec {
|
132
|
+
=> String
|
133
|
+
} for {
|
134
|
+
read-line(sep = $separator) := do:
|
135
|
+
x = ^input-port gets(sep)
|
136
|
+
|
137
|
+
unless(x):
|
138
|
+
error(EndOfFile new(^input-port))
|
139
|
+
|
140
|
+
x
|
141
|
+
} examples:
|
142
|
+
with-input-from("foo"):
|
143
|
+
read-line
|
144
|
+
|
145
|
+
doc"
|
146
|
+
Read all lines of text from \hl{^input-port}. Lines are separated by \
|
147
|
+
\hl{sep}. A separator of \hl{nil} reads the entire contents as one \
|
148
|
+
segment, and a zero-length separator reads the input one paragraph at a \
|
149
|
+
time (separated by two linebreaks).
|
150
|
+
" spec {
|
151
|
+
=> String
|
152
|
+
} for {
|
153
|
+
read-lines(sep = $separator) := do:
|
154
|
+
x = ^input-port readlines(sep)
|
155
|
+
|
156
|
+
unless(x):
|
157
|
+
error(EndOfFile new(^input-port))
|
158
|
+
|
159
|
+
x
|
160
|
+
} examples:
|
161
|
+
with-input-from("foo"):
|
162
|
+
read-lines
|
163
|
+
|
164
|
+
doc"
|
165
|
+
Read a single byte from \hl{^input-port}, signalling \hl{EndOfFile} on \
|
166
|
+
end of file.
|
167
|
+
" spec {
|
168
|
+
=> Integer
|
169
|
+
} for {
|
170
|
+
read-byte := do:
|
171
|
+
x = ^input-port getc
|
172
|
+
|
173
|
+
unless(x):
|
174
|
+
error(EndOfFile new(^input-port))
|
175
|
+
|
176
|
+
x
|
177
|
+
} examples:
|
178
|
+
with-input-from("foo"):
|
179
|
+
read-byte
|
180
|
+
|
181
|
+
doc"
|
182
|
+
Same as \hl{read-byte chr}.
|
183
|
+
" spec {
|
184
|
+
=> String
|
185
|
+
} for {
|
186
|
+
read-char := read-byte chr
|
187
|
+
} examples:
|
188
|
+
with-input-from("foo"):
|
189
|
+
read-char
|
190
|
+
|
191
|
+
doc"
|
192
|
+
Read at most \hl{length} bytes from \hl{^input-port}, or to the end of \
|
193
|
+
file if \hl{length} is \hl{nil}. If \hl{buffer} is given, the data read \
|
194
|
+
will be written to it.
|
195
|
+
" spec {
|
196
|
+
length nil? || length >= 0
|
197
|
+
buffer nil? || buffer is-a?(String)
|
198
|
+
=> String || buffer || nil
|
199
|
+
} for {
|
200
|
+
read(length = nil, buffer = nil) :=
|
201
|
+
^input-port send(#read, length, buffer)
|
202
|
+
} examples:
|
203
|
+
x = ""
|
204
|
+
with-input-from("foo"):
|
205
|
+
read(10)
|
206
|
+
|
207
|
+
with-input-from("foo"):
|
208
|
+
read(10, x)
|
209
|
+
|
210
|
+
x
|
211
|
+
|
212
|
+
doc"
|
213
|
+
Set \hl{^input-port} to read input from \hl{filename} for the duration \
|
214
|
+
of \hl{action}, ensuring that the file is closed.
|
215
|
+
|
216
|
+
Returns the result of \hl{action}.
|
217
|
+
" spec {
|
218
|
+
filename is-a?(String)
|
219
|
+
mode is-a?(String)
|
220
|
+
=> any
|
221
|
+
} for {
|
222
|
+
with-input-from((filename: String), mode = "r", &action) :=
|
223
|
+
let(input-port = File open(filename, mode)):
|
224
|
+
action ensuring:
|
225
|
+
^input-port close
|
226
|
+
} examples:
|
227
|
+
with-input-from("foo"):
|
228
|
+
read-line
|
229
|
+
|
230
|
+
doc"
|
231
|
+
Set \hl{^input-port} to write to \hl{io} for the duration of \hl{action}.
|
232
|
+
|
233
|
+
Returns the result of \hl{action}.
|
234
|
+
" spec {
|
235
|
+
=> any
|
236
|
+
} for {
|
237
|
+
with-input-from(io, &action) :=
|
238
|
+
let(input-port = io, &action)
|
239
|
+
} examples:
|
240
|
+
require("stringio")
|
241
|
+
x = StringIO new("hello\ngoodbye\n")
|
242
|
+
|
243
|
+
with-input-from(x):
|
244
|
+
read-line
|
@@ -0,0 +1,63 @@
|
|
1
|
+
macro(namespace(n: Variable)):
|
2
|
+
`(evaluate-when(compile, run, load):
|
3
|
+
Atomy::Namespace ensure(#~n))
|
4
|
+
|
5
|
+
macro(let-when(when, *bindings, &b)):
|
6
|
+
tmps = names(bindings size)
|
7
|
+
save = []
|
8
|
+
set = []
|
9
|
+
restore = []
|
10
|
+
|
11
|
+
bindings zip(tmps) [[`(~n = ~v), tmp]]:
|
12
|
+
save << `(Atomy::STATE [#~tmp] = ^~n)
|
13
|
+
set << set-dynvar(n, v)
|
14
|
+
restore << set-dynvar(n, `(Atomy::STATE delete(#~tmp)))
|
15
|
+
|
16
|
+
names [res]:
|
17
|
+
`(let(~*bindings):
|
18
|
+
evaluate-when(~when):
|
19
|
+
~*save
|
20
|
+
~*set
|
21
|
+
|
22
|
+
~res = ~(b body)
|
23
|
+
|
24
|
+
evaluate-when(~when):
|
25
|
+
~restore
|
26
|
+
|
27
|
+
~res)
|
28
|
+
|
29
|
+
macro(in-namespace(n, &b)):
|
30
|
+
`(do:
|
31
|
+
evaluate-when(load):
|
32
|
+
Atomy::Namespace create(#~n)
|
33
|
+
|
34
|
+
let-when(compile, namespace = Atomy::Namespace ensure(#~n)):
|
35
|
+
~(b body))
|
36
|
+
|
37
|
+
macro(no-namespace(&b)):
|
38
|
+
`(let-when(compile, namespace = nil):
|
39
|
+
~(b body))
|
40
|
+
|
41
|
+
macro(export(&b)):
|
42
|
+
`(let-when(compile, define-in = "_"):
|
43
|
+
~(b body))
|
44
|
+
|
45
|
+
macro(export-to(n, &b)):
|
46
|
+
`(let-when(compile, define-in = ~(n name)):
|
47
|
+
~(b body))
|
48
|
+
|
49
|
+
macro(use(*ns)):
|
50
|
+
current = Atomy::Namespace get
|
51
|
+
where = current && current name
|
52
|
+
|
53
|
+
`(evaluate-when(compile, run, load):
|
54
|
+
~*(ns collect [n]:
|
55
|
+
`(Atomy::Namespace get(~where) use(#~n))))
|
56
|
+
|
57
|
+
macro(symbols(*ns)):
|
58
|
+
current = Atomy::Namespace get
|
59
|
+
where = current && current name
|
60
|
+
|
61
|
+
`(evaluate-when(compile, run, load):
|
62
|
+
~*(ns collect [n]:
|
63
|
+
`(Atomy::Namespace register(#~n, ~where))))
|
data/kernel/node.ay
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
namespace(atomy)
|
2
|
+
|
3
|
+
export:
|
4
|
+
module(Atomy::AST):
|
5
|
+
'_ pattern :=
|
6
|
+
Atomy::Patterns::Any new
|
7
|
+
|
8
|
+
`(~h . ~t) pattern :=
|
9
|
+
Atomy::Patterns::HeadTail new(h to-pattern, t to-pattern)
|
10
|
+
|
11
|
+
`(~p = ~d) pattern :=
|
12
|
+
Atomy::Patterns::Default new(p to-pattern, d)
|
13
|
+
|
14
|
+
`(? ~t) pattern :=
|
15
|
+
Atomy::Patterns::Predicate new(Atomy::Patterns::Any new, t)
|
16
|
+
|
17
|
+
`(~p ? ~t) pattern :=
|
18
|
+
Atomy::Patterns::Predicate new(p to-pattern, t)
|
19
|
+
|
20
|
+
`(~a & ~b) pattern :=
|
21
|
+
Atomy::Patterns::And new(a to-pattern, b to-pattern)
|
22
|
+
|
23
|
+
`(~a | ~b) pattern :=
|
24
|
+
Atomy::Patterns::Or new(a to-pattern, b to-pattern)
|
25
|
+
|
26
|
+
`(with(~attr, ~p)) pattern :=
|
27
|
+
Atomy::Patterns::With new(attr, p to-pattern)
|
28
|
+
|
29
|
+
`@@~n pattern :=
|
30
|
+
Atomy::Patterns::NamedClass new(n name)
|
31
|
+
|
32
|
+
`$~n pattern :=
|
33
|
+
Atomy::Patterns::NamedGlobal new(n name)
|
34
|
+
|
35
|
+
`@~n pattern :=
|
36
|
+
Atomy::Patterns::NamedInstance new(n name)
|
37
|
+
|
38
|
+
`%~x pattern :=
|
39
|
+
Atomy::Patterns::RuntimeClass new(x, nil)
|
40
|
+
|
41
|
+
`&~x pattern :=
|
42
|
+
Atomy::Patterns::BlockPass new(x to-pattern)
|
43
|
+
|
44
|
+
`*~x pattern :=
|
45
|
+
Atomy::Patterns::Splat new(x to-pattern)
|
46
|
+
|
47
|
+
`(Particle [~*as]) pattern :=
|
48
|
+
Atomy::Patterns::List new(as collect [a]: a to-pattern)
|
data/kernel/operators.ay
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
-- defining & assigning
|
2
|
+
operator right 0 = := **= *= <<= >>= &&=
|
3
|
+
&= ||= |= += -= /= ^= %=
|
4
|
+
|
5
|
+
-- association
|
6
|
+
operator right 1 <- ->
|
7
|
+
|
8
|
+
-- predicate pattern
|
9
|
+
operator right 2 ?
|
10
|
+
|
11
|
+
-- ranges
|
12
|
+
--operator 1 .. ...
|
13
|
+
|
14
|
+
-- comparison
|
15
|
+
operator 5 <=> < <= >= >
|
16
|
+
operator 4 == !=
|
17
|
+
operator 3 &&
|
18
|
+
operator 2 ||
|
19
|
+
|
20
|
+
-- math
|
21
|
+
operator right 12 **
|
22
|
+
operator 10 % * /
|
23
|
+
operator 9 + -
|
24
|
+
|
25
|
+
-- bitwise and shifting
|
26
|
+
operator 8 << >>
|
27
|
+
operator 6 ^ |
|
28
|
+
operator 7 &
|
data/kernel/particles.ay
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
namespace(atomy)
|
2
|
+
|
3
|
+
for-macro:
|
4
|
+
wildcard('_) := '_undefined
|
5
|
+
wildcard(x) := x
|
6
|
+
|
7
|
+
macro(#(x: Send)):
|
8
|
+
`(Particle [
|
9
|
+
~(if(x private)
|
10
|
+
then: '_undefined
|
11
|
+
else: wildcard(x receiver))
|
12
|
+
~(Atomy::AST::Particle new(0, x method-name))
|
13
|
+
~*(x arguments collect [c]: wildcard(c))
|
14
|
+
])
|
15
|
+
|
16
|
+
macro(#(x: BinarySend)):
|
17
|
+
`(Particle [
|
18
|
+
~(if(x private)
|
19
|
+
then: '_undefined
|
20
|
+
else: wildcard(x lhs))
|
21
|
+
~(Atomy::AST::Particle new(0, x operator))
|
22
|
+
~(wildcard(x rhs))
|
23
|
+
])
|
24
|
+
|
25
|
+
export:
|
26
|
+
class(Particle < Array):
|
27
|
+
call(*args) := to-proc [*args]
|
28
|
+
|
29
|
+
to-proc := [*args]:
|
30
|
+
x = dup
|
31
|
+
|
32
|
+
args each [a]:
|
33
|
+
idx = x find-index [a]:
|
34
|
+
a equal?(_undefined)
|
35
|
+
|
36
|
+
when(idx):
|
37
|
+
x [idx] = a
|
38
|
+
|
39
|
+
x first send(*(x drop(1)))
|
40
|
+
|
41
|
+
arity :=
|
42
|
+
select(&#equal?(_undefined)) size
|
43
|
+
|
44
|
+
receiver := at(0)
|
45
|
+
|
46
|
+
message := at(1)
|
47
|
+
|
48
|
+
arguments := drop(2)
|
49
|
+
|
50
|
+
class(Symbol):
|
51
|
+
call(*args) := to-proc [*args]
|
52
|
+
|
53
|
+
arity := 1
|