;; company.stk -- Company & employee example ;; useful utility function for resetting the object store (define (new . argv) (begin (apply run-process *program-name* :wait #t argv) (bye))) (load "ap") ;; define the class graph (define-class () ((depts :accessor depts :init-keyword :depts))) (define-class () ((name :accessor name :init-keyword :name) (emps :accessor emps :init-keyword :emps))) (define-class () ;; abstract ((salary :accessor salary :init-keyword :salary))) (define-class () ()) (define-class () ((hours :accessor hours :init-keyword :hours))) ;; define an object graph (define the-company (make :depts (list (make :name "marketing" :emps (list (make :salary 60000) (make :salary 90000) (make :salary 70000 :hours 20))) (make :name "sales" :emps (list (make :salary 70000) (make :salary 60000 :hours 25)))))) ;; define some visitors (define-visitor :params (target) :locals ((total :initform 0)) :polymorphic-methods? #t :methods ((before target (set! total (1+ total))))) (define-visitor :params (target part) :locals ((total :initform 0)) :polymorphic-methods? #t :methods ((before (elt target) (set! total (+ total [part elt]))))) (define-visitor :params (part) :locals (cv sv) :methods ((before (set! cv (make :target )) (set! sv (make :target :part part)) (add-visitors cv sv)))) (define-method count ((v )) [total [cv v]]) (define-method sum ((v )) [total [sv v]]) (define-method average ((v )) (/ (sum v) (count v))) (define-visitor :locals (avg) :methods ((before (set! avg (make :part salary)) (add-visitors avg)) (after (format #t "~%employees: ~a total salary: ~a average salary: ~a~%" (count avg) (sum avg) (average avg))))) ;; define some directives (define whole-company (make )) (define to-full-time (to :bypassing )) (define to-dept (to )) ;; now visit some visitors (define-method test () (traverse whole-company the-company (make :path to-full-time) (make )))