[gambit-list] Remote REPL

James Long longster at gmail.com
Tue Dec 4 01:36:45 EST 2007


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.html),
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))))


-- 
James Long
Coptix, Inc.
longster at gmail.com



More information about the Gambit-list mailing list