nydp 0.4.0 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +44 -0
- data/lib/lisp/core-010-precompile.nydp +13 -16
- data/lib/lisp/core-012-utils.nydp +21 -6
- data/lib/lisp/core-015-documentation.nydp +60 -19
- data/lib/lisp/core-017-builtin-dox.nydp +50 -39
- data/lib/lisp/core-020-utils.nydp +5 -5
- data/lib/lisp/core-030-syntax.nydp +103 -61
- data/lib/lisp/core-035-flow-control.nydp +18 -9
- data/lib/lisp/core-037-list-utils.nydp +36 -14
- data/lib/lisp/core-039-module.nydp +24 -0
- data/lib/lisp/core-040-utils.nydp +41 -23
- data/lib/lisp/core-041-string-utils.nydp +37 -9
- data/lib/lisp/core-042-date-utils.nydp +21 -1
- data/lib/lisp/core-043-list-utils.nydp +93 -67
- data/lib/lisp/core-045-dox-utils.nydp +5 -0
- data/lib/lisp/core-080-pretty-print.nydp +55 -17
- data/lib/lisp/core-090-hook.nydp +35 -1
- data/lib/lisp/core-100-utils.nydp +130 -28
- data/lib/lisp/core-110-hash-utils.nydp +61 -0
- data/lib/lisp/core-120-settings.nydp +46 -0
- data/lib/lisp/core-130-validations.nydp +51 -0
- data/lib/lisp/{core-060-benchmarking.nydp → core-900-benchmarking.nydp} +108 -5
- data/lib/lisp/tests/accum-examples.nydp +28 -1
- data/lib/lisp/tests/aif-examples.nydp +8 -3
- data/lib/lisp/tests/andify-examples.nydp +7 -0
- data/lib/lisp/tests/at-syntax-examples.nydp +17 -0
- data/lib/lisp/tests/best-examples.nydp +9 -0
- data/lib/lisp/tests/builtin-tests.nydp +19 -0
- data/lib/lisp/tests/case-examples.nydp +14 -0
- data/lib/lisp/tests/cdr-set-examples.nydp +6 -0
- data/lib/lisp/tests/date-examples.nydp +56 -1
- data/lib/lisp/tests/destructuring-examples.nydp +5 -5
- data/lib/lisp/tests/detect-examples.nydp +12 -0
- data/lib/lisp/tests/dp-examples.nydp +24 -0
- data/lib/lisp/tests/empty-examples.nydp +1 -1
- data/lib/lisp/tests/error-tests.nydp +4 -4
- data/lib/lisp/tests/filter-forms-examples.nydp +30 -0
- data/lib/lisp/tests/foundation-test.nydp +12 -0
- data/lib/lisp/tests/hash-examples.nydp +26 -2
- data/lib/lisp/tests/list-grep-examples.nydp +40 -0
- data/lib/lisp/tests/list-tests.nydp +58 -1
- data/lib/lisp/tests/map-hash-examples.nydp +11 -0
- data/lib/lisp/tests/mapreduce-examples.nydp +10 -0
- data/lib/lisp/tests/module-examples.nydp +10 -0
- data/lib/lisp/tests/multi-assign-examples.nydp +6 -0
- data/lib/lisp/tests/parser-tests.nydp +21 -0
- data/lib/lisp/tests/pretty-print-tests.nydp +16 -13
- data/lib/lisp/tests/set-difference-examples.nydp +8 -0
- data/lib/lisp/tests/set-intersection-examples.nydp +32 -0
- data/lib/lisp/tests/set-union-examples.nydp +24 -0
- data/lib/lisp/tests/settings-examples.nydp +40 -0
- data/lib/lisp/tests/sort-examples.nydp +8 -0
- data/lib/lisp/tests/string-tests.nydp +61 -1
- data/lib/lisp/tests/syntax-tests.nydp +5 -1
- data/lib/lisp/tests/to-integer-examples.nydp +16 -0
- data/lib/lisp/tests/validation-examples.nydp +15 -0
- data/lib/lisp/tests/zap-examples.nydp +12 -0
- data/lib/nydp.rb +13 -7
- data/lib/nydp/assignment.rb +10 -3
- data/lib/nydp/builtin.rb +1 -1
- data/lib/nydp/builtin/abs.rb +8 -0
- data/lib/nydp/builtin/cdr_set.rb +1 -6
- data/lib/nydp/builtin/date.rb +15 -1
- data/lib/nydp/builtin/error.rb +1 -1
- data/lib/nydp/builtin/handle_error.rb +1 -1
- data/lib/nydp/builtin/hash.rb +27 -45
- data/lib/nydp/builtin/inspect.rb +1 -1
- data/lib/nydp/builtin/plus.rb +10 -2
- data/lib/nydp/builtin/rand.rb +18 -0
- data/lib/nydp/builtin/random_string.rb +2 -2
- data/lib/nydp/builtin/ruby_wrap.rb +72 -0
- data/lib/nydp/builtin/set_intersection.rb +8 -0
- data/lib/nydp/builtin/set_union.rb +8 -0
- data/lib/nydp/builtin/string_match.rb +2 -2
- data/lib/nydp/builtin/string_pad_left.rb +7 -0
- data/lib/nydp/builtin/string_pad_right.rb +7 -0
- data/lib/nydp/builtin/string_replace.rb +1 -1
- data/lib/nydp/builtin/string_split.rb +1 -2
- data/lib/nydp/builtin/to_integer.rb +23 -0
- data/lib/nydp/builtin/to_string.rb +2 -9
- data/lib/nydp/builtin/type_of.rb +9 -6
- data/lib/nydp/closure.rb +0 -3
- data/lib/nydp/cond.rb +23 -1
- data/lib/nydp/context_symbol.rb +14 -6
- data/lib/nydp/core.rb +45 -33
- data/lib/nydp/core_ext.rb +54 -0
- data/lib/nydp/date.rb +37 -31
- data/lib/nydp/function_invocation.rb +34 -26
- data/lib/nydp/hash.rb +5 -6
- data/lib/nydp/helper.rb +41 -25
- data/lib/nydp/interpreted_function.rb +68 -40
- data/lib/nydp/literal.rb +1 -1
- data/lib/nydp/pair.rb +25 -9
- data/lib/nydp/parser.rb +8 -6
- data/lib/nydp/string_atom.rb +16 -22
- data/lib/nydp/symbol.rb +40 -27
- data/lib/nydp/symbol_lookup.rb +7 -7
- data/lib/nydp/tokeniser.rb +2 -2
- data/lib/nydp/truth.rb +17 -10
- data/lib/nydp/version.rb +1 -1
- data/lib/nydp/vm.rb +7 -2
- data/nydp.gemspec +2 -4
- data/spec/date_spec.rb +115 -22
- data/spec/embedded_spec.rb +12 -12
- data/spec/foreign_hash_spec.rb +14 -2
- data/spec/hash_non_hash_behaviour_spec.rb +7 -7
- data/spec/hash_spec.rb +24 -2
- data/spec/nydp_spec.rb +14 -2
- data/spec/parser_spec.rb +27 -16
- data/spec/rand_spec.rb +45 -0
- data/spec/spec_helper.rb +13 -1
- data/spec/symbol_spec.rb +31 -0
- data/spec/time_spec.rb +1 -1
- metadata +38 -37
- data/lib/nydp/builtin/car.rb +0 -7
- data/lib/nydp/builtin/cdr.rb +0 -7
- data/lib/nydp/builtin/cons.rb +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '06876fcb6832d6737b4763607cfe7b4c0ca003c3'
|
|
4
|
+
data.tar.gz: b45d30570c913940f93585241c1dad9cc71c5872
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d874e4fbbba55a5995f699451bbf305fe7667f4058cdab2e713fe64900bc96ed285fe5ae8d0c460c73001f0a44fb22699c634c2017a723e9c79d818779d38b7e
|
|
7
|
+
data.tar.gz: 5d5f3aeb4e7c0e65af1024990fdfa5f73a8f4657a06dfd11aaeec172709615a3879f0bdff0efd19475a223add58ee1dd6379951548979eda5b80f30861967e61
|
data/README.md
CHANGED
|
@@ -55,6 +55,22 @@ answer = Nydp.apply_function ns, :question, :life, ["The Universe", and_also(eve
|
|
|
55
55
|
|
|
56
56
|
You can maintain multiple `ns` instances without mutual interference. In other words, assigning global variables while one `ns` is in scope will not affect the values of variables in any other `ns` (unless you've specifically arranged it to be so by duplicating namespaces or some such sorcery).
|
|
57
57
|
|
|
58
|
+
|
|
59
|
+
#### Facing the Truth
|
|
60
|
+
|
|
61
|
+
In conditional statements, nil is false, anything else is true
|
|
62
|
+
|
|
63
|
+
```lisp
|
|
64
|
+
(if) ;; same as (if nil)
|
|
65
|
+
(if a) ;; same as a
|
|
66
|
+
(if a b) ;; same as (if a b nil)
|
|
67
|
+
(if a b c) ;; if a is nil, return c, otherwise return b
|
|
68
|
+
(if a b c d) ;; same as (if a b (if c d))
|
|
69
|
+
(if a b c d e) ;; same as (if a b (if c d e))
|
|
70
|
+
|
|
71
|
+
;; and so on
|
|
72
|
+
```
|
|
73
|
+
|
|
58
74
|
## Different from Arc :
|
|
59
75
|
|
|
60
76
|
#### 1. Macro-expansion runs in lisp
|
|
@@ -151,8 +167,36 @@ nydp > (map &lastname german-composers) ; ampersand-syntax creates a function
|
|
|
151
167
|
|
|
152
168
|
As with all other syntax, you can of course override the `ampersand-syntax` macro to handle your special needs.
|
|
153
169
|
|
|
170
|
+
You can combine special syntaxes ("%td" comes from nydp-html gem)
|
|
171
|
+
|
|
172
|
+
```lisp
|
|
173
|
+
|
|
174
|
+
nydp > (map %td:&lastname german-composers)
|
|
175
|
+
|
|
176
|
+
"<td>Bach</td><td>Beethoven</td><td>Wagner</td><td>Mozart</td>"
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
So, @%td@ expands to @(percent-syntax || td)@, @&lastname@ to @(ampersand-syntax || lastname)@, and the whole @%td:&lastname@
|
|
181
|
+
to @(colon-syntax (percent-syntax || td) (ampersand-syntax || lastname))@. Luckily for you, there's a fine @colon-syntax@ macro
|
|
182
|
+
that knows how to build a function out of these bits and pieces.
|
|
183
|
+
|
|
184
|
+
|
|
154
185
|
Look for `SYMBOL_OPERATORS` in [parser.rb](lib/nydp/parser.rb) to see which syntax is recognised and in which order. The order of these definitions defines special-syntax-operator precedence.
|
|
155
186
|
|
|
187
|
+
Any character that is not special syntax will be recognised as part of a symbol. At time of writing, this includes the plus sign, hyphen, and slash.
|
|
188
|
+
|
|
189
|
+
```lisp
|
|
190
|
+
|
|
191
|
+
;; nonsense code illustrating the use of certain
|
|
192
|
+
;; characters as function and variable names
|
|
193
|
+
(def //-+ (x y z)
|
|
194
|
+
(let -*- (x y)
|
|
195
|
+
(if z (//-+ x y -*-) -*-)))
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
|
|
156
200
|
#### 3. Special list syntax
|
|
157
201
|
|
|
158
202
|
The parser detects alternative list delimiters
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
(assign mac-expand
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
(assign mac-expand
|
|
2
|
+
(fn (names macfn expr)
|
|
3
|
+
(cond macfn
|
|
4
|
+
(handle-error
|
|
5
|
+
(fn (errors)
|
|
6
|
+
(error "expanding" (inspect expr) "with" (inspect macfn)))
|
|
7
|
+
(fn ()
|
|
8
|
+
(pre-compile-with names (apply macfn (cdr expr)))))
|
|
9
|
+
expr)))
|
|
6
10
|
|
|
7
11
|
(assign macs (hash))
|
|
8
12
|
|
|
9
|
-
(assign pre-compile-expr
|
|
10
|
-
(fn (names expr)
|
|
11
|
-
(mac-expand names
|
|
12
|
-
(hash-get names (car expr))
|
|
13
|
-
expr)))
|
|
14
|
-
|
|
15
13
|
(assign pre-compile-each
|
|
16
14
|
(fn (names args)
|
|
17
15
|
(cond args
|
|
@@ -33,7 +31,10 @@
|
|
|
33
31
|
(cond (eq? (car arg) 'quote)
|
|
34
32
|
arg
|
|
35
33
|
(pre-compile-each names
|
|
36
|
-
(
|
|
34
|
+
(mac-expand names
|
|
35
|
+
(hash-get names
|
|
36
|
+
(car arg))
|
|
37
|
+
arg)))
|
|
37
38
|
arg)))
|
|
38
39
|
|
|
39
40
|
(assign pre-compile-debug
|
|
@@ -136,7 +137,3 @@
|
|
|
136
137
|
|
|
137
138
|
(hash-set macs 'quasiquote
|
|
138
139
|
(fn (arg) (qq-quasiquote arg 0)))
|
|
139
|
-
|
|
140
|
-
(hash-set macs 'do
|
|
141
|
-
(fn args
|
|
142
|
-
`((fn nil ,@args))))
|
|
@@ -8,16 +8,31 @@
|
|
|
8
8
|
(car args))
|
|
9
9
|
nil)))
|
|
10
10
|
|
|
11
|
-
(def map (f things)
|
|
12
|
-
; transforms the list 'things by applying 'f to each item
|
|
13
|
-
; returns the resulting list
|
|
11
|
+
(def map-helper-0 (f things lc)
|
|
14
12
|
(if (pair? things)
|
|
15
|
-
(
|
|
13
|
+
(map-helper-0 f (cdr things) (cdr-set lc (cons (f (car things)))))
|
|
16
14
|
things
|
|
17
|
-
(f things)))
|
|
15
|
+
(cdr-set lc (f things))))
|
|
16
|
+
|
|
17
|
+
(def map-helper-1 (f things acc)
|
|
18
|
+
(map-helper-0 f things acc)
|
|
19
|
+
(cdr acc))
|
|
20
|
+
|
|
21
|
+
;; transforms the list 'things by applying 'f to each item, returns the resulting list
|
|
22
|
+
;; conceptually, does the following:
|
|
23
|
+
;;
|
|
24
|
+
;; (if (pair? things)
|
|
25
|
+
;; (cons (f (car things)) (map f (cdr things)))
|
|
26
|
+
;; things
|
|
27
|
+
;; (f things))
|
|
28
|
+
;;
|
|
29
|
+
;; however the actual version is more complicated to allow for TCO ("modulo-cons" issue)
|
|
30
|
+
(def map (f things)
|
|
31
|
+
(map-helper-1 f things (cons)))
|
|
18
32
|
|
|
33
|
+
;; push 'v onto the value for 'k in 'h
|
|
34
|
+
;; the hash-values of h will all be lists, in reverse order of consing
|
|
19
35
|
(def hash-cons (h k v)
|
|
20
|
-
; push 'v onto the value for 'k in 'h
|
|
21
36
|
(hash-set h k (cons v (hash-get h k))))
|
|
22
37
|
|
|
23
38
|
(def rev (things last-cdr)
|
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
(def privately () nil)
|
|
2
2
|
|
|
3
|
+
(assign comments nil)
|
|
4
|
+
|
|
5
|
+
(def fetch-and-clear-comments ()
|
|
6
|
+
((fn (c) (assign comments nil) c) (rev comments)))
|
|
7
|
+
|
|
8
|
+
(def filter-comments (form acc)
|
|
9
|
+
(if (no form)
|
|
10
|
+
(rev acc)
|
|
11
|
+
(pair? form)
|
|
12
|
+
(filter-comments (cdr form)
|
|
13
|
+
(if (if (pair? (car form))
|
|
14
|
+
(eq? (caar form)
|
|
15
|
+
'comment))
|
|
16
|
+
acc
|
|
17
|
+
(cons (filter-comments (car form)
|
|
18
|
+
nil)
|
|
19
|
+
acc)))
|
|
20
|
+
form))
|
|
21
|
+
|
|
22
|
+
(hash-set macs 'do
|
|
23
|
+
(fn forms
|
|
24
|
+
`((fn nil ,@forms))))
|
|
25
|
+
|
|
3
26
|
((fn (this-chapter-name chapters chapter-new chapter-build chapter-add-to-chapter)
|
|
4
27
|
(assign chapters (hash))
|
|
5
28
|
|
|
@@ -45,7 +68,7 @@
|
|
|
45
68
|
(assign this-script nil)
|
|
46
69
|
(assign this-plugin "Nydp Core")
|
|
47
70
|
|
|
48
|
-
((fn (dox examples chapters dox-new dox-build)
|
|
71
|
+
((fn (dox examples chapters types types-chapters dox-new dox-build)
|
|
49
72
|
(def dox-build (hsh name what texts args src chapters)
|
|
50
73
|
(hash-set hsh 'name name )
|
|
51
74
|
(hash-set hsh 'what what )
|
|
@@ -59,26 +82,38 @@
|
|
|
59
82
|
|
|
60
83
|
(def dox-new (item)
|
|
61
84
|
(hash-cons dox (hash-get item 'name) item)
|
|
62
|
-
(
|
|
85
|
+
(hash-cons types (hash-get item 'what) item)
|
|
86
|
+
(dox-add-to-chapters item (hash-get item 'what) (hash-get item 'chapters) (hash)))
|
|
63
87
|
|
|
64
88
|
(def dox-add-doc (name what texts args src chapters more)
|
|
65
89
|
(cond (no (privately))
|
|
66
90
|
(dox-new (dox-build (if more more (hash)) name what texts args src chapters))))
|
|
67
91
|
|
|
68
|
-
(def dox-add-to-chapters (item chapters)
|
|
92
|
+
(def dox-add-to-chapters (item type chapters already)
|
|
69
93
|
(cond chapters
|
|
70
|
-
|
|
71
|
-
|
|
94
|
+
(cond (no (hash-get already (car chapters)))
|
|
95
|
+
(do (hash-set already (car chapters) t)
|
|
96
|
+
(chapter-add-item item (car chapters))
|
|
97
|
+
(hash-cons types-chapters (inspect (cons type (car chapters))) item)
|
|
98
|
+
(dox-add-to-chapters item type (cdr chapters) already))
|
|
99
|
+
item)
|
|
72
100
|
item))
|
|
73
101
|
|
|
74
102
|
(def dox-add-examples (name example-exprs)
|
|
75
103
|
(hash-cons examples name example-exprs))
|
|
76
104
|
|
|
77
|
-
(def dox-lookup (
|
|
105
|
+
(def dox-lookup (name) (hash-get dox name))
|
|
78
106
|
|
|
79
107
|
(def dox? (sym) (hash-key? dox sym))
|
|
80
108
|
|
|
81
109
|
(def dox-names () (hash-keys dox))
|
|
110
|
+
(def dox-types () (hash-keys types))
|
|
111
|
+
(def dox-items-by-type (type) (hash-get types type))
|
|
112
|
+
|
|
113
|
+
(def get-types-chapters () types-chapters)
|
|
114
|
+
|
|
115
|
+
(def dox-items-by-type-and-chapter (dox-type chapter)
|
|
116
|
+
(hash-get types-chapters (inspect (cons dox-type chapter))))
|
|
82
117
|
|
|
83
118
|
(def dox-get-attr (name attr)
|
|
84
119
|
(cond (dox? name)
|
|
@@ -89,7 +124,7 @@
|
|
|
89
124
|
(def dox-examples (name) (hash-get examples name ))
|
|
90
125
|
(def dox-args (name) (dox-get-attr name 'args ))
|
|
91
126
|
(def dox-example-names () (hash-keys examples )))
|
|
92
|
-
(hash) (hash) (hash) nil)
|
|
127
|
+
(hash) (hash) (hash) (hash) (hash) nil)
|
|
93
128
|
|
|
94
129
|
(def plugin-start (name) (assign this-plugin name) (chapter-end))
|
|
95
130
|
(def plugin-end (name) (assign this-plugin nil ) (chapter-end))
|
|
@@ -106,9 +141,9 @@
|
|
|
106
141
|
(cond (eq? event 'script-end)
|
|
107
142
|
(script-end name))))))
|
|
108
143
|
|
|
144
|
+
;; if the car of 'form is a key of 'hsh, add the cdr of 'form to the value of the key in 'hsh
|
|
145
|
+
;; otherwise add the form to the list whose key is nil
|
|
109
146
|
(def filter-form (hsh form)
|
|
110
|
-
; if the car of 'form is a key of 'hsh, add the cdr of 'form to the value of the key in 'hsh
|
|
111
|
-
; otherwise add the form to the list whose key is nil
|
|
112
147
|
(cond (cond (pair? form)
|
|
113
148
|
(hash-key? hsh (car form)))
|
|
114
149
|
(hash-cons hsh (car form) (cdr form))
|
|
@@ -127,9 +162,9 @@
|
|
|
127
162
|
(def rev-values (hsh)
|
|
128
163
|
(rev-value-keys (hash-keys hsh) hsh (hash)))
|
|
129
164
|
|
|
165
|
+
;; group forms by their first element, if the first element
|
|
166
|
+
;; is already a key in hsh, collect all other elements under key nil
|
|
130
167
|
(def filter-forms (hsh forms)
|
|
131
|
-
; group forms by their first element, if the first element
|
|
132
|
-
; is already a key in hsh, collect all other elements under key nil
|
|
133
168
|
(cond forms
|
|
134
169
|
(filter-forms (filter-form hsh (car forms)) (cdr forms))
|
|
135
170
|
(rev-values hsh)))
|
|
@@ -139,12 +174,14 @@
|
|
|
139
174
|
(hash-set hsh 'chapter nil)
|
|
140
175
|
hsh)
|
|
141
176
|
|
|
177
|
+
(def dox-build-def-name (name) name)
|
|
178
|
+
|
|
179
|
+
;; used internally by 'mac
|
|
142
180
|
(def define-mac-expr (name args body-forms)
|
|
143
|
-
; used internally by 'mac
|
|
144
181
|
`(do (hash-set macs ',name (fun ,args ,@(hash-get body-forms nil)))
|
|
145
|
-
(dox-add-doc ',name
|
|
182
|
+
(dox-add-doc ',(dox-build-def-name name)
|
|
146
183
|
'mac
|
|
147
|
-
',(map car (hash-get body-forms 'comment))
|
|
184
|
+
',(+ (fetch-and-clear-comments) (map car (hash-get body-forms 'comment)))
|
|
148
185
|
',args
|
|
149
186
|
'(mac ,name ,args ,@(hash-get body-forms nil))
|
|
150
187
|
',(map car (hash-get body-forms 'chapter)))))
|
|
@@ -169,17 +206,21 @@
|
|
|
169
206
|
|
|
170
207
|
(mac def-assign args `(assign ,@args))
|
|
171
208
|
|
|
209
|
+
;; used internally by 'def
|
|
172
210
|
(def define-def-expr (name args body-forms)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
(dox-add-doc ',name
|
|
211
|
+
`(do (def-assign ,name (fun ,args ,@(filter-comments (hash-get body-forms nil))))
|
|
212
|
+
(dox-add-doc ',(dox-build-def-name name)
|
|
176
213
|
'def
|
|
177
|
-
',(map car (hash-get body-forms 'comment))
|
|
214
|
+
',(+ (fetch-and-clear-comments) (map car (hash-get body-forms 'comment)))
|
|
178
215
|
',args
|
|
179
216
|
'(def ,name ,args ,@(hash-get body-forms nil))
|
|
180
217
|
',(map car (hash-get body-forms 'chapter)))))
|
|
181
218
|
|
|
219
|
+
;; define a new function in the global namespace
|
|
182
220
|
(mac def (name args . body)
|
|
183
|
-
; define a new function in the global namespace
|
|
184
221
|
(chapter nydp-core)
|
|
185
222
|
(define-def-expr name args (filter-forms (build-def-hash (hash)) body)))
|
|
223
|
+
|
|
224
|
+
(mac comment (txt)
|
|
225
|
+
(assign comments (cons txt comments))
|
|
226
|
+
nil)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
(dox-add-doc 'cons 'def '("with args a and b, returns a new cons cell, (a . b)") '(a b) nil '(list-manipulation))
|
|
2
2
|
(dox-add-doc 'car 'def '("with args a, where a is a cons cell (x . y), return x." "Commonly used to get the first element of a list") '(a) nil '(list-manipulation))
|
|
3
3
|
(dox-add-doc 'cdr 'def '("with args a, where a is a cons cell (x . y), return y." "Commonly used to get contents of a list, excluding the first element") '(a) nil '(list-manipulation))
|
|
4
|
+
(dox-add-doc 'log 'def '("write arg to Nydp.logger ; be sure to assign Nydp.logger first!") '(arg) nil '(nydp-core))
|
|
4
5
|
(dox-add-doc '+ 'def '("with rest-args things, return the sum of the elements of things." "Will also increment dates and concatenate strings and lists") 'things nil '(math))
|
|
5
6
|
(dox-add-doc '- 'def '("return the result of subtracting all other args from the first arg." "(- a b c d) is equivalent to (- a (+ b c d))") 'things nil '(math))
|
|
6
7
|
(dox-add-doc '* 'def '("with rest-args things, return the product of the elements of things.") 'things nil '(math))
|
|
@@ -35,18 +36,21 @@
|
|
|
35
36
|
(dox-add-doc 'pair? 'def '("t if arg is a cons cell or (equivalently) the start of a list") '(arg) nil '(nydp-core))
|
|
36
37
|
(dox-add-doc 'hash? 'def '("t if arg is a hash") '(arg) nil '(nydp-core))
|
|
37
38
|
(dox-add-doc 'sym? 'def '("t if arg is a symbol, nil otherwise") '(arg) nil '(nydp-core))
|
|
38
|
-
(dox-add-doc 'ensuring 'def '("execute '
|
|
39
|
-
"'ensure-f will always be executed, even if there is an error in '
|
|
40
|
-
"returns the return value of '
|
|
39
|
+
(dox-add-doc 'ensuring 'def '("execute 'try-f, then 'ensure-f afterwards"
|
|
40
|
+
"'ensure-f will always be executed, even if there is an error in 'try-f"
|
|
41
|
+
"returns the return value of 'try-f. Similar to try/finally in java, or begin/ensure in ruby.") '(ensure-f try-f) nil '(flow-control))
|
|
41
42
|
(dox-add-doc 'inspect 'def '("return a string representing 'arg, potentially (but not always) in a way that can be parsed back in to get the original object") '(arg) nil '(nydp-core))
|
|
42
43
|
(dox-add-doc 'comment 'def '("does nothing at all." "Intercepted inside 'def and 'mac and used for documentation") '(arg) nil '(nydp-core))
|
|
43
44
|
(dox-add-doc 'parse-in-string 'def '("parse the given string assuming a string-open delimiter has already been encountered") '(str) nil '(nydp-core))
|
|
44
|
-
(dox-add-doc '
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
(dox-add-doc 'string
|
|
48
|
-
(dox-add-doc 'string
|
|
49
|
-
(dox-add-doc 'string-
|
|
45
|
+
(dox-add-doc 'rand 'def '("return a random number ; with no args, between 0 and 1"
|
|
46
|
+
"with 1 arg, an integer less than arg"
|
|
47
|
+
"with two args, an integer >= arg 0 and < arg 1") 'args nil '(math))
|
|
48
|
+
(dox-add-doc 'random-string 'def '("return a random string of length 'len (default 10)") '(len) nil '(string-manipulation))
|
|
49
|
+
(dox-add-doc 'to-string 'def '("return a human-readable string representation of 'arg") '(arg) nil '(string-manipulation))
|
|
50
|
+
(dox-add-doc 'string-length 'def '("return the length of 'arg") '(arg) nil '(string-manipulation))
|
|
51
|
+
(dox-add-doc 'string-replace 'def '("replace 'pattern with 'replacement in 'str") '(pattern replacement str) nil '(string-manipulation))
|
|
52
|
+
(dox-add-doc 'string-split 'def '("split 'str delimited by 'delim") '(str delim) nil '(string-manipulation))
|
|
53
|
+
(dox-add-doc 'string-match 'def '("if 'str matches 'pattern, return hash with keys 'match and 'captures ; otherwise nil") '(str pattern) nil '(string-manipulation))
|
|
50
54
|
(dox-add-doc 'time 'def '("with no args, return the current time."
|
|
51
55
|
"With one arg, if 'arg-0 is a number, return the current time plus 'arg-0 seconds."
|
|
52
56
|
"With one arg, if 'arg-0 is a date, return the time at the beginning of the given date."
|
|
@@ -54,35 +58,42 @@
|
|
|
54
58
|
"With two args, 'arg-0 must be a time."
|
|
55
59
|
"If 'arg-1 is a number, return 'arg-0 plus 'arg-1 seconds as a time object."
|
|
56
60
|
"If 'arg-1 is a time, return the number of seconds between the two (- 'arg-0 arg-1)."
|
|
57
|
-
"Otherwise, expect 3
|
|
61
|
+
"Otherwise, expect 3 or more args, to construct a time from"
|
|
58
62
|
"year, month, date, hours, minutes, seconds, milliseconds, reading arguments in that order,"
|
|
59
|
-
"where hours, minutes, seconds, and milliseconds are optional")
|
|
60
|
-
(dox-add-doc 'thread-locals
|
|
61
|
-
(dox-add-doc 'type-of
|
|
62
|
-
(dox-add-doc 'eq?
|
|
63
|
-
(dox-add-doc 'cdr-set
|
|
64
|
-
(dox-add-doc 'hash-get
|
|
65
|
-
(dox-add-doc 'hash-set
|
|
66
|
-
(dox-add-doc 'hash-keys
|
|
67
|
-
(dox-add-doc 'hash-key?
|
|
68
|
-
(dox-add-doc 'hash-merge
|
|
69
|
-
(dox-add-doc 'vm-info
|
|
70
|
-
(dox-add-doc 'pre-compile
|
|
71
|
-
(dox-add-doc 'script-run
|
|
72
|
-
|
|
73
|
-
|
|
63
|
+
"where hours, minutes, seconds, and milliseconds are optional") 'args nil '(date-time))
|
|
64
|
+
(dox-add-doc 'thread-locals 'def '("return a hash bound to the current thread") nil nil '(nydp-core))
|
|
65
|
+
(dox-add-doc 'type-of 'def '("return a symbol for the type of 'arg") '(arg) nil '(nydp-core))
|
|
66
|
+
(dox-add-doc 'eq? 'def '("return 't if 'arg-0 and 'arg-1 are equal, nil otherwise") '(arg-0 arg-1) nil '(nydp-core))
|
|
67
|
+
(dox-add-doc 'cdr-set 'def '("set the cdr of the given 'cell to 'arg, returns 'cell") '(cell arg) nil '(list-manipulation))
|
|
68
|
+
(dox-add-doc 'hash-get 'def '("return the value stored by 'key in 'hsh") '(hsh key) nil '(hash-manipulation))
|
|
69
|
+
(dox-add-doc 'hash-set 'def '("store 'val under 'key in 'hsh, return 'val") '(hsh key val) nil '(hash-manipulation))
|
|
70
|
+
(dox-add-doc 'hash-keys 'def '("return the list of keys in 'hsh") '(hsh) nil '(hash-manipulation))
|
|
71
|
+
(dox-add-doc 'hash-key? 'def '("return 't if 'key is a key of 'hsh") '(hsh key) nil '(hash-manipulation))
|
|
72
|
+
(dox-add-doc 'hash-merge 'def '("return a new hash containing keys and values from 'h0 and 'h1, where values of 'h1 override values of 'h0") '(h0 h1) nil '(hash-manipulation))
|
|
73
|
+
(dox-add-doc 'vm-info 'def '("return some information about the state of the current thread") nil nil '(nydp-core))
|
|
74
|
+
(dox-add-doc 'pre-compile 'def '("transform parsed forms before the compile and eval stages") '(arg) nil '(nydp-compilation))
|
|
75
|
+
(dox-add-doc 'script-run 'def '("announces the start of a plugin load or a script load."
|
|
76
|
+
"'event may be one of '(script-start script-end plugin-start plugin-end)"
|
|
77
|
+
"'name is the name of the script or plugin concerned") '(event name) nil '(nydp-core))
|
|
74
78
|
|
|
75
|
-
(dox-add-doc 'chapter-end
|
|
76
|
-
(dox-add-doc 'chapter-start
|
|
77
|
-
(dox-add-doc 'chapter-names
|
|
78
|
-
(dox-add-doc 'chapter-current
|
|
79
|
-
(dox-add-doc 'chapter-delete
|
|
80
|
-
(dox-add-doc 'chapter-find
|
|
81
|
-
(dox-add-doc '
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
79
|
+
(dox-add-doc 'chapter-end 'def '("Announce the end of a chapter. Called by 'plugin-start, 'plugin-end, 'script-start, 'script-end") nil nil '(nydp/documentation))
|
|
80
|
+
(dox-add-doc 'chapter-start 'def '("Announce the start of a chapter. Creates a new chapter if the named chapter does not already exist") '(chapter-name description) nil '(nydp/documentation))
|
|
81
|
+
(dox-add-doc 'chapter-names 'def '("Get the names of all the chapters nydp knows about") nil nil '(nydp/documentation))
|
|
82
|
+
(dox-add-doc 'chapter-current 'def '("Get the name of the chapter in progress right now - this is normally the last value sent to 'chapter-start") nil nil '(nydp/documentation))
|
|
83
|
+
(dox-add-doc 'chapter-delete 'def '("Remove the named chapter") '(name) nil '(nydp/documentation))
|
|
84
|
+
(dox-add-doc 'chapter-find 'def '("Get the named chapter") '(name) nil '(nydp/documentation))
|
|
85
|
+
(dox-add-doc 'set-intersection 'def '("return the intersection of the given lists") 'args nil '(list-manipulation))
|
|
86
|
+
(dox-add-doc '⋂ 'def '("return the intersection of the given lists") 'args nil '(list-manipulation))
|
|
87
|
+
(dox-add-doc 'set-union 'def '("return the union of the given lists") 'args nil '(list-manipulation))
|
|
88
|
+
(dox-add-doc '⋃ 'def '("return the union of the given lists") 'args nil '(list-manipulation))
|
|
89
|
+
(dox-add-doc 'dox-add-doc 'def '("Store the provided documentation item."
|
|
90
|
+
"'name is the name of the item"
|
|
91
|
+
"'what is the type of the item ('def or 'mac or 'thingy ... this is user-definable, not related to 'type-of)"
|
|
92
|
+
"'texts is a list of strings to store for this item"
|
|
93
|
+
"'args is the args if the item has the notion of args"
|
|
94
|
+
"'src the source code of the item if any"
|
|
95
|
+
"'chapters the chapters to which the item should be added, if any") '(name what texts args src chapters) nil '(nydp/documentation))
|
|
96
|
+
(dox-add-doc 'dox-add-examples 'def '("Add the given examples to the dox for the named item") '(name example-exprs) nil '(nydp/documentation))
|
|
97
|
+
(dox-add-doc 'dox-types 'def '("Get the list of types of documented items") nil nil '(nydp/documentation))
|
|
98
|
+
(dox-add-doc 'dox-lookup 'def '("Get the documentation for the given item") '(name) nil '(nydp/documentation))
|
|
99
|
+
(dox-add-doc 'dox-items-by-type 'def '("Get the list of dox items of a given type") '(type) nil '(nydp/documentation))
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(assign script-name "core-
|
|
1
|
+
(assign script-name "core-020-utils.nydp")
|
|
2
2
|
|
|
3
3
|
(dox-add-doc 'if
|
|
4
4
|
'mac
|
|
@@ -43,12 +43,12 @@
|
|
|
43
43
|
'(hash-set h k (cons v (hash-get h k)))
|
|
44
44
|
'(hash-manipulation))
|
|
45
45
|
|
|
46
|
+
;; equivalent to (join-str "~prefix~joint~(car things)" joint (cdr things)) - except
|
|
47
|
+
;; 'string-pieces hasn't been defined yet, and if it were, it would be defined in terms of
|
|
48
|
+
;; 'join-str, so it would be circular.
|
|
49
|
+
;; see 'joinstr for a more powerful and easier-to-use implementation of the same idea
|
|
46
50
|
(def join-str (prefix joint things)
|
|
47
51
|
(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
52
|
(if things
|
|
53
53
|
(join-str (+ (to-string prefix)
|
|
54
54
|
joint
|
|
@@ -21,16 +21,26 @@ scoping, assignment, anonymous functions and more...")
|
|
|
21
21
|
(apply orf
|
|
22
22
|
(cdr args)))))
|
|
23
23
|
|
|
24
|
+
; returns true if 'things is a list and the first item of the
|
|
25
|
+
; list is the given object
|
|
24
26
|
(def caris (obj things)
|
|
25
|
-
; returns true if 'things is a list and the first item of the
|
|
26
|
-
; list is the given object
|
|
27
27
|
(and (pair? things)
|
|
28
|
-
(eq? (car things)
|
|
28
|
+
(eq? (car things) obj)))
|
|
29
29
|
|
|
30
|
+
; evaluate 'body if 'arg is nil
|
|
30
31
|
(mac unless (arg . body)
|
|
31
|
-
; evaluate 'body if 'arg is nil
|
|
32
32
|
`(if (no ,arg) (do ,@body)))
|
|
33
33
|
|
|
34
|
+
; looks up a key in @
|
|
35
|
+
; assumes local lexical context has defined a hash called '@
|
|
36
|
+
(mac prefix-at-syntax (name . names)
|
|
37
|
+
`(hash-get @ ',name))
|
|
38
|
+
|
|
39
|
+
(mac at-syntax names
|
|
40
|
+
(if (eq? (car names) '||)
|
|
41
|
+
`(prefix-at-syntax ,@(cdr names))
|
|
42
|
+
(error "unknown at-syntax: expected prefix-syntax (eg @name), got ~(join-str (car names) "@" (cdr names))")))
|
|
43
|
+
|
|
34
44
|
(def expand-colon-syntax (names)
|
|
35
45
|
(if (no (cdr names))
|
|
36
46
|
`(apply ,(car names) args)
|
|
@@ -84,13 +94,17 @@ scoping, assignment, anonymous functions and more...")
|
|
|
84
94
|
(cons (list (car things) (cadr things))
|
|
85
95
|
(pairs (cddr things)))))
|
|
86
96
|
|
|
97
|
+
;; like 'let, but creates and assigns multiple local variables.
|
|
98
|
+
;; for example, "(with (a 1 b 2) (+ a b))" returns 3
|
|
87
99
|
(mac with (parms . body)
|
|
88
100
|
`((fun ,(map car (pairs parms))
|
|
89
101
|
,@body)
|
|
90
102
|
,@(map cadr (pairs parms))))
|
|
91
103
|
|
|
104
|
+
;; same as ( (fn (var) body) val ) -> ie create a lexical scope
|
|
105
|
+
;; where val is assigned to var, execute 'body in that scope
|
|
92
106
|
(mac let (var val . body)
|
|
93
|
-
|
|
107
|
+
`(with (,var ,val) ,@body))
|
|
94
108
|
|
|
95
109
|
(mac rfn (name parms . body)
|
|
96
110
|
; creates a named, locally-scoped function
|
|
@@ -116,6 +130,17 @@ scoping, assignment, anonymous functions and more...")
|
|
|
116
130
|
(assign ,name (fun ,(map car ppairs) ,@body))
|
|
117
131
|
(,name ,@(map cadr ppairs)))))
|
|
118
132
|
|
|
133
|
+
;; (andify a b c) is equivalent to
|
|
134
|
+
;; (fn args (and (apply a args) (apply b args) (apply c args)))
|
|
135
|
+
;; or more simply
|
|
136
|
+
;; (fn (x) (and (a x) (b x) (c x)))
|
|
137
|
+
;; note: alias as 'andf ??
|
|
138
|
+
(def andify args
|
|
139
|
+
(fn args2 (rfnwith self (ands args)
|
|
140
|
+
(if ands (if (apply (car ands) args2)
|
|
141
|
+
(self (cdr ands)))
|
|
142
|
+
t))))
|
|
143
|
+
|
|
119
144
|
(let uniq-counter 0
|
|
120
145
|
(def uniq (prefix)
|
|
121
146
|
(assign uniq-counter (+ uniq-counter 1))
|
|
@@ -127,7 +152,7 @@ scoping, assignment, anonymous functions and more...")
|
|
|
127
152
|
; creates a lexical scope with a unique symbol assigned to
|
|
128
153
|
; each variable in 'vars ; executes the 'body.
|
|
129
154
|
(if (pair? vars)
|
|
130
|
-
`(with ,(apply + (map (fn (n) (
|
|
155
|
+
`(with ,(apply + (map (fn (n) `(,n (uniq ',n))) vars))
|
|
131
156
|
,@body)
|
|
132
157
|
`(let ,vars (uniq ',vars) ,@body)))
|
|
133
158
|
|
|
@@ -194,29 +219,23 @@ scoping, assignment, anonymous functions and more...")
|
|
|
194
219
|
(and (pair? name)
|
|
195
220
|
(caris 'ampersand-syntax (car name))))
|
|
196
221
|
|
|
222
|
+
;; (= (&key (expr)) (val))
|
|
223
|
+
;; (= ((ampersand-syntax key) (expr)) (val))
|
|
224
|
+
;; 'place is ((ampersand-syntax || key) (expr))
|
|
225
|
+
;; we need (hash-set (expr) 'key (val))
|
|
226
|
+
;; however,
|
|
227
|
+
;; (= (&key.subkey (expr)) (val))
|
|
228
|
+
;; 'place is ((ampersand-syntax || (dot-syntax key subkey)) (expr))
|
|
229
|
+
;; we need (hash-set (hash-get (expr) 'key) 'subkey (val))
|
|
197
230
|
(def ampersand-expression-assignment (place value)
|
|
198
|
-
; (= (&key (expr)) (val))
|
|
199
|
-
; (= ((ampersand-syntax key) (expr)) (val))
|
|
200
|
-
; 'place is ((ampersand-syntax || key) (expr))
|
|
201
|
-
; we need (hash-set (expr) 'key (val))
|
|
202
|
-
; however,
|
|
203
|
-
; (= (&key.subkey (expr)) (val))
|
|
204
|
-
; 'place is ((ampersand-syntax || (dot-syntax key subkey)) (expr))
|
|
205
|
-
; we need (hash-set (hash-get (expr) 'key) 'subkey (val))
|
|
206
231
|
(with (k (cadr:cdar place)
|
|
207
232
|
hsh (cadr place))
|
|
208
233
|
(if (caris 'dot-syntax k)
|
|
209
234
|
(dot-syntax-assignment (cons hsh (cdr k)) value)
|
|
210
235
|
`(hash-set ,hsh ',k ,value))))
|
|
211
236
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
; to hash keys
|
|
215
|
-
; (= (hash-get (expr) 'key) (val) => (hash-set (expr) 'key (val))
|
|
216
|
-
; (= h.k (val)) => (hash-set h 'k (val))
|
|
217
|
-
; (= h.j.k (val)) => (hash-set (hash-get h 'j) 'k (val))
|
|
218
|
-
; (= (&key (expr)) (val)) => (hash-set (expr) 'key (val))
|
|
219
|
-
; (= (&j.k (expr)) (val)) => (hash-set (hash-get (expr) 'j) 'k (val))
|
|
237
|
+
;; used internally by '= macro
|
|
238
|
+
(def assign-expr (name value)
|
|
220
239
|
(if (isa 'symbol name)
|
|
221
240
|
`(assign ,name ,value)
|
|
222
241
|
(caris 'dot-syntax name)
|
|
@@ -224,15 +243,35 @@ scoping, assignment, anonymous functions and more...")
|
|
|
224
243
|
(caris 'hash-get name)
|
|
225
244
|
(hash-get-assignment (cdr name) value)
|
|
226
245
|
(ampersand-expression? name)
|
|
227
|
-
(ampersand-expression-assignment name value)
|
|
228
|
-
|
|
229
|
-
(
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
246
|
+
(ampersand-expression-assignment name value)
|
|
247
|
+
(caris 'at-syntax name)
|
|
248
|
+
`(hash-set @ ',(caddr name) ,value)
|
|
249
|
+
(error "unknown assignment to place: ~(inspect name)")))
|
|
250
|
+
|
|
251
|
+
;; generic assignment which unlike builtin 'assign, knows how to assign
|
|
252
|
+
;; to hash keys
|
|
253
|
+
;; (= (hash-get (expr) 'key) (val) => (hash-set (expr) 'key (val))
|
|
254
|
+
;; (= h.k (val)) => (hash-set h 'k (val))
|
|
255
|
+
;; (= h.j.k (val)) => (hash-set (hash-get h 'j) 'k (val))
|
|
256
|
+
;; (= (&key (expr)) (val)) => (hash-set (expr) 'key (val))
|
|
257
|
+
;; (= (&j.k (expr)) (val)) => (hash-set (hash-get (expr) 'j) 'k (val))
|
|
258
|
+
(mac = (name value . more)
|
|
259
|
+
(if more
|
|
260
|
+
`(do ,(assign-expr name value) (= ,@more))
|
|
261
|
+
(assign-expr name value)))
|
|
262
|
+
|
|
263
|
+
;; quiet assignment ; like =, but expression returns nil
|
|
264
|
+
(mac #= (name value)
|
|
265
|
+
`(do (= ,name ,value) nil))
|
|
266
|
+
|
|
267
|
+
; increment the value at 'place by 'inc (default 1)
|
|
268
|
+
(mac ++ (place inc) `(= ,place (+ ,place ,(or inc 1))))
|
|
269
|
+
|
|
270
|
+
; override previous definition to allow expressions like (def hsh.foo (arg arg2) ...)
|
|
271
|
+
(mac def-assign args `(= ,@args))
|
|
272
|
+
|
|
273
|
+
; evaluate ,val and assign result to ,place only if ,place is already nil
|
|
274
|
+
(mac or= (place val) `(or ,place (= ,place ,val)))
|
|
236
275
|
|
|
237
276
|
(def brace-list-hash-key (k)
|
|
238
277
|
(if (isa 'symbol k) `(quote ,k)
|
|
@@ -259,43 +298,42 @@ scoping, assignment, anonymous functions and more...")
|
|
|
259
298
|
(error "Irregular '& syntax: got suffix ~(inspect (cdr rest)) in ~(join-str pfx "&" rest)")
|
|
260
299
|
(build-ampersand-syntax (car rest))))
|
|
261
300
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
arg)
|
|
301
|
+
; override 'brace-list-mono in order to provide a useful interpretation for "{ x }" syntax
|
|
302
|
+
(mac brace-list-mono (arg) arg)
|
|
265
303
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
'(hash))
|
|
304
|
+
; interprets "{ }" as new hash
|
|
305
|
+
(mac brace-list-empty () '(hash))
|
|
269
306
|
|
|
307
|
+
; parser expands { foo bar } to (brace-list foo bar)
|
|
270
308
|
(mac brace-list args
|
|
271
|
-
; parser expands { foo bar } to (brace-list foo bar)
|
|
272
309
|
(if (no args)
|
|
273
310
|
`(brace-list-empty)
|
|
274
311
|
(no (cdr args))
|
|
275
312
|
`(brace-list-mono ,(car args))
|
|
276
313
|
(brace-list-build-hash args)))
|
|
277
314
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
; it gets changed. See also 'returning
|
|
282
|
-
`(let ,var ,val ,@body ,var))
|
|
315
|
+
; stores ,val in ,var, executes ,@body, returns ,var. Saves a line of code at the end of
|
|
316
|
+
; 'let. If 'body assigns to 'var, the assigned value of 'var will be returned. See also 'returning
|
|
317
|
+
(mac returnlet (var val . body) `(let ,var ,val ,@body ,var))
|
|
283
318
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
319
|
+
; stores ,val, executes ,@body, and returns ,val. Assumes 'body is going to do something
|
|
320
|
+
; destructive with 'val, but you want 'val before it gets changed. Note that if 'val is mutated
|
|
321
|
+
; (eg hash), the mutated value will be returned. See also 'returnlet
|
|
322
|
+
(mac returning (val . body) (w/uniq retval `(returnlet ,retval ,val ,@body)))
|
|
288
323
|
|
|
289
|
-
(mac
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
; source: arc.arc
|
|
293
|
-
`(let it ,expr
|
|
294
|
-
(if it
|
|
324
|
+
(mac ifv (var expr . body)
|
|
325
|
+
`(let ,var ,expr
|
|
326
|
+
(if ,var
|
|
295
327
|
,@(if (cddr body)
|
|
296
|
-
`(,(car body) (
|
|
328
|
+
`(,(car body) (ifv ,var ,@(cdr body)))
|
|
297
329
|
body))))
|
|
298
330
|
|
|
331
|
+
; like if, except the value of each condition is locally bound to the variable 'it
|
|
332
|
+
; eg (aif (find thing) (show it))
|
|
333
|
+
; source: arc.arc
|
|
334
|
+
(mac aif (expr . body)
|
|
335
|
+
`(ifv it ,expr ,@body))
|
|
336
|
+
|
|
299
337
|
(def destructure/with (var args n)
|
|
300
338
|
; provides the argument expression to 'with when
|
|
301
339
|
; destructuring arguments are present in a 'fun definition
|
|
@@ -318,16 +356,20 @@ scoping, assignment, anonymous functions and more...")
|
|
|
318
356
|
`(fn ,(rev new-args given-args) ,@body)))
|
|
319
357
|
|
|
320
358
|
|
|
321
|
-
(def fun/approve-arg-names (orig args)
|
|
359
|
+
(def fun/approve-arg-names (orig args body)
|
|
322
360
|
(if (pair? args)
|
|
323
|
-
(do (fun/approve-arg-names orig (car args))
|
|
324
|
-
(fun/approve-arg-names orig (cdr args)))
|
|
361
|
+
(do (fun/approve-arg-names orig (car args) body)
|
|
362
|
+
(fun/approve-arg-names orig (cdr args) body))
|
|
325
363
|
args
|
|
326
364
|
(if (hash-get macs args)
|
|
327
|
-
(warnings/new 'arg-shadows-macro "arg " args " shadows macro " args " in arg list " orig))))
|
|
365
|
+
(warnings/new 'arg-shadows-macro "arg " args " shadows macro " args " in arg list " orig " and body " body))))
|
|
328
366
|
|
|
367
|
+
;; build a 'fn form, changing 'args and 'body to
|
|
368
|
+
;; properly handle any destructuring args if present
|
|
329
369
|
(mac fun (args . body)
|
|
330
|
-
|
|
331
|
-
; properly handle any destructuring args if present
|
|
332
|
-
(fun/approve-arg-names args args)
|
|
370
|
+
(fun/approve-arg-names args args body)
|
|
333
371
|
(destructure/build args nil body))
|
|
372
|
+
|
|
373
|
+
;; assign (f place) to place
|
|
374
|
+
(mac zap (f place . args)
|
|
375
|
+
`(= ,place (,f ,place ,@args)))
|