nydp 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +25 -13
- data/lib/lisp/core-015-documentation.nydp +11 -2
- data/lib/lisp/core-030-syntax.nydp +52 -8
- data/lib/lisp/core-040-utils.nydp +35 -47
- data/lib/lisp/core-045-dox-utils.nydp +85 -0
- data/lib/lisp/core-050-test-runner.nydp +20 -2
- data/lib/lisp/core-080-pretty-print.nydp +5 -1
- data/lib/lisp/tests/boot-tests.nydp +125 -255
- data/lib/lisp/tests/car-examples.nydp +16 -0
- data/lib/lisp/tests/collect-tests.nydp +28 -0
- data/lib/lisp/tests/cons-examples.nydp +8 -0
- data/lib/lisp/tests/curry-tests.nydp +17 -18
- data/lib/lisp/tests/detect-examples.nydp +24 -0
- data/lib/lisp/tests/dot-syntax-examples.nydp +40 -0
- data/lib/lisp/tests/dox-tests.nydp +116 -100
- data/lib/lisp/tests/dynamic-scope-test.nydp +10 -10
- data/lib/lisp/tests/each-tests.nydp +4 -5
- data/lib/lisp/tests/error-tests.nydp +17 -16
- data/lib/lisp/tests/explain-mac-examples.nydp +24 -0
- data/lib/lisp/tests/foundation-test.nydp +57 -223
- data/lib/lisp/tests/hash-examples.nydp +41 -0
- data/lib/lisp/tests/isa-examples.nydp +7 -0
- data/lib/lisp/tests/len-examples.nydp +11 -0
- data/lib/lisp/tests/list-tests.nydp +110 -75
- data/lib/lisp/tests/parser-tests.nydp +67 -109
- data/lib/lisp/tests/pretty-print-tests.nydp +19 -20
- data/lib/lisp/tests/quasiquote-examples.nydp +10 -0
- data/lib/lisp/tests/rfnwith-tests.nydp +7 -0
- data/lib/lisp/tests/string-tests.nydp +60 -31
- data/lib/lisp/tests/syntax-tests.nydp +22 -24
- data/lib/lisp/tests/type-of-examples.nydp +48 -0
- data/lib/lisp/tests/unparse-tests.nydp +2 -3
- data/lib/nydp.rb +2 -1
- data/lib/nydp/version.rb +1 -1
- metadata +14 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f4074a517649b09d3911d3b593e19ff0f0bc6d66
|
4
|
+
data.tar.gz: cf2d6625885b45055f2e09601dc5914da308d5e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 722eb57b1b40efaed06e432f3d70e00e18cda57ccef51b404f755b4b35dab3456a68a3542bb2185e68a22c5c1b2463c0320b5a223fa6901c1240ad542c07a0f3
|
7
|
+
data.tar.gz: 4d5a6a702eb006751548d594515022f1c2e2f8b2697d45b95973db83abb2ad2d53d29d6495fbde9281f21c9ae98bf02e87b5b6c19e6ae9c053ad9152804f41d8
|
data/README.md
CHANGED
@@ -1,16 +1,18 @@
|
|
1
|
-
#
|
1
|
+
# `'nydp`
|
2
2
|
|
3
|
-
|
3
|
+
`'nydp` is a new LISP dialect, much inspired by [Arc](http://arclanguage.org/), and hence indirectly by all of `'arc`'s ancestors,
|
4
|
+
and implemented in Ruby.
|
4
5
|
|
5
|
-
|
6
|
-
to Star Wars), as well as to the meme [Not Your Daddy's Q](http://tvtropes.org/pmwiki/pmwiki.php/Main/NotYourDaddysX), where Q is a
|
7
|
-
improved Q unlike the Q your daddy used.
|
6
|
+
`'nydp` is "Not Your Daddy's Parentheses", a reference to [Xkcd 297](http://xkcd.com/297/) (itself a reference
|
7
|
+
to Star Wars), as well as to the meme [Not Your Daddy's Q](http://tvtropes.org/pmwiki/pmwiki.php/Main/NotYourDaddysX), where Q is a
|
8
|
+
modern, improved Q quite unlike the Q your daddy used. `'nydp` also shamelessly piggypacks on the
|
8
9
|
catchiness and popularity of the [NYPD](https://en.wikipedia.org/wiki/NYPD_Blue) abbreviation ("New York Police Department",
|
9
10
|
for those who have no interest in popular US politics or TV).
|
10
11
|
|
11
|
-
We do not wish to suggest by "Not Your Daddy's Parentheses" that Common Lisp, Scheme, Racket, Arc, Clojure or your favourite
|
12
|
+
We do not wish to suggest by "Not Your Daddy's Parentheses" that Common Lisp, Scheme, Racket, Arc, Clojure or your favourite
|
13
|
+
other lisp are somehow old-fashioned, inferior, or in need of improvement in any way.
|
12
14
|
|
13
|
-
The goal of
|
15
|
+
The goal of `'nydp` is to allow untrusted users run sandboxed server-side scripts. By default, `'nydp` provides no system access :
|
14
16
|
|
15
17
|
* no file functions
|
16
18
|
* no network functions
|
@@ -19,7 +21,10 @@ The goal of NYDP is to allow untrusted users run sandboxed server-side scripts.
|
|
19
21
|
* no threading functions
|
20
22
|
* no ruby calls
|
21
23
|
|
22
|
-
[Peruse
|
24
|
+
[Peruse `'nydp`'s features here](lib/lisp/tests) in the `tests` directory.
|
25
|
+
|
26
|
+
Pronunciation guide: there is no fixed canonical pronunciation of `'nydp`. Just keep in mind that if you find yourself
|
27
|
+
wading _knee-deep_ through raw sewage, it's still better than working on a java project in a bank.
|
23
28
|
|
24
29
|
## Running
|
25
30
|
|
@@ -41,7 +46,7 @@ Suppose you want to invoke the function named `question` with some arguments. Do
|
|
41
46
|
```ruby
|
42
47
|
ns = Nydp.build_nydp # keep this for later re-use, it's expensive to set up
|
43
48
|
|
44
|
-
answer = Nydp.apply_function ns, :question, :life,
|
49
|
+
answer = Nydp.apply_function ns, :question, :life, ["The Universe" and(everything)]
|
45
50
|
|
46
51
|
==> 42
|
47
52
|
```
|
@@ -55,7 +60,7 @@ You can maintain multiple `ns` instances without mutual interference. In other w
|
|
55
60
|
|
56
61
|
#### 1. Macro-expansion runs in lisp
|
57
62
|
|
58
|
-
After parsing its input,
|
63
|
+
After parsing its input, `'nydp` passes the result as an argument to the `pre-compile` function. This is where things get a little bit circular: initially, `pre-compile` is a builtin function that just returns its argument. `pre-compile` bootstraps itself into existence in [boot.nydp](lib/lisp/boot.nydp).
|
59
64
|
|
60
65
|
You can override `pre-compile` to transform the expression in any way you wish. By default, the `boot.nydp` implementation of `pre-compile` performs macro-expansion.
|
61
66
|
|
@@ -185,7 +190,7 @@ nydp > (parse "\"foo\"")
|
|
185
190
|
|
186
191
|
nydp > (let bar "Mister Nice Guy" "hello, ~bar")
|
187
192
|
|
188
|
-
==> hello, Mister Nice Guy
|
193
|
+
==> "hello, Mister Nice Guy"
|
189
194
|
|
190
195
|
; this is a more tricky example because we need to make a string with an interpolation token in it
|
191
196
|
|
@@ -193,6 +198,8 @@ nydp > (let s (joinstr "" "\"hello, " '~ "world\"") (parse s))
|
|
193
198
|
|
194
199
|
==> (string-pieces "hello, " world "") ; "hello, ", followed by the interpolation 'world, followed by the empty string after 'world
|
195
200
|
|
201
|
+
; It is possible to nest interpolations. Note that as with many popular language features, just because you can do something, does not mean you should:
|
202
|
+
|
196
203
|
nydp > (def also (str) "\nAND ALSO, ~str")
|
197
204
|
nydp > (with (a 1 b 2)
|
198
205
|
(p "Consider ~a : the first thing,
|
@@ -204,13 +211,17 @@ nydp > (with (a 1 b 2)
|
|
204
211
|
==> AND ALSO, Consider 3, the third (and final) thing
|
205
212
|
```
|
206
213
|
|
207
|
-
By default, `string-pieces` is a function that just concatenates the string value of its arguments. You can redefine it as a macro to
|
214
|
+
By default, `string-pieces` is a function that just concatenates the string value of its arguments. You can redefine it as a macro to
|
215
|
+
perform more fun stuff, or you can detect it within another macro to do extra-special stuff with it. The 'nydp-html gem detects
|
216
|
+
'string-pieces and gives it special treatment in order to render haml and textile efficiently, and also to capture and report errors
|
217
|
+
inside interpolations and report them correctly.
|
208
218
|
|
209
219
|
|
210
220
|
#### 5. No continuations.
|
211
221
|
|
212
222
|
Sorry. While technically possible ... why bother?
|
213
223
|
|
224
|
+
|
214
225
|
#### 6. No argument destructuring
|
215
226
|
|
216
227
|
However, this doesn't need to be built-in, it can be done with macros alone. On the other hand, "rest" arguments are implicitly available using the same syntax as Arc uses:
|
@@ -277,7 +288,8 @@ nydp > (parse "; blah blah")
|
|
277
288
|
==> (comment "blah blah")
|
278
289
|
```
|
279
290
|
|
280
|
-
Except in 'mac and 'def forms, by default, `comment` is a macro that expands to nil. If you have a better idea, go for it.
|
291
|
+
Except in 'mac and 'def forms, by default, `comment` is a macro that expands to nil. If you have a better idea, go for it. Any comments present at the
|
292
|
+
beginning of the `body` argument to `mac` or `def` are considered documentation. (See "self-documenting" below).
|
281
293
|
|
282
294
|
#### 8 Prefix lists
|
283
295
|
|
@@ -1,10 +1,16 @@
|
|
1
|
-
((fn (dox)
|
1
|
+
((fn (dox examples)
|
2
2
|
(def dox-add-doc (name what texts args src)
|
3
3
|
(hash-set dox
|
4
4
|
name
|
5
5
|
(cons (list name what texts args src)
|
6
6
|
(hash-get dox sym))))
|
7
7
|
|
8
|
+
(def dox-add-examples (name example-exprs)
|
9
|
+
(hash-set examples
|
10
|
+
name
|
11
|
+
(cons example-exprs
|
12
|
+
(hash-get examples sym))))
|
13
|
+
|
8
14
|
(def dox-lookup (sym) (hash-get dox sym))
|
9
15
|
|
10
16
|
(def dox? (sym) (hash-key? dox sym))
|
@@ -19,10 +25,13 @@
|
|
19
25
|
(cond (dox? name)
|
20
26
|
(car (cddr (cddr (car (dox-lookup name)))))))
|
21
27
|
|
28
|
+
(def dox-examples (name)
|
29
|
+
(hash-get examples name))
|
30
|
+
|
22
31
|
(def dox-arg-names (name)
|
23
32
|
(cond (dox? name)
|
24
33
|
(cadddr (car (dox-lookup name))))))
|
25
|
-
(hash))
|
34
|
+
(hash) (hash))
|
26
35
|
|
27
36
|
(def isa-comment? (thing)
|
28
37
|
(cond (pair? thing)
|
@@ -1,4 +1,7 @@
|
|
1
1
|
(def orf args
|
2
|
+
; evaluates each arg in 'args, returns the
|
3
|
+
; first non-nil value, or nil if they are
|
4
|
+
; all nil
|
2
5
|
(cond args
|
3
6
|
(cond (car args)
|
4
7
|
(car args)
|
@@ -6,6 +9,7 @@
|
|
6
9
|
(cdr args)))))
|
7
10
|
|
8
11
|
(mac unless (arg . body)
|
12
|
+
; evaluate 'body if 'arg is nil
|
9
13
|
`(if (no ,arg) (do ,@body)))
|
10
14
|
|
11
15
|
(def expand-colon-syntax (names)
|
@@ -27,11 +31,23 @@
|
|
27
31
|
(error "Irregular ': syntax: got ~(inspect names) : not prefix-syntax : in ~(joinstr ":" names)"))
|
28
32
|
|
29
33
|
(mac colon-syntax names
|
34
|
+
; handle syntax of the form a:b, which the parser expands to
|
35
|
+
; (colon-syntax a b). By default, this complains if colon is used
|
36
|
+
; as a prefix (ie it disallows ":foo"), otherwise creates a new
|
37
|
+
; function which is the composition of the functions named in its
|
38
|
+
; arguments. For example,
|
39
|
+
; (count:parts spaceship) is the same as (count (parts spaceship))
|
30
40
|
((orf (hash-get colon-syntax-overrides (car names))
|
31
41
|
default-colon-syntax)
|
32
42
|
names))
|
33
43
|
|
34
44
|
(mac bang-syntax (pfx . rest)
|
45
|
+
; handle syntax of the form !x, which the parser expands to
|
46
|
+
; (bang-syntax || x). By default, this complains if there is
|
47
|
+
; a non-empty prefix (ie it disallows x!y), otherwise it creates
|
48
|
+
; a new function which is the negation of the given named function.
|
49
|
+
; For example,
|
50
|
+
; (!eq? a 10) is the same as (no:eq? a 10), which is the same as (no (eq? a 10))
|
35
51
|
(if (no (eq? pfx '||))
|
36
52
|
(error "Irregular '! syntax: got prefix ~(inspect pfx) in ~(joinstr "!" (cons pfx rest))"))
|
37
53
|
(if (cdr rest)
|
@@ -64,6 +80,30 @@
|
|
64
80
|
(mac let (var val . body)
|
65
81
|
`(with (,var ,val) ,@body))
|
66
82
|
|
83
|
+
(mac rfn (name parms . body)
|
84
|
+
; creates a named, locally-scoped function
|
85
|
+
; with the given parameter names. It is possible
|
86
|
+
; to reference the function by its name from within
|
87
|
+
; the function (to pass as an argument or for
|
88
|
+
; recursive invocation)
|
89
|
+
`(let ,name nil
|
90
|
+
(assign ,name (fn ,parms ,@body))))
|
91
|
+
|
92
|
+
(mac afn (parms . body)
|
93
|
+
; same as 'rfn, but using the name 'self
|
94
|
+
`(rfn self ,parms ,@body))
|
95
|
+
|
96
|
+
(mac rfnwith (name params . body)
|
97
|
+
; a mix of rfn and with; creates a locally-scoped named function with
|
98
|
+
; the given parameter names, and invokes it with the given parameter
|
99
|
+
; values. It is possible to reference the function by its name from
|
100
|
+
; within the function (to pass as an argument or for recursive
|
101
|
+
; invocation)
|
102
|
+
(let ppairs (pairs params)
|
103
|
+
`(let ,name nil
|
104
|
+
(assign ,name (fn ,(map car ppairs) ,@body))
|
105
|
+
(,name ,@(map cadr ppairs)))))
|
106
|
+
|
67
107
|
(let uniq-counter 0
|
68
108
|
(def uniq (prefix)
|
69
109
|
(sym (joinstr "-"
|
@@ -74,16 +114,20 @@
|
|
74
114
|
(assign uniq-counter 0)))
|
75
115
|
|
76
116
|
(mac w/uniq (vars . body)
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
117
|
+
; creates a lexical scope with a unique symbol assigned to
|
118
|
+
; each variable in 'vars ; executes the 'body.
|
119
|
+
(if (pair? vars)
|
120
|
+
`(with ,(apply + (map (fn (n) (list n '(uniq ',n))) vars))
|
121
|
+
,@body)
|
122
|
+
`(let ,vars (uniq ',vars) ,@body)))
|
81
123
|
|
82
124
|
(mac or args
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
125
|
+
; lazy-evaluates each argument, returns the first
|
126
|
+
; non-nil result, or nil if all evaluate to nil.
|
127
|
+
(cond args
|
128
|
+
(w/uniq ora
|
129
|
+
`(let ,ora ,(car args)
|
130
|
+
(cond ,ora ,ora (or ,@(cdr args)))))))
|
87
131
|
|
88
132
|
(mac pop (xs)
|
89
133
|
(w/uniq gp
|
@@ -14,12 +14,10 @@
|
|
14
14
|
|
15
15
|
(def flatten (things)
|
16
16
|
(let acc nil
|
17
|
-
(
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
(push x acc))))
|
22
|
-
(flattenize things))
|
17
|
+
(rfnwith flattenize (x things)
|
18
|
+
(if (pair? x)
|
19
|
+
(eachr flattenize x)
|
20
|
+
(push x acc)))
|
23
21
|
acc))
|
24
22
|
|
25
23
|
(def string-strip (txt)
|
@@ -40,6 +38,9 @@
|
|
40
38
|
(joinstr "" pieces))
|
41
39
|
|
42
40
|
(def detect (f things)
|
41
|
+
; if 'things is a list, return the first item in the list for which 'f returns non-nil
|
42
|
+
; otherwise, return 'things if (f things) is non-nil
|
43
|
+
; otherwise, nil
|
43
44
|
(if (pair? things)
|
44
45
|
(let it (car things)
|
45
46
|
(or
|
@@ -48,10 +49,26 @@
|
|
48
49
|
(f things)
|
49
50
|
things))
|
50
51
|
|
52
|
+
(def collect (f things)
|
53
|
+
; if 'things is a list, return all the items in the list for which 'f returns non-nil
|
54
|
+
; otherwise, return 'things if (f things) is non-nil
|
55
|
+
; otherwise, nil
|
56
|
+
(rfnwith collector (items things)
|
57
|
+
(if (no items)
|
58
|
+
nil
|
59
|
+
(pair? items)
|
60
|
+
(if (f (car items))
|
61
|
+
(cons (car items)
|
62
|
+
(collector (cdr items)))
|
63
|
+
(collector (cdr items)))
|
64
|
+
(f items)
|
65
|
+
items)))
|
66
|
+
|
51
67
|
(def nth (n things)
|
52
|
-
|
53
|
-
|
54
|
-
|
68
|
+
; returns the n-th item in the list 'things
|
69
|
+
(if (eq? n 0)
|
70
|
+
(car things)
|
71
|
+
(nth (- n 1) (cdr things))))
|
55
72
|
|
56
73
|
(def iso (x y)
|
57
74
|
(or (eq? x y)
|
@@ -68,8 +85,10 @@
|
|
68
85
|
(def quotify (arg) `(quote ,arg))
|
69
86
|
|
70
87
|
(def caris (obj things)
|
71
|
-
|
72
|
-
|
88
|
+
; returns true if 'things is a list and the first item of the
|
89
|
+
; list is the given object
|
90
|
+
(and (isa 'pair things)
|
91
|
+
(eq? (car things) obj)))
|
73
92
|
|
74
93
|
(def len (xs)
|
75
94
|
(if (pair? xs) (+ 1 (len (cdr xs)))
|
@@ -79,6 +98,7 @@
|
|
79
98
|
(assign dynamics (hash))
|
80
99
|
|
81
100
|
(mac dynamic (name)
|
101
|
+
; creates a dynamic variable.
|
82
102
|
(hash-set dynamics name t)
|
83
103
|
(let with-mac-name (sym "w/~name")
|
84
104
|
(w/uniq prev
|
@@ -93,20 +113,17 @@
|
|
93
113
|
(def ,name () (hash-get (thread-locals) ',name))))))
|
94
114
|
|
95
115
|
(mac on-err (handler . body)
|
116
|
+
; executes 'body. If an error is raised, executes 'handler. Inside
|
117
|
+
; 'handler, the parameter 'err refers to the error that was raised.
|
96
118
|
`(handle-error (fn (err) ,handler)
|
97
119
|
(fn () ,@body)))
|
98
120
|
|
99
121
|
(mac ensure (protection . body)
|
122
|
+
; executes 'body. Afterwards, executes 'protection.
|
123
|
+
; 'protection is always executed even if there is an error.
|
100
124
|
`(ensuring (fn () ,protection)
|
101
125
|
(fn () ,@body)))
|
102
126
|
|
103
|
-
(mac rfn (name parms . body)
|
104
|
-
`(let ,name nil
|
105
|
-
(assign ,name (fn ,parms ,@body))))
|
106
|
-
|
107
|
-
(mac afn (parms . body)
|
108
|
-
`(rfn self ,parms ,@body))
|
109
|
-
|
110
127
|
(mac loop (start test update . body)
|
111
128
|
(w/uniq (gfn gparm)
|
112
129
|
`(do ,start
|
@@ -143,35 +160,6 @@
|
|
143
160
|
acc))
|
144
161
|
(car things) (cdr things)))
|
145
162
|
|
146
|
-
(def dox-show-src (src)
|
147
|
-
; show 'src as source code.
|
148
|
-
; expect to override this later when pretty-printing is available
|
149
|
-
(inspect src))
|
150
|
-
|
151
|
-
(def dox-show-info (name what texts args src)
|
152
|
-
; show the given dox info
|
153
|
-
; 'info arg is a dox object from the dox system
|
154
|
-
"~(if (eq? what 'mac) "Macro"
|
155
|
-
(eq? what 'def) "Function"
|
156
|
-
what) : ~name
|
157
|
-
|
158
|
-
args : ~(inspect args)
|
159
|
-
|
160
|
-
~(joinstr "\n" texts)
|
161
|
-
|
162
|
-
source
|
163
|
-
======
|
164
|
-
~(dox-show-src src)
|
165
|
-
")
|
166
|
-
|
167
|
-
(mac dox (name)
|
168
|
-
; show dox for the given name
|
169
|
-
`(let infos (dox-lookup ',name)
|
170
|
-
(if (no infos)
|
171
|
-
(p "No documentation for" ',name)
|
172
|
-
(each info infos
|
173
|
-
(p:apply dox-show-info info)))))
|
174
|
-
|
175
163
|
(def proper? (list)
|
176
164
|
; t if this is a proper list (last cdr is nil)
|
177
165
|
; nil otherwise (last cdr is neither cons nor nil)
|
@@ -0,0 +1,85 @@
|
|
1
|
+
(def dox-show-src (src)
|
2
|
+
; show 'src as source code.
|
3
|
+
; expect to override this later when pretty-printing is available
|
4
|
+
(inspect src))
|
5
|
+
|
6
|
+
(def dox-show-info (name what texts args src)
|
7
|
+
; show the given dox info
|
8
|
+
; 'info arg is a dox object from the dox system
|
9
|
+
"~(if (eq? what 'mac) "Macro"
|
10
|
+
(eq? what 'def) "Function"
|
11
|
+
what) : ~name
|
12
|
+
|
13
|
+
args : ~(inspect args)
|
14
|
+
|
15
|
+
~(joinstr "\n" texts)
|
16
|
+
|
17
|
+
source
|
18
|
+
======
|
19
|
+
~(dox-show-src src)
|
20
|
+
")
|
21
|
+
|
22
|
+
(def dox-show-one-example (name example)
|
23
|
+
"~|name| ~(car example)
|
24
|
+
|
25
|
+
running :
|
26
|
+
~(dox-show-src:cadr example)
|
27
|
+
|
28
|
+
produces : ~(dox-show-src:caddr example)
|
29
|
+
|
30
|
+
--------------------------------
|
31
|
+
")
|
32
|
+
|
33
|
+
(def dox-show-examples (name examples)
|
34
|
+
(if examples
|
35
|
+
"
|
36
|
+
Examples for ~name
|
37
|
+
==================
|
38
|
+
|
39
|
+
~(joinstr "\n\n" (map (curry dox-show-one-example name) examples))
|
40
|
+
|
41
|
+
"))
|
42
|
+
|
43
|
+
(def dox-all-items ()
|
44
|
+
; return all documentation items in a single list
|
45
|
+
(apply joinlists (map dox-lookup (dox-names))))
|
46
|
+
|
47
|
+
(def dox-with-documentation (dox-item)
|
48
|
+
; a documentation filter that returns non-nil for items with text documentation
|
49
|
+
; use with 'dox-all-items to gather dox items that are explicitly documented
|
50
|
+
; for example (cleverly-show (collect dox-with-documentation (dox-all-items)))
|
51
|
+
(nth 2 dox-item))
|
52
|
+
|
53
|
+
(mac dox (name)
|
54
|
+
; show dox for the given name, or all available dox if name is not given
|
55
|
+
(if name
|
56
|
+
`(let infos (dox-lookup ',name)
|
57
|
+
(if (no infos)
|
58
|
+
(p "No documentation for" ',name)
|
59
|
+
(each info infos
|
60
|
+
(p:apply dox-show-info info)))
|
61
|
+
(let examples (dox-examples ',name)
|
62
|
+
(if (no examples)
|
63
|
+
(p "No examples for" ',name)
|
64
|
+
(p (joinstr "\n" (map (curry dox-show-examples ',name) examples)))))
|
65
|
+
nil)
|
66
|
+
`(let infos (collect dox-with-documentation (dox-all-items))
|
67
|
+
(p "documentation available for the following:")
|
68
|
+
(each info infos
|
69
|
+
(p:inspect:firstn 2 info)))))
|
70
|
+
|
71
|
+
(def-colon-syntax dox names
|
72
|
+
(let target (cadr names)
|
73
|
+
`(dox ,(if (eq? target '||)
|
74
|
+
nil
|
75
|
+
target))))
|
76
|
+
|
77
|
+
(def explain-mac (n expr)
|
78
|
+
(if (eq? n 0)
|
79
|
+
expr
|
80
|
+
(let macfn (hash-get macs (car expr))
|
81
|
+
(if macfn
|
82
|
+
(explain-mac (- n 1)
|
83
|
+
(apply macfn
|
84
|
+
(cdr expr)))
|
85
|
+
expr))))
|