initial list support
authorStefan Israelsson Tampe <stefan.itampe@gmail.com>
Sat, 16 Sep 2017 19:03:41 +0000 (21:03 +0200)
committerStefan Israelsson Tampe <stefan.itampe@gmail.com>
Sat, 16 Sep 2017 19:03:41 +0000 (21:03 +0200)
modules/language/python/compile.scm
modules/language/python/exceptions.scm
modules/language/python/for.scm
modules/language/python/list.scm

index 0919f1b2588951bcd05073922f59bd7c4a09b44a..332c22eb02846222562bf896458d2ed2b4a4fad9 100644 (file)
 (define-syntax-rule (<< x y) (ash x y))
 (define-syntax-rule (>> x y) (ash x (- y)))
 
+(define (fastfkn x)
+  (case x
+    ;; Lists
+    ((append)  (L 'pylist-apbpend!))
+    ((count)   (L 'pylist-count!))
+    ((extend)  (L 'pylist-extend!))
+    ((index)   (L 'pylist-index))
+    ((pop)     (L 'pylist-pop!))
+    ((insert)  (L 'pylist-insert!))
+    ((remove)  (L 'pylist-remove!))
+    ((reverse) (L 'pylist-reverse!))
+    ((sort)    (L 'pylist-sort!))
+    (else #f)))
+
 (define (make-set vs op x u)
   (define (tr-op op)
     (match op
                      `(,s/d ,v ,u))
                  (if op
                      `(,s/d ,(exp vs kind)
-                        (,(O 'fset-x) ,v (list ,@(map q addings))
-                         (,(tr-op op) (,(C 'ref-x) ,v ,@addings) ,u)))
+                            (,(O 'fset-x) ,v (list ,@(map q addings))
+                             (,(tr-op op) (,(C 'ref-x) ,v ,@addings) ,u)))
                      
                      `(,s/d ,(exp vs kind)
-                        (,(O 'fset-x) ,v (list ,@(map q addings)) ,u)))))
+                            (,(O 'fset-x) ,v (list ,@(map q addings)) ,u)))))
            
            (let ((v (string->symbol v)))
              (if (null? addings)
 
 (gen-table x vs
  (#:power
-  ((#:power _ (x) () . #f)
+  ((_ _ (x) () . #f)
    (exp vs x))
-  ((#:power _ x () . #f)
+  
+  ((_ _ x () . #f)
    (exp vs x))
-  ((#:power #f vf trailer . **)
+  
+  ((_ #f vf trailer . **)
    (let ()
      (define (pw x)
        (if **
           ((#f)          
            (list e))
           ((x . trailer)
-           (match (pr x)
+           (let ((is-fkn? (match trailer
+                            (((#:arglist . _) . _)
+                             #t)
+                            (_
+                             #f))))
+             (match (pr x)
                ((#:identifier . _)
-                (lp `(,(O 'refq) ,e ',(exp vs x) #f) trailer))
+                (let* ((tag     (exp vs x))
+                       (xs      (gensym "xs"))
+                       (is-fkn? (aif it (and is-fkn? (fastfkn tag))
+                                     `(lambda ,xs (apply ,it ,e ,xs))
+                                     #f)))
+                  (lp (if is-fkn?
+                          is-fkn?
+                          `(,(O 'refq) ,e ',tag #f))
+                      trailer)))
                
                ((#:arglist args apply  #f)
                 (if apply
                         trailer)
                     (lp `(,e ,@(map (g vs exp) args)) trailer)))
                
-               (_ (error "unhandled trailer"))))))))))
+               (_ (error "unhandled trailer")))))))))))
 
  (#:identifier
   ((#:identifier x . _)
   (#:global
    ((_ . _)
     '(values)))
-  
+
+  (#:list
+   ((_ . l)
+    (list (L 'to-pylist) (let lp ((l l))
+                           (match l
+                             (() ''())
+                             (((#:starexpr  #:power #f (#:list . l) . _) . _)
+                              (lp l))
+                             (((#:starexpr . l) . _)
+                              `(,(L 'to-list) ,(exp vs l)))
+                             ((x . l)
+                              `(cons ,(exp vs x) ,(lp l))))))))
+
   (#:lambdef
    ((_ v e)
     (list `lambda v (exp vs e))))
            obj)))))
                       
 (define-syntax ref-x
-  (syntax-rules ()
-    ((_ v)
-     v)
-    ((_ v x . l)
-     (ref-x (ref v 'x) . l))))
+  (lambda (x)
+    (syntax-case x ()
+      ((_ v)
+       #'v)
+      ((_ v x . l)
+       #'(ref-x (refq v 'x) . l)))))
 
index 954f3b34d5d61c9508537b145dc23b8bd804d64a..5b3b5ca8804f44cc76d8d2d8ad13bcf5580138a6 100644 (file)
@@ -2,14 +2,16 @@
   #:use-module (oop pf-objects)
   #:use-module (oop goops)
   #:export (StopIteration GeneratorExit RuntimeError
-                          Exception))
+                          Exception
+                          IndexError))
 
 (define-syntax-rule (aif it p x y) (let ((it p)) (if it x y)))
 
 (define StopIteration 'StopIteration)
 (define GeneratorExit 'GeneratorExit)
 (define RuntimeError  'RuntimeError)
-
+(define IndexError    'IndexError)
+  
 (define-python-class Exception ()
   (define __init__
     (case-lambda
index bb0afa4f9c07625bf0fa87fefe0e46b869eac7ea..fade3f2203db853ff9af8993310ce084c2d0908b 100644 (file)
@@ -4,7 +4,7 @@
   #:use-module (language python exceptions)
   #:use-module (oop goops)
   #:use-module (ice-9 control)
-  #:export (for break next write))
+  #:export (for break next))
 
 (define-syntax-rule (aif it p x y) (let ((it p)) (if it x y)))
 
index 64ff6e40568ab0ca3e7377bb810596a1d5e16f68..1935f027137f2de2f5afb5e62b4b52974824990a 100644 (file)
@@ -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
         (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)))))
+