summaryrefslogtreecommitdiff
path: root/modules/language/python/number.scm
diff options
context:
space:
mode:
Diffstat (limited to 'modules/language/python/number.scm')
-rw-r--r--modules/language/python/number.scm84
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))