;; For loops.
(use-modules (srfi srfi-1))
(define-syntax for
(syntax-rules (in .. .= by)
;; Integer range exclusive by step.
((for index in start .. end by step body ...)
(do ((index start (+ index step))
(n (ceiling-quotient (- end start) step) (- n 1)))
((<= n 0))
body ...))
;; Integer range inclusive by step.
((for index in start .= end by step body ...)
(for index in start .. (+ end (if (negative? step) -1 1)) by step
body ...))
;; Integer range exclusive default step.
((for index in start .. end body ...)
(for index in start .. end by 1
body ...))
;; Integer range inclusive default step.
((for index in start .= end body ...)
(for index in start .= end by 1
body ...))
;; Iterate over a list.
((for item in list body ...)
(for-each (lambda (item)
body ...)
list))))
;; Main.
(define (print-range start end step)
(for i in start .. end by step
(format #t "~A " i))
(newline)
(for i in start .= end by step
(format #t "~A " i))
(newline)
(let ((n (ceiling-quotient (- end start) step)))
(for i in (iota (max n 0) start step)
(format #t "~A " i)))
(newline))
(print-range 1 5 1)
(print-range 1 11 2)
(print-range -11 -1 2)
(print-range 5 1 -1)
(print-range 11 1 -2)
(print-range -1 -11 -2)
;; Nested default step.
(for y in 0 .. 4
(for x in 0 .. 4
(format #t "[~A ~A] " x y))
(newline))