45a10696018e88a044aa1c781a2474a585181813
[software/python-on-guile.git] / modules / language / python / range.scm
1 (define-module (language python range)
2 #:use-module (oop pf-objects)
3 #:use-module (language python exceptions)
4 #:use-module (language python number)
5 #:use-module (language python list)
6 #:use-module (language python yield)
7 #:use-module (language python try)
8 #:export (range))
9
10 (define-python-class range ()
11 (define __init__
12 (case-lambda
13 ((self n)
14 (let ((n (py-index n)))
15 (set self '_a 0)
16 (set self '_b (max 0 n))
17 (set self '_c 1)))
18
19 ((self n m)
20 (let ((n (py-index n))
21 (m (py-index m)))
22 (set self '_a n)
23 (set self '_b (max m n))
24 (set self '_c 1)))
25
26 ((self n m k)
27 (let ((n (py-index n))
28 (m (py-index m))
29 (k (py-index k)))
30 (cond
31 ((= k 0)
32 (raise TypeError "range does not allow 0 as a step"))
33 ((> k 0)
34 (set self '_a n)
35 (set self '_b (if (< m n) n m))
36 (set self '_c k))
37 ((< k 0)
38 (set self '_a n)
39 (set self '_b (if (> m n) n m))
40 (set self '_c k)))))))
41
42 (define __iter__
43 (make-generator (self)
44 (lambda (yield self)
45 (let* ((a (ref self '_a))
46 (b (ref self '_b))
47 (c (ref self '_c))
48 (aa (if (> c 0) a (- a 1)))
49 (op (if (> c 0) < >=)))
50 (let lp ((i aa))
51 (if (op i b)
52 (begin
53 (yield i)
54 (lp (+ i c)))))))))
55
56 (define __reversed__
57 (lambda (self)
58 (__getslice__ self None None -1)))
59
60 (define __repr__
61 (lambda (self)
62 (format #f "range(~a,~a,~a)"
63 (ref self '_a)
64 (ref self '_b)
65 (ref self '_c))))
66
67 (define __contains__
68 (lambda (self x)
69 (let ((x (py-index x ))
70 (a (ref self '_a))
71 (b (ref self '_b))
72 (c (ref self '_c)))
73 (if (> c 0)
74 (and
75 (>= x a)
76 (< x b)
77 (= (modulo (- x a) c) 0))
78 (and
79 (<= x a)
80 (> x b)
81 (= (modulo (- x a) c) 0))))))
82
83 (define __getitem__
84 (lambda (self x)
85 (let* ((x (py-index x))
86 (a (ref self '_a))
87 (b (ref self '_b))
88 (c (ref self '_c))
89 (m (+ a (* c x))))
90 (if (> c 0)
91 (if (and (>= x 0)
92 (< m b))
93 m
94 (raise IndexError "getitem out of range"))
95 (if (and (<= x 0)
96 (> m b))
97 m
98 (raise IndexError "getitem out of range"))))))
99
100 (define __min__
101 (lambda (self)
102 (let* ((a (ref self '_a))
103 (b (ref self '_b))
104 (c (ref self '_c))
105 (n (abs (py-floordiv (- a b) c))))
106 (if (> c 0)
107 a
108 (+ a (* c (- n 1)))))))
109
110 (define __max__
111 (lambda (self)
112 (let* ((a (ref self '_a))
113 (b (ref self '_b))
114 (c (ref self '_c))
115 (n (abs (py-floordiv (- a b) c))))
116 (if (> c 0)
117 (+ a (* c (- n 1)))
118 n))))
119
120 (define __len__
121 (lambda (self)
122 (let* ((a (ref self '_a))
123 (b (ref self '_b))
124 (c (ref self '_c)))
125 (abs (py-floordiv (- a b) c)))))
126
127 (define __getslice__
128 (lambda (self x y z)
129 (let* ((a (ref self '_a))
130 (b (ref self '_b))
131 (c (ref self '_c))
132 (x (if (eq? x None) None (py-index x)))
133 (y (if (eq? y None) None (py-index y)))
134 (z (if (eq? z None) None (py-index z)))
135 (n (abs (py-floordiv (- a b) c))))
136 (if (or (eq? z None) (> (* z c) 0))
137 (begin
138 (if (eq? z 'None) (set! z 1))
139 (if (eq? y 'None) (set! y n))
140 (if (eq? x 'None) (set! x 0))
141 (if (< x 0) (set! x 0))
142 (if (> x n) (set! x n))
143 (if (< y 0) (set! y 0))
144 (if (> y n) (set! y n))
145 (let* ((cc (* c z))
146 (xx (+ a (* c x)))
147 (yy (+ a (* c y)))
148 (aa (min xx yy))
149 (bb (max xx yy)))
150 (range aa bb cc)))
151 (begin
152 (if (eq? y 'None) (set! y 0))
153 (if (eq? x 'None) (set! x n))
154 (if (< x 0) (set! x 0))
155 (if (> x n) (set! x n))
156 (if (< y 0) (set! y 0))
157 (if (> y n) (set! y n))
158 (let* ((cc (* c z))
159 (xx (+ a (* c x)))
160 (yy (+ a (* c y)))
161 (aa (max xx yy))
162 (bb (min xx yy)))
163 (range aa bb cc)))))))
164
165 (define __index__
166 (case-lambda
167 ((self x)
168 (let ((x (py-index x ))
169 (a (ref self '_a))
170 (b (ref self '_b))
171 (c (ref self '_c)))
172 (if (> c 0)
173 (if (and
174 (>= x a)
175 (< x b)
176 (= (modulo (- x a) c) 0))
177 (py-floordiv (- x a) c)
178 (raise IndexError))
179
180 (if (and
181 (<= x a)
182 (> x b)
183 (= (modulo (- x a) c) 0))
184 (py-floordiv (- x a) c)
185 (raise IndexError)))))
186
187 ((self x i)
188 (py-index (pylist-slice None i 1) x))
189 ((self x i j)
190 (py-index (pylist-slice i j 1) x))))
191
192 (define __count__
193 (lambda (self i)
194 (if (__contains__ self i)
195 1
196 0))))
197
198
199
200
201
202