;;;"yasyn.scm" YASOS in terms of "object.scm" ;;; Author: Wade Humeniuk ;;; ;;; This code is in the public domain. (require 'object) (define yasos:instance? object?) ;; Removed (define yasos:make-instance 'bogus) ;; ;; Removed (define-syntax YASOS:INSTANCE-DISPATCHER ;; alias so compiler can inline for speed ;; (syntax-rules () ((yasos:instance-dispatcher inst) (cdr inst)))) ;; DEFINE-OPERATION (define-syntax define-operation (syntax-rules () ((define-operation ( ...) ...) ;;=> (define (make-generic-method (lambda ( ...) ...)))) ((define-operation ( ...) ) ;; no body ;;=> (define-operation ( ...) (slib:error "Operation not handled" ' (format #f (if (yasos:instance? ) "#" "~s") )))))) ;; DEFINE-PREDICATE (define-syntax define-predicate (syntax-rules () ((define-predicate ) ;;=> (define (make-generic-predicate))))) ;; OBJECT (define-syntax object (syntax-rules () ((object (( ...) ...) ...) ;;=> (let ((self (make-object))) (make-method! self (lambda ( ...) ...)) ... self)))) ;; OBJECT with MULTIPLE INHERITANCE {First Found Rule} (define-syntax object-with-ancestors (syntax-rules () ((object-with-ancestors ( ( ) ... ) (( ...) ...) ...) ;;=> (let* (( ) ... (self (make-object ...))) (make-method! self (lambda ( ...) ...)) ... self)))) ;; OPERATE-AS {a.k.a. send-to-super} ; used in operations/methods (define-syntax operate-as (syntax-rules () ((operate-as ...) ;; What is ??? ;;=> ((get-method ) ...)))) ;; SET & SETTER (define-syntax set (syntax-rules () ((set ( ...) ) ((yasos:setter ) ... ) ) ((set ) (set! ) ) ) ) (define yasos:add-setter 'bogus) (define yasos:remove-setter-for 'bogus) (define yasos:setter (let ( (known-setters (list (cons car set-car!) (cons cdr set-cdr!) (cons vector-ref vector-set!) (cons string-ref string-set!)) ) (added-setters '()) ) (set! yasos:add-setter (lambda (getter setter) (set! added-setters (cons (cons getter setter) added-setters))) ) (set! yasos:remove-setter-for (lambda (getter) (cond ((null? added-setters) (slib:error "REMOVE-SETTER-FOR: Unknown getter" getter) ) ((eq? getter (caar added-setters)) (set! added-setters (cdr added-setters)) ) (else (let loop ((x added-setters) (y (cdr added-setters))) (cond ((null? y) (slib:error "REMOVE-SETTER-FOR: Unknown getter" getter)) ((eq? getter (caar y)) (set-cdr! x (cdr y))) (else (loop (cdr x) (cdr y))) ) ) ) ) ) ) (letrec ( (self (lambda (proc-or-operation) (cond ((assq proc-or-operation known-setters) => cdr) ((assq proc-or-operation added-setters) => cdr) (else (proc-or-operation self))) ) ) ) self) ) ) (define (yasos:make-access-operation ) (letrec ( (setter-dispatch (lambda (inst . args) (cond ((and (yasos:instance? inst) (get-method inst setter-dispatch)) => (lambda (method) (apply method (cons inst args))) ) (else #f))) ) (self (lambda (inst . args) (cond ((eq? inst yasos:setter) setter-dispatch) ; for (setter self) ((and (yasos:instance? inst) (get-method inst self)) => (lambda (method) (apply method (cons inst args))) ) (else (slib:error "Operation not handled" inst)) ) ) ) ) self ) ) (define-syntax define-access-operation (syntax-rules () ((define-access-operation ) ;=> (define (yasos:make-access-operation ')) ) ) ) ;;--------------------- ;; general operations ;;--------------------- (define-operation (yasos:print obj port) (format port ;; if an instance does not have a PRINT operation.. (if (yasos:instance? obj) "#" "~s") obj ) ) (define-operation (yasos:size obj) ;; default behavior (cond ((vector? obj) (vector-length obj)) ((list? obj) (length obj)) ((pair? obj) 2) ((string? obj) (string-length obj)) ((char? obj) 1) (else (slib:error "Operation not supported: size" obj)) ) ) (require 'format) ;;; exports: (define print yasos:print) ; print also in debug.scm (define size yasos:size) (define add-setter yasos:add-setter) (define remove-setter-for yasos:remove-setter-for) (define setter yasos:setter) (provide 'oop) ;in case we were loaded this way. (provide 'yasos)