remote.scm 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. ; Copyright (c) 1993-2007 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; This is a small mock-up of the Cornell mobile robot system.
  3. ; It is not intended as a remote procedure call mechanism.
  4. ; ,load-config =scheme48/misc/packages.scm
  5. ; ,open remote
  6. ; To start a server, do
  7. ; (define sock (make-socket))
  8. ; (serve sock)
  9. ; To start a client, do
  10. ; (remote-repl "hostname" <number>)
  11. ; where <number> is the number displayed by the server when it starts up.
  12. ; Server side
  13. (define (note-structure-locations! s)
  14. (define (recur name env trail)
  15. (let ((b (generic-lookup env name)))
  16. (if (binding? b)
  17. (begin
  18. (note-location! (binding-place b))
  19. (let ((t (binding-static b)))
  20. (if (and (transform? t) (not (member t trail)))
  21. (let ((trail (cons t trail))
  22. (env (transform-env t)))
  23. (for-each (lambda (name)
  24. (recur name env trail))
  25. (transform-aux-names (binding-static b))))))))))
  26. (for-each-declaration (lambda (name package-name type)
  27. (recur package-name s '()))
  28. (structure-interface s)))
  29. (note-structure-locations! scheme-level-2)
  30. (define (make-socket)
  31. (call-with-values socket-server cons))
  32. (define (serve sock)
  33. (let ((port-number (car sock))
  34. (accept (cdr sock)))
  35. (display "Port number is ")
  36. (write port-number)
  37. (newline)
  38. (let ((in #f)
  39. (out #f))
  40. (dynamic-wind (lambda ()
  41. (call-with-values accept
  42. (lambda (i-port o-port)
  43. (display "Open") (newline)
  44. (set! in i-port)
  45. (set! out o-port))))
  46. (lambda ()
  47. (start-server in out))
  48. (lambda ()
  49. (if in (close-input-port in))
  50. (if out (close-output-port out)))))))
  51. (define (start-server in out)
  52. (let loop ()
  53. (let ((message (restore-carefully in)))
  54. (case (car message)
  55. ((run)
  56. (dump (run-carefully (cdr message))
  57. (lambda (c) (write-char c out))
  58. -1)
  59. (force-output out)
  60. (loop))
  61. ((eof) (cdr message))
  62. (else (error "unrecognized message" message))))))
  63. (define (run-carefully template)
  64. (call-with-current-continuation
  65. (lambda (escape)
  66. (with-handler
  67. (lambda (c punt)
  68. (if (error? c)
  69. (escape (cons 'condition c))
  70. (punt)))
  71. (lambda ()
  72. (call-with-values (lambda ()
  73. (invoke-closure (make-closure template #f)))
  74. (lambda vals
  75. (cons 'values vals))))))))
  76. ; Client side
  77. (define (make-remote-eval in out)
  78. (lambda (form p)
  79. (compile-and-run-forms (list form)
  80. p
  81. #f
  82. (lambda (template)
  83. (dump (cons 'run template)
  84. (lambda (c) (write-char c out))
  85. -1)
  86. (force-output out)
  87. (let ((reply (restore-carefully in)))
  88. (case (car reply)
  89. ((values)
  90. (apply values (cdr reply)))
  91. ((condition)
  92. (signal-condition (cdr reply)))
  93. ((eof)
  94. (error "eof on connection")))))
  95. #f)))
  96. (define (make-remote-package in out opens id)
  97. (let ((p (make-simple-package opens
  98. #t
  99. (reflective-tower
  100. (package->environment (interaction-environment)))
  101. id)))
  102. (set-package-evaluator! p (make-remote-eval in out))
  103. p))
  104. (define (remote-repl host-name socket-port-number)
  105. (let ((in #f) (out #f))
  106. (dynamic-wind
  107. (lambda ()
  108. (call-with-values (lambda ()
  109. (socket-client host-name socket-port-number))
  110. (lambda (i-port o-port)
  111. (set! in i-port)
  112. (set! out o-port))))
  113. (lambda ()
  114. (with-interaction-environment (make-remote-package in out (list scheme) 'remote)
  115. (lambda () (command-loop list #f))))
  116. (lambda ()
  117. (if in (close-input-port in))
  118. (if out (close-output-port out))))))
  119. ; Common auxiliary
  120. (define (restore-carefully in)
  121. (call-with-current-continuation
  122. (lambda (exit)
  123. (restore (lambda ()
  124. (let ((c (read-char in)))
  125. (if (eof-object? c)
  126. (exit (cons 'eof c))
  127. c)))))))