# load-coroutine generator x :: (1 2 3) { . yield } consume ; ' x start x x x x x x .n # this is clearly because of consume: # it messes with the abort stack... # these should use only return stack recursion: # move the control stuff to RS and leave the data stack free # for unbalanced words to mess up # in addition to that, they should not use the abort stack, which woul # allow them to be used in coroutines (or anything that survives # context switches) # SEMANTICS: both are serial: they can use the data stack for # accumulation: if map/consume are called with ( ..stuff.. lst xt ), # the corresponding xt is called with ( ..stuf.. el ) # ( ..stuff.. ptr xt -- ) : _@map .S over if >r dup @ swap # ( ..stuff.. in-el ptr ) ( xt ) r swap >r # ( ..stuff.. in-el xt ) ( ptr xt ) execute # ( ..stuff.. out-el ) ( ptr xt ) r ! # ( ..stuff.. ) ( ptr xt ) r> follow r> # ( ..stuff.. next-ptr xt ) pass _@map then 2drop ; : _@consume .S over if >r dup @ swap # ( ..stuff.. in-el ptr ) ( xt ) r swap >r # ( ..stuff.. in-el xt ) ( ptr xt ) execute # ( ..stuff.. out-el ) ( ptr xt ) r> follow r> # ( ..stuff.. next-ptr xt ) pass _@consume then 2drop ; : _map swap >r rsp head swap _@map r> ; : _consume swap >r rsp head swap _@consume rdrop ;