nydp 0.4.2 → 0.4.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/lib/lisp/core-010-precompile.nydp +10 -12
- data/lib/lisp/core-012-utils.nydp +1 -1
- data/lib/lisp/core-015-documentation.nydp +9 -5
- data/lib/lisp/core-030-syntax.nydp +25 -12
- data/lib/lisp/core-037-list-utils.nydp +1 -0
- data/lib/lisp/core-042-date-utils.nydp +5 -1
- data/lib/lisp/core-043-list-utils.nydp +13 -3
- data/lib/lisp/core-090-hook.nydp +11 -1
- data/lib/lisp/core-110-hash-utils.nydp +18 -2
- data/lib/lisp/core-120-settings.nydp +5 -3
- data/lib/lisp/tests/aif-examples.nydp +8 -3
- data/lib/lisp/tests/andify-examples.nydp +7 -0
- data/lib/lisp/tests/builtin-tests.nydp +9 -0
- data/lib/lisp/tests/destructuring-examples.nydp +5 -5
- data/lib/lisp/tests/hash-examples.nydp +8 -1
- data/lib/lisp/tests/list-tests.nydp +19 -1
- data/lib/lisp/tests/map-hash-examples.nydp +11 -0
- data/lib/lisp/tests/parser-tests.nydp +5 -0
- data/lib/lisp/tests/pretty-print-tests.nydp +8 -11
- data/lib/lisp/tests/set-difference-examples.nydp +8 -0
- data/lib/nydp/builtin/hash.rb +13 -0
- data/lib/nydp/core.rb +1 -0
- data/lib/nydp/date.rb +8 -1
- data/lib/nydp/function_invocation.rb +1 -1
- data/lib/nydp/pair.rb +1 -0
- data/lib/nydp/parser.rb +3 -3
- data/lib/nydp/string_atom.rb +3 -4
- data/lib/nydp/tokeniser.rb +2 -2
- data/lib/nydp/truth.rb +8 -8
- data/lib/nydp/version.rb +1 -1
- data/spec/date_spec.rb +14 -0
- data/spec/embedded_spec.rb +8 -8
- data/spec/foreign_hash_spec.rb +12 -0
- data/spec/hash_spec.rb +22 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a6a8e0215b81d92423402f9933413c58ebcdad9
|
4
|
+
data.tar.gz: eeb8d8bb621ed6349d2e9d4e7823c3be5e875d04
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f32b55812f569e1329b657eed211054be4e275fcd778671ec7e251fe2b98fc7390531a9742ca819c9eb076aeb9bb34ffd2390c0fd5ebe43ddfc35d75e0eae95
|
7
|
+
data.tar.gz: 2f5cad91e0551afb32c410751c56b11e1b55158218a8bdab8eb5db3d2b38719d3cfb63cc04ca961b7e1436075dbaf10ad3d5d82bf75a61f1fc1d91fd25c03a3f
|
@@ -1,17 +1,12 @@
|
|
1
|
-
(assign mac-expand
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
(assign mac-expand
|
2
|
+
(fn (names macfn expr)
|
3
|
+
(cond macfn
|
4
|
+
(pre-compile-with names
|
5
|
+
(apply macfn (cdr expr)))
|
6
|
+
expr)))
|
6
7
|
|
7
8
|
(assign macs (hash))
|
8
9
|
|
9
|
-
(assign pre-compile-expr
|
10
|
-
(fn (names expr)
|
11
|
-
(mac-expand names
|
12
|
-
(hash-get names (car expr))
|
13
|
-
expr)))
|
14
|
-
|
15
10
|
(assign pre-compile-each
|
16
11
|
(fn (names args)
|
17
12
|
(cond args
|
@@ -33,7 +28,10 @@
|
|
33
28
|
(cond (eq? (car arg) 'quote)
|
34
29
|
arg
|
35
30
|
(pre-compile-each names
|
36
|
-
(
|
31
|
+
(mac-expand names
|
32
|
+
(hash-get names
|
33
|
+
(car arg))
|
34
|
+
arg)))
|
37
35
|
arg)))
|
38
36
|
|
39
37
|
(assign pre-compile-debug
|
@@ -64,7 +64,7 @@
|
|
64
64
|
(assign this-script nil)
|
65
65
|
(assign this-plugin "Nydp Core")
|
66
66
|
|
67
|
-
((fn (dox examples chapters types dox-new dox-build)
|
67
|
+
((fn (dox examples chapters types types-chapters dox-new dox-build)
|
68
68
|
(def dox-build (hsh name what texts args src chapters)
|
69
69
|
(hash-set hsh 'name name )
|
70
70
|
(hash-set hsh 'what what )
|
@@ -79,16 +79,17 @@
|
|
79
79
|
(def dox-new (item)
|
80
80
|
(hash-cons dox (hash-get item 'name) item)
|
81
81
|
(hash-cons types (hash-get item 'what) item)
|
82
|
-
(dox-add-to-chapters item (hash-get item 'chapters)))
|
82
|
+
(dox-add-to-chapters item (hash-get item 'what) (hash-get item 'chapters)))
|
83
83
|
|
84
84
|
(def dox-add-doc (name what texts args src chapters more)
|
85
85
|
(cond (no (privately))
|
86
86
|
(dox-new (dox-build (if more more (hash)) name what texts args src chapters))))
|
87
87
|
|
88
|
-
(def dox-add-to-chapters (item chapters)
|
88
|
+
(def dox-add-to-chapters (item type chapters)
|
89
89
|
(cond chapters
|
90
90
|
(do (chapter-add-item item (car chapters))
|
91
|
-
(
|
91
|
+
(hash-cons types-chapters (cons type (car chapters)) item)
|
92
|
+
(dox-add-to-chapters item type (cdr chapters)))
|
92
93
|
item))
|
93
94
|
|
94
95
|
(def dox-add-examples (name example-exprs)
|
@@ -102,6 +103,9 @@
|
|
102
103
|
(def dox-types () (hash-keys types))
|
103
104
|
(def dox-items-by-type (type) (hash-get types type))
|
104
105
|
|
106
|
+
(def dox-items-by-type-and-chapter (type chapter)
|
107
|
+
(hash-get types-chapters (cons type chapter)))
|
108
|
+
|
105
109
|
(def dox-get-attr (name attr)
|
106
110
|
(cond (dox? name)
|
107
111
|
(hash-get (car (dox-lookup name)) attr)))
|
@@ -111,7 +115,7 @@
|
|
111
115
|
(def dox-examples (name) (hash-get examples name ))
|
112
116
|
(def dox-args (name) (dox-get-attr name 'args ))
|
113
117
|
(def dox-example-names () (hash-keys examples )))
|
114
|
-
(hash) (hash) (hash) (hash) nil)
|
118
|
+
(hash) (hash) (hash) (hash) (hash) nil)
|
115
119
|
|
116
120
|
(def plugin-start (name) (assign this-plugin name) (chapter-end))
|
117
121
|
(def plugin-end (name) (assign this-plugin nil ) (chapter-end))
|
@@ -116,6 +116,16 @@ scoping, assignment, anonymous functions and more...")
|
|
116
116
|
(assign ,name (fun ,(map car ppairs) ,@body))
|
117
117
|
(,name ,@(map cadr ppairs)))))
|
118
118
|
|
119
|
+
;; (andify a b c) is equivalent to
|
120
|
+
;; (fn args (and (apply a args) (apply b args) (apply c args)))
|
121
|
+
;; or more simply
|
122
|
+
;; (fn (x) (and (a x) (b x) (c x)))
|
123
|
+
(def andify args
|
124
|
+
(fn args2 (rfnwith self (ands args)
|
125
|
+
(if ands (if (apply (car ands) args2)
|
126
|
+
(self (cdr ands)))
|
127
|
+
t))))
|
128
|
+
|
119
129
|
(let uniq-counter 0
|
120
130
|
(def uniq (prefix)
|
121
131
|
(assign uniq-counter (+ uniq-counter 1))
|
@@ -283,16 +293,19 @@ scoping, assignment, anonymous functions and more...")
|
|
283
293
|
; (eg hash), the mutated value will be returned. See also 'returnlet
|
284
294
|
(mac returning (val . body) (w/uniq retval `(returnlet ,retval ,val ,@body)))
|
285
295
|
|
286
|
-
(mac
|
287
|
-
|
288
|
-
|
289
|
-
; source: arc.arc
|
290
|
-
`(let it ,expr
|
291
|
-
(if it
|
296
|
+
(mac ifv (var expr . body)
|
297
|
+
`(let ,var ,expr
|
298
|
+
(if ,var
|
292
299
|
,@(if (cddr body)
|
293
|
-
`(,(car body) (
|
300
|
+
`(,(car body) (ifv ,var ,@(cdr body)))
|
294
301
|
body))))
|
295
302
|
|
303
|
+
; like if, except the value of each condition is locally bound to the variable 'it
|
304
|
+
; eg (aif (find thing) (show it))
|
305
|
+
; source: arc.arc
|
306
|
+
(mac aif (expr . body)
|
307
|
+
`(ifv it ,expr ,@body))
|
308
|
+
|
296
309
|
(def destructure/with (var args n)
|
297
310
|
; provides the argument expression to 'with when
|
298
311
|
; destructuring arguments are present in a 'fun definition
|
@@ -315,18 +328,18 @@ scoping, assignment, anonymous functions and more...")
|
|
315
328
|
`(fn ,(rev new-args given-args) ,@body)))
|
316
329
|
|
317
330
|
|
318
|
-
(def fun/approve-arg-names (orig args)
|
331
|
+
(def fun/approve-arg-names (orig args body)
|
319
332
|
(if (pair? args)
|
320
|
-
(do (fun/approve-arg-names orig (car args))
|
321
|
-
(fun/approve-arg-names orig (cdr args)))
|
333
|
+
(do (fun/approve-arg-names orig (car args) body)
|
334
|
+
(fun/approve-arg-names orig (cdr args) body))
|
322
335
|
args
|
323
336
|
(if (hash-get macs args)
|
324
|
-
(warnings/new 'arg-shadows-macro "arg " args " shadows macro " args " in arg list " orig))))
|
337
|
+
(warnings/new 'arg-shadows-macro "arg " args " shadows macro " args " in arg list " orig " and body " body))))
|
325
338
|
|
326
339
|
(mac fun (args . body)
|
327
340
|
; build a 'fn form, changing 'args and 'body to
|
328
341
|
; properly handle any destructuring args if present
|
329
|
-
(fun/approve-arg-names args args)
|
342
|
+
(fun/approve-arg-names args args body)
|
330
343
|
(destructure/build args nil body))
|
331
344
|
|
332
345
|
; assign (f place) to place
|
@@ -1,5 +1,9 @@
|
|
1
1
|
(chapter-start 'date-time "utilities for retrieving and manipulating dates and times")
|
2
2
|
|
3
|
+
;; return a date for the current day
|
3
4
|
(def today ()
|
4
|
-
; return a date for the current day
|
5
5
|
(date))
|
6
|
+
|
7
|
+
;; return a Time object representing the time 's seconds ago
|
8
|
+
(def seconds-ago (s)
|
9
|
+
(- (time) s))
|
@@ -48,9 +48,8 @@
|
|
48
48
|
|
49
49
|
(assign select collect)
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
(collect present? things))
|
51
|
+
; return a new list containing only 'present? items from the given list
|
52
|
+
(def compact (things) (collect present? things))
|
54
53
|
|
55
54
|
(def +nz args
|
56
55
|
; return the sum of all non-nil values (consider nil as zero)
|
@@ -215,3 +214,14 @@
|
|
215
214
|
|
216
215
|
; given an arg 'f, invoke 'f with no args
|
217
216
|
(def self-invoke (f) (f))
|
217
|
+
|
218
|
+
;; returns the first element of 'things iff it is the only element of 'things
|
219
|
+
(def list-single-element (things)
|
220
|
+
(if (no (cdr things)) (car things)))
|
221
|
+
|
222
|
+
;; like map, but function 'f takes two arguments: the thing and the 0-based index of the thing
|
223
|
+
(def map-with-index (f things)
|
224
|
+
(let i -1
|
225
|
+
(map (fn (thing)
|
226
|
+
(f thing (++ i)))
|
227
|
+
things)))
|
data/lib/lisp/core-090-hook.nydp
CHANGED
@@ -35,7 +35,15 @@
|
|
35
35
|
(each hook (hooks-for hook-name)
|
36
36
|
(apply hook args))))
|
37
37
|
|
38
|
-
|
38
|
+
; install a hook for a particular kind of event
|
39
|
+
;
|
40
|
+
; example
|
41
|
+
; (on transaction (account amount) (update account total (+ account.total amount)))
|
42
|
+
;
|
43
|
+
; same as (add-hook 'transaction (fn (account amount) (update account total (+ account.total amount))))
|
44
|
+
;
|
45
|
+
(mac on (event args . body)
|
46
|
+
`(add-hook ',event (fn ,args ,@body)))
|
39
47
|
|
40
48
|
(let super warnings/new
|
41
49
|
(def warnings/new (kind . info)
|
@@ -43,3 +51,5 @@
|
|
43
51
|
(chapter nydp/warnings)
|
44
52
|
(apply super kind info)
|
45
53
|
(run-hooks 'warnings/new (cons kind info))))
|
54
|
+
|
55
|
+
(on warnings/new w (apply p w))
|
@@ -1,7 +1,23 @@
|
|
1
1
|
(chapter-start 'hash-manipulation "utilities for manipulating, accessing and altering hash objects")
|
2
2
|
|
3
3
|
; return values for each key in hash 'h
|
4
|
-
(def hash-values (h)
|
4
|
+
(def hash-values (h)
|
5
|
+
(map λk(hash-get h k)
|
6
|
+
(hash-keys h)))
|
5
7
|
|
6
8
|
; (auto-hash a b c) same as { a a b b c c }
|
7
|
-
(mac auto-hash names
|
9
|
+
(mac auto-hash names
|
10
|
+
`(brace-list ,@(flatten:map λn(list n n) names)))
|
11
|
+
|
12
|
+
;; like 'map, but for a hash instead of a list ; provided function 'f takes three arguments,
|
13
|
+
;; a key, the corresponding value from the given hash, and the index of the item in the list
|
14
|
+
(def map-hash (f h pre)
|
15
|
+
(map-with-index λki(f k (hash-get h k) i)
|
16
|
+
((or pre x1) (hash-keys h))))
|
17
|
+
|
18
|
+
;; Return a new hash where keys are (map f things) and values are the corresponding things.
|
19
|
+
;; No attempt is made to avoid clobbering items. Use 'group-by if there are duplicate keys.
|
20
|
+
(def hashify (f things)
|
21
|
+
(returnlet hsh {}
|
22
|
+
(each thing things
|
23
|
+
(hash-set hsh (f thing) thing))))
|
@@ -29,7 +29,9 @@
|
|
29
29
|
{ setting { default ',initial context ',context name ',name } })
|
30
30
|
(set-setting ,(sym name) ,initial))))
|
31
31
|
|
32
|
-
; get the value of the given setting
|
32
|
+
; get the value of the given setting. Raises an error if the setting is unknown
|
33
33
|
(def setting (name)
|
34
|
-
(
|
35
|
-
|
34
|
+
(aif (hash-get settings (sym name))
|
35
|
+
(on-err (error "can't get value of setting ~name")
|
36
|
+
(it name))
|
37
|
+
(error "unknown setting ~(inspect name)")))
|
@@ -12,9 +12,14 @@
|
|
12
12
|
"hello world")
|
13
13
|
|
14
14
|
("recurses as necessary"
|
15
|
-
(explain-mac
|
16
|
-
(let it (a) (if it (b) (
|
15
|
+
(explain-mac 2 '(aif (a) (b) (c) (d) (e)))
|
16
|
+
(let it (a) (if it (b) (ifv it (c) (d) (e)))))
|
17
|
+
|
18
|
+
("assigns each successive condition to 'it"
|
19
|
+
(aif (eq? 1 2) nil
|
20
|
+
42 (list it it))
|
21
|
+
(42 42))
|
17
22
|
|
18
23
|
("avoids unnecessary expansion"
|
19
|
-
(explain-mac
|
24
|
+
(explain-mac 2 '(aif (a) (b) (c)))
|
20
25
|
(let it (a) (if it (b) (c)))))
|
@@ -0,0 +1,7 @@
|
|
1
|
+
(examples-for andify
|
2
|
+
("takes a list of functions A and returns a function that applies its arguments to each f in A in turn, returning the logical AND of the set of return values"
|
3
|
+
(with (even? λn(eq? (mod n 2) 0)
|
4
|
+
triple? λn(eq? (mod n 3) 0)
|
5
|
+
big? λn(> n 10))
|
6
|
+
(select (andify even? triple? big?) (range -10 31)))
|
7
|
+
(12 18 24 30)))
|
@@ -84,3 +84,12 @@
|
|
84
84
|
|
85
85
|
(examples-for mod
|
86
86
|
("modulus for two ints" (mod 64 6) 4))
|
87
|
+
|
88
|
+
(examples-for inspect
|
89
|
+
("truth" (inspect t) "t")
|
90
|
+
("nil" (inspect nil) "nil")
|
91
|
+
("number" (inspect 42) "42")
|
92
|
+
("string" (inspect "hello") "\"hello\"")
|
93
|
+
("list" (inspect '(fn (x) (this that))) "(fn (x) (this that))")
|
94
|
+
("list with string" (inspect '(fn (x) (this "string"))) "(fn (x) (this \"string\"))")
|
95
|
+
("list with sym" (inspect '(fn (x) (this 'quoted))) "(fn (x) (this (quote quoted)))"))
|
@@ -66,12 +66,12 @@
|
|
66
66
|
(do (without-hooks 'warnings/new
|
67
67
|
λ(on-err nil
|
68
68
|
(pre-compile '(fun (aif (and or) . when)
|
69
|
-
|
69
|
+
ignore))))
|
70
70
|
warnings/list)
|
71
|
-
((arg-shadows-macro "arg " when " shadows macro " when " in arg list " (aif (and or) . when))
|
72
|
-
(arg-shadows-macro "arg "
|
73
|
-
(arg-shadows-macro "arg "
|
74
|
-
(arg-shadows-macro "arg "
|
71
|
+
((arg-shadows-macro "arg " when " shadows macro " when " in arg list " (aif (and or) . when) " and body " (ignore) )
|
72
|
+
(arg-shadows-macro "arg " or " shadows macro " or " in arg list " (aif (and or) . when) " and body " (ignore) )
|
73
|
+
(arg-shadows-macro "arg " and " shadows macro " and " in arg list " (aif (and or) . when) " and body " (ignore) )
|
74
|
+
(arg-shadows-macro "arg " aif " shadows macro " aif " in arg list " (aif (and or) . when) " and body " (ignore) )))
|
75
75
|
|
76
76
|
("implicit in 'let and 'with"
|
77
77
|
(with ((a b) (list "h" "e")
|
@@ -10,6 +10,12 @@
|
|
10
10
|
(" t for a hash" (hash? {a 1 b 2}) t )
|
11
11
|
("nil for a symbol" (hash? 'foo) nil))
|
12
12
|
|
13
|
+
(examples-for hash-slice
|
14
|
+
("returns a new hash containing only the specified keys"
|
15
|
+
(let h (hash-slice { a 1 b 2 c 3 d 4 } '(a b e f))
|
16
|
+
(list (hash-keys h) (hash-values h)))
|
17
|
+
((a b) (1 2))))
|
18
|
+
|
13
19
|
(examples-for hash-merge
|
14
20
|
("merge with symbol keys"
|
15
21
|
(let h (hash-merge { a 1 b 2 c 3 } { a 99 c 98 d 97 })
|
@@ -29,7 +35,8 @@
|
|
29
35
|
|
30
36
|
("returns date operations"
|
31
37
|
(sort:hash-keys (date 2015 11 18))
|
32
|
-
(
|
38
|
+
(age
|
39
|
+
beginning_of_month
|
33
40
|
beginning_of_week
|
34
41
|
beginning_of_year
|
35
42
|
day
|
@@ -1,3 +1,17 @@
|
|
1
|
+
(examples-for list-single-element
|
2
|
+
("returns nothing from an empty list"
|
3
|
+
(list-single-element nil)
|
4
|
+
nil)
|
5
|
+
|
6
|
+
("returns first item from a list with one item"
|
7
|
+
(list-single-element '(x))
|
8
|
+
x)
|
9
|
+
|
10
|
+
("returns nothing from a list with more than one item"
|
11
|
+
(list-single-element '(x y z))
|
12
|
+
nil))
|
13
|
+
|
14
|
+
|
1
15
|
(examples-for iso
|
2
16
|
("(nil) is not the same as nil"
|
3
17
|
(iso '(nil) nil)
|
@@ -37,7 +51,11 @@
|
|
37
51
|
(g f (c d e) b a)))
|
38
52
|
|
39
53
|
(examples-for flatten
|
40
|
-
("
|
54
|
+
("removes empty lists and nil"
|
55
|
+
(flatten '(a b nil (c d () e nil) f ()))
|
56
|
+
(a b c d e f))
|
57
|
+
|
58
|
+
("returns a flat list of things"
|
41
59
|
(flatten '((poo (x) (* x x)) (1 2 3)))
|
42
60
|
(poo x * x x 1 2 3)))
|
43
61
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
(examples-for map-hash
|
2
|
+
("iterates over key-value pairs"
|
3
|
+
(map-hash (fn (k v i) "pos.~i : ~k is for ~v")
|
4
|
+
{ a 42 b 729 c 1024 })
|
5
|
+
("pos.0 : a is for 42" "pos.1 : b is for 729" "pos.2 : c is for 1024"))
|
6
|
+
|
7
|
+
("sorts keys before iterating"
|
8
|
+
(map-hash (fn (k v i) "pos.~i : ~k is for ~v")
|
9
|
+
{ "aa" 1 "bbb" 2 "c" 3 }
|
10
|
+
(fn (keys) (sort-by len keys)))
|
11
|
+
("pos.0 : c is for 3" "pos.1 : aa is for 1" "pos.2 : bbb is for 2" )))
|
@@ -9,9 +9,14 @@
|
|
9
9
|
("parses an empty symbol" (parse "||") (||) )
|
10
10
|
("parses a colon-syntax symbol" (parse "this:that") ((colon-syntax this that)) )
|
11
11
|
("parses a percent-syntax symbol" (parse "this%that") ((percent-syntax this that)) )
|
12
|
+
("parses combined percent-colon" (parse "%this:%that") ((colon-syntax (percent-syntax || this) (percent-syntax || that))) )
|
12
13
|
("parses a prefix dollar" (parse "$this") ((dollar-syntax || this)))
|
13
14
|
("parses a prefix dollar-dot" (parse "$.this") ((dot-syntax (dollar-syntax || ||) this)))
|
14
15
|
|
16
|
+
("parses combined percent-colon-dot"
|
17
|
+
(parse "%this.foo:%that.bar")
|
18
|
+
((colon-syntax (percent-syntax || (dot-syntax this foo)) (percent-syntax || (dot-syntax that bar)))) )
|
19
|
+
|
15
20
|
("parse custom prefix-lists with a special-syntax prefix"
|
16
21
|
(parse "x.y(1 2 3)")
|
17
22
|
((prefix-list "x.y" (1 2 3))))
|
@@ -206,13 +206,12 @@ toto")
|
|
206
206
|
(pp '(def yoohoo (it) (wrangle "foobar" it)))
|
207
207
|
"(def yoohoo (it) (wrangle \"foobar\" it))")
|
208
208
|
|
209
|
-
("a
|
210
|
-
(pp '(
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
acc))
|
209
|
+
("something with a nil and t literal"
|
210
|
+
(pp '(def yoohoo (it) (wrangle nil t it)))
|
211
|
+
"(def yoohoo (it) (wrangle nil t it))")
|
212
|
+
|
213
|
+
("a 'let form squished into one line"
|
214
|
+
(pp '(let acc nil (rfnwith flattenize (x things) (if (pair? x) (eachr flattenize x) (push x acc))) acc))
|
216
215
|
"(let acc nil
|
217
216
|
(rfnwith flattenize (x things)
|
218
217
|
(if (pair? x)
|
@@ -221,13 +220,11 @@ toto")
|
|
221
220
|
acc)")
|
222
221
|
|
223
222
|
|
224
|
-
("a real-life example from utils"
|
223
|
+
("a real-life example from utils with improper 'if formatting"
|
225
224
|
(pp '(def flatten (things)
|
226
225
|
(let acc nil
|
227
226
|
(rfnwith flattenize (x things)
|
228
|
-
(if (pair? x)
|
229
|
-
(eachr flattenize x)
|
230
|
-
(push x acc)))
|
227
|
+
(if (pair? x) (eachr flattenize x) (push x acc)))
|
231
228
|
acc)))
|
232
229
|
"(def flatten (things)
|
233
230
|
(let acc nil
|
data/lib/nydp/builtin/hash.rb
CHANGED
@@ -56,3 +56,16 @@ class Nydp::Builtin::HashMerge
|
|
56
56
|
vm.push_arg hash_0.merge hash_1
|
57
57
|
end
|
58
58
|
end
|
59
|
+
|
60
|
+
class Nydp::Builtin::HashSlice
|
61
|
+
include Nydp::Helper, Nydp::Builtin::Base, Singleton
|
62
|
+
|
63
|
+
def builtin_invoke vm, args
|
64
|
+
old = args.car
|
65
|
+
h = old.class.new
|
66
|
+
slice = args.cdr.car
|
67
|
+
slice = slice.map { |k| n2r k } unless old.is_a? Nydp::Hash
|
68
|
+
slice.each { |k| h[k] = old[k] if old.key?(k) }
|
69
|
+
vm.push_arg h
|
70
|
+
end
|
71
|
+
end
|
data/lib/nydp/core.rb
CHANGED
@@ -71,6 +71,7 @@ module Nydp
|
|
71
71
|
Symbol.mk(:"hash-keys", ns).assign(Nydp::Builtin::HashKeys.instance)
|
72
72
|
Symbol.mk(:"hash-key?", ns).assign(Nydp::Builtin::HashKeyPresent.instance)
|
73
73
|
Symbol.mk(:"hash-merge", ns).assign(Nydp::Builtin::HashMerge.instance)
|
74
|
+
Symbol.mk(:"hash-slice", ns).assign(Nydp::Builtin::HashSlice.instance)
|
74
75
|
Symbol.mk(:"vm-info", ns).assign Nydp::Builtin::VmInfo.instance
|
75
76
|
Symbol.mk(:"pre-compile" , ns).assign Nydp::Builtin::PreCompile.instance
|
76
77
|
Symbol.mk(:"script-run" , ns).assign Nydp::Builtin::ScriptRun.instance
|
data/lib/nydp/date.rb
CHANGED
@@ -38,7 +38,7 @@ module Nydp
|
|
38
38
|
last_year next_year beginning_of_year end_of_year
|
39
39
|
last_month next_month beginning_of_month end_of_month
|
40
40
|
last_week next_week beginning_of_week end_of_week
|
41
|
-
yesterday tomorrow
|
41
|
+
yesterday tomorrow age
|
42
42
|
} + @@pass_through
|
43
43
|
|
44
44
|
def year y, m, d, w ; y ; end
|
@@ -64,6 +64,13 @@ module Nydp
|
|
64
64
|
def yesterday y, m, d, w ; ruby_date - 1 ; end
|
65
65
|
def tomorrow y, m, d, w ; ruby_date + 1 ; end
|
66
66
|
|
67
|
+
def age y,m,d,w # args not used
|
68
|
+
interval = (::Date.today - ruby_date) / 365.0
|
69
|
+
age_in_years = interval.to_i
|
70
|
+
extra_months = (12 * (interval - age_in_years)).to_i
|
71
|
+
{ years: age_in_years, months: extra_months }
|
72
|
+
end
|
73
|
+
|
67
74
|
@@pass_through.each do |n|
|
68
75
|
class_eval "def #{n} * ; ruby_date.#{n} ; end"
|
69
76
|
end
|
@@ -24,7 +24,7 @@ module Nydp
|
|
24
24
|
raise
|
25
25
|
else
|
26
26
|
if e.is_a?(NoMethodError) && !f.respond_to?(invoker)
|
27
|
-
raise InvocationFailed.new("#{f.inspect} is not a function: args were #{args.inspect}")
|
27
|
+
raise InvocationFailed.new("#{f.inspect} is not a function: args were #{args.inspect} in #{source.inspect}")
|
28
28
|
else
|
29
29
|
msg = args.map { |a| " #{a.inspect}"}.join("\n")
|
30
30
|
msg = "failed to execute invocation #{f.inspect}\n#{msg}"
|
data/lib/nydp/pair.rb
CHANGED
@@ -24,6 +24,7 @@ class Nydp::Pair
|
|
24
24
|
def inspect ; "(#{inspect_rest})" ; end
|
25
25
|
def & other ; self.class.from_list((Set.new(self) & other).to_a) ; end
|
26
26
|
def | other ; self.class.from_list((Set.new(self) | other).to_a) ; end
|
27
|
+
def - other ; self.class.from_list((Set.new(self) - other).to_a) ; end
|
27
28
|
def proper? ; Nydp::NIL.is?(cdr) || (cdr.is_a?(Nydp::Pair) && cdr.proper?) ; end
|
28
29
|
|
29
30
|
# returns Array of elements after calling #n2r on each element
|
data/lib/nydp/parser.rb
CHANGED
@@ -45,11 +45,11 @@ module Nydp
|
|
45
45
|
|
46
46
|
SYMBOL_OPERATORS =
|
47
47
|
[
|
48
|
-
[ /%/, "percent-syntax" ],
|
49
48
|
[ /\!/, "bang-syntax" ],
|
50
49
|
[ /::/, "colon-colon-syntax"],
|
51
50
|
[ /:/, "colon-syntax" ],
|
52
51
|
[ /&/, "ampersand-syntax" ],
|
52
|
+
[ /%/, "percent-syntax" ],
|
53
53
|
[ /\./, "dot-syntax" ],
|
54
54
|
[ /\$/, "dollar-syntax" ],
|
55
55
|
[ /->/, "arrow-syntax" ],
|
@@ -129,11 +129,11 @@ module Nydp
|
|
129
129
|
fragments = [sym(:"string-pieces")]
|
130
130
|
string_token = token_stream.next_string_fragment(open_delimiter, close_delimiter, INTERPOLATION_SIGN, INTERPOLATION_ESCAPES)
|
131
131
|
raise "unterminated string" if string_token.nil?
|
132
|
-
fragments << Nydp::StringAtom.new(string_token.string
|
132
|
+
fragments << Nydp::StringAtom.new(string_token.string)
|
133
133
|
while !(string_token.is_a? StringFragmentCloseToken)
|
134
134
|
fragments << expression(token_stream)
|
135
135
|
string_token = token_stream.next_string_fragment('', close_delimiter, INTERPOLATION_SIGN, INTERPOLATION_ESCAPES)
|
136
|
-
fragments << Nydp::StringAtom.new(string_token.string
|
136
|
+
fragments << Nydp::StringAtom.new(string_token.string)
|
137
137
|
end
|
138
138
|
|
139
139
|
if fragments.size == 2
|
data/lib/nydp/string_atom.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
module Nydp
|
2
2
|
class StringAtom
|
3
|
-
attr_accessor :string
|
4
|
-
|
5
|
-
|
6
|
-
end
|
3
|
+
attr_accessor :string
|
4
|
+
|
5
|
+
def initialize string ; @string = string ; end
|
7
6
|
|
8
7
|
def nydp_type ; :string ; end
|
9
8
|
def to_s ; string ; end
|
data/lib/nydp/tokeniser.rb
CHANGED
@@ -3,7 +3,7 @@ require "strscan"
|
|
3
3
|
module Nydp
|
4
4
|
class Tokeniser
|
5
5
|
BACKSLASH = /\\/.freeze
|
6
|
-
COMMENT =
|
6
|
+
COMMENT = /;;?.*$/.freeze
|
7
7
|
QUOTE = /"/.freeze
|
8
8
|
PIPE = /\|/.freeze
|
9
9
|
LIST_PFX = /[^\s()]*\(/.freeze
|
@@ -89,7 +89,7 @@ module Nydp
|
|
89
89
|
@finished = true
|
90
90
|
return nil
|
91
91
|
elsif comment = s.scan(COMMENT)
|
92
|
-
tok = [:comment, comment
|
92
|
+
tok = [:comment, comment.gsub(/^;;?\s*/, '').strip]
|
93
93
|
elsif open_str = s.scan(QUOTE)
|
94
94
|
tok = [:string_open_delim, open_str]
|
95
95
|
elsif open_sym = s.scan(PIPE)
|
data/lib/nydp/truth.rb
CHANGED
@@ -3,14 +3,14 @@ require 'singleton'
|
|
3
3
|
module Nydp
|
4
4
|
class Truth
|
5
5
|
include Singleton
|
6
|
-
def init_with *; Nydp::T
|
7
|
-
def to_s ; 't'
|
8
|
-
def inspect ; 't
|
9
|
-
def assign *_ ; self
|
10
|
-
def nydp_type ; :truth
|
11
|
-
def to_ruby ; true
|
12
|
-
def _nydp_get a ; Nydp::T
|
13
|
-
def _nydp_set a, v ; Nydp::T
|
6
|
+
def init_with *; Nydp::T ; end
|
7
|
+
def to_s ; 't' ; end
|
8
|
+
def inspect ; 't' ; end
|
9
|
+
def assign *_ ; self ; end
|
10
|
+
def nydp_type ; :truth ; end
|
11
|
+
def to_ruby ; true ; end
|
12
|
+
def _nydp_get a ; Nydp::T ; end
|
13
|
+
def _nydp_set a, v ; Nydp::T ; end
|
14
14
|
end
|
15
15
|
|
16
16
|
class Nil
|
data/lib/nydp/version.rb
CHANGED
data/spec/date_spec.rb
CHANGED
@@ -147,4 +147,18 @@ describe Nydp::Date do
|
|
147
147
|
expect(nd._nydp_get(:"beginning-of-week").to_s). to eq "2015-03-09"
|
148
148
|
expect(nd._nydp_get(:"end-of-week").to_s). to eq "2015-03-15"
|
149
149
|
end
|
150
|
+
|
151
|
+
it "returns age relative to today" do
|
152
|
+
rd = Date.parse "2014-03-12"
|
153
|
+
nd = Nydp.r2n rd
|
154
|
+
allow(::Date).to receive_messages(today: Date.parse("2016-06-21"))
|
155
|
+
expect(nd._nydp_get(:age)).to eq({ years: 2, months: 3 })
|
156
|
+
end
|
157
|
+
|
158
|
+
it "returns a negative age relative to today for a date in the future" do
|
159
|
+
rd = Date.parse "2094-11-18"
|
160
|
+
nd = Nydp.r2n rd
|
161
|
+
allow(::Date).to receive_messages(today: Date.parse("2016-06-21"))
|
162
|
+
expect(nd._nydp_get(:age)).to eq({ years: -78, months: -5 })
|
163
|
+
end
|
150
164
|
end
|
data/spec/embedded_spec.rb
CHANGED
@@ -46,10 +46,10 @@ describe Nydp::Parser do
|
|
46
46
|
it "should parse a string with embedded code, delimited by eof" do
|
47
47
|
x1 = sym('string-pieces')
|
48
48
|
x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','a fluffy bunny! ~')
|
49
|
-
x2 = Nydp::StringAtom.new(x2.string
|
49
|
+
x2 = Nydp::StringAtom.new(x2.string)
|
50
50
|
x3 = sym('expr')
|
51
51
|
x4 = Nydp::StringFragmentCloseToken.new(' a purple cow!',' a purple cow!')
|
52
|
-
x4 = Nydp::StringAtom.new(x4.string
|
52
|
+
x4 = Nydp::StringAtom.new(x4.string)
|
53
53
|
|
54
54
|
expected = pair_list([x1,x2,x3,x4])
|
55
55
|
actual = parse_string "a fluffy bunny! ~expr a purple cow!"
|
@@ -64,10 +64,10 @@ describe Nydp::Parser do
|
|
64
64
|
|
65
65
|
x1 = sym('string-pieces')
|
66
66
|
x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','a fluffy bunny! ~')
|
67
|
-
x2 = Nydp::StringAtom.new(x2.string
|
67
|
+
x2 = Nydp::StringAtom.new(x2.string)
|
68
68
|
x3 = pair_list [n1, n2, n3, n4]
|
69
69
|
x4 = Nydp::StringFragmentCloseToken.new(' a purple cow!',' a purple cow!')
|
70
|
-
x4 = Nydp::StringAtom.new(x4.string
|
70
|
+
x4 = Nydp::StringAtom.new(x4.string)
|
71
71
|
|
72
72
|
expected = pair_list([x1,x2,x3,x4])
|
73
73
|
actual = parse_string 'a fluffy bunny! ~(foo bar "an embedded bunny :)" zop) a purple cow!'
|
@@ -80,10 +80,10 @@ describe Nydp::Parser do
|
|
80
80
|
|
81
81
|
s1 = sym('string-pieces')
|
82
82
|
s2 = Nydp::StringFragmentToken.new('a rather ','a rather ~')
|
83
|
-
s2 = Nydp::StringAtom.new(s2.string
|
83
|
+
s2 = Nydp::StringAtom.new(s2.string)
|
84
84
|
s3 = pair_list [e1, e2]
|
85
85
|
s4 = Nydp::StringFragmentCloseToken.new(' bunny :)',' bunny :)"')
|
86
|
-
s4 = Nydp::StringAtom.new(s4.string
|
86
|
+
s4 = Nydp::StringAtom.new(s4.string)
|
87
87
|
|
88
88
|
n1 = sym(:foo)
|
89
89
|
n2 = sym(:bar)
|
@@ -92,10 +92,10 @@ describe Nydp::Parser do
|
|
92
92
|
|
93
93
|
x1 = sym('string-pieces')
|
94
94
|
x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','a fluffy bunny! ~')
|
95
|
-
x2 = Nydp::StringAtom.new(x2.string
|
95
|
+
x2 = Nydp::StringAtom.new(x2.string)
|
96
96
|
x3 = pair_list [n1, n2, n3, n4]
|
97
97
|
x4 = Nydp::StringFragmentCloseToken.new(' a purple cow!',' a purple cow!')
|
98
|
-
x4 = Nydp::StringAtom.new(x4.string
|
98
|
+
x4 = Nydp::StringAtom.new(x4.string)
|
99
99
|
|
100
100
|
expected = pair_list([x1,x2,x3,x4])
|
101
101
|
actual = parse_string "a fluffy bunny! ~(foo bar \"a rather ~(describe bunny) bunny :)\" zop) a purple cow!"
|
data/spec/foreign_hash_spec.rb
CHANGED
@@ -84,5 +84,17 @@ describe Nydp::Hash do
|
|
84
84
|
expect(vm.args.pop).to eq pair_list [sym("k0"), sym("k1")]
|
85
85
|
end
|
86
86
|
end
|
87
|
+
|
88
|
+
describe "hash-slice" do
|
89
|
+
it "returns a new hash containing only the given keys from the old hash" do
|
90
|
+
ahash[:k0] = 42
|
91
|
+
ahash[:k1] = 84
|
92
|
+
args = [ahash, pair_list([sym("k0"), sym("k1")])]
|
93
|
+
|
94
|
+
Nydp::Builtin::HashSlice.instance.invoke vm, pair_list(args)
|
95
|
+
|
96
|
+
expect(vm.args.pop).to eq({ k0: 42, k1: 84 })
|
97
|
+
end
|
98
|
+
end
|
87
99
|
end
|
88
100
|
end
|
data/spec/hash_spec.rb
CHANGED
@@ -143,4 +143,26 @@ describe Nydp::Hash do
|
|
143
143
|
end
|
144
144
|
end
|
145
145
|
end
|
146
|
+
|
147
|
+
describe "hash-slice" do
|
148
|
+
it "returns a new hash containing only the given keys from the old hash" do
|
149
|
+
hash = Nydp::Hash.new
|
150
|
+
sfoo = sym "foo"
|
151
|
+
sbar = sym "bar"
|
152
|
+
syak = sym "yak"
|
153
|
+
szeb = sym "zeb"
|
154
|
+
|
155
|
+
h = Nydp::Hash.new
|
156
|
+
|
157
|
+
h[sfoo] = 16
|
158
|
+
h[sbar] = 42
|
159
|
+
h[szeb] = 99
|
160
|
+
|
161
|
+
args = [h, pair_list([sbar, syak, szeb])]
|
162
|
+
|
163
|
+
Nydp::Builtin::HashSlice.instance.invoke vm, pair_list(args)
|
164
|
+
|
165
|
+
expect(vm.args.pop).to eq({ sbar => 42, szeb => 99 })
|
166
|
+
end
|
167
|
+
end
|
146
168
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nydp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Conan Dalton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-10-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -113,6 +113,7 @@ files:
|
|
113
113
|
- lib/lisp/tests/aif-examples.nydp
|
114
114
|
- lib/lisp/tests/all-examples.nydp
|
115
115
|
- lib/lisp/tests/ampersand-syntax-examples.nydp
|
116
|
+
- lib/lisp/tests/andify-examples.nydp
|
116
117
|
- lib/lisp/tests/any-examples.nydp
|
117
118
|
- lib/lisp/tests/auto-hash-examples.nydp
|
118
119
|
- lib/lisp/tests/best-examples.nydp
|
@@ -150,6 +151,7 @@ files:
|
|
150
151
|
- lib/lisp/tests/list-gsub-examples.nydp
|
151
152
|
- lib/lisp/tests/list-match-examples.nydp
|
152
153
|
- lib/lisp/tests/list-tests.nydp
|
154
|
+
- lib/lisp/tests/map-hash-examples.nydp
|
153
155
|
- lib/lisp/tests/mapreduce-examples.nydp
|
154
156
|
- lib/lisp/tests/mapsum-examples.nydp
|
155
157
|
- lib/lisp/tests/none-examples.nydp
|
@@ -166,6 +168,7 @@ files:
|
|
166
168
|
- lib/lisp/tests/returning-examples.nydp
|
167
169
|
- lib/lisp/tests/rfnwith-tests.nydp
|
168
170
|
- lib/lisp/tests/seqf-examples.nydp
|
171
|
+
- lib/lisp/tests/set-difference-examples.nydp
|
169
172
|
- lib/lisp/tests/set-intersection-examples.nydp
|
170
173
|
- lib/lisp/tests/set-union-examples.nydp
|
171
174
|
- lib/lisp/tests/settings-examples.nydp
|