⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 goops.scm

📁 MSYS在windows下模拟了一个类unix的终端
💻 SCM
📖 第 1 页 / 共 4 页
字号:
    (if (not (memq (slot-definition-allocation this-slot)		   '(#:class #:each-subclass)))	(slot-missing class slot-name))    g-n-s))(define (class-slot-ref class slot)  (let ((x ((car (class-slot-g-n-s class slot)) #f)))    (if (unbound? x)	(slot-unbound class slot)	x)))(define (class-slot-set! class slot value)  ((cadr (class-slot-g-n-s class slot)) #f value))(define-method (slot-unbound (c <class>) (o <object>) s)  (goops-error "Slot `~S' is unbound in object ~S" s o))(define-method (slot-unbound (c <class>) s)  (goops-error "Slot `~S' is unbound in class ~S" s c))(define-method (slot-unbound (o <object>))  (goops-error "Unbound slot in object ~S" o))(define-method (slot-missing (c <class>) (o <object>) s)  (goops-error "No slot with name `~S' in object ~S" s o))  (define-method (slot-missing (c <class>) s)  (goops-error "No class slot with name `~S' in class ~S" s c))  (define-method (slot-missing (c <class>) (o <object>) s value)  (slot-missing c o s));;; Methods for the possible error we can encounter when calling a gf(define-method (no-next-method (gf <generic>) args)  (goops-error "No next method when calling ~S\nwith arguments ~S" gf args))(define-method (no-applicable-method (gf <generic>) args)  (goops-error "No applicable method for ~S in call ~S"	       gf (cons (generic-function-name gf) args)))(define-method (no-method (gf <generic>) args)  (goops-error "No method defined for ~S"  gf));;;;;; {Cloning functions (from rdeline@CS.CMU.EDU)};;;(define-method (shallow-clone (self <object>))  (let ((clone (%allocate-instance (class-of self) '()))	(slots (map slot-definition-name		    (class-slots (class-of self)))))    (for-each (lambda (slot)		(if (slot-bound? self slot)		    (slot-set! clone slot (slot-ref self slot))))	      slots)    clone))(define-method (deep-clone  (self <object>))  (let ((clone (%allocate-instance (class-of self) '()))	(slots (map slot-definition-name		    (class-slots (class-of self)))))    (for-each (lambda (slot)		(if (slot-bound? self slot)		    (slot-set! clone slot			       (let ((value (slot-ref self slot)))				 (if (instance? value)				     (deep-clone value)				     value)))))	      slots)    clone));;;;;; {Class redefinition utilities};;;;;; (class-redefinition OLD NEW);;;;;; Has correct the following conditions:;;; Methods;;; ;;; 1. New accessor specializers refer to new header;;; ;;; Classes;;; ;;; 1. New class cpl refers to the new class header;;; 2. Old class header exists on old super classes direct-subclass lists;;; 3. New class header exists on new super classes direct-subclass lists(define-method (class-redefinition (old <class>) (new <class>))  ;; Work on direct methods:  ;;		1. Remove accessor methods from the old class   ;;		2. Patch the occurences of new in the specializers by old  ;;		3. Displace the methods from old to new  (remove-class-accessors! old)					;; -1-  (let ((methods (class-direct-methods new)))    (for-each (lambda (m)     	         (update-direct-method! m new old))	;; -2-              methods)    (slot-set! new	       'direct-methods	       (append methods (class-direct-methods old))))  ;; Substitute old for new in new cpl  (set-car! (slot-ref new 'cpl) old)    ;; Remove the old class from the direct-subclasses list of its super classes  (for-each (lambda (c) (slot-set! c 'direct-subclasses				   (delv! old (class-direct-subclasses c))))	    (class-direct-supers old))  ;; Replace the new class with the old in the direct-subclasses of the supers  (for-each (lambda (c)	      (slot-set! c 'direct-subclasses			 (cons old (delv! new (class-direct-subclasses c)))))	    (class-direct-supers new))  ;; Swap object headers  (%modify-class old new)  ;; Now old is NEW!  ;; Redefine all the subclasses of old to take into account modification  (for-each        (lambda (c)	 (update-direct-subclass! c new old))       (class-direct-subclasses new))  ;; Invalidate class so that subsequent instances slot accesses invoke  ;; change-object-class  (slot-set! new 'redefined old)  (%invalidate-class new) ;must come after slot-set!  old);;;;;; remove-class-accessors!;;;(define-method (remove-class-accessors! (c <class>))  (for-each (lambda (m)	      (if (is-a? m <accessor-method>)		  (remove-method-in-classes! m)))	    (class-direct-methods c)));;;;;; update-direct-method!;;;(define-method (update-direct-method! (m  <method>)				      (old <class>)				      (new <class>))  (let loop ((l (method-specializers m)))    ;; Note: the <top> in dotted list is never used.     ;; So we can work as if we had only proper lists.    (if (pair? l)       	  	(begin	  (if (eqv? (car l) old)  	      (set-car! l new))	  (loop (cdr l))))));;;;;; update-direct-subclass!;;;(define-method (update-direct-subclass! (c <class>)					(old <class>)					(new <class>))  (class-redefinition c		      (make-class (class-direct-supers c)				  (class-direct-slots c)				  #:name (class-name c)				  #:environment (slot-ref c 'environment)				  #:metaclass (class-of c))));;;;;; {Utilities for INITIALIZE methods};;;;;; compute-slot-accessors;;;(define (compute-slot-accessors class slots env)  (for-each      (lambda (s g-n-s)	(let ((name            (slot-definition-name     s))	      (getter-function (slot-definition-getter   s))	      (setter-function (slot-definition-setter   s))	      (accessor        (slot-definition-accessor s)))	  (if getter-function	      (add-method! getter-function			   (compute-getter-method class g-n-s)))	  (if setter-function	      (add-method! setter-function			   (compute-setter-method class g-n-s)))	  (if accessor	      (begin		(add-method! accessor			     (compute-getter-method class g-n-s))		(add-method! (setter accessor)			     (compute-setter-method class g-n-s))))))      slots (slot-ref class 'getters-n-setters)))(define-method (compute-getter-method (class <class>) slotdef)  (let ((init-thunk (cadr slotdef))	(g-n-s (cddr slotdef)))    (make <accessor-method>          #:specializers (list class)	  #:procedure (cond ((pair? g-n-s)			     (if init-thunk				 (car g-n-s)				 (make-generic-bound-check-getter (car g-n-s))				 ))			    (init-thunk			     (standard-get g-n-s))			    (else			     (bound-check-get g-n-s)))	  #:slot-definition slotdef)))(define-method (compute-setter-method (class <class>) slotdef)  (let ((g-n-s (cddr slotdef)))    (make <accessor-method>          #:specializers (list class <top>)	  #:procedure (if (pair? g-n-s)			  (cadr g-n-s)			  (standard-set g-n-s))	  #:slot-definition slotdef)))(define (make-generic-bound-check-getter proc)  (let ((source (and (closure? proc) (procedure-source proc))))    (if (and source (null? (cdddr source)))	(let ((obj (caadr source)))	  ;; smart closure compilation	  (local-eval	   `(lambda (,obj) (,assert-bound ,(caddr source) ,obj))	   (procedure-environment proc)))	(lambda (o) (assert-bound (proc o) o)))))(define n-standard-accessor-methods 10)(define bound-check-get-methods (make-vector n-standard-accessor-methods #f))(define standard-get-methods (make-vector n-standard-accessor-methods #f))(define standard-set-methods (make-vector n-standard-accessor-methods #f))(define (standard-accessor-method make methods)  (lambda (index)    (cond ((>= index n-standard-accessor-methods) (make index))	  ((vector-ref methods index))	  (else (let ((m (make index)))		  (vector-set! methods index m)		  m)))))(define (make-bound-check-get index)  (local-eval `(lambda (o) (@assert-bound-ref o ,index)) (the-environment)))(define (make-get index)  (local-eval `(lambda (o) (@slot-ref o ,index)) (the-environment)))(define (make-set index)  (local-eval `(lambda (o v) (@slot-set! o ,index v)) (the-environment)))(define bound-check-get  (standard-accessor-method make-bound-check-get bound-check-get-methods))(define standard-get (standard-accessor-method make-get standard-get-methods))(define standard-set (standard-accessor-method make-set standard-set-methods));;; compute-getters-n-setters;;; (define (compute-getters-n-setters class slots env)  (define (compute-slot-init-function s)    (or (slot-definition-init-thunk s)	(let ((init (slot-definition-init-value s)))	  (and (not (unbound? init))	       (lambda () init)))))  (define (verify-accessors slot l)    (if (pair? l)	(let ((get (car l)) 	      (set (cadr l)))	  (if (not (and (closure? get)			(= (car (procedure-property get 'arity)) 1)))	      (goops-error "Bad getter closure for slot `~S' in ~S: ~S"			   slot class get))	  (if (not (and (closure? set)			(= (car (procedure-property set 'arity)) 2)))	    (goops-error "Bad setter closure for slot `~S' in ~S: ~S"			 slot class set)))))  (map (lambda (s)	 (let* ((g-n-s (compute-get-n-set class s))		(name  (slot-definition-name s)))	   ; For each slot we have '(name init-function getter setter)	   ; If slot, we have the simplest form '(name init-function . index)	   (verify-accessors name g-n-s)	   (cons name		 (cons (compute-slot-init-function s)		       g-n-s))))       slots));;; compute-cpl;;;;;; Correct behaviour:;;;;;; (define-class food ());;; (define-class fruit (food));;; (define-class spice (food));;; (define-class apple (fruit));;; (define-class cinnamon (spice));;; (define-class pie (apple cinnamon));;; => cpl (pie) = pie apple fruit cinnamon spice food object top;;;;;; (define-class d ());;; (define-class e ());;; (define-class f ());;; (define-class b (d e));;; (define-class c (e f));;; (define-class a (b c));;; => cpl (a) = a b d c e f object top;;;(define-method (compute-cpl (class <class>))  (compute-std-cpl class class-direct-supers));; Support(define (only-non-null lst)  (filter (lambda (l) (not (null? l))) lst))(define (compute-std-cpl c get-direct-supers)  (let ((c-direct-supers (get-direct-supers c)))    (merge-lists (list c)                 (only-non-null (append (map class-precedence-list					     c-direct-supers)                                        (list c-direct-supers))))))(define (merge-lists reversed-partial-result inputs)  (cond   ((every null? inputs)    (reverse! reversed-partial-result))   (else    (let* ((candidate (lambda (c)                        (and (not (any (lambda (l)                                         (memq c (cdr l)))                                       inputs))                             c)))           (candidate-car (lambda (l)                            (and (not (null? l))                                 (candidate (car l)))))           (next (any candidate-car inputs)))      (if (not next)          (goops-error "merge-lists: Inconsistent precedence graph"))      (let ((remove-next (lambda (l)                           (if (eq? (car l) next)                               (cdr l)                             l))))        (merge-lists (cons next reversed-partial-result)                     (only-non-null (map remove-next inputs))))))));; Modified from TinyClos:;;;; A simple topological sort.;;;; It's in this file so that both TinyClos and Objects can use it.;;;; This is a fairly modified version of code I originally got from Anurag;; Mendhekar <anurag@moose.cs.indiana.edu>.;;(define (compute-clos-cpl c get-direct-supers)  (top-sort ((build-transitive-closure get-direct-supers) c)	    ((build-constraints get-direct-supers) c)	    (std-tie-breaker get-direct-supers)))(define (top-sort elements constraints tie-breaker)  (let loop ((elements    elements)	     (constraints constraints)	     (result      '()))    (if (null? elements)	result

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -