;;; -*- Mode:Lisp; Readtable:ZL; Package:USER; Base:8; Patch-File:T -*- ;;; Patch file for System version 126.107 ;;; Reason: ;;; Moderately hairy patch to DEFSTRUCT: Sort subslot fields in order that ;;; provides better handling by constructor form. ;;; ;;; Fixes the most pathological of problems with constructors for structures with ;;; byte fields (ZetaLISP style). You may not get the fields initialized in the ;;; "obvious" order, but at least the constructor doesn't blow up. The order of ;;; initialization is fairly predictable, but still differs from the manual; but ;;; I don't believe I've broken any cases that even sort of worked before. ;;; Written 14-Oct-88 17:39:32 by keith (Keith Corbett) at site Gigamos Cambridge ;;; while running on Breaking Glass from band 3 ;;; with Experimental System 126.104, Experimental ZWEI 126.18, Experimental ZMail 74.9, Experimental Local-File 76.0, Experimental File-Server 25.0, Experimental Lambda-Diag 18.0, Experimental Unix-Interface 15.0, Experimental Tape 26.4, Experimental IMicro 20.0, microcode 1762, SDU Boot Tape 3.14, SDU ROM 103. ; From file DJ: L.SYS2; STRUCT.LISP#340 at 14-Oct-88 17:41:11 #8R SYSTEM-INTERNALS#: (COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "SYSTEM-INTERNALS"))) (COMPILER::PATCH-SOURCE-FILE "SYS: SYS2; STRUCT  " (DEFUN DEFSTRUCT-PARSE-ITEMS (ITEMS DESCRIPTION) (LET ((NAME (DEFSTRUCT-DESCRIPTION-NAME)) (OFFSET (DEFSTRUCT-DESCRIPTION-INITIAL-OFFSET)) (INCLUDE (DEFSTRUCT-DESCRIPTION-INCLUDE)) (O-SLOT-ALIST NIL) (CONC-NAME (DEFSTRUCT-DESCRIPTION-CONC-NAME)) #+MACLISP-10 (CHARS (EXPLODEN CONC-NAME))) ;;;Handle INCLUDEd structures: (OR (NULL INCLUDE) (LET ((D (GET-DEFSTRUCT-DESCRIPTION (CAR INCLUDE)))) (SETQ OFFSET (+ OFFSET (DEFSTRUCT-DESCRIPTION-SIZE D))) (SETQ O-SLOT-ALIST (COPYTREE (DEFSTRUCT-DESCRIPTION-SLOT-ALIST D))) (DOLIST (L O-SLOT-ALIST) (SETF (DEFSTRUCT-SLOT-DESCRIPTION-REF-MACRO-NAME (CDR L)) (IF CONC-NAME #+MACLISP-10 (IMPLODE (APPEND CHARS (EXPLODEN (CAR L)))) #-MACLISP-10 (DEFSTRUCT-APPEND-SYMBOLS CONC-NAME (CAR L)) (CAR L)))) (DOLIST (L (CDR INCLUDE)) (LET* ((IT (IF (CONSP L) (CAR L) L)) (name-of-it (if (consp it) (car it) it)) (REST (IF (CONSP L) (CDR L) NIL)) (SLOT-DESCRIPTION (CDR (ASSQ name-of-IT O-SLOT-ALIST)))) (IF (NULL SLOT-DESCRIPTION) (DEFSTRUCT-ERROR "Unknown slot in :INCLUDEd defstruct" IT 'IN INCLUDE 'INCLUDED 'BY NAME)) (cond ((not (consp it)) (DEFSTRUCT-PARSE-ONE-FIELD name-of-IT NIL NIL REST CONC-NAME #+MACLISP-10 (EXPLODEN CONC-NAME) SLOT-DESCRIPTION)) (t ;Following code allows multiple names for an included slot. The slot in question ; is specified by the first name. The new names are in "format 3" and may have byte-specs. (DEFSTRUCT-PARSE-ONE-FIELD ;use the original slot-description for the first guy. name-of-IT NIL NIL (cddr it) CONC-NAME #+MACLISP-10 (EXPLODEN CONC-NAME) SLOT-DESCRIPTION) (dolist (e (cdr l)) (let ((name-of-it (if (consp e) (car e) e)) (rest (if (consp e) (cddr e) nil)) ;for the rest, use the original as a default, but mung as necessary. (slot-description (copy-list slot-description))) (defstruct-parse-one-field name-of-it nil (if (consp e) (cadr e) nil) rest conc-name #+MACLISP-10 (EXPLODEN CONC-NAME) slot-description) (push (cons name-of-it slot-description) o-slot-alist))))) )))) ;;;Handle slots: (DO ((I OFFSET (1+ I)) (L ITEMS (CDR L)) (SLOT-ALIST NIL) ) ((NULL L) (SETQ SLOT-ALIST (NREVERSE SLOT-ALIST)) (SETF (DEFSTRUCT-DESCRIPTION-SIZE) I) (SETF (DEFSTRUCT-DESCRIPTION-SLOT-ALIST) (NCONC O-SLOT-ALIST SLOT-ALIST))) ;Now returns ALL slots, not just new ;;; (COND ((ATOM (CAR L)) ;Just slot name, no initial value (PUSH (DEFSTRUCT-PARSE-ONE-FIELD (CAR L) I NIL NIL CONC-NAME #+MACLISP-10 CHARS) SLOT-ALIST)) ((ATOM (CAAR L)) ;Slot definition list (PUSH (DEFSTRUCT-PARSE-ONE-FIELD (CAAR L) I NIL (CDAR L) CONC-NAME #+MACLISP-10 CHARS) SLOT-ALIST)) (T ;Slot with subslots ;;;Currently, ;;;BYTE FIELDS are the only kind of supported subslot definition! ;;; ;;;Possible extension: SUB-STRING FIELDS... ;;; (let ((subslots (car l)) subfield-inits subfield-no-inits whole-word-inits whole-word-no-inits) ;;;Order subslots so that constructor works properly: ;;; 1) Whole-word slots with inits ;;; 2) Subfields with inits ;;; 3) Whole-word slots without inits ;;; 4) Subfields without inits (do* ((slots subslots (cdr slots)) (slot (first slots) (first slots))) ((null slots)) (if (second slot) ;Presumably, a subfield (if (third slot) (push slot subfield-inits) (push slot subfield-no-inits)) (if (third slot) (push slot whole-word-inits) (push slot whole-word-no-inits)))) (setq subslots (append whole-word-inits subfield-inits whole-word-no-inits subfield-no-inits)) ;;;Parse (reordered) subslots (do ((slots subslots (cdr slots))) ((null slots)) (let* ((slot (car slots)) (name (car slot)) (spec (cadr slot)) (options (cddr slot))) (PUSH (DEFSTRUCT-PARSE-ONE-FIELD name I spec options CONC-NAME #+MACLISP-10 CHARS) SLOT-ALIST))))))))) ))