diff options
Diffstat (limited to 'modules/language/*.scm')
-rw-r--r-- | modules/language/*.scm | 0 | ||||
l--------- | modules/language/python/.#spec.scm | 1 | ||||
-rw-r--r-- | modules/language/python/bool.scm | 35 | ||||
-rw-r--r-- | modules/language/python/bytes.scm | 1465 | ||||
-rw-r--r-- | modules/language/python/checksum.scm | 124 | ||||
-rw-r--r-- | modules/language/python/class.scm | 71 |
6 files changed, 1696 insertions, 0 deletions
diff --git a/modules/language/*.scm b/modules/language/*.scm deleted file mode 100644 index e69de29..0000000 --- a/modules/language/*.scm +++ /dev/null diff --git a/modules/language/python/.#spec.scm b/modules/language/python/.#spec.scm new file mode 120000 index 0000000..bf7a10b --- /dev/null +++ b/modules/language/python/.#spec.scm @@ -0,0 +1 @@ +stis@lapwine.29401:1539964896
\ No newline at end of file diff --git a/modules/language/python/bool.scm b/modules/language/python/bool.scm new file mode 100644 index 0000000..d15c749 --- /dev/null +++ b/modules/language/python/bool.scm @@ -0,0 +1,35 @@ +(define-module (language python bool) + #:use-module (oop goops) + #:use-module (language python exceptions) + #:use-module (oop pf-objects) + #:export (bool)) + +(define-syntax-rule (aif it p x y) (let ((it p)) (if it x y))) + +(define-method (bool x) + (cond + ((null? x) + #f) + ((eq? x None) + #f) + (else x))) + +(define-method (bool (x <integer>)) (if (= x 0) #f x)) +(define-method (bool (x <p>)) + (aif it (ref x '__bool__) + (it) + (next-method))) + + +(define-method (+ (a <boolean>) b) + (+ (if a 1 0) b)) +(define-method (+ b (a <boolean>)) + (+ (if a 1 0) b)) +(define-method (* (a <boolean>) b) + (* (if a 1 0) b)) +(define-method (* b (a <boolean>)) + (* (if a 1 0) b)) +(define-method (- (a <boolean>) b) + (- (if a 1 0) b)) +(define-method (- b (a <boolean>)) + (- b (if a 1 0))) diff --git a/modules/language/python/bytes.scm b/modules/language/python/bytes.scm new file mode 100644 index 0000000..e3d8245 --- /dev/null +++ b/modules/language/python/bytes.scm @@ -0,0 +1,1465 @@ +(define-module (language python bytes) + #:use-module (oop goops) + #:use-module (oop pf-objects) + #:use-module (ice-9 match) + #:use-module (ice-9 format) + #:use-module (ice-9 iconv) + #:use-module (rnrs bytevectors) + #:use-module (system foreign) + #:use-module (language python string) + #:use-module (language python for) + #:use-module (language python def) + #: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 (<py-bytes> bv-scm pybytes-listing bytes bytearray bytes->bytevector + py-decode make_trans + <py-bytearray> pybytesarray-listing scm-bytevector)) + +(define (bv-scm x) + (slot-ref (bytes x) 'bytes)) + +(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 (b->list x) (bytevector->u8-list (bv-scm x))) +(define list->b u8-list->bytevector) +(define-class <py-bytes> () bytes) +(define-class <py-bytearray> () n vec) + +(name-object <py-bytes>) +(name-object <py-bytearray>) + +(cpit <py-bytes> (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 <py-bytearray> (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 <bytevector>)) + o) +(define-method (b-get (o <py-bytes>)) + (slot-ref o 'bytes)) +(define-method (b-get (o <py-bytearray>)) + (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 (<py-bytes>) + (define maketrans + (lambda (x y) (make_trans x y))) + + (define __init__ + (case-lambda + ((self) + (__init__ self "")) + ((self s) + (cond + ((is-a? s <string>) + (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 <py-string>) + (__init__ self (slot-ref s 'str))) + ((is-a? s <py-bytes>) + (slot-set! self 'bytes (slot-ref s 'bytes))) + ((is-a? s <bytevector>) + (slot-set! self 'bytes s)) + ((is-a? s <py-bytearray>) + (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 (<py-bytearray>) + (define __init__ + (case-lambda + ((self) + (__init__ self "")) + ((self s) + (cond + ((is-a? s <string>) + (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 <py-string>) + (__init__ self (slot-ref s 'str))) + ((is-a? s <py-bytes>) + (let ((b (slot-ref s 'bytes))) + (slot-set! self 'vec (bytevector-copy b)) + (slot-set! self 'n (b-len b)))) + ((is-a? s <bytevector>) + (slot-set! self 'vec (bytevector-copy s)) + (slot-set! self 'n (b-len s))) + ((is-a? s <py-bytearray>) + (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 <bytevector>) . u) code ...) + (define-method (f (o <py-bytes>) . l) (apply f (slot-ref o 'bytes) l)))) + +(define-syntax-rule (define-py! (f o . u) code ...) + (begin + (define-method (f (o <py-bytearray>) . 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 <bytevector>) . l) + (apply g idd o (b-len o) l)) + (define-method (f (o <py-bytes>) . l) + (let ((b (slot-ref o 'bytes))) + (apply g bytes b (b-len b) l))) + (define-method (f (o <py-bytearray>) . l) + (let ((b (slot-ref o 'vec)) + (n (slot-ref o 'n))) + (apply g bytearray b n l))))) + +(define-syntax-rule (define-py** g (f m o nn . u) code ...) + (begin + (define (g m o nn . u) code ...) + (define-method (f (o <bytevector>) . l) + (apply g idd o (b-len o) l)) + (define-method (f (o <py-bytes>) . l) + (let ((b (slot-ref o 'bytes))) + (apply g bytes b (b-len b) l))) + (define-method (f (o <py-bytearray>) . l) + (let ((b (slot-ref o 'vec)) + (n (slot-ref o 'n))) + (apply g bytearray b n l))) + (define-method (f (o <p>) . l) + (aif it (ref o 'g) + (apply it l) + (next-method))))) + +(define-py* -bool (bool m o nn) (if (= (len o) 0) #f o)) + +(define-method (write (b <py-bytes>) . 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 <py-bytearray>) . 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 <py-list>)) + (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) (max 0 (min 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 <bytevector>) (b-ref x 0)) + (and (is-a? x <py-bytes>) (b-ref (slot-ref x 'bytes) 0)) + (and (is-a? x <py-bytearray>) (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 <py-bytes>) (b2 <bytevector>)) + (let* ((b1 (slot-ref o1 'bytes)) + (n1 (b-len b1)) + (n2 (b-len b2)) + (o (make <py-bytes>)) + (b (b-concat b1 n1 b2 n2))) + (slot-set! o 'bytes b) + o)) + +(define-method (+ (b2 <bytevector>) (o1 <py-bytes>)) + (let* ((b1 (slot-ref o1 'bytes)) + (n1 (b-len b1)) + (n2 (b-len b2)) + (o (make <py-bytes>)) + (b (b-concat b2 n2 b1 n1))) + (slot-set! o 'bytes b) + o)) + +(define-method (+ (b1 <bytevector>) (b2 <bytevector>)) + (let* ((n1 (b-len b1)) + (n2 (b-len b2))) + (b-concat b1 n1 b2 n2))) + +(define-method (+ (o1 <py-bytes>) (o2 <py-bytes>)) + (let* ((b1 (slot-ref o1 'bytes)) + (b2 (slot-ref o2 'bytes)) + (n1 (b-len b1)) + (n2 (b-len b2)) + (o (make <py-bytes>)) + (b (b-concat b1 n1 b2 n2))) + (slot-set! o 'bytes b) + o)) + +(define-method (+ (o1 <py-bytearray>) (o2 <py-bytes>)) + (let* ((b1 (slot-ref o1 'vec)) + (b2 (slot-ref o2 'bytes)) + (n1 (slot-ref o1 'n)) + (n2 (b-len b2)) + (o (make <py-bytearray>)) + (b (b-concat b1 n1 b2 n2))) + (slot-set! o 'vec b) + (slot-set! o 'n (+ n1 n2)) + o)) + +(define-method (+ (o1 <py-bytearray>) (b2 <bytevector>)) + (let* ((b1 (slot-ref o1 'vec)) + (n1 (slot-ref o1 'n)) + (n2 (b-len b2)) + (o (make <py-bytearray>)) + (b (b-concat b1 n1 b2 n2))) + (slot-set! o 'vec b) + (slot-set! o 'n (+ n1 n2)) + o)) + +(define-method (+ (o2 <py-bytes>) (o1 <py-bytearray>)) + (let* ((b1 (slot-ref o1 'vec)) + (b2 (slot-ref o2 'bytes)) + (n1 (slot-ref o1 'n)) + (n2 (b-len b2)) + (o (make <py-bytearray>)) + (b (b-concat b2 n2 b1 n1))) + (slot-set! o 'vec b) + (slot-set! o 'n (+ n1 n2)) + o)) + +(define-method (+ (b2 <bytevector>) (o1 <py-bytearray>) ) + (let* ((b1 (slot-ref o1 'vec)) + (n1 (slot-ref o1 'n)) + (n2 (b-len b2)) + (o (make <py-bytearray>)) + (b (b-concat b2 n2 b1 n1))) + (slot-set! o 'vec b) + (slot-set! o 'n (+ n1 n2)) + o)) + +(define-method (+ (o1 <py-bytearray>) (o2 <py-bytearray>)) + (let* ((b1 (slot-ref o1 'vec)) + (b2 (slot-ref o2 'vec)) + (n1 (slot-ref o1 'n)) + (n2 (slot-ref o2 'n)) + (o (make <py-bytearray>)) + (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 <py-bytearray>) m) + (let* ((b1 (slot-ref o1 'vec)) + (n1 (slot-ref o1 'n)) + (o (make <py-bytearray>)) + (b (b-rep b1 n1 m))) + (slot-set! o 'vec b) + (slot-set! o 'n (* n1 m)) + o)) + +(define-method (* (b1 <bytevector>) m) + (let* ((n1 (b-len b1))) + (b-rep b1 n1 m))) + +(define-method (* (o1 <py-bytes>) m) + (let* ((b1 (slot-ref o1 'bytes)) + (n1 (b-len b1)) + (o (make <py-bytes>)) + (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))) + +(define-python-class UnicodeDecodeError (Exception)) + +(define-py** decode (py-decode bytes o n . l) + (apply + (lam ((= encoding "UTF-8") (= errors "strict")) + (set! errors (py-lower (scm-str errors))) + (set! errors (cond + ((equal? errors "strict") + 'error) + ((equal? errors "escape") + 'escape) + ((equal? errors "replace") + 'substitute) + ((equal? errors "ignore") + (warn + (string-append + "not possible to use ignore " + "encodong error strategy " + "using replace in stead")) + 'substitute) + (else + (warn + "not a correct encodong error strategy") + 'error))) + (set! encoding (py-upper (scm-str encoding))) + + (let lp ((i 0) (r '())) + (if (< i n) + (lp (+ i 1) (cons (b-ref o i) r)) + (catch #t + (lambda () + (bytevector->string + (list->b (reverse r)) + encoding + errors)) + (lambda x + (raise (UnicodeDecodeError + (+ + "failed to decode " + encoding)))))))) + l)) + +;;;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 (<py-bytes>)) + (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* split (py-split bytes o n tag) + (let ((tag (b->list tag))) + (let lp ((i 0) (r '())) + (if (< i n) + (if (eq? (car tag) (b-ref o i)) + (let lp2 ((j i) (tag tag)) + (if (null? tag) + (cons (bytes (list->b (reverse r))) + (lp (+ i 1) '())) + (if (< j n) + (if (eq? (car tag) (b-ref o j)) + (lp2 (+ j 1) (cdr tag)) + (lp (+ i 1) (cons (b-ref o i) r))) + (lp (+ i 1) (cons (b-ref o i) r))))) + (lp (+ i 1) (cons (b-ref o i) r))) + '())))) +#; +(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 (make_trans b1 b2) + (let* ((b1 (bv-scm b1)) + (b2 (bv-scm b2)) + (n1 (len b1)) + (n2 (len b2)) + (n (let lp ((i 0) (r 0)) + (if (< i n1) + (lp (+ i 1) (max (bytevector-u8-ref b1 i) r)) + r)))) + (if (= n1 n2) + (let lp ((i 0) (r '())) + (if (< i n) + (let lp2 ((j 0)) + (if (< j n1) + (if (= (bytevector-u8-ref b1 j) i) + (lp (+ i 1) (cons (bytevector-u8-ref b2 j) r)) + (lp2 (+ j 1))) + (lp (+ i 1) (cons i r)))) + (bytes (list->u8vector (reverse r))))) + (raise + (ValueError + "maketrans: wrong number in second string compared to first"))))) + +(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 <bytevector>) (s2 <py-bytes>)) + (let ((b2 (slot-ref s2 'bytes))) + (cmp op b1 (b-len b1) b2 (b-len b2)))) + (define-method (op (s1 <py-bytes>) (b2 <bytevector>) ) + (let ((b1 (slot-ref s1 'bytes))) + (cmp op b1 (b-len b1) b2 (b-len b2)))) + (define-method (op (b1 <bytevector>) (b2 <bytevector>) ) + (cmp op b1 (b-len b1) b2 (b-len b2))) + (define-method (op (s1 <py-bytes>) (s2 <py-bytes>) ) + (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 <py-bytearray>) (b2 <bytevector>)) + (let ((b1 (slot-ref a1 'vec)) + (n1 (slot-ref a1 'n))) + (cmp op b1 n1 b2 (b-len b2)))) + (define-method (op (b1 <bytevector>) (a2 <py-bytearray>)) + (let ((b2 (slot-ref a2 'vec)) + (n2 (slot-ref a2 'n))) + (cmp op b1 (b-len b1) b2 n2))) + (define-method (op (a1 <py-bytearray>) (s2 <py-bytes>)) + (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 <py-bytes>) (a2 <py-bytearray>)) + (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 <py-bytearray>) (a2 <py-bytearray>)) + (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 <py-bytes>)) (hash (slot-ref o 'bytes) pyhash-N)) + +(define-class <bytes-iter> (<py-bytes>) i d) +(define-class <bytearray-iter> (<py-bytearray>) i d) + +(define-method (wrap-in (o <bytes-iter> )) + (let ((out (make <bytes-iter>))) + (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 <bytearray-iter> )) + (let ((out (make <bytearray-iter>))) + (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 <bytevector>)) + (let ((out (make <bytes-iter>))) + (slot-set! out 'bytes s) + (slot-set! out 'i 0) + (slot-set! out 'd 1) + out)) + +(define-method (wrap-in (s <py-bytes>)) + (let ((out (make <bytes-iter>))) + (slot-set! out 'bytes (slot-ref s 'bytes)) + (slot-set! out 'i 0) + (slot-set! out 'd 1) + out)) + +(define-method (wrap-in (s <py-bytearray>)) + (let ((out (make <bytes-iter>))) + (slot-set! out 'vec (slot-ref s 'vec)) + (slot-set! out 'n (slot-ref s 'n)) + (slot-set! out 'i 0) + (slot-set! out 'd 1) + out)) + +(define-method (py-reversed (s <py-bytes>)) + (let ((out (make <bytes-iter>))) + (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 <py-bytearray>)) + (let ((out (make <bytearray-iter>))) + (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 <bytes-iter>)) + (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 <bytearray-iter>)) + (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 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)) + +(define (_in x y n) + (let lp ((i 0)) + (if (< i n) + (if (= (b-ref y i) x) + #t + (lp (+ i 1))) + #f))) + +(define (_in2 x y n) + (let lp ((i 0)) + (if (< i n) + (let lp2 ((j i) (r x)) + (if (null? r) + #t + (if (< j n) + (if (= (b-ref y j) (car r)) + (lp2 (+ j 1) (cdr r)) + (lp (+ i 1))) + #f))) + #f))) + +(define-method (in (x <integer>) (b <bytevector>)) + (_in x b (len b))) +(define-method (in (x <integer>) (b <py-bytes>)) + (_in x (slot-ref b 'bytes) (len b))) +(define-method (in (x <integer>) (b <py-bytearray>)) + (_in x (slot-ref b 'vec) (len b))) + +(define-method (in (x <pair>) (b <bytevector>)) + (_in2 x b (len b))) +(define-method (in (x <pair>) (b <py-bytes>)) + (_in2 x (slot-ref b 'bytes) (len b))) +(define-method (in (x <pair>) (b <py-bytearray>)) + (_in2 x (slot-ref b 'vec) (len b))) + +(define-method (in (x <bytevector>) b) + (in (b->list x) b)) +(define-method (in (x <py-bytes>) b) + (in (b->list x) b)) +(define-method (in (x <py-bytearray>) b) + (in (b->list x) b)) + + +(set! (@@ (language python string) bytes) bytes) +(set! (@@ (language python string) b?) + (lambda (x) + (or (is-a? x <bytevector>) + (is-a? x <py-bytes>) + (is-a? x <py-bytearray>)))) +(set! (@@ (language python string) b-decode) py-decode) + +(define b-enc #f) diff --git a/modules/language/python/checksum.scm b/modules/language/python/checksum.scm new file mode 100644 index 0000000..dc0ce80 --- /dev/null +++ b/modules/language/python/checksum.scm @@ -0,0 +1,124 @@ +(define-module (language python checksum) + #:use-module (oop pf-objects) + #:use-module (language python bytes) + #:use-module (language python for) + #:use-module (language python list) + #:use-module (language python exceptions) + #:use-module (ice-9 binary-ports) + #:use-module (rnrs bytevectors) + #:use-module (ice-9 popen) + #:export (Summer run)) + +(define mapper (make-hash-table)) + +(let lp ((i 0)) + (if (< i 256) + (let ((a (logand #xf i)) + (b (ash (logand #xf0 i) -16))) + + (define (m i) + (car (string->list (number->string i 16)))) + + (hash-set! mapper i (cons (m a) (m b))) + (lp (+ i 1))))) + +(define (run data command) + (define n1 (char->integer #\0)) + (define n2 (char->integer #\9)) + (define p1 (char->integer #\a)) + (define p2 (char->integer #\f)) + + (let ((i.o (pipe))) + (with-output-to-port (cdr i.o) + (lambda () + (let ((port (open-pipe command OPEN_WRITE))) + (for ((b : data)) () + (put-u8 port b)) + (close-pipe port)))) + (close-port (cdr i.o)) + (let* ((ret (get-bytevector-all (car i.o))) + (n (len ret))) + (let lp ((i 0)) + (define (hex? i) + (and (< i n) + (let ((i (bytevector-u8-ref ret i))) + (or + (and (>= i n1) (<= i n2)) + (and (>= i p1) (<= i p2)))))) + + (define (hex i) + (let ((i (bytevector-u8-ref ret i))) + (if (and (>= i n1) (<= i n2)) + (+ (- i n1) 0) + (+ (- i p1) 10)))) + + (define (final l) + (let ((ret (make-bytevector (len l)))) + (let lp ((l l) (i (- (len l) 1))) + (if (>= i 0) + (begin + (bytevector-u8-set! ret i (car l)) + (lp (cdr l) (- i 1))) + (bytes ret))))) + + (if (hex? i) + (let lp ((i i) (l '())) + (if (hex? i) + (if (hex? (+ i 1)) + (lp (+ i 2) (cons (+ (hex i) (ash (hex (+ i 1)) 4)) + l)) + (final (cons (hex i) l))) + (final l))) + (error "no hex output checksum code")))))) + + + +(define-python-class Summer () + (define __init__ + (lambda (self) + (set self '_data None))) + + (define update + (lambda (self data) + (let ((old (ref self '_data))) + (if (eq? old None) + (set self '_data data) + (set self '_data (+ old data)))) + (set self '_digest None) + (values))) + + (define digest + (lambda (self) + (let ((data (ref self '_data))) + (if (eq? data None) + (raise (ValueError "no data to digest")) + (let ((old (ref self '_digest))) + (if (eq? old None) + (set! old (run data (ref self '_command)))) + (set self '_digest old) + old))))) + + + (define hexdigest + (lambda (self) + (let* ((x (digest self)) + (o (make-string (* 2 (len x))))) + (for ((b : (bv-scm x))) ((i 0)) + (let ((a.b (hash-ref mapper b))) + (string-set! o i (car a.b)) + (string-set! o (+ i 1) (cdr a.b)) + (+ i 2)) + #:final + o)))) + + (define copy + (lambda (self) + (let ((o ((ref self '__class__)))) + (set o '_data (ref self '_data)) + (set o '_digest (ref self '_digest)) + o)))) + + + + + diff --git a/modules/language/python/class.scm b/modules/language/python/class.scm new file mode 100644 index 0000000..41ed09a --- /dev/null +++ b/modules/language/python/class.scm @@ -0,0 +1,71 @@ +(define-module (language python class) + #:export (class_+ class_- class_* class_// class_% + class_power class_<< class_>> class_ior + class_xor class_band)) + +(define-syntax-rule (class-ref x) (struct-ref x 0)) +(define-syntax-rule (class-num x) (struct-ref x 1)) +(define-syntax-rule (class-log x) (struct-ref x 2)) +(define-syntax-rule (class-map x) (struct-ref x 3)) + +(define-syntax-rule (mkref +-ref n) + (define-syntax-rule (+-ref x) (vector-ref x n))) + +(mkref +-ref 0) +(mkref --ref 1) +(mkref *-ref 2) +(mkref /-ref 3) +(mkref //-ref 4) +(mkref %-ref 5) +(mkref **-ref 6) +(mkref <<-ref 7) +(mkref >>-ref 8) + +(mkref ior-ref 0) +(mkref xor-ref 1) +(mkref and-ref 2) + +(define-syntax-rule (class-lookup class key ) + (hashq-ref (class-map class) key #f)) + +(define-syntax-rule (meta-mk mk-num class-num) +(define-syntax-rule (mk-num class_+ __add__ __radd__ +-ref err) + (define (class_+ x y) + (let* ((cl (class-ref x)) + (r (class-num cl))) + (define (f) + (let ((rrr (class-lookup cl '__add__))) + (if rrr + (rrr x y) + (if (class? y) + (let* ((cl (class-ref y)) + (rrrr (class-lookup cl '__radd__))) + (if rrrr + (rrrr y x) + (err))) + (err))))) + + (if r + (let ((rr (+-ref r))) + (if rr + (rr x y) + (f))) + (f)))))) + +(meta-mk mk-num class-num) +(meta-mk mk-log class-log) + +(define (err) (error "could not do artithmetic ops")) + +(mk-num class_+ __add__ __radd__ +-ref err) +(mk-num class_- __sub__ __rsub__ --ref err) +(mk-num class_* __mul__ __rmul__ *-ref err) +(mk-num class_/ __div__ __rdiv__ /-ref err) +(mk-num class_// __floordiv__ __rfloordiv__ //-ref err) +(mk-num class_% __divmod__ __rdivmod__ %-ref err) +(mk-num class_power __pow__ __rpow__ **-ref err) +(mk-num class_<< __lshift__ __rlshift__ <<-ref err) +(mk-num class_>> __rshift__ __rrshift__ >>-ref err) +(mk-log class_ior __or__ __ror__ ior-ref err) +(mk-log class_xor __xor__ __rxor__ xor-ref err) +(mk-log class_band __and__ __rand__ and-ref err) |