diff --git a/forge/forge.lisp b/forge/forge.lisp index 8c4dc3c..0d49906 100644 --- a/forge/forge.lisp +++ b/forge/forge.lisp @@ -85,7 +85,11 @@ (defun repl () (do ((input (read-line) (read-line))) ((string= input "q") (stack *forge-env*)) - (exec-string input))) + (handler-bind + ((end-of-file + (lambda (c) + (invoke-restart 'iter:try-with-more-input (read-line))))) + (exec-string input)))) (defun exec-list (lst) (let ((*input* (iter:list-iterator lst))) diff --git a/util/iter.lisp b/util/iter.lisp index d4dee88..324f98b 100644 --- a/util/iter.lisp +++ b/util/iter.lisp @@ -6,7 +6,8 @@ (defpackage :scopes/util/iter (:use :common-lisp) (:export #:stop #:next #:value #:next-value #:process - #:list-iterator #:string-iterator #:stream-iterator)) + #:list-iterator #:string-iterator #:stream-iterator + #:try-with-more-input)) (in-package :scopes/util/iter) @@ -56,7 +57,7 @@ ;;;; string iterator implementation (defclass string-iterator (iterator) - ((data :reader data :initarg :data :initform "") + ((data :accessor data :initarg :data :initform "") (curpos :accessor curpos :initform 0) (value :accessor value :initform nil))) @@ -64,14 +65,18 @@ (make-instance 'string-iterator :data s)) (defmethod next ((it string-iterator)) - (let ((pos (curpos it))) - (if (< pos (length (data it))) - (multiple-value-bind (val newpos) - (read-from-string (data it) nil nil :start pos) - (setf (curpos it) newpos - (value it) val) - nil) - t))) + (restart-case + (let ((pos (curpos it))) + (if (< pos (length (data it))) + (multiple-value-bind (val newpos) + (read-from-string (data it) nil nil :start pos) + (setf (curpos it) newpos + (value it) val) + nil) + t)) + (try-with-more-input (more) + (setf (data it) (str:join " " (list (data it) more))) + (next it)))) ;;;; stream iterator implementation