; TREE TRAVERSAL STUFF:
; Function that initiates a tree traveral.
; When done, handle an 'end of traversal' value to the controller.
(define (traverse-start tree controller-cont)
(let ((cont (traverse tree controller-cont)))
(cont (cons #f 'no-continuation)) ; end of traversal value, passed back to controller.
))
; Traverse tree, and send every node encountered to controller-cont.
; Returns a controller continuation.
(define (traverse tree controller-cont)
(cond ((empty-tree? tree) controller-cont)
((inner-node? tree)
(let ((new-controller-cont (traverse (left-tree tree) controller-cont)))
(let ((new-controller-cont (handle-node (root tree) new-controller-cont)))
(let ((new-controller-cont (traverse (right-tree tree) new-controller-cont)))
new-controller-cont))))
((leaf? tree)
(handle-node (root tree) controller-cont))
(else (error "Should not happen"))) )
; Function that handles nodes (internal as well as leafs).
; Send the node value n, together with a continuation, to controller-cont.
; In turn, receive a new controller continuation, which is returned by handle-node.
(define (handle-node n controller-cont)
(call-with-current-continuation
(lambda (here)
(controller-cont (cons n here)))))
| |
This is a recursive tree traversal function. As such it is relatively
straightforward. The tricky thing is to pass the controller continuation
around during the traversal. When a node has beeen handled, we get a
a new controller continuation which must be passed on
instead of 'the old one'.
This function is called for every node n we meet during the tree traversal.
We pass the node to the controller continuation. But we also capture a
traversal continuation - here - which we pass to the controller continuation. This
makes it possible to return to handle-node when the controller is done.
When the controller uses the 'here' continuation, the value passed by the
controller becomes the returned value of handle-node. The value received
from the controller is another continuation, which handle-node return to traverse.
traverse passes this continuation during ist recursive calls, until the next
node must be handled by handle-node. |