(module roos-internal mzscheme
(require "c-roos.scm")
(require "spod-roos.scm")
(require (lib "list.ss" "mzlib"))
(define-syntax %error
(syntax-rules ()
((%error a1 ...)
(error (string-append "roos-internal.scm:" (format "~a" a1) ...)))))
(define (displayp . args)
(define (f l)
(if (null? l)
(newline)
(begin
(display (car l))
(f (cdr l)))))
(f args))
(define (%roos-raise . args)
(let ((msg (apply string-append args)))
(%error msg)
))
(define (%roos-invalid . args)
(%roos-raise "This object has been invalided"))
(define-syntax %roos-make-container
(syntax-rules ()
((_)
(make-hash-table))))
(define-syntax %roos-put-container
(syntax-rules ()
((_ C item value)
(hash-table-put! C item value))))
(define-syntax %roos-register-item
(syntax-rules ()
((_ L type item value)
(%roos-put-container L item (cons type value)))))
(define-syntax %roos-assoc
(syntax-rules ()
((%roos-assoc %m %members)
(hash-table-get %members %m (lambda () #f)))))
(define-syntax %roos-remove
(syntax-rules ()
((_ C item)
(hash-table-remove! C item))))
(define %roos-class-definitions (%roos-make-container))
(define %roos-class-symbols (%roos-make-container))
(define %roos-symbols-classes (%roos-make-container))
(define %roos-class-docs (make-hash-table))
(define %roos-class-supers (make-hash-table))
(define (roos-class-change from-sym from-class
to-sym to-class)
(%roos-put-container %roos-class-definitions to-class to-class)
(%roos-remove %roos-class-definitions from-class)
(%roos-put-container %roos-class-symbols to-class to-sym)
(%roos-remove %roos-class-symbols from-class)
(%roos-put-container %roos-symbols-classes to-sym to-class)
(%roos-remove %roos-symbols-classes from-sym)
(let ((current-doc (hash-table-get %roos-class-docs from-sym (lambda () (spod)))))
(hash-table-put! %roos-class-docs to-sym current-doc)
(hash-table-remove! %roos-class-docs from-sym))
(let ((current-supers (hash-table-get %roos-class-supers from-sym
(lambda () (lambda () '())))))
(hash-table-put! %roos-class-supers to-sym current-supers)
(hash-table-remove! %roos-class-supers from-sym))
)
(define (%roos-is-class? class)
(let ((c (%roos-assoc class %roos-class-definitions)))
(eq? c class)))
(define (%roos-get-supers class-sym)
(hash-table-get %roos-class-supers
class-sym
(lambda () (lambda () '()))))
(define-syntax %roos-get-class-symbol
(syntax-rules ()
((_ class)
(%roos-assoc class %roos-class-symbols))))
(define-syntax %roos-get-class-for-symbol
(syntax-rules ()
((_ class-sym)
(%roos-assoc class-sym %roos-symbols-classes))))
(define (%do-roos-register-class class classname)
(begin
(%roos-put-container %roos-class-definitions class class)
(%roos-put-container %roos-class-symbols class classname)
(%roos-put-container %roos-symbols-classes classname class)))
(define-syntax %roos-register-class
(syntax-rules ()
((_ class)
(%do-roos-register-class class 'class))))
(define-syntax %roos-register-class-name1
(syntax-rules ()
((_ (%name . %arguments1))
(%roos-register-class %name))
((_ (%name %arg1 . %arg2))
(%roos-register-class %name))
((_ (%name args ...))
(%roos-register-class %name))
((_ (%name))
(%roos-register-class %name))))
(define-syntax %roos-register-class-name
(syntax-rules ()
((_ %def)
(%roos-register-class-name1 %def))
((_ %def . %no)
(%roos-register-class-name1 %def))))
(define-syntax %roos-get-class-name1
(syntax-rules ()
((_ (%name . %arguments1)) '%name)
((_ (%name %arg1 . %arg2)) '%name)
((_ (%name args ...)) '%name)
((_ (%name)) '%name)))
(define-syntax %roos-get-class-name
(syntax-rules ()
((_ %def)
(%roos-get-class-name1 %def))
((_ %def . %no)
(%roos-get-class-name1 %def))))
(define-syntax %roos-get-class-def
(syntax-rules ()
((_ %def)
'%def)
((_ %def . %no)
'%def)))
(define-syntax %roos-get-constructor-doc
(syntax-rules ()
((_ (constructor d1 ...) body ...)
(spod d1 ...))
((_ constructor body ...)
(spod))
))
(define-syntax %roos-get-private-doc
(syntax-rules ()
((_ (private d1 ...))
(spod d1 ...))
((_ private)
(spod))
))
(define-syntax %roos-get-public-doc
(syntax-rules ()
((_ (public d1 ...))
(spod d1 ...))
((_ public)
(spod))
))
(define-syntax %roos-get-cleanup-doc
(lambda (x)
(syntax-case x (roos-doc)
((_ explicit-cleanup (roos-doc d1 ...) body ...)
(syntax (spod d1 ...)))
((_ explicit-cleanup body ...)
(syntax (spod))))
))
(define (%roos-add-doc-to-class name doc)
(let ((curdoc (hash-table-get %roos-class-docs
name (lambda () (spod)))))
(hash-table-put! %roos-class-docs
name (spod-merge curdoc doc))
))
(define (%roos-prepend-doc-to-class name doc)
(let ((curdoc (hash-table-get %roos-class-docs
name (lambda () (spod)))))
(hash-table-put! %roos-class-docs
name (spod-merge doc curdoc))
))
(define (%roos-get-class-derivatives myname)
(let ((ds (make-hash-table)))
(roos-map-classes (lambda (name cl)
(let ((sups (hash-table-get %roos-class-supers name
(lambda () (lambda () '())))))
(let ((sps (sups)))
(for-each (lambda (n)
(if (eq? n myname)
(hash-table-put! ds name name)))
sps)))))
(hash-table-map ds (lambda (key value) key))))
(define callno 0)
(define (%roos-register-class-doc name namedef def cleanup global-doc supers privates publics)
(define (get-supers supers)
(let ((S (make-hash-table)))
(define (find l)
(if (symbol? l)
(let ((c (%roos-get-class-for-symbol l)))
(if (not (eq? c #f))
(hash-table-put! S l l)))
(if (list? l)
(if (null? l)
#t
(begin
(find (car l))
(find (cdr l))))
#t)))
(find supers)
(let ((M (hash-table-map S (lambda (c0 c1) c0))))
M)))
(define (reg-supers name sups)
(hash-table-put! %roos-class-supers name sups))
(define (get-spod-supers name)
(let ((sups (hash-table-get %roos-class-supers name
(lambda () (lambda () '())))))
(spod-merge
(spod (class-supers (sups)))
(let ((derives (%roos-get-class-derivatives name)))
(spod (class-derived derives))))))
(let ((sups (lambda () (get-spod-supers name))))
(set! callno (+ callno 1))
(reg-supers name (lambda () (get-supers supers)))
(hash-table-put! %roos-class-docs
name
(spod namedef
global-doc
sups
def
cleanup
privates
publics))))
(define (%roos-find-member-in-supers %supers %get-mem)
(define (%find %supers)
(if (null? %supers)
'roos-not-found
(let ((%member (((cadar %supers) '%find-member) %get-mem)))
(if (eq? %member 'roos-not-found)
(%find (cdr %supers))
%member))))
(%find %supers))
(define %roos-find-member-in-proxies %roos-find-member-in-supers)
(define (%roos-propagate-this %supers %this)
(for-each
(lambda (%super)
(begin
(((cadr %super) '%propagate-this) %this)
(((cadr %super) '%set-this) %this)))
%supers))
(define (%roos-apply %mem . %args)
(let* ((%type (car %mem))
(%func-or-var (cdr %mem)))
(if (eq? %type 'private)
'roos-private
(cond
((procedure? %func-or-var)
(apply %func-or-var %args))
(else
'roos-unexpected)))))
(define-syntax %roos-def-internal
(syntax-rules ()
((_ (define (function . arguments1) body ...))
(define (function . arguments1) body ...))
((_ (define (function arguments1 . arguments2) body ...))
(define (function arguments1 . arguments2) body ...))
((_ (define (function arguments ...) body ...))
(define (function arguments ...) body ...))
((_ (define (function argument) body ...))
(define (function argument) body ...))
((_ (define variable argument))
(define variable argument))))
(define-syntax %roos-def
(syntax-rules ()
((_ ((define d1 ...) a1 ...))
(%roos-def-internal (define a1 ...)))
((_ (define a1 ...))
(%roos-def-internal (define a1 ...)))
))
(define-syntax %roos-def-doc-get-def
(syntax-rules ()
((_ (function) body ...) (list '(function)))
((_ (function . arguments) body ...) (list '(function . arguments)))
((_ (function arg1 . arg2) body ...) (list '(function arg1 . arg2)))
((_ (function arg1 ...) body ...) (list '(function arg1 ...)))
((_ (function arg1) body ...) (list '(function arg1)))
((_ variable value ) 'variable)
))
(define-syntax %roos-def-doc
(syntax-rules ()
((_ ((define (d1 ...)) a1 ...))
(let ((fdef (%roos-def-doc-get-def a1 ...)))
(if (list? fdef)
(spod (member-function (car fdef) (d1 ...)))
(spod (member-var fdef (d1 ...))))))
((_ ((define F) a1 ...))
(if (procedure? F)
(let ((fdef-doc (F 'a1 ...)))
(let ((fdef (car fdef-doc))
(doc (cadr fdef-doc)))
(if (list? fdef)
(spod (member-function (car fdef) doc))
(spod (member-var fdef doc)))))
(let ((fdef (%roos-def-doc-get-def a1 ...)))
(if (list? fdef)
(spod (member-function (car fdef) F))
(spod (member-var fdef F))))))
((_ ((define d1 ...) a1 ...))
(let ((fdef (%roos-def-doc-get-def a1 ...)))
(if (list? fdef)
(spod (member-function (car fdef) d1 ...))
(spod (member-var fdef d1 ...)))))
((_ (define a1 ...))
(spod))
))
(define-syntax %roos-body
(syntax-rules ()
((_)
(%roos-body #t))
((_ body ...)
(begin body ...))))
(define-syntax %roos-register
(syntax-rules ()
((%roos-register L type (define (function . arguments1) body ...))
(c-roos-add-member L type 'function function))
((%roos-register L type (define (function arguments1 . arguments2) body ...))
(c-roos-add-member L type 'function function))
((%roos-register L type (define (function arguments ...) body ...))
(c-roos-add-member L type 'function function))
((%roos-register L type (define (function argument) body ...))
(c-roos-add-member L type 'function function))
((%roos-register L type (define variable argument))
(c-roos-add-member L type 'variable (lambda args
(if (not (null? args))
(set! variable (car args)))
variable)))))
(define-syntax %roos-register-member
(syntax-rules ()
((_ a1 ...)
(c-roos-add-member a1 ...))))
(define-syntax %roos-define-class
(syntax-rules ()
((_ (%class-definition . %declarations) body)
(define %class-definition body))))
(define-syntax %roos-declarations
(syntax-rules ()
((_ (a) (body))
body)
((_ (a . (p1 ...)) . (body))
(let* (p1 ...)
body))))
(define-syntax %roos-class
(lambda (x)
(syntax-case x (roos-doc)
((%roos-class
((doc %spod1 ...)
(this %class-definition ...)
(supers %class-instance1 ...)
(%private %private-memberdef1 ...)
(%public %memberdef1 ...)
(%constructor %body ...)
(%explicit-cleanup %clbody ...)))
(syntax
(begin
(%roos-define-class (%class-definition ...)
(%roos-declarations (%class-definition ...)
(letrec ((*this
(let* ((this #f)
(supers #f)
(%cobj (c-roos-new (%roos-get-class-name %class-definition ...)
(lambda (t) (set! this t))
(list %class-instance1 ...))))
(define (roos-cleanup)
(let ((R (%roos-body %clbody ...)))
(c-roos-supers-for-each %cobj
(lambda (obj)
(-> obj roos-cleanup)))
(c-roos-invalidate %cobj)
R))
(define (roos-add-proxy proxy-obj)
(c-roos-add-proxy %cobj proxy-obj)
this)
(%roos-def %private-memberdef1)
...
(%roos-def %memberdef1)
...
(%roos-def (define (%construct) (%roos-body %body ...)))
(%roos-register-member %cobj 'public 'roos-cleanup roos-cleanup)
(%roos-register-member %cobj 'public 'roos-add-proxy roos-add-proxy)
(%roos-register %cobj 'private %private-memberdef1)
...
(%roos-register %cobj 'public %memberdef1)
...
(%roos-register %cobj 'public (define (%construct) (%roos-body %body ...)))
(set! supers (c-roos-new-super %cobj))
%cobj)))
(let ((%object *this))
(c-roos-set-this %object %object)
(c-roos-call-member %object '%construct)
%object)
)))
(%roos-register-class-name %class-definition ...)
(%roos-register-class-doc
(%roos-get-class-name %class-definition ...)
(spod (class-name (%roos-get-class-name %class-definition ...)))
(spod (class-def (%roos-get-class-def %class-definition ...)
(%roos-get-constructor-doc %constructor %body ...)))
(spod (class-cleanup (%roos-get-cleanup-doc %explicit-cleanup %clbody ...)))
(spod (class-doc %spod1 ...))
(list '%class-instance1 ...)
(spod (class-private (%roos-get-private-doc %private) (%roos-def-doc %private-memberdef1) ...))
(spod (class-public (%roos-get-public-doc %public) (%roos-def-doc %memberdef1) ...)))
))))))
(define-syntax def-class
(lambda (x)
(syntax-case x (roos-doc)
((_
(this %this ...)
(supers super1 ...)
(private private1 ...)
(public public1 ...)
(constructor c1 ...))
(syntax
(def-class
(roos-doc (spod))
(this %this ...)
(supers super1 ...)
(private private1 ...)
(public public1 ...)
(constructor c1 ...)
(explicit-cleanup #t))))
((_
(roos-doc %spod ...)
(this %this ...)
(supers super1 ...)
(private private1 ...)
(public public1 ...)
(constructor c1 ...))
(syntax
(def-class
(roos-doc %spod ...)
(this %this ...)
(supers super1 ...)
(private private1 ...)
(public public1 ...)
(constructor c1 ...)
(explicit-cleanup #t))))
((_
(this %this ...)
(supers super1 ...)
(private private1 ...)
(public public1 ...)
(constructor c1 ...)
(explicit-cleanup cln1 ...))
(syntax
(def-class
(roos-doc (spod))
(this %this ...)
(supers super1 ...)
(private private1 ...)
(public public1 ...)
(constructor c1 ...)
(explicit-cleanup cln1 ...))))
((_
(roos-doc %spod ...)
(this %this ...)
(supers super1 ...)
(private private1 ...)
(public public1 ...)
(constructor c1 ...)
(explicit-cleanup cln1 ...))
(syntax
(%roos-class
((roos-doc %spod ...)
(this %this ...)
(supers super1 ...)
(private private1 ...)
(public public1 ...)
(constructor c1 ...)
(explicit-cleanup cln1 ...)))))
)))
(define (class? obj)
(%roos-is-class? obj))
(define (class=? obj class)
(let ((s (if (class? class)
(%roos-get-class-symbol class)
(if (procedure? class)
'%roos-no-class-def
class))))
(c-roos-class-is obj s)))
(define (class obj)
(if (object? obj)
(c-roos-class obj)
#f))
(define (class-constructor obj)
(if (object? obj)
(let ((C (c-roos-class obj)))
(let ((class-sym (car C)))
(%roos-get-class-for-symbol class-sym)))
#f))
(define-syntax ->
(syntax-rules ()
((_ obj f)
(c-roos-call-member obj 'f))
((_ obj f a1 ...)
(c-roos-call-member obj 'f a1 ...))))
(define-syntax ->>
(syntax-rules ()
((_ obj f)
(c-roos-get-member obj 'f))))
(define (roos-dispatch obj f . args)
(apply (c-roos-get-member obj f) args))
(define-syntax %roos-generic-intern
(syntax-rules ()
((_ object f)
(-> object f))
((_ object f (a1 ...))
(-> object f a1 ...))))
(define-syntax def-generic
(syntax-rules ()
((_ generic-function)
(def-generic generic-function generic-function))
((_ generic-function object-function)
(define-syntax generic-function
(syntax-rules ()
((_ object)
(%roos-generic-intern object object-function))
((_ object . arguments)
(%roos-generic-intern object object-function arguments)))))))
(define (roos-cleanup obj)
(-> obj roos-cleanup))
(define-syntax -<
(syntax-rules ()
((-< obj)
(roos-cleanup obj))))
(define (roos-invalid? obj)
(not (c-roos-valid? obj)))
(define (roos-add-proxy obj obj-to-proxy-for)
(-> obj roos-add-proxy obj-to-proxy-for))
(define-syntax named-argument
(syntax-rules ()
((_ name arglist)
(named-argument name arglist #f))
((_ name arglist default-value)
(let ((a (memq name arglist)))
(if (eq? a #f)
default-value
(if (null? (cdr a))
'%roos-exists
(cadr a)))))))
(define-syntax =>
(syntax-rules ()
((_ a b)
(named-argument a b))
((_ a b c)
(named-argument a b c))))
(define (roos-version)
(string->number "1.9"))
(define (roos-class-doc class)
(let ((s (if (class? class)
(%roos-get-class-symbol class)
(if (procedure? class)
'%roos-no-class-def
class))))
(hash-table-get %roos-class-docs s (lambda () (list "")))))
(define (roos-class-name class)
(if (symbol? class)
class
(%roos-get-class-symbol class)))
(define (roos-map-classes proc)
(hash-table-map %roos-symbols-classes (lambda (sym class) (proc sym class))))
(define (roos-class-hierarchy . class-filter)
(define (find-depth clh name)
(let ((supers (hash-table-get clh name)))
(if (null? supers)
0
(apply max (map (lambda (sup)
(+ 1 (find-depth clh sup)))
supers)))))
(define (create-class-tree class cldh)
(list class (map (lambda (cl)
(create-class-tree cl cldh))
(hash-table-get cldh class (lambda () '())))))
(let ((classes (if (null? class-filter)
(roos-map-classes (lambda (name cl) cl))
(let ((f (car class-filter)))
(filter (lambda (e) e)
(roos-map-classes (lambda (name cl)
(if (f name cl)
cl
#f)))))))
(clh (make-hash-table)))
(for-each (lambda (cl)
(let* ((name (roos-class-name cl))
(supers ((%roos-get-supers name))))
(hash-table-put! clh name supers)))
classes)
(let ((max-depth 0)
(cll (make-hash-table)))
(hash-table-for-each clh
(lambda (name cl)
(let ((d (find-depth clh name)))
(hash-table-put! cll name d)
(set! max-depth (max d max-depth)))))
(let ((zero-level-classes (map (lambda (dcl) (car dcl))
(filter (lambda (depth-name)
(= (cadr depth-name) 0))
(hash-table-map cll (lambda (name depth)
(list name depth))))
))
(cldh (make-hash-table)))
(hash-table-for-each clh
(lambda (name sups)
(for-each (lambda (super)
(let ((derivs (hash-table-get cldh super (lambda () '()))))
(hash-table-put! cldh super (cons name derivs))))
sups)))
(map (lambda (class)
(create-class-tree class cldh))
zero-level-classes)
))))
(define (roos-class-hierarchy->spod hierarchy . name)
(define (sort-classes L)
(define (get-sym e)
(if (symbol? e)
(symbol->string e)
(if (list? e)
(if (null? e)
""
(get-sym (car e))))))
(quicksort L (lambda (e1 e2)
(string-ci<? (get-sym e1) (get-sym e2)))))
(define (make-hierarchy cl-h indent)
(if (null? cl-h)
(spod)
(let ((cl (car cl-h)))
(if (symbol? cl)
(spod (s\\ (s%% (make-string (* indent 3) #\ )) (slink cl cl))
(make-hierarchy (cdr cl-h) (+ indent 1)))
(if (list? cl)
(map (lambda (cl)
(make-hierarchy cl indent))
(sort-classes cl-h))
(%error "UNEXPECTED?" cl))))))
(apply
->spod
(cons
(spod-merge (spod (s= "Class hierarchy"))
(map (lambda (h)
(spod-nlnl h))
(make-hierarchy hierarchy 0)))
name)))
(define (roos->spod info class . see-also)
(let ((name (roos-class-name class))
(doc (roos-class-doc class)))
(let ((fulldoc (spod (ssyn 'scm 8)
doc
(if (null? see-also) (spod-empty) (car see-also))
info)))
(->spod fulldoc name))))
(define (roos-classes->spod class-filter hierarchy-name info . _see-also)
(let ((classes (filter (lambda (cl) cl)
(roos-map-classes class-filter)))
(see-also (spod-merge (spod (s= "See also")
(spod-nlnl
(let ((comma ""))
(map
(lambda (link)
(let ((R (spod-merge (spod comma)
(if (list? link)
(if (> (length link) 1)
(spod (slink (car link) (cadr link)))
(if (null? link)
(spod)
(spod (slink (car link)))))
(spod (slink link))))))
(set! comma ",")
R))
(cons hierarchy-name _see-also))))))))
(for-each (lambda (class)
(roos->spod info class see-also))
classes)
(roos-class-hierarchy->spod (roos-class-hierarchy class-filter) hierarchy-name)))
(define (roos-add-doc %class %spod)
(let ((name (roos-class-name %class)))
(%roos-add-doc-to-class name %spod)))
(define (roos-prepend-doc %class %spod)
(let ((name (roos-class-name %class)))
(%roos-prepend-doc-to-class name %spod)))
(provide def-class
def-generic
class?
object?
class=?
class
class-constructor
->
->>
roos-cleanup
-<
roos-invalid?
=>
named-argument
roos-add-proxy
roos-version
roos-id
roos-dispatch
roos-class-doc
roos-class-name
roos-add-doc
roos-prepend-doc
roos-map-classes
roos->spod
roos-class-change
roos-class-hierarchy
roos-class-hierarchy->spod
roos-classes->spod
(all-from "spod-roos.scm")
c-roos-kind
c-roos-available?
)
)