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