diff --git a/basic.lisp b/basic.lisp index 77d773e..43942d2 100644 --- a/basic.lisp +++ b/basic.lisp @@ -9,21 +9,20 @@ ;;; lazy results (defclass parse-result () - ((top-results :initform nil :initarg :top-results :accessor top-results-of) - (promise-list :initform nil :initarg :promise-list :accessor promise-list-of))) + ((current-result :initform nil :initarg :top-results :accessor current-result-of) + (continuation :initform (constantly nil) :initarg :promise-list :accessor continuation-of))) + +(defun current-result (parser-result) + (with-accessors ((current-result current-result-of) + (continuation continuation-of)) parse-result + (if current-result + current-result + (setf current-result (funcall continuation))))) (defun next-result (parse-result) - (with-accessors ((top-results top-results-of) - (promise-list promise-list-of)) parse-result - (cond ((and (null top-results) - (null promise-list)) - nil) - ((and (null top-results) - promise-list) - (setf top-results (force (pop promise-list))) - (next-result parse-result)) - (top-results - (pop top-results))))) + (with-accessors ((current-result current-result-of) + (continuation continuation-of)) parse-result + (setf current-result (funcall continuation)))) (defun gather-results (parse-result) (iter (for result next (next-result parse-result)) diff --git a/primitives.lisp b/primitives.lisp index e517ee8..5993bcf 100644 --- a/primitives.lisp +++ b/primitives.lisp @@ -54,8 +54,8 @@ (delay #'(lambda (inp) (make-instance 'parse-result - :top-results (list (make-instance 'parser-possibility - :tree v :suffix inp)))))) + :current-result (make-instance 'parser-possibility + :tree v :suffix inp))))) (def-cached-parser zero "Primitive parser: parsing failure" @@ -68,8 +68,8 @@ #'(lambda (inp) (if inp (make-instance 'parse-result - :top-results (list (make-instance 'parser-possibility - :tree (car inp) :suffix (cdr inp)))) + :current-result (make-instance 'parser-possibility + :tree (car inp) :suffix (cdr inp))) (make-instance 'parse-result))))) (declaim (inline sat)) @@ -83,7 +83,10 @@ (defun force? (parser) "Parser modifier: fully realize result from parser" (delay - #'(lambda (inp) - (let ((result (funcall parser inp))) - (make-instance 'parse-result - :top-results (gather-results result)))))) + #'(lambda (inp) + (let ((result (funcall parser inp))) + (let ((all-results (gather-results result))) + (make-instance 'parse-result + :current-result (car all-results) + :continuation #'(lambda () + (pop all-results))))))))