remove warnings, reordering
[software/python-on-guile.git] / modules / language / python / module / operator.scm
1 (define-module (language python module operator)
2 #:use-module (oop pf-objects)
3 #:use-module (ice-9 control)
4 #:use-module (ice-9 format)
5 #:use-module (language python number)
6 #:use-module (language python list)
7 #:use-module (language python string)
8 #:use-module (language python for)
9 #:use-module (language python try)
10 #:use-module (language python def)
11 #:use-module (language python persist)
12 #:use-module (language python exceptions)
13 #:use-module ((language python module python)
14 #:select (enumerate getattr hasattr))
15
16 #:export
17 (abs add and_ attrgetter concat contains countOf
18 delitem eq floordiv ge getitem gt iadd iand
19 iconcat ifloordiv ilshift imatmul imod imul
20 index indexOf inv invert ior ipow irshift
21 is_ is_not isub itemgetter itruediv ixor le
22 length_hint lshift lt matmul methodcaller mod
23 mul ne neg not_ or_ pos pow rshift
24 setitem sub truediv truth xor
25 __lt__ __le__ __eq__ __ne__ __ge__ __gt__ __not__ __abs__ __add__
26 __and__ __floordiv__ __index__ __inv__ __invert__ __lshift__ __mod__
27 __mul__ __matmul__ __neg__ __or__ __pos__ __pow__ __rshift__ __sub__
28 __truediv__ __xor__ __concat__ __contains__ __delitem__ __getitem__
29 __setitem__ __iadd__ __iand__ __iconcat__ __ifloordiv__ __ilshift__
30 __imod__ __imul__ __imatmul__ __ior__ __ipow__ __irshift__ __isub__
31 __itruediv__ __ixor__ ))
32
33 (define (hash->assoc h)
34 (for ((k v : h)) ((l '()))
35 (cons (cons k v) l)
36 #:final (reverse l)))
37
38 (define (assoc->hash a)
39 (let ((h (make-hash-table)))
40 (let lp ((a a))
41 (if (pair? a)
42 (begin
43 (hash-set! h (caar a) (cdar a))
44 (lp (cdr a)))))
45 h))
46
47
48
49 ;; Comparison Operations
50 (define (lt a b) (< a b))
51 (define (le a b) (<= a b))
52 (define (eq a b) (equal? a b))
53 (define (ne a b) (not (equal? a b)))
54 (define (ge a b) (>= a b))
55 (define (gt a b) (> a b))
56
57 ;; Logical Operations
58 (define (not_ a) (not a))
59 (define (truth a) (if a #t #f))
60 (define (is_ a b) (eq? a b))
61 (define (is_not a b) (not (eq? a b)))
62
63 ;; Mathematical/Bitwise Operations
64 (define abs (@ (guile) abs))
65 (define (add a b) (+ a b))
66 (define and_ py-logand)
67 (define floordiv py-floordiv)
68 (define index py-index)
69 (define inv py-lognot)
70 (define invert inv)
71 (define lshift py-lshift)
72 (define mod py-mod)
73 (define (mul x y) (* x y))
74 (define matmul py-matmul)
75 (define (neg x) (- x))
76 (define or_ py-logior)
77 (define (pos a) (+ a))
78 (define pow expt)
79 (define rshift py-rshift)
80 (define (sub a b) (- a b))
81 (define truediv py-/)
82 (define xor py-logxor)
83
84 ;; Sequence Operations
85 (define (concat a b) (+ a b))
86 (define (contains a b) (in b a))
87 (define (countOf a b)
88 (for ((x : a)) ((c 0))
89 (if (equal? x b)
90 (+ c 1)
91 c)
92
93 #:final c))
94
95 (define delitem pylist-delete!)
96 (define getitem pylist-ref)
97 (define (indexOf a b)
98 (for ((i x : (enumerate a))) ()
99 (if (equal? x b)
100 (break i))
101
102 #:final (raise ValueError "sequence.index(x): x not in sequence'")))
103
104 (define setitem pylist-delete!)
105
106 (define* (length_hint obj #:optional (default 0))
107 (if (not (and (number? default) (integer? default)))
108 (raise TypeError (format #f "default=~a is not an integer" default)))
109 (let/ec ret
110 (try
111 (lambda ()
112 (ret (len obj)))
113
114 (#:except TypeError =>
115 (lambda x (values))))
116
117 (let ((hint
118 (try
119 (lambda ()
120 (ref obj '__length_hint__))
121
122 (#:except AttributeError =>
123 (lambda x (ret default))))))
124 (let ((val (try
125 (lambda () (hint))
126
127 (#:except TypeError =>
128 (lambda x (ret default))))))
129 (cond
130 ((eq? val NotImplemented)
131 default)
132 ((not (and (number? val) (integer? val)))
133 (raise TypeError
134 (format #f "__length_hint__() must be integer, not ~a" val)))
135 ((< val 0)
136 (raise ValueError
137 "__length_hint__() should return integer >= 0"))
138 (else
139 val))))))
140
141 ;; Generalized Lookup Objects
142 (define-python-class attrgetter ()
143 (define __init__
144 (lambda (self attr . attrs)
145 (if (null? attrs)
146 (begin
147 (if (not (py-string? attr))
148 (raise TypeError "attribute name must be a string"))
149 (set self '_attrs (list attr))
150 (let ((names (string-split attr #\.)))
151 (define (func obj)
152 (for ((name : names)) ((obj obj))
153 (getattr obj name)
154
155 #:final obj))
156 (set self '_call func)))
157 (let ((attrs (cons attr attrs)))
158 (set self '_attrs attrs)
159 (let ((getters (map attrgetter attrs)))
160 (define (func obj)
161 (for ((getter : getters)) ((l '()))
162 (cons (getter obj) l)
163
164 #:final (reverse l)))
165 (set self '_call func))))))
166
167 (define __reduce__
168 (lambda (self)
169 (list (lambda (o data)
170 (apply (ref o '__init__) data))
171 (list (ref self '_attrs)))))
172
173 (define __call__
174 (lambda (self obj)
175 ((ref self '_call) obj)))
176
177 (define __repr__
178 (lambda (self)
179 (let ((cl (ref self '__class__))
180 (as (ref self '_attrs)))
181 (format #f "~a(~a~{,~a~})"
182 (ref cl '__name__)
183 (car as)
184 (cdr as))))))
185
186 (define-python-class itemgetter ()
187 (define __init__
188 (lambda (self item . items)
189 (if (null? items)
190 (let ()
191 (define (func obj)
192 (pylist-ref obj item))
193 (set self '_items (list item))
194 (set self '_call func))
195 (let ()
196 (define (func obj)
197 (map (lambda (i) (pylist-ref obj i))
198 (ref self '_items)))
199 (set self '_items (cons item items))
200 (set self '_call func)))))
201
202 (define __reduce__
203 (lambda (self)
204 (list (lambda (o data)
205 (apply (ref o '__init__) data))
206 (list (ref self '_items)))))
207
208 (define __call__
209 (lambda (self obj)
210 ((ref self '_call) obj)))
211
212 (define __repr__
213 (lambda (self)
214 (let ((args (ref self '_args)))
215 (format #f "~a(~a~{,~a~})"
216 (ref (ref self '__class__) '__name__)
217 (car args) (cdr args))))))
218
219 (define-python-class methodcaller ()
220 (define __init__
221 (lam (self (* args) (** kwargs))
222 (if (< (len args) 1)
223 (raise TypeError
224 "methodcaller needs at least one argument, the method name"
225 ))
226 (let ((name (car args)))
227 (set self '_name name)
228 (if (not (py-string? name))
229 (raise TypeError "method name must be a string")))
230
231 (set self '_args (cdr args))
232 (set self '_kwargs kwargs)))
233
234 (define __reduce__
235 (lambda (self)
236 (list
237 (lambda (o name args a)
238 (let ((kwargs (assoc->hash a)))
239 (py-apply (ref methodcaller '__init__) o name (* args) (** kwargs))))
240 (list
241 (ref self '_name)
242 (ref self '_args)
243 (hash->assoc (ref self '_kwargs))))))
244
245 (define __call__
246 (lambda (self obj)
247 (py-apply (getattr obj (ref self '_name))
248 (* (ref self '_args))
249 (** (ref self '_kwargs)))))
250
251 (define __repr__
252 (lambda (self)
253 (define cln (ref (ref self '__class__) '__name__))
254 (define v1 (for ((x : (ref self '_args)))
255 ((l (list (ref self '_name))))
256 (cons x l)
257
258 #:final l))
259 (define v2 (for ((k v : (ref self '_kwargs))) ((l v1))
260 (cons (format #f "~a=~a" k v) l)
261
262 #:final (reverse l)))
263 (format #f "~a(~a~{,~a~})" cln (car v2) (cdr v2)))))
264
265 ;; In-place Operations
266 (define iadd py-iadd)
267 (define iand py-ilogand)
268 (define (iconcat a b)
269 (if (not (hasattr a '__getitem__'))
270 (raise TypeError
271 (format
272 #f
273 "'~a' object can't be concatenated"
274 (ref (type a) '__name__))))
275 (iadd a b))
276
277 (define ifloordiv py-ifloordiv)
278 (define ilshift py-ilshift)
279 (define imod py-imod)
280 (define imul py-imul)
281 (define imatmul py-imatmul)
282 (define ior py-ilogior)
283 (define ipow py-ipow)
284 (define irshift py-irshift)
285 (define isub py-isub)
286 (define itruediv py-i/)
287 (define ixor py-ilogxor)
288
289 (define __lt__ lt)
290 (define __le__ le)
291 (define __eq__ eq)
292 (define __ne__ ne)
293 (define __ge__ ge)
294 (define __gt__ gt)
295 (define __not__ not_)
296 (define __abs__ abs)
297 (define __add__ add)
298 (define __and__ and_)
299 (define __floordiv__ floordiv)
300 (define __index__ index)
301 (define __inv__ inv)
302 (define __invert__ invert)
303 (define __lshift__ lshift)
304 (define __mod__ mod)
305 (define __mul__ mul)
306 (define __matmul__ matmul)
307 (define __neg__ neg)
308 (define __or__ or_)
309 (define __pos__ pos)
310 (define __pow__ pow)
311 (define __rshift__ rshift)
312 (define __sub__ sub)
313 (define __truediv__ truediv)
314 (define __xor__ xor)
315 (define __concat__ concat)
316 (define __contains__ contains)
317 (define __delitem__ delitem)
318 (define __getitem__ getitem)
319 (define __setitem__ setitem)
320 (define __iadd__ iadd)
321 (define __iand__ iand)
322 (define __iconcat__ iconcat)
323 (define __ifloordiv__ ifloordiv)
324 (define __ilshift__ ilshift)
325 (define __imod__ imod)
326 (define __imul__ imul)
327 (define __imatmul__ imatmul)
328 (define __ior__ ior)
329 (define __ipow__ ipow)
330 (define __irshift__ irshift)
331 (define __isub__ isub)
332 (define __itruediv__ itruediv)
333 (define __ixor__ ixor)