From db48ec7818abefc43679922b71b02a01e7567a91 Mon Sep 17 00:00:00 2001 From: Stefan Israelsson Tampe Date: Fri, 17 Aug 2018 21:05:18 +0200 Subject: to_bytes, from_bytes, split --- modules/language/python/compile.scm | 1 + modules/language/python/module/_python.scm | 1 + modules/language/python/module/ipaddress.py | 6 +- modules/language/python/number.scm | 84 +++++++++++++++++++++++++--- modules/language/python/string.scm | 85 ++++++++++++++++++++--------- 5 files changed, 140 insertions(+), 37 deletions(-) diff --git a/modules/language/python/compile.scm b/modules/language/python/compile.scm index bbeb069..43db80f 100644 --- a/modules/language/python/compile.scm +++ b/modules/language/python/compile.scm @@ -386,6 +386,7 @@ ((conjugate) (N 'py-conjugate)) ((denominator) (N 'py-denominator)) ((numerator) (N 'py-numerator)) + ((to_bytes) (N 'py-to-bytes)) ((fromhex) (N 'py-fromhex)) ((hex) (N 'py-hex)) ((imag) (N 'py-imag)) diff --git a/modules/language/python/module/_python.scm b/modules/language/python/module/_python.scm index 11d6710..4f96611 100644 --- a/modules/language/python/module/_python.scm +++ b/modules/language/python/module/_python.scm @@ -41,6 +41,7 @@ tuple bytes bytearray eval locals globals exec type object open __import__ frozenset Warning BytesWarning DeprecationWarning + py-list ) #:export (print repr complex float int str diff --git a/modules/language/python/module/ipaddress.py b/modules/language/python/module/ipaddress.py index eafbd3e..f084bfa 100644 --- a/modules/language/python/module/ipaddress.py +++ b/modules/language/python/module/ipaddress.py @@ -1532,9 +1532,10 @@ class IPv4Network(_BaseV4, _BaseNetwork): else: arg = self._max_prefixlen self.netmask, self._prefixlen = self._make_netmask(arg) - + xx = int(self.netmask) + yy = int(self.network_address) if strict: - if (IPv4Address(int(self.network_address) & int(self.netmask)) != + if (IPv4Address(yy & xx) != self.network_address): raise ValueError('%s has host bits set' % self) self.network_address = IPv4Address(int(self.network_address) & @@ -2207,6 +2208,7 @@ class IPv6Network(_BaseV6, _BaseNetwork): self.netmask, self._prefixlen = self._make_netmask(arg) self.network_address = IPv6Address(address[0]) packed = int(self.network_address) + if packed & int(self.netmask) != packed: if strict: raise ValueError('%s has host bits set' % self) 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 ) . l) (apply write (slot-ref o 'x) l)) +(define-method (py-from-bytes (o

) . l) + (aif it (ref o 'from_bytes) + (apply it l) + (next-method))) + +(define-method (py-from-bytes (o ) . l) + (apply py-from-bytes int l)) + +(define-method (py-to-bytes (o

) . 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 ) . 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 ( ) (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)) diff --git a/modules/language/python/string.scm b/modules/language/python/string.scm index 9a58712..3069527 100644 --- a/modules/language/python/string.scm +++ b/modules/language/python/string.scm @@ -407,33 +407,66 @@ l)) (define-py (py-split split s . l) - (define ws (f+ (f-reg "[ \t\n]"))) - (define (r ws) - (f-or! (f-seq f-eof (f-out '())) - (f-cons (f-seq (f? ws) (mk-token (f* (f-reg! "."))) f-eof) - (f-out '())))) - (define (u ws) (mk-token (f+ (f-not! ws)))) - (define (tok ws i) - (if (= i 0) - (f-list (mk-token (f* (f-reg! ".")))) - (let ((e (mk-token (f* (f-not! ws))))) - (f-seq (f? ws) - (f-cons* e - (let lp ((i i)) - (if (> (- i 1) 0) - (f-or! (f-seq (f? ws) f-eof (f-out '())) - (f-cons (f-seq ws e) (Ds (lp (- i 1))))) - (r ws)))))))) + (define N 1000000000000) + + (define ws (list (list (char->integer #\space)) + (list (char->integer #\newline)) + (list (char->integer #\tab)))) + + (define (to-ch x) (string-ref (scm-str x) 0)) - (define N 1000000000000) - (let ((e (call-with-values - (lambda () - (match l - (() (values ws N)) - ((sep) (values (f-tag sep) N)) - ((sep n) (values (f-tag sep) n)))) - tok))) - (parse s e))) + (define (mksep sep) + (for ((x : sep)) ((l '())) + (cons + (cond + ((and (number? x) (integer? x)) + (integer->char x)) + ((char? x) + x) + (else + (to-ch x))) l) + #:final + (list (reverse l)))) + + (call-with-values + (lambda () + (match l + (() (values (list ws ) N)) + ((sep) (values (mksep sep) N)) + ((sep n) (values (mksep sep) n)))) + (lambda (sep n) + (let lp ((l (to-list s)) (i 0) (v '()) (r '())) + (if (= i n) + (reverse r) + (if (pair? l) + (let ((ch (to-ch (car l)))) + (let lp2 ((ss sep)) + (if (pair? ss) + (let lp3 ((sl (car ss)) (l3 l)) + (if (pair? sl) + (if (pair? l3) + (let ((s (car sl))) + (if (eqv? s ch) + (lp3 (cdr sl) (cdr l3)) + (lp2 (cdr ss)))) + (lp2 (cdr ss))) + (lp l3 (+ i 1) + '() + (cons + (list->string (reverse v)) + r)))) + (lp (cdr l) i (cons ch v) r)))) + (reverse (cons (list->string (reverse v)) r)))))))) + + + + + + + + + + (define-py (py-rsplit rsplit s . l) (reverse -- cgit v1.2.3