cl-rw

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

commit 1f47d2a91045607faa7a39c8672a4ce9cdfea3fd
parent 978279cd99ad2531a5e1dcbc371ae76cd10d380b
Author: Tomas Hlavaty <tom@logand.com>
Date:   Sun, 18 Aug 2013 00:10:11 +0200

more readers, better skip, till doesnt eat the last item but peeks

Diffstat:
Mrw.lisp | 79++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 60 insertions(+), 19 deletions(-)

diff --git a/rw.lisp b/rw.lisp @@ -27,6 +27,9 @@ :char-reader :char-writer :copy + :fibonacci-reader + :filter-reader + :line-reader :next :next-octets :next-u16 @@ -66,24 +69,12 @@ (incf i)))))))) (defun char-reader (stream) - (lambda () (read-char stream nil nil))) + (lambda () + (read-char stream nil nil))) (defun byte-reader (stream) - (lambda () (read-byte stream nil nil))) - -(defun skip (reader n) - (dotimes (i n reader) - (next reader))) - -(defun till (reader &optional markers) - (let (x) - (loop - until (member (setq x (next reader)) (or markers '(nil))) - collect x))) - -;;(till (skip (reader '(0 1 2 3 4)) 1) '(3)) -;;(till (skip (reader #(0 1 2 3 4)) 1) '(3)) -;;(with-open-file (s "printers.html") (till (char-reader s) '(#\>))) + (lambda () + (read-byte stream nil nil))) (defun peek-reader (reader) (let (x) @@ -93,6 +84,27 @@ ((nil) (prog1 (if x x (next reader)) (setq x nil))))))) +(defun skip (reader &optional n/items) + (etypecase n/items + (integer + (dotimes (i n/items reader) + (next reader))) + (list + (let ((x (or n/items '(#\space #\tab #\newline)))) + (loop + while (member (peek reader) x) + do (next reader))) + reader))) + +(defun till (reader &optional items) + (loop + while (let ((x (peek reader))) (and x (not (member x items)))) + collect (next reader))) + +;;(till (skip (peek-reader (reader '(0 1 2 3 4))) 1) '(3)) +;;(till (skip (peek-reader (reader #(0 1 2 3 4))) 1) '(3)) +;;(with-open-file (s "/etc/passwd") (till (peek-reader (char-reader s)) '(#\:))) + (defun search-reader (reader needle) (let ((all (till reader)) ;; TODO optimize? use kmp algorithm (start 0)) @@ -101,9 +113,7 @@ (setq start (1+ i)) (values i all))))) -#+nil -(with-open-file (s "printers.html") - (till (search-reader (char-reader s) '#.(coerce "/printers/" 'list)))) +;;(with-open-file (s "/etc/passwd") (till (peek-reader (search-reader (peek-reader (char-reader s)) '#.(coerce "user" 'list))))) (defun next-u8 (reader) (let? x (next reader) @@ -169,3 +179,34 @@ ;; TODO write-u64|128 ;; TODO write-s8|16|32|64|128 + +(defun line-reader (reader) + (lambda () + (let ((x (till reader '(#\newline)))) + (when (next reader) + (or x :empty-line))))) + +(defun filter-reader (reader predicate) + (lambda () + (block found + (loop + (let ((x (next reader))) + (unless x + (return-from found nil)) + (when (funcall predicate x) + (return-from found x))))))) + +(defun fibonacci-reader (n) + (let ((i -1) + (z1 0) + (z2 1)) + (lambda () + (incf i) + (cond + ((<= n i) nil) + ((< i 2) i) + (t (let ((z (+ z1 z2))) + (setq z1 z2 + z2 z))))))) + +;;(till (peek-reader (fibonacci-reader 10))) => 0 1 1 2 3 5 8 13 21 34