engine.scm 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees
  3. ; Christopher P. Haynes and Daniel P. Friedman.
  4. ; Engines build process abstractions.
  5. ; 1984 ACM Symposium on Lisp and Functional Programming, pages 18-24.
  6. ; This is incompatible with the threads package.
  7. ; ,open primitives interrupts
  8. (define interrupt/alarm (enum interrupt alarm))
  9. (define (run thunk interval when-done when-timeout)
  10. (let ((save (vector-ref interrupt-handlers interrupt/alarm)))
  11. (let ((finish
  12. (call-with-current-continuation
  13. (lambda (k)
  14. (vector-set! interrupt-handlers
  15. interrupt/alarm
  16. (lambda (tem ei)
  17. (set-enabled-interrupts! ei)
  18. (call-with-current-continuation
  19. (lambda (resume)
  20. (k (lambda ()
  21. (when-timeout (lambda ()
  22. (resume #f)))))))))
  23. (schedule-interrupt interval *exponent* #f)
  24. (call-with-values thunk
  25. (lambda vals
  26. (let ((time-remaining (schedule-interrupt 0 0 #f)))
  27. (lambda ()
  28. (apply when-done time-remaining vals)))))))))
  29. (vector-set! interrupt-handlers
  30. interrupt/alarm
  31. save)
  32. (finish))))
  33. (define *exponent* -3)
  34. (define-syntax engine
  35. (syntax-rules ()
  36. ((engine ?E) (%engine (lambda () ?E)))))
  37. (define (%engine thunk)
  38. (lambda (ticks done out)
  39. (run thunk
  40. ticks
  41. (lambda (ticks val)
  42. (done val ticks))
  43. (lambda (new-thunk)
  44. (out (%engine new-thunk))))))
  45. ; Example from the LFP '84 paper (verbatim)
  46. ;(define-syntax rec
  47. ; (syntax-rules () ((rec ?X ?E) (letrec ((?X ?E)) ?X))))
  48. ;
  49. ;(define complete
  50. ; (lambda (eng)
  51. ; ((rec loop
  52. ; (lambda (eng count)
  53. ; (eng 1000
  54. ; (lambda (val ticks-left)
  55. ; (cons val
  56. ; (+ (- 1000 ticks-left)
  57. ; count)))
  58. ; (lambda (eng)
  59. ; (loop eng (+ count 1000))))))
  60. ; eng 0)))