;;;;
;;;;
;;;; 190.stk         -- Implementation of SRFI-190
;;;;
;;;; Copyright © 2020-2022 Erick Gallesio - I3S-CNRS/Polytech Nice-Sophia <eg@unice.fr>
;;;;
;;;;
;;;; This program is free software; you can redistribute it and/or modify
;;;; it under the terms of the GNU General Public License as published by
;;;; the Free Software Foundation; either version 2 of the License, or
;;;; (at your option) any later version.
;;;;
;;;; This program is distributed in the hope that it will be useful,
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;;; GNU General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU General Public License
;;;; along with this program; if not, write to the Free Software
;;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
;;;; USA.
;;;;
;;;;           Author: Erick Gallesio [eg@unice.fr]
;;;;    Creation date: 18-Jun-2020 15:32
;;;;


(define-module srfi/190
  (import (srfi 158))
  (export yield coroutine-generator define-coroutine-generator)

  (define (yield value)
    (error 'yield "cannot be used outside coroutine generator"))

  (define-macro (coroutine-generator . body)
    `(make-coroutine-generator (lambda (yield) ,@body)))

  (define-macro (define-coroutine-generator proto . body)
    `(define ,proto (coroutine-generator ,@body))))

#|
Examples:
(define g1 (coroutine-generator
           (do ((i 0 (+ i 1)))
               ((<= 5 i))
             (yield i))))

(define g2 (let ((yield-square (lambda (yield i) (yield (* i i)))))
            (coroutine-generator
             (do ((i 0 (+ i 1)))
                 ((<= 5 i))
               (yield-square yield i)))))

(define-coroutine-generator (g3 n)
  (do ((i 0 (+ i 1)))
      ((<= n i))
    (yield i)))

(print (generator->list g1))            ⊢ (0 1 2 3 4)
(print (generator->list g2))            ⊢ (0 1 4 9 16)
(print (generator->list (g3 7)))        ⊢ (0 1 2 3 4 5 6)
|#

(provide "srfi/190")
