summaryrefslogtreecommitdiff
path: root/modules/language/python/list.scm
diff options
context:
space:
mode:
Diffstat (limited to 'modules/language/python/list.scm')
-rw-r--r--modules/language/python/list.scm110
1 files changed, 109 insertions, 1 deletions
diff --git a/modules/language/python/list.scm b/modules/language/python/list.scm
index 64ff6e4..1935f02 100644
--- a/modules/language/python/list.scm
+++ b/modules/language/python/list.scm
@@ -1,11 +1,13 @@
(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 exceptions)
- #:export (to-list))
+ #:export (to-list pylist-ref pylist-set! pylist-append!))
+(define-syntax-rule (aif it p x y) (let ((it p)) (if it x y)))
(define-method (to-list x)
(if (vector? x)
@@ -15,6 +17,7 @@
(define-method (to-list (x <p>))
((ref x '__tolist__ (lambda () (error "missing __tolist__ in object")))))
+
(define-method (to-list (x <yield>))
(define l '())
(catch StopIteration
@@ -24,3 +27,108 @@
(lp)))
(lambda x
(reverse l))))
+
+(define-class <py-list> () vec n)
+
+(define-method (to-pylist (l <pair>))
+ (let* ((n (length l))
+ (vec (make-vector (* 2 n)))
+ (o (make <py-list>)))
+
+ (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))
+
+
+;;; REF
+(define-method (pylist-ref (o <py-list>) n)
+ (if (< n (slot-ref o 'n))
+ (vector-ref (slot-ref o 'vec) n)
+ (raise IndexError)))
+
+(define-method (pylist-ref (o <pair>) n)
+ (list-ref o n))
+
+(define-method (pylist-ref (o <vector>) n)
+ (vector-ref o n))
+
+(define-method (pylist-ref (o <p>) n)
+ ((ref o '__listref__) n))
+
+;;; SET
+(define-method (pylist-set! (o <py-list>) n val)
+ (if (< n (slot-ref o 'n))
+ (vector-set! (slot-ref o 'vec) n val)
+ (raise IndexError)))
+
+(define-method (pylist-set! (o <pair>) n val)
+ (list-set! o n val))
+
+(define-method (pylist-set! (o <vector>) n val)
+ (vector-set! o n val))
+
+(define-method (pylist-set! (o <p>) n val)
+ ((ref o '__listset__) n val))
+
+;;APPEND
+(define-method (pylist-append! (o <py-list>) n 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))))
+
+(define-method (pylist-append! o n)
+ (raise 'NotSupportedOP '__append__))
+
+(define-method (pylist-append! (o <p>) n . l)
+ (aif it (ref o '__append__)
+ (it n)
+ (aif it (ref o 'append)
+ (apply it n l)
+ (error "no append"))))
+
+
+(define-method (to-list (x <py-list>))
+ (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 (write (o <py-list>) . 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 <py-list>) . 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)))))
+