itertools
[software/python-on-guile.git] / modules / language / python / list.scm
1 (define-module (language python list)
2 #:use-module (ice-9 match)
3 #:use-module (ice-9 control)
4 #:use-module (oop pf-objects)
5 #:use-module (oop goops)
6 #:use-module (language python hash)
7 #:use-module (language python tuple)
8 #:use-module (language python exceptions)
9 #:use-module (language python yield)
10 #:use-module (language python for)
11 #:use-module (language python try)
12 #:use-module (language python exceptions)
13 #:use-module (language python persist)
14 #:export (to-list to-pylist <py-list>
15 pylist-append!
16 pylist-slice pylist-subset! pylist-reverse!
17 pylist-pop! pylist-count pylist-extend! len in
18 pylist-insert! pylist-remove! pylist-sort!
19 pylist-index pylist-null pylist-delete!
20 pylist pylist-listing py-reversed
21 py-all py-any py-reversed))
22
23 (define scm-list list)
24
25 (define-syntax-rule (aif it p x y) (let ((it p)) (if it x y)))
26
27 (define-class <py-list> () vec n)
28 (name-object <py-list>)
29
30 (cpit <py-list> (o (lambda (o n l)
31 (slot-set! o 'n n)
32 (slot-set! o 'vec (list->vector l)))
33 ((@ (guile) list)
34 (slot-ref o 'n)
35 (vector->list (slot-ref o 'vec)))))
36
37 (define-method (pylist-delete! (o <py-list>) k)
38 (let* ((n (slot-ref o 'n))
39 (k (if (< k 0) (+ k n) k)))
40 (pylist-subset! o k (+ k 1) None pylist-null)))
41
42 (define-method (pylist-delete! (o <p>) k)
43 (aif it (ref o '__delitem__)
44 (it k)
45 (next-method)))
46
47 (define pylist-null
48 (let ((o (make <py-list>)))
49 (slot-set! o 'vec (make-vector 0))
50 (slot-set! o 'n 0)
51 o))
52
53 (define-method (py-hash (o <py-list>))
54 (let ((n (min complexity (slot-ref o 'n)))
55 (v (slot-ref o 'vec)))
56 (let lp ((i 0) (s 0))
57 (if (< i n)
58 (lp (+ i 1)
59 (xy (py-hash (vector-ref v i)) s))
60 s))))
61
62 (define-method (to-list x)
63 (if (vector? x)
64 (vector->list x)
65 x))
66
67 (define-method (to-list (x <p>))
68 (aif it (ref x '__tolist__)
69 (it)
70 (next-method)))
71
72
73 (defpair (to-list x) x)
74
75 (define-method (to-list (x <yield>))
76 (define l '())
77 (catch StopIteration
78 (lambda ()
79 (let lp ()
80 (set! l (cons (next x) l))
81 (lp)))
82 (lambda x
83 (reverse l))))
84
85 (define-method (to-list (x <py-list>))
86 (let ((vec (slot-ref x 'vec))
87 (n (slot-ref x 'n)))
88 (let lp ((i 0))
89 (if (< i n)
90 (cons (vector-ref vec i) (lp (+ i 1)))
91 '()))))
92
93 (define-method (to-pylist (l <py-list>))
94 l)
95
96 (defpair (to-pylist l)
97 (let* ((n (length l))
98 (vec (make-vector (* 2 n)))
99 (o (make <py-list>)))
100
101 (let lp ((l l) (i 0))
102 (if (pair? l)
103 (begin
104 (vector-set! vec i (car l))
105 (lp (cdr l) (+ i 1)))))
106
107 (slot-set! o 'n n)
108 (slot-set! o 'vec vec)
109 o))
110
111 (define-method (to-pylist (l <vector>))
112 (to-pylist (vector->list l)))
113
114 (define-method (to-pylist (o <string>))
115 (to-pylist (string->list o)))
116
117 (define-method (to-pylist l)
118 (if (null? l)
119 (let ((o (make <py-list>)))
120 (slot-set! o 'vec (make-vector 4))
121 (slot-set! o 'n 0)
122 o)
123 (error "not able to make a pylist")))
124
125 ;;; REF
126 (define-method (pylist-ref (o <py-list>) nin)
127 (define N (slot-ref o 'n))
128 (define n (if (< nin 0) (+ N nin) nin))
129 (if (and (>= n 0) (< n (slot-ref o 'n)))
130 (vector-ref (slot-ref o 'vec) n)
131 (raise IndexError)))
132
133 (defpair (pylist-ref o n)
134 (list-ref o (if (< n 0) (+ (length o) n) n)))
135
136 (define-method (pylist-ref (o <vector>) n)
137 (vector-ref o n))
138
139 (define-method (pylist-ref (o <p>) n)
140 (aif it (ref o '__getitem__)
141 (it n)
142 (next-method)))
143
144 ;;; SET
145 (define-method (pylist-set! (o <py-list>) nin val)
146 (define N (slot-ref o 'n))
147 (define n (if (< nin 0) (+ N nin) nin))
148
149 (if (and (>= n 0) (< n (slot-ref o 'n)))
150 (vector-set! (slot-ref o 'vec) n val)
151 (raise IndexError)))
152
153 (defpair (pylist-set! o n val)
154 (list-set! o n val))
155
156 (define-method (pylist-set! (o <vector>) n val)
157 (vector-set! o n val))
158
159 (define-method (pylist-set! (o <p>) n val)
160 (aif it (ref o '__setitem__)
161 (it n val)
162 (next-method)))
163
164 ;;SLICE
165 (define-method (pylist-slice (o <p>) n1 n2 n3)
166 (aif it (ref o '__getslice__)
167 (it n1 n2 n3)
168 (next-method)))
169
170 (define-method (pylist-slice (o <py-list>) n1 n2 n3)
171 (define N (slot-ref o 'n))
172 (define (f n) (if (< n 0) (+ N n) n))
173
174 (let* ((n1 (f (if (eq? n1 None) 0 n1)))
175 (n2 (f (if (eq? n2 None) (slot-ref o 'n) n2)))
176 (n3 (f (if (eq? n3 None) 1 n3)))
177
178 (vec (slot-ref o 'vec))
179 (l (let lp ((i n1))
180 (if (< i n2)
181 (cons (vector-ref vec i) (lp (+ i n3)))
182 '()))))
183 (to-pylist l)))
184
185 (define-method (pylist-slice (o <string>) n1 n2 n3)
186 (define N (string-length o))
187 (define (f n) (if (< n 0) (+ N n) n))
188
189 (let* ((n1 (f (if (eq? n1 None) 0 n1)))
190 (n2 (f (if (eq? n2 None) (slot-ref o 'n) n2)))
191 (n3 (f (if (eq? n3 None) 1 n3))))
192 (list->string
193 (to-list
194 (pylist-slice (to-pylist o) n1 n2 n3)))))
195
196
197 (defpair (pylist-slice o n1 n2 n3)
198 (to-list
199 (pylist-slice (to-pylist o) n1 n2 n3)))
200
201 (define-method (pylist-slice (o <vector>) n1 n2 n3)
202 (list->vector
203 (to-list
204 (pylist-slice (to-pylist o) n1 n2 n3))))
205
206 ;;SUBSET
207 (define-method (pylist-subset! (o <p>) n1 n2 n3 val)
208 (aif it (ref o '__setslice__)
209 (it n1 n2 n3 val)
210 (next-method)))
211
212 (define-method (pylist-subset! (o <py-list>) n1 n2 n3 val)
213 (define N (slot-ref o 'n))
214 (define (f n) (if (< n 0) (+ N n) n))
215
216 (let* ((n1 (f (if (eq? n1 None) 0 n1)))
217 (n2 (f (if (eq? n2 None) (slot-ref o 'n) n2)))
218 (n3 (f (if (eq? n3 None) 1 n3)))
219 (vec (slot-ref o 'vec))
220 (o2 (to-pylist val))
221 (N2 (slot-ref o2 'n))
222 (vec2 (slot-ref o2 'vec)))
223 (if (<= n2 N)
224 (let lp ((i 0) (j n1))
225 (if (< j n2)
226 (if (< i N2)
227 (begin
228 (vector-set! vec j (vector-ref vec2 i))
229 (lp (+ i 1) (+ j n3)))
230 (let lp ((j2 j))
231 (if (< j2 n2)
232 (lp (+ j2 n3))
233 (let lp ((k1 j) (k2 j2))
234 (if (< k2 N)
235 (begin
236 (vector-set! vec k1 (vector-ref vec k2))
237 (lp (+ k1 1) (+ k2 1)))
238 (begin
239 (let lp ((i k2))
240 (if (< i N)
241 (begin
242 (vector-set! vec i #f)
243 (lp (+ i 1)))
244 (slot-set! o 'n k1)))))))))))
245 (raise IndexError))
246 (values)))
247
248
249 ;;APPEND
250 (define-method (pylist-append! (o <py-list>) val)
251 (let* ((n (slot-ref o 'n))
252 (vec (slot-ref o 'vec))
253 (N (vector-length vec)))
254 (if (< n N)
255 (begin
256 (vector-set! vec n val)
257 (slot-set! o 'n (+ n 1)))
258 (let* ((N (* 2 N))
259 (vec2 (make-vector N)))
260 (let lp ((i 0))
261 (if (< i n)
262 (begin
263 (vector-set! vec2 i (vector-ref vec i))
264 (lp (+ i 1)))))
265 (vector-set! vec2 n val)
266 (slot-set! o 'vec vec2)))
267 (slot-set! o 'n (+ n 1))
268 (values)))
269
270 (define-method (pylist-append! o n)
271 (raise 'NotSupportedOP '__append__))
272
273 (define-method (pylist-append! (o <p>) n . l)
274 (aif it (ref o 'append)
275 (apply it n l)
276 (next-method)))
277
278
279
280 (define-method (write (o <py-list>) . l)
281 (define port (if (null? l) #t (car l)))
282 (let* ((l (to-list o)))
283 (if (null? l)
284 (format port "[]")
285 (format port "[~a~{, ~a~}]" (car l) (cdr l)))))
286
287 (define-method (display (o <py-list>) . l)
288 (define port (if (null? l) #t (car l)))
289
290 (let* ((l (to-list o)))
291 (if (null? l)
292 (format port "[]")
293 (format port "[~a~{, ~a~}]" (car l) (cdr l)))))
294
295
296 (define-method (+ (o1 <py-list>) (o2 <py-list>))
297 (let* ((vec1 (slot-ref o1 'vec))
298 (vec2 (slot-ref o2 'vec))
299 (n1 (slot-ref o1 'n))
300 (n2 (slot-ref o2 'n))
301 (n (+ n1 n2))
302 (vec (make-vector (* 2 n)))
303 (o (make <py-list>)))
304
305 (let lp ((i1 0))
306 (if (< i1 n1)
307 (begin
308 (vector-set! vec i1 (vector-ref vec1 i1))
309 (lp (+ i1 1)))
310 (let lp ((i2 0) (i i1))
311 (if (< i2 n2)
312 (begin
313 (vector-set! vec i (vector-ref vec2 i2))
314 (lp (+ i2 1) (+ i 1)))))))
315
316 (slot-set! o 'n n )
317 (slot-set! o 'vec vec)
318 o))
319
320
321 (define-method (+ (o1 <pair>) (o2 <pair>))
322 (append o1 o2))
323
324 (define-method (+ (o1 <py-tuple>) o2)
325 (+ (slot-ref o1 'l) o2))
326
327 (define-method (+ o2 (o1 <py-tuple>))
328 (+ o2 (slot-ref o1 'l)))
329
330 (define-method (+ (o1 <string>) (o2 <string>))
331 (string-append o1 o2))
332
333 (define-method (+ (o1 <symbol>) (o2 <symbol>))
334 (string->symbol
335 (string-append
336 (symbol->string o1)
337 (symbol->string o2))))
338
339 (define-method (* (x <integer>) (o1 <py-list>)) (* o1 x))
340 (define-method (* (o1 <py-list>) (x <integer>))
341 (let* ((vec (slot-ref o1 'vec))
342 (n (slot-ref o1 'n))
343 (n2 (* n x))
344 (vec2 (make-vector (* 2 n2)))
345 (o (make <py-list>)))
346
347 (let lp1 ((i 0) (j 0))
348 (if (< i x)
349 (let lp2 ((j j) (k 0))
350 (if (< k n)
351 (begin
352 (vector-set! vec2 j (vector-ref vec k))
353 (lp2 (+ j 1) (+ k 1)))
354 (lp1 (+ i 1) j)))))
355
356 (slot-set! o 'n n2 )
357 (slot-set! o 'vec vec2)
358 o))
359
360 (define-method (* (x <integer>) (vec <string>)) (* vec x))
361 (define-method (* (vec <string>) (x <integer>))
362 (let* ((n (string-length vec))
363 (n2 (* n x))
364 (vec2 (make-string n2)))
365
366 (let lp1 ((i 0) (j 0))
367 (if (< i x)
368 (let lp2 ((j j) (k 0))
369 (if (< k n)
370 (begin
371 (string-set! vec2 j (string-ref vec k))
372 (lp2 (+ j 1) (+ k 1)))
373 (lp1 (+ i 1) j)))))
374 vec2))
375
376 (define-method (* (x <integer> ) (l <pair>)) (* l x))
377 (define-method (* (x <py-tuple>) l) (* (slot-ref x 'l) l))
378 (define-method (* l (x <py-tuple>)) (* l (slot-ref x 'l)))
379 (define-method (* (l <pair>) (x <integer>))
380 (let lp1 ((i 0))
381 (if (< i x)
382 (let lp2 ((k l))
383 (if (pair? k)
384 (cons (car k) (lp2 (cdr k)))
385 (lp1 (+ i 1))))
386 '())))
387
388
389 ;;REVERSE
390 (define-method (pylist-reverse! (o <py-list>))
391 (let* ((N (slot-ref o 'n))
392 (M (- N 1))
393 (n (floor-quotient N 2))
394 (vec (slot-ref o 'vec)))
395 (let lp ((i 0))
396 (if (< i n)
397 (let ((swap (vector-ref vec i))
398 (k (- M i)))
399 (vector-set! vec i (vector-ref vec k))
400 (vector-set! vec k swap))))))
401
402
403 (define-method (pylist-reverse! (o <p>) . l)
404 (aif it (ref o 'reverse)
405 (apply it l)
406 (next-method)))
407
408 ;;POP!
409 (define-method (pylist-pop! (o <py-list>))
410 (let* ((n (slot-ref o 'n))
411 (m (- n 1))
412 (vec (slot-ref o 'vec)))
413 (if (> n 0)
414 (let ((ret (vector-ref vec m)))
415 (slot-set! o 'n m)
416 (vector-set! vec m #f)
417 ret)
418 (raise IndexError "pop from empty list"))))
419
420 (define-method (pylist-pop! (o <p>) . l)
421 (aif it (ref o 'pop)
422 (apply it l)
423 (next-method)))
424
425 ;;COUNT
426 (define-method (pylist-count (o <py-list>) q)
427 (let* ((n (slot-ref o 'n))
428 (vec (slot-ref o 'vec)))
429 (let lp ((i 0) (sum 0))
430 (if (< i n)
431 (if (equal? (vector-ref vec i) q)
432 (lp (+ i 1) (+ sum 1))
433 (lp (+ i 1) sum ))
434 sum))))
435
436 (define-method (pylist-count (s <string>) q)
437 (let* ((n (string-length s))
438 (q (if (and (string? q) (= (string-length q) 1))
439 (string-ref q 0))))
440 (let lp ((i 0) (sum 0))
441 (if (< i n)
442 (if (eq? (string-ref s i) q)
443 (lp (+ i 1) (+ sum 1))
444 (lp (+ i 1) sum ))
445 sum))))
446
447 (defpair (pylist-count l q)
448 (let lp ((l l) (sum 0))
449 (if (pair? l)
450 (if (eq? (car l) q)
451 (lp (cdr l) (+ sum 1))
452 (lp (cdr l) sum ))
453 sum)))
454
455 (define-method (pylist-count (o <p>) . l)
456 (aif it (ref o 'count)
457 (apply it l)
458 (next-method)))
459
460 ;; extend!
461 (define-method (pylist-extend! (o <py-list>) iter)
462 (for ((x : iter)) ()
463 (pylist-append! o x)))
464
465 (define-method (pylist-extend! (o <p>) . l)
466 (aif it (ref o 'extend)
467 (apply it l)
468 (next-method)))
469
470 ;; equal?
471 (define-method (py-equal? (o1 <py-list>) (o2 <py-list>))
472 (equal o1 o2))
473
474 (define (equal o1 o2)
475 (let ((n1 (slot-ref o1 'n))
476 (n2 (slot-ref o2 'n))
477 (vec1 (slot-ref o1 'vec))
478 (vec2 (slot-ref o2 'vec)))
479 (and
480 (equal? n1 n2)
481 (let lp ((i 0))
482 (if (< i n1)
483 (and (equal? (vector-ref vec1 i) (vector-ref vec2 i))
484 (lp (+ i 1)))
485 #t)))))
486
487 (define-class <py-seq-iter> () o i n d)
488 (define-class <py-list-iter> (<py-list>) i d)
489
490 (name-object <py-seq-iter>)
491 (name-object <py-list-iter>)
492
493 (cpit <py-list-iter> (o (lambda (o i d)
494 (slot-set! o 'i i)
495 (slot-set! o 'd d))
496 (list
497 (slot-ref o 'i)
498 (slot-ref o 'd))))
499
500 (cpit <py-seq-iter> (o (lambda (o oo i n d)
501 (slot-set! o 'o oo)
502 (slot-set! o 'i i)
503 (slot-set! o 'n i)
504 (slot-set! o 'd d))
505 (list
506 (slot-ref o 'o)
507 (slot-ref o 'i)
508 (slot-ref o 'n)
509 (slot-ref o 'd))))
510
511
512
513 (define-method (write (o <py-list-iter>) . l)
514 (define port (if (null? l) #t (car l)))
515 (for ((x : o)) ((l '()))
516 (cons x l)
517 #:final
518 (let ((l (reverse l)))
519 (if (null? l)
520 (format port "iter[]")
521 (format port "iter[~a~{, ~a~}]" (car l) (cdr l))))))
522
523 (define-method (write (o <py-seq-iter>) . l)
524 (define port (if (null? l) #t (car l)))
525 (for ((x : o)) ((l '()))
526 (cons x l)
527 #:final
528 (let ((l (reverse l)))
529 (if (null? l)
530 (format port "iter[]")
531 (format port "iter[~a~{, ~a~}]" (car l) (cdr l))))))
532
533
534 ;;WRAP-IN
535 (define-method (wrap-in (o <py-list>))
536 (let ((out (make <py-list-iter>)))
537 (slot-set! out 'n (slot-ref o 'n ))
538 (slot-set! out 'vec (slot-ref o 'vec))
539 (slot-set! out 'i 0)
540 (slot-set! out 'd 1)
541 out))
542
543 (define-method (py-reversed (o <py-list>))
544 (let ((out (make <py-list-iter>)))
545 (slot-set! out 'i (- (slot-ref o 'n) 1))
546 (slot-set! out 'vec (slot-ref o 'vec))
547 (slot-set! out 'n (slot-ref o 'n))
548 (slot-set! out 'd -1)
549 out))
550
551 (define-method (py-reversed (o <p>))
552 (aif it (ref o '__reversed__)
553 (it)
554 (let ((a (ref o '__getitem__))
555 (n (ref o '__len__)))
556 (if (and a n)
557 (let ((ret (make <py-seq-iter>)))
558 (slot-set! ret 'o a)
559 (slot-set! ret 'i (n))
560 (slot-set! ret 'n -1)
561 (slot-set! ret 'd -1))
562 (next-method)))))
563
564 (define-method (wrap-in (o <p>))
565 (aif it (ref o '__iter__)
566 (it)
567 (let ((a (ref o '__getitem__)))
568 (if a
569 (let ((ret (make <py-seq-iter>)))
570 (slot-set! ret 'o a)
571 (slot-set! ret 'i 0)
572 (slot-set! ret 'n -1)
573 (slot-set! ret 'd 1))
574 (next-method)))))
575
576
577 (define-method (wrap-in (o <py-list-iter>))
578 (let ((out (make <py-list-iter>)))
579 (slot-set! out 'vec (slot-ref o 'vec))
580 (slot-set! out 'i (slot-ref o 'i))
581 (slot-set! out 'n (slot-ref o 'n))
582 (slot-set! out 'd (slot-ref o 'd))
583 out))
584
585 (define-method (wrap-in (o <py-seq-iter>))
586 (let ((out (make <py-seq-iter>)))
587 (slot-set! out 'o (slot-ref o 'o))
588 (slot-set! out 'i (slot-ref o 'i))
589 (slot-set! out 'n (slot-ref o 'n))
590 (slot-set! out 'd (slot-ref o 'd))
591 out))
592
593
594
595 (define-method (wrap-in (o <py-seq-iter> )) o)
596
597 ;;NEXT
598 (define-method (next (o <py-seq-iter>))
599 (let ((i (slot-ref o 'i))
600 (d (slot-ref o 'd))
601 (a (slot-ref o 'a)))
602 (let ((r (a i)))
603 (slot-set! o 'i (+ i d))
604 r)))
605
606 (define-method (next (o <py-list-iter>))
607 (let ((i (slot-ref o 'i ))
608 (d (slot-ref o 'd))
609 (n (slot-ref o 'n ))
610 (vec (slot-ref o 'vec)))
611 (if (> d 0)
612 (if (< i n)
613 (let ((ret (vector-ref vec i)))
614 (slot-set! o 'i (+ i 1))
615 ret)
616 (throw StopIteration))
617 (if (>= i 0)
618 (let ((ret (vector-ref vec i)))
619 (slot-set! o 'i (- i 1))
620 ret)
621 (throw StopIteration)))))
622
623 ;;INSERT
624 (define-method (pylist-insert! (o <py-list>) i val)
625 (let* ((vec (slot-ref o 'vec))
626 (n (slot-ref o 'n))
627 (i (if (< i 0) (+ n i) i)))
628 (if (and (>= i 0) (<= i n))
629 (let lp ((v val) (i i))
630 (if (< i n)
631 (let ((swap (vector-ref vec i)))
632 (vector-set! vec i v)
633 (lp swap (+ i 1)))
634 (pylist-append! o v)))
635 (raise IndexError "Wrong index in insert"))))
636
637 (define-method (pylist-insert! (o <p>) . l)
638 (aif it (ref o 'insert)
639 (apply it l)
640 (next-method)))
641
642
643 ;;REMOVE
644 (define-method (pylist-remove! (o <py-list>) val)
645 (let ((n (slot-ref o 'n ))
646 (vec (slot-ref o 'vec)))
647 (let lp ((i 0))
648 (if (< i n)
649 (let ((r (vector-ref vec i)))
650 (if (equal? r val)
651 (pylist-subset! o i (+ i 1) 1 '())
652 (lp (+ i 1))))
653 (raise ValueError "list removal has no element to remove")))))
654
655 (define-method (pylist-remove! (o <p>) . l)
656 (aif it (ref o 'remove)
657 (apply it l)
658 (next-method)))
659
660 ;; SORT!
661 (define (id x) x)
662 (define-method (pylist-sort! (o <py-list>) . l)
663 (apply
664 (lambda* (#:key (key id) (reverse #f))
665 (let lp ((l (sort (map key (to-list o)) (if reverse > <))) (i 0))
666 (if (pair? l)
667 (begin
668 (pylist-set! o i (car l))
669 (lp (cdr l) (+ i 1))))))
670 l))
671
672 (define-method (pylist-sort! (o <p>) . l)
673 (aif it (ref o 'sort)
674 (apply it l)
675 (next-method)))
676
677 ;; INDEX
678 (define-method (pylist-index (o <py-list>) val . l)
679 (let* ((n (slot-ref o 'n ))
680 (vec (slot-ref o 'vec))
681 (f (lambda (m) (if (< m 0) (+ m n) m))))
682 (call-with-values
683 (lambda ()
684 (match l
685 (()
686 (values 0 n))
687 ((x)
688 (values (f x) n))
689 ((x y)
690 (values (f x) (f y)))))
691 (lambda (n1 n2)
692 (if (and (>= n1 0) (>= n2 0) (< n1 n) (<= n2 n))
693 (let lp ((i n1))
694 (if (< i n2)
695 (let ((r (vector-ref vec i)))
696 (if (equal? r val)
697 i
698 (lp (+ i 1))))
699 (raise ValueError "could not find value in index fkn")))
700 (raise IndexError "index out of scop in index fkn"))))))
701
702 (define-method (pylist-index (o <string>) val . l)
703 (let* ((n (string-length o))
704 (f (lambda (m) (if (< m 0) (+ m n) m)))
705 (val (if (and (string? val) (> (string-length val) 0))
706 (string-ref val 0)
707 val)))
708 (call-with-values
709 (lambda ()
710 (match l
711 (()
712 (values 0 n))
713 ((x)
714 (values (f x) n))
715 ((x y)
716 (values (f x) (f y)))))
717 (lambda (n1 n2)
718 (if (and (>= n1 0) (>= n2 0) (< n1 n) (<= n2 n))
719 (let lp ((i n1))
720 (if (< i n2)
721 (let ((r (string-ref o i)))
722 (if (equal? r val)
723 i
724 (lp (+ i 1))))
725 (raise ValueError "could not find value in index fkn")))
726 (raise IndexError "index out of scop in index fkn"))))))
727
728 (defpair (pylist-index o val . l)
729 (let* ((n (length o))
730 (f (lambda (m) (if (< m 0) (+ m n) m))))
731 (call-with-values
732 (lambda ()
733 (match l
734 (()
735 (values 0 n))
736 ((x)
737 (values (f x) n))
738 ((x y)
739 (values (f x) (f y)))))
740 (lambda (n1 n2)
741 (if (and (>= n1 0) (>= n2 0) (< n1 n) (<= n2 n))
742 (let lp ((i o))
743 (if (pair? i)
744 (let ((r (car i)))
745 (if (equal? r val)
746 i
747 (lp (cdr i))))
748 (raise ValueError "could not find value in index fkn")))
749 (raise IndexError "index out of scop in index fkn"))))))
750
751 (define-method (pylist-index (o <p>) . l)
752 (aif it (ref o 'index)
753 (apply it l)
754 (next-method)))
755
756
757 ;; len
758
759
760 (defpair (len l) (length l))
761 (define-method (len x)
762 (if (null? x)
763 0
764 (error "not a suitable lengthof")))
765 (define-method (len (v <vector>)) (vector-length v))
766 (define-method (len (s <string>)) (string-length s))
767 (define-method (len (o <py-list>)) (slot-ref o 'n))
768 (define-method (len (o <p>))
769 (aif it (ref o '__len__)
770 (it)
771 (next-method)))
772
773 (define-method (in x (l <py-tuple>)) (member x (slot-ref l 'l)))
774 (define-method (in x (l <pair>)) (member x l))
775 (define-method (in x (l <vector>))
776 (define n (vector-length l))
777 (let lp ((i 0))
778 (if (< i n)
779 (if (equal? x (vector-ref l i))
780 #t
781 (lp (+ i 1)))
782 #f)))
783
784 (define-method (in (x <string>) (s <string>))
785 (string-contains s x))
786
787 (define-method (in (x <char>) (s <string>))
788 (let/ec ret
789 (string-for-each
790 (lambda (ch)
791 (if (eq? ch x)
792 (ret #t)))
793 s))
794 #f)
795
796 (define-method (in x (o <py-list>))
797 (define l (slot-ref o 'vec))
798 (define n (slot-ref o 'n))
799 (let lp ((i 0))
800 (if (< i n)
801 (if (equal? x (vector-ref l i))
802 #t
803 (lp (+ i 1)))
804 #f)))
805
806 (define-method (in x (o <p>))
807 (aif it (ref o '__contains__)
808 (it x)
809 (next-method)))
810
811 (define-syntax-rule (defgen (op r s o1 o2) code ...)
812 (begin
813 (define-method (op (o1 <py-list>) (o2 <py-list>)) code ...)
814 (define-method (op (o1 <pair>) (o2 <pair> )) code ...)
815 (define-method (op (o1 <py-tuple>) o2)
816 (op (slot-ref o1 'l) o2))
817 (define-method (op o2 (o1 <py-tuple>))
818 (op o2 (slot-ref o1 'l)))
819 (define-method (op (o1 <vector>) (o2 <vector>)) code ...)
820 (define-method (op (o1 <p>) o2)
821 (aif it (ref o1 'r)
822 (it o2)
823 (next-method)))
824 (define-method (op o1 (o2 <p>))
825 (aif it (ref o2 's)
826 (it o1)
827 (next-method)))))
828
829 (defgen (< __le__ __gt__ o1 o2)
830 (let ((n1 (len o1))
831 (n2 (len o2)))
832 (for ((x1 : o1) (x2 : o2)) ()
833 (if (< x1 x2)
834 (break #t))
835 #:final
836 (< n1 n2))))
837
838 (defgen (<= __lt__ __ge__ o1 o2)
839 (let ((n1 (len o1))
840 (n2 (len o2)))
841 (for ((x1 : o1) (x2 : o2)) ()
842 (if (< x1 x2)
843 (break #t))
844 #:final
845 (<= n1 n2))))
846
847 (defgen (> __ge__ __lt__ o1 o2)
848 (let ((n1 (len o1))
849 (n2 (len o2)))
850 (for ((x1 : o1) (x2 : o2)) ()
851 (if (> x1 x2)
852 (break #t))
853 #:final
854 (> n1 n2))))
855
856 (defgen (>= __gt__ __le__ o1 o2)
857 (let ((n1 (len o1))
858 (n2 (len o2)))
859 (for ((x1 : o1) (x2 : o2)) ()
860 (if (> x1 x2)
861 (break #t))
862 #:final
863 (>= n1 n2))))
864
865 (define-python-class list (<py-list>)
866 (define __init__
867 (letrec ((__init__
868 (case-lambda
869 ((self)
870 (slot-set! self 'vec (make-vector 30))
871 (slot-set! self 'n 0))
872 ((self it)
873 (__init__ self)
874 (for ((i : it)) () (pylist-append! self i))))))
875 __init__)))
876
877 (name-object list)
878
879 (define pylist list)
880
881 (define-method (py-class (o <py-list>) list))
882
883 (define (pylist-listing)
884 (let ((l
885 (to-pylist
886 (map symbol->string
887 '(append
888 count
889 extend
890 index
891 pop
892 insert
893 remove
894 reverse
895 sort
896 __init__
897 __le__
898 __lt__
899 __gt__
900 __ge__
901 __ne__
902 __eq__
903 __len__
904 __init__
905 __add__
906 __mul__
907 __rmul__
908 __radd__
909 __repr__
910 __contains__
911 __getattr__
912 __setattr__
913 __delattr__
914 __delitem__
915 __setitem__
916 __iter__
917 )))))
918
919 (pylist-sort! l)
920 l))
921
922 (define (py-all x)
923 (for ((i : x)) ()
924 (if (not i)
925 (break #f))
926 #:final
927 #t))
928
929 (define (py-any x)
930 (for ((i : x)) ()
931 (if i
932 (break #t))
933 #:final
934 #f))