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 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