Chris Dean writes:
>
> How do I make a repl server that I can telnet into? The network
> plumbing is straight forward, but we would like a full repl with the sbcl
> debugger, etc. It's easy to make a naive version, but that only
> handles the basics.
>
> Presumably I use sb-impl::toplevel-repl, but I can't quite figure out
> how to do it.
>
> (In LispWorks I would use system::listener-top-level)
>
> For reference here is the naive repl loop I'm using:
>
> (defun run-remote-repl (socket)
> (let ((stream (sb-bsd-sockets:socket-make-stream socket
> :input t :output t
> :buffering :none)))
> (let ((*standard-output* stream))
> (iter (fresh-line)
> (princ "> ")
> (for expr :in-stream stream)
> (iter (for res :in (multiple-value-list (eval expr)))
> (prin1 res))))))
For a basic, standard REPL:
http://paste.lisp.org/display/18280
http://paste.lisp.org/display/57465
Now, you will need to also to bind more streams (*error-output*,
*standard-input*, etc):
(defmacro with-restricted-dynamic-environment (&body body)
`(with-output-to-string (*standard-output*)
(with-input-from-string (*standard-input* "")
(let* ((*print-circle* t)
(*print-readably* nil)
(*error-output* *standard-output*)
(*trace-output* *standard-output*)
(*query-io* (MAKE-TWO-WAY-STREAM *standard-input*
*standard-output*))
(*terminal-io* *query-io*)
(*package* (find-package "RCL-USER"))
(*read-eval* nil)
(-))
(restart-case (progn ,@body)
(abort () :report "Aborted")
(continue () :report "Continued")
(muffle-warning () :report "Warning muffled")
(store-value (value) :report "Value stored")
(use-value (value) :report "Value used"))))))
And finally you have to decide whether you want to do the debugging on
the server or on the client, and in the later case, include
*debug-io*, and perhaps add some *debugger-hook*.
--
__Pascal Bourguignon__ http://www.informatimago.com/
CONSUMER NOTICE: Because of the "uncertainty principle," it is
impossible for the consumer to simultaneously know both the precise
location and velocity of this product.
|