(define-module (language python list) #:use-module (oop pf-objects) #:use-module (oop goops) #:use-module (language python exceptions) #:use-module (language python yield) #:use-module (language python for) #:use-module (language python try) #:use-module (language python exceptions) #:export (to-list pylist-ref pylist-set! pylist-append! pylist-slice pylist-subset! pylist-reverse! pylist-pop! pylist-count)) (define-syntax-rule (aif it p x y) (let ((it p)) (if it x y))) (define-class () vec n) (define-method (to-list x) (if (vector? x) (vector->list x) x)) (define-method (to-list (x

)) ((ref x '__tolist__ (lambda () (error "missing __tolist__ in object"))))) (define-method (to-list (x )) (define l '()) (catch StopIteration (lambda () (let lp () (set! l (cons (next x) l)) (lp))) (lambda x (reverse l)))) (define-method (to-list (x )) (let ((vec (slot-ref x 'vec)) (n (slot-ref x 'n))) (let lp ((i 0)) (if (< i n) (cons (vector-ref vec i) (lp (+ i 1))) '())))) (define-method (to-pylist (l )) l) (define-method (to-pylist (l )) (let* ((n (length l)) (vec (make-vector (* 2 n))) (o (make ))) (let lp ((l l) (i 0)) (if (pair? l) (begin (vector-set! vec i (car l)) (lp (cdr l) (+ i 1))))) (slot-set! o 'n n) (slot-set! o 'vec vec) o)) (define-method (to-pylist (l )) (to-pylist (vector->list l))) (define-method (to-pylist l) (if (null? l) (let ((o (make ))) (slot-set! o 'vec (make-vector 4)) (slot-set! o 'n 0) o) (error "not able to make a pylist"))) ;;; REF (define-method (pylist-ref (o ) nin) (define N (slot-ref o 'n)) (define n (if (< nin 0) (+ N nin) nin)) (if (and (>= n 0) (< n (slot-ref o 'n))) (vector-ref (slot-ref o 'vec) n) (raise IndexError))) (define-method (pylist-ref (o ) n) (define n (if (< n 0) (+ (length o) n))) (list-ref o n)) (define-method (pylist-ref (o ) n) (vector-ref o n)) (define-method (pylist-ref (o

) n) ((ref o '__listref__) n)) ;;; SET (define-method (pylist-set! (o ) nin val) (define N (slot-ref o 'n)) (define n (if (< nin 0) (+ N nin) nin)) (if (and (>= n 0) (< n (slot-ref o 'n))) (vector-set! (slot-ref o 'vec) n val) (raise IndexError))) (define-method (pylist-set! (o ) n val) (list-set! o n val)) (define-method (pylist-set! (o ) n val) (vector-set! o n val)) (define-method (pylist-set! (o

) n val) ((ref o '__listset__) n val)) ;;SLICE (define-method (pylist-slice (o ) n1 n2 n3) (define N (slot-ref o 'n)) (define (f n) (if (< n 0) (+ N n) n)) (let* ((n1 (f (if (eq? n1 'None) 0 n1))) (n2 (f (if (eq? n2 'None) (slot-ref o 'n) n2))) (n3 (f (if (eq? n3 'None) 1 n3))) (vec (slot-ref o 'vec)) (l (let lp ((i n1)) (if (< i n2) (cons (vector-ref vec i) (lp (+ i n3))) '())))) (to-pylist l))) (define-method (pylist-slice o n1 n2 n3) (pylist-slice (to-pylist o) n1 n2 n3)) ;;SUBSET (define-method (pylist-subset! (o ) n1 n2 n3 val) (define N (slot-ref o 'n)) (define (f n) (if (< n 0) (+ N n) n)) (let* ((n1 (f (if (eq? n1 'None) 0 n1))) (n2 (f (if (eq? n2 'None) (slot-ref o 'n) n2))) (n3 (f (if (eq? n3 'None) 1 n3))) (vec (slot-ref o 'vec)) (o2 (to-pylist val)) (N2 (slot-ref o2 'n)) (vec2 (slot-ref o2 'vec))) (if (<= n2 N) (let lp ((i 0) (j n1)) (if (< j n2) (if (< i N2) (begin (vector-set! vec j (vector-ref vec2 i)) (lp (+ i 1) (+ j n3))) (let lp ((j2 j)) (if (< j2 n2) (lp (+ j2 n3)) (let lp ((k1 j) (k2 j2)) (if (< k2 N) (begin (vector-set! vec k1 (vector-ref vec k2)) (lp (+ k1 1) (+ k2 1))) (slot-set! o 'n k1)))))))) (raise IndexError)) (values))) ;;APPEND (define-method (pylist-append! (o ) val) (let* ((n (slot-ref o 'n)) (vec (slot-ref o 'vec)) (N (vector-length vec))) (if (< n N) (begin (vector-set! vec n val) (slot-set! o 'n (+ n 1))) (let* ((N (* 2 N)) (vec2 (make-vector N))) (let lp ((i 0)) (if (< i n) (begin (vector-set! vec2 i (vector-ref vec i)) (lp (+ i 1))))) (vector-set! vec2 n val) (slot-set! o 'vec vec2))) (slot-set! o 'n (+ n 1)) (values))) (define-method (pylist-append! o n) (raise 'NotSupportedOP '__append__)) (define-method (pylist-append! (o

) n . l) (aif it (ref o 'append) (apply it n l) (error "no append"))) (define-method (write (o ) . l) (define port (if (null? l) #t (car l))) (let* ((l (to-list o))) (if (null? l) (format port "[]") (format port "[~a~{, ~a~}]" (car l) (cdr l))))) (define-method (display (o ) . l) (define port (if (null? l) #t (car l))) (let* ((l (to-list o))) (if (null? l) (format port "[]") (format port "[~a~{, ~a~}]" (car l) (cdr l))))) (define-method (+ (o1 ) (o2 )) (let* ((vec1 (slot-ref o1 'vec)) (vec2 (slot-ref o2 'vec)) (n1 (slot-ref o1 'n)) (n2 (slot-ref o2 'n)) (n (+ n1 n2)) (vec (make-vector (* 2 n))) (o (make ))) (let lp ((i1 0)) (if (< i1 n1) (begin (vector-set! vec i1 (vector-ref vec1 i1)) (lp (+ i1 1))) (let lp ((i2 0) (i i1)) (if (< i2 n2) (begin (vector-set! vec i (vector-ref vec2 i2)) (lp (+ i2 1) (+ i 1))))))) (slot-set! o 'n n ) (slot-set! o 'vec vec) o)) (define-method (+ (o1 ) (o2 )) (append o1 o2)) (define-method (+ (o1 ) (o2 )) (string-append o1 o2)) (define-method (* (o1 ) (x )) (let* ((vec (slot-ref o1 'vec)) (n (slot-ref o1 'n)) (n2 (* n x)) (vec2 (make-vector (* 2 n2))) (o (make ))) (let lp1 ((i 0) (j 0)) (if (< i x) (let lp2 ((j j) (k 0)) (if (< k n) (begin (vector-set! vec2 j (vector-ref vec k)) (lp2 (+ j 1) (+ k 1))) (lp1 (+ i 1) j))))) (slot-set! o 'n n2 ) (slot-set! o 'vec vec2) o)) (define-method (* (vec ) (x )) (let* ((n (string-length vec)) (n2 (* n x)) (vec2 (make-string n2))) (let lp1 ((i 0) (j 0)) (if (< i x) (let lp2 ((j j) (k 0)) (if (< k n) (begin (string-set! vec2 j (string-ref vec k)) (lp2 (+ j 1) (+ k 1))) (lp1 (+ i 1) j))))) vec2)) (define-method (* (l ) (x )) (let lp1 ((i 0)) (if (< i x) (let lp2 ((k l)) (if (pair? k) (cons (car k) (lp2 (cdr k))) (lp1 (+ i 1)))) '()))) (define-method (+ (o1 ) (o2 )) (append o1 o2)) (define-method (+ (o1 ) (o2 )) (string-append o1 o2)) ;;REVERSE (define-method (pylist-reverse! (o )) (let* ((N (slot-ref o 'n)) (M (- N 1)) (n (floor-quotient N 2)) (vec (slot-ref o 'vec))) (let lp ((i 0)) (if (< i n) (let ((swap (vector-ref vec i)) (k (- M i))) (vector-set! vec i (vector-ref vec k)) (vector-set! vec k swap)))))) (define-method (pylist-reverse! (o

)) ((ref o 'reverse))) ;;POP! (define-method (pylist-pop! (o )) (let* ((n (slot-ref o 'n)) (m (- n 1)) (vec (slot-ref o 'vec))) (if (> n 0) (let ((ret (vector-ref vec m))) (slot-set! o 'n m) (vector-set! vec m #f) ret) (raise IndexError "pop from empty list")))) (define-method (pylist-pop! (o

)) ((ref o 'pop))) ;;COUNT (define-method (pylist-count (o ) q) (let* ((n (slot-ref o 'n)) (vec (slot-ref o 'vec))) (let lp ((i 0) (sum 0)) (if (< i n) (if (equal? (vector-ref vec i) q) (lp (+ i 1) (+ sum 1)) (lp (+ i 1) sum )) sum)))) (define-method (pylist-count (s ) q) (let* ((n (string-length s)) (q (if (and (string? q) (= (string-length q) 1)) (string-ref q 0)))) (let lp ((i 0) (sum 0)) (if (< i n) (if (eq? (string-ref s i) q) (lp (+ i 1) (+ sum 1)) (lp (+ i 1) sum )) sum)))) (define-method (pylist-count (l ) q) (let lp ((l l) (sum 0)) (if (pair? l) (if (eq? (car l) q) (lp (cdr l) (+ sum 1)) (lp (cdr l) sum )) sum))) (define-method (pylist-count (o

) q) ((ref o 'count) q))