#lang scheme/base
(require scheme/contract
(file "base.ss"))
(define-struct stage (name body)
#:transparent
#:property prop:procedure
(struct-field-index body))
(define-syntax define-stage
(syntax-rules ()
[(define-stage (name continue args ...)
expr ...)
(define name
(make-stage
'name
(lambda (continue args ...)
expr ...)))]
[(define-stage (name continue args ... . rest)
expr ...)
(define name
(make-stage
'name
(lambda (continue args ... . rest)
expr ...)))]))
(define (call-with-pipeline pipeline procedure . args)
(define (pipe pipeline . args)
(if (null? pipeline)
(apply procedure args)
(let ([stage (car pipeline)]
[success
(lambda args
(apply pipe (cdr pipeline) args))])
(apply stage (cons success args)))))
(apply pipe pipeline args))
(define (find-stage pipeline name)
(ormap (lambda (stage)
(and (eq? (stage-name stage) name) stage))
pipeline))
(provide define-stage)
(provide/contract
[struct stage ([name symbol?] [body procedure?])]
[call-with-pipeline (->* ((listof procedure?) procedure?) () #:rest any/c any)]
[find-stage (-> (listof stage?) symbol? (or/c stage? false/c))])