105-do.scm (1669B)
1 ; (do ((var init step) ...) (test result ...) body ...) 2 ; Iteration. Each iteration: evaluate test; if truthy run result forms 3 ; and return last (UNSPEC if none); else run body for side effects, then 4 ; evaluate every step in the current env, rebind, loop. A binding form 5 ; (var init) -- with no step -- carries var unchanged. 6 7 ;; --- Sum 1..10 via step -------------------------------------------------- 8 (define s 9 (do ((i 1 (+ i 1)) 10 (acc 0 (+ acc i))) 11 ((> i 10) acc))) 12 (if (= s 55) 0 (sys-exit 1)) 13 14 ;; --- Test truthy on first eval: result evaluated, body never runs ------- 15 (define touched 0) 16 (do ((i 0 (+ i 1))) 17 ((= i 0) 'done) 18 (set! touched 99)) 19 (if (= touched 0) 0 (sys-exit 2)) 20 21 ;; --- No result expressions: returns UNSPEC ------------------------------- 22 (if (eq? (do ((i 0 (+ i 1))) ((= i 0))) (do () (#t))) 0 (sys-exit 3)) 23 24 ;; --- Multiple result expressions: last is the value ---------------------- 25 (define n 26 (do ((i 0 (+ i 1))) 27 ((= i 3) 'a 'b 7))) 28 (if (= n 7) 0 (sys-exit 4)) 29 30 ;; --- Body runs in env that sees current iteration's bindings ------------- 31 (define collected '()) 32 (do ((i 0 (+ i 1))) 33 ((= i 3)) 34 (set! collected (cons i collected))) 35 (if (equal? collected '(2 1 0)) 0 (sys-exit 5)) 36 37 ;; --- Step omitted: variable keeps its value ------------------------------ 38 (define hits 0) 39 (do ((i 0 (+ i 1)) 40 (cap 5)) 41 ((= i cap)) 42 (set! hits (+ hits 1))) 43 (if (= hits 5) 0 (sys-exit 6)) 44 45 ;; --- Steps evaluated in pre-update env (parallel update) ---------------- 46 (define swap 47 (do ((a 1 b) 48 (b 2 a) 49 (n 0 (+ n 1))) 50 ((= n 3) (cons a b)))) 51 (if (equal? swap (cons 2 1)) 0 (sys-exit 7)) 52 53 (sys-exit 42)