! Copyright (C) 2005 Chris Double. ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met: ! ! 1. Redistributions of source code must retain the above copyright notice, ! this list of conditions and the following disclaimer. ! ! 2. Redistributions in binary form must reproduce the above copyright notice, ! this list of conditions and the following disclaimer in the documentation ! and/or other materials provided with the distribution. ! ! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, ! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND ! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ! IN: coroutines USING: kernel lists generic ; TUPLE: coroutine resumecc exitcc ; : cocreate ( quot - co ) #! Create a new coroutine, which will execute the quotation #! when resumed. The quotation will have the coroutine #! on the stack and an initial value (received from coresume) #! when first resumed. ie. The quotation should have stack #! effect ( co value -- ). f f dup rot cons over set-coroutine-resumecc ; : coresume ( v co -- result ) #! Resume a coroutine with 'v' as the first item on the #! stack. The result placed on the stack is that of the #! topmost argument on the stack when coyield is called #! within the coroutine. [ over set-coroutine-exitcc coroutine-resumecc call ] callcc1 >r >r drop r> r> ; : coyield ( v co -- result ) #! Suspend a coroutine, leaving the value 'v' on the #! stack when control is passed to the 'coresume' caller. [ over set-coroutine-resumecc coroutine-exitcc call ] callcc1 >r >r drop r> r> ; : tree-each ( [ tree ] [ quotation ] -- ) #! Perform a preorder iteration of the tree, calling #! the quotation on each key. over [ over cons? [ >r uncons r> tuck >r >r tree-each r> r> tree-each ] [ call ] ifte ] [ 2drop ] ifte ; : test1 ( -- co ) [ swap [ over coyield 2drop ] tree-each f swap coyield ] cocreate ; : test2 ( -- co ) [ 1 over coyield drop 2 over coyield drop 3 over coyield ] cocreate ; USE: prettyprint USE: sequences test2 f swap coresume . f swap coresume . f swap coresume . drop : test3 ( -- co ) [ [ 1 2 3 ] [ over coyield drop ] each ] cocreate ; test3 f swap coresume . f swap coresume . f swap coresume . drop