From 89dfe9ab35890371300014c34d5ae88696bb78ce Mon Sep 17 00:00:00 2001 From: Alex Shinn Date: Mon, 16 Jul 2012 17:46:13 +0900 Subject: [PATCH] Patch from Alan Watson for nicer handling of multiple value results in the repl, and also evaling multiple sexps on the same input line. --- lib/chibi/repl.scm | 48 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/lib/chibi/repl.scm b/lib/chibi/repl.scm index 35548a79..3ee689da 100644 --- a/lib/chibi/repl.scm +++ b/lib/chibi/repl.scm @@ -104,6 +104,13 @@ ;;> @item{@scheme|{@exit}| - exit the REPL} ;;> ] +(define (read/ss/all port) + (let loop ((l '())) + (let ((x (read/ss port))) + (if (eof-object? x) + (reverse l) + (loop (cons x l)))))) + (define (repl . o) (let* ((in (cond ((memq 'in: o) => cadr) (else (current-input-port)))) (out (cond ((memq 'out: o) => cadr) (else (current-output-port)))) @@ -221,15 +228,16 @@ ;; The outer guard in the parent thread catches read ;; errors and errors in the repl logic itself. (guard (exn (else (print-exception exn (current-error-port)))) - (let* ((expr (call-with-input-string line - (lambda (in2) - ;; Ugly wrapper to account for the - ;; implicit state mutation implied by - ;; the #!fold-case read syntax. - (set-port-fold-case! in2 (port-fold-case? in)) - (let ((expr (read/ss in2))) - (set-port-fold-case! in (port-fold-case? in2)) - expr)))) + (let* ((expr-list + (call-with-input-string line + (lambda (in2) + ;; Ugly wrapper to account for the + ;; implicit state mutation implied by + ;; the #!fold-case read syntax. + (set-port-fold-case! in2 (port-fold-case? in)) + (let ((expr-list (read/ss/all in2))) + (set-port-fold-case! in (port-fold-case? in2)) + expr-list)))) (thread (make-thread (lambda () @@ -238,11 +246,23 @@ (guard (exn (else (print-exception exn (current-output-port)))) - (let ((res (eval expr env))) - (cond - ((not (eq? res (if #f #f))) - (write/ss res out) - (newline out))))))))) + (for-each + (lambda (expr) + (call-with-values + (lambda () + (eval (list 'begin expr) env)) + (lambda res-list + (cond + ((not (or (null? res-list) + (equal? res-list (list (if #f #f))))) + (write/ss (car res-list) out) + (for-each + (lambda (res) + (write-char #\space out) + (write/ss res out)) + (cdr res-list)) + (newline out)))))) + expr-list)))))) ;; If an interrupt occurs while the child thread is ;; still running, terminate it, otherwise wait for it ;; to complete.