nydp 0.1.2 → 0.1.3
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.
- 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))))
|