]> code.delx.au - gnu-emacs-elpa/blobdiff - packages/stream/stream.el
update stream.el to the latest version
[gnu-emacs-elpa] / packages / stream / stream.el
index 6bbf99fce596ce1d5cb98b306220cf111e34f76b..567a9e354e8fc147a89941b1f2b34fff93481d62 100644 (file)
@@ -4,7 +4,7 @@
 
 ;; Author: Nicolas Petton <nicolas@petton.fr>
 ;; Keywords: stream, laziness, sequences
-;; Version: 2.0.2
+;; Version: 2.1.0
 ;; Package-Requires: ((emacs "25"))
 ;; Package: stream
 
@@ -113,14 +113,24 @@ The sequence starts at POS if non-nil, 1 otherwise."
            (char-after (point)))))
      (stream buffer (1+ pos)))))
 
+(declare-function iter-next "generator")
+
+(defun stream-from-iterator (iterator)
+  "Return a stream generating new elements through ITERATOR.
+ITERATOR is an iterator object in terms of the \"generator\"
+package."
+  (stream-make
+   (condition-case nil
+       (cons (iter-next iterator) (stream-from-iterator iterator))
+     (iter-end-of-sequence nil))))
+
 (defun stream-regexp (buffer regexp)
   (stream-make
    (let (match)
      (with-current-buffer buffer
        (setq match (re-search-forward regexp nil t)))
      (when match
-       (cons (match-data) (stream-regexp buffer regexp))
-       nil))))
+       (cons (match-data) (stream-regexp buffer regexp))))))
 
 (defun stream-range (&optional start end step)
   "Return a stream of the integers from START to END, stepping by STEP.
@@ -157,6 +167,30 @@ range is infinite."
   "Return a stream of all but the first element of STREAM."
   (or (cdr (thunk-force (cadr stream)))
       (stream-empty)))
+
+(defun stream-append (&rest streams)
+  "Concatenate the STREAMS.
+Requesting elements from the resulting stream will request the
+elements in the STREAMS in order."
+  (if (null streams)
+      (stream-empty)
+    (stream-make
+     (let ((first (pop streams)))
+       (while (and (stream-empty-p first) streams)
+         (setq first (pop streams)))
+       (if (stream-empty-p first)
+           nil
+         (cons (stream-first first)
+               (if streams (apply #'stream-append (stream-rest first) streams)
+                 (stream-rest first))))))))
+
+(defmacro stream-pop (stream)
+  "Return the first element of STREAM and set the value of STREAM to its rest."
+  (unless (symbolp stream)
+    (error "STREAM must be a symbol"))
+  `(prog1
+       (stream-first ,stream)
+     (setq ,stream (stream-rest ,stream))))
 \f
 
 ;;; cl-generic support for streams
@@ -177,7 +211,7 @@ range is infinite."
 
 ;;; Implementation of seq.el generic functions
 
-(cl-defmethod seq-p ((_stream stream))
+(cl-defmethod seqp ((_stream stream))
   t)
 
 (cl-defmethod seq-elt ((stream stream) n)
@@ -257,12 +291,9 @@ This function will eagerly consume the entire stream."
 The elements of the produced stream are the results of the
 applications of FUNCTION on each element of STREAM in succession."
   (stream-make
-   ;; Avoid using `stream-empty-p', as it will consume the first element of the
-   ;; stream before iterating over the stream.
-   (let ((first (stream-first stream)))
-     (when first
-       (cons (funcall function first)
-             (seq-map function (stream-rest stream)))))))
+   (when (not (stream-empty-p stream))
+     (cons (funcall function (stream-first stream))
+           (seq-map function (stream-rest stream))))))
 
 (cl-defmethod seq-do (function (stream stream))
   "Evaluate FUNCTION for each element of STREAM eagerly, and return nil.