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