diff options
author | Stefan Israelsson Tampe <stefan.itampe@gmail.com> | 2017-09-16 21:03:41 +0200 |
---|---|---|
committer | Stefan Israelsson Tampe <stefan.itampe@gmail.com> | 2017-09-16 21:03:41 +0200 |
commit | 7fa0e1dd09693f84f9189e2231228b722f88e8f7 (patch) | |
tree | dc0001591f894d0f622aa46305c6e9b289c8dea8 /modules/language/python/list.scm | |
parent | 56d7b7b64eafd02f626826f9bf6e2dbe7c26d6ac (diff) |
initial list support
Diffstat (limited to 'modules/language/python/list.scm')
-rw-r--r-- | modules/language/python/list.scm | 110 |
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))))) + |