(define-module (language python range) #:use-module (oop pf-objects) #:use-module (language python exceptions) #:use-module (language python number) #:use-module (language python list) #:use-module (language python yield) #:use-module (language python try) #:use-module (language python persist) #:export (range)) (define-python-class range () (define __init__ (case-lambda ((self n) (let ((n (py-index n))) (set self '_a 0) (set self '_b (max 0 n)) (set self '_c 1))) ((self n m) (let ((n (py-index n)) (m (py-index m))) (set self '_a n) (set self '_b (max m n)) (set self '_c 1))) ((self n m k) (let ((n (py-index n)) (m (py-index m)) (k (py-index k))) (cond ((= k 0) (raise TypeError "range does not allow 0 as a step")) ((> k 0) (set self '_a n) (set self '_b (if (< m n) n m)) (set self '_c k)) ((< k 0) (set self '_a n) (set self '_b (if (> m n) n m)) (set self '_c k))))))) (define __iter__ (lambda (self) ((make-generator () (lambda (yield) (let* ((a (ref self '_a)) (b (ref self '_b)) (c (ref self '_c)) (aa (if (> c 0) a (- a 1))) (op (if (> c 0) < >))) (let lp ((i aa)) (if (op i b) (begin (yield i) (lp (+ i c))))))))))) (define __reversed__ (lambda (self) (__getslice__ self None None -1))) (define __repr__ (lambda (self) (format #f "range(~a,~a,~a)" (ref self '_a) (ref self '_b) (ref self '_c)))) (define __contains__ (lambda (self x) (let ((x (py-index x )) (a (ref self '_a)) (b (ref self '_b)) (c (ref self '_c))) (if (> c 0) (and (>= x a) (< x b) (= (modulo (- x a) c) 0)) (and (<= x a) (> x b) (= (modulo (- x a) c) 0)))))) (define __getitem__ (lambda (self x) (let* ((x (py-index x)) (a (ref self '_a)) (b (ref self '_b)) (c (ref self '_c)) (m (+ a (* c x)))) (if (> c 0) (if (and (>= x 0) (< m b)) m (raise IndexError "getitem out of range")) (if (and (<= x 0) (> m b)) m (raise IndexError "getitem out of range")))))) (define __min__ (lambda (self) (let* ((a (ref self '_a)) (b (ref self '_b)) (c (ref self '_c)) (n (abs (py-floordiv (- a b) c)))) (if (> c 0) a (+ a (* c (- n 1))))))) (define __max__ (lambda (self) (let* ((a (ref self '_a)) (b (ref self '_b)) (c (ref self '_c)) (n (abs (py-floordiv (- a b) c)))) (if (> c 0) (+ a (* c (- n 1))) n)))) (define __len__ (lambda (self) (let* ((a (ref self '_a)) (b (ref self '_b)) (c (ref self '_c))) (abs (py-floordiv (- a b) c))))) (define __getslice__ (lambda (self x y z) (let* ((a (ref self '_a)) (b (ref self '_b)) (c (ref self '_c)) (x (if (eq? x None) None (py-index x))) (y (if (eq? y None) None (py-index y))) (z (if (eq? z None) None (py-index z))) (n (abs (py-floordiv (- a b) c)))) (if (or (eq? z None) (> (* z c) 0)) (begin (if (eq? z 'None) (set! z 1)) (if (eq? y 'None) (set! y n)) (if (eq? x 'None) (set! x 0)) (if (< x 0) (set! x 0)) (if (> x n) (set! x n)) (if (< y 0) (set! y 0)) (if (> y n) (set! y n)) (let* ((cc (* c z)) (xx (+ a (* c x))) (yy (+ a (* c y))) (aa (min xx yy)) (bb (max xx yy))) (range aa bb cc))) (begin (if (eq? y 'None) (set! y 0)) (if (eq? x 'None) (set! x n)) (if (< x 0) (set! x 0)) (if (> x n) (set! x n)) (if (< y 0) (set! y 0)) (if (> y n) (set! y n)) (let* ((cc (* c z)) (xx (+ a (* c x))) (yy (+ a (* c y))) (aa (max xx yy)) (bb (min xx yy))) (range aa bb cc))))))) (define __index__ (case-lambda ((self x) (let ((x (py-index x )) (a (ref self '_a)) (b (ref self '_b)) (c (ref self '_c))) (if (> c 0) (if (and (>= x a) (< x b) (= (modulo (- x a) c) 0)) (py-floordiv (- x a) c) (raise IndexError)) (if (and (<= x a) (> x b) (= (modulo (- x a) c) 0)) (py-floordiv (- x a) c) (raise IndexError))))) ((self x i) (py-index (pylist-slice None i 1) x)) ((self x i j) (py-index (pylist-slice i j 1) x)))) (define __count__ (lambda (self i) (if (__contains__ self i) 1 0)))) (name-object range)