Undid racketification, because not diffrentiating between :for and :acc means that errors become very strange and unhelpful.
Added simple forms, like loop/list that accumulates bodies into a list. Add :final that works like in racket: (loop/list ((:for a (in-list '(1 2 3))) :final (= a 2)) (display a)) => (1 2)
This commit is contained in:
parent
80464ebe48
commit
1a826f86e2
2 changed files with 154 additions and 115 deletions
150
goof.scm
150
goof.scm
|
@ -33,15 +33,15 @@
|
|||
;; trying to understand the iterator protocol.
|
||||
|
||||
|
||||
|
||||
(use-modules (helpers)
|
||||
((srfi srfi-1) #:select (circular-list))
|
||||
(srfi srfi-71)
|
||||
(rnrs io simple))
|
||||
(rnrs io simple)
|
||||
(ice-9 futures))
|
||||
|
||||
(define-aux-syntaxes
|
||||
;; Auxiliary syntax for the loop clauses
|
||||
:when :unless :break :final :let :let* :subloop
|
||||
:when :unless :break :final :let :let* :subloop :for :acc
|
||||
;; Auxiliary syntax for the iterators.
|
||||
:gen)
|
||||
|
||||
|
@ -51,23 +51,31 @@
|
|||
|
||||
|
||||
(define-syntax loop
|
||||
(syntax-rules ()
|
||||
(syntax-rules (=>)
|
||||
((loop () => expr body ...)
|
||||
(let () expr))
|
||||
((loop () body ...)
|
||||
(let () body ...))
|
||||
((loop name () => expr body ...)
|
||||
expr)
|
||||
((loop name () body ...)
|
||||
(if #f #f))
|
||||
((loop (clauses ...) body ...)
|
||||
(cl (loop (clauses ...) body ...)
|
||||
loop-name
|
||||
(()) (()) (()) (()) (()) () (()) (()) (())
|
||||
(()) (()) (()) (()) (()) () (()) (()) (()) ()
|
||||
(clauses ...)
|
||||
body ... (loop-name)))
|
||||
((loop name (clauses ...) . body)
|
||||
(cl (loop name (clauses ...) . body)
|
||||
name
|
||||
(()) (()) (()) (()) (()) () (()) (()) (())
|
||||
(()) (()) (()) (()) (()) () (()) (()) (()) ()
|
||||
(clauses ...)
|
||||
. body))))
|
||||
|
||||
(define-syntax push-new-subloop
|
||||
(syntax-rules ()
|
||||
((_ orig name (lets ...) (accs ...) (vars ...) (checks ...) (refs ...) f (ul ...) (uw ...) (ub ...) clauses . body)
|
||||
((_ orig name (lets ...) (accs ...) (vars ...) (checks ...) (refs ...) f (ul ...) (uw ...) (ub ...) uf clauses . body)
|
||||
(cl orig name
|
||||
(() lets ...)
|
||||
(() accs ...)
|
||||
|
@ -78,47 +86,58 @@
|
|||
(() ul ...)
|
||||
(() uw ...)
|
||||
(() ub ...)
|
||||
uf
|
||||
clauses . body))))
|
||||
|
||||
|
||||
;; Clauses sorts all the clauses into subloops and positions everything where it should be.
|
||||
(define-syntax cl
|
||||
(syntax-rules (=> in :when :unless :break :final :let :let* :subloop)
|
||||
((_ orig name l a v c r f ul uw ub () => expr . body)
|
||||
(emit orig name l a v c r f ul uw ub expr . body))
|
||||
((_ orig name l a v c r f ul uw ub () . body)
|
||||
(emit orig name l a v c r f ul uw ub (if #f #f) . body))
|
||||
(syntax-rules (=> :for :acc :when :unless :break :final :let :let* :subloop)
|
||||
((_ orig name l a v c r f ul uw ub uf () => expr . body)
|
||||
(emit orig name l a v c r f ul uw ub uf expr . body))
|
||||
((_ orig name l a v c r f ul uw ub uf () . body)
|
||||
(emit orig name l a v c r f ul uw ub uf (if #f #f) . body))
|
||||
|
||||
;; USER LETS
|
||||
((_ orig name l a v c r f ((cur-ul ...) . ul-rest) uw ub uf (:let (id id* ... expr) clauses ...) . body)
|
||||
(cl orig name l a v c r f ((cur-ul ... (:let id id* ... expr)) . ul-rest) uw ub uf (clauses ...) . body))
|
||||
((_ orig name l a v c r f ((cur-ul ...) . ul-rest) uw ub uf (:let* (id id* ... expr) clauses ...) . body)
|
||||
(cl orig name l a v c r f ((cur-ul ... (:let* id id* ... expr)) . ul-rest) uw ub uf (clauses ...) . body))
|
||||
;; user-whens
|
||||
((_ orig name l a v c r f ul ((cur-uw ...) . uw-rest) ub (:when test clauses ...) . body)
|
||||
(cl orig name l a v c r f ul ((cur-uw ... test) . uw-rest) ub (clauses ...) . body))
|
||||
((_ orig name l a v c r f ul ((cur-uw ...) . uw-rest) ub (:unless test clauses ...) . body)
|
||||
(cl orig name l a v c r f ul ((cur-uw ... (not test)) . uw-rest) ub (clauses ...) . body))
|
||||
((_ orig name l a v c r f ul ((cur-uw ...) . uw-rest) ub uf (:when test clauses ...) . body)
|
||||
(cl orig name l a v c r f ul ((cur-uw ... test) . uw-rest) ub uf (clauses ...) . body))
|
||||
((_ orig name l a v c r f ul ((cur-uw ...) . uw-rest) ub uf (:unless test clauses ...) . body)
|
||||
(cl orig name l a v c r f ul ((cur-uw ... (not test)) . uw-rest) ub uf (clauses ...) . body))
|
||||
;; USER BREAKS
|
||||
;; This pushes a #t to the user when expression, thus forcing a subloop if a for-clause is found afterwards.
|
||||
((_ orig name l a v c r f ul ((cur-uw ...) . uw-rest) ((cur-ub ...) . ub-rest) (:break expr clauses ...) . body)
|
||||
(cl orig name l a v c r f ul ((cur-uw ... #t) . uw-rest) ((cur-ub ... expr) . ub-rest) (clauses ...) . body))
|
||||
;; USER LETS
|
||||
((_ orig name l a v c r f ((cur-ul ...) . ul-rest) uw ub (:let (id id* ... expr) clauses ...) . body)
|
||||
(cl orig name l a v c r f ((cur-ul ... (:let id id* ... expr)) . ul-rest) uw ub (clauses ...) . body))
|
||||
((_ orig name l a v c r f ((cur-ul ...) . ul-rest) uw ub (:let* (id id* ... expr) clauses ...) . body)
|
||||
(cl orig name l a v c r f ((cur-ul ... (:let* id id* ... expr)) . ul-rest) (clauses ...) . body))
|
||||
((_ orig name l a v c r f ul ((cur-uw ...) . uw-rest) ((cur-ub ...) . ub-rest) uf (:break expr clauses ...) . body)
|
||||
(cl orig name l a v c r f ul ((cur-uw ... #t) . uw-rest) ((cur-ub ... expr) . ub-rest) uf (clauses ...) . body))
|
||||
;; user final
|
||||
;; This pushes a #t to the user when expression, thus forcing a subloop if a for-clause is found afterwards.
|
||||
((_ orig name l a v c r f ul ((cur-uw ...) . uw-rest) ub (cur-uf ...) (:final expr clauses ...) . body)
|
||||
(cl orig name l a v c r f ul ((cur-uw ... #t) . uw-rest) ub (cur-uf ... expr) (clauses ...) . body))
|
||||
|
||||
;; Explicit subloop. Shorthand for (:when #t)
|
||||
((_ orig name l a v c r f ul ((cur-uw ...) . uw-rest) ub (:subloop clauses ...) . body)
|
||||
(cl orig name l a v c r f ul ((cur-uw ... #t) . uw-rest) ub (clauses ...) . body))
|
||||
((_ orig name l a v c r f ul ((cur-uw ...) . uw-rest) ub uf (:subloop clauses ...) . body)
|
||||
(cl orig name l a v c r f ul ((cur-uw ... #t) . uw-rest) ub uf (clauses ...) . body))
|
||||
;; :for-clauses
|
||||
;; found a for clause when we have a :when or :unless clause. Push new subloop
|
||||
((_ orig name l a v c r f ul ((uw uw* ...) . uw-rest) ub ((for-rest ...) clauses ...) . body)
|
||||
(push-new-subloop orig name l a v c r f ul ((uw uw* ...) . uw-rest) ub ((for-rest ...) clauses ...) . body))
|
||||
((_ orig name l a v c r f ul ((uw uw* ...) . uw-rest) ub uf ((:for for-rest ...) clauses ...) . body)
|
||||
(push-new-subloop orig name l a v c r f ul ((uw uw* ...) . uw-rest) ub uf ((:for for-rest ...) clauses ...) . body))
|
||||
|
||||
;; For clause with a sequence creator.
|
||||
((_ orig name l a v c r f ul uw ub ((id ids ... (iterator source ...)) clauses ...) . body)
|
||||
(iterator ((id ids ...) (source ...)) cl-next orig name l a v c r f ul uw ub (clauses ...) . body))
|
||||
((_ orig name l a v c r f ul uw ub uf ((:for id ids ... (iterator source ...)) clauses ...) . body)
|
||||
(iterator ((id ids ...) (source ...)) cl-next orig name l a v c r f ul uw ub uf (clauses ...) . body))
|
||||
|
||||
((_ orig name l a v c r f ul uw ub uf ((:acc id ids ... (accumulator source ...)) clauses ...) . body)
|
||||
(accumulator :acc ((id ids ...) (source ...)) cl-next orig name l a v c r f ul uw ub uf (clauses ...) . body))
|
||||
|
||||
;; no :acc or :for: imlplicit for!
|
||||
((_ orig name l a v c r f ul uw ub uf ((id ids ... (iterator source ...)) clauses ...) . body)
|
||||
(cl orig name l a v c r f ul uw ub uf ((:for id ids ... (iterator source ...)) clauses ...) . body))
|
||||
|
||||
;; ERROR HANDLING?
|
||||
((_ orig name l a v c r f ul uw ub (clause . rest) . body)
|
||||
((_ orig name l a v c r f ul uw ub uf (clause . rest) . body)
|
||||
(syntax-error "Invalid clause in loop" clause orig))
|
||||
|
||||
))
|
||||
|
@ -129,7 +148,7 @@
|
|||
;; into the outer loops. Since accumulators need to be available in the (final-fun ...), they need to be visible also
|
||||
;; in the outer loops if the loop exits there.
|
||||
(define-syntax cl-next
|
||||
(syntax-rules ()
|
||||
(syntax-rules (:for :acc)
|
||||
((_ (new-lets ...) ((accvar accinit accupdate) ...) (new-vars ...) (new-checks ...) (new-refs ...) (new-finals ...)
|
||||
orig name
|
||||
((lets ...))
|
||||
|
@ -137,7 +156,7 @@
|
|||
((vars ...))
|
||||
((checks ...))
|
||||
((refs ...))
|
||||
(finals ...) ul uw ub clauses . body)
|
||||
(finals ...) ul uw ub uf clauses . body)
|
||||
(cl orig name
|
||||
((lets ... new-lets ...))
|
||||
((accs ... (accvar accinit accupdate) ...))
|
||||
|
@ -145,7 +164,7 @@
|
|||
((checks ... new-checks ...))
|
||||
((refs ... new-refs ...))
|
||||
(finals ... new-finals ...)
|
||||
ul uw ub clauses . body))
|
||||
ul uw ub uf clauses . body))
|
||||
;; We have ONE subloop!
|
||||
((_ (new-lets ...) ((accvar accinit accupdate) ...) (new-vars ...) (new-checks ...) (new-refs ...) (new-finals ...)
|
||||
orig name
|
||||
|
@ -154,7 +173,7 @@
|
|||
((vars ...) . vars-rest)
|
||||
((checks ...) . checks-rest)
|
||||
((refs ...) . refs-rest)
|
||||
(finals ...) ul uw ub clauses . body)
|
||||
(finals ...) ul uw ub uf clauses . body)
|
||||
(cl orig name
|
||||
((lets ... new-lets ...) . lets-rest)
|
||||
((accs ... (accvar accvar accupdate) ...) ((oldacc oldinit oldupdate) ... (accvar accinit accvar) ...))
|
||||
|
@ -162,7 +181,7 @@
|
|||
((checks ... new-checks ...) . checks-rest)
|
||||
((refs ... new-refs ...) . refs-rest)
|
||||
(finals ... new-finals ...)
|
||||
ul uw ub clauses . body))
|
||||
ul uw ub uf clauses . body))
|
||||
;; We have several subloops!
|
||||
((_ (new-lets ...) ((accvar accinit accupdate) ...) (new-vars ...) (new-checks ...) (new-refs ...) (new-finals ...)
|
||||
orig name
|
||||
|
@ -171,7 +190,7 @@
|
|||
((vars ...) . vars-rest)
|
||||
((checks ...) . checks-rest)
|
||||
((refs ...) . refs-rest)
|
||||
(finals ...) ul uw ub clauses . body)
|
||||
(finals ...) ul uw ub uf clauses . body)
|
||||
(cl orig name
|
||||
((lets ... new-lets ...) . lets-rest)
|
||||
((accs ... (accvar accvar accupdate) ...) ((oldacc oldinit oldupdate) ... (accvar accvar accvar) ...) ...
|
||||
|
@ -180,7 +199,7 @@
|
|||
((checks ... new-checks ...) . checks-rest)
|
||||
((refs ... new-refs ...) . refs-rest)
|
||||
(finals ... new-finals ...)
|
||||
ul uw ub clauses . body))
|
||||
ul uw ub uf clauses . body))
|
||||
))
|
||||
|
||||
(define-syntax user-let
|
||||
|
@ -224,7 +243,8 @@
|
|||
((checks ...))
|
||||
((refs ...))
|
||||
((final-binding final-value) ...)
|
||||
((user-lets ...)) ((user-whens ...)) ((user-breaks ...)) final-expr . body)
|
||||
((user-lets ...)) ((user-whens ...)) ((user-breaks ...)) uf
|
||||
final-expr . body)
|
||||
(let* (lets ...)
|
||||
(define (final-fun final-binding ...)
|
||||
final-expr)
|
||||
|
@ -234,7 +254,10 @@
|
|||
(let (refs ...)
|
||||
(user-let () () (user-lets ...)
|
||||
(if (and user-whens ...)
|
||||
(let-kw-form name (loopy-loop (accvar accstep) ... (var step) ...)
|
||||
(let-kw-form name
|
||||
(final-fun final-value ...)
|
||||
uf
|
||||
(loopy-loop (accvar accstep) ... (var step) ...)
|
||||
(if (or user-breaks ...)
|
||||
(final-fun final-value ...)
|
||||
(let () (if #f #f) . body)))
|
||||
|
@ -254,6 +277,7 @@
|
|||
(ul-next ... (user-lets ...))
|
||||
(uw-next ... (user-whens ...))
|
||||
(ub-next ... (user-breaks ...))
|
||||
uf
|
||||
final-expr
|
||||
. body)
|
||||
(let* ((final-fun (lambda (final-binding ...) final-expr))
|
||||
|
@ -280,6 +304,7 @@
|
|||
(ul-next ...)
|
||||
(uw-next ...)
|
||||
(ub-next ...)
|
||||
uf
|
||||
. body)))
|
||||
(outer-loop accvar ... step ...))))))))))
|
||||
|
||||
|
@ -298,6 +323,7 @@
|
|||
((user-lets ...))
|
||||
((user-whens ...))
|
||||
((user-breaks ...))
|
||||
uf
|
||||
. body)
|
||||
(let* (lets ...)
|
||||
(let innermost-loop ((accvar accinit) ...
|
||||
|
@ -310,7 +336,7 @@
|
|||
(cond
|
||||
((or user-breaks ...) final)
|
||||
(else
|
||||
(let-kw-form name (innermost-loop (accvar accstep) ... (var step) ...)
|
||||
(let-kw-form name final uf (innermost-loop (accvar accstep) ... (var step) ...)
|
||||
. body)))
|
||||
(innermost-loop accvar ... step ...))))))))
|
||||
|
||||
|
@ -327,6 +353,7 @@
|
|||
(ul-next ... (user-lets ...))
|
||||
(uw-next ... (user-whens ...))
|
||||
(ub-next ... (user-breaks ...))
|
||||
uf
|
||||
. body)
|
||||
(let* (lets ...)
|
||||
(let intermediate-loop ((accvar accinit) ...
|
||||
|
@ -351,6 +378,7 @@
|
|||
(ul-next ...)
|
||||
(uw-next ...)
|
||||
(ub-next ...)
|
||||
uf
|
||||
. body))
|
||||
(intermediate-loop accvar ... step ...))))))))))
|
||||
|
||||
|
@ -362,7 +390,7 @@
|
|||
|
||||
(define (update-name params name val)
|
||||
(cond
|
||||
((null? params) (error "unknown loop parameter name " name (list '=> name val)))
|
||||
((null? params) (error "unknown loop variable name " name (list '=> name val)))
|
||||
((syntax= name (caar params))
|
||||
(cons (list (caar params) val) (cdr params)))
|
||||
(else
|
||||
|
@ -374,7 +402,7 @@
|
|||
|
||||
(define-syntax let-kw-form
|
||||
(syntax-rules ()
|
||||
((_ macro-name (loop-name (var step) ...) . body)
|
||||
((_ macro-name final-fun (user-finals ...) (loop-name (var step) ...) . body)
|
||||
(let-syntax ((macro-name
|
||||
(lambda (stx)
|
||||
(with-ellipsis :::
|
||||
|
@ -382,7 +410,10 @@
|
|||
(params (list #'(var step) ...)))
|
||||
(if (null? lst)
|
||||
(with-syntax ((((v s) :::) params))
|
||||
#'(loop-name s :::))
|
||||
#'(let ((v s) :::)
|
||||
(if (or user-finals ...)
|
||||
final-fun
|
||||
(loop-name v :::))))
|
||||
(syntax-case (car lst) (=>)
|
||||
((=> name val)
|
||||
(loop (cdr lst) (update-name params #'name #'val)))
|
||||
|
@ -401,19 +432,19 @@
|
|||
(define-syntax loop/sum
|
||||
(syntax-rules ()
|
||||
((_ (clauses ...) body ...)
|
||||
(loop (clauses ... (acc (summing (let () body ...)))) => acc))))
|
||||
(loop (clauses ... (:acc acc (summing (let () body ...)))) => acc))))
|
||||
|
||||
(define-syntax loop/product
|
||||
(syntax-rules ()
|
||||
((_ (clauses ...) body ...)
|
||||
(loop (clauses ... (acc (multiplying (let () body ...)))) => acc))))
|
||||
(loop (clauses ... (:acc acc (multiplying (let () body ...)))) => acc))))
|
||||
|
||||
(define sentinel (list 'unique))
|
||||
|
||||
(define-syntax loop/first
|
||||
(syntax-rules ()
|
||||
((_ (clauses ...) body ...)
|
||||
(loop loop-name ((acc (folding sentinel)) clauses ... :break (not (eq? sentinel acc)))
|
||||
(loop loop-name (clauses ... (:acc acc (folding sentinel)) :break (not (eq? sentinel acc)))
|
||||
=> (if (eq? sentinel acc) #f acc)
|
||||
(let ((result (let () body ...)))
|
||||
(loop-name (=> acc result)))))))
|
||||
|
@ -421,9 +452,34 @@
|
|||
(define-syntax loop/last
|
||||
(syntax-rules ()
|
||||
((_ (clauses ...) body ...)
|
||||
(loop loop-name ((acc (folding sentinel)) clauses ...) => (if (eq? sentinel acc) #f acc)
|
||||
(loop loop-name (clauses ... (:acc acc (folding sentinel))) => (if (eq? sentinel acc) #f acc)
|
||||
(let ((result (let () body ...)))
|
||||
(loop-name (=> acc result)))))))
|
||||
|
||||
(define-syntax loop/and
|
||||
(syntax-rules ()
|
||||
((_ (clauses ...) body ...)
|
||||
(loop loop-name (clauses ... (:acc acc (folding #t)))
|
||||
=> acc
|
||||
(let ((res (let () body ...)))
|
||||
(if res
|
||||
(loop-name (=> acc res))
|
||||
#f))))))
|
||||
|
||||
(define-syntax loop/or
|
||||
(syntax-rules ()
|
||||
((_ (clauses ...) body ...)
|
||||
(loop loop-name (clauses ...)
|
||||
=> #f
|
||||
(or (let () body ...) (loop-name))))))
|
||||
|
||||
(define-syntax loop/list/parallel
|
||||
(syntax-rules ()
|
||||
((_ (clauses ...) body ...)
|
||||
(loop (clauses ... (:acc futures (listing-reverse (future (let () body ...)))))
|
||||
=> (loop ((:for future (in-list futures))
|
||||
(:acc futures2 (listing-reverse (touch future))))
|
||||
=> futures2)))))
|
||||
|
||||
|
||||
|
||||
|
|
115
iterators.scm
115
iterators.scm
|
@ -214,23 +214,20 @@
|
|||
((up-from (() . args) next . rest)
|
||||
(up-from ((var) . args) next . rest))
|
||||
((up-from ((var) (start (to limit) (by step))) next . rest)
|
||||
(next ((s start) (l limit) (e step)) ()
|
||||
((var s (+ var e))) ((>= var l)) () () . rest))
|
||||
(next ((s start) (l limit) (e step))
|
||||
()
|
||||
((var s (+ var e)))
|
||||
((>= var l))
|
||||
() () . rest))
|
||||
((up-from ((var) (start (to limit))) next . rest)
|
||||
(next ((s start) (l limit))()
|
||||
((var s (+ var 1)))
|
||||
(next ((s start) (l limit)) () ((var s (+ var 1)))
|
||||
((>= var l)) () () . rest))
|
||||
((up-from ((var) (start (by step))) next . rest)
|
||||
(next ((s start) (e step))()
|
||||
((var s (+ var e))) () () () . rest))
|
||||
((up-from ((var) (start)) next . rest)
|
||||
(next ((s start))
|
||||
()
|
||||
((var s (+ var 1)))
|
||||
()
|
||||
()
|
||||
()
|
||||
. rest))
|
||||
(next ((s start)) () ((var s (+ var 1)))
|
||||
() () () . rest))
|
||||
;; Extra convenience, make it act like (in-range ...) from racket, but only for positive numbers.
|
||||
((up-from ((var) (start limit step)) next . rest)
|
||||
(next ((s start) (l limit) (e step)) () ((var s (+ var e))) ((>= var l)) () () . rest))
|
||||
|
@ -248,42 +245,28 @@
|
|||
()
|
||||
((var (- s e) (- var e)))
|
||||
((< var l))
|
||||
()
|
||||
()
|
||||
. rest))
|
||||
() () . rest))
|
||||
((down-from ((var) (start (to limit))) next . rest)
|
||||
(next ((s start) (l limit))
|
||||
()
|
||||
((var (- s 1) (- var 1)))
|
||||
((< var l))
|
||||
()
|
||||
()
|
||||
. rest))
|
||||
(next ((s start) (l limit)) () ((var (- s 1) (- var 1)))
|
||||
((< var l)) () () . rest))
|
||||
((down-from ((var) (start (by step))) next . rest)
|
||||
(next ((s start) (e step))
|
||||
()
|
||||
((var (- s e) (- var e)))
|
||||
()
|
||||
()
|
||||
()
|
||||
. rest))
|
||||
(next ((s start) (e step)) () ((var (- s e) (- var e)))
|
||||
() () () . rest))
|
||||
((down-from ((var) (start)) next . rest)
|
||||
(next ((s start))
|
||||
()
|
||||
((var (- s 1) (- var 1)))
|
||||
()
|
||||
()
|
||||
()
|
||||
. rest))
|
||||
))
|
||||
(next ((s start)) () ((var (- s 1) (- var 1)))
|
||||
() () () . rest))
|
||||
((down-from ((var) (start limit step)) next . rest)
|
||||
(next ((s start) (l limit) (e step)) () ((var (- s e) (- var e))) ((< var l)) () () . rest))
|
||||
((down-from ((var) (start limit)) next . rest)
|
||||
(down-from ((var) (start limit 1)) next . rest))))
|
||||
|
||||
(define-syntax accumulating
|
||||
(syntax-rules (initial if)
|
||||
((accumulating (kons final init) ((var) . x) next . rest)
|
||||
(accumulating (kons final init) ((var cursor) . x) next . rest))
|
||||
((accumulating (kons final init) ((var cursor) ((initial i) . x)) n . rest)
|
||||
(accumulating (kons final i) ((var cursor) x) n . rest))
|
||||
((accumulating (kons final init) ((var cursor) (expr (if check))) n . rest)
|
||||
(syntax-rules (initial if :acc)
|
||||
((accumulating :acc (kons final init) ((var) . x) next . rest)
|
||||
(accumulating :acc (kons final init) ((var cursor) . x) next . rest))
|
||||
((accumulating :acc (kons final init) ((var cursor) ((initial i) . x)) n . rest)
|
||||
(accumulating :acc (kons final i) ((var cursor) x) n . rest))
|
||||
((accumulating :acc (kons final init) ((var cursor) (expr (if check))) n . rest)
|
||||
(n ((tmp-kons kons))
|
||||
((cursor init (if check (tmp-kons expr cursor) cursor)))
|
||||
()
|
||||
|
@ -291,7 +274,7 @@
|
|||
()
|
||||
((var (final cursor)))
|
||||
. rest))
|
||||
((accumulating (kons final init) ((var cursor) (expr)) n . rest)
|
||||
((accumulating :acc (kons final init) ((var cursor) (expr)) n . rest)
|
||||
(n ((tmp-kons kons))
|
||||
((cursor init (tmp-kons expr cursor)))
|
||||
()
|
||||
|
@ -301,32 +284,32 @@
|
|||
. rest))))
|
||||
|
||||
(define-syntax folding
|
||||
(syntax-rules (if)
|
||||
((_ ((var) (init update (if guard))) n . rest)
|
||||
(syntax-rules (if :acc)
|
||||
((_ :acc ((var) (init update (if guard))) n . rest)
|
||||
(n ()
|
||||
((var init (if guard update var)))
|
||||
() () ()
|
||||
((var var))
|
||||
. rest))
|
||||
((_ ((var) (init update)) n . rest)
|
||||
((_ :acc ((var) (init update)) n . rest)
|
||||
(folding ((var) (init update (if #t))) n . rest))
|
||||
((_ ((var) (init)) n . rest)
|
||||
((_ :acc ((var) (init)) n . rest)
|
||||
(folding ((var) (init var (if #t))) n . rest))))
|
||||
|
||||
|
||||
;;> \macro{(for x [pair] (listing expr))}
|
||||
|
||||
(define-syntax listing
|
||||
(syntax-rules ()
|
||||
((listing args next . rest)
|
||||
(accumulating (cons reverse '()) args next . rest))))
|
||||
(syntax-rules (:acc)
|
||||
((listing :acc args next . rest)
|
||||
(accumulating :acc (cons reverse '()) args next . rest))))
|
||||
|
||||
;;> \macro{(for x [pair] (listing-reverse expr))}
|
||||
|
||||
(define-syntax listing-reverse
|
||||
(syntax-rules ()
|
||||
((listing-reverse args next . rest)
|
||||
(accumulating (cons (lambda (x) x) '()) args next . rest))))
|
||||
(syntax-rules (:acc)
|
||||
((listing-reverse :acc args next . rest)
|
||||
(accumulating :acc (cons (lambda (x) x) '()) args next . rest))))
|
||||
|
||||
(define (append-reverse rev tail)
|
||||
(if (null? rev) tail (append-reverse (cdr rev) (cons (car rev) tail))))
|
||||
|
@ -334,29 +317,29 @@
|
|||
;;> \macro{(for x [pair] (appending expr))}
|
||||
|
||||
(define-syntax appending
|
||||
(syntax-rules ()
|
||||
((appending args next . rest)
|
||||
(accumulating (append-reverse reverse '()) args next . rest))))
|
||||
(syntax-rules (:acc)
|
||||
((appending :acc args next . rest)
|
||||
(accumulating :acc (append-reverse reverse '()) args next . rest))))
|
||||
|
||||
;;> \macro{(for x [pair] (appending-reverse expr))}
|
||||
|
||||
(define-syntax appending-reverse
|
||||
(syntax-rules ()
|
||||
((appending-reverse args next . rest)
|
||||
(accumulating (append-reverse (lambda (x) x) '()) args next . rest))))
|
||||
(syntax-rules (:acc)
|
||||
((appending-reverse :acc args next . rest)
|
||||
(accumulating :acc (append-reverse (lambda (x) x) '()) args next . rest))))
|
||||
|
||||
;;> \macro{(for x (summing expr))}
|
||||
|
||||
(define-syntax summing
|
||||
(syntax-rules ()
|
||||
((summing args next . rest)
|
||||
(accumulating (+ (lambda (x) x) 0) args next . rest))))
|
||||
(syntax-rules (:acc)
|
||||
((summing :acc args next . rest)
|
||||
(accumulating :acc (+ (lambda (x) x) 0) args next . rest))))
|
||||
|
||||
;;> \macro{(for x (multiplying expr))}
|
||||
|
||||
(define-syntax multiplying
|
||||
(syntax-rules ()
|
||||
((multiplying args next . rest)
|
||||
(syntax-rules (:acc)
|
||||
((multiplying :acc args next . rest)
|
||||
(accumulating (* (lambda (x) x) 1) args next . rest))))
|
||||
|
||||
|
||||
|
@ -380,10 +363,10 @@
|
|||
((_ ((id) (source)) n . rest)
|
||||
(n ((gen (generator-cycle source)))
|
||||
()
|
||||
((id (gen) (gen)))
|
||||
((eof-object? id))
|
||||
()
|
||||
()
|
||||
((id (gen)))
|
||||
()
|
||||
. rest))))
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue