(DEFINE-FILE-INFO READTABLE "XCL" PACKAGE "LISP")(IL:FILECREATED " 4-Jan-93 18:04:53" IL:|{DSK}<python>lde>lispcore>sources>DEFSTRUCT.;2| 83865        IL:|previous| IL:|date:| "11-Jun-92 14:44:30" IL:|{DSK}<python>lde>lispcore>sources>DEFSTRUCT.;1|); Copyright (c) 1986, 1987, 1900, 1988, 1989, 1990, 1992, 1993 by Venue & Xerox Corporation.  All rights reserved.(IL:PRETTYCOMPRINT IL:DEFSTRUCTCOMS)(IL:RPAQQ IL:DEFSTRUCTCOMS ((IL:* IL:|;;;| "Implementation of Structure facilities of Commmon Lisp.  (Chapter 19 of CLtL).")                                (IL:* IL:|;;;| "public interface ")                                (IL:DEFINE-TYPES IL:STRUCTURES)                                (IL:FUNCTIONS DEFSTRUCT)                                (IL:* IL:|;;;| "top-level ")                                (IL:DECLARE\: IL:DOCOPY IL:DONTEVAL@LOAD (IL:FILES                                                                                 IL:DEFSTRUCT-RUN-TIME                                                                                ))                                (IL:* IL:|;;;| "parsing code")                                (IL:VARIABLES %DEFAULT-DEFSTRUCT-TYPE %DEFAULT-SLOT-TYPE                                        %DEFAULT-STRUCTURE-INCLUDE %DEFSTRUCT-OPTIONS %NO-CONSTRUCTOR                                       %NO-PREDICATE %NO-COPIER %DEFSTRUCT-CONSP-OPTIONS                                        %DEFSTRUCT-EXPORT-OPTIONS)                                (IL:FUNCTIONS ASSIGN-SLOT-ACCESSOR REMOVE-DOCUMENTATION                                        RECORD-DOCUMENTATION ENSURE-VALID-TYPE PARSE-SLOT                                        DEFSTRUCT-PARSE-OPTIONS ENSURE-CONSISTENT-PS                                        PS-NUMBER-OF-SLOTS PS-TYPE-SPECIFIER)                                (IL:* IL:|;;;| "slot resolution code")                                (IL:FUNCTIONS ASSIGN-SLOT-OFFSET RESOLVE-SLOTS INSERT-INCLUDED-SLOT                                        MERGE-SLOTS NAME-SLOT DUMMY-SLOT OFFSET-SLOT)                                (IL:* IL:|;;;| "data layout code")                                (IL:FUNCTIONS ASSIGN-STRUCTURE-REPRESENTATION COERCE-TYPE                                        %STRUCTURE-TYPE-TO-FIELDSPEC ASSIGN-FIELD-DESCRIPTORS                                        STRUCTURE-POINTER-SLOTS)                                (IL:* IL:|;;;| "type system hooks")                                (IL:FUNCTIONS PROCESS-TYPE PREDICATE-BODY TYPE-EXPAND-STRUCTURE                                        TYPE-EXPAND-NAMED-STRUCTURE PS-NAME-SLOT-POSITION                                        DEFAULT-PREDICATE-NAME DEFSTRUCT-SHARED-PREDICATE-OPTIMIZER                                        CACHE-PREDICATE-INFO)                                (IL:VARIABLES %FUNCTION-DEFINING-FORM-KEYWORDS)                                (IL:* IL:|;;;| "accessors and setfs")                                (IL:FUNCTIONS SETF-NAME)                                (IL:FUNCTIONS ACCESSOR-BODY PROCESS-ACCESSORS ESTABLISH-ACCESSORS                                        DEFINE-ACCESSORS DEFSTRUCT-SHARED-ACCESSOR-OPTIMIZER                                        DEFSTRUCT-SHARED-SETF-EXPANDER CACHE-SLOT-INFO)                                (IL:FUNCTIONS %MAKE-ACCESSOR-CLOSURE %MAKE-LIST-ACCESSOR                                        %MAKE-ARRAY-ACCESSOR %MAKE-POINTER-ACCESSOR %MAKE-BIT-ACCESSOR                                       %MAKE-FLAG-ACCESSOR %MAKE-WORD-ACCESSOR %MAKE-FIXP-ACCESSOR                                        %MAKE-SMALL-FIXP-ACCESSOR %MAKE-FLOAT-ACCESSOR)                                (IL:* IL:|;;;| "constructor definition code")                                (IL:FUNCTIONS DEFINE-CONSTRUCTORS DEFINE-BOA-CONSTRUCTOR                                        ARGUMENT-NAMES BOA-ARG-LIST-WITH-INITIAL-VALUES BOA-SLOT-SETFS                                       FIND-SLOT RAW-CONSTRUCTOR BUILD-CONSTRUCTOR-ARGLIST                                        BUILD-CONSTRUCTOR-SLOT-SETFS BOA-CONSTRUCTOR-P                                        DEFAULT-CONSTRUCTOR-NAME)                                (IL:* IL:|;;;| "copiers")                                (IL:FUNCTIONS DEFINE-COPIERS BUILD-COPIER-SLOT-SETFS                                        BUILD-COPIER-TYPE-CHECK)                                (IL:* IL:|;;;| "print functions")                                (IL:VARIABLES %DEFAULT-PRINT-FUNCTION)                                (IL:* IL:|;;;| "internal stuff.")                                (IL:SETFS IL:FFETCHFIELD)                                (IL:* IL:|;;;| "utilities")                                (IL:FUNCTIONS DEFSTRUCT-ASSERT-SUBTYPEP)                                (IL:* IL:|;;;| "inspecting structures")                                (IL:FUNCTIONS STRUCTURE-OBJECT-P INSPECT-STRUCTURE-OBJECT                                        STRUCTURE-OBJECT-INSPECT-FETCHFN                                        STRUCTURE-OBJECT-INSPECT-PROPPRINTFN                                        STRUCTURE-OBJECT-INSPECT-STOREFN                                        STRUCTURE-OBJECT-PROPCOMMANDFN)                                                                (IL:* IL:|;;|                           "Defined last so functions required to load a defstruct are loaded first")                                (IL:STRUCTURES PS PARSED-SLOT)                                                                (IL:* IL:|;;|                      "Mapping between names of generated functions and their associated structures")                                (IL:FUNCTIONS STRUCTURE-FUNCTION-P STRUCTURE-FUNCTIONS)                                (IL:* IL:|;;;| "Editing structures")                                (IL:FUNCTIONS STRUCTURES.HASDEF STRUCTURES.EDITDEF)                                (IL:P (IL:FILEPKGTYPE 'IL:STRUCTURES 'IL:HASDEF 'STRUCTURES.HASDEF                                             'IL:EDITDEF                                             'STRUCTURES.EDITDEF))                                (IL:ADDVARS (IL:SHADOW-TYPES (IL:STRUCTURES IL:FNS)))                                (IL:DECLARE\: IL:DOCOPY IL:DONTEVAL@LOAD                                       (IL:ADDVARS (IL:INSPECTMACROS ((IL:FUNCTION STRUCTURE-OBJECT-P                                                                             )                                                                          . INSPECT-STRUCTURE-OBJECT)                                                          )))                                (IL:* IL:|;;;| "file properties")                                (IL:PROP IL:FILETYPE IL:DEFSTRUCT)                                (IL:PROP IL:MAKEFILE-ENVIRONMENT IL:DEFSTRUCT)))(IL:* IL:|;;;| "Implementation of Structure facilities of Commmon Lisp.  (Chapter 19 of CLtL).")(IL:* IL:|;;;| "public interface ")(XCL:DEF-DEFINE-TYPE IL:STRUCTURES "Common Lisp structures")(XCL:DEFDEFINER (DEFSTRUCT (:NAME (LAMBDA (WHOLE)                                             (LET ((NAME-AND-OPTIONS (SECOND WHOLE)))                                                  (IF (CONSP NAME-AND-OPTIONS)                                                      (CAR NAME-AND-OPTIONS)                                                      NAME-AND-OPTIONS))))                               (:PROTOTYPE (LAMBDA (NAME)                                                  (AND (SYMBOLP NAME)                                                       `(DEFSTRUCT (,NAME (":option" "value"))                                                           "documentation string"                                                           ("slot-name" "initial-value"))))))    IL:STRUCTURES (NAME &REST SLOT-DESCRIPTIONS)   (LET* ((PS (DEFSTRUCT-PARSE-OPTIONS NAME))          (SLOT-DESCRIPTIONS (REMOVE-DOCUMENTATION PS SLOT-DESCRIPTIONS)))         (RESOLVE-SLOTS SLOT-DESCRIPTIONS PS)         `(PROGN (EVAL-WHEN (EVAL COMPILE LOAD)                        (SETF (PARSED-STRUCTURE ',(PS-NAME PS)                                     T)                              ',PS))                 ,@(ASSIGN-STRUCTURE-REPRESENTATION PS)                 ,@(PROCESS-TYPE PS)                 ,@(PROCESS-ACCESSORS PS)                 (EVAL-WHEN (EVAL COMPILE LOAD)                        (ESTABLISH-SETFS-AND-OPTIMIZERS ',(PS-NAME PS)))                 ,@(DEFINE-CONSTRUCTORS PS)                 ,@(DEFINE-COPIERS PS)                 ,@(RECORD-DOCUMENTATION PS))))(IL:* IL:|;;;| "top-level ")(IL:DECLARE\: IL:DOCOPY IL:DONTEVAL@LOAD (IL:FILESLOAD IL:DEFSTRUCT-RUN-TIME))(IL:* IL:|;;;| "parsing code")(DEFVAR %DEFAULT-DEFSTRUCT-TYPE 'DATATYPE                                           "The type of structures when no :type option is specified")(DEFVAR %DEFAULT-SLOT-TYPE 'T "the type of any slot which does not specifiy a :type option")(DEFCONSTANT %DEFAULT-STRUCTURE-INCLUDE 'STRUCTURE-OBJECT "datatype included by every structure")(DEFPARAMETER %DEFSTRUCT-OPTIONS   '(:CONC-NAME :CONSTRUCTOR :COPIER :PREDICATE :INCLUDE :PRINT-FUNCTION :TYPE :INITIAL-OFFSET :NAMED           :INLINE :FAST-ACCESSORS :TEMPLATE :EXPORT))(DEFCONSTANT %NO-CONSTRUCTOR ':NONE "the value which says that no constructor was specified.")(DEFCONSTANT %NO-PREDICATE ':NONE "the value which says that no constructor was specified")(DEFCONSTANT %NO-COPIER ':NONE)(DEFPARAMETER %DEFSTRUCT-CONSP-OPTIONS (REMOVE ':NAMED %DEFSTRUCT-OPTIONS))(DEFPARAMETER %DEFSTRUCT-EXPORT-OPTIONS '(:ACCESSOR :CONSTRUCTOR :PREDICATE :COPIER))(DEFUN ASSIGN-SLOT-ACCESSOR (SLOT CONC-NAME)   (IL:* IL:|;;| "assigns the accessor name to a slot")   (IF (PSLOT-ACCESSOR SLOT)       (SETF (PSLOT-ACCESSOR SLOT)             (VALUES (INTERN (CONCATENATE 'STRING (STRING CONC-NAME)                                    (STRING (PSLOT-NAME SLOT))))))))(DEFUN REMOVE-DOCUMENTATION (PS SLOT-DESCRIPTIONS)   (IL:* IL:|;;| "Records it if there is any documentation string.")   (LET ((DOC? (CAR SLOT-DESCRIPTIONS)))        (COND           ((STRINGP DOC?)            (IL:* IL:|;;| " save it and return the rest of the slots.")            (SETF (PS-DOCUMENTATION-STRING PS)                  DOC?)            (REST SLOT-DESCRIPTIONS))           (T               (IL:* IL:|;;| "no doc string, return the whole thing.")              SLOT-DESCRIPTIONS))))(DEFUN RECORD-DOCUMENTATION (PS)   (IL:* IL:|;;| "Returns a form which saves the documentation string for a structure.")   (LET ((PARSED-DOCSTRING (PS-DOCUMENTATION-STRING PS)))        (IF PARSED-DOCSTRING            `((SETF (DOCUMENTATION ',(PS-NAME PS)                           'STRUCTURE)                    ,PARSED-DOCSTRING)))))(DEFUN ENSURE-VALID-TYPE (TYPE-FORM)   (IL:* IL:|;;| "Bogus right now ")   TYPE-FORM)(DEFUN PARSE-SLOT (DESCRIPTION &OPTIONAL (GENERATE-ACCESSOR T))   (IL:* IL:|;;|  "Takes a slot description from the defstruct body or included slots and returns a parsed version")   (LET* ((DESCRIPTION (IF (CONSP DESCRIPTION)                           DESCRIPTION                           (LIST DESCRIPTION)))          (SLOT (MAKE-PARSED-SLOT)))         (XCL:DESTRUCTURING-BIND (NAME &OPTIONAL INITIAL-VALUE &REST SLOT-OPTIONS)                DESCRIPTION                (IF (SYMBOLP NAME)                    (SETF (PSLOT-NAME SLOT)                          NAME)                    (ERROR "Slot name not symbol: ~S" NAME))                (SETF (PSLOT-INITIAL-VALUE SLOT)                      INITIAL-VALUE)                (IL:* IL:|;;| "some variant of PCL's keyword-bind would be easier here, but it's incapable of producing reasonable error msgs for the user.  Maybe later.")                (DO ((OPTION-PAIR SLOT-OPTIONS (CDDR OPTION-PAIR)))                    ((NULL OPTION-PAIR))                  (CASE (CAR OPTION-PAIR)                      (:TYPE (SETF (PSLOT-TYPE SLOT)                                   (ENSURE-VALID-TYPE (CADR OPTION-PAIR))))                      (:READ-ONLY (SETF (PSLOT-READ-ONLY SLOT)                                        (AND (CADR OPTION-PAIR)                                             T)))                      (OTHERWISE (IF (KEYWORDP INITIAL-VALUE)                                     (ERROR "Initial value must be specified to use slot options. ~S"                                            DESCRIPTION)                                     (ERROR "Illegal slot option ~S in slot ~S" (CAR OPTION-PAIR)                                            NAME)))))                (IF GENERATE-ACCESSOR                    (SETF (PSLOT-ACCESSOR SLOT)                          T)))         SLOT))(DEFUN DEFSTRUCT-PARSE-OPTIONS (NAME&OPTIONS)   (IL:* IL:|;;| "Returns a structure representing the options in a defstruct call.")   (LET* ((OPTIONS (IF (LISTP NAME&OPTIONS)                       NAME&OPTIONS                       (LIST NAME&OPTIONS)))          (NAME (POP OPTIONS))          (PS (MAKE-PS :NAME NAME :CONC-NAME (CONCATENATE 'STRING (STRING NAME)                                                    "-"))))         (DOLIST (OPTION OPTIONS)             (COND                ((LISTP OPTION)                 (XCL:DESTRUCTURING-BIND (OPTION-KEYWORD &OPTIONAL (OPTION-VALUE NIL                                                                           ARGUMENT-PROVIDED)                                                &REST FURTHER-ARGUMENTS)                        OPTION                        (CASE OPTION-KEYWORD                            (:CONC-NAME                                (IL:* IL:|;;|   "if the option is specified, but the option value is nil, then use the empty string as conc-name")                               (SETF (PS-CONC-NAME PS)                                     (OR OPTION-VALUE "")))                            (:CONSTRUCTOR                                (IL:* IL:|;;|               "multiple constructors are allowed.  If NIL is provided, then define no constructor.")                               (COND                                  ((NOT OPTION-VALUE)                                   (IF ARGUMENT-PROVIDED                                       (IL:* IL:|;;|                                    "NIL was specified.  Record that no constructor is to be built.")                                       (SETF (PS-CONSTRUCTORS PS)                                             NIL)                                       (IL:* IL:|;;| "otherwise, it as though the option weren't specified (p. 312 cltl) so leave the default value there.")                                       ))                                  ((EQ (PS-CONSTRUCTORS PS)                                       %NO-CONSTRUCTOR)                                   (IL:* IL:|;;|                           "this is the first constructor specified.  Make the field be a list now.")                                   (SETF (PS-CONSTRUCTORS PS)                                         (LIST (IF FURTHER-ARGUMENTS                                                   (CDR OPTION)                                                   OPTION-VALUE))))                                  (T                                      (IL:* IL:|;;|                                    "just push another one on the list of constructors.")                                     (PUSH (IF FURTHER-ARGUMENTS                                               (CDR OPTION)                                               OPTION-VALUE)                                           (PS-CONSTRUCTORS PS)))))                            (:COPIER                                (IL:* IL:|;;| "if the argument is specified (even if it is nil), use it.  Otherwise use the default COPY- form already in the ps.")                               (IF ARGUMENT-PROVIDED                                   (SETF (PS-COPIER PS)                                         OPTION-VALUE)))                            (:PREDICATE (IF ARGUMENT-PROVIDED                                            (SETF (PS-PREDICATE PS)                                                  OPTION-VALUE)))                            (:INCLUDE                                (SETF (PS-INCLUDE PS)                                     OPTION-VALUE)                               (IL:* IL:|;;| "if there are any included slots record them")                               (SETF (PS-INCLUDED-SLOTS PS)                                     (CDDR OPTION)))                            (:PRINT-FUNCTION (COND                                                ((AND ARGUMENT-PROVIDED (NULL OPTION-VALUE))                                                (IL:* IL:|;;| "extension to CLtL, if NIL is specified as the defprint, then the internal print function is specified.")                                                 (SETF (PS-PRINT-FUNCTION PS)                                                       'IL:\\PRINT-USING-ADDRESS))                                                (ARGUMENT-PROVIDED (SETF (PS-PRINT-FUNCTION PS)                                                                         OPTION-VALUE))))                            (:TYPE (SETF (PS-TYPE PS)                                         (COND                                            ((EQ OPTION-VALUE 'LIST)                                             'LIST)                                            ((EQ OPTION-VALUE 'VECTOR)                                                             (IL:* IL:\;                                                            "default the vector type to t")                                             (SETF (PS-VECTOR-TYPE PS)                                                   T)                                             'VECTOR)                                            ((AND (CONSP OPTION-VALUE)                                                  (EQ (CAR OPTION-VALUE)                                                      'VECTOR))                                             (SETF (PS-VECTOR-TYPE PS)                                                   (IL:%GET-CANONICAL-CML-TYPE (CADR OPTION-VALUE)))                                             'VECTOR)                                            (T (ERROR                                            "the specified :type is not list or subtype of vector: ~S"                                                      OPTION-VALUE)))))                            (:INITIAL-OFFSET                                (IF (NOT (TYPEP OPTION-VALUE '(INTEGER 0 *)))                                   (ERROR ":initial-offset isn't a non-negative integer: ~S"                                           OPTION-VALUE))                               (SETF (PS-INITIAL-OFFSET PS)                                     OPTION-VALUE))                            (:INLINE                                (IL:* IL:|;;|                   "Is one or both of  :accessor, and  :predicate or t, which is equivalent to both")                               (IL:* IL:|;;| "Default is '(:accessor :predicate) ")                               (IL:* IL:|;;|                 "option (:inline :only) implies no funcallable accessors or predicate is generated")                               (IF ARGUMENT-PROVIDED                                   (SETF (PS-INLINE PS)                                         OPTION-VALUE)))                            (:FAST-ACCESSORS                                (IL:* IL:|;;|                              "Is either t or nil,  t implying no type checks for all accessors")                               (IF ARGUMENT-PROVIDED                                   (SETF (PS-FAST-ACCESSORS PS)                                         OPTION-VALUE)))                            (:TEMPLATE                                (IL:* IL:|;;| "Is either t or nil -- t  implying type datatype, no copier, predicate, print-function or constructors, and fast accessors, and no new datatype declared.")                               (IF ARGUMENT-PROVIDED                                   (SETF (PS-TEMPLATE PS)                                         OPTION-VALUE)))                            (:EXPORT                                (IL:* IL:|;;| "Edited by TT(13-June-90) Export Option is added for DEFSTRUCT(Medley 1.2). The Specified functions(ex. :constructor, :copier...) will be exported.")                               (IF FURTHER-ARGUMENTS                                   (ERROR "The specified export functions is not list or atom : ~S"                                          (CONS :EXPORT (CONS OPTION-VALUE FURTHER-ARGUMENTS)))                                   (IF ARGUMENT-PROVIDED                                       (SETF (PS-EXPORT PS)                                             OPTION-VALUE)                                       (SETF (PS-EXPORT PS)                                             T))))                            (OTHERWISE (ERROR "Bad option to defstruct: ~S." OPTION)))))                (T (CASE OPTION                       (:NAMED (SETF (PS-NAMED PS)                                     T))                       (OTHERWISE (IF (MEMBER OPTION %DEFSTRUCT-CONSP-OPTIONS :TEST #'EQ)                                      (ERROR                                           "defstruct option ~s must be in parentheses with its value"                                             OPTION)                                      (ERROR "Bad option to defstruct: ~S." OPTION)))))))         (ENSURE-CONSISTENT-PS PS)         PS))(DEFUN ENSURE-CONSISTENT-PS (PS)   (IL:* IL:|;;|  "Accomplishes the consistency checks that can't occur until all the options have been parsed.")   (IF (PS-INCLUDE PS)       (LET* ((INCLUDE (PS-INCLUDE PS))              (INCLUDED-PSTRUCTURE (PARSED-STRUCTURE INCLUDE)))             (IL:* IL:|;;| "ensure that the user is not suicidal.  If a structure includes itself, a *very* tight ucode loop will  occur in the instancep opcode.")             (IF (EQ INCLUDE (PS-NAME PS))                 (ERROR "You probably don't want ~S to include ~S." INCLUDE INCLUDE))             (IL:* IL:|;;| "ensure that the included structure is defined.")             (IF (OR (NULL INCLUDED-PSTRUCTURE)                     (PS-TEMPLATE INCLUDED-PSTRUCTURE))                 (ERROR "Included structure ~s is unknown or not instantiated." INCLUDE))             (IL:* IL:|;;| "make sure the type of the included structure is the same")             (IF (OR (NOT (EQ (PS-TYPE INCLUDED-PSTRUCTURE)                              (PS-TYPE PS)))                     (NOT (EQ (PS-VECTOR-TYPE INCLUDED-PSTRUCTURE)                              (PS-VECTOR-TYPE PS))))                 (ERROR "~s must be same type as included structure ~s" (PS-NAME PS)                        INCLUDE))))   (LET ((INLINE (PS-INLINE PS))         (POSSIBLE-KEYWORDS '(:ACCESSOR :PREDICATE)))        (CASE INLINE            ((T)                (IL:* IL:|;;|  "this is the default case, so make the default be that only the accessors, predicates are inline.")               (SETF (PS-INLINE PS)                     POSSIBLE-KEYWORDS))            ((NIL :ONLY) )            (OTHERWISE (MAPCAR #'(LAMBDA (KEYWORD)                                        (IF (NOT (MEMBER KEYWORD POSSIBLE-KEYWORDS :TEST #'EQ))                                            (ERROR "~s must be one of ~s." KEYWORD POSSIBLE-KEYWORDS)                                            ))                              (IF (CONSP INLINE)                                  INLINE                                  (SETF (PS-INLINE PS)                                        (LIST INLINE)))))))   (COND      ((PS-TEMPLATE PS)       (IF (NOT (EQ (PS-TYPE PS)                    %DEFAULT-DEFSTRUCT-TYPE))           (ERROR "Templated defstructs may not be of type: ~s" (PS-TYPE PS)))       (IF (OR (NOT (EQ (PS-CONSTRUCTORS PS)                        %NO-CONSTRUCTOR))               (NOT (EQ (PS-PREDICATE PS)                        %NO-PREDICATE))               (NOT (EQ (PS-COPIER PS)                        %NO-COPIER))               (PS-PRINT-FUNCTION PS))           (ERROR                "Templated defstructs may not have constructors predicates copiers or print functions"                  )))      (T (IF (PS-PRINT-FUNCTION PS)             (IF (NOT (EQ (PS-TYPE PS)                          %DEFAULT-DEFSTRUCT-TYPE))                 (ERROR "A print-function can't be specified for structures of type ~s" (PS-TYPE                                                                                         PS)))             (LET ((INCLUDE (PS-INCLUDE PS)))                  (IF INCLUDE                      (IL:* IL:|;;| "CLtL is silent, but we inherit print-functions")                      (SETF (PS-PRINT-FUNCTION PS)                            (PS-PRINT-FUNCTION (PARSED-STRUCTURE INCLUDE)))                      (IL:* IL:|;;| "otherwise, use the default #s style printer")                      (SETF (PS-PRINT-FUNCTION PS)                            %DEFAULT-PRINT-FUNCTION))))         (IF (AND (EQ (PS-TYPE PS)                      'VECTOR)                  (EQ (PS-NAMED PS)                      T))             (IL:* IL:|;;|            "check that the vector type can actually hold the symbol required for the name.")             (DEFSTRUCT-ASSERT-SUBTYPEP 'SYMBOL (PS-VECTOR-TYPE PS)                    ("vector of ~S cannot contain the symbol required for the :named options"                     (PS-VECTOR-TYPE PS))))         (IF (EQ (PS-PREDICATE PS)                 %NO-PREDICATE)             (IL:* IL:|;;| "there is no predicate. (Note that this is not a null check.  If this field is NIL the user explicitly gave NIL as the predicate.)  ")             (IF (OR (EQ (PS-TYPE PS)                         'DATATYPE)                     (PS-NAMED PS))                 (IL:* IL:|;;| "If this structure is type datatype or named, use the default name")                 (SETF (PS-PREDICATE PS)                       (DEFAULT-PREDICATE-NAME (PS-NAME PS)))                 (IL:* IL:|;;| "now set it to NIL to signal no predicate to the predicate builder.")                 (SETF (PS-PREDICATE PS)                       NIL)))         (IF (EQ (PS-COPIER PS)                 %NO-COPIER)             (IL:* IL:|;;| "Note that this is not a null check.  If this field is NIL the user explicitly gave NIL as the copier  ")             (SETF (PS-COPIER PS)                   (INTERN (CONCATENATE 'STRING "COPY-" (STRING (PS-NAME PS))))))         (LET ((EXPORTNAMES (PS-EXPORT PS)))              (IL:* IL:|;;| "If export-slot is nil, functions will not be exported. otherwise, export the specified functions.[Edited by TT (13-June-90)")              (AND EXPORTNAMES (OR (EQ EXPORTNAMES T)                                   (AND (NOT (LISTP EXPORTNAMES))                                        (NOT (SETF (PS-EXPORT PS)                                                   (SETQ EXPORTNAMES (LIST EXPORTNAMES)))))                                   (DOLIST (EXPORTNAME EXPORTNAMES T)                                       (OR (MEMBER EXPORTNAME %DEFSTRUCT-EXPORT-OPTIONS)                                           (ERROR "~S is not valid option keyword for :EXPORT"                                                   EXPORTNAME))))))         (COND            ((EQ (PS-CONSTRUCTORS PS)                 %NO-CONSTRUCTOR)             (IL:* IL:|;;| "There were no constructors specified.  Default the value.")             (SETF (PS-CONSTRUCTORS PS)                   `(,(DEFAULT-CONSTRUCTOR-NAME (PS-NAME PS)))))))))(DEFUN PS-NUMBER-OF-SLOTS (PS)   "the number of slots in an instance of this structure"   (LENGTH (PS-ALL-SLOTS PS)))(DEFUN PS-TYPE-SPECIFIER (PS)   "returns list, vector, or (vector foo)"   (ECASE (PS-TYPE PS)       (LIST 'LIST)       (VECTOR (LET ((ELEMENT-TYPE (PS-VECTOR-TYPE PS)))                    (IF (IL:NEQ ELEMENT-TYPE T)                        `(VECTOR ,ELEMENT-TYPE)                        'VECTOR)))))(IL:* IL:|;;;| "slot resolution code")(DEFUN ASSIGN-SLOT-OFFSET (PS)   (IL:* IL:|;;| "Assigns the offsets for each slot for type vector and list.")   (LET* ((NAME (PS-NAME PS))          (SLOTS (PS-ALL-SLOTS PS)))         (ECASE (PS-TYPE PS)             ((VECTOR LIST)                 (IL:* IL:|;;| "the field descriptor is just the offset.")                (DO ((I 0 (1+ I))                     (SLOT SLOTS (CDR SLOT)))                    ((NULL SLOT))                  (SETF (PSLOT-FIELD-DESCRIPTOR (CAR SLOT))                        I))))))(DEFUN RESOLVE-SLOTS (LOCAL-SLOT-DESCRIPTIONS PS)   (IL:* IL:|;;| "Combines the slot descriptions from the defstruct call with the included slot-descriptions from supers and the :includes option, and installs the decription in the parsed-structure")   (LET ((LOCAL-SLOTS (MAPCAR #'PARSE-SLOT LOCAL-SLOT-DESCRIPTIONS))         (INCLUDED-SLOTS (MAPCAR #'PARSE-SLOT (PS-INCLUDED-SLOTS PS)))         (INCLUDES (PS-INCLUDE PS)))        (WHEN (PS-NAMED PS)            (IL:* IL:|;;| "Adds the slot representing the name pseudo-slot. ")            (IF (NOT (PS-NAMED PS))                (ERROR ":named not supplied for this defstruct"))            (PUSH (NAME-SLOT PS)                  LOCAL-SLOTS))        (WHEN (NOT (EQ 0 (PS-INITIAL-OFFSET PS)))            (IL:* IL:|;;| "Adds parsed-slots to the local-slots to represent the initial offset.")            (SETQ LOCAL-SLOTS (NCONC (XCL:WITH-COLLECTION (DOTIMES (I (PS-INITIAL-OFFSET PS))                                                              (XCL:COLLECT (OFFSET-SLOT))))                                     LOCAL-SLOTS)))        (IF INCLUDES            (LET ((SUPER-SLOTS                          (IL:* IL:|;;| "must copy the slots, since the accessor-name will be destructively modified to use the new conc-name.")                         (MAPCAR #'COPY-PARSED-SLOT (PS-ALL-SLOTS (PARSED-STRUCTURE INCLUDES)))))                 (IL:* IL:|;;| "update the super-slots according to the included-slots, then make all-slots be (append merged-slots local-slots)")                 (SETF (PS-ALL-SLOTS PS)                       (NCONC (MERGE-SLOTS INCLUDED-SLOTS SUPER-SLOTS PS)                              LOCAL-SLOTS)))            (PROGN (IF INCLUDED-SLOTS                       (ERROR "Can't include slots when ~s includes no structure." (PS-NAME PS)))                   (IL:* IL:|;;| "no included slots, so the local-slots are it.")                   (SETF (PS-ALL-SLOTS PS)                         LOCAL-SLOTS)))        (WHEN (AND (NULL (PS-ALL-SLOTS PS))                   (EQ (PS-TYPE PS)                       %DEFAULT-DEFSTRUCT-TYPE))            (PUSH (DUMMY-SLOT)                  LOCAL-SLOTS)            (SETF (PS-ALL-SLOTS PS)                  LOCAL-SLOTS))        (IL:* IL:|;;| "No longer require local slots to be recorded")        (SETF (PS-LOCAL-SLOTS PS)              LOCAL-SLOTS)        (IL:* IL:|;;| "now that all slots (included, super, local and filler) have been included, we can create accessor names.")        (LET ((CONC-NAME (PS-CONC-NAME PS)))             (DOLIST (SLOT (PS-ALL-SLOTS PS))                 (ASSIGN-SLOT-ACCESSOR SLOT CONC-NAME)))        (IL:* IL:|;;|       "we can also record slot-names for the default-structure-printer and inspector.")        (SETF (PS-ALL-SLOT-NAMES PS)              (MAPCAR #'PSLOT-NAME (PS-ALL-SLOTS PS)))        (IL:* IL:|;;| "make sure that no slot names have been repeated (either from being explicitly listed twice in the defstruct, or using a slot name that is present in the super without using :include for the slot)")        (DO ((SLOT-NAMES (PS-ALL-SLOT-NAMES PS)                    (CDR SLOT-NAMES)))            ((NULL SLOT-NAMES))          (IF (MEMBER (CAR SLOT-NAMES)                     (CDR SLOT-NAMES)                     :TEST                     #'EQ)              (ERROR "The slot ~s is repeated in ~s." (CAR SLOT-NAMES)                     (PS-ALL-SLOT-NAMES PS))))))(DEFUN INSERT-INCLUDED-SLOT (NEW-SLOT SUPER-SLOTS PS)   (IL:* IL:|;;| "Replaces the slot in super-slots that corresponds to new-slot with new-slot")   (FLET ((SAME-SLOT (SLOT1 SLOT2)                 (EQ (PSLOT-NAME SLOT1)                     (PSLOT-NAME SLOT2))))         (LET* ((TAIL (MEMBER NEW-SLOT SUPER-SLOTS :TEST #'SAME-SLOT))                (OLD-SLOT (CAR TAIL)))               (IF (NOT TAIL)                   (ERROR "included slot ~S not present in included structure ~S" (PSLOT-NAME                                                                                          NEW-SLOT)                          (PS-INCLUDE PS)))               (IL:* IL:|;;| " verify the inclusion rules.")               (IF (AND (PSLOT-READ-ONLY OLD-SLOT)                        (NOT (PSLOT-READ-ONLY NEW-SLOT)))                   (ERROR "included slot ~s must be read-only.  It is in included structure ~S"                          (PSLOT-NAME NEW-SLOT)                          (PS-INCLUDE PS)))               (DEFSTRUCT-ASSERT-SUBTYPEP (PSLOT-TYPE NEW-SLOT)                      (PSLOT-TYPE OLD-SLOT)                      ("Included slot ~S's type ~s is not a subtype of original slot type ~s"                       (PSLOT-NAME NEW-SLOT)                       (PSLOT-TYPE NEW-SLOT)                       (PSLOT-TYPE OLD-SLOT)))               (IL:* IL:|;;| "finally, we can replace the slot")               (RPLACA TAIL NEW-SLOT))))(DEFUN MERGE-SLOTS (INCLUDED-SLOTS SUPER-SLOTS PS)   (IL:* IL:|;;| "Takes the included-slots, and the local slots, then merges them with the slots from the super that aren't shadowed.")   (IL:* IL:|;;| "go through the slots from the super and replace the super's def with the overriding included-slot")   (DOLIST (NEW-SLOT INCLUDED-SLOTS)       (INSERT-INCLUDED-SLOT NEW-SLOT SUPER-SLOTS PS))   SUPER-SLOTS)(DEFUN NAME-SLOT (PS)   (IL:* IL:|;;| "Returns a parsed-slot representing the 'name' field of a structure")   (PARSE-SLOT `(SI::--STRUCTURE-NAME-SLOT-- ',(PS-NAME PS)                           :READ-ONLY T)          NIL))(DEFUN DUMMY-SLOT ()   (PARSE-SLOT `(SI::--STRUCTURE-DUMMY-SLOT-- NIL :READ-ONLY T :TYPE IL:XPOINTER)          NIL))(DEFUN OFFSET-SLOT ()   (PARSE-SLOT `(,(GENSYM)                     (IL:* IL:|;;| "to make sure that names are unique, so that when the inspector works on :type list, there will be a unique name.")                     NIL :READ-ONLY T)          NIL))(IL:* IL:|;;;| "data layout code")(DEFUN ASSIGN-STRUCTURE-REPRESENTATION (PS)   (IL:* IL:|;;|  "Determines the descriptors and returns a form to create the datatype at loadtime.")   (IL:* IL:|;;| "Side effects ps.")   (LET ((LOCAL-SLOTS (PS-LOCAL-SLOTS PS)))        (IL:* IL:|;;| "Local slots no longer need be recorded")        (SETF (PS-LOCAL-SLOTS PS)              NIL)        (CASE (PS-TYPE PS)            ((VECTOR LIST)                (IL:* IL:|;;| "just assign the the field descriptors (offsets).  No run-time declaration is needed since the representation is known (list and vector)")               (ASSIGN-SLOT-OFFSET PS)               NIL)            (DATATYPE (LET* ((LOCAL-FIELD-SPECS (MAPCAR #'(LAMBDA (SLOT)                                                                 (%STRUCTURE-TYPE-TO-FIELDSPEC                                                                  (PSLOT-TYPE SLOT)))                                                       LOCAL-SLOTS))                             (SUPER-FIELD-SPECS (IF (PS-INCLUDE PS)                                                    (PS-FIELD-SPECIFIERS (PARSED-STRUCTURE                                                                          (PS-INCLUDE PS)))))                             (ALL-FIELD-SPECS (APPEND SUPER-FIELD-SPECS LOCAL-FIELD-SPECS))                             (STRUCTURE-NAME (PS-NAME PS)))                            (SETF (PS-FIELD-SPECIFIERS PS)                                  ALL-FIELD-SPECS)                            (XCL:DESTRUCTURING-BIND                             (LENGTH &REST FIELD-DESCRIPTORS)                             (IL:TRANSLATE.DATATYPE (IF (NOT (PS-TEMPLATE PS))                                                        STRUCTURE-NAME)                                    ALL-FIELD-SPECS)                             (IL:* IL:|;;| "Note that this side-effects ps")                             (ASSIGN-FIELD-DESCRIPTORS PS FIELD-DESCRIPTORS)                             (IL:* IL:|;;| "save the descriptors? No, even though the ones in the dtd are for the current world, not the crosscompiling world.  They are recomputed each redeclaration by TRANSLATE.DATATYPE")                             (IF (NOT (PS-TEMPLATE PS))                                 `((SI::%STRUCTURE-DECLARE-DATATYPE ',STRUCTURE-NAME                                          ',ALL-FIELD-SPECS                                          ',FIELD-DESCRIPTORS                                          ,LENGTH                                          ',(OR (PS-INCLUDE PS)                                                %DEFAULT-STRUCTURE-INCLUDE))))))))))(DEFUN COERCE-TYPE (ELEMENT-TYPE)   (IL:* IL:|;;| "As in IL:%canonical-cml-type -- Returns the types (t, string-char, single-float, IL:xpointer, (unsigned-byte n) and (signed-byte n)")   (IF (CONSP ELEMENT-TYPE)       (CASE (CAR ELEMENT-TYPE)           (UNSIGNED-BYTE               (IL:* IL:|;;| "Let the bits hang out")              (IF (> (CADR ELEMENT-TYPE)                     16)                  T                  ELEMENT-TYPE))           (SIGNED-BYTE (IL:%GET-ENCLOSING-SIGNED-BYTE ELEMENT-TYPE))           (MOD               (IL:* IL:|;;| "From cmlarray -- reduces (mod n) to (unsigned-byte m)")              (IL:%REDUCE-MOD ELEMENT-TYPE))           (INTEGER               (IL:* IL:|;;| "From cmlarray -- reduces (integer x y) to (signed-byte m)")              (IL:%REDUCE-INTEGER ELEMENT-TYPE))           (MEMBER (IF (AND (EQ 2 (LENGTH (CDR ELEMENT-TYPE)))                            (EVERY #'(LAMBDA (ELT)                                            (OR (EQ ELT T)                                                (EQ ELT NIL)))                                   (CDR ELEMENT-TYPE)))                       ELEMENT-TYPE                       T))           (T               (IL:* IL:|;;| "Attempt type expansion")              (LET ((EXPANDER (TYPE-EXPANDER (CAR ELEMENT-TYPE))))                   (IF EXPANDER                       (COERCE-TYPE (TYPE-EXPAND ELEMENT-TYPE EXPANDER))                       T))))       (CASE ELEMENT-TYPE           ((T IL:FULLPOINTER IL:XPOINTER IL:FULLXPOINTER SINGLE-FLOAT STRING-CHAR) ELEMENT-TYPE)           (IL:POINTER T)           ((FLOAT SHORT-FLOAT LONG-FLOAT DOUBLE-FLOAT) 'SINGLE-FLOAT)           (FIXNUM               (IL:* IL:|;;|             "Could be (signed-byte 32) -- but pointer representation is more efficient")              T)           (CHARACTER 'STRING-CHAR)           (BIT '(UNSIGNED-BYTE 1))           (T (LET ((EXPANDER (TYPE-EXPANDER ELEMENT-TYPE)))                   (IF EXPANDER                       (COERCE-TYPE (TYPE-EXPAND ELEMENT-TYPE EXPANDER))                       T))))))(DEFUN %STRUCTURE-TYPE-TO-FIELDSPEC (ELEMENT-TYPE)(IL:* IL:|;;;| "Returns the most specific InterLisp type descriptor which will hold a given type.")(IL:* IL:|;;;| "Note: This function accepts only a limited subset of the Common Lisp type specifiers: T FLOAT SINGLE-FLOAT FIXNUM BIT (MOD n) (UNSIGNED-BYTE n) INTEGER (INTEGER low high) IL:XPOINTER DOUBLE-IL:POINTER")   (LET ((COERCED-TYPE (COERCE-TYPE ELEMENT-TYPE)))        (IF (NOT (CONSP COERCED-TYPE))            (CASE COERCED-TYPE                ((T STRING-CHAR) 'IL:POINTER)                ((IL:FULLPOINTER IL:XPOINTER IL:FULLXPOINTER) COERCED-TYPE)                ((SINGLE-FLOAT) 'IL:FLOATP)                (OTHERWISE 'IL:POINTER))            (CASE (CAR COERCED-TYPE)                (UNSIGNED-BYTE `(IL:BITS ,(CADR COERCED-TYPE)))                (SIGNED-BYTE (CASE (CADR COERCED-TYPE)                                 (16 'IL:SIGNEDWORD)                                 (32 'IL:FIXP)                                 (OTHERWISE 'IL:POINTER)))                (MEMBER 'IL:FLAG)                (OTHERWISE 'IL:POINTER)))))(DEFUN ASSIGN-FIELD-DESCRIPTORS (PS FIELD-DESCRIPTORS)   (IL:* IL:|;;| "Assigns the field descriptors for accessing each slot of the structure")   (IF (NOT (EQ (PS-TYPE PS)                'DATATYPE))       (ERROR "Not a structure of type datatype"))   (DO ((F FIELD-DESCRIPTORS (CDR F))        (SLOT (PS-ALL-SLOTS PS)              (CDR SLOT)))       ((NULL F))     (SETF (PSLOT-FIELD-DESCRIPTOR (CAR SLOT))           (CAR F)))   (IL:* IL:|;;| "DON'T record where the pointer fields are for the circle printer.  it will do this when it needs them.")   (IL:* IL:|;;| "(setf (ps-pointer-descriptors ps) (mapcan #'(lambda (descriptor) (case (caddr descriptor) ((il:pointer il:fullpointer il:xpointer il:fullxpointer) (list descriptor)))) field-descriptors))")   )(DEFUN STRUCTURE-POINTER-SLOTS (STRUCTURE-NAME)   (IL:* IL:|;;| "record where the pointer fields are for the circle printer.")   (LET ((PS (PARSED-STRUCTURE STRUCTURE-NAME)))        (OR (PS-POINTER-DESCRIPTORS PS)            (SETF (PS-POINTER-DESCRIPTORS PS)                  (MAPCAN #'(LAMBDA (DESCRIPTOR)                                   (CASE (CADDR DESCRIPTOR)                                       ((IL:POINTER IL:FULLPOINTER IL:XPOINTER IL:FULLXPOINTER)                                           (LIST DESCRIPTOR))))                         (MAPCAR #'PSLOT-FIELD-DESCRIPTOR (PS-ALL-SLOTS PS)))))))(IL:* IL:|;;;| "type system hooks")(DEFUN PROCESS-TYPE (PS)(IL:* IL:|;;;| "adds the structure to the common lisp type system and defines the predicate, if any.")   (IF (NOT (PS-TEMPLATE PS))       (LET*        ((NAME (PS-NAME PS))         (TYPE (PS-TYPE PS))         (PREDICATE (PS-PREDICATE PS))         (PREDICATE-BODY (AND PREDICATE (PREDICATE-BODY PS 'OBJECT)))         (EXPORTNAME (PS-EXPORT PS)))        (IF (AND PREDICATE (OR (EQ EXPORTNAME T)                               (MEMBER :PREDICATE EXPORTNAME)))            (EXPORT PREDICATE))               (IL:* IL:\;                                                 "Edited by TT(13-June-90) Export Option Follow up")        `(,@(COND               ((EQ TYPE 'DATATYPE)                `((EVAL-WHEN (EVAL LOAD COMPILE)                         (SETF (TYPE-EXPANDER ',NAME)                               'TYPE-EXPAND-STRUCTURE))))               ((PS-NAMED PS)                `((EVAL-WHEN (EVAL LOAD COMPILE)                         (SETF (TYPE-EXPANDER ',NAME)                               'TYPE-EXPAND-NAMED-STRUCTURE)))))          ,@(WHEN PREDICATE                (LET* ((INLINE (PS-INLINE PS))                       (INLINE-P (AND (EQ TYPE 'DATATYPE)                                      (OR (EQ INLINE :ONLY)                                          (AND (CONSP INLINE)                                               (MEMBER :PREDICATE INLINE :TEST #'EQ)))))                       (INLINE-ONLY-P (EQ INLINE :ONLY)))                      (IF (NULL INLINE-P)                          (IL:* IL:|;;| "Flush optimizer (a bit extreme, but also gets rid of old definline optimizers from the old defstruct")                          (SETF (COMPILER:OPTIMIZER-LIST PREDICATE)                                NIL))                      `(,@(IF (NOT INLINE-ONLY-P)                              `((DEFUN ,PREDICATE (OBJECT)                                   ,PREDICATE-BODY)))                        ,@(IF INLINE-P                              `((EVAL-WHEN (EVAL LOAD COMPILE)                                       (ESTABLISH-PREDICATE ',(PS-NAME PS))))))))))))(DEFUN PREDICATE-BODY (PS ARG)   (LET ((PREDICATE (PS-PREDICATE PS))         (TYPE (PS-TYPE PS)))        (CASE TYPE            (DATATYPE                (IL:* IL:|;;| "for datatypes, always create a predicate.  Use typep")               `(TYPEP ,ARG ',(PS-NAME PS)))            (OTHERWISE                (IL:* IL:|;;| "vectors and lists can only have a predicate if they are named")               (IF (NOT (PS-NAMED PS))                   (ERROR "The predicate ~s may not be specified for ~s because it is not :name'd"                           PREDICATE (PS-NAME PS)))               `(AND (TYPEP ,ARG ',(IF (EQ TYPE 'LIST)                                       'CONS                                       'VECTOR))                     (EQ ,(IF (EQ TYPE 'LIST)                              `(NTH ,(PS-NAME-SLOT-POSITION PS)                                    ,ARG)                              `(AREF ,ARG ,(PS-NAME-SLOT-POSITION PS)))                         ',(PS-NAME PS)))))))(DEFUN TYPE-EXPAND-STRUCTURE (TYPE-FORM)   `(:DATATYPE ,(CAR TYPE-FORM)))(DEFUN TYPE-EXPAND-NAMED-STRUCTURE (TYPE-FORM)   `(SATISFIES ,(PS-PREDICATE (PARSED-STRUCTURE (CAR TYPE-FORM)))))(DEFUN PS-NAME-SLOT-POSITION (PS)   "returns the offset of the name slot for ps."   (LET* ((INCLUDE (PS-INCLUDE PS))          (SUPER-SLOTS (AND INCLUDE (PS-ALL-SLOTS (PARSED-STRUCTURE INCLUDE)))))         (+ (PS-INITIAL-OFFSET PS)            (LENGTH SUPER-SLOTS))))(DEFUN DEFAULT-PREDICATE-NAME (STRUCTURE-NAME)   (VALUES (INTERN (CONCATENATE 'STRING (STRING STRUCTURE-NAME)                          "-P"))))(DEFUN DEFSTRUCT-SHARED-PREDICATE-OPTIMIZER (FORM &OPTIONAL ENVIRONMENT CONTEXT)   (XCL:DESTRUCTURING-BIND (PREDICATE OBJECT)          FORM          (LET ((NAME (GETHASH PREDICATE *DEFSTRUCT-INFO-CACHE*)))               (IF (NULL NAME)                   (SETQ NAME (CACHE-PREDICATE-INFO PREDICATE)))               (IF NAME                   `(TYPEP ,OBJECT ',NAME)                   COMPILER:PASS))))(DEFUN CACHE-PREDICATE-INFO (PREDICATE)   (IL:* IL:|;;| "Establishes a shared a shared optimizer for a defstruct predicate")   (LET ((PS (GET-PS-FROM-PREDICATE PREDICATE T)))        (WHEN PS            (SETF (GETHASH PREDICATE *DEFSTRUCT-INFO-CACHE*)                  (PS-NAME PS)))))(DEFCONSTANT %FUNCTION-DEFINING-FORM-KEYWORDS '(:ACCESSOR :COPIER :PREDICATE :BOA-CONSTRUCTOR                                                           :CONSTRUCTOR)                                                                                       "all the legal contexts for function-defining-form in defstruct")(IL:* IL:|;;;| "accessors and setfs")(DEFUN SETF-NAME (ACCESSOR-NAME)   "produces the name of the setf function for this accessor"   (XCL:PACK (LIST '%%SETF- ACCESSOR-NAME)))(DEFUN ACCESSOR-BODY (SLOT ARGUMENT STRUCTURE-TYPE &OPTIONAL (NO-TYPE-CHECK NIL))   (IL:* IL:|;;| "Returns a form which fetches slot from argument")   (ECASE STRUCTURE-TYPE       (DATATYPE `(,(IF NO-TYPE-CHECK                        'IL:FFETCHFIELD                        'IL:FETCHFIELD)                   ',(PSLOT-FIELD-DESCRIPTOR SLOT)                   ,ARGUMENT))       (LIST `(NTH ,(PSLOT-FIELD-DESCRIPTOR SLOT)                   ,ARGUMENT))       (VECTOR `(AREF ,ARGUMENT ,(PSLOT-FIELD-DESCRIPTOR SLOT)))))(DEFUN PROCESS-ACCESSORS (PS)   (IF (NOT (EQ (PS-INLINE PS)                :ONLY))       (IF COMPILER::*NEW-COMPILER-IS-EXPANDING*           `((ESTABLISH-ACCESSORS ',(PS-NAME PS)))           `((EVAL-WHEN (EVAL)                    (ESTABLISH-ACCESSORS ',(PS-NAME PS)))             (EVAL-WHEN (LOAD)                    ,@(DEFINE-ACCESSORS PS))))))(DEFUN ESTABLISH-ACCESSORS (PS-NAME)   (IL:* IL:|;;| "Makes a closure for every accessor ")   (LET* ((PS (PARSED-STRUCTURE PS-NAME))          (STRUCTURE-TYPE (PS-TYPE PS)))         (MAPCAN #'(LAMBDA (SLOT)                          (LET ((ACCESSOR (PSLOT-ACCESSOR SLOT))                                (EXPORTNAME (PS-EXPORT PS)))                               (WHEN ACCESSOR                                   (IF (OR (EQ EXPORTNAME T)                                           (MEMBER :ACCESSOR EXPORTNAME))                                       (EXPORT ACCESSOR))                                                  (IL:* IL:\;                                                 "Edited by TT(13-June-90) Export Option Follow up ")                                   (SETF (SYMBOL-FUNCTION ACCESSOR)                                         (%MAKE-ACCESSOR-CLOSURE SLOT STRUCTURE-TYPE)))))                (PS-ALL-SLOTS PS))))(DEFUN DEFINE-ACCESSORS (PS)   (IL:* IL:|;;| "Returns the forms that when evaluated, define the accessors")   (IL:* IL:|;;| "Only used by the byte compiler")   (LET ((NAME (PS-NAME PS))         (STRUCTURE-TYPE (PS-TYPE PS)))        (IL:* IL:|;;|       "the arg-name must be the structure name, since it is already in the raw-accessors.")        (MAPCAN #'(LAMBDA (SLOT)                         (LET ((ACCESSOR (PSLOT-ACCESSOR SLOT))                               (EXPORTNAME (PS-EXPORT PS)))                              (WHEN ACCESSOR                                  (IF (OR (EQ EXPORTNAME T)                                          (MEMBER :ACCESSOR EXPORTNAME))                                      (EXPORT ACCESSOR))                                                  (IL:* IL:\;                                                "Edited by TT(13-June-90) Export Option follow-up. ")                                  `((DEFUN ,ACCESSOR (,NAME)                                       ,(ACCESSOR-BODY SLOT NAME STRUCTURE-TYPE))))))               (PS-ALL-SLOTS PS))))(DEFUN DEFSTRUCT-SHARED-ACCESSOR-OPTIMIZER (FORM &OPTIONAL ENVIRONMENT CONTEXT)   (XCL:DESTRUCTURING-BIND (ACCESSOR OBJECT)          FORM          (LET ((SLOT-INFO (GETHASH ACCESSOR *DEFSTRUCT-INFO-CACHE*)))               (IF (NULL SLOT-INFO)                   (SETQ SLOT-INFO (CACHE-SLOT-INFO ACCESSOR)))               (IF SLOT-INFO                   (XCL:DESTRUCTURING-BIND (TYPE SLOT FAST-ACCESSORS-P)                          SLOT-INFO                          (ACCESSOR-BODY SLOT OBJECT TYPE FAST-ACCESSORS-P))                   'COMPILER:PASS))))(DEFINE-SHARED-SETF-MACRO DEFSTRUCT-SHARED-SETF-EXPANDER ACCESSOR (DATUM) (NEW-VALUE)   (IL:* IL:|;;| "Shared setf expander for all defstruct slot accessors ")   (LET ((SLOT-INFO (GETHASH ACCESSOR *DEFSTRUCT-INFO-CACHE*)))        (WHEN (NULL SLOT-INFO)            (SETQ SLOT-INFO (CACHE-SLOT-INFO ACCESSOR)))        (XCL:DESTRUCTURING-BIND         (TYPE SLOT FAST-ACCESSSOR-P)         SLOT-INFO         (LET ((DESCRIPTOR (PSLOT-FIELD-DESCRIPTOR SLOT)))              (ECASE TYPE                  (DATATYPE `(,(IF FAST-ACCESSSOR-P                                   'IL:FREPLACEFIELD                                   'IL:REPLACEFIELD)                              ',DESCRIPTOR                              ,DATUM                              ,NEW-VALUE))                  (LIST `(SETF (NTH ,DESCRIPTOR ,DATUM)                               ,NEW-VALUE))                  (VECTOR (MACROLET ((SIMPLE-P (X)                                            `(OR (SYMBOLP ,X)                                                 (CONSTANTP ,X))))                                 (IF (AND (SIMPLE-P DATUM)                                          (SIMPLE-P NEW-VALUE))                                     `(XCL:ASET ,NEW-VALUE ,DATUM ,DESCRIPTOR)                                     (LET ((D (GENSYM))                                           (V (GENSYM)))                                          `(LET ((,D ,DATUM)                                                 (,V ,NEW-VALUE))                                                (XCL:ASET ,V ,D ,DESCRIPTOR)))))))))))(DEFUN CACHE-SLOT-INFO (ACCESSOR)(IL:* IL:|;;;| "saves the internal accessors in a hash table so that setf methods can be generated at interpret/compile time.")   (LET* ((PS (GET-PS-FROM-ACCESSOR ACCESSOR))          (FAST-ACCESSORS (PS-FAST-ACCESSORS PS)))         (SETF (GETHASH ACCESSOR *DEFSTRUCT-INFO-CACHE*)     (IL:* IL:\;                                                    "Make a copy of the slot to keep refcounts down")               (LIST (PS-TYPE PS)                     (COPY-TREE (GET-SLOT-DESCRIPTOR-FROM-PS ACCESSOR PS))                     (AND FAST-ACCESSORS T)))))(DEFUN %MAKE-ACCESSOR-CLOSURE (SLOT STRUCTURE-TYPE)   (LET ((DESCRIPTOR (PSLOT-FIELD-DESCRIPTOR SLOT)))        (ECASE STRUCTURE-TYPE            (DATATYPE (XCL:DESTRUCTURING-BIND                       (TYPENAME OFFSET FIELD-DESCRIPTOR)                       DESCRIPTOR                       (CASE FIELD-DESCRIPTOR                           ((IL:POINTER IL:FULLPOINTER IL:XPOINTER IL:FULLXPOINTER) (                                                                             %MAKE-POINTER-ACCESSOR                                                                                     TYPENAME OFFSET))                           (IL:FLOATP (%MAKE-FLOAT-ACCESSOR TYPENAME OFFSET))                           (IL:FIXP (%MAKE-FIXP-ACCESSOR TYPENAME OFFSET))                           (OTHERWISE                               (IL:* IL:|;;| "Must be a bit field")                              (LET* ((FIELD-TYPE (CAR FIELD-DESCRIPTOR))                                     (FIELD-ARG (CDR FIELD-DESCRIPTOR))                                     (SIZE (1+ (LOGAND FIELD-ARG 15)))                                     (POSITION (- 16 (+ SIZE (ASH FIELD-ARG -4)))))                                    (ECASE FIELD-TYPE                                        (IL:BITS (IF (EQ SIZE 16)                                                     (%MAKE-WORD-ACCESSOR TYPENAME OFFSET)                                                     (%MAKE-BIT-ACCESSOR TYPENAME OFFSET POSITION                                                            SIZE)))                                        (IL:FLAGBITS (IF (EQ SIZE 1)                                                         (%MAKE-FLAG-ACCESSOR TYPENAME OFFSET                                                                 POSITION)                                                         (ERROR "Illegal field descriptor: ~s"                                                                 DESCRIPTOR)))                                        (IL:SIGNEDBITS (IF (EQ SIZE 16)                                                           (%MAKE-SMALL-FIXP-ACCESSOR TYPENAME                                                                   OFFSET)                                                           (IL:* IL:|;;|                                     "Would be better to say here \"Inconvenient field descriptor\"")                                                           (ERROR "Illegal field descriptor: ~s"                                                                   DESCRIPTOR)))))))))            (LIST (%MAKE-LIST-ACCESSOR DESCRIPTOR))            (VECTOR (%MAKE-ARRAY-ACCESSOR DESCRIPTOR)))))(DEFUN %MAKE-LIST-ACCESSOR (OFFSET)   #'(LAMBDA (LIST)            (NTH OFFSET LIST)))(DEFUN %MAKE-ARRAY-ACCESSOR (OFFSET)   #'(LAMBDA (VECTOR)            (AREF VECTOR OFFSET)))(DEFUN %MAKE-POINTER-ACCESSOR (TYPE OFFSET)   (IF TYPE       #'(LAMBDA (OBJECT)                (IF (NOT (IL:\\INSTANCE-P OBJECT TYPE))                    (ERROR "Arg not ~s: ~s" TYPE OBJECT)                    (IL:\\GETBASEPTR OBJECT OFFSET)))       #'(LAMBDA (OBJECT)                (IL:\\GETBASEPTR OBJECT OFFSET))))(DEFUN %MAKE-BIT-ACCESSOR (TYPE WORD-OFFSET OFFSET SIZE)   (IF TYPE       #'(LAMBDA (OBJECT)                (IF (NOT (IL:\\INSTANCE-P OBJECT TYPE))                    (ERROR "Arg not ~s: ~s" TYPE OBJECT)                    (LDB (BYTE SIZE OFFSET)                         (IL:\\GETBASE OBJECT WORD-OFFSET))))       #'(LAMBDA (OBJECT)                (LDB (BYTE SIZE OFFSET)                     (IL:\\GETBASE OBJECT WORD-OFFSET)))))(DEFUN %MAKE-FLAG-ACCESSOR (TYPE WORD-OFFSET OFFSET)   (IF TYPE       #'(LAMBDA (OBJECT)                (IF (NOT (IL:\\INSTANCE-P OBJECT TYPE))                    (ERROR "Arg not ~s: ~s" TYPE OBJECT)                    (NOT (EQ 0 (LDB (BYTE 1 OFFSET)                                    (IL:\\GETBASE OBJECT WORD-OFFSET))))))       #'(LAMBDA (OBJECT)                (NOT (EQ 0 (LDB (BYTE 1 OFFSET)                                (IL:\\GETBASE OBJECT WORD-OFFSET)))))))(DEFUN %MAKE-WORD-ACCESSOR (TYPE OFFSET)   (IF TYPE       #'(LAMBDA (OBJECT)                (IF (NOT (IL:\\INSTANCE-P OBJECT TYPE))                    (ERROR "Arg not ~s: ~s" TYPE OBJECT)                    (IL:\\GETBASE OBJECT OFFSET)))       #'(LAMBDA (OBJECT)                (IL:\\GETBASE OBJECT OFFSET))))(DEFUN %MAKE-FIXP-ACCESSOR (TYPE OFFSET)   (IF TYPE       #'(LAMBDA (OBJECT)                (IF (NOT (IL:\\INSTANCE-P OBJECT TYPE))                    (ERROR "Arg not ~s: ~s" TYPE OBJECT)                    (IL:\\GETBASEFIXP OBJECT OFFSET)))       #'(LAMBDA (OBJECT)                (IL:\\GETBASEFIXP OBJECT OFFSET))))(DEFUN %MAKE-SMALL-FIXP-ACCESSOR (TYPE OFFSET)   (IF TYPE       #'(LAMBDA (OBJECT)                (IF (NOT (IL:\\INSTANCE-P OBJECT TYPE))                    (ERROR "Arg not ~s: ~s" TYPE OBJECT)                    (IL:\\GETBASESMALL-FIXP OBJECT OFFSET)))       #'(LAMBDA (OBJECT)                (IL:\\GETBASESMALL-FIXP OBJECT OFFSET))))(DEFUN %MAKE-FLOAT-ACCESSOR (TYPE OFFSET)   (IF TYPE       #'(LAMBDA (OBJECT)                (IF (NOT (IL:\\INSTANCE-P OBJECT TYPE))                    (ERROR "Arg not ~s: ~s" TYPE OBJECT)                    (IL:\\GETBASEFLOATP OBJECT OFFSET)))       #'(LAMBDA (OBJECT)                (IL:\\GETBASEFLOATP OBJECT OFFSET))))(IL:* IL:|;;;| "constructor definition code")(DEFUN DEFINE-CONSTRUCTORS (PS)   (IL:* IL:|;;| "Returns the forms that when evaluated, define the constructors")   (IF (NOT (PS-TEMPLATE PS))       (LET*        ((CONSTRUCTORS (PS-CONSTRUCTORS PS))         (SLOTS (PS-ALL-SLOTS PS))         (RESULT-ARG (PS-NAME PS))         (ALL-BOAS? (EVERY #'BOA-CONSTRUCTOR-P CONSTRUCTORS))         (EXPORTNAME (PS-EXPORT PS)))        (IF (OR (EQ EXPORTNAME T)                (MEMBER :CONSTRUCTOR EXPORTNAME))            (EXPORT CONSTRUCTORS))            (IL:* IL:\;                                                 "Edited by TT(13-June-90) Export Option Follow up")        (COND           (ALL-BOAS?                   (IL:* IL:|;;| "don't bother building the arglist etc.")                  (MAPCAR #'(LAMBDA (CONSTRUCTOR)                                   (DEFINE-BOA-CONSTRUCTOR CONSTRUCTOR PS))                         CONSTRUCTORS))           (T (LET* ((ARGUMENT-LIST (BUILD-CONSTRUCTOR-ARGLIST SLOTS))                     (SLOT-SETFS (BUILD-CONSTRUCTOR-SLOT-SETFS SLOTS ARGUMENT-LIST PS)))                    (XCL:WITH-COLLECTION                     (DOLIST (CONSTRUCTOR CONSTRUCTORS)                         (XCL:COLLECT (COND                                         ((BOA-CONSTRUCTOR-P CONSTRUCTOR)                                          (DEFINE-BOA-CONSTRUCTOR CONSTRUCTOR PS))                                         (T                                             (IL:* IL:|;;|                    "keep the name of a standard constructor, if any, so that the #s form can work.")                                            (SETF (PS-STANDARD-CONSTRUCTOR PS)                                                  CONSTRUCTOR)                                            (IL:* IL:|;;|           "since we just built the object we're setting fields of, we don't need to type check it.")                                            `(DEFUN ,CONSTRUCTOR (&KEY ,@ARGUMENT-LIST)                                                (LET ((,RESULT-ARG ,(RAW-CONSTRUCTOR PS)))                                                     ,@SLOT-SETFS                                                     ,RESULT-ARG)))))))))))))(DEFUN DEFINE-BOA-CONSTRUCTOR (NAME&ARGLIST PS)   (LET* ((CONSTRUCTOR-NAME (CAR NAME&ARGLIST))          (ARGLIST (CADR NAME&ARGLIST))          (NEW-ARGUMENT-LIST (BOA-ARG-LIST-WITH-INITIAL-VALUES ARGLIST PS))          (RESULT-ARG (PS-NAME PS))          (SLOT-SETFS (BOA-SLOT-SETFS RESULT-ARG (ARGUMENT-NAMES NEW-ARGUMENT-LIST)                             PS)))         `(DEFUN ,CONSTRUCTOR-NAME ,NEW-ARGUMENT-LIST             (LET ((,RESULT-ARG ,(RAW-CONSTRUCTOR PS)))                  ,@SLOT-SETFS                  ,RESULT-ARG))))(DEFUN ARGUMENT-NAMES (ARG-LIST)   (MAPCAN #'(LAMBDA (ARG)                    (COND                       ((CONSP ARG)                        (LIST ARG))                       ((MEMBER ARG LAMBDA-LIST-KEYWORDS)                        NIL)                       (T (LIST (LIST ARG :REQUIRED-ARG)))))          ARG-LIST))(DEFUN BOA-ARG-LIST-WITH-INITIAL-VALUES (ARG-LIST PS)   (LET ((NEW-ARG-LIST (COPY-TREE ARG-LIST))         (SLOTS (PS-ALL-SLOTS PS)))        (IL:* IL:|;;| "for all the args from &optional up to &rest or &aux get the default value.")        (IL:FOR ARG-TAIL IL:ON (CDR (MEMBER '&OPTIONAL NEW-ARG-LIST))           IL:DO (COND                        ((MEMBER (CAR ARG-TAIL)                                LAMBDA-LIST-KEYWORDS)                         (IL:* IL:|;;| "we have found an ampersand arg, we're done the optionals.")                         (RETURN))                        (T (LET ((OPTIONAL (CAR ARG-TAIL)))                                (SETF (CAR ARG-TAIL)                                      (COND                                         ((MEMBER OPTIONAL '(&REST &AUX))                                          (IL:* IL:|;;|                                         "we have hit the end of the optionals, just return.")                                          (RETURN))                                         ((MEMBER OPTIONAL LAMBDA-LIST-KEYWORDS)                                          (IL:* IL:|;;| "illegal keyword here")                                          (ERROR                                             "~S cannot appear in a BOA constructor as it does in ~S."                                                 OPTIONAL ARG-LIST))                                         ((SYMBOLP OPTIONAL)                                          (LET ((INTIAL-VALUE-FORM (PSLOT-INITIAL-VALUE (FIND-SLOT                                                                                         OPTIONAL                                                                                          SLOTS))))                                               (IF INTIAL-VALUE-FORM                                                   `(,OPTIONAL ,INTIAL-VALUE-FORM)                                                   `(,OPTIONAL NIL ,(IL:GENSYM)))))                                         ((AND (CONSP OPTIONAL)                                               (CDR OPTIONAL))                                          (IL:* IL:|;;| "already a default just leave it alone")                                          OPTIONAL)                                         ((CONSP OPTIONAL)                                          (LET ((INTIAL-VALUE-FORM (PSLOT-INITIAL-VALUE                                                                    (FIND-SLOT (CAR OPTIONAL)                                                                           SLOTS))))                                               (IF INTIAL-VALUE-FORM                                                   `(,(CAR OPTIONAL)                                                     ,INTIAL-VALUE-FORM)                                                   `(,(CAR OPTIONAL)                                                     NIL                                                     ,(IL:GENSYM)))))))))))        NEW-ARG-LIST))(DEFUN BOA-SLOT-SETFS (RESULT-ARG SLOT-NAMES PS)   (LET ((STRUCTURE-TYPE (PS-TYPE PS)))        (XCL:WITH-COLLECTION         (LET (SLOT-PLACE SLOT-NAME SLOT-ARGUMENT)              (DOLIST (SLOT (PS-ALL-SLOTS PS))                  (SETQ SLOT-NAME (PSLOT-NAME SLOT))                  (SETQ SLOT-PLACE (ACCESSOR-BODY SLOT RESULT-ARG STRUCTURE-TYPE T))                  (SETQ SLOT-ARGUMENT (ASSOC SLOT-NAME SLOT-NAMES :TEST #'EQ))                  (XCL:COLLECT (IF SLOT-ARGUMENT                                   (LET ((SUPPLIED-P (CADDR SLOT-ARGUMENT)))                                        (IF SUPPLIED-P                                            `(IF ,SUPPLIED-P                                                 (SETF ,SLOT-PLACE ,SLOT-NAME))                                            `(SETF ,SLOT-PLACE ,SLOT-NAME)))                                   `(SETF ,SLOT-PLACE ,(PSLOT-INITIAL-VALUE SLOT)))))))))(DEFUN FIND-SLOT (NAME SLOTS &OPTIONAL (DONT-ERROR NIL))   (DOLIST (SLOT SLOTS (OR DONT-ERROR (ERROR "slot ~s not found." NAME)))       (IF (EQ NAME (PSLOT-NAME SLOT))           (RETURN SLOT))))(DEFUN RAW-CONSTRUCTOR (PS)   (IL:* IL:|;;| "Returns a form which will make an instance of this structure w/o initialisation")   (ECASE (PS-TYPE PS)       (DATATYPE `(IL:NCREATE ',(PS-NAME PS)))       (LIST `(MAKE-LIST ,(PS-NUMBER-OF-SLOTS PS)))       (VECTOR `(MAKE-ARRAY '(,(PS-NUMBER-OF-SLOTS PS))                       :ELEMENT-TYPE                       ',(PS-VECTOR-TYPE PS)))))(DEFUN BUILD-CONSTRUCTOR-ARGLIST (SLOTS)   (IL:* IL:|;;| "Gathers the keywords and initial-values for (non BOA) constructors")   (MAPCAN #'(LAMBDA (SLOT)                    (LET* ((INIT-FORM (PSLOT-INITIAL-VALUE SLOT))                           (ARG-NAME (PSLOT-NAME SLOT))                           (KEYWORD-PAIR `(,(VALUES (INTERN (SYMBOL-NAME ARG-NAME)                                                           'KEYWORD))                                           ,(GENSYM))))                          (COND                             ((NOT (PSLOT-ACCESSOR SLOT))                              (IL:* IL:|;;|               "this is an invisible slot (name, initial-offset, etc.) don't generate a keyword arg")                              NIL)                             (INIT-FORM                                     (IL:* IL:|;;| "specify an initial value for the keyword arg")                                    `((,KEYWORD-PAIR ,INIT-FORM)))                             (T `((,KEYWORD-PAIR NIL ,(GENSYM)))))))          SLOTS))(DEFUN BUILD-CONSTRUCTOR-SLOT-SETFS (SLOTS ARGUMENT-LIST PS)   (IL:* IL:|;;| "Builds the setfs that initialize the slots in a constructor")   (LET ((STRUCTURE-TYPE (PS-TYPE PS))         (OBJECT-NAME (PS-NAME PS))         (ARGUMENT-LIST ARGUMENT-LIST))        (IL:* IL:|;;| "The argument list does not have arguments for \"invisible\" slots.")        (MAPCAR #'(LAMBDA (SLOT)                         (COND                            ((NOT (PSLOT-ACCESSOR SLOT))                             (IL:* IL:|;;|                            "invisible slot, so generate a setf to it's initial-value")                             `(SETF ,(ACCESSOR-BODY SLOT OBJECT-NAME STRUCTURE-TYPE T)                                    ,(PSLOT-INITIAL-VALUE SLOT)))                            (T (LET* ((ARGUMENT (POP ARGUMENT-LIST))                                      (KEYWORD-VAR-NAME (CADAR ARGUMENT))                                      (INITIAL-VALUE-FORM (CADR ARGUMENT)))                                     (IL:* IL:|;;|                    "since slots can be read-only, we setf the raw accessor, not the slot accessor.")                                     (IL:* IL:|;;| "Also, since we built the object in which we are setting fields, we use the internal-accessor without typecheck")                                     (IF INITIAL-VALUE-FORM                                         `(SETF ,(ACCESSOR-BODY SLOT OBJECT-NAME STRUCTURE-TYPE T                                                        )                                                ,KEYWORD-VAR-NAME)                                         `(IF ,(CADDR ARGUMENT)                                              (SETF ,(ACCESSOR-BODY SLOT OBJECT-NAME                                                             STRUCTURE-TYPE T)                                                    ,KEYWORD-VAR-NAME)))))))               SLOTS)))(DEFUN BOA-CONSTRUCTOR-P (CONSTRUCTOR)   (IL:* IL:|;;| "Returns t if the constructor is a By Order of Arguments constructor")   (CONSP CONSTRUCTOR))(DEFUN DEFAULT-CONSTRUCTOR-NAME (STRUCTURE-NAME)   (VALUES (INTERN (CONCATENATE 'STRING "MAKE-" (STRING STRUCTURE-NAME)))))(IL:* IL:|;;;| "copiers")(DEFUN DEFINE-COPIERS (PS)   (IL:* IL:|;;| "Returns the form that when evaluated, defines the copier")   (IF (NOT (PS-TEMPLATE PS))       (LET ((COPIER (PS-COPIER PS))             (RESULT-ARG 'NEW)             (FROM-ARG (PS-NAME PS)))            (IF COPIER                (MULTIPLE-VALUE-BIND (FROM-ARG-TYPE-CHECK TYPE-CHECK-SLOTS?)                       (BUILD-COPIER-TYPE-CHECK PS FROM-ARG)                       (LET ((SLOT-SETFS (BUILD-COPIER-SLOT-SETFS (PS-ALL-SLOTS PS)                                                (PS-TYPE PS)                                                FROM-ARG RESULT-ARG TYPE-CHECK-SLOTS?))                             (EXPORTNAME (PS-EXPORT PS)))                            (IF (OR (EQ EXPORTNAME T)                                    (MEMBER :COPIER EXPORTNAME))                                (EXPORT (PS-COPIER PS)))                                                  (IL:* IL:\;                                                 "Edited by TT(13-June-90) Export Option follow up")                            (IL:* IL:|;;|           "Since we just built the object we're setting fields of, we don't need to type check it.")                            `((DEFUN ,(PS-COPIER PS) (,FROM-ARG)                                 ,@FROM-ARG-TYPE-CHECK (LET ((,RESULT-ARG ,(RAW-CONSTRUCTOR                                                                            PS)))                                                            ,@SLOT-SETFS                                                            ,RESULT-ARG)))))))))(DEFUN BUILD-COPIER-SLOT-SETFS (SLOTS STRUCTURE-TYPE FROM-ARGUMENT TO-ARGUMENT TYPE-CHECK-SLOTS?)   "constructs the forms that copy each individual slot."   (IL:* IL:|;;| "build a series of forms that look like")   (IL:* IL:|;;| "(setf (structure-slot to-arg) (structure-slot from-arg))")   (MAPCAR #'(LAMBDA (SLOT)                    `(SETF ,(ACCESSOR-BODY SLOT TO-ARGUMENT STRUCTURE-TYPE T)                           ,(ACCESSOR-BODY SLOT FROM-ARGUMENT STRUCTURE-TYPE T)))          SLOTS))(DEFUN BUILD-COPIER-TYPE-CHECK (PS FROM-ARG)   (IL:* IL:|;;| "Constructs the type checking form at the beginning of the copier and decides whether individual slots need to be type-checked.")   (COND      ((EQ (PS-TYPE PS)           'DATATYPE)       (IL:* IL:|;;| "If something is a datatype type check the from-arg once at the beginning.  Don't check the individual accesses.")       (VALUES `((CHECK-TYPE ,FROM-ARG ,(PS-NAME PS)))              NIL))      ((PS-PREDICATE PS)       (IL:* IL:|;;| "if the structure has a predicate ,then call the predicate.")       (VALUES `((OR (,(PS-PREDICATE PS)                      ,FROM-ARG)                     (ERROR ,(FORMAT NIL "Arg not ~s: ~~S" (PS-NAME PS))                            ,FROM-ARG)))              NIL))      (T          (IL:* IL:|;;| "Otherwise, just use the type-checked slot access, so that at least the argument is assured to be a vector/list.")         (VALUES NIL T))))(IL:* IL:|;;;| "print functions")(DEFVAR %DEFAULT-PRINT-FUNCTION 'DEFAULT-STRUCTURE-PRINTER                                           "print function used when none is specified in a defstruct")(IL:* IL:|;;;| "internal stuff.")(DEFSETF IL:FFETCHFIELD IL:FREPLACEFIELD)(IL:* IL:|;;;| "utilities")(DEFMACRO DEFSTRUCT-ASSERT-SUBTYPEP (TYPE1 TYPE2 (ERROR-STRING . ERROR-ARGS)                                               &REST CERROR-ACTIONS)   (IL:* IL:|;;|  "Provides an interface for places where the implementor isn't sure that subtypep can be trusted")   (LET ((ERROR-STRING (OR ERROR-STRING "~S is not a subtype of ~S"))         (ERROR-ARGS (OR ERROR-ARGS (LIST TYPE1 TYPE2))))        `(MULTIPLE-VALUE-BIND (SUBTYPE? CERTAIN?)                (SUBTYPEP ,TYPE1 ,TYPE2)                (COND                   (SUBTYPE?                                 (IL:* IL:\; "it's ok, continue")                          T)                   (CERTAIN?                                 (IL:* IL:\;                                                            "subtypep says it sure, so blow up")                          (ERROR ,ERROR-STRING ,@ERROR-ARGS))                   (T                                        (IL:* IL:\;                                                 "subtypep isn't sure, so raise a continuable error")                      (CERROR "Assume subtypep should return t" ,(FORMAT NIL "Perhaps, ~a"                                                                         ERROR-STRING)                             ,@ERROR-ARGS)                      ,@CERROR-ACTIONS T)))))(IL:* IL:|;;;| "inspecting structures")(DEFUN STRUCTURE-OBJECT-P (OBJECT)   (TYPEP OBJECT 'STRUCTURE-OBJECT))(DEFUN INSPECT-STRUCTURE-OBJECT (STRUCTURE OBJECTTYPE WHERE)   "calls the system facilities with the appropriate slots and functions."   (IL:INSPECTW.CREATE STRUCTURE (PS-ALL-SLOTS (PARSED-STRUCTURE (TYPE-OF STRUCTURE)))          'STRUCTURE-OBJECT-INSPECT-FETCHFN          'STRUCTURE-OBJECT-INSPECT-STOREFN          'STRUCTURE-OBJECT-PROPCOMMANDFN NIL NIL (LET ((XCL:*PRINT-STRUCTURE* NIL))                                                       (CONCATENATE 'STRING (PRINC-TO-STRING                                                                                    STRUCTURE)                                                              " Inspector"))          NIL WHERE 'STRUCTURE-OBJECT-INSPECT-PROPPRINTFN))(DEFUN STRUCTURE-OBJECT-INSPECT-FETCHFN (OBJECT PROPERTY)   (IF (PSLOT-ACCESSOR PROPERTY)       (FUNCALL (PSLOT-ACCESSOR PROPERTY)              OBJECT)       (IL:FETCHFIELD (PSLOT-FIELD-DESCRIPTOR PROPERTY)              OBJECT)))(DEFUN STRUCTURE-OBJECT-INSPECT-PROPPRINTFN (PROPERTY DATUM)   (PSLOT-NAME PROPERTY))(DEFUN STRUCTURE-OBJECT-INSPECT-STOREFN (OBJECT PROPERTY NEWVALUE)   (IL:* IL:|;;|  "this effectively does (eval `(setf (,(pslot-accessor property) object) newvalue)) ")   (IF (PSLOT-ACCESSOR PROPERTY)       (EVAL `(SETF (,(PSLOT-ACCESSOR PROPERTY)                     ',OBJECT)                    ',NEWVALUE))       (IL:REPLACEFIELD (PSLOT-FIELD-DESCRIPTOR PROPERTY)              OBJECT NEWVALUE)))(DEFUN STRUCTURE-OBJECT-PROPCOMMANDFN (PROPERTY DATUM INSPECTOR-WINDOW)   (IF (AND (TYPEP DATUM 'STRUCTURE-OBJECT)            (PSLOT-READ-ONLY PROPERTY))       (IL:PROMPTPRINT "Can't set a read-only slot.")       (IL:DEFAULT.INSPECTW.PROPCOMMANDFN PROPERTY DATUM INSPECTOR-WINDOW)))(IL:* IL:|;;| "Defined last so functions required to load a defstruct are loaded first")(DEFSTRUCT (PS (:TYPE LIST)                   :NAMED)(IL:* IL:|;;;| "Contains the parsed information for a SINGLE structure type")   (IL:* IL:|;;| "most values are not defaulted here, because the defaults depend on other slot values (e.g. predicate depends on type and named.)  These defaults are installed in ensure-consistent-ps.")   (NAME)                                                    (IL:* IL:\;                                                            "The name of the structure")   (STANDARD-CONSTRUCTOR)                                    (IL:* IL:\;                                             "Contains the constructor to be used by the #s reader.")   (ALL-SLOT-NAMES)                                          (IL:* IL:\;                                                         "The slot-name list used by the inspector.")   (TYPE %DEFAULT-DEFSTRUCT-TYPE)                            (IL:* IL:\;                                                     "Is this structure a datatype, list or vector.")   (VECTOR-TYPE)                                             (IL:* IL:\;                                           "If its a vector, this is the element-type of the vector")   (INCLUDE NIL)                                             (IL:* IL:\;                                                            "The included structure, if any.")   (CONC-NAME)   (CONSTRUCTORS %NO-CONSTRUCTOR)                            (IL:* IL:\;   "A list of the constructors for this structure.  Boas have the argument list, not just the name.")   (PREDICATE %NO-PREDICATE)   (PRINT-FUNCTION)   (COPIER %NO-COPIER)   (NAMED NIL)   (INITIAL-OFFSET 0)   (LOCAL-SLOTS NIL)                                         (IL:* IL:\;                                    "The slot descriptors for slots present locally (not included).")   (ALL-SLOTS)                                               (IL:* IL:\;                  "The list of slot descriptors for every slot present in an instance of this slot.")   (INCLUDED-SLOTS)                                          (IL:* IL:\;                                                           "Slots specified in the :include option.")   (IL:* IL:|;;| "Redundant")   (DOCUMENTATION-STRING)   (IL:* IL:|;;| "Unused")   (FIELD-SPECIFIERS)                                        (IL:* IL:\; "The position of each slot in the structure.  For vectors and  list structures, it is just an offset.  For datatypes, it is a field-specifier for fetchield.")   (IL:* IL:|;;| "Unused")   (POINTER-DESCRIPTORS)                                     (IL:* IL:\; "the descriptors for all fields which the circle-printer must scan.  It is filled in the first time it is needed.")   (INLINE T)                                                (IL:* IL:\;                       "Flag telling whether or not functions built by defstruct are inline or not.")   (FAST-ACCESSORS NIL)                                      (IL:* IL:\; "Flag telling whether or not accessor functions should check the type of the object before slot accesses.")   (TEMPLATE NIL)                                            (IL:* IL:\; "As in IL:BLOCKRECORD. Implies type datatype, no copier, predicate or constructors, and fast accessors. No datatype is declared for this option.")   (EXPORT NIL)                                              (IL:* IL:\;                                                 "EXPORT indicates  export of Structure's functions")   )(DEFSTRUCT (PARSED-SLOT (:CONC-NAME PSLOT-)                            (:TYPE LIST))   "describes a single slot in a structure"   (NAME NIL :TYPE SYMBOL)   (INITIAL-VALUE NIL)   (TYPE %DEFAULT-SLOT-TYPE)   (READ-ONLY NIL)   FIELD-DESCRIPTOR ACCESSOR)(IL:* IL:|;;| "Mapping between names of generated functions and their associated structures")(DEFUN STRUCTURE-FUNCTION-P (SYMBOL)   (CATCH 'FOUND       (MAPHASH #'(LAMBDA (KEY PS)                         (IF (OR (AND (CONSP (PS-CONSTRUCTORS PS))                                      (MEMBER SYMBOL (PS-CONSTRUCTORS PS)                                             :TEST                                             #'EQ))                                 (EQ SYMBOL (PS-PREDICATE PS))                                 (EQ SYMBOL (PS-COPIER PS))                                 (DOLIST (SLOT (PS-ALL-SLOTS PS))                                     (IF (EQ SYMBOL (PSLOT-ACCESSOR SLOT))                                         (RETURN (PS-NAME PS)))))                             (THROW 'FOUND KEY)))              *PARSED-DEFSTRUCTS*)))(DEFUN STRUCTURE-FUNCTIONS (STRUCTURE-NAME)   (LET ((PS (PARSED-STRUCTURE STRUCTURE-NAME)))        `(,@(PS-CONSTRUCTORS PS)          ,.(LET ((PREDICATE (PS-PREDICATE PS)))                 (IF PREDICATE (LIST PREDICATE)))          ,.(LET ((COPIER (PS-COPIER PS)))                 (IF COPIER (LIST COPIER)))          ,.(MAPCAN #'(LAMBDA (SLOT)                             (LET ((ACCESSOR (PSLOT-ACCESSOR SLOT)))                                  (AND ACCESSOR (LIST ACCESSOR))))                   (PS-ALL-SLOTS PS)))))(IL:* IL:|;;;| "Editing structures")(DEFUN STRUCTURES.HASDEF (NAME &OPTIONAL TYPE SOURCE SPELLFLG)   (OR (IL:GETDEF NAME 'IL:STRUCTURES 'IL:CURRENT '(IL:NODWIM IL:NOCOPY IL:NOERROR IL:HASDEF))       (STRUCTURE-FUNCTION-P NAME)))(DEFUN STRUCTURES.EDITDEF (NAME TYPE SOURCE EDITCOMS OPTIONS)   "From accessor function or structure name, edit the structure."   (IF (PARSED-STRUCTURE NAME T)       (IL:DEFAULT.EDITDEF NAME 'IL:STRUCTURES SOURCE EDITCOMS OPTIONS)       (LET ((STRUCTURE-NAME (STRUCTURE-FUNCTION-P NAME)))            (IF STRUCTURE-NAME                (IL:DEFAULT.EDITDEF STRUCTURE-NAME 'IL:STRUCTURES SOURCE EDITCOMS OPTIONS)                (IL:DEFAULT.EDITDEF NAME TYPE SOURCE EDITCOMS OPTIONS))))   NAME)(IL:FILEPKGTYPE 'IL:STRUCTURES 'IL:HASDEF 'STRUCTURES.HASDEF 'IL:EDITDEF 'STRUCTURES.EDITDEF)(IL:ADDTOVAR IL:SHADOW-TYPES (IL:STRUCTURES IL:FNS))(IL:DECLARE\: IL:DOCOPY IL:DONTEVAL@LOAD (IL:ADDTOVAR IL:INSPECTMACROS ((IL:FUNCTION STRUCTURE-OBJECT-P) . INSPECT-STRUCTURE-OBJECT)))(IL:* IL:|;;;| "file properties")(IL:PUTPROPS IL:DEFSTRUCT IL:FILETYPE :COMPILE-FILE)(IL:PUTPROPS IL:DEFSTRUCT IL:MAKEFILE-ENVIRONMENT (:READTABLE "XCL" :PACKAGE "LISP"))(IL:PUTPROPS IL:DEFSTRUCT IL:COPYRIGHT ("Venue & Xerox Corporation" 1986 1987 1900 1988 1989 1990 1992 1993))(IL:DECLARE\: IL:DONTCOPY  (IL:FILEMAP (NIL)))IL:STOP