Correctly substitute directory names in 'python' executable.
[software/python-on-guile.git] / modules / language / python / set.scm
1 (define-module (language python set)
2 #:use-module (oop pf-objects)
3 #:use-module (oop goops)
4 #:use-module (ice-9 format)
5 #:use-module (language python exceptions)
6 #:use-module (language python dict)
7 #:use-module (language python for)
8 #:use-module (language python try)
9 #:use-module (language python list)
10 #:use-module (language python yield)
11 #:use-module (language python persist)
12 #:use-module (language python bool)
13 #:export (py-set frozenset weak-set))
14
15 (define-class <set> () dict)
16 (name-object <set>)
17
18 (cpit <set>
19 (o (lambda (o a)
20 (slot-set! o 'dict
21 (let ((h (make-py-hashtable)))
22 (let lp ((a a))
23 (if (pair? a)
24 (begin
25 (py-hash-set! h (caar a) (cdar a))
26 (lp (cdr a))))))))
27 (list
28 (hash-fold (lambda (k v s) (cons (cons k v) s))
29 '()
30 (slot-ref o 'dict)))))
31
32
33 (define miss (list 'miss))
34
35 (define-method (< (o1 <set>) ( o2 <set>))
36 (and (not (equal? o1 o2))
37 (for ((k : o1)) ()
38 (if (in k o2)
39 (values)
40 (break #f))
41 #:final #t)))
42
43 (define-method (> (o1 <set>) ( o2 <set>))
44 (and (not (equal? o1 o2))
45 (for ((k : o2)) ()
46 (if (in k o1)
47 (values)
48 (break #f))
49 #:final #t)))
50
51 (define-method (<= (o1 <set>) ( o2 <set>))
52 (for ((k : o1)) ()
53 (if (in k o2)
54 (values)
55 (break #f))
56 #:final #t))
57
58 (define-method (>= (o1 <set>) ( o2 <set>))
59 (for ((k : o2)) ()
60 (if (in k o1)
61 (values)
62 (break #f))
63 #:final #t))
64
65 (define-method (in k (o <set>))
66 (in k (slot-ref o 'dict)))
67
68 (define-syntax-rule (mk set make-py-hashtable)
69 (define-python-class set (<set>)
70 (define __init__
71 (case-lambda
72 ((self)
73 (slot-set! self 'dict (make-py-hashtable)))
74 ((self x)
75 (let ((d (make-py-hashtable)))
76 (slot-set! self 'dict d)
77 (if (eq? x '())
78 (values)
79 (for ((y : x)) ()
80 (pylist-set! d y #t)))))))
81
82 (define __bool__
83 (lambda (self)
84 (bool (slot-ref self 'dict))))
85
86 (define pop
87 (lambda (self)
88 (call-with-values (lambda () (pylist-pop! (slot-ref self 'dict)))
89 (lambda (k v) k))))
90
91 (define add
92 (lambda (self k)
93 (pylist-set! (slot-ref self 'dict) k #t)))
94
95 (define copy
96 (lambda (self)
97 (let ((dict (py-copy (slot-ref self 'dict))))
98 (set dict))))
99
100 (define difference
101 (lambda (self . l)
102 (let* ((d (slot-ref self 'dict))
103 (r (py-copy d)))
104 (let lp ((l l))
105 (if (pair? l)
106 (begin
107 (for ((x : (car l))) ()
108 (when (in x d)
109 (pylist-delete! r x)))
110 (lp (cdr l)))))
111 (set r))))
112
113 (define difference_update
114 (lambda (self . l)
115 (let* ((r (slot-ref self 'dict)))
116 (let lp ((l l))
117 (if (pair? l)
118 (begin
119 (for ((x : (car l))) ()
120 (when (in x r)
121 (pylist-delete! r x)))
122 (lp (cdr l)))))
123 (values))))
124
125 (define discard
126 (lambda (self . l)
127 (let* ((r (slot-ref self 'dict)))
128 (let lp ((l l))
129 (if (pair? l)
130 (begin
131 (pylist-delete! r (car l))
132 (lp (cdr l))))))))
133
134 (define intersection
135 (lambda (self . l)
136 (let* ((d (slot-ref self 'dict))
137 (r (py-copy d)))
138 (let lp ((l l))
139 (if (pair? l)
140 (let ((y (car l)))
141 (for ((k v : r)) ((dels '()))
142 (if (not (__contains__ y k))
143 (cons k dels)
144 dels)
145 #:final
146 (let lp ((dels dels))
147 (if (pair? dels)
148 (begin
149 (pylist-delete! r (car dels))
150 (lp (cdr dels))))))
151 (lp (cdr l)))))
152 (set r))))
153
154 (define intersection_update
155 (lambda (self . l)
156 (let* ((r (slot-ref self 'dict)))
157 (let lp ((l l))
158 (if (pair? l)
159 (let ((y (car l)))
160 (for ((k v : r)) ((dels '()))
161 (if (not (__contains__ y k))
162 (cons k dels)
163 dels)
164 #:final
165 (let lp ((dels dels))
166 (if (pair? dels)
167 (begin
168 (pylist-delete! r (car dels))
169 (lp (cdr dels))))))
170 (lp (cdr l))))))))
171
172 (define isdisjoint
173 (lambda (self x)
174 (let* ((r (slot-ref self 'dict))
175 (n1 (len r))
176 (n2 (len x)))
177 (if (< n2 n1)
178 (let ((xx x))
179 (set! x r)
180 (set! r xx)))
181 (for ((k v : r)) ()
182 (if (in k x)
183 (break #f))
184 #:final
185 #t))))
186
187 (define issubset
188 (lambda (self x)
189 (let* ((r (slot-ref self 'dict)))
190 (for ((k v : r)) ()
191 (if (not (__contains__ x k))
192 (break #f))
193 #:final
194 #t))))
195
196 (define issuperset
197 (lambda (self x)
198 (let* ((r (slot-ref self 'dict)))
199 (for ((x v : r)) ()
200 (if (not (in x r))
201 (break #f))
202 #:final
203 #t))))
204
205 (define remove
206 (lambda (self x)
207 (let* ((r (slot-ref self 'dict)))
208 (if (not (in x r))
209 (raise KeyError "missing key in set at remove")
210 (pylist-delete! r x)))))
211
212 (define symmetric_difference
213 (lambda (self x)
214 (union (difference self x) (difference x self))))
215
216 (define symmetric_difference_update
217 (lambda (self x)
218 (difference_update self x)
219 (update self (difference x self))))
220
221 (define union
222 (lambda (self . l)
223 (let* ((d (slot-ref self 'dict))
224 (r (py-copy d)))
225 (let lp ((l l))
226 (if (pair? l)
227 (begin
228 (for ((k : (car l))) ()
229 (pylist-set! r k #t))
230 (lp (cdr l)))
231 (set r))))))
232
233 (define update
234 (lambda (self . l)
235 (let* ((r (slot-ref self 'dict)))
236 (let lp ((l l))
237 (if (pair? l)
238 (begin
239 (for ((k v : (car l))) ()
240 (pylist-set! r k #t))
241 (lp (cdr l)))
242 (values))))))
243
244 (define __repr__
245 (lambda (self)
246 (let* ((r (py-keys (slot-ref self 'dict)))
247 (n (len r))
248 (l (to-list r)))
249 (cond
250 ((= n 0)
251 (format #f "set([])"))
252 (else
253 (format #f "set([~a~{, ~a~}])" (car l) (cdr l)))))))
254
255 (define __contains__
256 (lambda (self x)
257 (let* ((d (slot-ref self 'dict))
258 (t (slot-ref d 't)))
259 (not (eq? miss (py-hash-ref t x miss))))))
260
261 (define __and__
262 (lambda (self op)
263 (intersection self op)))
264
265 (define __or__
266 (lambda (self op)
267 (union self op)))
268
269 (define __sub__
270 (lambda (self op)
271 (difference self op)))
272
273 (define __xor__
274 (lambda (self op)
275 (symmetric_difference self op)))
276
277 (define __eq__
278 (lambda (self x)
279 (and
280 (is-a? x <p>)
281 (eq? (ref self '__class__ 1) (ref x '__class__ 2))
282 (equal? (ref self 'd 1) (ref x 'd 2)))))
283
284 (define __iter__
285 (lambda (self)
286 ((make-generator ()
287 (lambda (yield)
288 (for ((k v : (slot-ref self 'dict))) ()
289 (yield k)
290 (values)))))))))
291
292 (mk set make-py-hashtable)
293 (mk weak-set make-py-weak-key-hashtable)
294
295 (define py-set set)
296 (define-python-class frozenset (set))