chex lets you run a REPL in a separate Lisp instance and fully communicate with it over streams.
It uses uiop:launch-program
to asynchronously launch a program and get its
i/o over streams.
chex is available on Ultralisp.
Assuming you have added Ultralisp to your quicklisp, just run
(ql:quickload :chex)
You may need to run (ql:update-dist "ultralisp")
to get the latest version of chex.
or if Ultralisp is down you can use quicklisp's local-projects mechanism:
cd ~/quicklisp/local-projects
git clone https://github.com/oliverdelancey/chex.git
chex has been tested with SBCL, CCL, and ABCL, and should be either implementation-independent or trivially easy to add compatibility. Hit up Issues if there's an implementation that's not working.
chex has been tested on Windows 11 and Linux (Fedora Workstation), so it should also work on Windows 10 and other Linux distributions.
All functions/methods/classes have docstrings, so describe
is your friend.
See start.lisp for an example.
(defparameter *repl*
(chex:start-repl
"sbcl"
(asdf:system-relative-pathname "chex" "child/chex-init.lisp")))
chex-init.lisp redirects relevant streams in the child
process to allow reading/writing to all standard streams
through *standard-output*
and *standard-input*
. It also adds :chex-child
to *features*
.
It is provided as an option so you can supply your own file if needed, to do whatever setup you need in the child process.
(chex:read-strings-from-repl *repl*)
This will return 2 values: the output of IO-STREAM
, the main i/o stream, and
the output of ERROR-STREAM
, the error output stream.
(chex:send-string-to-repl str *repl*)
This should input to any input stream in the child process, including the
interactive debugger (*debug-io*
) and queries (*query-io*
), as long as they
have been properly redirected with chex-init.lisp
.
(chex:close-repl *repl*)
This should close the process and all related streams. Returns T
if the close
was successful, NIL
otherwise.