chibi-scheme/lib/chibi/repl.scm
2011-03-28 23:04:45 +09:00

55 lines
1.9 KiB
Scheme

;;;; repl.scm - friendlier repl with line editing and signal handling
;;
;; Copyright (c) 2011 Alex Shinn. All rights reserved.
;; BSD-style license: http://synthcode.com/license.txt
(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 (buffer-complete-sexp? buf)
(guard (exn (else #f))
(call-with-input-string (buffer->string buf) read)
#t))
(define (run-repl module env . o)
(let ((history (make-history)))
(let lp ((module module) (env env))
(let ((line
(edit-line
(string-append (if module (symbol->string module) "") "> ")
'history: history
'complete?: buffer-complete-sexp?)))
(cond
((or (not line) (eof-object? line)))
((equal? line "") (lp module env))
(else
(history-commit! history line)
(guard
(exn
(else (print-exception exn (current-error-port))))
(let* ((expr (call-with-input-string line read/ss))
(thread
(make-thread
(lambda ()
(guard
(exn
(else (print-exception exn (current-error-port))))
(let ((res (eval expr env)))
(cond
((not (eq? res (if #f #f)))
(write/ss res)
(newline)))))))))
(with-signal-handler
signal/interrupt
(lambda (n)
(display "Interrupt\n" (current-error-port))
(thread-terminate! thread))
(lambda () (thread-join! (thread-start! thread))))))
(lp module env)))))))
(define (repl)
(run-repl #f (interaction-environment)))