Skip to content

Instantly share code, notes, and snippets.

@hraban
Forked from ryepup/coroutines in lisp
Created May 29, 2011 12:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hraban/997717 to your computer and use it in GitHub Desktop.
Save hraban/997717 to your computer and use it in GitHub Desktop.
lisp coroutines using chanl (threads)
(defmacro make-coroutine ((&key (coroutine-done-value :done)) &body body)
(alexandria:with-gensyms ((thrfn "thread body")
(c "channel"))
`(let* ((,c (make-instance 'chanl:bounded-channel))
(,thrfn (lambda ()
(flet ((yield (&optional n)
(chanl:send ,c n)))
,@body
(yield ,coroutine-done-value)))))
(let ((alive-p T) val thr)
(lambda ()
(unless thr
(setf thr (chanl:pcall ,thrfn :name "coroutine")))
(when alive-p
(setf val (chanl:recv ,c))
(when (eq ,coroutine-done-value val)
(setf alive-p nil)))
val)))))
(defun coroutine-test ()
(let ((cor (make-coroutine (:coroutine-done-value :done)
(yield 1)
(yield)
(yield 4))))
(assert (eql 1 (funcall cor)) )
(assert (null (funcall cor)))
(assert (eql 4 (funcall cor)))
(assert (eql :done (funcall cor)))
(assert (eql :done (funcall cor)))))
@hraban
Copy link
Author

hraban commented May 29, 2011

I changed the filename to end in .lisp for syntax highlighting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment