commit c6f2cf9dfd016366dae673e47f032c1751f61232
parent fbbb4b359a4bdf9cfcb0df60e3c12eb277bbb6fc
Author: Tomas Hlavaty <tom@logand.com>
Date: Sun, 22 Oct 2017 08:19:30 +0200
more readers
Diffstat:
M | rw.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