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.scm34
1 files changed, 33 insertions, 1 deletions
diff --git a/modules/language/python/number.scm b/modules/language/python/number.scm
index b51cd6b..e25c612 100644
--- a/modules/language/python/number.scm
+++ b/modules/language/python/number.scm
@@ -4,7 +4,10 @@
#:use-module (language python hash)
#:use-module (language python list)
#:use-module (language python try)
+ #:use-module (language python for)
+ #:use-module (language python def)
#:use-module (language python exceptions)
+ #:use-module (language python bytes)
#:use-module (language python persist)
#:export (py-int py-float py-complex
py-/ py-logand py-logior py-logxor py-abs py-trunc
@@ -307,6 +310,35 @@
(apply write (slot-ref o 'x) l))
(define-python-class int (<py> <py-int>)
+ (define from_bytes
+ (class-method
+ (lam (self bytes byteorder (= signed #f))
+ (for ((x : bytes)) ((l '()))
+ (cons
+ (let ((i (if (and (number? x) (integer? x))
+ x
+ (list-ref (bv-scm x) 0))))
+ (if (not (and (number? i) (integer? i)
+ (>= i 0) (<= i 356)))
+ (raise (ValueError "wrong bytevector in from_bytes"))
+ i))
+ l)
+ #:final
+ (begin
+ (if (equal? byteorder "big")
+ (set! l (reverse l)))
+ (let lp ((s 0) (i 0) (l l))
+ (if (pair? l)
+ (let ((x (car l)))
+ (if (null? (cdr l))
+ (if (and signed (not (= 0 (logand x #x80))))
+ (set! x (logand x #x7f))
+ (set! signed #f)))
+ (lp (logior s (ash x i)) (+ i 8) (cdr l)))
+ (if signed
+ (let ((mask (ash 1 (- i 1))))
+ (- s mask))
+ s))))))))
(define __new__
(letrec ((__new__
(case-lambda
@@ -440,7 +472,7 @@
__rpow__ __rrshift__ __rshift__ __rsub__ __rtruediv__
__rxor__ __setattr__ __sizeof__ __str__ __sub__
__subclasshook__ __truediv__ __trunc__ __xor__
- bit_length conjugate denominator imag numerator
+ bit_length conjugate denominator imag numerator from_bytes
real)))))
(pylist-sort! l)
l))