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