slice set and improvements
authorStefan Israelsson Tampe <stefan.itampe@gmail.com>
Mon, 18 Sep 2017 16:12:25 +0000 (18:12 +0200)
committerStefan Israelsson Tampe <stefan.itampe@gmail.com>
Mon, 18 Sep 2017 16:12:25 +0000 (18:12 +0200)
modules/language/python/compile.scm
modules/language/python/list.scm

index 4aa67ec4b736951e01757bac3969723396a23ee2..46a9199611e09d90084a2d65ec57be5efd3ec10b 100644 (file)
     ((sort)    (L 'pylist-sort!))
     (else #f)))
 
+(define (get-addings vs x)
+  (match x
+    (() '())
+    ((x . l)
+     (let ((is-fkn? (match l
+                      (((#:arglist . _) . _)
+                       #t)
+                      (_
+                       #f))))
+       
+       (cons
+        (match x
+          ((#:identifier . _)
+           (let* ((tag     (exp vs x))
+                  (xs      (gensym "xs"))
+                  (is-fkn? (aif it (and is-fkn? (fastfkn tag))
+                                `(#:call-obj (lambda (e)
+                                               `(lambda ,xs
+                                                  (apply ,it ,e ,xs))))
+                                #f)))
+             (if is-fkn?
+                 is-fkn?
+                 `(#:identifier ',tag))))
+          
+          ((#:arglist args apply  #f)
+           (if apply
+               `(#:apply ,@(map (g vs exp) args)
+                         ,`(,(L 'to-list) ,(exp vs apply)))
+               `(#:call  ,@(map (g vs exp) args))))
+        
+          ((#:subscripts (n #f #f))
+           `(#:vecref ,(exp vs n)))
+        
+          ((#:subscripts (n1 n2 n3))
+           (let ((w (lambda (x) (if (eq? x 'None) ''None x))))
+             `(#:vecsub            
+               ,(w (exp vs n1)) ,(w (exp vs n2)) ,(w (exp vs n3)))))
+        
+          ((#:subscripts (n #f #f) ...)
+           `(#:array-ref ,@ (map (lambda (n)
+                                   (exp vs n))
+                                 n)))
+        
+          ((#:subscripts (n1 n2 n3) ...)
+           (let ((w (lambda (x) (if (eq? x 'None) ''None x))))
+             `(#:arraysub
+               ,@(map (lambda (x y z)
+                        `(,(exp vs x) ,(exp vs y) ,(exp vs z)))
+                      n1 n2 n3))))
+        
+          (_ (error "unhandled addings")))
+        (get-addings vs l))))))
+  
+
 (define (make-set vs op x u)
   (define (tr-op op)
     (match op
   
   (match x
     ((#:test (#:power kind (#:identifier v . _) addings . _) . _)
-     (let ((addings (map (lambda (x) (exp vs x)) addings)))
+     (let ((addings (get-addings vs addings)))
        (define q (lambda (x) `',x))
        (if kind
            (let ((v (string->symbol v)))
                  (if op
                      `(,s/d ,v (,(tr-op op) (,(C 'ref-x) ,v ,@addings) ,u))
                      `(,s/d ,v ,u))
-                 (let* ((rev (reverse addings))
-                        (las (car rev))
-                        (new (reverse (cdr rev))))
-                   `(,(O 'set) ,(let lp ((v v) (new new))
-                                  (match new
-                                    ((x . new)
-                                     (lp `(,(O 'refq) ,v 'x) ',new))
-                                    (() v)))
-                     ',(exp vs las)
-                     ,(if op
-                          `(,(tr-op op) (,(C 'ref-x) ,v ,@addings) ,u)
-                          u))))))))))
+                 `(,(C 'set-x)
+                   ,v
+                   ,addings
+                   ,(if op
+                        `(,(tr-op op) (,(C 'ref-x) ,v ,@addings) ,u)
+                        u)))))))))
   
 (define is-class? (make-fluid #f))
 (define (gen-yargs vs x)
   ((_ x)
    (list 'lognot (exp vs x))))
 
+ (#:u-
+  ((_ x)
+   (list '- (exp vs x))))
+
+ (#:u+
+  ((_ x)
+   (list '+ (exp vs x))))
+
  (#:band
   ((_ . l)
    (cons 'logand (map (g vs exp) l))))
   (#:list
    ((_ . l)
     (list (L 'to-pylist) (let lp ((l l))
-                           (match l
-                             (() ''())
+                           (match l                             
+                             ((or () #f) ''())                            
                              (((#:starexpr  #:power #f (#:list . l) . _) . _)
                               (lp l))
                              (((#:starexpr  #:power #f (#:tuple . l) . _) . _)
            obj)))))
                       
 (define-syntax ref-x
-  (lambda (x)
-    (syntax-case x ()
-      ((_ v)
-       #'v)
-      ((_ v x . l)
-       #'(ref-x (refq v 'x) . l)))))
+  (syntax-rules ()
+    ((_ v)
+     v)
+    ((_ v (#:identifier x) . l)
+     (ref-x (refq v 'x) . l))
+    ((_ v (#:identifier x) . l)
+     (ref-x (refq v 'x) . l))
+    ((_ v (#:call-obj x) . l)
+     (ref-x (x v) . l))
+    ((_ v (#:call x ...) . l)
+     (ref-x (v x ...) . l))
+    ((_ v (#:apply x ...) . l)
+     (ref-x (apply v x ...) . l))
+    ((_ v (#:apply x ...) . l)
+     (ref-x (apply v x ...) . l))
+    ((_ v (#:vecref x) . l)
+     (ref-x (pylist-ref v x) . l))
+    ((_ v (#:vecsub . x) . l)
+     (ref-x (pylist-slice v . x) . l))))
+
+(define-syntax set-x
+  (syntax-rules ()
+    ((_ v (a ... b) val)
+     (set-x-2 (ref-x v a ...) b val))))
+
+(define-syntax set-x-2
+  (syntax-rules ()
+    ((_ v (#:identifier x) val)
+     (set v 'x val)) 
+    ((_ v (#:vecref n) val)
+     (pylist-set! v n val))
+    ((_ v (#:vecsub x ...) val)
+     (pylist-subset! v x ... val))))
 
index b8f1860c0aad2326b6a9312ef825499bddca02f6..8b25077fa682f22c99324a86af8d2e7c45993862 100644 (file)
@@ -7,7 +7,7 @@
   #:use-module (language python try)
   #:use-module (language python exceptions)
   #:export (to-list pylist-ref pylist-set! pylist-append!
-                    pylist-slice))
+                    pylist-slice pylist-subset!))
 
 (define-syntax-rule (aif it p x y) (let ((it p)) (if it x y)))
 
@@ -32,6 +32,9 @@
 
 (define-class <py-list> () vec n)
 
+(define-method (to-pylist (l <py-list>))
+  l)
+
 (define-method (to-pylist (l <pair>))
   (let* ((n   (length l))
          (vec (make-vector (* 2 n)))
         (slot-set! o 'n   0)
         o)
       (error "not able to make a pylist")))
-  
+
 ;;; REF
-(define-method (pylist-ref (o <py-list>) n)
-  (if (< n (slot-ref o 'n))
+(define-method (pylist-ref (o <py-list>) 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 <pair>) n)
+  (define n (if (< n 0) (+ (length o) n)))
   (list-ref o n))
 
 (define-method (pylist-ref (o <vector>) n)
   ((ref o '__listref__) n))
 
 ;;; SET
-(define-method (pylist-set! (o <py-list>) n val)
-  (if (< n (slot-ref o 'n))
+(define-method (pylist-set! (o <py-list>) 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)))
 
 
 ;;SLICE
 (define-method (pylist-slice (o <py-list>) n1 n2 n3)
-  (let* ((n1   (if (eq? n1 'None) 0                n1))
-         (n2   (if (eq? n2 'None) (slot-ref o 'n)  n2))
-         (n3   (if (eq? n3 'None) 1                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))
 (define-method (pylist-slice o n1 n2 n3)
   (pylist-slice (to-pylist o) n1 n2 n3))
 
+;;SUBSET
+(define-method (pylist-subset! (o <py-list>) 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 <py-list>) val)
   (let* ((n   (slot-ref o 'n))