This repository was archived by the owner on May 18, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathcore.bn
361 lines (250 loc) · 11.3 KB
/
core.bn
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
;;;; core.bn -- Documentation for Bone Lisp core operations. -*- lisp -*-
;;;; Copyright (C) 2016 Wolfgang Jaehrling
;;;;
;;;; Permission to use, copy, modify, and/or distribute this software for any
;;;; purpose with or without fee is hereby granted, provided that the above
;;;; copyright notice and this permission notice appear in all copies.
;;;;
;;;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
;;;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
;;;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
;;;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
;;;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
;;;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
;;;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
;;;; Note: This file just provides the docstrings for the operations
;;;; in the core. You will not find any implementation here. This
;;;; file should not be evaluated, it should only be parsed by a
;;;; documentation generator. This file uses `defspecial` to document
;;;; special forms.
(defspecial (if test then . else)
"If `test` yields true, evaluate `then`, otherwise all expressions in `else`.
If `else` is empty and `test` is false, returns false.
The only value that does not count as true is `#f`, the booolean false
value. This means that the empty list as well as the number zero are
considered to be true values. See `nil?` and `zero?` if you want to
check for those values.")
(defspecial (quote . obj)
"Returns `obj`, unevaluated.")
(defspecial (do . exprs)
"Evaluate the `exprs` in order.")
(defspecial (with name value . exprs)
"Bind `name` to `value`, then evaluate the `exprs` in order.")
(defspecial (lambda args . body)
"Create an anonymous sub with arguments `args` and code `body` (which may not be empty).
`args` can be either a `sym` or a list of `sym`s; if it is a list, it
may be improper, but only if it has a `sym` as rest. This means:
* `(lambda x ...)` will bind the list of arguments to `x`.
* `(lambda (a b) ...)` will find two arguments to `a` and `b`, respectively.
* `(lambda (a b . x) ...)` will bind two arguments to `a` and `b`,
as well as all remaining arguments to `x`.
`body` is a list of expressions, which will be evaluated in order.
The anonymous sub that is created will be lexically scoped,
i.e. bindings defined in an outer scope may be used and are
encapsulated if the sub is passed back as a return value.")
(defmac (quasiquote . form)
"Quote `form`, except for unquoted parts.
This macro is generally used via its short form `\\`form`. It works
like `quote`, but may contain `(unquote x)` forms which will cause x`
to appear unquoted in the result. For `unquote` the abbreviation
`,` (comma) is available. `(unquote-splicing x)` or `,@x` forms
expect `x` to evaluate to a list, which will be embedded into the
resulting list, i.e.:
`(a b c ,@(list 1 2 3) d e f)
; => (a b c 1 2 3 d e f)")
(defsub (mac-expand-1 form)
"Expand macros in `form` once, i.e. show the immediate result of macro expansion.")
(defsub (mac-expand form)
"Expand macros in `form` repeatedly until there are no macros anymore.")
(defsub (bound? sym)
"Check whether `sym` is bound.")
(defsub (mac-bound? sym)
"Check whether `sym` is bound in the macro namespace.")
(defsub (var-bound? sym)
"Check whether `sym` is bound in the dynamic variable namespace.")
(defsub (reader-bound? sym)
"Check whether `sym` is bound in the reader macro namespace.")
(defsub (eval x)
"Evaluate `x`; this allows to generate code at runtime.")
(defsub (id x)
"This is the identity sub; it simply returns `x`.
This is sometimes useful in higher order programming.")
(defsub (eq? a b)
"Returns whether `a` and `b` are the same object.
Don't use this for comparing numbers, use `=?` instead. The most
important use of `eq?` is as a quick way to compare `sym`s.")
(defsub (copy x)
"Return a newly allocated copy of `x`.")
(defsub (not x)
"Boolean negation: Return whether `x` is false.
Do not confuse this with `no` or `nil?`, which test for the empty list.")
(defsub (sub? x)
"Return whether `x` is a sub.")
(defsub (apply sub . args)
"Apply `sub` to the given arguments, the last value in `args` must be a list.
The exact behaviour is best explained with examples:
* `(apply f)` is `(f)`
* `(apply f '(1 2 3))` is `(f 1 2 3)`
* `(apply f 1 2 '(3 4))` is `(f 1 2 3 4)`
This allows to use a list as the arguments to a sub, while also having
fixed arguments at the same time (without a need for consing them to
the front of the list manually). See also `list*`.")
(defsub (cons a d)
"Create a cons cell containing `a` as car and `d` as cdr.")
(defsub (car x)
"Return the car (first element) of the cons cell `x`.
Note that `car` and `cdr` are low-level operations which usually
should not appear in application code. Instead, higher-level list
operations should be used (which may be implemented in terms of `car`
and `cdr`).")
(defsub (cdr x)
"Return the cdr (second element) of the cons cell `x`.
See `car` for additional usage information.")
(defsub (cons? x)
"Return whether `x` is a `cons` cell.")
(defsub (nil? x)
"Return whether `x` is the empty list.")
(defsub (single? x)
"Check whether `x` is a list of exactly one element.
`x` may be any object, it does not have to be a list.")
(defsub (list? x)
"Return whether `x` is a list (i.e. either a `cons` or nil).")
(defsub (list . xs)
"Returns `xs`.
This is a basic list constructor; it's more convenient (and faster)
than nested `cons` calls.")
(defsub (list* . xs)
"Create a list consisting of the elements of `xs`, but using the last element as rest.
This means that `(list* 1 2 3)` returns `(1 2 . 3)`.")
(defsub (len xs)
"Return the number of elements in `xs`.")
(defsub (dup xs)
"Duplicate the list `xs`; the elements will not be duplicated.")
(defsub (cat . lists)
"Concatenate the `lists` into a single list.")
(defsub (reverse xs)
"Return a list with the elements of `xs`, but in opposite order.")
(defsub (member? x xs)
"Return whether `x` is in the list `xs`.")
(defsub (each sub xs)
"Apply `sub` to every element of the list `xs` in sequence.
The result should be ignored, but will be the result of the last call to `sub`.")
(defsub (map sub xs)
"Call `sub` for each element in `xs` and return a list of the results.")
(defsub (filter keep? xs)
"Call `keep?` for each element in `xs` and return a list of the elements where the result was true.")
(defsub (sort is>? xs)
"Sort `xs` according to the predicate `is>?`.")
(defsub (assoc? x alist)
"Get the value corresponding to the key `x` in `alist` (`#f` if not found).
This sub will return the `cdr` where the `car` is `x`.")
(defsub (assoc-entry? x alist)
"Returns the key/value entry from `alist` with the key `x` (`#f` if not found).")
(defsub (num? x)
"Return whether `x` is a number.")
(defsub (integer? x)
"Return whether `x` is an integer number.")
(defsub (float? x)
"Return whether `x` is a floating-point number.")
(defsub (round x)
"Round `x` to the nearest integer number.")
(defsub (floor x)
"Round `x` to the nearest integer number smaller than `x`.")
(defsub (ceil x)
"Round `x` to the nearest integer number greater than `x`.")
(defsub (trunc x)
"Round `x` towards zero to the nearest integer number.")
(defsub (+ . nums)
"Return the sum of the numbers in `nums` (which may not contain anything but numbers).")
(defsub (- n . nums)
"Arithmetic minus: The sum of `nums` will be subtracted from `n`.
This is not the traditional behaviour of `-` in Lisp, which did allow
the unary minus `(- x)` as an alias for `(- 0 x)`. This was removed
from Bone Lisp because it would cause trouble with constructs
like `(apply - num xs)` giving unexpected results when `xs` is
empty.")
(defsub (* . nums)
"Return the product of the numbers in `nums` (which may not contain anything but numbers).
When applied to the empty list (as in `(*)` or `(apply * ())`), the result is 1.")
(defsub (/ dividend . divisors)
"Divide the `dividend` by the product of all `divisors`.")
(defsub (mod dividend divisor)
"Return the remainder of dividing `dividend` by `divisor`.")
(defsub (=? . nums)
"Return whether the numbers in `nums` are all equal.")
(defsub (<>? a b)
"Return whether the numbers `a` and `b` are different.
Note that this sub accepts only two arguments, while similar subs like
`=?` accept an arbitrary number of args.")
(defsub (>? . nums)
"Return whether each number in `nums` is greater than the next.")
(defsub (<? . nums)
"Return whether each number in `nums` is less than the next.")
(defsub (>=? . nums)
"Return whether each number in `nums` is greater than or equal to the next.")
(defsub (<=? . nums)
"Return whether each number in `nums` is less than or equal to the next.")
(defsub (bit-not n)
"Return the bitwise negation of `n` (i.e. flip each bit).")
(defsub (bit-and n1 n2)
"Return the bitwise AND of `n1` and `n2`.")
(defsub (bit-or n1 n2)
"Return the bitwise OR (inclusive or) of `n1` and `n2`.")
(defsub (bit-xor n1 n2)
"Return the bitwise XOR (exclusive or) of `n1` and `n2`.")
(defsub (str? x)
"Return whether `x` is a string (a `str`).")
(defsub (str chrs)
"Return a new `str` with the characters from the list `chrs`.")
(defsub (unstr s)
"Return the list of characters in `s`.")
(defsub (str=? s1 s2)
"Return whether `str1` and `str2` consist of the same characters.")
(defsub (str<>? s1 s2)
"Return whether `str1` and `str2` consist of different characters.")
(defsub (num->str n)
"Return a representation of `n` as a str.")
(defsub (print x)
"Print `x` as an extended symbolic expression.
This will print the object so that it can be read by humans and also
read back by the Lisp reader, except if it contains objects which
cannot be read back, like `sub`s. Reading back is possible as long as
it only contains lists, `sym`s, numbers and bools. The abbreviations
for `quote`, `quasiquote`, `unquote`, `unquote-splicing` and `lambda`
will be printed to keep the output short and as human-readable as
possible.")
(defsub (say . xs)
"Print all `xs`.
The differences to the `print` sub are:
* A `str` is printed without the quote signs and without escape sequences.
* A list is printed by applying it to `say`.
* All other objects are printed as with `print`.
Always returns `#t`.")
(defsub (err . xs)
"Print all of `xs` as with `say`, then raise an error.")
(defsub (read)
"Read a symbolic expression from the current src.")
(defsub (chr-read)
"Read a single character from the current src.")
(defsub (chr-look)
"Look ahead at the next character from the current src without reading it.")
(defsub (src-line src)
"The current line number of `src`.")
(defsub (file-name src-or-dst)
"The file name associated with `src-or-dst`.")
(defsub (src? x)
"Check whether `x` is a src.")
(defsub (dst? x)
"Check whether `x` is a dst.")
(defsub (eof? x)
"Check whether `x` is the end of file object.")
(defsub (sym? x)
"Return whether `x` is a sym.")
(defsub (intern s)
"Return the `sym` with the text of `str`.
If it does not exist yet, it will be created.")
(defsub (sym->str symbol)
"Return the name of the sym `symbol` as a str.")
(defsub (gensym)
"Return a new non-interned sym.
This is especially useful to avoid naming conflicts in macros.")