cl-rw

Layered streams for Common Lisp
git clone https://logand.com/git/cl-rw.git/
Log | Files | Refs

commit c6f2cf9dfd016366dae673e47f032c1751f61232
parent fbbb4b359a4bdf9cfcb0df60e3c12eb277bbb6fc
Author: Tomas Hlavaty <tom@logand.com>
Date:   Sun, 22 Oct 2017 08:19:30 +0200

more readers

Diffstat:
Mrw.lisp | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 99 insertions(+), 14 deletions(-)

diff --git a/rw.lisp b/rw.lisp @@ -23,16 +23,21 @@ (defpackage :rw (:use :cl) (:export :*endian* + :append-reader :bit-reader :byte-reader :byte-writer :char-reader :char-writer :copy + :count-reader :fibonacci-reader :filter-reader :flat-reader + :head-reader :line-reader + :map-reader + :n-reader :next :next-octets :next-u16 @@ -50,12 +55,12 @@ :peek :peek-reader :reader + :reduce-reader :search-reader - :shorter-reader :skip :slurp + :tail-reader :till - :u8 :u16 :u16be :u16le @@ -65,8 +70,8 @@ :u32 :u32be :u32le + :u8 :utf8-reader - :wrap-reader :wrap-writer :write-octets :write-u16 @@ -83,7 +88,9 @@ :write-utf8-codepoint :write-utf8-string :writer - :z0)) + :z0 + :zip-reader + )) (in-package :rw) @@ -537,18 +544,46 @@ (setq z1 z2 z2 z))))))) -;;(till (peek-reader (fibonacci-reader 10))) => 0 1 1 2 3 5 8 13 21 34 +;;(slurp (fibonacci-reader 10)) => 0 1 1 2 3 5 8 13 21 34 + +(defun head-reader (reader n) + (let ((i 0)) + (lambda () + (when (< i n) + (incf i) + (funcall reader))))) + +;;(slurp (head-reader (reader '(1 2 3 4 5)) 3)) +;;(slurp (head-reader (reader '(1 2 3 4 5)) 7)) + +(defun tail-reader (reader n) + (labels ((rec () + (cond + ((plusp n) + (decf n) + (funcall reader) + (rec)) + (t + (funcall reader))))) + #'rec)) + +;;(slurp (tail-reader (reader '(1 2 3 4 5)) 3)) +;;(slurp (tail-reader (reader '(1 2 3 4 5)) 7)) + +;;(next (head-reader (tail-reader (reader '(1 2 3 4 5)) 2) 1)) + +(defun n-reader (reader n) + (let ((i 0)) + (lambda () + (when (< i n) + (incf i) + (or (funcall reader) + (error "only ~s out of ~s items read" (1- i) n)))))) -(defun shorter-reader (reader size) - (if size - (let ((offset 0)) - (lambda () - (when (< offset size) - (incf offset) - (funcall reader)))) - reader)) +;;(slurp (n-reader (reader '(1 2 3 4 5)) 3)) +;;(slurp (n-reader (reader '(1 2 3 4 5)) 7)) -(defun wrap-reader (reader fn) +(defun map-reader (reader fn) (lambda () (let ((z (next reader))) (when z @@ -584,3 +619,53 @@ ;; flat input octets -> cons tree -> octet-reader tree -> [writer] flat output octets ;; https://rosettacode.org/wiki/Flatten_a_list + +(defun append-reader (readers) + (labels ((rec () + (when readers + (let ((z (next (car readers)))) + (cond + (z) + (t + (pop readers) + (rec))))))) + #'rec)) + +;;(slurp (append-reader (list (reader "hi") (rw:reader "hello")))) + +(defun ref (reader n) ;; is it useful? + (dotimes (i n (next reader)) + (next reader))) + +;;(ref (append-reader (list (reader "hi") (rw:reader "hello"))) 3) + +(defun reduce-reader (reader fn i) + (lambda () + (let ((z (next reader))) + (when z + (setq i (funcall fn z i)))))) + +;;(slurp (reduce-reader (reader '(1 2 3)) #'+ 0)) + +(defun count-reader (reader) + (let ((i 0)) + (lambda () + (let ((z (next reader))) + (when z + (incf i)))))) + +;;(slurp (count-reader (reader '(1 2 3)))) + +(defun zip-reader (readers) + (lambda () + (loop + for r in readers + for v = (next r) + unless v do (return) + collect v))) + +;;(slurp (zip-reader (list (reader '(1 2 3 4 5)) (reader '(a b c d))))) +;;(slurp (zip-reader (list (reader '(1 2 3 4 5)) (reader '(a b c d e f))))) + +;; ? readers -> choose one based on some criterion? flat-reader + sort? +;; mux-reader