diff options
Diffstat (limited to 'modules/language/python/module/struct.scm')
-rw-r--r-- | modules/language/python/module/struct.scm | 222 |
1 files changed, 125 insertions, 97 deletions
diff --git a/modules/language/python/module/struct.scm b/modules/language/python/module/struct.scm index 5f5e872..b3d5b9f 100644 --- a/modules/language/python/module/struct.scm +++ b/modules/language/python/module/struct.scm @@ -1,19 +1,31 @@ (define-module (language python module struct) #:use-module (oop pf-objects) + #:use-module (ice-9 match) + #:use-module (rnrs bytevectors) + #:use-module (parser stis-parser) #:use-module (language python list) + #:use-module (language python bool) #:use-module (language python yield) + #:use-module (language python def) + #:use-module (language python exceptions) #:export (calcsize pack pack_into unpack unpack_from iter_unpack Struct error)) -(define-python-class StructError (Error)) +(define-python-class StructError (Exception)) + +(define bytevector-f32-ref bytevector-ieee-single-ref) +(define bytevector-f32-set! bytevector-ieee-single-set!) +(define bytevector-f64-ref bytevector-ieee-double-ref) +(define bytevector-f64-set! bytevector-ieee-double-set!) + (define error StructError) (define (analyze s) ;; Parser - (define f-head (make-token (f-or! (f-reg! "[@=<>!]") (f-out "@")))) - (define f-1 (make-token (f-reg! "[xcbB?hHiIlLqQnNefdspP]"))) - (define f-item (f-or! (f-list (make-token (f+ (f-tag! "[0-9]")) - string->number) + (define f-head (f-or! (mk-token (f-reg! "[@=<>!]")) (f-out "@"))) + (define f-1 (mk-token (f-reg! "[xcbB?hHiIlLqQnNefdspP]"))) + (define f-item (f-or! (f-list (mk-token (f+ (f-reg! "[0-9]")) + string->number) f-1) (f-list (f-out 1) f-1))) (define f-e (f-cons f-head (ff* f-item))) @@ -37,10 +49,10 @@ (define (incr i n) (+ i (if pack n - (+ n (let ((x (modulo n 8))) + (+ n (let ((x (modulo n 4))) (if (= x 0) 0 - (- 8 x))))))) + (- 4 x))))))) (define c-x (lambda (k) @@ -110,8 +122,8 @@ (cons (bytevector-u64-ref bv i end) (k bv (incr i 8)))))) - (define c-i c-i8) - (define c-I c-I8) + (define c-i c-i4) + (define c-I c-I4) (define c-l (if standard c-i4 c-l8)) (define c-L (if standard c-I4 c-L8)) @@ -134,7 +146,7 @@ (cons (bytevector-f64-ref bv i end) (k bv (incr i 8)))))) - (define c-g + (define c-e (lambda (k) (lambda (bv i) (let* ((num (bytevector-u16-ref bv i end)) @@ -143,7 +155,7 @@ (mant (logand #x3ff num))) (cons (cond ((= exp 0) - (* (if (= sign 0) 0 -1) + (* (if (= sign 0) 1 -1) (expt 2 -14) (string->number (format #f "0.~a" mant)))) ((= exp #x1f) @@ -151,9 +163,16 @@ (inf) (- (inf)))) (else - (* (if (= sign 0) 0 -1) + (* (if (= sign 0) 1 -1) (expt 2 (- exp 15)) - (string->number (format #f "1.~a" mant))))) + (+ 1 + (cond + ((< mant 10) + (/ mant 1000.0)) + ((< mant 100) + (/ mant 100.0)) + (else + (/ mant 10.0))))))) (k bv (incr i 2))))))) @@ -182,7 +201,7 @@ (let lp ((j 0) (l i)) (if (and (< j size) (< j N)) (begin - (bytevector-u8-set! bvv j (bytevector-u8-ref bv l) r) + (bytevector-u8-set! bvv j (bytevector-u8-ref bv l)) (lp (+ j 1) (+ l 1))) (cons bvv (k bv (incr i N))))))))) @@ -227,7 +246,7 @@ l (cons (list (- n 1) tp) l)))) bv i))) - (() (lambda (bv i) '()))))) + (() '())))) bv n)) (define (unpack format buffer) @@ -238,9 +257,9 @@ (unpacker (analyze format) buffer offset))) (define (iter_unpack format buffer) - (let ((l (analyze format)) - (n (len buffer)) - (m (calcsize l))) + (let* ((l format) + (n (len buffer)) + (m (calcsize l))) ((make-generator (lambda (yield) (let lp ((i 0)) @@ -250,60 +269,61 @@ (lp (+ i m)))))))))) (define (calcsize format) - (define type (car format)) - (define rest (cdr l)) - (define pack (member type '("@"))) - (define end (if (member type '("@")) - (native-endianness) - (if (member type '("<")) - 'little - 'big))) - (define standard (not (member type '("@")))) - - (define (sz p i) - (if p - i - (let ((x (modulo i 8))) - (if (= x 0) i (+ i (- 8 x)))))) - - (define (size n p tp) - (sz p - (match tp - ((or "x" "c" "B" "b" "?") - 1) - ((or "h" "H" "g") - 2) - ((or "i" "I" "f") - 4) - ((or "q" "Q" "n" "N" "d" "P") - 8) - ((or "l" "L") - (if standard 4 8)) - ((or "s" "p") - n)))) - - (if (string? format) - (calcsize (analyze format)) - (let ((type (car format))) - (let lp ((l (cdr format))) - (match l - (((1 tp) . l) - (+ (size 1 (null? l) tp))) - (((n (or "s" "p")) . l) - (+ (size n (null? l) tp) - (lp l))) - (((n tp) . l) - (+ (size (- n 1) #f tp) - (lp (cons (list 1 tp) l)))) - (() 0)))))) - + (let lp ((format format)) + (if (string? format) + (lp (analyze format)) + (let () + (define type (car format)) + (define rest (cdr format)) + (define pack (member type '("@"))) + (define end (if (member type '("@")) + (native-endianness) + (if (member type '("<")) + 'little + 'big))) + (define standard (not (member type '("@")))) + + (define (sz p i) + (if p + i + (let ((x (modulo i 4))) + (if (= x 0) i (+ i (- 4 x)))))) + + (define (size n p tp) + (sz p + (match tp + ((or "x" "c" "B" "b" "?") + 1) + ((or "h" "H" "e") + 2) + ((or "i" "I" "f") + 4) + ((or "q" "Q" "n" "N" "d" "P") + 8) + ((or "l" "L") + (if standard 4 8)) + ((or "s" "p") + n)))) + + (let lp ((l (cdr format))) + (match l + (((1 tp) . l) + (+ (size 1 (null? l) tp))) + (((n (and tp (or "s" "p"))) . l) + (+ (size n (null? l) tp) + (lp l))) + (((n tp) . l) + (+ (size (- n 1) #f tp) + (lp (cons (list 1 tp) l)))) + (() 0))))))) + (define (pack_into_ format bv offset l) - (let lp ((l format)) - (if (string? l) - (lp (analyze l)) + (let lp ((format format)) + (if (string? format) + (lp (analyze format)) (let () - (define type (car l)) - (define rest (cdr l)) + (define type (car format)) + (define rest (cdr format)) (define pack (member type '("@"))) (define end (if (member type '("@")) (native-endianness) @@ -311,7 +331,15 @@ 'little 'big))) (define standard (not (member type '("@")))) - + + (define (incr i n) + (+ i (if pack + n + (+ n (let ((x (modulo n 4))) + (if (= x 0) + 0 + (- 4 x))))))) + (define c-x (lambda (i) (bytevector-u8-set! bv i 0) @@ -320,52 +348,52 @@ (define c-c (lambda (i l) (bytevector-u8-set! bv i (pylist-ref (car l) 0)) - (values (inc i 1) (cdr l)))) + (values (incr i 1) (cdr l)))) (define c-b (lambda (i l) (bytevector-s8-set! bv i (car l)) - (values (inc i 1) (cdr l)))) + (values (incr i 1) (cdr l)))) (define c-B (lambda (i l) (bytevector-u8-set! bv i (car l)) - (values (inc i 1) (cdr l)))) + (values (incr i 1) (cdr l)))) (define c-? (lambda (i l) (bytevector-u8-set! bv i (if (bool (car l)) 1 0)) - (values (inc i 1) (cdr l)))) + (values (incr i 1) (cdr l)))) (define c-h (lambda (i l) (bytevector-s16-set! bv i (car l) end) - (values (inc i 2) (cdr l)))) + (values (incr i 2) (cdr l)))) (define c-H (lambda (i l) (bytevector-u16-set! bv i (car l) end) - (values (inc i 2) (cdr l)))) + (values (incr i 2) (cdr l)))) (define c-i (lambda (i l) (bytevector-s32-set! bv i (car l) end) - (values (inc i 4) (cdr l)))) + (values (incr i 4) (cdr l)))) (define c-I (lambda (i l) (bytevector-u32-set! bv i (car l) end) - (values (inc i 4) (cdr l)))) + (values (incr i 4) (cdr l)))) (define c-l8 (lambda (i l) (bytevector-s64-set! bv i (car l) end) - (values (inc i 8) (cdr l)))) + (values (incr i 8) (cdr l)))) (define c-L8 (lambda (i l) (bytevector-u64-set! bv i (car l) end) - (values (inc i 8) (cdr l)))) + (values (incr i 8) (cdr l)))) (define c-l (if standard c-i c-l8)) (define c-L (if standard c-I c-L8)) @@ -373,36 +401,36 @@ (define c-q (lambda (i l) (bytevector-s64-set! bv i (car l) end) - (values (inc i 8) (cdr l)))) + (values (incr i 8) (cdr l)))) (define c-Q (lambda (i l) (bytevector-u64-set! bv i (car l) end) - (values (inc i 8) (cdr l)))) + (values (incr i 8) (cdr l)))) (define c-n (lambda (i l) (bytevector-s64-set! bv i (car l) end) - (values (inc i 8) (cdr l)))) + (values (incr i 8) (cdr l)))) (define c-N (lambda (i l) (bytevector-u64-set! bv i (car l) end) - (values (inc i 8) (cdr l)))) + (values (incr i 8) (cdr l)))) (define c-e (let ((X (expt 2 -14)) (XX (expt 2 -24))) (lambda (i l) (let* ((x (car l)) - (s (>= x 0) 0 1) + (s (if (>= x 0) 0 1)) (x (abs x)) (e (if (< x X) (if (< x XX) #x1f - 0)) - (inexact->exact - (floor (+ (log2 x) 15)))) + 0) + (inexact->exact + (floor (+ (/ (log x) (log 2)) 15))))) (s? (= e 0)) (i? (= e #x1f)) (m (if i? @@ -414,26 +442,26 @@ (inexact->exact (floor (* x (expt 2 14))))))) - (x (logand (ash s 16) + (x (logior (ash s 16) (ash (logand e #x1f ) 10) (ash (logand m #x3ff) 00)))) (bytevector-u16-set! bv i x end) - (values (inc i 2) (cdr l)))))) + (values (incr i 2) (cdr l)))))) (define c-f (lambda (i l) (bytevector-f32-set! bv i (car l) end) - (values (inc i 4) (cdr l)))) + (values (incr i 4) (cdr l)))) (define c-d (lambda (i l) (bytevector-f64-set! bv i (car l) end) - (values (inc i 8) (cdr l)))) + (values (incr i 8) (cdr l)))) (define c-P (lambda (i l) (bytevector-u64-set! bv i (car l) end) - (values (inc i 8) (cdr l)))) + (values (incr i 8) (cdr l)))) (define c-s (lambda (i l n) @@ -443,7 +471,7 @@ (begin (bytevector-u8-set! bv k (pylist-ref x j)) (lp (+ j 1) (+ k 1))) - (values (inc i n) (cdr l))))))) + (values (incr i n) (cdr l))))))) (define c-p (lambda (i l n) @@ -461,7 +489,7 @@ (begin (bytevector-u8-set! bv k 0) (lp (+ j 1) (+ k 1))) - (values (inc i n) (cdr l))))))))) + (values (incr i n) (cdr l))))))))) (define tr (make-hash-table)) @@ -488,7 +516,7 @@ (hash-set! tr "p" c-p) (hash-set! tr "P" c-P) - (let lp ((p rest) (i offset) (l rest)) + (let lp ((p rest) (i offset) (l l)) (match p (((n (and tp (or "p" "s"))) . p) (call-with-values |