Changed the loop protocol for :acc clauses

The third clause (the "check" clause) now breaks the entire
iteration for :acc clauses instead of just exiting the current subloop.

This is much saner, and was immediately usable in vectoring.
This commit is contained in:
Linus 2021-03-11 22:18:29 +01:00
parent 90c2c6bfdf
commit 172d0aa180
2 changed files with 32 additions and 38 deletions

View file

@ -180,55 +180,55 @@
((lets ...)) ((lets ...))
((accs ...)) ((accs ...))
vars vars
((checks ...)) checks
((refs ...)) ((refs ...))
(finals ...) (finals ...)
ff ul uw ub uf clauses . body) ff ul uw ((cur-ub ...) . ub-rest) uf clauses . body)
(cl orig name (cl orig name
((lets ... new-lets ...)) ((lets ... new-lets ...))
((accs ... (accvar accinit accupdate) ...)) ((accs ... (accvar accinit accupdate) ...))
vars vars
((checks ... new-checks ...)) checks
((refs ... new-refs ...)) ((refs ... new-refs ...))
(finals ... new-finals ...) (finals ... new-finals ...)
ff ul uw ub uf clauses . body)) ff ul uw ((cur-ub ... new-checks ...) . ub-rest) uf clauses . body))
;; We have ONE subloop! ;; We have ONE subloop!
((_ (new-lets ...) ((accvar accinit accupdate) ...) (new-checks ...) (new-refs ...) (new-finals ...) ((_ (new-lets ...) ((accvar accinit accupdate) ...) (new-checks ...) (new-refs ...) (new-finals ...)
orig name orig name
(lets ... (outermost-lets ...)) (lets ... (outermost-lets ...))
((accs ...) ((oldacc oldinit oldupdate) ...)) ((accs ...) ((oldacc oldinit oldupdate) ...))
vars vars
((checks ...) . checks-rest) checks
((refs ...) . refs-rest) ((refs ...) . refs-rest)
(finals ...) (finals ...)
ff ul uw ub uf clauses . body) ff ul uw ((cur-ub ...) . ub-rest) uf clauses . body)
(cl orig name (cl orig name
(lets ... (outermost-lets ... new-lets ...)) (lets ... (outermost-lets ... new-lets ...))
((accs ... (accvar accvar accupdate) ...) ((oldacc oldinit oldupdate) ... (accvar accinit accvar) ...)) ((accs ... (accvar accvar accupdate) ...) ((oldacc oldinit oldupdate) ... (accvar accinit accvar) ...))
vars vars
((checks ... new-checks ...) . checks-rest) checks
((refs ... new-refs ...) . refs-rest) ((refs ... new-refs ...) . refs-rest)
(finals ... new-finals ...) (finals ... new-finals ...)
ff ul uw ub uf clauses . body)) ff ul uw ((cur-ub ... new-checks ...) . ub-rest) uf clauses . body))
;; We have several subloops! ;; We have several subloops!
((_ (new-lets ...) ((accvar accinit accupdate) ...) (new-checks ...) (new-refs ...) (new-finals ...) ((_ (new-lets ...) ((accvar accinit accupdate) ...) (new-checks ...) (new-refs ...) (new-finals ...)
orig name orig name
(lets ... (outermost-lets ...)) (lets ... (outermost-lets ...))
((accs ...) ((oldacc oldinit oldupdate) ...) ... ((oldestacc oldestinit oldestupdate) ...)) ((accs ...) ((oldacc oldinit oldupdate) ...) ... ((oldestacc oldestinit oldestupdate) ...))
vars vars
((checks ...) . checks-rest) checks
((refs ...) . refs-rest) ((refs ...) . refs-rest)
(finals ...) (finals ...)
ff ul uw ub uf clauses . body) ff ul uw ((cur-ub ...) . ub-rest) uf clauses . body)
(cl orig name (cl orig name
(lets ... (outermost-lets ... new-lets ...)) (lets ... (outermost-lets ... new-lets ...))
((accs ... (accvar accvar accupdate) ...) ((oldacc oldinit oldupdate) ... (accvar accvar accvar) ...) ... ((accs ... (accvar accvar accupdate) ...) ((oldacc oldinit oldupdate) ... (accvar accvar accvar) ...) ...
((oldestacc oldestinit oldestupdate) ... (accvar accinit accvar) ...)) ((oldestacc oldestinit oldestupdate) ... (accvar accinit accvar) ...))
vars vars
((checks ... new-checks ...) . checks-rest) checks
((refs ... new-refs ...) . refs-rest) ((refs ... new-refs ...) . refs-rest)
(finals ... new-finals ...) (finals ... new-finals ...)
ff ul uw ub uf clauses . body)))) ff ul uw ((cur-ub ... new-checks ...) . ub-rest) uf clauses . body))))
;; Integrating for clauses is not as involved, since they only want to be introduced into the current ;; Integrating for clauses is not as involved, since they only want to be introduced into the current
;; loop. Any propagation of for finalizers (ff) is done by push-new-subloop ;; loop. Any propagation of for finalizers (ff) is done by push-new-subloop

View file

@ -447,18 +447,12 @@
. rest)) . rest))
((_ :acc ((var index) (expr (:length len))) n . rest) ((_ :acc ((var index) (expr (:length len))) n . rest)
(vectoring :acc ((var index) (expr (:length len) (:fill (if #f #f)))) n . rest)) (vectoring :acc ((var index) (expr (:length len) (:fill (if #f #f)))) n . rest))
((_ :acc ((var index) (expr (:length len) (:fill f))) next . rest)
;; I am truly sorry. Currently this relies on pushing a :break clause WITHOUT
;; the :when #t to ensure a subloop. It is the solution I would have used
;; otherwise as well, but I would have wished for it to be more elegant.
((_ :acc ((var index) (expr (:length len) (:fill f))) next
o n l a v c r fi ff ul uw ((ub ...) . ub-rest) uf . rest)
(next ((var (make-vector len f))) (next ((var (make-vector len f)))
((index 0 (begin (vector-set! var index expr) (+ index 1)))) ((index 0 (begin (vector-set! var index expr) (+ index 1))))
() ((= index len))
() ()
((var var)) ((var var))
o n l a v c r fi ff ul uw ((ub ... (= index len)) . ub-rest) uf
. rest)))) . rest))))
;;; Here starts generator clauses. ;;; Here starts generator clauses.