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:
M | rw.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