reroot.scm 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. ; Copyright (c) 1993-2007 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; A state space is a tree with the state at the root. Each node other
  3. ; than the root is a triple <before, after, parent>, represented in
  4. ; this implementation as a structure ((before . after) . parent).
  5. ; Moving from one state to another means re-rooting the tree by pointer
  6. ; reversal.
  7. (define *here* (list #f))
  8. (define original-cwcc call-with-current-continuation)
  9. (define (call-with-current-continuation proc)
  10. (let ((here *here*))
  11. (original-cwcc (lambda (cont)
  12. (proc (lambda results
  13. (reroot! here)
  14. (apply cont results)))))))
  15. (define (dynamic-wind before during after)
  16. (let ((here *here*))
  17. (reroot! (cons (cons before after) here))
  18. (call-with-values during
  19. (lambda results
  20. (reroot! here)
  21. (apply values results)))))
  22. (define (reroot! there)
  23. (if (not (eq? *here* there))
  24. (begin (reroot! (cdr there))
  25. (let ((before (caar there))
  26. (after (cdar there)))
  27. (set-car! *here* (cons after before))
  28. (set-cdr! *here* there)
  29. (set-car! there #f)
  30. (set-cdr! there '())
  31. (set! *here* there)
  32. (before)))))
  33. ; -----
  34. ;
  35. ;(define r #f) (define s #f) (define (p x) (write x) (newline))
  36. ;(define (tst)
  37. ; (set! r *here*)
  38. ; (set! s (cons (cons (lambda () (p 'in)) (lambda () (p 'out))) *here*))
  39. ; (reroot! s))
  40. ;
  41. ;
  42. ;(define (check) ;Algorithm invariants
  43. ; (if (not (null? (cdr *here*)))
  44. ; (error "confusion #1"))
  45. ; (if (car *here*)
  46. ; (error "confusion #2")))