From 60cee400514430e72dcdb193380b38632c36975a Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Mon, 9 Sep 2024 19:52:19 +0200 Subject: [PATCH] util/iter: allow stopping an iterator by setting its stop slot to t --- util/iter.lisp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/util/iter.lisp b/util/iter.lisp index a3dd6f1..785f130 100644 --- a/util/iter.lisp +++ b/util/iter.lisp @@ -5,36 +5,38 @@ (defpackage :scopes/util/iter (:use :common-lisp) - (:export #:next #:value #:next-value #:process + (:export #:stop #:next #:value #:next-value #:process #:list-iterator)) (in-package :scopes/util/iter) ;;;; iterators -(defclass abstract-iterator () ()) +(defclass iterator () + ((stop :accessor stop :initform nil))) (defgeneric next (it)) (defgeneric value (it)) (defgeneric next-value (it) - (:method ((it abstract-iterator)) + (:method ((it iterator)) (next it) (value it))) -(defgeneric process (it fn &optional stop) - (:method ((it abstract-iterator) fn &optional (stop (constantly nil))) +(defgeneric process (it fn) + (:method ((it iterator) fn) (do ((eoi (next it) (next it))) - ((or eoi (funcall stop))) - (funcall fn (value it))))) + ((or eoi (stop it))) + (funcall fn (value it))) + (setf (stop it) nil))) ;;;; list iterator implementation -(defclass list-iterator (abstract-iterator) +(defclass list-iterator (iterator) ((data :reader data :initarg :data :initform nil) (cur :accessor cur))) -(defmethod initialize-instance :after ((it list-iterator) &key &allow-other-keys) +(defmethod initialize-instance :after ((it list-iterator) &key) (setf (cur it) (cons nil (data it)))) (defmethod next ((it list-iterator))