|
|
1.1 ! root 1: ;; (c) Copywrite 1983, Massachusetts Institute of Technology ! 2: (setq rcs-flavorm- ! 3: "$Header: flavorm.l,v 1.2 85/03/24 11:25:34 sklower Exp $") ! 4: ! 5: ;; This file contains some of the support macros that are need by the ! 6: ;; flavor system. ! 7: ! 8: (environment-maclisp) ! 9: (declare (macros t)) ! 10: ! 11: ; The data-structure on the FLAVOR property of a flavor-name ! 12: (DEFSTRUCT (FLAVOR :NAMED) ! 13: FLAVOR-BINDINGS ;List of locatives to instance variable ! 14: ; internal value cells. MUST BE CDR-CODED!! ! 15: ;Fixnums can also appear. They say to skip ! 16: ;whatever number of instance variable slots. ! 17: FLAVOR-METHOD-HASH-TABLE ;The hash table for methods of this flavor. ! 18: ; NIL means method-combination not composed yet. ! 19: FLAVOR-NAME ;Symbol which is the name of the flavor. ! 20: ; This is returned by TYPEP. ! 21: FLAVOR-LOCAL-INSTANCE-VARIABLES ;Names and initializations, ! 22: ; does not include inherited ones. ! 23: FLAVOR-ALL-INSTANCE-VARIABLES ;Just names, only valid when "flavor ! 24: ; combination" composed. Corresponds directly ! 25: ; to FLAVOR-BINDINGS and the instances. ! 26: FLAVOR-METHOD-TABLE ;Defined below. ! 27: ;; End of locations depended on in many other files. ! 28: FLAVOR-DEPENDS-ON ;List of names of flavors incorporated into this flavor. ! 29: FLAVOR-DEPENDED-ON-BY ;List of names of flavors which incorporate this one. ! 30: ;The above are only immediate dependencies. ! 31: FLAVOR-INCLUDES ;List of names of flavors to include at the end ! 32: ; rather than as immediate depends-on's. ! 33: FLAVOR-DEPENDS-ON-ALL ;Names of all flavors depended on, to all levels, including ! 34: ; this flavor itself. NIL means flavor-combination not ! 35: ; composed yet. This is used by TYPEP of 2 arguments. ! 36: (FLAVOR-WHICH-OPERATIONS NIL) ;List of operations handled, created when needed. ! 37: ; This is NIL if it has not been computed yet. ! 38: ;; Redundant copy of :DEFAULT-HANDLER property, for speed in calling it. ! 39: (FLAVOR-DEFAULT-HANDLER NIL) ! 40: (FLAVOR-GETTABLE-INSTANCE-VARIABLES NIL) ! 41: (FLAVOR-SETTABLE-INSTANCE-VARIABLES NIL) ! 42: (FLAVOR-INITABLE-INSTANCE-VARIABLES NIL) ! 43: ;Alist from init keyword to name of variable ! 44: (FLAVOR-INIT-KEYWORDS NIL) ;option ! 45: (FLAVOR-PLIST NIL) ;Esoteric things stored here as properties ! 46: ;Known: :ORDERED-INSTANCE-VARIABLES, :DEFAULT-HANDLER ! 47: ; :OUTSIDE-ACCESSIBLE-INSTANCE-VARIABLES, :ACCESSOR-PREFIX, ! 48: ; :REQUIRED-INSTANCE-VARIABLES, :REQUIRED-METHODS, ! 49: ; :REQUIRED-FLAVORS, :SELECT-METHOD-ORDER, ! 50: ; :DEFAULT-INIT-PLIST, :DOCUMENTATION, :NO-VANILLA-FLAVOR ! 51: ; :GETTABLE-INSTANCE-VARIABLES :SETTABLE-INSTANCE-VARIABLES ! 52: ; ADDITIONAL-INSTANCE-VARIABLES ! 53: ; COMPILE-FLAVOR-METHODS ! 54: ; MAPPED-COMPONENT-FLAVORS ! 55: ; INSTANCE-VARIABLE-INITIALIZATIONS ! 56: ; ALL-INITABLE-INSTANCE-VARIABLES ! 57: ; REMAINING-DEFAULT-PLIST ! 58: ; REMAINING-INIT-KEYWORDS ! 59: ;The convention on these is supposed to be that ! 60: ;ones in the keyword packages are allowed to be ! 61: ;used by users. ! 62: ;Some of these are not used by the flavor system, they are ! 63: ;just remembered on the plist in case anyone cares. The ! 64: ;flavor system does all its handling of them during the ! 65: ;expansion of the DEFFLAVOR macro. ! 66: ) ! 67: ! 68: (defsubst instancep (x) ! 69: (and (fclosurep x) (eq (fclosure-function x) #'flavor-dispatch))) ! 70: ! 71: (defvar self () ! 72: "Self referential pointer for flavors") ! 73: ! 74: (defmacro send (object message &rest args) ! 75: (if (eq object 'self) ! 76: `(send-self ,message ,@args) ! 77: `(send-internal ,object ,message ,@args))) ! 78: ! 79: (defmacro lexpr-send (object &rest args) ! 80: (if (eq object 'self) ! 81: `(lexpr-send-self ,@args) ! 82: `(lexpr-funcall #'send-internal ,object ,@args))) ! 83: ! 84: ;; These two functions are used when sending a message to yourself, for ! 85: ;; extra efficiency. They avoid the variable unbinding and binding ! 86: ;; required when entering a closure. ! 87: (defmacro send-self (message &rest args) ! 88: `(funcall (or (gethash ,message (flavor-method-hash-table .own-flavor.)) ! 89: (flavor-default-handler .own-flavor.)) ! 90: ,message . ,args)) ! 91: (defmacro funcall-self (&rest args) `(send-self . ,args)) ! 92: ! 93: (defmacro lexpr-send-self (message &rest args) ! 94: `(lexpr-funcall (or (gethash ,message ! 95: (flavor-method-hash-table .own-flavor.)) ! 96: (flavor-default-handler .own-flavor.)) ! 97: ,message . ,args)) ! 98: (defmacro lexpr-funcall-self (&rest args) `(lexpr-send-self . ,args)) ! 99: ! 100: (defsetf send (e v) ! 101: (if (or (atom (caddr e)) ! 102: (neq (car (caddr e)) 'quote)) ! 103: (ferror () "Don't know how to setf this ~S" e)) ! 104: (cond ((eq (cadr (caddr e)) ':get) ! 105: `(send ,(cadr e) ':putprop ,v ,(cadddr e))) ! 106: (t ! 107: `(send ,(cadr e) ',(intern (format () ":set-~A" ! 108: (remove-colon (cadr (caddr e))))) ! 109: ,v)))) ! 110: ! 111: (putprop 'flavorm t 'version)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.