nydp 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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))
|