slices now working
[software/python-on-guile.git] / modules / language / python / list.scm
1 (define-module (language python list)
2 #:use-module (oop pf-objects)
3 #:use-module (oop goops)
4 #:use-module (language python exceptions)
5 #:use-module (language python yield)
6 #:use-module (language python for)
7 #:use-module (language python try)
8 #:use-module (language python exceptions)
9 #:export (to-list pylist-ref pylist-set! pylist-append!
10 pylist-slice))
11
12 (define-syntax-rule (aif it p x y) (let ((it p)) (if it x y)))
13
14 (define-method (to-list x)
15 (if (vector? x)
16 (vector->list x)
17 x))
18
19 (define-method (to-list (x <p>))
20 ((ref x '__tolist__ (lambda () (error "missing __tolist__ in object")))))
21
22
23 (define-method (to-list (x <yield>))
24 (define l '())
25 (catch StopIteration
26 (lambda ()
27 (let lp ()
28 (set! l (cons (next x) l))
29 (lp)))
30 (lambda x
31 (reverse l))))
32
33 (define-class <py-list> () vec n)
34
35 (define-method (to-pylist (l <pair>))
36 (let* ((n (length l))
37 (vec (make-vector (* 2 n)))
38 (o (make <py-list>)))
39
40 (let lp ((l l) (i 0))
41 (if (pair? l)
42 (begin
43 (vector-set! vec i (car l))
44 (lp (cdr l) (+ i 1)))))
45
46 (slot-set! o 'n n)
47 (slot-set! o 'vec vec)
48 o))
49
50 (define-method (to-pylist (l <vector>))
51 (to-pylist (vector->list l)))
52
53 (define-method (to-pylist l)
54 (if (null? l)
55 (let ((o (make <py-list>)))
56 (slot-set! o 'vec (make-vector 4))
57 (slot-set! o 'n 0)
58 o)
59 (error "not able to make a pylist")))
60
61 ;;; REF
62 (define-method (pylist-ref (o <py-list>) n)
63 (if (< n (slot-ref o 'n))
64 (vector-ref (slot-ref o 'vec) n)
65 (raise IndexError)))
66
67 (define-method (pylist-ref (o <pair>) n)
68 (list-ref o n))
69
70 (define-method (pylist-ref (o <vector>) n)
71 (vector-ref o n))
72
73 (define-method (pylist-ref (o <p>) n)
74 ((ref o '__listref__) n))
75
76 ;;; SET
77 (define-method (pylist-set! (o <py-list>) n val)
78 (if (< n (slot-ref o 'n))
79 (vector-set! (slot-ref o 'vec) n val)
80 (raise IndexError)))
81
82 (define-method (pylist-set! (o <pair>) n val)
83 (list-set! o n val))
84
85 (define-method (pylist-set! (o <vector>) n val)
86 (vector-set! o n val))
87
88 (define-method (pylist-set! (o <p>) n val)
89 ((ref o '__listset__) n val))
90
91 ;;SLICE
92 (define-method (pylist-slice (o <py-list>) n1 n2 n3)
93 (let* ((n1 (if (eq? n1 'None) 0 n1))
94 (n2 (if (eq? n2 'None) (slot-ref o 'n) n2))
95 (n3 (if (eq? n3 'None) 1 n3))
96
97 (vec (slot-ref o 'vec))
98 (l (let lp ((i n1))
99 (if (< i n2)
100 (cons (vector-ref vec i) (lp (+ i n3)))
101 '()))))
102 (to-pylist l)))
103
104 (define-method (pylist-slice o n1 n2 n3)
105 (pylist-slice (to-pylist o) n1 n2 n3))
106
107 ;;APPEND
108 (define-method (pylist-append! (o <py-list>) val)
109 (let* ((n (slot-ref o 'n))
110 (vec (slot-ref o 'vec))
111 (N (vector-length vec)))
112 (if (< n N)
113 (begin
114 (vector-set! vec n val)
115 (slot-set! o 'n (+ n 1)))
116 (let* ((N (* 2 N))
117 (vec2 (make-vector N)))
118 (let lp ((i 0))
119 (if (< i n)
120 (begin
121 (vector-set! vec2 i (vector-ref vec i))
122 (lp (+ i 1)))))
123 (vector-set! vec2 n val)
124 (slot-set! o 'vec vec2)))
125 (slot-set! o 'n (+ n 1))
126 (values)))
127
128 (define-method (pylist-append! o n)
129 (raise 'NotSupportedOP '__append__))
130
131 (define-method (pylist-append! (o <p>) n . l)
132 (aif it (ref o '__append__)
133 (it n)
134 (aif it (ref o 'append)
135 (apply it n l)
136 (error "no append"))))
137
138
139 (define-method (to-list (x <py-list>))
140 (let ((vec (slot-ref x 'vec))
141 (n (slot-ref x 'n)))
142 (let lp ((i 0))
143 (if (< i n)
144 (cons (vector-ref vec i) (lp (+ i 1)))
145 '()))))
146
147
148 (define-method (write (o <py-list>) . l)
149 (define port (if (null? l) #t (car l)))
150
151 (let* ((l (to-list o)))
152 (if (null? l)
153 (format port "[]")
154 (format port "[~a~{, ~a~}]" (car l) (cdr l)))))
155
156 (define-method (display (o <py-list>) . l)
157 (define port (if (null? l) #t (car l)))
158
159 (let* ((l (to-list o)))
160 (if (null? l)
161 (format port "[]")
162 (format port "[~a~{, ~a~}]" (car l) (cdr l)))))
163