1 (define-module (language python number
)
2 #:use-module
(oop pf-objects
)
3 #:use-module
(oop goops
)
4 #:use-module
(language python hash
)
5 #:use-module
(language python list
)
6 #:use-module
(language python try
)
7 #:use-module
(language python exceptions
)
8 #:use-module
(language python persist
)
9 #:export
(py-int py-float py-complex
10 py-
/ py-logand py-logior py-logxor py-abs py-trunc
11 py-lshift py-rshift py-mod py-floordiv py-round py-iadd
13 <py-int
> <py-float
> <py-complex
>
14 py-divmod pyfloat-listing pyint-listing pycomplex-listing
15 py-as-integer-ratio py-conjugate py-fromhex py-hex py-imag
16 py-is-integer py-real hex py-bin py-index
17 py-ifloordiv py-ilshift py-imod py-imul py-imatmul
18 py-ilogior py-ilogand py-ipow py-isub py-i
/
19 py-irshift py-ilogxor
))
21 (define-syntax-rule (aif it p x y
) (let ((it p
)) (if it x y
)))
23 (define-syntax-rule (mki py-iadd __iadd__
)
25 ((ref x
'__iadd__
) y
)))
27 (mki py-iadd __iadd__
)
29 (mki py-matmul __matmul__
)
30 (mki py-ifloordiv __ifloordiv__
)
31 (mki py-ilshift __ilshift__
)
32 (mki py-imod __imod__
)
33 (mki py-imul __imul__
)
34 (mki py-imatmul __imatmul__
)
35 (mki py-ilogior __ior__
)
36 (mki py-ilogand __iand__
)
37 (mki py-ipow __ipow__
)
38 (mki py-isub __isub__
)
39 (mki py-irshift __irshift__
)
40 (mki py-ilogxor __ixor__
)
41 (mki py-i
/ __itruediv__
)
44 (define-class <py-int
> () x
)
45 (define-class <py-float
> () x
)
46 (define-class <py-complex
> () x
)
48 (name-object <py-int
>)
49 (name-object <py-float
>)
50 (name-object <py-complex
>)
52 (define-syntax-rule (mk <py-int
>)
53 (cpit <py-int
> (o (lambda (o x
) (slot-set! o
'x x
)) (list (slot-ref o
'x
)))))
59 (define-syntax-rule (b0 op
)
61 (define-method (op (o1 <py-int
>) o2
)
62 (op (slot-ref o1
'x
) o2
))
63 (define-method (op (o1 <py-float
>) o2
)
64 (op (slot-ref o1
'x
) o2
))
65 (define-method (op (o1 <py-complex
>) o2
)
66 (op (slot-ref o1
'x
) o2
))
67 (define-method (op o2
(o1 <py-int
>))
68 (op o2
(slot-ref o1
'x
)))
69 (define-method (op o2
(o1 <py-complex
>))
70 (op o2
(slot-ref o1
'x
)))
71 (define-method (op o2
(o1 <py-float
>))
72 (op o2
(slot-ref o1
'x
)))))
74 (define-syntax-rule (mk-biop1 mk-biop0 op r1
)
77 (define-method (op (o <p
>) v
)
82 (define-syntax-rule (mk-biop2 mk-biop0 rop op r1 r2
)
84 (define-syntax-rule (rop x y
) (op y x
))
85 (mk-biop1 mk-biop0 op r1
)
86 (define-method (op v
(o <p
>))
91 (define-syntax-rule (i0 op
)
93 (define-method (op (o1 <py-int
>) o2
)
94 (op (slot-ref o1
'x
) o2
))
95 (define-method (op o2
(o1 <py-int
>))
96 (op o2
(slot-ref o1
'x
)))))
99 (mk-biop2 b0 r
+ + __add__ __radd__
)
100 (mk-biop2 b0 r- - __sub__ __rsub__
)
101 (mk-biop2 b0 r
* * __mul__ __rmul__
)
103 (mk-biop1 b0
< __le__
)
104 (mk-biop1 b0
> __ge__
)
105 (mk-biop1 b0
<= __lt__
)
106 (mk-biop1 b0
>= __gt__
)
107 (mk-biop2 b0 rexpt expt __pow__ __rpow__
)
111 (define-method (py-lshift (o1 <integer
>) (o2 <integer
>))
113 (define-method (py-rshift (o1 <integer
>) (o2 <integer
>))
116 (mk-biop2 i0 py-rlshift py-lshift __lshift__ __rlshift__
)
117 (mk-biop2 i0 py-rrshift py-rshift __rshift__ __rrshift__
)
119 (define-method (py-logand (o1 <integer
>) (o2 <integer
>))
121 (define-method (py-logior (o1 <integer
>) (o2 <integer
>))
123 (define-method (py-logxor (o1 <integer
>) (o2 <integer
>))
125 (define-method (py-lognot (o1 <integer
>))
128 (define-method (py-logand o1
(o2 <py-int
>))
129 (py-logand o1
(slot-ref o2
'x
)))
131 (define-method (py-logand (o1 <py-int
>) o2
)
132 (py-logand (slot-ref o1
'x
) o2
))
134 (define-method (py-logior o1
(o2 <py-int
>))
135 (py-logior o1
(slot-ref o2
'x
)))
137 (define-method (py-logior (o1 <py-int
>) o2
)
138 (py-logior (slot-ref o1
'x
) o2
))
140 (define-method (py-logxor o1
(o2 <py-int
>))
141 (py-logxor o1
(slot-ref o2
'x
)))
143 (define-method (py-logxor (o1 <py-int
>) o2
)
144 (py-logxor (slot-ref o1
'x
) o2
))
146 (define-method (py-lognot (o1 <py-int
>))
147 (lognot (slot-ref o1
'x
)))
149 (define-method (py-logand (o1 <p
>) o2
)
150 (aif it
(ref o1
'__and__
)
154 (define-method (py-logand o1
(o2 <p
>))
155 (aif it
(ref o1
'__rand__
)
159 (define-method (py-logior (o1 <p
>) o2
)
160 (aif it
(ref o1
'__or__
)
164 (define-method (py-logior o1
(o2 <p
>))
165 (aif it
(ref o1
'__ror__
)
169 (define-method (py-logxor (o1 <p
>) o2
)
170 (aif it
(ref o1
'__xor__
)
174 (define-method (py-logxor o1
(o2 <p
>))
175 (aif it
(ref o1
'__rxor__
)
179 (define-method (py-lognot (o1 <p
>))
180 (aif it
(ref o1
'__not__
)
185 (define-method (py-/ (o1 <number
>) (o2 <integer
>))
186 (/ o1
(exact->inexact o2
)))
187 (define-method (py-/ (o1 <number
>) (o2 <number
>))
190 (define-method (py-divmod (o1 <integer
>) (o2 <integer
>))
192 (floor-quotient o1 o2
)
195 (define-method (py-divmod (o1 <number
>) (o2 <number
>))
197 (floor-quotient o1 o2
)
198 (floor-remainder o1 o2
)))
200 (define-method (py-floordiv (o1 <number
>) (o2 <number
>))
201 (floor-quotient o1 o2
))
203 (mk-biop2 b0 py-rfloordiv py-floordiv __floordiv__ __rfloordiv__
)
204 (mk-biop2 b0 py-rdivmod py-divmod __divmod__ __rdivmod__
)
205 (mk-biop2 b0 py-r
/ py-
/ __truediv__ __rtruediv__
)
207 (mk-biop2 i0 py-rlogand py-logand __and__ __rand__
)
208 (mk-biop2 i0 py-rlogior py-logior __or__ __ror__
)
209 (mk-biop2 i0 py-rlogxor py-logxor __xor__ __rxor__
)
211 (define-method (py-mod (o1 <integer
>) (o2 <integer
>))
213 (define-method (py-mod (o1 <real
>) (o2 <real
>))
214 (floor-remainder o1 o2
))
216 (mk-biop2 i0 py-rmod py-mod __mod__ __rmod__
)
219 (define-method (py-floor (o1 <integer
>)) o1
)
220 (define-method (py-floor (o1 <number
> )) )
221 (define-method (py-trunc (o1 <integer
>)) (exact->inexact o1
))
222 (define-method (py-trunc (o1 <number
> ))
225 (define-syntax-rule (u0 f
)
227 (define-method (f (o <py-int
> )) (f (slot-ref o
'x
)))
228 (define-method (f (o <py-float
>)) (f (slot-ref o
'x
)))
229 (define-method (f (o <py-complex
>)) (f (slot-ref o
'x
)))))
231 (define-syntax-rule (i0 f
)
233 (define-method (f (o <py-int
> )) (f (slot-ref o
'x
)))))
235 (define-syntax-rule (mk-unop u0 f r
)
238 (define-method (f (o <p
>))
242 (mk-unop u0 - __neg__
)
243 (mk-unop u0 py-trunc __trunc__
)
244 (mk-unop i0 py-lognot __invert__
)
246 (define-method (py-bit-length (i <integer
>))
249 (define-method (py-conjugate (i <complex
>))
250 (make-rectangular (real-part i
) (- (imag-part i
))))
251 (define-method (py-conjugate (i <number
>)) i
)
253 (define-method (py-imag (i <complex
>)) (imag-part i
))
254 (define-method (py-imag (i <number
>)) i
)
256 (define-method (py-real (i <complex
>)) (real-part i
))
257 (define-method (py-real (i <number
>)) i
)
259 (define-method (py-denominator (o <integer
>)) 0)
260 (define-method (py-denominator (o <real
>))
261 (denominator (inexact->exact o
)))
263 (define-method (py-numerator (o <integer
>)) o
)
264 (define-method (py-numerator (o <real
> ))
265 (numerator (inexact->exact o
)))
267 (define-method (py-as-integer-ratio (o <integer
>))
269 (define-method (py-as-integer-ratio (o <real
>))
270 (let ((r (inexact->exact o
)))
271 (list (numerator r
) (denominator r
))))
273 (define-method (py-fromhex (o <real
>))
274 (error "1.2.fromhex('0x1.ap4') is not implemented"))
277 (+ "0x" (number->string
(py-index x
) 16)))
279 (define-method (py-is-integer (o <real
>))
280 (= 1 (denominator (inexact->exact o
))))
281 (define-method (py-is-integer (o <integer
>)) #t
)
283 (define-method (hex (o <integer
>))
284 (+ "0x" (number->string o
16)))
286 (define-method (py-abs (o <complex
>))
288 (define-method (py-abs (o <number
>))
290 (define-method (py-index (o <integer
>)) o
)
291 (mk-unop u0 py-abs __abs__
)
292 (mk-unop u0 py-conjugate conjugate
)
293 (mk-unop u0 py-imag imag
)
294 (mk-unop u0 py-real real
)
295 (mk-unop u0 py-denominator denominator
)
296 (mk-unop u0 py-numerator numerator
)
297 (mk-unop u0 py-as-integer-ratio as_integer_ratio
)
298 (mk-unop u0 py-fromhex fromhex
)
299 (mk-unop i0 hex __hex__
)
300 (mk-unop u0 py-is-integer is_integer
)
301 (mk-unop u0 py-index __index__
)
303 (define-method (write (o <py-float
>) . l
)
304 (apply write
(slot-ref o
'x
) l
))
305 (define-method (write (o <py-int
>) . l
)
306 (apply write
(slot-ref o
'x
) l
))
308 (define-python-class int
(<py
> <py-int
>)
318 ((and (number? n
) (integer? n
))
319 (slot-set! self
'x n
))
323 (lp (string->number n
)))
325 (aif it
(slot-ref n
'__int__
)
326 (slot-set! self
'x it
)
327 (raise ValueError
"could not make int from " n
))))))
330 (__init__ self
(string->number n k
))))))
339 (or (is-a? x
<py-complex
>)
341 (is-a? x
<py-float
>))
346 (if (not (complex? x
))
350 (or (is-a? x
<py-complex
>)
352 (is-a? x
<py-float
>))
353 (let ((ret (slot-ref x
'x
)))
354 (if (not (complex? ret
))
358 (define-python-class float
(<py
> <py-float
>)
366 (slot-set! self
'x n
)))
368 (lp (string->number n
)))
370 (aif it
(slot-ref n
'__float__
)
371 (slot-set! self
'x it
)
372 (raise ValueError
"could not make float from " n
)))))))))
376 (define-python-class py-complex
(<py
> <py-complex
>)
383 (slot-set! self
'x n
)))
385 (raise ValueError
"could not make complex from " n
))))
393 (slot-set! self
'x
(make-rectangular n m
))))
395 (raise ValueError
"could not make complex from " n m
)))))
397 (raise ValueError
"could not make complex from " n m
)))))))
399 (name-object py-complex
)
401 (define-method (py-class (o <integer
> )) int
)
402 (define-method (py-class (o <real
> )) float
)
406 (define py-float float
)
408 (define-method (mk-int (o <number
>)) (slot-ref (py-int o
) 'x
))
409 (define-method (mk-float (o <number
>)) (slot-ref (py-float o
) 'x
))
411 (mk-unop u0 mk-int __int__
)
412 (mk-unop u0 mk-float __float__
)
414 (define (pyint-listing)
418 '(__abs__ __add__ __and__ __class__ __cmp__ __coerce__
419 __delattr__ __div__ __divmod__ __doc__ __float__
420 __floordiv__ __format__ __getattribute__
421 __getnewargs__ __hash__ __hex__ __index__ __init__
422 __int__ __invert__ __long__ __lshift__ __mod__
423 __mul__ __neg__ __new__ __nonzero__ __oct__ __or__
424 __pos__ __pow__ __radd__ __rand__ __rdiv__
425 __rdivmod__ __reduce__ __reduce_ex__ __repr__
426 __rfloordiv__ __rlshift__ __rmod__ __rmul__ __ror__
427 __rpow__ __rrshift__ __rshift__ __rsub__ __rtruediv__
428 __rxor__ __setattr__ __sizeof__ __str__ __sub__
429 __subclasshook__ __truediv__ __trunc__ __xor__
430 bit_length conjugate denominator imag numerator
435 (define (pyfloat-listing)
439 '(__abs__ __add__ __class__ __coerce__ __delattr__ __div__
440 __divmod__ __doc__ __eq__ __float__ __floordiv__
441 __format__ __ge__ __getattribute__ __getformat__
442 __getnewargs__ __gt__ __hash__ __init__ __int__
443 __le__ __long__ __lt__ __mod__ __mul__ __ne__
444 __neg__ __new__ __nonzero__ __pos__ __pow__
445 __radd__ __rdiv__ __rdivmod__ __reduce__
446 __reduce_ex__ __repr__ __rfloordiv__ __rmod__
447 __rmul__ __rpow__ __rsub__ __rtruediv__
448 __setattr__ __setformat__ __sizeof__ __str__
449 __sub__ __subclasshook__ __truediv__ __trunc__
450 as_integer_ratio conjugate fromhex hex imag
455 (define (pycomplex-listing)
459 '(__abs__ __add__ __class__ __coerce__ __delattr__ __div__
460 __divmod__ __doc__ __eq__ __float__ __floordiv__
461 __format__ __ge__ __getattribute__ __getnewargs__
462 __gt__ __hash__ __init__ __int__ __le__ __long__
463 __lt__ __mod__ __mul__ __ne__ __neg__ __new__
464 __nonzero__ __pos__ __pow__ __radd__ __rdiv__
465 __rdivmod__ __reduce__ __reduce_ex__ __repr__
466 __rfloordiv__ __rmod__ __rmul__ __rpow__ __rsub__
467 __rtruediv__ __setattr__ __sizeof__ __str__
468 __sub__ __subclasshook__ __truediv__
469 conjugate imag real
)))))
473 (define* (py-round x
#:optional
(digits 0))
474 (let* ((f (expt 10.0 digits
)))
475 (if (equal? digits
0)
477 (/ (round (* x f
)) f
))))
479 (define-method (py-bin (o <integer
>))
480 (number->string o
2))
481 (define-method (py-bin (o <py-int
>))
482 (number->string
(slot-ref o
'x
) 2))
484 (+ "0b" (number->string
(py-index o
) 2)))