nydp 0.3.0 → 0.4.0
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/.zeiger.yml +28 -0
- data/lib/lisp/core-000.nydp +1 -1
- data/lib/lisp/core-015-documentation.nydp +6 -9
- data/lib/lisp/core-017-builtin-dox.nydp +33 -0
- data/lib/lisp/core-025-warnings.nydp +15 -0
- data/lib/lisp/core-030-syntax.nydp +38 -2
- data/lib/lisp/core-035-flow-control.nydp +2 -2
- data/lib/lisp/core-037-list-utils.nydp +7 -5
- data/lib/lisp/core-040-utils.nydp +15 -4
- data/lib/lisp/core-043-list-utils.nydp +1 -0
- data/lib/lisp/core-045-dox-utils.nydp +6 -0
- data/lib/lisp/core-050-test-runner.nydp +9 -9
- data/lib/lisp/core-070-prefix-list.nydp +2 -2
- data/lib/lisp/core-090-hook.nydp +24 -0
- data/lib/lisp/core-100-utils.nydp +38 -10
- data/lib/lisp/tests/ampersand-syntax-examples.nydp +26 -0
- data/lib/lisp/tests/boot-tests.nydp +1 -1
- data/lib/lisp/tests/collect-tests.nydp +4 -0
- data/lib/lisp/tests/destructuring-examples.nydp +18 -1
- data/lib/lisp/tests/fill-bucket-examples.nydp +46 -2
- data/lib/lisp/tests/floor-examples.nydp +58 -0
- data/lib/lisp/tests/k-examples.nydp +5 -0
- data/lib/lisp/tests/power-examples.nydp +16 -0
- data/lib/lisp/tests/string-tests.nydp +8 -0
- data/lib/lisp/tests/syntax-tests.nydp +6 -0
- data/lib/lisp/tests/zip-examples.nydp +16 -0
- data/lib/nydp.rb +6 -2
- data/lib/nydp/assignment.rb +1 -2
- data/lib/nydp/builtin/ensuring.rb +1 -2
- data/lib/nydp/builtin/greater_than.rb +2 -2
- data/lib/nydp/builtin/handle_error.rb +1 -2
- data/lib/nydp/builtin/less_than.rb +2 -2
- data/lib/nydp/builtin/math_ceiling.rb +7 -0
- data/lib/nydp/builtin/math_floor.rb +7 -0
- data/lib/nydp/builtin/math_power.rb +7 -0
- data/lib/nydp/builtin/math_round.rb +7 -0
- data/lib/nydp/builtin/parse.rb +2 -2
- data/lib/nydp/builtin/parse_in_string.rb +3 -3
- data/lib/nydp/builtin/pre_compile.rb +0 -1
- data/lib/nydp/compiler.rb +1 -1
- data/lib/nydp/cond.rb +3 -6
- data/lib/nydp/context_symbol.rb +40 -32
- data/lib/nydp/core.rb +8 -2
- data/lib/nydp/function_invocation.rb +3 -5
- data/lib/nydp/image_store.rb +21 -0
- data/lib/nydp/interpreted_function.rb +8 -12
- data/lib/nydp/lexical_context_builder.rb +19 -35
- data/lib/nydp/pair.rb +2 -1
- data/lib/nydp/parser.rb +4 -0
- data/lib/nydp/plugin.rb +15 -8
- data/lib/nydp/runner.rb +3 -3
- data/lib/nydp/symbol.rb +3 -1
- data/lib/nydp/symbol_lookup.rb +2 -2
- data/lib/nydp/truth.rb +2 -2
- data/lib/nydp/version.rb +1 -1
- data/lib/nydp/vm.rb +47 -27
- data/spec/date_spec.rb +2 -2
- data/spec/embedded_spec.rb +16 -16
- data/spec/error_spec.rb +1 -1
- data/spec/nydp_spec.rb +13 -4
- data/spec/parser_spec.rb +63 -16
- data/spec/spec_helper.rb +1 -2
- data/spec/string_atom_spec.rb +2 -2
- data/spec/symbol_spec.rb +2 -2
- data/spec/tokeniser_spec.rb +101 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d9a87eb0c014a51f391ddd1ba6686165a01ab48
|
4
|
+
data.tar.gz: 8c3f3146c0ae8dc18ac6e86324274423d75be651
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f946a10304dd7422fb73243b9cd3ef40fab33aa9ff4f0b53568278761b64905d00714ed0cf7401db29b8c3613d8a683460ed48feef3f174ab0c724dd3e5f922e
|
7
|
+
data.tar.gz: 1925438dd0eca5a718e6f41ff39ef9f35e1a9ed18279e58f2ebfa88c284cb46526f4864932db706dc346662a59cb153fbec70fca1047aeddc742740de971dab5
|
data/.zeiger.yml
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
search:
|
2
|
+
- "bin/**/*"
|
3
|
+
- "lib/**/*"
|
4
|
+
- "spec/**/*"
|
5
|
+
- "*.gemspec"
|
6
|
+
- ".*.yml"
|
7
|
+
- ".git?*"
|
8
|
+
- "Gemfile*"
|
9
|
+
- README
|
10
|
+
ignore:
|
11
|
+
- .doc$
|
12
|
+
- .ods$
|
13
|
+
- .gz$
|
14
|
+
- .png$
|
15
|
+
- .gif$
|
16
|
+
- .zip$
|
17
|
+
- .jpg$
|
18
|
+
- .xcf$
|
19
|
+
- .pdf$
|
20
|
+
- /select2/.*.js$
|
21
|
+
stats:
|
22
|
+
nydp:
|
23
|
+
- ".*\\.nydp"
|
24
|
+
code:
|
25
|
+
- "lib/.*\\.(rb|rake)"
|
26
|
+
test:
|
27
|
+
- "spec/.*"
|
28
|
+
- "test/.*"
|
data/lib/lisp/core-000.nydp
CHANGED
@@ -5,8 +5,8 @@
|
|
5
5
|
;; to, 'do, 'rfn, 'loop, 'for) were directly inspired by (aka stolen from) arc.arc. See
|
6
6
|
;; README.md however for some significant differences
|
7
7
|
|
8
|
+
(assign noop (fn))
|
8
9
|
(assign list (fn args args))
|
9
|
-
(assign noop (fn args nil))
|
10
10
|
(assign x1 (fn (arg) arg))
|
11
11
|
(assign caar (fn (arg) (car (car arg))))
|
12
12
|
(assign cadr (fn (arg) (car (cdr arg))))
|
@@ -14,9 +14,6 @@
|
|
14
14
|
(hash-set hsh 'name name)
|
15
15
|
hsh)
|
16
16
|
|
17
|
-
(def chapter-names () (hash-keys chapters))
|
18
|
-
(def chapter-current () this-chapter-name)
|
19
|
-
|
20
17
|
(def chapter-build (name chapter)
|
21
18
|
(cond chapter
|
22
19
|
chapter
|
@@ -25,8 +22,10 @@
|
|
25
22
|
name
|
26
23
|
(chapter-new (hash) name)))))
|
27
24
|
|
28
|
-
(def chapter-
|
29
|
-
|
25
|
+
(def chapter-names () (hash-keys chapters))
|
26
|
+
(def chapter-current () this-chapter-name)
|
27
|
+
(def chapter-delete (name) (hash-set chapters name nil))
|
28
|
+
(def chapter-find (name) (chapter-build name (hash-get chapters name)))
|
30
29
|
|
31
30
|
(def chapter-add-to-chapter (chapter attribute thing)
|
32
31
|
(cond chapter
|
@@ -62,9 +61,9 @@
|
|
62
61
|
(hash-cons dox (hash-get item 'name) item)
|
63
62
|
(dox-add-to-chapters item (hash-get item 'chapters)))
|
64
63
|
|
65
|
-
(def dox-add-doc (name what texts args src chapters)
|
64
|
+
(def dox-add-doc (name what texts args src chapters more)
|
66
65
|
(cond (no (privately))
|
67
|
-
(dox-new (dox-build (hash) name what texts args src chapters))))
|
66
|
+
(dox-new (dox-build (if more more (hash)) name what texts args src chapters))))
|
68
67
|
|
69
68
|
(def dox-add-to-chapters (item chapters)
|
70
69
|
(cond chapters
|
@@ -85,8 +84,6 @@
|
|
85
84
|
(cond (dox? name)
|
86
85
|
(hash-get (car (dox-lookup name)) attr)))
|
87
86
|
|
88
|
-
(def dox-chapter-names () (hash-keys chapters ))
|
89
|
-
(def dox-chapter (name) (hash-get chapters name ))
|
90
87
|
(def dox-what-is? (name) (dox-get-attr name 'what ))
|
91
88
|
(def dox-src (name) (dox-get-attr name 'src ))
|
92
89
|
(def dox-examples (name) (hash-get examples name ))
|
@@ -7,6 +7,10 @@
|
|
7
7
|
(dox-add-doc '/ 'def '("return the result of dividing all other args into the first arg." "(/ a b c d) is equivalent to (/ a (* b c d))") 'things nil '(math))
|
8
8
|
(dox-add-doc '> 'def '("true if each arg is greater than the next arg") 'things nil '(math))
|
9
9
|
(dox-add-doc '< 'def '("true if each arg is less than the next arg") 'things nil '(math))
|
10
|
+
(dox-add-doc '** 'def '("returns a to the power of b") '(a b) nil '(math))
|
11
|
+
(dox-add-doc '⌊ 'def '("returns the floor of a (round towards -∞)") '(a) nil '(math))
|
12
|
+
(dox-add-doc '⌈ 'def '("returns the ceiling of a (round towards +∞)") '(a) nil '(math))
|
13
|
+
(dox-add-doc 'round 'def '("returns a rounded half-away from zero") '(a) nil '(math))
|
10
14
|
(dox-add-doc 'mod 'def '("return the remainder after diving a by b") '(a b) nil '(math))
|
11
15
|
(dox-add-doc 'eval 'def '("evaluate the given lisp expression") '(expr) nil '(nydp-core))
|
12
16
|
(dox-add-doc 'hash 'def '("create a new Hash instance") nil nil '(hash-manipulation))
|
@@ -18,6 +22,19 @@
|
|
18
22
|
(dox-add-doc 'sort 'def '("return 'things, sorted according to their natural sort order") 'things nil '(list-manipulation))
|
19
23
|
(dox-add-doc 'sqrt 'def '("return the square root of 'arg") '(arg) nil '(math))
|
20
24
|
(dox-add-doc 'sym 'def '("return the symbol for the given string 'arg") '(arg) nil '(nydp-core))
|
25
|
+
(dox-add-doc 'list 'def '("returns args as a list") 'args nil '(nydp-core))
|
26
|
+
(dox-add-doc 'noop 'def '("does nothing; returns nil") nil nil '(nydp-core))
|
27
|
+
(dox-add-doc 'x1 'def '("just returns arg; the identity function") '(arg) nil '(nydp-core))
|
28
|
+
(dox-add-doc 'caar 'def '("car of car; same as (car (car arg))") '(arg) nil '(nydp-core))
|
29
|
+
(dox-add-doc 'cadr 'def '("car of cdr; same as (car (cdr arg))") '(arg) nil '(nydp-core))
|
30
|
+
(dox-add-doc 'cdar 'def '("cdr of car; same as (cdr (car arg))") '(arg) nil '(nydp-core))
|
31
|
+
(dox-add-doc 'cddr 'def '("cdr of cdr; same as (cdr (cdr arg))") '(arg) nil '(nydp-core))
|
32
|
+
(dox-add-doc 'no 'def '("t if arg is nil, nil otherwise") '(arg) nil '(nydp-core))
|
33
|
+
(dox-add-doc 'just 'def '("just returns arg; the identity function") '(arg) nil '(nydp-core))
|
34
|
+
(dox-add-doc 'isa 'def '("t if (type-of obj) is equal to type") '(type obj) nil '(nydp-core))
|
35
|
+
(dox-add-doc 'pair? 'def '("t if arg is a cons cell or (equivalently) the start of a list") '(arg) nil '(nydp-core))
|
36
|
+
(dox-add-doc 'hash? 'def '("t if arg is a hash") '(arg) nil '(nydp-core))
|
37
|
+
(dox-add-doc 'sym? 'def '("t if arg is a symbol, nil otherwise") '(arg) nil '(nydp-core))
|
21
38
|
(dox-add-doc 'ensuring 'def '("execute 'tricky-f, then 'ensure-f afterwards"
|
22
39
|
"'ensure-f will always be executed, even if there is an error in 'tricky-f"
|
23
40
|
"returns the return value of 'tricky-f") '(ensure-f tricky-f) nil '(flow-control))
|
@@ -29,6 +46,7 @@
|
|
29
46
|
(dox-add-doc 'string-length 'def '("return the length of 'arg") '(arg) nil '(string-manipulation))
|
30
47
|
(dox-add-doc 'string-replace 'def '("replace 'pattern with 'insert in 'str") '(pattern insert str) nil '(string-manipulation))
|
31
48
|
(dox-add-doc 'string-split 'def '("split 'str delimited by 'delim") '(str delim) nil '(string-manipulation))
|
49
|
+
(dox-add-doc 'string-match 'def '("if 'str matches 'pattern, return hash with keys 'match and 'captures ; otherwise nil") '(str pattern) nil '(string-manipulation))
|
32
50
|
(dox-add-doc 'time 'def '("with no args, return the current time."
|
33
51
|
"With one arg, if 'arg-0 is a number, return the current time plus 'arg-0 seconds."
|
34
52
|
"With one arg, if 'arg-0 is a date, return the time at the beginning of the given date."
|
@@ -53,3 +71,18 @@
|
|
53
71
|
(dox-add-doc 'script-run 'def '("announces the start of a plugin load or a script load."
|
54
72
|
"'event may be one of '(script-start script-end plugin-start plugin-end)"
|
55
73
|
"'name is the name of the script or plugin concerned") '(event name) nil '(nydp-core))
|
74
|
+
|
75
|
+
(dox-add-doc 'chapter-end 'def '("Announce the end of a chapter. Called by 'plugin-start, 'plugin-end, 'script-start, 'script-end") nil nil '(nydp/documentation))
|
76
|
+
(dox-add-doc 'chapter-start 'def '("Announce the start of a chapter. Creates a new chapter if the named chapter does not already exist") '(chapter-name description) nil '(nydp/documentation))
|
77
|
+
(dox-add-doc 'chapter-names 'def '("Get the names of all the chapters nydp knows about") nil nil '(nydp/documentation))
|
78
|
+
(dox-add-doc 'chapter-current 'def '("Get the name of the chapter in progress right now - this is normally the last value sent to 'chapter-start") nil nil '(nydp/documentation))
|
79
|
+
(dox-add-doc 'chapter-delete 'def '("Remove the named chapter") '(name) nil '(nydp/documentation))
|
80
|
+
(dox-add-doc 'chapter-find 'def '("Get the named chapter") '(name) nil '(nydp/documentation))
|
81
|
+
(dox-add-doc 'dox-add-doc 'def '("Store the provided documentation item."
|
82
|
+
"'name is the name of the item"
|
83
|
+
"'what is the type of the item ('def or 'mac or 'thingy ... this is user-definable, not related to 'type-of)"
|
84
|
+
"'texts is a list of strings to store for this item"
|
85
|
+
"'args is the args if the item has the notion of args"
|
86
|
+
"'src the source code of the item if any"
|
87
|
+
"'chapters the chapters to which the item should be added, if any") '(name what texts args src chapters) nil '(nydp/documentation))
|
88
|
+
(dox-add-doc 'dox-add-examples 'def '("Add the given examples to the dox for the named item") '(name example-exprs) nil '(nydp/documentation))
|
@@ -0,0 +1,15 @@
|
|
1
|
+
(chapter-start 'nydp/warnings "Store, display, and manage warnings")
|
2
|
+
|
3
|
+
(def warnings/clear nil
|
4
|
+
; clear all stored warnings
|
5
|
+
(assign warnings/list nil))
|
6
|
+
|
7
|
+
(warnings/clear)
|
8
|
+
|
9
|
+
(def warnings (f)
|
10
|
+
; apply f to each stored warning. For example, (warnings p) to print warnings to console
|
11
|
+
(mapply f warnings))
|
12
|
+
|
13
|
+
(def warnings/new (kind . info)
|
14
|
+
; store a warning for future retrieval or display
|
15
|
+
(assign warnings/list (cons (cons kind info) warnings/list)))
|
@@ -190,15 +190,41 @@ scoping, assignment, anonymous functions and more...")
|
|
190
190
|
(def hash-get-assignment (lookup value)
|
191
191
|
`(hash-set ,@lookup ,value))
|
192
192
|
|
193
|
+
(def ampersand-expression? (name)
|
194
|
+
(and (pair? name)
|
195
|
+
(caris 'ampersand-syntax (car name))))
|
196
|
+
|
197
|
+
(def ampersand-expression-assignment (place value)
|
198
|
+
; (= (&key (expr)) (val))
|
199
|
+
; (= ((ampersand-syntax key) (expr)) (val))
|
200
|
+
; 'place is ((ampersand-syntax || key) (expr))
|
201
|
+
; we need (hash-set (expr) 'key (val))
|
202
|
+
; however,
|
203
|
+
; (= (&key.subkey (expr)) (val))
|
204
|
+
; 'place is ((ampersand-syntax || (dot-syntax key subkey)) (expr))
|
205
|
+
; we need (hash-set (hash-get (expr) 'key) 'subkey (val))
|
206
|
+
(with (k (cadr:cdar place)
|
207
|
+
hsh (cadr place))
|
208
|
+
(if (caris 'dot-syntax k)
|
209
|
+
(dot-syntax-assignment (cons hsh (cdr k)) value)
|
210
|
+
`(hash-set ,hsh ',k ,value))))
|
211
|
+
|
193
212
|
(mac = (name value)
|
194
213
|
; generic assignment which unlike builtin 'assign, knows how to assign
|
195
214
|
; to hash keys
|
215
|
+
; (= (hash-get (expr) 'key) (val) => (hash-set (expr) 'key (val))
|
216
|
+
; (= h.k (val)) => (hash-set h 'k (val))
|
217
|
+
; (= h.j.k (val)) => (hash-set (hash-get h 'j) 'k (val))
|
218
|
+
; (= (&key (expr)) (val)) => (hash-set (expr) 'key (val))
|
219
|
+
; (= (&j.k (expr)) (val)) => (hash-set (hash-get (expr) 'j) 'k (val))
|
196
220
|
(if (isa 'symbol name)
|
197
221
|
`(assign ,name ,value)
|
198
222
|
(caris 'dot-syntax name)
|
199
223
|
(dot-syntax-assignment (cdr name) value)
|
200
224
|
(caris 'hash-get name)
|
201
|
-
(hash-get-assignment (cdr name) value)
|
225
|
+
(hash-get-assignment (cdr name) value)
|
226
|
+
(ampersand-expression? name)
|
227
|
+
(ampersand-expression-assignment name value)))
|
202
228
|
|
203
229
|
(mac def-assign args
|
204
230
|
; override previous definition to allow expressions like (def hsh.foo (arg arg2) ...)
|
@@ -276,7 +302,7 @@ scoping, assignment, anonymous functions and more...")
|
|
276
302
|
(if (pair? args)
|
277
303
|
`(,(car args) (nth ,n ,var) ,@(destructure/with var (cdr args) (+ n 1)))
|
278
304
|
args
|
279
|
-
`(,args (
|
305
|
+
`(,args (nthcdr ,n ,var))))
|
280
306
|
|
281
307
|
(def destructure/build (given-args new-args body)
|
282
308
|
; used internally by 'fun
|
@@ -291,7 +317,17 @@ scoping, assignment, anonymous functions and more...")
|
|
291
317
|
`((with ,(destructure/with destructure (car given-args) 0) ,@body)))))
|
292
318
|
`(fn ,(rev new-args given-args) ,@body)))
|
293
319
|
|
320
|
+
|
321
|
+
(def fun/approve-arg-names (orig args)
|
322
|
+
(if (pair? args)
|
323
|
+
(do (fun/approve-arg-names orig (car args))
|
324
|
+
(fun/approve-arg-names orig (cdr args)))
|
325
|
+
args
|
326
|
+
(if (hash-get macs args)
|
327
|
+
(warnings/new 'arg-shadows-macro "arg " args " shadows macro " args " in arg list " orig))))
|
328
|
+
|
294
329
|
(mac fun (args . body)
|
295
330
|
; build a 'fn form, changing 'args and 'body to
|
296
331
|
; properly handle any destructuring args if present
|
332
|
+
(fun/approve-arg-names args args)
|
297
333
|
(destructure/build args nil body))
|
@@ -63,6 +63,6 @@
|
|
63
63
|
(w/uniq h
|
64
64
|
`(let ,h (hash)
|
65
65
|
(def ,name ,args
|
66
|
-
,@(
|
67
|
-
|
66
|
+
,@(map (fn (c) (cons 'comment c)) forms.comment)
|
67
|
+
,@(map (fn (c) (cons 'chapter c)) forms.chapter)
|
68
68
|
(cache-get ,h (list ,@args) (do ,@(hash-get forms nil))))))))
|
@@ -1,10 +1,10 @@
|
|
1
1
|
(chapter-start 'list-manipulation "utilities for manipulating and iterating over lists, including filters and transforms")
|
2
2
|
|
3
|
-
(def zip
|
4
|
-
; takes
|
5
|
-
(if
|
6
|
-
(cons (
|
7
|
-
(zip (
|
3
|
+
(def zip args
|
4
|
+
; takes a list of lists, ((p q r) (1 2 3) (a b c) ...), returns ((p 1 a ...) (q 2 b ...) (r 3 c ...))
|
5
|
+
(if (car args)
|
6
|
+
(cons (map car args)
|
7
|
+
(apply zip (map cdr args)))))
|
8
8
|
|
9
9
|
(def eachr (f things)
|
10
10
|
(when things
|
@@ -12,9 +12,11 @@
|
|
12
12
|
(f (car things))))
|
13
13
|
|
14
14
|
(mac push (x things)
|
15
|
+
; assign (cons x things) to things
|
15
16
|
`(= ,things (cons ,x ,things)))
|
16
17
|
|
17
18
|
(def flatten (things)
|
19
|
+
; flatten the given list, recursively
|
18
20
|
(let acc nil
|
19
21
|
(rfnwith flattenize (x things)
|
20
22
|
(if (pair? x)
|
@@ -4,13 +4,24 @@
|
|
4
4
|
(or (eq? x y)
|
5
5
|
(and (pair? x)
|
6
6
|
(pair? y)
|
7
|
+
(eq? (len x) (len y))
|
7
8
|
(iso (car x) (car y))
|
8
9
|
(iso (cdr x) (cdr y)))))
|
9
10
|
|
10
|
-
(def num? (arg)
|
11
|
-
(def string? (arg)
|
12
|
-
|
13
|
-
(
|
11
|
+
(def num? (arg) (comment "true if arg is a number") (isa 'number arg))
|
12
|
+
(def string? (arg) (comment "true if arg is a string") (isa 'string arg))
|
13
|
+
|
14
|
+
(mac just (expr)
|
15
|
+
; this is useful sometimes when 'expr can't stand on its own due to lexical ambiguity, most often in string interpolations
|
16
|
+
; for example, in "hello ~person, how are you", the parser will try to interpolate the symbol "person," rather than the
|
17
|
+
; expected "person". In this case, use "hello ~(just person), how are you"
|
18
|
+
expr)
|
19
|
+
|
20
|
+
(def quotify (arg) `(quote ,arg))
|
21
|
+
|
22
|
+
(defmemo k (arg)
|
23
|
+
; return a function that always returns 'arg, similar to K in SKI calculus
|
24
|
+
(fn nil arg))
|
14
25
|
|
15
26
|
(def len (things)
|
16
27
|
; return the length of 'things where 'things may be nil, a string, list or hash
|
@@ -34,6 +34,7 @@
|
|
34
34
|
; if 'things is a list, return all the items in the list for which 'f returns non-nil
|
35
35
|
; otherwise, return 'things if (f things) is non-nil
|
36
36
|
; otherwise, nil
|
37
|
+
; note that this preserves improper lists and may return only the lastcdr if all else fails...
|
37
38
|
(rfnwith collector (items things)
|
38
39
|
(if (no items)
|
39
40
|
nil
|
@@ -84,3 +84,9 @@ Examples for ~name
|
|
84
84
|
(apply macfn
|
85
85
|
(cdr expr)))
|
86
86
|
expr))))
|
87
|
+
|
88
|
+
(def chapter-remove-item (chapter-name item-name)
|
89
|
+
; remove the named item from the named chapter
|
90
|
+
(chapter nydp/documentation)
|
91
|
+
(let ch (chapter-find chapter-name)
|
92
|
+
(= ch.contents (collect (fn (item) (!eq? item.name item-name)) ch.contents))))
|
@@ -26,15 +26,15 @@
|
|
26
26
|
|
27
27
|
(def execute-single-test (desc test passf failf verbose)
|
28
28
|
(if verbose (p desc " - " (car test)))
|
29
|
-
(
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
")
|
37
|
-
|
29
|
+
(on-err (error (j "FAILED " desc " - " (car test)) (pp:nth 1 test))
|
30
|
+
(with (expected (nth 2 test) result (eval (nth 1 test)))
|
31
|
+
(if (iso result expected)
|
32
|
+
(passf)
|
33
|
+
(do (p desc " - " (car test) " - FAILED:
|
34
|
+
running " (pp (nth 1 test)) ",
|
35
|
+
expected " (inspect expected) ",
|
36
|
+
got " (inspect result) "\n")
|
37
|
+
(failf))))))
|
38
38
|
|
39
39
|
(def execute-tests (desc tests passf failf verbose)
|
40
40
|
(execute-test desc
|
@@ -26,8 +26,8 @@
|
|
26
26
|
`(push (cons ,regex (fn (,prefix-var ,list-var) ,@body))
|
27
27
|
prefix-list-prefixes))
|
28
28
|
|
29
|
-
(define-prefix-list-macro "
|
29
|
+
(define-prefix-list-macro "^λ.*" vars expr
|
30
30
|
;; allows (map λa(upcase a.name) people)
|
31
31
|
;; as shortcut for (map (fn (a) (upcase a.name)) people)
|
32
|
-
(let var-list (map sym (cdr:string-split vars))
|
32
|
+
(let var-list (map sym (collect !empty? (cdr:string-split vars)))
|
33
33
|
`(fn ,var-list ,expr)))
|
data/lib/lisp/core-090-hook.nydp
CHANGED
@@ -1,21 +1,45 @@
|
|
1
|
+
(chapter-start 'nydp/hooks "event management - execute a piece of code when something happens")
|
2
|
+
|
1
3
|
(let hooks {}
|
2
4
|
(def hook-names ()
|
5
|
+
; return the list of hook-names
|
3
6
|
(hash-keys hooks))
|
4
7
|
|
5
8
|
(def hooks-for (hook-name)
|
9
|
+
; return the list of hooks for 'hook-name
|
6
10
|
hooks.,hook-name)
|
7
11
|
|
8
12
|
(def add-hook (hook-name f)
|
13
|
+
; add a function 'f to execute when 'hook-name is fired
|
9
14
|
(hash-cons hooks hook-name f))
|
10
15
|
|
11
16
|
(def clear-hooks (hook-name)
|
17
|
+
; remove all hooks for 'hook-name
|
12
18
|
(= hooks.,hook-name nil))
|
13
19
|
|
20
|
+
(def without-hooks (hook-name f)
|
21
|
+
; temporarily remove all hooks for 'hook-name, restoring them after running 'f
|
22
|
+
(let previous-hooks (hooks-for hook-name)
|
23
|
+
(ensure (= hooks.,hook-name previous-hooks)
|
24
|
+
(clear-hooks hook-name)
|
25
|
+
(f))))
|
26
|
+
|
14
27
|
(def remove-hook (hook-name f)
|
28
|
+
; only works if you have a reference to the original function
|
15
29
|
(= hooks.,hook-name
|
16
30
|
(collect (curry !eq? f)
|
17
31
|
hooks.,hook-name)))
|
18
32
|
|
19
33
|
(def run-hooks (hook-name . args)
|
34
|
+
; apply all functions attached to 'hook-name to given 'args
|
20
35
|
(each hook (hooks-for hook-name)
|
21
36
|
(apply hook args))))
|
37
|
+
|
38
|
+
(add-hook 'warnings/new λw(apply p w))
|
39
|
+
|
40
|
+
(let super warnings/new
|
41
|
+
(def warnings/new (kind . info)
|
42
|
+
; enhance original warnings/new to run the 'warnings/new hook
|
43
|
+
(chapter nydp/warnings)
|
44
|
+
(apply super kind info)
|
45
|
+
(run-hooks 'warnings/new (cons kind info))))
|
@@ -87,7 +87,7 @@
|
|
87
87
|
(nth (= i (mod (+ 1 (or j i)) list-len))
|
88
88
|
xs))))
|
89
89
|
|
90
|
-
(def fill
|
90
|
+
(def bucket/fill (items bucket size-f bucket-size maximum-size)
|
91
91
|
; returns a list (list a b c) where
|
92
92
|
; 'a is a subset of 'items
|
93
93
|
; 'b is the sum of sizes of items in 'a : (apply + (map size-f a))
|
@@ -101,12 +101,40 @@
|
|
101
101
|
; 'size-f is a function that can tell the size of each item in 'items
|
102
102
|
; 'bucket-size is the size of the existing bucket, or 0 if empty
|
103
103
|
; 'maximum-size is the maximum allowed size for the bucket
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
104
|
+
; implementation note: this function exploits the behaviour of '> returning its last argument when true
|
105
|
+
(aif (and items
|
106
|
+
(> maximum-size (+ (size-f (car items)) bucket-size)))
|
107
|
+
(bucket/fill (cdr items)
|
108
|
+
(cons (car items) bucket)
|
109
|
+
size-f
|
110
|
+
it
|
111
|
+
maximum-size)
|
112
|
+
(and items (eq? bucket-size 0))
|
113
|
+
(bucket/fill (cdr items)
|
114
|
+
(cons (car items) bucket)
|
115
|
+
size-f
|
116
|
+
(size-f (car items))
|
117
|
+
maximum-size)
|
118
|
+
(list (rev bucket) bucket-size items)))
|
119
|
+
|
120
|
+
(def bucket/new (buckets)
|
121
|
+
; used by 'fill-buckets
|
122
|
+
(cons { bucket-size 0 } buckets))
|
123
|
+
|
124
|
+
(def fill-buckets (items max buckets size-f key)
|
125
|
+
; useful for pagination where each item may have a different size
|
126
|
+
; returns a list of hash with keys 'bucket-size and key
|
127
|
+
; if buckets is non-nil, assumes it is a list of previously-established buckets
|
128
|
+
; will add new items to first bucket if its 'bucket-size permits
|
129
|
+
(if items
|
130
|
+
(if buckets
|
131
|
+
(let initial (car buckets)
|
132
|
+
(let (these size others)
|
133
|
+
(bucket/fill items nil size-f initial.bucket-size max)
|
134
|
+
(hash-set initial key these)
|
135
|
+
(= initial.bucket-size size)
|
136
|
+
(if others
|
137
|
+
(fill-buckets others max (bucket/new buckets) size-f key)
|
138
|
+
(fill-buckets others max buckets size-f key))))
|
139
|
+
(fill-buckets items max (bucket/new buckets) size-f key))
|
140
|
+
buckets))
|