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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 93571312813f5383bd47d92b298cd95b0239f07e
4
- data.tar.gz: 242349e0186b701a602e94cbfdba9a1adfb5d5bb
3
+ metadata.gz: 1a6a8e0215b81d92423402f9933413c58ebcdad9
4
+ data.tar.gz: eeb8d8bb621ed6349d2e9d4e7823c3be5e875d04
5
5
  SHA512:
6
- metadata.gz: 47e4c03909bcc94e0440d35f6a8e4f3cf36241832a89042456d18d556c6f8a34953d10382e2b5c17df6d28a7c530f9347c505cb6cf66931b9dcf18b34c2df88d
7
- data.tar.gz: c899014050d46f2a093dec88a62f6a44ff70fffdd6bc66392338c33699f49c92e4ef0239d49e337685190757b318409d614a9319463dedd0bba1883526e78dc6
6
+ metadata.gz: 1f32b55812f569e1329b657eed211054be4e275fcd778671ec7e251fe2b98fc7390531a9742ca819c9eb076aeb9bb34ffd2390c0fd5ebe43ddfc35d75e0eae95
7
+ data.tar.gz: 2f5cad91e0551afb32c410751c56b11e1b55158218a8bdab8eb5db3d2b38719d3cfb63cc04ca961b7e1436075dbaf10ad3d5d82bf75a61f1fc1d91fd25c03a3f
@@ -1,17 +1,12 @@
1
- (assign mac-expand (fn (names macfn expr)
2
- (cond macfn
3
- (pre-compile-with names
4
- (apply macfn (cdr expr)))
5
- expr)))
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
- (pre-compile-expr names arg)))
31
+ (mac-expand names
32
+ (hash-get names
33
+ (car arg))
34
+ arg)))
37
35
  arg)))
38
36
 
39
37
  (assign pre-compile-debug
@@ -8,7 +8,7 @@
8
8
  (car args))
9
9
  nil)))
10
10
 
11
- (def map-helper-0 (f things lc _)
11
+ (def map-helper-0 (f things lc)
12
12
  (if (pair? things)
13
13
  (map-helper-0 f (cdr things) (cdr-set lc (cons (f (car things)))))
14
14
  things
@@ -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
- (dox-add-to-chapters item (cdr chapters)))
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 aif (expr . body)
287
- ; like if, except the value of each condition is locally bound to the variable 'it
288
- ; eg (aif (find thing) (show it))
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) (aif ,@(cdr 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
@@ -29,6 +29,7 @@
29
29
  (rfnwith flattenize (x things)
30
30
  (if (pair? x)
31
31
  (eachr flattenize x)
32
+ x
32
33
  (push (f x) acc)))
33
34
  acc))
34
35
 
@@ -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
- (def compact (things)
52
- ; return a new list containing only non-nil items from the given list
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)))
@@ -35,7 +35,15 @@
35
35
  (each hook (hooks-for hook-name)
36
36
  (apply hook args))))
37
37
 
38
- (add-hook 'warnings/new λw(apply p w))
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) (map (fn (k) h.,k) (hash-keys 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 `(brace-list ,@(flatten:map λn(list n n) 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
- (on-err (error "can't get value of setting ~name")
35
- ((hash-get settings (sym name)) name)))
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 1 '(aif (a) (b) (c) (d) (e)))
16
- (let it (a) (if it (b) (aif (c) (d) (e)))))
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 1 '(aif (a) (b) (c)))
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
- "ignore"))))
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 " or " shadows macro " or " in arg list " (aif (and or) . when))
73
- (arg-shadows-macro "arg " and " shadows macro " and " in arg list " (aif (and or) . when))
74
- (arg-shadows-macro "arg " aif " shadows macro " aif " in arg list " (aif (and or) . when))))
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
- (beginning_of_month
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
- ("'flatten returns a flat list of things"
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 'let form"
210
- (pp '(let acc nil
211
- (rfnwith flattenize (x things)
212
- (if (pair? x)
213
- (eachr flattenize x)
214
- (push x acc)))
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
@@ -0,0 +1,8 @@
1
+ (examples-for -
2
+ ("returns elements of first that are not in second"
3
+ (- '(a b c e) '(a b d))
4
+ (c e))
5
+
6
+ ("returns all of first if second is nil"
7
+ (- '(a b c) nil)
8
+ (a b c)))
@@ -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
@@ -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
@@ -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}"
@@ -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
@@ -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, string_token)
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, string_token)
136
+ fragments << Nydp::StringAtom.new(string_token.string)
137
137
  end
138
138
 
139
139
  if fragments.size == 2
@@ -1,9 +1,8 @@
1
1
  module Nydp
2
2
  class StringAtom
3
- attr_accessor :string, :token
4
- def initialize string, token=nil
5
- @string, @token = string, token
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
@@ -3,7 +3,7 @@ require "strscan"
3
3
  module Nydp
4
4
  class Tokeniser
5
5
  BACKSLASH = /\\/.freeze
6
- COMMENT = /;.*$/.freeze
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[1..-1].strip]
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)
@@ -3,14 +3,14 @@ require 'singleton'
3
3
  module Nydp
4
4
  class Truth
5
5
  include Singleton
6
- def init_with *; Nydp::T ; end
7
- def to_s ; 't' ; end
8
- def inspect ; 't[nydp::Truth]' ; 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
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
@@ -1,3 +1,3 @@
1
1
  module Nydp
2
- VERSION = "0.4.2"
2
+ VERSION = "0.4.3"
3
3
  end
@@ -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
@@ -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, x2)
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, x4)
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, x2)
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, x4)
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, s2)
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, s4)
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, x2)
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, x4)
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!"
@@ -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
@@ -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.2
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-05-12 00:00:00.000000000 Z
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