;;;; repl.scm - friendlier repl with line editing and signal handling ;; ;; Copyright (c) 2010 Alex Shinn. All rights reserved. ;; BSD-style license: http://synthcode.com/license.txt (define-syntax handle-exceptions (syntax-rules () ((handle-exceptions exn handler expr) (call-with-current-continuation (lambda (return) (with-exception-handler (lambda (exn) (return handler)) (lambda () expr))))))) (define (with-signal-handler sig handler thunk) (let ((old-handler #f)) (dynamic-wind (lambda () (set! old-handler (set-signal-action! sig handler))) thunk (lambda () (set-signal-action! sig old-handler))))) (define (run-repl module env) (let ((line (edit-line (if module (string-append (symbol->string module) "> ") "> ")))) (cond ((or (not line) (eof-object? line))) ((equal? line "") (run-repl module env)) (else (handle-exceptions exn (print-exception exn (current-error-port)) (let* ((expr (call-with-input-string line read)) (thread (make-thread (lambda () (let ((res (eval expr env))) (if (not (eq? res (if #f #f))) (write res))))))) (with-signal-handler signal/interrupt (lambda (n) (thread-terminate! thread)) (lambda () (thread-start! thread) (thread-join! thread))))) (newline) (run-repl module env))))) (define (repl) (run-repl #f (interaction-environment)))