(define-module (language python bytes) #:use-module (oop goops) #:use-module (oop pf-objects) #:use-module (ice-9 match) #:use-module (rnrs bytevectors) #:use-module (system foreign) #:use-module (language python string) #:use-module (language python for) #:use-module (language python try) #:use-module (language python exceptions) #:use-module (language python list) #:use-module (language python hash) #:use-module (language python bool) #:use-module (language python persist) #:export ( pybytes-listing bytes bytearray bytes->bytevector pybytesarray-listing scm-bytevector)) (define (scm-bytevector x) (slot-ref (bytes x) 'bytes)) (define (bytes->bytevector x) (slot-ref x 'bytes)) (define-syntax-rule (aif it p x y) (let ((it p)) (if it x y))) (define b-ref bytevector-u8-ref) (define b-set! bytevector-u8-set!) (define b-make make-bytevector) (define b-len bytevector-length) (define-class () bytes) (define-class () n vec) (name-object ) (name-object ) (cpit (o (lambda (o n l) (slot-set! o 'bytes (let lp ((l l) (i 0) (b (b-make n))) (if (pair? l) (b-set! b i (car l)) (lp (cdr l) (+ i 1) b))))) (let* ((b (slot-ref o 'bytes)) (n (b-len b))) (list n (let lp ((i 0)) (if (< i n) (cons (b-ref b i) (lp (+ i 1))) '())))))) (cpit (o (lambda (o n m l) (slot-set! o 'n m) (slot-set! o 'vec (let lp ((l l) (i 0) (b (b-make n))) (if (pair? l) (b-set! b i (car l)) (lp (cdr l) (+ i 1) b))))) (let* ((b (slot-ref o 'vec)) (n (b-len b))) (list n (slot-ref o 'n) (let lp ((i 0)) (if (< i n) (cons (b-ref b i) (lp (+ i 1))) '())))))) (define-method (b-get (o )) o) (define-method (b-get (o )) (slot-ref o 'bytes)) (define-method (b-get (o )) (slot-ref o 'vec)) (define (b-char x) (cond ((char? x) (ch-find x)) ((string? x) (ch-find (string-ref x 0))) (else x))) (define-python-class bytes () (define __init__ (case-lambda ((self) (__init__ self "")) ((self s) (cond ((is-a? s ) (let* ((n (string-length s)) (bytes (b-make n))) (let lp ((i 0)) (if (< i n) (begin (b-set! bytes i (ch-find (string-ref s i))) (lp (+ i 1))))) (slot-set! self 'bytes bytes))) ((is-a? s ) (__init__ self (slot-ref s 'str))) ((is-a? s ) (slot-set! self 'bytes (slot-ref s 'bytes))) ((is-a? s ) (slot-set! self 'bytes s)) ((is-a? s ) (let* ((n (slot-ref s 'n)) (b (b-make n))) (bytevector-copy! (slot-ref s 'vec) 0 b 0 n) (slot-set! self 'bytes b))) (else (for ((x : s)) ((r '())) (cons (b-char x) r) #:final (let* ((n (length r)) (bytes (b-make n))) (let lp ((i (- n 1)) (r r)) (if (>= i 0) (begin (b-set! bytes i (car r)) (lp (- i 1) (cdr r))) (slot-set! self 'bytes bytes))))))))))) (name-object bytes) (define-python-class bytearray () (define __init__ (case-lambda ((self) (__init__ self "")) ((self s) (cond ((is-a? s ) (let* ((n (string-length s)) (bytes (b-make n))) (let lp ((i 0)) (if (< i n) (begin (b-set! bytes i (ch-find (string-ref s i))) (lp (+ i 1))))) (slot-set! self 'vec bytes) (slot-set! self 'n n))) ((is-a? s ) (__init__ self (slot-ref s 'str))) ((is-a? s ) (let ((b (slot-ref s 'bytes))) (slot-set! self 'vec (bytevector-copy b)) (slot-set! self 'n (b-len b)))) ((is-a? s ) (slot-set! self 'vec (bytevector-copy s)) (slot-set! self 'n (b-len s))) ((is-a? s ) (slot-set! self 'vec (bytevector-copy (slot-ref s 'vec))) (slot-set! self 'n (slot-ref s 'n))) (else (for ((x : s)) ((r '())) (cons (b-char x) r) #:final (let* ((n (length r)) (bytes (b-make n))) (let lp ((i (- n 1)) (r r)) (if (>= i 0) (begin (b-set! bytes i (car r)) (lp (- i 1) (cdr r))) (begin (slot-set! self 'vec bytes) (slot-set! self 'n (b-len bytes))))))))))))) (name-object bytearray) (define-syntax-rule (define-py (f o . u) code ...) (begin (define-method (f (o ) . u) code ...) (define-method (f (o ) . l) (apply f (slot-ref o 'bytes) l)))) (define-syntax-rule (define-py! (f o . u) code ...) (begin (define-method (f (o ) . u) code ...))) (define (idd x) x) (define-syntax-rule (define-py* g (f m o nn . u) code ...) (begin (define (g m o nn . u) code ...) (define-method (f (o ) . l) (apply g idd o (b-len o) l)) (define-method (f (o ) . l) (let ((b (slot-ref o 'bytes))) (apply g bytes b (b-len b) l))) (define-method (f (o ) . l) (let ((b (slot-ref o 'vec)) (n (slot-ref o 'n))) (apply g bytearray b n l))))) (define-py* -bool (bool m o nn) (not (= (len o) 0))) (define-method (write (b ) . l) (define port (if (pair? l) (car l) #t)) (format port "b'") (b->string port (slot-ref b 'bytes)) (format port "'")) (define-method (write (b ) . l) (define port (if (pair? l) (car l) #t)) (format port "bytearray(b'") (b->string port (pylist-slice (slot-ref b 'vec) 0 (len b) 1)) (format port "')")) (define dynlink (dynamic-link)) (define stringn (pointer->procedure '* (dynamic-func "scm_from_latin1_stringn" dynlink) (list '* size_t))) (define ch->i (make-hash-table)) (define (re-eval ch) (let lp ((i 0)) (if (< i 256) (if (eq? ch (chf i)) (begin (hash-set! ch->i ch i) (lp (+ i 1))) (lp (+ i 1))) (hash-ref ch->i ch)))) (define (ch-find ch) (aif it (hash-ref ch->i ch #f) (if (eq? ch (chf it)) it (re-eval ch)) (re-eval ch))) (define (chf ch) (let ((bytes (pointer->scm (stringn (bytevector->pointer (b-make 1 ch)) 1)))) (if (= (string-length bytes) 1) (string-ref bytes 0) (chf 0)))) (define (b->string port b) (let ((n (b-len b))) (let lp ((i 0)) (if (< i n) (let ((ch (b-ref b i))) (cond ((equal? ch 0) (format port "\\x00")) ((equal? (chf ch) #\\) (format port "\\\\")) ((equal? (chf ch) #\') (format port "\\'")) ((equal? (chf ch) #\newline) (format port "\\n")) ((= ch 7) (format port "\\a")) ((= ch 8) (format port "\\b")) ((= ch 12) (format port "\\f")) ((= ch 10) (format port "\\n")) ((= ch 13) (format port "\\r")) ((= ch 9) (format port "\\t")) ((= ch 11) (format port "\\v")) (else (if (< ch 32) (format port "\\x~2,'0x" ch) (format port "~a" (make-string 1 (chf ch)))))) (lp (+ i 1))))))) (define-py (py-hash b) (hash b pyhash-N)) (define-py* pylist (pylist-ref bytes o N nin) (define n (if (< nin 0) (+ N nin) nin)) (if (and (>= n 0) (< n N)) (if (eq? bytes idd) (b-ref o n) (bytes (b-make 1 (b-ref o n)))) (raise IndexError))) (define-py (len b) (b-len b)) (define-py! (len b) (slot-ref b 'n)) (define-py* ->list (to-list mk b n) (let lp ((i 0) (r '())) (if (< i n) (lp (+ i 1) (cons (b-ref b i) r)) (reverse r)))) (define-py* ->pylist (to-pylist mk b n) (let* ((m n) (o (make )) (v (make-vector m))) (slot-set! o 'vec v) (slot-set! o 'n n) (let lp ((i 0)) (if (< i n) (begin (vector-set! v i (if (equal? bytes idd) (b-ref b i) (bytes (b-make 1 (b-ref b i))))) (lp (+ i 1))) o)))) (define-py! (pylist-set! o nin val) (define N (slot-ref o 'n)) (define n (if (< nin 0) (+ N nin) nin)) (if (and (>= n 0) (< n (slot-ref o 'n))) (b-set! (slot-ref o 'vec) n val) (raise IndexError))) (define-py* slice (pylist-slice bytes o N n1 n2 n3) (define (f n) (if (< n 0) (+ N n) n)) (let* ((n1 (f (if (eq? n1 None) 0 n1))) (n2 (f (if (eq? n2 None) N n2))) (n3 (f (if (eq? n3 None) 1 n3))) (n (let lp ((i n1) (j 0)) (if (< i n2) (lp (+ i n3) (+ j 1)) j))) (b (b-make n))) (let lp ((i n1) (j 0)) (if (< j n) (begin (b-set! b j (b-ref o i)) (lp (+ i n3) (+ j 1))) (bytes b))))) (define-py! (pylist-subset! o n1 n2 n3 val) (define N (slot-ref o 'n)) (define (f n) (if (< n 0) (+ N n) n)) (let* ((n1 (f (if (eq? n1 None) 0 n1))) (n2 (f (if (eq? n2 None) (slot-ref o 'n) n2))) (n3 (f (if (eq? n3 None) 1 n3))) (vec (slot-ref o 'vec)) (l2 (to-list val)) (N2 (length l2))) (if (<= n2 N) (let lp ((i 0) (l2 l2) (j n1)) (if (< j n2) (if (< i N2) (let ((r (car l2))) (if (and (number? r) (integer? r) (>= r 0) (< r 256)) (begin (b-set! vec j r) (lp (+ i 1) (cdr l2) (+ j n3))) (raise TypeError "not a byte"))) (let lp ((j2 j)) (if (< j2 n2) (lp (+ j2 n3)) (let lp ((k1 j) (k2 j2)) (if (< k2 N) (begin (b-set! vec k1 (b-ref vec k2)) (lp (+ k1 1) (+ k2 1))) (begin (let lp ((i k2)) (if (< i N) (begin (b-set! vec i #f) (lp (+ i 1))) (slot-set! o 'n k1))))))))))) (raise IndexError)) (values))) (define (byte x) (or (and (integer? x) (>= x 0) (< x 256) x) (and (is-a? x ) (b-ref x 0)) (and (is-a? x ) (b-ref (slot-ref x 'bytes) 0)) (and (is-a? x ) (b-ref (slot-ref x 'vec) 0)))) (define-py! (pylist-append! o val) (let* ((n (slot-ref o 'n)) (vec (slot-ref o 'vec)) (N (b-len vec))) (aif v (byte val) (begin (if (< n N) (b-set! vec n v) (let* ((N (* 2 N)) (vec2 (b-make N))) (let lp ((i 0)) (if (< i n) (begin (b-set! vec2 i (b-ref vec i)) (lp (+ i 1))))) (b-set! vec2 n v) (slot-set! o 'vec vec2))) (slot-set! o 'n (+ n 1)) (values)) (raise TypeError "not a byte" val)))) (define (b-concat b1 n1 b2 n2) (let* ((n (+ n1 n2)) (b (b-make n))) (let lp ((i 0)) (if (< i n1) (begin (b-set! b i (b-ref b1 i)) (lp (+ i 1))) (let lp ((i i) (j 0)) (if (< j n2) (begin (b-set! b i (b-ref b2 j)) (lp (+ i 1) (+ j 1))) b)))))) (define-method (+ (o1 ) (b2 )) (let* ((b1 (slot-ref o1 'bytes)) (n1 (b-len b1)) (n2 (b-len b2)) (o (make )) (b (b-concat b1 n1 b2 n2))) (slot-set! o 'bytes b) o)) (define-method (+ (b2 ) (o1 )) (let* ((b1 (slot-ref o1 'bytes)) (n1 (b-len b1)) (n2 (b-len b2)) (o (make )) (b (b-concat b2 n2 b1 n1))) (slot-set! o 'bytes b) o)) (define-method (+ (b1 ) (b2 )) (let* ((n1 (b-len b1)) (n2 (b-len b2))) (b-concat b1 n1 b2 n2))) (define-method (+ (o1 ) (o2 )) (let* ((b1 (slot-ref o1 'bytes)) (b2 (slot-ref o2 'bytes)) (n1 (b-len b1)) (n2 (b-len b2)) (o (make )) (b (b-concat b1 n1 b2 n2))) (slot-set! o 'bytes b) o)) (define-method (+ (o1 ) (o2 )) (let* ((b1 (slot-ref o1 'vec)) (b2 (slot-ref o2 'bytes)) (n1 (slot-ref o1 'n)) (n2 (b-len b2)) (o (make )) (b (b-concat b1 n1 b2 n2))) (slot-set! o 'vec b) (slot-set! o 'n (+ n1 n2)) o)) (define-method (+ (o1 ) (b2 )) (let* ((b1 (slot-ref o1 'vec)) (n1 (slot-ref o1 'n)) (n2 (b-len b2)) (o (make )) (b (b-concat b1 n1 b2 n2))) (slot-set! o 'vec b) (slot-set! o 'n (+ n1 n2)) o)) (define-method (+ (o2 ) (o1 )) (let* ((b1 (slot-ref o1 'vec)) (b2 (slot-ref o2 'bytes)) (n1 (slot-ref o1 'n)) (n2 (b-len b2)) (o (make )) (b (b-concat b2 n2 b1 n1))) (slot-set! o 'vec b) (slot-set! o 'n (+ n1 n2)) o)) (define-method (+ (b2 ) (o1 ) ) (let* ((b1 (slot-ref o1 'vec)) (n1 (slot-ref o1 'n)) (n2 (b-len b2)) (o (make )) (b (b-concat b2 n2 b1 n1))) (slot-set! o 'vec b) (slot-set! o 'n (+ n1 n2)) o)) (define-method (+ (o1 ) (o2 )) (let* ((b1 (slot-ref o1 'vec)) (b2 (slot-ref o2 'vec)) (n1 (slot-ref o1 'n)) (n2 (slot-ref o2 'n)) (o (make )) (b (b-concat b1 n1 b2 n2))) (slot-set! o 'vec b) (slot-set! o 'n (+ n1 n2)) o)) (define (b-rep b n m) (let* ((N (* n m)) (r (b-make N))) (let lp ((i 0) (j 0)) (if (< i m) (let lp2 ((j j) (k 0)) (if (< k n) (begin (b-set! r j (b-ref b k)) (lp2 (+ j 1) (+ k 1))) (lp (+ i 1) j))) r)))) (define-method (* (o1 ) m) (let* ((b1 (slot-ref o1 'vec)) (n1 (slot-ref o1 'n)) (o (make )) (b (b-rep b1 n1 m))) (slot-set! o 'vec b) (slot-set! o 'n (* n1 m)) o)) (define-method (* (b1 ) m) (let* ((n1 (b-len b1))) (b-rep b1 n1 m))) (define-method (* (o1 ) m) (let* ((b1 (slot-ref o1 'bytes)) (n1 (b-len b1)) (o (make )) (b (b-rep b1 n1 m))) (slot-set! o 'bytes b) o)) (define-py* cap (py-capitalize bytes s n) (let* ((w (b-make n))) (let lp ((i 0) (first? #t)) (if (< i n) (let* ((x (b-ref s i)) (ch (chf x))) (define (f first?) (b-set! w i x) (lp (+ i 1) first?)) (if (and first? (char-alphabetic? ch)) (aif it (ch-find (char-upcase ch)) (begin (b-set! w i it) (lp (+ i 1) #f)) (f #t)) (f #f))) (bytes w))))) (define-py* center (py-center bytes o n w . l) (let* ((ws (if (pair? l) (ch-find (b-ref (car l) 0)) (ch-find #\space))) (w (if (< w n) n w)) (d (- w n)) (e (floor-quotient (- w n) 2)) (s (b-make w (ch-find #\space)))) (let lp ((i 0) (j e)) (if (< i n) (begin (b-set! s j (b-ref o i)) (lp (+ i 1) (+ j 1))))) (bytes s))) ;;;py-decode ;;;py-encode (define-py* endswith (py-endswith bytes o n suff . l) (let* ((suff (slot-ref (bytes suff) 'bytes)) (ns (b-len suff)) (f (lambda (x) (< x 0) (+ n x) x))) (call-with-values (lambda () (match l (() (values 0 n )) ((x) (values (f x) n )) ((x y) (values (f x) (f y))))) (lambda (start end) (let lp ((i (- n ns)) (j 0)) (if (< i start) (lp (+ i 1) (+ j 1)) (if (>= i end) #t (and (eq? (b-ref o i) (b-ref suff j)) (lp (+ i 1) (+ j 1)))))))))) (define-py* startswith (py-startswith bytes o n pre . l) (let* ((pre (slot-ref (bytes pre) 'bytes)) (pre (b-get pre)) (ns (len pre)) (f (lambda (x) (< x 0) (+ n x) x))) (call-with-values (lambda () (match l (() (values 0 n )) ((x) (values (f x) n )) ((x y) (values (f x) (f y))))) (lambda (start end) (let lp ((i 0)) (cond ((or (>= i end) (>= i ns)) #t) ((< i start) (lp (+ i 1))) (else (and (eq? (b-ref o i) (b-ref pre i)) (lp (+ i 1)))))))))) (define-py* expand (py-expandtabs bytes s n . l) (let* ((tabsize (match l (() 8) ((x) x))) (ct (ch-find #\tab)) (cs (ch-find #\space)) (n (b-len s))) (let lp ((i 0) (r '())) (if (< i n) (let ((x (b-ref s i))) (if (eq? x ct) (let lp2 ((j 0) (r r)) (if (< j tabsize) (lp2 (+ j 1) (cons cs r)) (lp (+ i 1) r))) (lp (+ i 1) (cons x r)))) (bytes (reverse r)))))) (define (b-contains s sub nsub start end) (define (match i) (let lp ((i i) (j 0)) (if (and (< j nsub) (< i end)) (if (eq? (b-ref s i) (b-ref sub j)) (lp (+ i 1) (+ j 1)) #f) #t))) (let lp ((i (max start 0))) (if (< i end) (if (match i) i (lp (+ i 1))) #f))) (define-py* find (py-find bytes s n sub . l) (let* ((f (lambda (x) (< x 0) (+ n x) x))) (call-with-values (lambda () (match l (() (values 0 n )) ((x) (values (f x) n )) ((x y) (values (f x) (f y))))) (lambda (start end) (let ((sub (b-get sub))) (aif it (b-contains s sub (len sub) start end) it -1)))))) (define (b-reverse s n) (if (is-a? s ()) (b-reverse (slot-ref s 'bytes) n) (let* ((r (b-make n))) (let lp ((i 0) (j (- n 1))) (if (< i n) (begin (b-set! r j (b-ref s i)) (lp (+ i 1) (- j 1))) r))))) (define-py* rfind (py-rfind bytes s n sub . l) (let* ((sub (slot-ref (bytes sub) 'bytes)) (s (b-reverse s n)) (nsub (len sub)) (sub (b-reverse (b-get sub) nsub)) (f (lambda (x) (< x 0) (+ n x) x))) (call-with-values (lambda () (match l (() (values 0 n )) ((x) (values (f x) n )) ((x y) (values (f x) (f y))))) (lambda (start end) (aif it (b-contains s sub nsub start end) (- n it nsub) -1))))) #| (define i (f-list #:i (mk-token (f+ (f-reg! "[0-9]"))))) (define s (f-list #:s (mk-token (f+ (f-not! (f-tag "}")))))) (define e (f-list #:e (f-and (f-tag "}") f-true))) (define tagbody (f-or! e i s)) (define tag (f-seq "{" tagbody "}")) (define nontag (f-list #:bytes (mk-token (f+ (f-or! (f-tag "{{") (f-not! tag)))))) (define e (ff* (f-or! tag nontag))) (define (compile x args kwargs) (let lp ((l x) (r '()) (u '()) (i 0)) (match l (((#:bytes x) . l) (lp l (cons x r) u i)) (((#:i x) . l) (lp l (cons "~a" r) (cons (list-ref args (string->number x)) u) i)) (((#:s x) . l) (lp l (cons "~a" r) (cons (hash-ref kwargs x None) u) i)) (((#:e) . l) (lp l (cons "~a" r) (cons (list-ref args i) u) (+ i 1))) (() (apply format #f (string-join (reverse r) "") (reverse u)))))) (define-py (py-format format s . l) (call-with-values (lambda () (let lp ((l l) (args '()) (kwargs (make-hash-table))) (match l (((? keyword? key) x . l) (hash-set! kwargs (symbol->string (keyword->symbol key)) x) (lp l args kwargs)) ((x . l) (lp l (cons x args) kwargs)) (() (values (reverse args) kwargs))))) (lambda (args kwargs) (compile (parse s e) args kwargs)))) |# (define-syntax-rule (mk-is py-isalnum x ...) (define-py* isalnum (py-isalnum bytes s n) (let lp ((i 0)) (if (< i n) (let ((ch (chf (b-ref s i)))) (if (or (x ch) ...) (lp (+ i 1)) #f)) #t)))) (mk-is py-isalnum char-alphabetic? char-numeric?) (mk-is py-isalpha char-alphabetic?) (mk-is py-isdigit char-numeric?) (mk-is py-islower char-lower-case?) (mk-is py-isspace char-whitespace?) (mk-is py-isupper char-upper-case?) (define-py* istitle (py-istitle bytes s n) (if ((> n 0)) (let lp ((i 0) (space? #t)) (if (< i n) (let ((ch (chf (b-ref s i)))) (if space? (cond ((char-whitespace? ch) (lp (+ i 1) #t)) ((char-upper-case? ch) (lp (+ i 1) #f)) (else #f)) (cond ((char-whitespace? ch) (lp (+ i 1) #t)) ((char-upper-case? ch) #f) ((char-lower-case? ch) (lp (+ i 1) #f)) (else #f)))) #t)) #f)) (define (b-join bytes l s ns) (let* ((n (let lp ((l l) (n 0)) (if (pair? l) (let ((x (car l)) (l (cdr l))) (lp l (+ n (len x) (if (pair? l) ns 0)))) n))) (r (b-make n))) (let lp ((l l) (i 0)) (if (pair? l) (let* ((x (car l)) (n (len x)) (x (b-get x)) (l (cdr l))) (let lp2 ((j 0) (i i)) (if (< j n) (begin (b-set! r i (b-ref x j)) (lp2 (+ j 1) (+ i 1))) (if (pair? l) (let lp3 ((j 0) (i i)) (if (< j ns) (begin (b-set! r i (b-ref s j)) (lp3 (+ j 1) (+ i 1))) (lp l i))) (lp l i))))) (bytes r))))) (define-py* join (py-join bytes s n iterator) (b-join bytes (to-list iterator) s n)) (define-py* ljust (py-ljust bytes s n width . l) (let* ((ch (match l ((x) (b-char x)) (() (b-char #\space))))) (if (< width n) (pylist-slice s 0 width 1) (let ((ret (b-make width ch))) (let lp ((i 0)) (if (< i n) (begin (b-set! ret i (b-ref s i)) (lp (+ i 1))) (bytes ret))))))) (define-py* rjust (py-rjust bytes s n width . l) (let* ((ch (match l ((x) (b-char x)) (() (b-char #\space))))) (if (< width n) (pylist-slice s (- width) (len s) 1) (let ((ret (b-make width ch))) (let lp ((i 0) (j (- width n))) (if (< i n) (begin (b-set! ret j (b-ref s i)) (lp (+ i 1) (+ j 1))) (bytes ret))))))) (define-py* lower (py-lower bytes s n) (let* ((r (b-make n))) (let lp ((i 0)) (if (< i n) (let* ((x (b-ref s i)) (ch (chf x))) (b-set! r i (if (char-upper-case? ch) (ch-find (char-downcase ch)) x)) (lp (+ i 1))) (bytes r))))) (define-py* upper (py-upper bytes s n) (let* ((r (b-make n))) (let lp ((i 0)) (if (< i n) (let* ((x (b-ref s i)) (ch (chf x))) (b-set! r i (if (char-lower-case? ch) (ch-find (char-upcase ch)) x)) (lp (+ i 1))) (bytes r))))) (define-py* swapcase (py-swapcase bytes s n) (let* ((r (b-make n))) (let lp ((i 0)) (if (< i n) (let* ((x (b-ref s i)) (ch (chf x))) (b-set! r i (cond ((char-lower-case? ch) (ch-find (char-upcase ch))) ((char-upper-case? ch) (ch-find (char-downcase ch))) (else x))) (lp (+ i 1))) (bytes r))))) (define b-trim (case-lambda ((bytes s n) (b-trim bytes s n (lambda (ch x) (char-whitespace? ch)))) ((bytes s n p) (let lp ((i 0) (r '()) (first? #t)) (if (< i n) (let ((x (b-ref s i))) (if first? (if (p (chf x) x) (lp (+ i 1) r #t) (lp (+ i 1) (cons x r) #f)) (lp (+ i 1) (cons x r) #f))) (bytes (reverse r))))))) (define b-rtrim (case-lambda ((bytes s n) (b-rtrim bytes s n (lambda (ch x) (char-whitespace? ch)))) ((bytes s n p) (let lp ((i (- n 1)) (r '()) (first? #t)) (if (>= i 0) (let ((x (b-ref s i))) (if first? (if (p (chf x) x) (lp (- i 1) r #t) (lp (- i 1) (cons x r) #f)) (lp (- i 1) (cons x r) #f))) (bytes r)))))) (define-py* lstrip (py-lstrip bytes s n . l) (match l (() (b-trim bytes s n)) ((x) (let ((l (map b-char (to-list x)))) (b-trim bytes s n (lambda (ch x) (member x l))))))) (define-py* restrip (py-rstrip bytes s n . l) (match l (() (b-rtrim bytes s n)) ((x) (let ((l (map b-char (to-list x)))) (b-rtrim bytes s n (lambda (ch x) (member x l))))))) (define-py* partition (py-partition bytes s n sep) (let* ((sep (b-get sep)) (m (b-len sep))) (define (test i) (let lp ((i i) (j 0)) (if (< i n) (if (< j m) (if (eq? (b-ref s i) (b-ref sep j)) (lp (+ i 1) (+ j 1)) #f) #t) #f))) (let lp ((i 0)) (if (< i n) (if (test i) (list (pylist-slice s 0 i) sep (pylist-slice s (+ i m) n)) (lp (+ i 1))) (list s "" ""))))) (define-py* rpartition (py-rpartition bytes ss n ssep) (let* ((s (b-reverse ss n)) (m (len ssep)) (sep (b-reverse (b-get ssep) m))) (define (test i) (let lp ((i i) (j 0)) (if (< i n) (if (< j m) (if (eq? (b-ref s i) (b-ref sep j)) (lp (+ i 1) (+ j 1)) #f) #t) #f))) (let lp ((i 0)) (if (< i n) (if (test i) (list (bytes (b-reverse (pylist-slice s (+ i m) n) (- n (+ i m)))) (bytes sep) (bytes (b-reverse (pylist-slice s 0 i) i))) (lp (+ i 1))) (list (bytes "") (bytes "") s))))) (define-py* replace (py-replace bytes s n old new . l) (let ((n (match l (() #f) ((n . _) n)))) (b-join bytes (reverse (let lp ((s s) (r '())) (let ((l (py-partition s old))) (if (equal? (cadr l) "") (cons s r) (lp (list-ref l 2) (cons (car l) r)))))) n new))) (define-py (py-stripip s . l) (apply py-rstrip (apply py-lstrip s l) l)) (define-py! (py-stripip s . l) (apply py-rstrip (apply py-lstrip s l) l)) (define-py* index (pylist-index bytes o n val . l) (let* ((vec o) (f (lambda (m) (if (< m 0) (+ m n) m)))) (call-with-values (lambda () (match l (() (values 0 n)) ((x) (values (f x) n)) ((x y) (values (f x) (f y))))) (lambda (n1 n2) (if (and (>= n1 0) (>= n2 0) (< n1 n) (<= n2 n)) (let lp ((i n1)) (if (< i n2) (let ((r (b-ref vec i))) (if (equal? r val) i (lp (+ i 1)))) (raise ValueError "could not find value in index fkn"))) (raise IndexError "index out of scop in index fkn")))))) (define-py* rindex (py-rindex býtes s n . l) (let ((n (b-len s))) (- n (apply pylist-index (b-reverse s n) l) 1))) #; (define-py (py-title title s) (string-titlecase s)) #; (define-py (py-split s . l) (define ws (f+ (f-reg "[ \t\n]"))) (define r (f-or! (f-seq f-eof (f-out '())) (f-cons (f-seq (mk-token (f* (f-reg! "."))) f-eof) (f-out '())))) (define (u ws) (mk-token (f+ (f-not! ws)))) (define (tok ws i) (if (= i 0) (f-list (mk-token (f* (f-reg! ".")))) (let ((e (mk-token (f* (f-not! ws))))) (f-seq (f? ws) (f-cons e (let lp ((i i)) (if (> (- i 1) 0) (f-or! (f-seq (f? ws) f-eof (f-out '())) (f-cons (f-seq ws e) (Ds (lp (- i 1))))) r))))))) (define N 1000000000000) (let ((e (call-with-values (lambda () (match l (() (values ws N)) ((sep) (values (f-tag sep) N)) ((sep n) (values (f-tag sep) n)))) tok))) (parse s e))) #; (define-py (py-rsplit s . l) (reverse (map string-reverse (apply py-split (string-reverse s) (match l (() '()) ((sep . l) (cons (string-reverse sep) l))))))) (define-py* splitlines (py-splitlines bytes s n . l) (let ((keep? (match l ((#:keepends v) v) ((v) v) (_ #f)))) (let lp ((i 0) (r '()) (old 0)) (if (< i n) (let* ((x (b-ref s i)) (ch (chf x))) (if (eq? ch #\newline) (if keep? (lp (+ i 1) (cons (pylist-slice s old (+ i 1) 1) r) (+ i 1)) (lp (+ i 1) (cons (pylist-slice s old i 1) r) (+ i 1))) (lp (+ i 1) r old))) (reverse r))))) (define-py* translate (py-translate bytes s n table . l) (let* ((table (b-get table)) (w (b-make n)) (t (if (eq? table None) #f table)) (d (match l (() #f) ((x) (map b-char (to-list x)))))) (define (tr ch) (define (e) (if t (if (< ch (b-len t)) (b-ref t ch) ch) ch)) (if d (if (member ch d) #f (e)) (e))) (let lp ((i 0) (k 0)) (if (< i n) (let ((ch (tr (b-ref s i)))) (if ch (begin (b-set! w k ch) (lp (+ i 1) (+ k 1))) (lp (+ i 1) k))) (bytes (if (= k n) w (pylist-slice w 0 k 1))))))) (define-syntax-rule (a b x y) (b (symbol->string x) (symbol->string y))) (define (cmp op s1 n1 s2 n2) (let ((n (min n1 n2))) (let lp ((i 0)) (if (< i n) (let ((x1 (b-ref s1 i)) (x2 (b-ref s2 i))) (if (= x1 x2) (lp (+ i 1)) (op x1 x2))) (op n1 n2))))) (define-syntax-rule (mkop op) (begin (define-method (op (b1 ) (s2 )) (let ((b2 (slot-ref s2 'bytes))) (cmp op b1 (b-len b1) b2 (b-len b2)))) (define-method (op (s1 ) (b2 ) ) (let ((b1 (slot-ref s1 'bytes))) (cmp op b1 (b-len b1) b2 (b-len b2)))) (define-method (op (b1 ) (b2 ) ) (cmp op b1 (b-len b1) b2 (b-len b2))) (define-method (op (s1 ) (s2 ) ) (let ((b1 (slot-ref s1 'bytes)) (b2 (slot-ref s2 'bytes))) (cmp op b1 (b-len b1) b2 (b-len b2)))) (define-method (op (a1 ) (b2 )) (let ((b1 (slot-ref a1 'vec)) (n1 (slot-ref a1 'n))) (cmp op b1 n1 b2 (b-len b2)))) (define-method (op (b1 ) (a2 )) (let ((b2 (slot-ref a2 'vec)) (n2 (slot-ref a2 'n))) (cmp op b1 (b-len b1) b2 n2))) (define-method (op (a1 ) (s2 )) (let ((b1 (slot-ref a1 'vec)) (n1 (slot-ref a1 'n)) (b2 (slot-ref s2 'bytes))) (cmp op b1 n1 b2 (b-len b2)))) (define-method (op (s1 ) (a2 )) (let ((b2 (slot-ref a2 'vec)) (n2 (slot-ref a2 'n)) (b1 (slot-ref s1 'bytes))) (cmp op b1 (b-len b1) b2 n2))) (define-method (op (a1 ) (a2 )) (let ((b1 (slot-ref a1 'vec)) (n1 (slot-ref a1 'n )) (b2 (slot-ref a2 'vec)) (n2 (slot-ref a2 'n ))) (cmp op b1 n1 b2 n2))))) (mkop <) (mkop <=) (mkop >) (mkop >=) (mkop py-equal?) (define-py* zfill (py-zfill bytes s n width) (let* ((w (pylist-slice s 0 n 1))) (let lp ((i 0)) (if (< i n) (let* ((x (b-ref s i)) (ch (chf x))) (if (char-numeric? ch) (let lp ((j (max 0 (- i width)))) (if (< j i) (begin (b-set! w j (ch-find #\0)) (lp (+ j 1))) (bytes w))) (lp (+ i 1)))) s)))) (define-method (py-hash (o )) (hash (slot-ref o 'bytes) pyhash-N)) (define-class () i d) (define-class () i d) (define-method (wrap-in (o )) (let ((out (make ))) (slot-set! out 'bytes (slot-ref o 'bytes)) (slot-set! out 'i (slot-ref o 'i)) (slot-set! out 'd (slot-ref o 'd)) out)) (define-method (wrap-in (o )) (let ((out (make ))) (slot-set! out 'vec (slot-ref o 'vec)) (slot-set! out 'n (slot-ref o 'n)) (slot-set! out 'i (slot-ref o 'i)) (slot-set! out 'd (slot-ref o 'd)) out)) (define-method (wrap-in (s )) (let ((out (make ))) (slot-set! out 'bytes s) (slot-set! out 'i 0) (slot-set! out 'd 1) out)) (define-method (py-reversed (s )) (let ((out (make ))) (slot-set! out 'bytes (slot-ref s 'bytes)) (slot-set! out 'i (- (b-len s) 1)) (slot-set! out 'd -1) out)) (define-method (py-reversed (s )) (let ((out (make ))) (slot-set! out 'n (slot-ref s 'n)) (slot-set! out 'vec (slot-ref s 'vec)) (slot-set! out 'i (- (slot-ref s 'n) 1)) (slot-set! out 'd -1) out)) (define-method (next (o )) (let ((i (slot-ref o 'i )) (d (slot-ref o 'd)) (bytes (slot-ref o 'bytes))) (if (> d 0) (if (< i (b-len bytes)) (let ((ret (b-ref bytes i))) (slot-set! o 'i (+ i d)) ret) (throw StopIteration)) (if (>= i 0) (let ((ret (b-ref bytes i))) (slot-set! o 'i (+ i d)) ret) (throw StopIteration))))) (define-method (next (o )) (let ((i (slot-ref o 'i )) (d (slot-ref o 'd )) (bytes (slot-ref o 'vec)) (n (slot-ref o 'n ))) (if (> d 0) (if (< i n) (let ((ret (b-ref bytes i))) (slot-set! o 'i (+ i d)) ret) (throw StopIteration)) (if (>= i 0) (let ((ret (b-ref bytes i))) (slot-set! o 'i (+ i d)) ret) (throw StopIteration))))) (define (pybytes-listing) (let ((l (to-pylist (map symbol->string '(__add__ __class__ __contains__ __delattr__ __doc__ __eq__ __format__ __ge__ __getattribute__ __getitem__ __getnewargs__ __getslice__ __gt__ __hash__ __init__ __le__ __len__ __lt__ __mod__ __mul__ __ne__ __new__ __reduce__ __reduce_ex__ __repr__ __rmod__ __rmul__ __setattr__ __sizeof__ __bytes__ __subclasshook__ _formatter_field_name_split _formatter_parser capitalize center count decode encode endswith expandtabs find format index isalnum isalpha isdigit islower isspace istitle isupper join ljust lower lbytesip partition replace rfind rindex rjust rpartition rsplit rbytesip split splitlines startswith strip swapcase title translate upper zfill))))) (pylist-sort! l) l)) (define (pybytesarray-listing) (let ((l (to-pylist (map symbol->string '(__add__ __alloc__ __class__ __contains__ __delattr__ __delitem__ __dir__ __doc__ __eq__ __format__ __ge__ __getattribute__ __getitem__ __gt__ __hash__ __iadd__ __imul__ __init__ __iter__ __le__ __len__ __lt__ __mod__ __mul__ __ne__ __new__ __reduce__ __reduce_ex__ __repr__ __rmod__ __rmul__ __setattr__ __setitem__ __sizeof__ __str__ __subclasshook__ append capitalize center clear copy count decode endswith expandtabs extend find fromhex hex index insert isalnum isalpha isdigit islower isspace istitle isupper join ljust lower lstrip maketrans partition pop remove replace reverse rfind rindex rjust rpartition rsplit rstrip split splitlines startswith strip swapcase title translate upper zfill))))) (pylist-sort! l) l))