#lang scheme/base
(require
scheme/control )
(provide repl
repl-command-hook
repl-break-hook)
(define repl-command-hook
(make-parameter
(lambda (interpret str)
(interpret str)
(interpret "OK"))))
(define (repl-break-exit command str)
(printf "\nCommand \"~a\" interrupted.\nTrying cold restart...\n" str)
(command "cold")
(let ((ok (with-timeout 1 (lambda () (command "OK")))))
(unless ok (printf "Timed out.\n"))
ok))
(define (repl-break command str)
(printf "\nCommand \"~a\" interrupted.\n" str)
#t)
(define repl-break-hook
(make-parameter repl-break))
(define (with-timeout sec thunk)
(define retv #t)
(define (watchdog)
(sleep sec)
(set! retv #f))
(let ((ok (thread thunk))
(timeout (thread watchdog)))
(sync ok timeout)
(kill-thread ok)
(kill-thread timeout)
retv))
(define (repl command)
(define (_read-line)
(with-handlers
((exn:break? (lambda _ "")))
(read-line)))
(define (_command cmd)
(prompt
(with-handlers
((exn:break?
(lambda _ ((repl-break-hook) command cmd))))
((repl-command-hook) command cmd)
#t)))
(define (console)
(let ((cmd (_read-line)))
(unless (eof-object? cmd)
(when (_command cmd)
(console)))))
(with-handlers ((void void))
(file-stream-buffer-mode (current-output-port) 'none))
(printf "Press ctrl-D to quit.\n")
(when (_command "") (console))
(printf "Dada.\n")
)