nydp 0.2.3 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/bin/nydp +1 -1
  3. data/lib/lisp/core-000.nydp +1 -0
  4. data/lib/lisp/core-010-precompile.nydp +15 -15
  5. data/lib/lisp/core-012-utils.nydp +6 -5
  6. data/lib/lisp/core-020-utils.nydp +20 -6
  7. data/lib/lisp/core-030-syntax.nydp +14 -16
  8. data/lib/lisp/core-035-flow-control.nydp +26 -8
  9. data/lib/lisp/core-040-utils.nydp +4 -15
  10. data/lib/lisp/core-041-string-utils.nydp +3 -3
  11. data/lib/lisp/core-043-list-utils.nydp +81 -16
  12. data/lib/lisp/core-045-dox-utils.nydp +2 -2
  13. data/lib/lisp/core-060-benchmarking.nydp +92 -27
  14. data/lib/lisp/tests/all-examples.nydp +20 -0
  15. data/lib/lisp/tests/any-examples.nydp +28 -0
  16. data/lib/lisp/tests/builtin-tests.nydp +3 -1
  17. data/lib/lisp/tests/collect-tests.nydp +10 -0
  18. data/lib/lisp/tests/curry-tests.nydp +7 -2
  19. data/lib/lisp/tests/error-tests.nydp +11 -0
  20. data/lib/lisp/tests/foundation-test.nydp +66 -0
  21. data/lib/lisp/tests/len-examples.nydp +1 -0
  22. data/lib/lisp/tests/list-gsub-examples.nydp +25 -0
  23. data/lib/lisp/tests/list-match-examples.nydp +40 -0
  24. data/lib/lisp/tests/list-tests.nydp +13 -0
  25. data/lib/lisp/tests/none-examples.nydp +16 -0
  26. data/lib/lisp/tests/parser-tests.nydp +4 -5
  27. data/lib/lisp/tests/quasiquote-examples.nydp +2 -0
  28. data/lib/lisp/tests/syntax-tests.nydp +3 -2
  29. data/lib/lisp/tests/tuples-examples.nydp +2 -2
  30. data/lib/nydp.rb +50 -18
  31. data/lib/nydp/assignment.rb +3 -1
  32. data/lib/nydp/builtin.rb +15 -13
  33. data/lib/nydp/builtin/error.rb +1 -1
  34. data/lib/nydp/builtin/handle_error.rb +8 -2
  35. data/lib/nydp/builtin/parse_in_string.rb +1 -1
  36. data/lib/nydp/builtin/plus.rb +4 -4
  37. data/lib/nydp/closure.rb +5 -1
  38. data/lib/nydp/compiler.rb +2 -3
  39. data/lib/nydp/cond.rb +134 -13
  40. data/lib/nydp/context_symbol.rb +4 -1
  41. data/lib/nydp/error.rb +8 -0
  42. data/lib/nydp/function_invocation.rb +46 -48
  43. data/lib/nydp/helper.rb +15 -0
  44. data/lib/nydp/interpreted_function.rb +10 -14
  45. data/lib/nydp/lexical_context.rb +13 -2
  46. data/lib/nydp/lexical_context_builder.rb +28 -13
  47. data/lib/nydp/pair.rb +35 -36
  48. data/lib/nydp/parser.rb +3 -0
  49. data/lib/nydp/runner.rb +4 -32
  50. data/lib/nydp/string_atom.rb +3 -2
  51. data/lib/nydp/symbol.rb +1 -1
  52. data/lib/nydp/symbol_lookup.rb +9 -1
  53. data/lib/nydp/truth.rb +1 -1
  54. data/lib/nydp/version.rb +1 -1
  55. data/lib/nydp/vm.rb +2 -2
  56. data/nydp.gemspec +1 -1
  57. data/spec/error_spec.rb +14 -4
  58. data/spec/hash_non_hash_behaviour_spec.rb +19 -12
  59. data/spec/hash_spec.rb +0 -13
  60. data/spec/pair_spec.rb +17 -3
  61. data/spec/spec_helper.rb +13 -1
  62. data/spec/symbol_spec.rb +1 -1
  63. metadata +9 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 546120f25e3fa424942cb1d4f6296da7007fa3a1
4
- data.tar.gz: afc6a8ac316812422abd8b4d8aa0e7c870ab73fd
3
+ metadata.gz: dc628274c2cf2f44cd05559766575d3cc9920d69
4
+ data.tar.gz: 619d6083cf6dab728793950bbc005fe3b281be56
5
5
  SHA512:
6
- metadata.gz: a8d144329085f686df6e0b3b12be6fb207e08fe0edca7633088d3a59095cdf1c0953636b8faf352037bdd22fc13dbc822604a76b6f6709b1e3d74787362ad34c
7
- data.tar.gz: 6c0875dfd8712fc2fb22dd987cc4cf323d7e4c39b6444e4da0b6e8790706e3f7714f0e1fdac563edad9ce1104cb1e38600becb3fdcadd668b498d0c2b5c9384c
6
+ metadata.gz: 391b384008f3e7e23505cb0871ab667435aea31a0841f71f3572316bdf1fc731a142f6dff7f0e2be26cf2eb60750bd60cf8ae89f298f9670f387b24fa2fd6141
7
+ data.tar.gz: 4390de26c600a52fbcf82bd91045acd3ed8791aeddcbec340cd227982632a28cdf2cbb1db42f2608f48b04010d3526870d5bfbfcc8161bf6601edd290394b5e5
data/bin/nydp CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  require 'nydp'
4
4
 
5
- Nydp.repl verbose: ($*.include? "-v")
5
+ Nydp.repl verbose: ($*.include? "-v"), exit: ($*.include? "-x"), silent: ($*.include? "-s")
@@ -6,6 +6,7 @@
6
6
  ;; README.md however for some significant differences
7
7
 
8
8
  (assign list (fn args args))
9
+ (assign noop (fn args nil))
9
10
  (assign caar (fn (arg) (car (car arg))))
10
11
  (assign cadr (fn (arg) (car (cdr arg))))
11
12
  (assign cdar (fn (arg) (cdr (car arg))))
@@ -70,11 +70,11 @@
70
70
  (qq-skip-unquote-splicing arg rest level)))
71
71
 
72
72
  (def qq-do-unquote-splicing (arg rest level)
73
- (cond (no rest)
74
- arg
73
+ (cond rest
75
74
  (list '+
76
75
  (pre-compile arg)
77
- (qq-quasiquote rest level))))
76
+ (qq-quasiquote rest level))
77
+ arg))
78
78
 
79
79
  (def qq-skip-unquote-splicing (arg rest level)
80
80
  (list 'cons
@@ -117,18 +117,18 @@
117
117
  (pre-compile xs)
118
118
  (list 'list ''unquote (qq-quasiquote xs (- level 1)))))
119
119
 
120
- (def qq-quasiquote (xs level)
121
- (cond (no xs)
122
- nil
123
- (cond (pair? xs)
124
- (cond (eq? (car xs) 'unquote)
125
- (qq-maybe-unquote (cadr xs) level)
126
- (cond (eq? (car xs) 'unquote-splicing)
127
- (qq-handle-unquote-splicing (cadr xs) nil level)
128
- (cond (eq? (car xs) 'quasiquote)
129
- (list 'list ''quasiquote (qq-quasiquote (cdr xs) (+ level 1)))
130
- (qq-unquote? (car xs) (cdr xs) level))))
131
- (list 'quote xs))))
120
+ (def qq-quasiquote (things level)
121
+ (cond things
122
+ (cond (pair? things)
123
+ (cond (eq? (car things) 'unquote)
124
+ (qq-maybe-unquote (cadr things) level)
125
+ (cond (eq? (car things) 'unquote-splicing)
126
+ (qq-handle-unquote-splicing (cadr things) nil level)
127
+ (cond (eq? (car things) 'quasiquote)
128
+ (list 'list ''quasiquote (qq-quasiquote (cdr things) (+ level 1)))
129
+ (qq-unquote? (car things) (cdr things) level))))
130
+ (list 'quote things))
131
+ nil))
132
132
 
133
133
  (hash-set macs 'quasiquote
134
134
  (fn (arg) (qq-quasiquote arg 0)))
@@ -1,11 +1,12 @@
1
1
 
2
2
  (hash-set macs 'if (fn args
3
- (cond (no args) nil
3
+ (cond args
4
4
  (cond (cdr args)
5
5
  (cond (cddr args)
6
6
  `(cond ,(car args) ,(cadr args) (if ,@(cddr args)))
7
7
  `(cond ,(car args) ,(cadr args)))
8
- (car args)))))
8
+ (car args))
9
+ nil)))
9
10
 
10
11
  (def map (f things)
11
12
  ; transforms the list 'things by applying 'f to each item
@@ -20,10 +21,10 @@
20
21
  (hash-set h k (cons v (hash-get h k))))
21
22
 
22
23
  (def rev-accum (things acc)
23
- (cond (no things)
24
- acc
24
+ (cond things
25
25
  (rev-accum (cdr things)
26
26
  (cons (car things)
27
- acc))))
27
+ acc))
28
+ acc))
28
29
 
29
30
  (def rev (things) (rev-accum things nil))
@@ -9,12 +9,13 @@
9
9
  "with arguments a b c d e, return b if a is true, otherwise return d if c is true, otherwise e"
10
10
  "and so on for subsequent arguments")
11
11
  'args
12
- '(cond (no args) nil
12
+ '(cond args
13
13
  (cond (cdr args)
14
14
  (cond (cddr args)
15
15
  `(cond ,(car args) ,(cadr args) (if ,@(cddr args)))
16
16
  `(cond ,(car args) ,(cadr args)))
17
- (car args)))
17
+ (car args))
18
+ nil)
18
19
  '(flow-control))
19
20
 
20
21
  (dox-add-doc 'map
@@ -22,11 +23,10 @@
22
23
  '("transforms the list 'things by applying 'f to each item"
23
24
  "returns the resulting list")
24
25
  '(f things)
25
- '(if (no things)
26
- nil
27
- (pair? things)
26
+ '(if (pair? things)
28
27
  (cons (f (car things)) (map f (cdr things)))
29
- (map f (list things)))
28
+ things
29
+ (f things))
30
30
  '(list-manipulation))
31
31
 
32
32
  (dox-add-doc 'rev
@@ -42,3 +42,17 @@
42
42
  '(h k v)
43
43
  '(hash-set h k (cons v (hash-get h k)))
44
44
  '(hash-manipulation))
45
+
46
+ (def join-str (prefix joint things)
47
+ (chapter string-manipulation)
48
+ ; equivalent to (join-str "~prefix~joint~(car things)" joint (cdr things)) - except
49
+ ; 'string-pieces hasn't been defined yet, and if it were, it would be defined in terms of
50
+ ; 'join-str, so it would be circular.
51
+ ; see 'joinstr for a more powerful and easier-to-use implementation of the same idea
52
+ (if things
53
+ (join-str (+ (to-string prefix)
54
+ joint
55
+ (to-string (car things)))
56
+ joint
57
+ (cdr things))
58
+ prefix))
@@ -47,7 +47,7 @@ scoping, assignment, anonymous functions and more...")
47
47
  (fn (,var) ,@body)))
48
48
 
49
49
  (def-colon-syntax || names
50
- (error "Irregular ': syntax: got ~(inspect names) : not prefix-syntax : in ~(joinstr ":" names)"))
50
+ (error "Irregular ': syntax: got ~(inspect names) : not prefix-syntax : in ~(join-str (car names) ":" (cdr names))"))
51
51
 
52
52
  (mac colon-syntax names
53
53
  ; handle syntax of the form a:b, which the parser expands to
@@ -68,9 +68,9 @@ scoping, assignment, anonymous functions and more...")
68
68
  ; For example,
69
69
  ; (!eq? a 10) is the same as (no:eq? a 10), which is the same as (no (eq? a 10))
70
70
  (if (no (eq? pfx '||))
71
- (error "Irregular '! syntax: got prefix ~(inspect pfx) in ~(joinstr "!" (cons pfx rest))"))
71
+ (error "Irregular '! syntax: got prefix ~(inspect pfx) in ~(join-str pfx "!" rest)"))
72
72
  (if (cdr rest)
73
- (error "Irregular '! syntax: got suffix ~(inspect (cdr rest)) in ~(joinstr "!" (cons pfx rest))")
73
+ (error "Irregular '! syntax: got suffix ~(inspect (cdr rest)) in ~(join-str pfx "!" rest)")
74
74
  (if (caris 'colon-syntax (car rest))
75
75
  `(colon-syntax no ,@(cdar rest))
76
76
  `(colon-syntax no ,(car rest)))))
@@ -79,10 +79,10 @@ scoping, assignment, anonymous functions and more...")
79
79
  `(cond ,condition (do ,@body)))
80
80
 
81
81
  (def pairs (things)
82
- (if (no things) nil
83
- (no (cdr things)) (list (list (car things)))
84
- (cons (list (car things) (cadr things))
85
- (pairs (cddr things)))))
82
+ (if (no things) nil
83
+ (no (cdr things)) (list (list (car things)))
84
+ (cons (list (car things) (cadr things))
85
+ (pairs (cddr things)))))
86
86
 
87
87
  (mac with (parms . body)
88
88
  `((fn ,(map car (pairs parms))
@@ -117,13 +117,11 @@ scoping, assignment, anonymous functions and more...")
117
117
  (,name ,@(map cadr ppairs)))))
118
118
 
119
119
  (let uniq-counter 0
120
- (def uniq (prefix)
121
- (sym (joinstr "-"
122
- (list prefix
123
- (assign uniq-counter
124
- (+ uniq-counter 1))))))
125
- (def reset-uniq-counter ()
126
- (assign uniq-counter 0)))
120
+ (def uniq (prefix)
121
+ (assign uniq-counter (+ uniq-counter 1))
122
+ (sym (join-str prefix "-" (list uniq-counter))))
123
+ (def reset-uniq-counter ()
124
+ (assign uniq-counter 0)))
127
125
 
128
126
  (mac w/uniq (vars . body)
129
127
  ; creates a lexical scope with a unique symbol assigned to
@@ -226,9 +224,9 @@ scoping, assignment, anonymous functions and more...")
226
224
  (mac ampersand-syntax (pfx . rest)
227
225
  ; parser expands a&b to (ampersand-syntax a b)
228
226
  (if (no (eq? pfx '||))
229
- (error "Irregular '& syntax: got prefix ~(inspect pfx) in ~(joinstr "&" (cons pfx rest))"))
227
+ (error "Irregular '& syntax: got prefix ~(inspect pfx) in ~(join-str pfx "&" rest)"))
230
228
  (if (cdr rest)
231
- (error "Irregular '& syntax: got suffix ~(inspect (cdr rest)) in ~(joinstr "&" (cons pfx rest))")
229
+ (error "Irregular '& syntax: got suffix ~(inspect (cdr rest)) in ~(join-str pfx "&" rest)")
232
230
  (build-ampersand-syntax (car rest))))
233
231
 
234
232
  (mac brace-list-mono (arg)
@@ -2,9 +2,10 @@
2
2
 
3
3
  (mac on-err (handler . body)
4
4
  ; executes 'body. If an error is raised, executes 'handler. Inside
5
- ; 'handler, the parameter 'err refers to the error that was raised.
6
- `(handle-error (fn (err) ,handler)
7
- (fn () ,@body)))
5
+ ; 'handler, the parameter 'errors is a list of error messages extracted from
6
+ ; the sequence of errors that led here (Exception#cause in ruby or Throwable.getCause() in java)
7
+ `(handle-error (fn (errors) ,handler)
8
+ (fn () ,@body)))
8
9
 
9
10
  (mac ensure (protection . body)
10
11
  ; executes 'body. Afterwards, executes 'protection.
@@ -39,12 +40,29 @@
39
40
  (loop (assign ,v ,gi) (< ,v ,gm) (assign ,v (+ ,v 1))
40
41
  ,@body))))
41
42
 
42
- (def curry (func . args1)
43
+ (mac curry (func . args1)
43
44
  ; return a new function which is the original function with
44
45
  ; the given args1 already applied
45
46
  ; arguments to the new function are whatever arguments remain
46
47
  ; for the old function
47
- (fn args
48
- (apply func
49
- (joinlists args1
50
- args))))
48
+ `(fn args (apply ,func ,@args1 args)))
49
+
50
+ (mac cache-get (hsh key val)
51
+ ; if ,key is already in ,hsh - return the associated value.
52
+ ; if ,key is not already in ,hsh - evaluate ,val, store the result
53
+ ; under ,key in ,hsh, and return it
54
+ (w/uniq (h k v)
55
+ `(with (,h ,hsh ,k ,key)
56
+ (let ,v (hash-get ,h ,k)
57
+ (or ,v (returnlet ,v ,val (hash-set ,h ,k ,v)))))))
58
+
59
+ (mac defmemo (name args . body)
60
+ ; same as 'def, but caches the result, keyed on args, so for a given set of args the result
61
+ ; is only ever calculated once
62
+ (let forms (filter-forms (build-def-hash (hash)) body)
63
+ (w/uniq h
64
+ `(let ,h (hash)
65
+ (def ,name ,args
66
+ ,@(if forms.comment (map (fn (c) list 'comment c)) forms.comment)
67
+ ,(if forms.chapter `(chapter ,forms.chapter))
68
+ (cache-get ,h (list ,@args) (do ,@(hash-get forms nil))))))))
@@ -1,17 +1,5 @@
1
1
  (chapter-start 'nydp-core "essential functions for getting anything done")
2
2
 
3
- (def joinstr (txt . things)
4
- ; flatten 'things into a single list (ie unnest lists)
5
- ; convert each item to a string
6
- ; return a single string which is the concatenation of each
7
- ; stringified item, with given 'txt inserted in between
8
- ; each item
9
- (let joinables (flatten things)
10
- (apply +
11
- (to-string (car joinables))
12
- (flatten (zip (map (fn (_) txt) (cdr joinables))
13
- (map to-string (cdr joinables)))))))
14
-
15
3
  (def iso (x y)
16
4
  (or (eq? x y)
17
5
  (and (pair? x)
@@ -21,6 +9,7 @@
21
9
 
22
10
  (def x1 (thing) thing)
23
11
  (def sym? (arg) (isa 'symbol arg))
12
+ (def num? (arg) (isa 'number arg))
24
13
  (def string? (arg) (isa 'string arg))
25
14
  (mac just (arg) arg)
26
15
  (def quotify (arg) `(quote ,arg))
@@ -32,11 +21,11 @@
32
21
  (chapter list-manipulation)
33
22
  (chapter string-manipulation)
34
23
  (chapter hash-manipulation)
35
- (if (no things) 0
36
- (pair? things) (list-length things)
24
+ (if (pair? things) (list-length things)
37
25
  (string? things) (string-length things)
38
26
  (hash? things) (list-length:hash-keys things)
39
- nil))
27
+ things nil
28
+ 0))
40
29
 
41
30
  (assign dynamics (hash))
42
31
 
@@ -11,9 +11,9 @@
11
11
  ; each item
12
12
  (let joinables (flatten things)
13
13
  (apply +
14
- (to-string (car joinables))
15
- (flatten (zip (map (fn (_) txt) (cdr joinables))
16
- (map to-string (cdr joinables)))))))
14
+ (to-string:car joinables)
15
+ (flatten (map (fn (x) (list txt x))
16
+ (cdr joinables))))))
17
17
 
18
18
  (def j items
19
19
  ; delegate to 'joinstr with an empty join string
@@ -1,18 +1,20 @@
1
1
  (chapter-start 'list-manipulation)
2
2
 
3
3
  (def list-length (things)
4
- (if (no things) 0
5
- (atom? things) 1
6
- (+ 1 (list-length:cdr things))))
4
+ (if (atom? things) 1
5
+ things (+ 1 (list-length (cdr things)))
6
+ 0))
7
7
 
8
8
  (def list-slices (things slice-size)
9
9
  ; slice 'things into a list of lists each with maximum 'slice-size items
10
10
  (chapter pagination)
11
- (if (< (len things) slice-size)
12
- (cons things nil)
13
- (cons (firstn slice-size things)
14
- (list-slices (nthcdr slice-size things)
15
- slice-size))))
11
+ (if things
12
+ (if (> slice-size (len things))
13
+ (list things)
14
+ (cons (firstn slice-size things)
15
+ (list-slices (nthcdr slice-size things)
16
+ slice-size)))
17
+ nil))
16
18
 
17
19
  (def intersperse (inbetween things)
18
20
  ; return a new list with 'inbetween in between every element of 'things
@@ -43,6 +45,16 @@
43
45
  (f items)
44
46
  items)))
45
47
 
48
+ (assign select collect)
49
+
50
+ (def compact (things)
51
+ ; return a new list containing only non-nil items from the given list
52
+ (collect present? things))
53
+
54
+ (def +nz args
55
+ ; return the sum of all non-nil values (consider nil as zero)
56
+ (apply + (compact args)))
57
+
46
58
  (def reject (f things)
47
59
  ; return all the items in 'things for which 'f returns nil
48
60
  (collect !f things))
@@ -53,14 +65,13 @@
53
65
  (car things)
54
66
  (nth (- n 1) (cdr things))))
55
67
 
56
- (mac each (var things code)
68
+ (mac each (var things . body)
57
69
  ; repeatedly assigns an element of 'things to 'var,
58
- ; and executes 'code each time
70
+ ; and executes 'body each time
59
71
  (w/uniq (xs c)
60
72
  `((rfn ,c (,xs)
61
73
  (if (pair? ,xs)
62
- (do
63
- (let ,var (car ,xs) ,code)
74
+ (do (let ,var (car ,xs) ,@body)
64
75
  (,c (cdr ,xs)))))
65
76
  ,things)))
66
77
 
@@ -81,10 +92,10 @@
81
92
 
82
93
  (def firstn (n things)
83
94
  ; returns the first 'n items in the list 'things
84
- (if (eq? n 0) nil
85
- (cons (car things)
86
- (firstn (- n 1)
87
- (cdr things)))))
95
+ (if (eq? n 0) nil
96
+ things (cons (car things)
97
+ (firstn (- n 1)
98
+ (cdr things)))))
88
99
 
89
100
  (def nthcdr (n things)
90
101
  ; returns the nth cdr of the list 'things
@@ -155,3 +166,57 @@
155
166
 
156
167
  (def min things (best < things))
157
168
  (def max things (best > things))
169
+
170
+ (def map-recurse (on-atom on-list things)
171
+ ((afn (xs)
172
+ (if (pair? xs)
173
+ (on-list self xs)
174
+ xs
175
+ (on-atom xs)))
176
+ things))
177
+
178
+ (def list-gsub (list old new)
179
+ ; recursively replaces 'old with 'new inside 'list
180
+ (map-recurse (fn (s) (if (eq? s old) new s))
181
+ (fn (m things)
182
+ (if (eq? things old)
183
+ new
184
+ (map m things)))
185
+ list))
186
+
187
+ (def all? (f things)
188
+ ; if 'things is a list, true when all items are non-nil
189
+ ; if 'things is an atom, true when non-nil
190
+ (if (pair? things)
191
+ (and (f:car things)
192
+ (or (no:cdr things)
193
+ (all? f (cdr things))))
194
+ (f things)))
195
+
196
+ (def any? (f things)
197
+ ; if 'things is a list, true when at least one item is non-nil
198
+ ; if 'things is an atom, true when non-nil
199
+ (if (pair? things)
200
+ (or (f:car things)
201
+ (and (cdr things)
202
+ (any? f (cdr things))))
203
+ (f things)))
204
+
205
+ (def none? (f things)
206
+ ; if 'things is a list, true when all items are nil
207
+ ; if 'things is an atom, true when nil
208
+ (if (pair? things)
209
+ (and (no:f:car things)
210
+ (none? f (cdr things)))
211
+ (no:f things)))
212
+
213
+ (def list-match? (matchers things)
214
+ ; 'matchers is a list of functions
215
+ ; 'things is a list of items to match
216
+ ; true when each function in 'matchers returns non-nil for the corresponding value in 'things
217
+ (if (pair? matchers)
218
+ (and ((car matchers) (car things))
219
+ (list-match? (cdr matchers) (cdr things)))
220
+ matchers
221
+ (matchers things)
222
+ t))