Guile-2D needs a REPL that runs within its event loop without blocking
when reading user input. Mark Weaver has helped me add a new REPL
option, read-wrapper, that can be used by Guile-2D to push the read
operation into another thread while the main thread's event loop
continues to run as normal. This avoids the problem of thread safety
with the normal REPL server.

I think that this could be useful for other programs that run in an
event loop. Perhaps Emacsy?

- Dave Thompson
>From 57e11747ee43d42e09b5c80e545f12728c75fbf5 Mon Sep 17 00:00:00 2001
From: David Thompson <dthomps...@worcester.edu>
Date: Sun, 29 Sep 2013 18:01:31 -0400
Subject: [PATCH] Add read-wrapper REPL option.

* module/system/repl/common.scm (repl-default-options): Add read-wrapper
  REPL option.

* module/system/repl/repl.scm (prompting-meta-read): Use read-wrapper
  REPL option.
---
 module/system/repl/common.scm |  4 ++++
 module/system/repl/repl.scm   | 29 ++++++++++++++++-------------
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/module/system/repl/common.scm b/module/system/repl/common.scm
index 5da7c48..030d5de 100644
--- a/module/system/repl/common.scm
+++ b/module/system/repl/common.scm
@@ -125,6 +125,10 @@ See <http://www.gnu.org/licenses/lgpl.html>, for more details.")
                    ((not print) #f)
                    ((procedure? print) print)
                    (else (error "Invalid print procedure" print)))))
+     (read-wrapper
+      ,(lambda (thunk)
+         (thunk))
+      #f)
      (value-history
       ,(value-history-enabled?)
       ,(lambda (x)
diff --git a/module/system/repl/repl.scm b/module/system/repl/repl.scm
index 1649556..23c624a 100644
--- a/module/system/repl/repl.scm
+++ b/module/system/repl/repl.scm
@@ -108,19 +108,22 @@
 ;;
 ;; Catches read errors, returning *unspecified* in that case.
 (define (prompting-meta-read repl)
-  (catch #t
-    (lambda ()
-      (repl-reader (lambda () (repl-prompt repl))
-                   (meta-reader (repl-language repl) (current-module))))
-    (lambda (key . args)
-      (case key
-        ((quit)
-         (apply throw key args))
-        (else
-         (format (current-output-port) "While reading expression:\n")
-         (print-exception (current-output-port) #f key args)
-         (flush-all-input)
-         *unspecified*)))))
+  (let ((read-wrapper (repl-option-ref repl 'read-wrapper)))
+    (read-wrapper
+     (lambda ()
+       (catch #t
+         (lambda ()
+           (repl-reader (lambda () (repl-prompt repl))
+                        (meta-reader (repl-language repl) (current-module))))
+         (lambda (key . args)
+           (case key
+             ((quit)
+              (apply throw key args))
+             (else
+              (format (current-output-port) "While reading expression:\n")
+              (print-exception (current-output-port) #f key args)
+              (flush-all-input)
+              *unspecified*))))))))
 
 
 
-- 
1.8.4.rc3

Reply via email to