summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/language/python/dir.scm48
-rw-r--r--modules/language/python/module.scm123
-rw-r--r--modules/oop/pf-objects.scm80
3 files changed, 196 insertions, 55 deletions
diff --git a/modules/language/python/dir.scm b/modules/language/python/dir.scm
index da07642..e41e235 100644
--- a/modules/language/python/dir.scm
+++ b/modules/language/python/dir.scm
@@ -17,15 +17,15 @@
(define (chash-for-each f c)
(let ((h (slot-ref c 'h)))
- (if (is-a? c <pf>)
- (let ((hh (make-hash-table)))
- (vhash-fold
- (lambda (k v s)
- (when (not (hash-ref hh k))
- (hash-set! hh k #t)
- (f k v))
- s) #f h))
- (hash-for-each f h))))
+ (if (is-a? c <pf>)
+ (let ((hh (make-hash-table)))
+ (vhash-fold
+ (lambda (k v s)
+ (when (not (hash-ref hh k))
+ (hash-set! hh k #t)
+ (f k v))
+ s) #f h))
+ (hash-for-each f h))))
(define (get-from-class c f)
(let lp ((pl (ref c '__mro__)))
@@ -38,20 +38,22 @@
(if (not (pyclass? o))
(aif it (ref o '__dir__)
(it)
- (aif it (ref o '__dict__)
- (let ((l (pylist)))
- (for ((k v : it)) ()
- (pylist-append! l k))
- (pylist-sort! l)
- l)
- (let* ((h (make-hash-table))
- (c (ref o '__class__))
- (l '())
- (f (lambda (k v) (set! l (cons k l)))))
- (chash-for-each f o)
- (get-from-class c f)
- (hash-for-each (lambda (k v) (pylist-append! l k)) h)
- (to-pylist (map symbol->string (sort l <))))))
+ (begin
+ (let ((l1 (aif it (ref o '__dict__)
+ (let ((l (pylist)))
+ (for ((k v : it)) ()
+ (pylist-append! l k))
+ (pylist-sort! l)
+ l)
+ (pylist))))
+ (let* ((h (make-hash-table))
+ (c (ref o '__class__))
+ (l '())
+ (f (lambda (k v) (set! l (cons k l)))))
+ (chash-for-each f o)
+ (get-from-class c f)
+ (hash-for-each (lambda (k v) (pylist-append! l k)) h)
+ (+ (pylist (map symbol->string (sort l <))) l1)))))
(let* ((h (make-hash-table))
(c o)
(l '())
diff --git a/modules/language/python/module.scm b/modules/language/python/module.scm
new file mode 100644
index 0000000..615d163
--- /dev/null
+++ b/modules/language/python/module.scm
@@ -0,0 +1,123 @@
+(define-module (language python module)
+ #:use-module (oop pf-objects)
+ #:use-module (ice-9 match)
+ #:use-module (language python exceptions)
+ #:use-module (language python yield)
+ #:use-module (language python try)
+ #:use-module (language python dir)
+ #:export (Module))
+
+(define e (list 'e))
+
+(define _k
+ (lambda (k)
+ (if (string? k)
+ (string->symbol k)
+ k)))
+
+(define _m
+ (lambda (self)
+ (if (rawref self '_private)
+ (rawref self '_module)
+ (rawref self '_export))))
+
+(define-python-class Module ()
+ (define __setprivate__
+ (lambda (self p)
+ (set self '_isprivate p)))
+
+ (define __init__
+ (case-lambda
+ ((self pre l nm)
+ (match l
+ ((name)
+ (_make self (cons name pre) (cons name nm)))
+ ((name . (and l (name2 . _)))
+ (set self name2 (Module (cons name pre) l (cons name nm)))
+ (_make self (cons name pre) (cons name nm)))))
+
+ ((self l)
+ (if (pair? l)
+ (if (and (> (length l) 3)
+ (equal? (list (list-ref l 0)
+ (list-ref l 1)
+ (list-ref l 2))
+ '(language python module)))
+ (__init__ self (reverse '(language python module)) (cdddr l) '())
+ (_make self l l))
+ (__init__ self
+ (map string->symbol
+ (string-split l #\.)))))))
+ (define _make
+ (lambda (self l nm)
+ (begin
+ (set self '_private #f)
+ (set self '__dict__ self)
+ (set self '__name__ (string-join (map symbol->string (reverse nm)) "."))
+ (let ((_module (resolve-module (reverse l))))
+ (set self '_export (module-public-interface _module))
+ (set self '_module _module)))))
+
+ (define __getattribute__
+ (lambda (self k . l)
+ (define (fail)
+ (if (pair? l)
+ (car l)
+ (raise KeyError "getattr in Module")))
+ (if (rawref self '_module)
+ (let ((k (_k k))
+ (m (_m self)))
+ (let ((x (module-ref m k e)))
+ (if (eq? e x)
+ (fail)
+ x)))
+ (fail))))
+
+ (define __setattr__
+ (lambda (self k v)
+ (let ((k (_k k))
+ (fail (lambda () (raise KeyError "getattr in Module"))))
+ (if (rawref self k)
+ (fail)
+ (if (rawref self '_module)
+ (let ((m (_m self)))
+ (catch #t
+ (lambda ()
+ (if (module-defined? m k)
+ (module-set! m k v)
+ (module-define! m k v)))
+ (lambda x (pk 'fail x))))
+ (fail))))))
+
+ (define __delattr__
+ (lambda (self k)
+ (define (fail) (raise KeyError "getattr in Module"))
+ (if (rawref self '_module)
+ (let ((m (_m self))
+ (k (_k k)))
+ (if (module-defined? m k)
+ (module-remove! m k)
+ (raise KeyError "delattr of missing key in Module")))
+ (fail))))
+
+ (define __repr__
+ (lambda (self) (ref self '__name__)))
+
+ (define __getitem__
+ (lambda (self k)
+ (define k (if (string? k) (string->symbol k) k))
+ (__getattr__ self k)))
+
+ (define __iter__
+ (lambda (self)
+ (define m (_m self))
+ ((make-generator ()
+ (lambda (yield)
+ (define l '())
+ (define (f k v) (set! l (cons (list (symbol->string k) v) l)))
+ (module-for-each f m)
+ (let lp ((l l))
+ (if (pair? l)
+ (begin
+ (apply yield (car l))
+ (lp (cdr l)))))))))))
diff --git a/modules/oop/pf-objects.scm b/modules/oop/pf-objects.scm
index f80a2d2..5b78063 100644
--- a/modules/oop/pf-objects.scm
+++ b/modules/oop/pf-objects.scm
@@ -13,7 +13,7 @@
py-super-mac py-super py-equal?
*class* *self* pyobject? pytype?
type object pylist-set! pylist-ref tr
- resolve-method
+ resolve-method rawref
))
#|
@@ -153,7 +153,8 @@ explicitly tell it to not update etc.
(type- meta name parents dict keys))))
(define (create-object class meta goops x)
- (aif it #f ;(ref meta '__call__)
+ (with-fluids ((*make-class* #t))
+ (aif it #f ;(ref meta '__call__)
(apply it x)
(let ((obj (aif it (find-in-class class '__new__ #f)
((it class 'object))
@@ -166,7 +167,7 @@ explicitly tell it to not update etc.
(aif it (ref obj '__call__)
(apply it x)
(error "not a callable object"))))
- obj)))
+ obj))))
(define (make-object class meta goops)
(let ((obj (make-p goops)))
@@ -288,16 +289,20 @@ explicitly tell it to not update etc.
(if (eq? g #t)
(aif it (mrefx xx '__getattribute__ '())
(begin
- (set xx '__fget__ it)
+ (mset xx '__fget__ it it)
it)
(begin
- (set xx '__fget__ it)
+ (if (mc?)
+ (mset xx '__fget__ it it))
#f))
g)
#f)))
(if (or (not f) (eq? f not-implemented))
(mrefx xx key l)
- (apply f xx key l))))))
+ (catch #t
+ (lambda () ((f xx (fluid-ref *refkind*)) key))
+ (lambda x
+ (mrefx xx key l))))))))
(define-syntax-rule (mref x key l)
@@ -320,6 +325,10 @@ explicitly tell it to not update etc.
(define-method (ref (x <pyf>) key . l) (mref-py x key l))
(define-method (ref (x <py> ) key . l) (mref-py x key l))
+(define-method (rawref (x <pf> ) key . l) (mref x key l))
+(define-method (rawref (x <p> ) key . l) (mref x key l))
+
+
(define-method (set (f <procedure>) key val)
(set-procedure-property! f key val))
@@ -351,7 +360,7 @@ explicitly tell it to not update etc.
(values)))
;; on object x add a binding that key -> val
-(define-method (mset (x <pf>) key val)
+(define-method (mset (x <pf>) key rval val)
(let ((h (slot-ref x 'h))
(s (slot-ref x 'size))
(n (slot-ref x 'n)))
@@ -366,33 +375,39 @@ explicitly tell it to not update etc.
(define (pkh h) (hash-for-each (lambda x (pk x)) h) h)
-(define-method (mset (x <p>) key val)
+(define-method (mset (x <p>) key rval val)
(begin
(hash-set! (slot-ref x 'h) key val)
(values)))
-(define-syntax-rule (mset-py x key val)
- (let* ((v (mref x key (list fail))))
- (if (or (eq? v fail) (not (and (is-a? v <property>) (not (pyclass? x)))))
- (let* ((g (mrefx x '__fset__ '(#t)))
+(define *make-class* (make-fluid #f))
+(define (mc?) (not (fluid-ref *make-class*)))
+
+(define-syntax-rule (mset-py x key rval val)
+ (let* ((xx x)
+ (v (mref xx key (list fail))))
+ (if (or (eq? v fail)
+ (not (and (is-a? v <property>)
+ (not (pyclass? xx)))))
+ (let* ((g (mrefx xx '__fset__ '(#t)))
(f (if g
(if (eq? g #t)
- (let ((class (aif it (mref x '__class__ '())
- it
- x)))
- (aif it (mrefx x '__setattr__ '())
- (begin
- (mset class '__fset__ it)
- it)
- (begin
- (mset class '__fset__ it)
- #f)))
+ (aif it (mrefx xx '__setattr__ '())
+ (begin
+ (mset xx '__fset__ it it)
+ it)
+ (begin
+ (if (mc?)
+ (mset xx '__fset__ it it))
+ #f))
g)
#f)))
(if (or (eq? f not-implemented) (not f))
- (mset x key val)
- (f key val)))
- ((slot-ref v 'set) x val))))
+ (mset xx key val val)
+ (catch #t
+ (lambda () ((f xx (fluid-ref *refkind*)) key rval))
+ (lambda x (mset xx key val val)))))
+ ((slot-ref v 'set) xx val))))
(define-syntax-rule (mklam (mset a ...) val)
(if (and (procedure? val)
@@ -402,9 +417,9 @@ explicitly tell it to not update etc.
(ref val '__call__)
#t))
(if (procedure-property val 'py-special)
- (mset a ... val)
- (mset a ... (object-method val)))
- (mset a ... val)))
+ (mset a ... val val)
+ (mset a ... val (object-method val)))
+ (mset a ... val val)))
(define-method (set (x <pf>) key val) (mklam (mset x key) val))
(define-method (set (x <p>) key val) (mklam (mset x key) val))
@@ -489,12 +504,12 @@ explicitly tell it to not update etc.
;; x untouched
(define-method (fset (x <pf>) key val)
(let ((x (mcopy x)))
- (mset x key val)
+ (mset x key val val)
x))
(define-method (fset (x <p>) key val)
(let ((x (mcopy- x)))
- (mset x key val)
+ (mset x key val val)
x))
(define (fset-x obj l val)
@@ -702,8 +717,9 @@ explicitly tell it to not update etc.
(pylist-set! dict '__class__ meta)
(pylist-set! dict '__mro__ (get-mro parents))
dict)
-
- (create-class meta name parents gen-methods kw))
+
+ (with-fluids ((*make-class* #t))
+ (create-class meta name parents gen-methods kw)))
;; Let's make an object essentially just move a reference