diff options
Diffstat (limited to 'modules/language/python/number.scm')
-rw-r--r-- | modules/language/python/number.scm | 84 |
1 files changed, 75 insertions, 9 deletions
diff --git a/modules/language/python/number.scm b/modules/language/python/number.scm index e25c612..a44707c 100644 --- a/modules/language/python/number.scm +++ b/modules/language/python/number.scm @@ -1,6 +1,7 @@ (define-module (language python number) #:use-module (oop pf-objects) #:use-module (oop goops) + #:use-module (rnrs bytevectors) #:use-module (language python hash) #:use-module (language python list) #:use-module (language python try) @@ -18,7 +19,7 @@ py-as-integer-ratio py-conjugate py-fromhex py-hex py-imag py-is-integer py-real hex py-bin py-index py-ifloordiv py-ilshift py-imod py-imul py-imatmul - py-bit-length + py-bit-length py-to-bytes py-ilogior py-ilogand py-ipow py-isub py-i/ py-irshift py-ilogxor)) @@ -309,6 +310,68 @@ (define-method (write (o <py-int>) . l) (apply write (slot-ref o 'x) l)) +(define-method (py-from-bytes (o <p>) . l) + (aif it (ref o 'from_bytes) + (apply it l) + (next-method))) + +(define-method (py-from-bytes (o <integer>) . l) + (apply py-from-bytes int l)) + +(define-method (py-to-bytes (o <p>) . l) + (aif it (ref o 'to_bytes) + (apply it l) + (aif it (ref o '__int__) + (apply py-to-bytes (int) l) + (next-method)))) + +(define-method (py-to-bytes (o <integer>) . l) + (apply + (lam (length (= byteorder "big") (= signed #f)) + (let ((big? (cond + ((equal? byteorder "little") + #f) + ((equal? byteorder "big") + #t) + (else + (raise (ValueError "to_bytes with wrong byteorder")))))) + + (if (and (< o 0) (not signed)) + (raise (OverflowError + "to_byted, integer negative but not signed"))) + + (if signed + (let ((mask (ash 1 (- (* 8 length) 1)))) + (set! o (+ mask o)))) + + (let lp ((o o) (l '())) + (if (= o 0) + (let ((n (len l))) + (if (> n length) + (raise (OverflowError + "to bytes number larger than size"))) + (let lp ((i (len l)) (l l)) + (if (< i length) + (lp (+ i 1) (cons 0 l)) + (begin + (if signed + (let ((x (car l))) + (if (> (logand x #x80) 0) + (raise + "OverflowError to large number compared to size in to_bytes")) + (set-car! l (logior #x80 x)))) + + (bytes + (if big? + l + (reverse l))))))) + (lp (ash o -8) (cons (logand o #xff) l)))))) + l)) + + + + + (define-python-class int (<py> <py-int>) (define from_bytes (class-method @@ -325,7 +388,7 @@ l) #:final (begin - (if (equal? byteorder "big") + (if (equal? byteorder "little") (set! l (reverse l))) (let lp ((s 0) (i 0) (l l)) (if (pair? l) @@ -364,12 +427,15 @@ (else (catch #t (lambda () - (aif it (slot-ref n '__int__) - it - (raise (ValueError (py-mod "could not make int from %r" - (list n)))))) - (lambda z (raise (ValueError (py-mod "could not make int from %r" - (list n)))))))))) + (aif it (ref n '__int__) + (it) + (raise (ValueError + (py-mod "could not make int from %r" + (list n)))))) + (lambda z + (raise + (ValueError (py-mod "could not make int from %r" + (list n)))))))))) ((self n k) (__new__ self (string->number n k)))))) @@ -472,7 +538,7 @@ __rpow__ __rrshift__ __rshift__ __rsub__ __rtruediv__ __rxor__ __setattr__ __sizeof__ __str__ __sub__ __subclasshook__ __truediv__ __trunc__ __xor__ - bit_length conjugate denominator imag numerator from_bytes + bit_length conjugate denominator imag numerator from_bytes to_bytes real))))) (pylist-sort! l) l)) |