I am writing some code that enables Gambit's REPL to be used remotely on any Termite node using remote (or process) ports. I'm am sure others have done this, but I haven't been able to find any working code.
It's working very well. Right now, you just fire up a normal gsi session, find your node, and say `(make-repl the-node)` and you have a REPL which is being evaluated on that node. I have attached the code to the bottom of this email. It is the result of studying the web-repl example and another post on this list about non-repl debugging (https://webmail.iro.umontreal.ca/pipermail/gambit-list/2007-August/001670.ht...), and eating some chocolate chip cookies too.
The main problem, however, is that debugging isn't working. When any kind of error happens, it just hangs and the repl worker doesn't give me anything. Usually it opens up a new sub-repl, but I'm not exactly sure how this is different than the initial repl call - and _repl.scm is quite a beast! The strange thing is that it works in the web-repl and probably the other one I previously mentioned. The biggest difference may be that the repl worker here isn't running on the primordial thread.
Thanks!
(The 'proc-port' stuff is the same as any ports, except it operates on the termite remote ports. Eventually I'll override the standard input/output/error ports and use these for everything. It looks like Termite did that at one point but for some reason all of that is commented out...)
;;;;; --- REMOTE REPL ---
(define (start-repl-worker-input-output repl-input-proc-port repl-output-proc-port repl-worker-port) (spawn (lambda () (let loop1 () (let loop2 ((line '())) (let ((c (proc-port-read-char repl-input-proc-port))) (if (char? c) (cond ((or (char=? c #\newline) (char=? c #\return)) (display (list->string (reverse line)) repl-worker-port) (write-char #\return repl-worker-port) (write-char #\linefeed repl-worker-port) (force-output repl-worker-port) (loop1)) (else (loop2 (cons c line))))))))))
(spawn (lambda () (let loop1 () (let ((c (read-char repl-worker-port))) (proc-port-write-char c repl-output-proc-port) (loop1))))))
(define (make-repl node) (let ((op (current-output-proc-port)) (ip (current-input-proc-port)) (repl (self))) (remote-spawn node (lambda () (receive (pipe1 pipe2) (open-string-pipe) (display "Starting repl io...\n") (start-repl-worker-input-output ip op pipe1) (display "Setting repl channel...\n") (set! ##thread-make-repl-channel (lambda () (##make-repl-channel-ports pipe2 pipe2))) (display "Firing up repl...\n") (##repl-debug-main))))) (?? (lambda (o) (eq? o 'quit))))