;;;"yasyn.scm" YASOS in terms of "object.scm" ;;; Author: Wade Humeniuk ;;; ;;; This code is in the public domain. (require 'object) (require 'object->string) ;; (define yasos:make-instance 'bogus) (define yasos:instance? object?) (define (pormat dest arg) (define obj (if (yasos:instance? arg) "#" arg)) (cond ((eqv? dest #t) (display obj)) (dest (display obj dest)) ((yasos:instance? arg) obj) (else (object->string arg)))) ;@ (define add-setter 'bogus) (define remove-setter-for 'bogus) ;@ (define 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! add-setter (lambda (getter setter) (set! added-setters (cons (cons getter setter) added-setters))) ) (set! 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 ) ) ;;--------------------- ;; general operations ;;--------------------- ;;; if an instance does not have a PRINT operation.. ;;(define-operation (yasos:print obj port) (pormat port obj) ) ;@ (define print (make-generic-method (lambda (obj!2 port!2) (pormat port!2 obj!2)))) ;;; default behavior ;;(define-operation (yasos:size obj) ;; (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)))) ;@ (define size (make-generic-method (lambda (obj!2) (cond ((vector? obj!2) (vector-length obj!2)) ((list? obj!2) (length obj!2)) ((pair? obj!2) 2) ((string? obj!2) (string-length obj!2)) ((char? obj!2) 1) (else (slib:error 'size "Operation not supported" obj!2)))))) ;;; internal aliases: ;;(define yasos:size size) (define yasos:setter setter) ;; (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 ' (if (yasos:instance? ) "#" )))))) ;; 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-syntax define-access-operation (syntax-rules () ((define-access-operation ) ;=> (define (yasos:make-access-operation ')) ) ) )