-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathiteration.tem
51 lines (50 loc) · 4.16 KB
/
iteration.tem
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
(page "Iteration"
(text "Arc provides a number of macros to iterate over code multiple times.
<code>while</code>, <code>until</code>, <code>whilet</code>,
<code>whiler</code>, and <code>loop</code> permit iteration subject to a
condition.
<code>drain</code> iterates over an expression, collecting the values.
<code>for</code> and <code>repeat</code> iterate a specified
number of times. <code>forlen</code>, <code>each</code>,
<code>noisy-each</code>, <code>on</code>, and <code>ontable</code> iterate over a sequence.
")
(newtable "Iteration"
(mac while "test [body ...]" "Executes <code>body</code> repeatedly while <code>test</code> is true. The test is evaluated before each execution of <code>body</code>." (tests (let x 0 (while (< x 3) (prn x) (++ x)))))
(mac until "test [body ...]" "Executes <code>body</code> repeatedly until <code>test</code> is true. The test is evaluated before each execution of <code>body</code>. <code>until</code> is the opposite of <code>while</code>." (tests (let x 0 (until (> x 3) (prn x) (++ x)))))
(mac whilet "var test [body ...]" "Executes <code>body</code> repeatedly while <code>test</code> is
true. The value of <code>test</code> is assigned to <code>var</code> on each iteration, for use in the
body. Typically <code>test</code> obtains a new value from some source, and whilet is used
to loop until <code>nil</code> is obtained." (tests (w/instring s "abc" (whilet c (readc s)
(prn c)))))
(mac whiler "var expr endval [body ...]" "Executes <code>body</code> repeatedly while <code>expr</code>
is not <code>endval</code>. The value of <code>expr</code> is assigned to <code>var</code> on each iteration." (tests (w/instring s "abcdef" (whiler x (readc s) #\d (prn x)))))
(mac loop "start test update [body ...]" "Executes <code>start</code>, then executes <code>body</code>
repeatedly, checking <code>test</code> before each iteration and executing <code>update</code> afterward." (tests (loop (= x 0) (< x 3) (++ x) (prn x))))
(mac drain "expr [eof]" "Repeatedly executes <code>expr</code> until it returns <code>eof</code>
(default <code>nil</code>). A list of the <code>expr</code> values is returned." (tests (w/instring s
"(1 2) (3 4)" (drain (sread s nil)))
(let x 256 (drain (= x (/ x 2)) 1))))
(mac for "var init max [body ...]" "Executes <code>body</code> repeatedly with <code>var</code> assigned the
values from <code>init</code> to <code>max</code>, incremented by 1 each time. For the last iteration,
<code>v</code> will be >= <code>max</code>. If <code>max <= init-1</code>, <code>body</code> will not be executed." (tests (for x 2.5 4.0 (prn x)) (for x 2.5 1.6 (prn x))))
(mac repeat "n [body ...]" "Executes <code>body</code> <code>n</code> times. Non-integers are rounded
up." (tests (repeat 3 (prn "hi"))))
(mac forlen "var seq [body ...]" "Iterates over a sequence (list, string, or
table) <code>seq</code>. <code>var</code> takes the values from 0 to <code>length</code>-1."
(tests
(let seq '(1 2 3) (forlen x seq (prn x " " (seq x))))
(let seq "abc" (forlen x seq (prn x " " (seq x))))
"(let seq (obj 0 'val0 1 'val1)
(forlen x seq (prn x \" \" (seq x))))"
))
(mac each "var expr [body ...]" "Executes <code>body</code>, with <code>var</code> taking on each value
from <code>expr</code>, which can be a list, string, or table. For a table, <code>var</code> takes on
the values, not the keys."
(tests (each x '(1 (2 3) 4) (prn x)) (each x "abc" (prn x)) (each x (obj key1 'val1 key2 'val2) (prn x))))
(mac noisy-each "n var val [body ...]" "Version of <code>each</code>, printing a dot every <code>n</code> iterations." (tests (noisy-each 3 x "abcdefghijk" (pr x))))
(mac on "var s [body ...]" "Iterates the same as <code>each</code>, except the variable <code>index</code> is assigned a count, starting at 0. For tables, <code>var</code> is assigned <code>nil</code> each iteration, so <code>ontable</code> is probably more useful."
(tests (on x '(1 (2 3) 4) (prn index " " x)) (on x "abc" (prn index " " x)) (on x (obj key1 'val1 key2 'val2) (prn index " " x))))
(mac ontable "k v tab [body ...]" "Iterates over the table <code>tab</code>, assigning <code>k</code> and <code>v</code>
each key and value." (tests (ontable k v (obj key1 'val1 key2 'val2) (prn k " " v))))
)
)