(define-module (language python list) #:use-module (ice-9 match) #:use-module (ice-9 control) #:use-module (oop pf-objects) #:use-module (oop goops) #:use-module (language python hash) #:use-module (language python tuple) #:use-module (language python exceptions) #:use-module (language python yield) #:use-module (language python for) #:use-module (language python try) #:use-module (language python bool) #:use-module (language python exceptions) #:use-module (language python persist) #:re-export (pylist-ref pylist-set!) #:export (to-list to-pylist py-list pylist-append! pylist-slice pylist-subset! pylist-reverse! pylist-pop! pylist-count pylist-extend! len in pylist-insert! pylist-remove! pylist-sort! pylist-index pylist-null pylist-delete! pylist pylist-listing py-reversed py-all py-any py-reversed)) (define scm-list list) (define-method (+ (x ) (y )) (let lp ((l y)) (if (pair? l) (cons (car l) (lp (cdr l))) '()))) (define-method (+ (x ) (y )) (let lp ((l x)) (if (pair? l) (cons (car l) (lp (cdr l))) '()))) (define-method (in x (y )) #f) (define-syntax-rule (aif it p x y) (let ((it p)) (if it x y))) (define-class () vec n) (name-object ) (cpit (o (lambda (o n l) (slot-set! o 'n n) (slot-set! o 'vec (list->vector l))) ((@ (guile) list) (slot-ref o 'n) (vector->list (slot-ref o 'vec))))) (define-method (pylist-delete! (o ) k) (let* ((n (slot-ref o 'n)) (k (if (< k 0) (+ k n) k))) (pylist-subset! o k (+ k 1) None pylist-null))) (define-method (pylist-delete! (o

) k) (aif it (ref o '__delitem__) (it k) (next-method))) (define pylist-null (let ((o (make ))) (slot-set! o 'vec (make-vector 0)) (slot-set! o 'n 0) o)) (define-method (py-hash (o )) (let ((n (min complexity (slot-ref o 'n))) (v (slot-ref o 'vec))) (let lp ((i 0) (s 0)) (if (< i n) (lp (+ i 1) (xy (py-hash (vector-ref v i)) s)) s)))) (define-method (to-list x) (for ((i : x)) ((r '())) (cons i r) #:final (reverse r))) (define-method (to-list (x

)) (aif it (ref x '__tolist__) (it) (next-method))) (defpair (to-list x) x) (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) (defpair (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 (o )) (to-pylist (string->list o))) (define-method (bool (o )) (if (= (len o) 0) #f o)) (define-method (bool (o )) (if (= (len o) 0) #f o)) (define-method (bool (o )) (if (= (len o) 0) #f o)) (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))) (defpair (pylist-ref o n) (list-ref o (if (< n 0) (+ (length o) n) n))) (define-method (pylist-ref (o ) n) (vector-ref o 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))) (defpair (pylist-set! o n val) (list-set! o n val)) (define-method (pylist-set! (o ) n val) (vector-set! o n val)) ;;SLICE (define-method (pylist-slice (o

) . l) (aif it (ref o '__getslice__) (apply it l) (next-method))) (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) (define N (string-length o)) (define (f n) (if (< n 0) (+ N n) n)) (let* ((n1 (f (if (eq? n1 None) 0 n1))) (n2 (f (if (eq? n2 None) (string-length o) n2))) (n3 (f (if (eq? n3 None) 1 n3)))) (list->string (to-list (pylist-slice (to-pylist o) n1 n2 n3))))) (defpair (pylist-slice o n1 n2 n3) (to-list (pylist-slice (to-pylist o) n1 n2 n3))) (define-method (pylist-slice (o ) n1 n2 n3) (list->vector (to-list (pylist-slice (to-pylist o) n1 n2 n3)))) ;;SUBSET (define-method (pylist-subset! (o

) n1 n2 n3 val) (aif it (ref o '__setslice__) (it n1 n2 n3 val) (next-method))) (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))) (begin (let lp ((i k2)) (if (< i N) (begin (vector-set! vec i #f) (lp (+ i 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) (vector-set! vec n val) (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) (next-method))) (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) (+ (slot-ref o1 'l) o2)) (define-method (+ o2 (o1 )) (+ o2 (slot-ref o1 'l))) (define-method (+ (o1 ) (o2 )) (string-append o1 o2)) (define-method (+ (o1 ) (o2 )) (string->symbol (string-append (symbol->string o1) (symbol->string o2)))) (define-method (* (x ) (o1 )) (* o1 x)) (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 (* (x ) (vec )) (* vec x)) (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 (* (x ) (l )) (* l x)) (define-method (* (x ) l) (* (slot-ref x 'l) l)) (define-method (* l (x )) (* l (slot-ref x 'l))) (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)))) '()))) ;;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) (lp (+ i 1))))))) (define-method (pylist-reverse! (o

) . l) (aif it (ref o 'reverse) (apply it l) (next-method))) ;;POP! (define-method (pylist-pop! (o ) . l) (let ((index (if (null? l) #f (car l)))) (if index (let ((x (pylist-ref o index))) (pylist-delete! o index) x) (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

) . l) (aif it (ref o 'pop) (apply it l) (next-method))) ;;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)))) (defpair (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

) . l) (aif it (ref o 'count) (apply it l) (next-method))) ;; extend! (define-method (pylist-extend! (o ) iter) (for ((x : iter)) () (pylist-append! o x))) (define-method (pylist-extend! (o

) . l) (aif it (ref o 'extend) (apply it l) (next-method))) ;; equal? (define-method (py-equal? (o1 ) (o2 )) (equal o1 o2)) (define (equal o1 o2) (let ((n1 (slot-ref o1 'n)) (n2 (slot-ref o2 'n)) (vec1 (slot-ref o1 'vec)) (vec2 (slot-ref o2 'vec))) (and (equal? n1 n2) (let lp ((i 0)) (if (< i n1) (and (equal? (vector-ref vec1 i) (vector-ref vec2 i)) (lp (+ i 1))) #t))))) (define-class () o i n d) (define-class () i d) (name-object ) (name-object ) (cpit (o (lambda (o i d) (slot-set! o 'i i) (slot-set! o 'd d)) (list (slot-ref o 'i) (slot-ref o 'd)))) (cpit (o (lambda (o oo i n d) (slot-set! o 'o oo) (slot-set! o 'i i) (slot-set! o 'n i) (slot-set! o 'd d)) (list (slot-ref o 'o) (slot-ref o 'i) (slot-ref o 'n) (slot-ref o 'd)))) (define-method (write (o ) . l) (define port (if (null? l) #t (car l))) (for ((x : o)) ((l '())) (cons x l) #:final (let ((l (reverse l))) (if (null? l) (format port "iter[]") (format port "iter[~a~{, ~a~}]" (car l) (cdr l)))))) (define-method (write (o ) . l) (define port (if (null? l) #t (car l))) (for ((x : o)) ((l '())) (cons x l) #:final (let ((l (reverse l))) (if (null? l) (format port "iter[]") (format port "iter[~a~{, ~a~}]" (car l) (cdr l)))))) ;;WRAP-IN (define-method (wrap-in (o )) (let ((out (make ))) (slot-set! out 'n (slot-ref o 'n )) (slot-set! out 'vec (slot-ref o 'vec)) (slot-set! out 'i 0) (slot-set! out 'd 1) out)) (define-method (wrap-in (o )) (let ((out (make ))) (slot-set! out 'n (vector-length o)) (slot-set! out 'vec o) (slot-set! out 'i 0) (slot-set! out 'd 1) out)) (define-method (py-reversed (o )) (let ((out (make ))) (slot-set! out 'i (- (slot-ref o 'n) 1)) (slot-set! out 'vec (slot-ref o 'vec)) (slot-set! out 'n (slot-ref o 'n)) (slot-set! out 'd -1) out)) (define-method (py-reversed (o

)) (aif it (ref o '__reversed__) (it) (let ((a (ref o '__getitem__)) (n (ref o '__len__))) (if (and a n) (let ((ret (make ))) (slot-set! ret 'o a) (slot-set! ret 'i (n)) (slot-set! ret 'n -1) (slot-set! ret 'd -1)) (next-method))))) (define-method (wrap-in (o

)) (aif it (ref o '__iter__) (let ((x (it))) (cond ((pair? x) (wrap-in x)) (else x))) (let ((a (ref o '__getitem__))) (if a (let ((ret (make ))) (slot-set! ret 'o a) (slot-set! ret 'i 0) (slot-set! ret 'n -1) (slot-set! ret 'd 1)) (next-method))))) (define-method (wrap-in (o )) o) (define-method (wrap-in (o )) o) (define-method (wrap-in (o )) o) ;;NEXT (define-method (next (o )) (let ((i (slot-ref o 'i)) (d (slot-ref o 'd)) (a (slot-ref o 'a))) (let ((r (a i))) (slot-set! o 'i (+ i d)) r))) (define-method (next (o )) (let ((i (slot-ref o 'i )) (d (slot-ref o 'd)) (n (slot-ref o 'n )) (vec (slot-ref o 'vec))) (if (> d 0) (if (< i n) (let ((ret (vector-ref vec i))) (slot-set! o 'i (+ i 1)) ret) (throw StopIteration)) (if (>= i 0) (let ((ret (vector-ref vec i))) (slot-set! o 'i (- i 1)) ret) (throw StopIteration))))) ;;INSERT (define-method (pylist-insert! (o ) i val) (let* ((vec (slot-ref o 'vec)) (n (slot-ref o 'n)) (i (if (< i 0) (+ n i) i))) (if (and (>= i 0) (<= i n)) (let lp ((v val) (i i)) (if (< i n) (let ((swap (vector-ref vec i))) (vector-set! vec i v) (lp swap (+ i 1))) (pylist-append! o v))) (raise IndexError "Wrong index in insert")))) (define-method (pylist-insert! (o

) . l) (aif it (ref o 'insert) (apply it l) (next-method))) ;;REMOVE (define-method (pylist-remove! (o ) val) (let ((n (slot-ref o 'n )) (vec (slot-ref o 'vec))) (let lp ((i 0)) (if (< i n) (let ((r (vector-ref vec i))) (if (equal? r val) (pylist-subset! o i (+ i 1) 1 '()) (lp (+ i 1)))) (raise ValueError "list removal has no element to remove"))))) (define-method (pylist-remove! (o

) . l) (aif it (ref o 'remove) (apply it l) (next-method))) ;; SORT! (define (id x) x) (define-method (pylist-sort! (o ) . l) (apply (lambda* (#:key (key id) (reverse #f)) (let lp ((l (sort (map key (to-list o)) (if reverse > <))) (i 0)) (if (pair? l) (begin (pylist-set! o i (car l)) (lp (cdr l) (+ i 1)))))) l)) (define-method (pylist-sort! (o

) . l) (aif it (ref o 'sort) (apply it l) (next-method))) ;; INDEX (define-method (pylist-index (o ) val . l) (let* ((n (slot-ref o 'n )) (vec (slot-ref o 'vec)) (f (lambda (m) (if (< m 0) (+ m n) m)))) (call-with-values (lambda () (match l (() (values 0 n)) ((x) (values (f x) n)) ((x y) (values (f x) (f y))))) (lambda (n1 n2) (if (and (>= n1 0) (>= n2 0) (< n1 n) (<= n2 n)) (let lp ((i n1)) (if (< i n2) (let ((r (vector-ref vec i))) (if (equal? r val) i (lp (+ i 1)))) (raise ValueError "could not find value in index fkn"))) (raise IndexError "index out of scop in index fkn")))))) (define-method (pylist-index (o ) val . l) (let* ((n (string-length o)) (f (lambda (m) (if (< m 0) (+ m n) m))) (val (if (and (string? val) (> (string-length val) 0)) (string-ref val 0) val))) (call-with-values (lambda () (match l (() (values 0 n)) ((x) (values (f x) n)) ((x y) (values (f x) (f y))))) (lambda (n1 n2) (if (and (>= n1 0) (>= n2 0) (< n1 n) (<= n2 n)) (let lp ((i n1)) (if (< i n2) (let ((r (string-ref o i))) (if (equal? r val) i (lp (+ i 1)))) (raise ValueError "could not find value in index fkn"))) (raise IndexError "index out of scop in index fkn")))))) (defpair (pylist-index o val . l) (let* ((n (length o)) (f (lambda (m) (if (< m 0) (+ m n) m)))) (call-with-values (lambda () (match l (() (values 0 n)) ((x) (values (f x) n)) ((x y) (values (f x) (f y))))) (lambda (n1 n2) (if (and (>= n1 0) (>= n2 0) (< n1 n) (<= n2 n)) (let lp ((i o)) (if (pair? i) (let ((r (car i))) (if (equal? r val) i (lp (cdr i)))) (raise ValueError "could not find value in index fkn"))) (raise IndexError "index out of scop in index fkn")))))) (define-method (pylist-index (o

) . l) (aif it (ref o 'index) (apply it l) (next-method))) ;; len (defpair (len l) (length l)) (define-method (len x) (if (null? x) 0 (error "not a suitable lengthof" x))) (define-method (len (v )) (vector-length v)) (define-method (len (s )) (string-length s)) (define-method (len (o )) (slot-ref o 'n)) (define-method (len (o

)) (aif it (ref o '__len__) (it) (next-method))) (define (bo x) (if x #t #f)) (define-method (in x (l )) (bo (member x (slot-ref l 'l)))) (define-method (in x (l )) (bo (member x l))) (define-method (in x (l )) (define n (vector-length l)) (let lp ((i 0)) (if (< i n) (if (equal? x (vector-ref l i)) #t (lp (+ i 1))) #f))) (define-method (in (x ) (s )) (string-contains s x)) (define-method (in (x ) (s )) (let/ec ret (string-for-each (lambda (ch) (if (eq? ch x) (ret #t))) s)) #f) (define-method (in x (o )) (define l (slot-ref o 'vec)) (define n (slot-ref o 'n)) (let lp ((i 0)) (if (< i n) (if (equal? x (vector-ref l i)) #t (lp (+ i 1))) #f))) (define-method (in x (o

)) (aif it (ref o '__contains__) (it x) (next-method))) (define-syntax-rule (defgen (op r s o1 o2) code ...) (begin (define-method (op (o1 ) (o2 )) code ...) (define-method (op (o1 ) (o2 )) code ...) (define-method (op (o1 ) o2) (op (slot-ref o1 'l) o2)) (define-method (op o2 (o1 )) (op o2 (slot-ref o1 'l))) (define-method (op (o1 ) (o2 )) code ...) (define-method (op (o1

) o2) (aif it (ref o1 'r) (it o2) (next-method))) (define-method (op o1 (o2

)) (aif it (ref o2 's) (it o1) (next-method))))) (defgen (< __le__ __gt__ o1 o2) (let ((n1 (len o1)) (n2 (len o2))) (for ((x1 : o1) (x2 : o2)) () (if (< x1 x2) (break #t)) (if (> x1 x2) (break #f)) #:final (< n1 n2)))) (defgen (<= __lt__ __ge__ o1 o2) (let ((n1 (len o1)) (n2 (len o2))) (for ((x1 : o1) (x2 : o2)) () (if (< x1 x2) (break #t)) (if (> x1 x2) (break #f)) #:final (<= n1 n2)))) (defgen (> __ge__ __lt__ o1 o2) (let ((n1 (len o1)) (n2 (len o2))) (for ((x1 : o1) (x2 : o2)) () (if (> x1 x2) (break #t)) (if (< x1 x2) (break #f)) #:final (> n1 n2)))) (defgen (>= __gt__ __le__ o1 o2) (let ((n1 (len o1)) (n2 (len o2))) (for ((x1 : o1) (x2 : o2)) () (if (> x1 x2) (break #t)) (if (< x1 x2) (break #f)) #:final (>= n1 n2)))) (define-python-class list () (define __init__ (letrec ((__init__ (case-lambda ((self) (slot-set! self 'vec (make-vector 30)) (slot-set! self 'n 0)) ((self it) (__init__ self) (for ((i : it)) () (pylist-append! self i)))))) __init__))) (name-object list) (define pylist list) (define-method (py-class (o ) list)) (define (pylist-listing) (let ((l (to-pylist (map symbol->string '(append count extend index pop insert remove reverse sort __init__ __le__ __lt__ __gt__ __ge__ __ne__ __eq__ __len__ __init__ __add__ __mul__ __rmul__ __radd__ __repr__ __contains__ __getattr__ __setattr__ __delattr__ __delitem__ __setitem__ __iter__ ))))) (pylist-sort! l) l)) (define (py-all x) (for ((i : x)) () (if (not i) (break #f)) #:final #t)) (define (py-any . x) (for ((i : x)) () (if i (break #t)) #:final #f)) (define py-list list)