87 lines
2.2 KiB
Common Lisp
87 lines
2.2 KiB
Common Lisp
;;;; cl-scopes/util/iter
|
|
|
|
;;;; iterators, queues, and other sequentially accessible stuff
|
|
;;;; producing items (objects) like: numbers, strings, symbols, lists, ...
|
|
|
|
(defpackage :scopes/util/iter
|
|
(:use :common-lisp)
|
|
(:export #:stop #:next #:value #:next-value #:process
|
|
#:list-iterator #:string-iterator #:stream-iterator))
|
|
|
|
(in-package :scopes/util/iter)
|
|
|
|
;;;; iterators
|
|
|
|
(defclass iterator ()
|
|
((stopped :accessor stopped :initform nil)))
|
|
|
|
(defgeneric next (it))
|
|
(defgeneric value (it))
|
|
|
|
(defgeneric next-value (it)
|
|
(:method ((it iterator))
|
|
(next it)
|
|
(value it)))
|
|
|
|
(defgeneric stop (it)
|
|
(:method ((it iterator))
|
|
(setf (stopped it) t)))
|
|
|
|
(defgeneric process (it fn)
|
|
(:method ((it iterator) fn)
|
|
(do ((eoi (next it) (or (stopped it) (next it))))
|
|
(eoi)
|
|
(funcall fn (value it)))
|
|
(setf (stopped it) nil)))
|
|
|
|
;;;; list iterator implementation
|
|
|
|
(defclass list-iterator (iterator)
|
|
((data :reader data :initarg :data :initform nil)
|
|
(cur :accessor cur)))
|
|
|
|
(defun list-iterator (data)
|
|
(make-instance 'list-iterator :data data))
|
|
|
|
(defmethod initialize-instance :after ((it list-iterator) &key)
|
|
(setf (cur it) (cons nil (data it))))
|
|
|
|
(defmethod next ((it list-iterator))
|
|
(pop (cur it))
|
|
(null (cur it)))
|
|
|
|
(defmethod value ((it list-iterator))
|
|
(car (cur it)))
|
|
|
|
;;;; string iterator implementation
|
|
|
|
(defclass string-iterator (iterator)
|
|
((data :reader data :initarg :data :initform "")
|
|
(curpos :accessor curpos :initform 0)
|
|
(value :accessor value :initform nil)))
|
|
|
|
(defun string-iterator (s)
|
|
(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)))
|
|
|
|
;;;; stream iterator implementation
|
|
|
|
(defclass stream-iterator (iterator)
|
|
((data :reader data :initarg :data :initform "")
|
|
(value :accessor value :initform nil)))
|
|
|
|
(defun stream-iterator (s)
|
|
(make-instance 'stream-iterator :data s))
|
|
|
|
(defmethod next ((it stream-iterator))
|
|
(setf (value it) (read (data it) nil nil))
|
|
(eql (value it) nil))
|