decorators works
authorStefan Israelsson Tampe <stefan.itampe@gmail.com>
Tue, 3 Oct 2017 19:44:56 +0000 (21:44 +0200)
committerStefan Israelsson Tampe <stefan.itampe@gmail.com>
Tue, 3 Oct 2017 19:44:56 +0000 (21:44 +0200)
modules/language/python/compile.scm
modules/language/python/list.scm
modules/language/python/number.scm
modules/language/python/set.scm
modules/oop/pf-objects.scm

index 5d9828bd1b33ba11e38d763714b7ff636957ef0f..275c635575196955f9a0824d06f7dbe81c7389ec 100644 (file)
                  ,(if op
                       `(,(tr-op op) (,(C 'ref-x) ,v ,@addings) ,u)
                       u))))))))
-  
+
+(define (filter-defs x)
+  (match (let lp ((x x))
+           (match x
+             ((('begin . l))
+              (lp (cons 'begin l)))
+             (('begin . l)
+              (let lp ((l l))
+                (match l
+                  ((('values) . l)
+                   (lp l))
+                  ((x . l)
+                   (cons x (lp l)))
+                  (x x))))))
+    (('begin)
+     '())
+    (x x)))
+                  
 (define is-class? (make-fluid #f))
 (define (gen-yargs vs x)
   (match (pr 'yarg x)    ((#:list args)
      (map (g vs exp) args))))
 
 (define inhibit-finally #f)
-
+(define decorations (make-fluid '()))
 (define tagis (make-hash-table))
 (define-syntax-rule (gen-table x vs (tag code ...) ...)
   (begin
   ((#:identifier x . _)
    (string->symbol x)))
 
+ (#:decorated
+  ((_ (l ...))
+   (fluid-set! decorations (map (g vs exp) l))
+   '(values)))
  (#:string
   ((#:string #f x)
    x))
                         ('fast #t)
                         (_ #f))))
                 #f l))
-        
          
-        (let* ((class   (string->symbol class))
+        (let* ((decor   (let ((r (fluid-ref decorations)))
+                          (fluid-set! decorations '())
+                          r))
+               (class   (string->symbol class))
                (parents (match parents
                           (()
                            '())
                                 'mk-p-class
                                 'mk-py-class)))              
                (parents (filt parents)))
-          `(define ,class (,(O kind) 
-                           ,class
-                           ,(map (lambda (x) `(,(O 'get-class) ,x)) parents)
-                           #:const
-                           ()
-                           #:dynamic
-                           ,(match (exp vs defs)
-                              (('begin . l)
-                               l)
-                              ((('begin . l))
-                               l)
-                              (l l)))))))))
+          `(define ,class
+             (,(C 'class-decor) ,decor
+              (,(O kind) 
+               ,class
+               ,(map (lambda (x) `(,(O 'get-class) ,x)) parents)
+               #:const
+               ()
+               #:dynamic
+               ,(match (filter-defs (exp vs defs))
+                  (('begin . l)
+                   l)
+                  ((('begin . l))
+                   l)
+                  (l l))))))))))
 
  (#:scm
   ((_ (#:string _ s)) (with-input-from-string s read)))
        *e **e)
       #f
       code)
-   (let* ((args (get-kwarg-def vs args))
+   (let* ((decor   (let ((r (fluid-ref decorations)))
+                          (fluid-set! decorations '())
+                          r))
+          (args (get-kwarg-def vs args))
           (c?   (fluid-ref is-class?))
           (f    (exp vs f))
           (y?   (is-yield f #f code))
        (if c?
            (if y?
                `(define ,f
-                  (,(C 'def-wrap) ,y? ,f ,ab
+                  (,(C 'def-decor) ,decor
+                   (,(C 'def-wrap) ,y? ,f ,ab
+                    (,(D 'lam) (,@args ,@*f ,@**f)
+                     (,(C 'with-return) ,r
+                      ,(mk `(let ,(map (lambda (x) (list x #f)) ls)
+                              ,(with-fluids ((return r))
+                                 (exp ns code)))))))))
+               
+               `(define ,f
+                  (,(C 'def-decor) ,decor
                    (,(D 'lam) (,@args ,@*f ,@**f)
                     (,(C 'with-return) ,r
                      ,(mk `(let ,(map (lambda (x) (list x #f)) ls)
                              ,(with-fluids ((return r))
-                                (exp ns code))))))))
-               
-               `(define ,f (,(D 'lam) (,@args ,@*f ,@**f)
-                            (,(C 'with-return) ,r
-                             ,(mk `(let ,(map (lambda (x) (list x #f)) ls)
-                                     ,(with-fluids ((return r))
-                                        (exp ns code))))))))
+                                (exp ns code)))))))))
             
            (if y?
                `(define ,f
-                  (,(C 'def-wrap) ,y? ,f ,ab
+                  (,(C 'def-decor) ,decor
+                   (,(C 'def-wrap) ,y? ,f ,ab
+                    (,(D 'lam) (,@args ,@*f ,@**f)
+                     (,(C 'with-return) ,r
+                      (let ,(map (lambda (x) (list x #f)) ls)
+                        ,(with-fluids ((return r))
+                           (mk
+                            (exp ns code)))))))))
+               `(define ,f
+                  (,(C 'def-decor) ,decor
                    (,(D 'lam) (,@args ,@*f ,@**f)
                     (,(C 'with-return) ,r
                      (let ,(map (lambda (x) (list x #f)) ls)
                        ,(with-fluids ((return r))
-                          (mk
-                           (exp ns code))))))))
-               `(define ,f
-                  (,(D 'lam) (,@args ,@*f ,@**f)
-                   (,(C 'with-return) ,r
-                    (let ,(map (lambda (x) (list x #f)) ls)
-                      ,(with-fluids ((return r))
-                         (exp ns code))))))))))))
+                          (exp ns code)))))))))))))
  
  (#:global
   ((_ . _)
     ((_ v (#:fast-id f _) . l)
      (ref-x (f v) . l))
     ((_ v (#:identifier x) . l)
-     (ref-x (refq v 'x) . l))
+     (ref-x (refq v x) . l))
     ((_ v (#:identifier x) . l)
-     (ref-x (refq v 'x) . l))
+     (ref-x (refq v x) . l))
     ((_ v (#:call-obj x) . l)
      (ref-x (x v) . l))
     ((_ v (#:call x ...) . l)
     ((_ v (#:vecsub x ...) val)
      (pylist-subset! v x ... val))))
 
+
+(define-syntax class-decor
+  (syntax-rules ()
+    ((_ () x) x)
+    ((_ (f ... r) y)
+     (class-decor (f ...) (r y)))))
+
+(define-syntax def-decor
+  (syntax-rules ()
+    ((_ () x) x)
+    ((_ (f ... r) y)
+     (def-decor (f ...) (r y)))))
+
+        
index 1afa56f18e0c424f8dbccc4262aa83d560e2fbcd..7f0d7e43636580ca7470ba909cd1c76c623b045a 100644 (file)
@@ -8,13 +8,14 @@
   #:use-module (language python for)
   #:use-module (language python try)
   #:use-module (language python exceptions)
-  #:export (to-list to-pylist <py-list>
+  #:export (to-list to-pylist <py-list> 
             pylist-ref pylist-set! 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))
+            pylist pylist-listing
+            py-all py-any))
 
 (define scm-list list)
 
     
     (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))
+           
+
+        
index f2c0c6bc779f2952aa149fa2912658c5ec8a37b1..56a50cf6f3d1169b14855fa72f3adcee6ed2c03c 100644 (file)
@@ -6,12 +6,12 @@
   #:use-module (language python try)
   #:use-module (language python exceptions)
   #:export (py-int py-float py-complex
-                   py-/ py-logand py-logior py-logxor py-abs
-                   py-lshift py-rshift py-mod py-floordiv
+                   py-/ py-logand py-logior py-logxor py-abs py-trunc
+                   py-lshift py-rshift py-mod py-floordiv py-round
                    <py-int> <py-float> <py-complex>
                    py-divmod pyfloat-listing pyint-listing pycomplex-listing
                    py-as-integer-ratio py-conjugate py-fromhex py-hex py-imag
-                   py-is-integer py-real hex))
+                   py-is-integer py-real hex py-bin))
 
 (define-syntax-rule (aif it p x y) (let ((it p)) (if it x y)))
 
 (mk-biop2 i0 py-rmod py-mod __mod__ __rmod__)
 
 
-(define-method (py-abs (o <number>)) (abs o))
 (define-method (py-floor (o1 <integer>)) o1)
 (define-method (py-floor (o1 <number> )) )
-(define-method (py-float (o1 <integer>)) (exact->inexact o1))
-(define-method (py-float (o1 <number> )) o1)
+(define-method (py-trunc (o1 <integer>)) (exact->inexact o1))
+(define-method (py-trunc (o1 <number> )) o1)
 
 (define-syntax-rule (u0 f)
   (begin
 
 (u0 py-hash )
 (mk-unop u0 -         __neg__   )
-(mk-unop u0 py-abs    __abs__   )
-(mk-unop u0 py-floor  __floor__ )
+(mk-unop u0 py-trunc  __trunc__ )
 (mk-unop i0 py-lognot __invert__)
 
 (define-method (py-bit-length (i <integer>))
 (define-method (hex (o <integer>))
   (+ "0x" (number->string o 16)))
 
+(define-method (py-abs (o <complex>))
+  (magnitude o))
+(define-method (py-abs (o <number>))
+  (abs o))
+
+(mk-unop u0 py-abs       __abs__)
 (mk-unop u0 py-conjugate conjugate)
 (mk-unop u0 py-imag imag)
 (mk-unop u0 py-real real)
                          conjugate imag real)))))
     (pylist-sort! l)
     l))
+
+(define* (py-round x #:optional (digits 0))
+  (let* ((f (expt 1.0 digits))
+         (a (if (< x 0) -0.5 0.5))
+         (x (py-trunc (+ a (* x f)))))
+    (/ x f)))
+         
+(define-method (py-bin (o <integer>))
+  (number->string o 2))
+(define-method (py-bin (o <py-int>))
+  (number->string (slot-ref o 'x) 2))
+(define-method (py-bin (o <p>))
+  (let ((r (ref o '__index__)))
+    (number->string (r) 2)
+    (raise TypeError "object cannot be interpretted as an index")))
+
+  
index 3164c8f00a1fb2ad4c471399a30471b34b918e93..cd1258697e6e682270c785eae4cd8574432175d6 100644 (file)
@@ -7,7 +7,7 @@
   #:use-module (language python try)
   #:use-module (language python list)
   #:use-module (language python yield)
-  #:export(set))
+  #:export(py-set))
 
 (define-class <set> () dict)
 
           (for ((k v : (slot-ref self 'dict))) ()
                (yield k)
                (values))))))
+
+(define py-set set)
index 5937d37d91a929e5bbec2dd6127ab2d44be5ce0a..d916fe88123780bdacf5dfcc0972001fb4c837f6 100644 (file)
@@ -10,6 +10,7 @@
                 def-pyf-class mk-pyf-class make-pyf-class
                 def-py-class  mk-py-class  make-py-class
                 define-python-class get-type py-class
+                object-method class-method static-method
                 ))
 #|
 Python object system is basically syntactic suger otop of a hashmap and one
@@ -178,8 +179,7 @@ explicitly tell it to not update etc.
     (let ((xx x))
       (let ((res (mrefx- xx key l)))
         (if (and (not (struct? res)) (procedure? res))
-            (lambda z
-              (apply res xx z))
+            (res xx)
             res)))))
 
 (unx mrefx-    mref-)
@@ -194,8 +194,7 @@ explicitly tell it to not update etc.
         (if (and (not (struct? res))
                  (not (pyclass? res))
                  (procedure? res))
-            (lambda z
-              (apply res xx z))
+            (res xx)
             res)))))
 
 (unx mrefx-    mref-q)
@@ -291,6 +290,13 @@ explicitly tell it to not update etc.
         (mset- x key val)
         (f key val))))
 
+(define-syntax-rule (mklam (mset a ...) val)
+  (if (procedure? val)
+      (if (procedure-property val 'py-special)
+          (mset a ... val)
+          (mset a ... (object-method val)))
+      (mset a ... val)))
+
 (define-method (set (x <pf>)  key val) (mset     x key val))
 (define-method (set (x <p>)   key val) (mset-    x key val))
 (define-method (set (x <pyf>) key val) (mset-py  x key val))
@@ -647,3 +653,27 @@ explicitly tell it to not update etc.
 
 (define-method (py-class (o <p>))
   (ref o '__class__ 'type))
+
+(define (mark-fkn f)
+  (set-procedure-property! f 'py-special #t)
+  f)
+
+(define (object-method f)
+  (mark-fkn
+   (lambda (x)
+     (if (pyclass? x)
+         f
+         (lambda z (apply f x z))))))
+
+(define (class-method f)
+  (mark-fkn
+   (lambda (x)
+     (if (pyclass? x)
+         (lambda z (apply f x z))
+         (lambda z (apply f (ref x '__class__) z))))))
+
+(define (static-method f)
+  (mark-fkn
+   (lambda (x) f)))
+
+