|
|
1.1 ! root 1: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; create.l ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ! 2: ; Functions for creating, copying, and merging structures. ! 3: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ! 4: ; Copyright (c) 1983 , The Regents of the University of California. ! 5: ; All rights reserved. ! 6: ; Authors: Joseph Faletti and Michael Deering. ! 7: ! 8: ; Create a new structure of one of the five types: ! 9: ; BASE: build a new structure with all new slots. ! 10: ; EXPANDED: build new slots in addition to slots inherited from ! 11: ; a BASE or EXPANDED structure. ! 12: ; INDIVIDUAL: create an instance of a BASE or EXPANDED structure, ! 13: ; filling in slots or inheriting defaults from above. ! 14: ; PATTERN: create an instance of a BASE or EXPANDED structure but ! 15: ; fill in unspecified slots with ?*ANY*. ! 16: ; FUNCTION: build a new structure with slots describing the ! 17: ; arguments to the function. ! 18: ! 19: ; Generalized syntax for this function is: ! 20: ; ! 21: ; (CREATE <StructureType> <ExpandedorBaseName> <NewItemName> ! 22: ; [{HashingInfo} <OldSlotName> {{{:=} <SlotValue>} | ^} ! 23: ; { : <Variable> } ! 24: ; {<ListOfRestrictionStructureOrSlotIfNames>} ] ! 25: ; . . . . . . . ! 26: ; [{HashingInfo} <NewSlotName> <Type> {{{:=} <SlotValue>} | ^} ! 27: ; { : <Variable> } ! 28: ; {<ListOfRestrictionStructureOrSlotIfNames>} ] ) ! 29: ! 30: ; BASE structures have no <ExpandedorBaseName> and only new slots. ! 31: ; EXPANDED structures should have at least one new slot and inherit ! 32: ; default values from the <ExpandedorBaseName>. ! 33: ; INDIVIDUAL structures have only old slots and inherit default values from ! 34: ; the <ExpandedorBaseName>; if the <NewItemName> occurs, the atom ! 35: ; <NewItemName> is set to point to the internal form which is also ! 36: ; returned as the value of CREATE. ! 37: ; PATTERN structures have only old slots and all unspecified slots are ! 38: ; set to ?*ANY* rather than inheriting a default. ! 39: ; FUNCTION structures have no <ExpandedOrBaseName> and only new slots. ! 40: ; They are interpreted as functions to be run rather than structures ! 41: ; to be accessed when they are MATCHed, FETCHed or PATHed. ! 42: ; ! 43: ; The structure created is always stored in the SPECIAL variable *LASTCREATED* ! 44: ; in addition to the <NewItemName> if specified and the atom formed ! 45: ; by prepending a 'd:' to the front of the <ExpandedOrBaseName>. ! 46: ; ! 47: ; If the SlotValue for a slot in a BASE or EXPANDED structure is preceded ! 48: ; by a :=, then the slot is filled with this value but it is not ! 49: ; used as the default for this slot in future INDIVIDUALS and ! 50: ; EXPANDEDS. ! 51: ; If the SlotValue is not preceded by a :=, then the value represents a ! 52: ; default to be inherited by INDIVIDUALs and new EXPANDEDS. ! 53: ! 54: ; This just sets the two atoms *toplevelp* and *currentcreatetype* ! 55: ; and calls the real workhorse "insidecreate". ! 56: (df create (l) ! 57: (setq *toplevelp* t) ! 58: (setq *currentcreatetype* (car l)) ! 59: (apply (function insidecreate) l)) ! 60: ! 61: ; Pick apart the atoms before the slots, handle them and pass the ! 62: ; rest on to the appropriate version of create XXX. ! 63: (df insidecreate (l) ! 64: (let ((type (car l)) ! 65: (abbrev (cond (*toplevelp* '*buildabbrev*) ! 66: ( t nil))) ! 67: (name1 (cadr l)) ! 68: (name2 (caddr l)) ! 69: (name3 (cadddr l)) ! 70: slots) ! 71: (cond ((reallitatom name2) ! 72: (setq abbrev name2) ! 73: (setq slots (cdddr l)) ! 74: (cond ((reallitatom name3) ! 75: (setq abbrev name3) ! 76: (setq slots (cddddr l))) ! 77: ( t (setq name3 name2)))) ! 78: ( t (setq name3 (setq name2 name1)) ! 79: (setq slots (cddr l)))) ! 80: (and (memq type '(ind individual pat pattern)) ! 81: (eq name1 name3) ! 82: (setq name3 '*lastcreated*)) ! 83: (set name3 ! 84: (setq *lastcreated* ! 85: (selectq type ! 86: ((individual ind) ! 87: (createindividual name1 abbrev slots)) ! 88: (base ! 89: (createbase name1 abbrev slots)) ! 90: ((expanded exp) ! 91: (createexpanded name1 name2 abbrev slots)) ! 92: ((pattern pat) ! 93: (createpattern name1 abbrev slots)) ! 94: ((function fn) ! 95: (createfunction name1 abbrev slots)) ! 96: (otherwise (msg t "CREATE: Illegal selector: " type ! 97: " in created structure: " l t) ! 98: (pearlbreak))))))) ! 99: ! 100: ; Create a new structure and insert it in the database. ! 101: (defmacro dbcreate (&rest rest) ! 102: `(insertdb (create .,rest))) ! 103: ! 104: (defmacro cb (&rest rest) ! 105: `(create base .,rest)) ! 106: ! 107: (defmacro ci (&rest rest) ! 108: `(create individual .,rest)) ! 109: ! 110: (defmacro ce (&rest rest) ! 111: `(create expanded .,rest)) ! 112: ! 113: (defmacro cp (&rest rest) ! 114: `(create pattern .,rest)) ! 115: ! 116: (defmacro cf (&rest rest) ! 117: `(create function .,rest)) ! 118: ! 119: (defmacro base (&rest rest) ! 120: `(create base .,rest)) ! 121: ! 122: (defmacro ind (&rest rest) ! 123: `(create individual .,rest)) ! 124: ! 125: (defmacro individual (&rest rest) ! 126: `(create individual .,rest)) ! 127: ! 128: (defmacro pexp (&rest rest) ! 129: `(create expanded .,rest)) ! 130: ! 131: (defmacro expanded (&rest rest) ! 132: `(create expanded .,rest)) ! 133: ! 134: (defmacro pat (&rest rest) ! 135: `(create pattern .,rest)) ! 136: ! 137: (defmacro pattern (&rest rest) ! 138: `(create pattern .,rest)) ! 139: ! 140: (defmacro fn (&rest rest) ! 141: `(create function .,rest)) ! 142: ! 143: (defmacro pfunction (&rest rest) ! 144: `(create function .,rest)) ! 145: ! 146: ; Put a *VAR* variable in the structure's assoc-list and return the cons-cell. ! 147: (defmacro installvar (varname) ! 148: `(cond ((eq '*any* ,varname) *any*conscell*) ! 149: ; else, if there, return it. ! 150: ((assq ,varname (getalist *currenttopcreated*))) ! 151: ; else, add it (which also returns the special conscell). ! 152: ( t (addalist ,varname *currenttopcreated*)))) ! 153: ! 154: ; Install an adjunct variable in the slot. ! 155: (defmacro installadjunct (adjunctvar) ! 156: `(let (var) ! 157: (cond ((dtpr ,adjunctvar) ! 158: (setq var (cadr ,adjunctvar)) ! 159: (selectq (car ,adjunctvar) ! 160: (*var* (installvar var)) ! 161: (*global* var) ! 162: (otherwise ! 163: (msg t "CREATE: no adjunct variable given after colon " ! 164: "-- rest of slot is: " ,adjunctvar slot t) ! 165: (pearlbreak)))) ! 166: ( t (msg t "CREATE: no adjunct variable given after colon. " ! 167: "Rest of slot is: " ,adjunctvar slot t) ! 168: (pearlbreak))))) ! 169: ! 170: (dm handlepossibleadjunctvar (none) ; but assumes SLOT, SLOTVALUE, & VALUETYPE. ! 171: '(let ((adjunctvar (car slot))) ! 172: (and (eq adjunctvar ':) ! 173: (cond ((neq valuetype 'CONSTANT) ! 174: (msg t "CREATE: Adjunct variables not allowed in " ! 175: "slots whose values are also variables." t) ! 176: (pearlbreak)) ! 177: ( t (setq slot (cdr slot)) ; throw away ":". ! 178: (setq adjunctvar (pop slot)) ! 179: (setq valuetype 'ADJUNCT) ! 180: (setq slotvalue (cons slotvalue ! 181: (installadjunct adjunctvar)))))))) ! 182: ! 183: ; Ensure that value is of type TYPENUM (used after ! or on value in atom ! 184: ; where setof value expected). Value returned (t / never) is used ! 185: ; only in evaluating atom. If error, doesn't return. ! 186: (de enforcetype (value typenum) ! 187: (or (selectq typenum ! 188: (0 (structurep value)) ! 189: (1 (psymbolp value)) ! 190: (2 (numberp value)) ! 191: (3 (not (reallitatom value))) ! 192: (otherwise ! 193: (apply (function and) ! 194: (mapcar (funl (singlevalue) ! 195: (enforcetype singlevalue ! 196: (- typenum 4))) ! 197: value)))) ! 198: (progn (msg t "CREATE: Value after ! or bound to atom in SETOF " ! 199: "slot is of wrong type. Value is: " value t) ! 200: (pearlbreak)))) ! 201: ! 202: ; Get the value for a slot. ! 203: ; If preceded by an ! then it is already in internal form but verify this. ! 204: ; If is preceded by a $ then it should be evaluated before continuing ! 205: ; processing (on its value). ! 206: (dm constructvalue (none) ! 207: '(let ((typenum (getslottype slotnum defblock)) ! 208: (ppset (getppset slotnum defblock))) ! 209: (selectq (car slot) ! 210: (\! (setq slot (cdr slot)) ! 211: (setq newvalue (eval (pop slot))) ! 212: (enforcetype newvalue typenum) ! 213: (setq valuetype 'CONSTANT) ! 214: (setq slotvalue newvalue)) ! 215: (\$ (setq slot (cdr slot)) ! 216: (setq newvalue (eval (pop slot))) ! 217: (setq valuetype 'CONSTANT) ! 218: (setq slotvalue (buildvalue newvalue typenum ppset))) ! 219: (otherwise ! 220: (cond ((and (dtpr (car slot)) ! 221: (eq (caar slot) '*var*)) ! 222: (setq valuetype 'LOCAL) ! 223: (setq newvalue (cadr (pop slot))) ! 224: (setq slotvalue (installvar newvalue))) ! 225: ((and (dtpr (car slot)) ! 226: (eq (caar slot) '*global*)) ! 227: (setq valuetype 'GLOBAL) ! 228: (setq slotvalue (cadr (pop slot)))) ! 229: ( t (setq valuetype 'CONSTANT) ! 230: (setq slotvalue ! 231: (buildvalue (pop slot) typenum ppset)))))))) ! 232: ! 233: ; Generate the default value for slots of the given type. ! 234: (defmacro defaultfortype (typenum) ! 235: `(selectq ,typenum ! 236: (0 (eval (instatom 'nilstruct))) ! 237: (1 (eval (symatom 'nilsym))) ! 238: (2 0) ! 239: (3 nil))) ! 240: ! 241: ; Look at the ISA to find the default value, or the else use ! 242: ; the default default for that type. ! 243: (defmacro inheritvalue (structdef) ! 244: `(let ((isa ,structdef)) ! 245: (cond ((or (null isa) ! 246: (not (getenforce slotnum isa))) ! 247: (setq slotvalue (defaultfortype (getslottype slotnum defblock))) ! 248: (setq valuetype 'CONSTANT)) ! 249: ( t (let ((default (getdefaultinst isa))) ! 250: (setq slotvalue (getslotvalue slotnum default)) ! 251: (setq valuetype (getslotvaluetype slotnum default))))))) ! 252: ! 253: ; Look for predicates and hooks. Use tconc to keep in order. ! 254: (dm handlepredicatesandhooks (none) ! 255: '(progn ! 256: (setq predlist (ncons nil)) ! 257: (setq slothooklist (ncons nil)) ! 258: (while (setq fcn (pop slot)) ! 259: (cond ((atom fcn) ! 260: (cond ((eq fcn 'instead) ! 261: ; Don't inherit hooks. ! 262: (putpred slotnum nil valblock)) ! 263: ((memq fcn '(if hook)) ! 264: ; A hook follows. ! 265: (tconc slothooklist (cons (pop slot) (pop slot)))) ! 266: ; Structure predicate. ! 267: ((structurenamep fcn) ! 268: (tconc predlist (eval (defatom fcn)))) ! 269: ; Otherwise, a predicate name. ! 270: ( t (tconc predlist fcn)))) ! 271: ; Otherwise an s-expression predicate. ! 272: ( t (tconc predlist fcn)))) ! 273: (putpred slotnum ! 274: (nconc (car predlist) (getpred slotnum valblock)) ! 275: valblock) ! 276: (putslothooks slotnum ! 277: (nconc (car slothooklist) (getslothooks slotnum valblock)) ! 278: valblock))) ! 279: ! 280: ; Build a new slot in the current structure. ! 281: (dm buildslot (none) ! 282: '(progn ! 283: (setq slotname (pop slot)) ! 284: (clearhashandformat slotnum defblock) ! 285: ; To gather hashing and enforce information before installing in defblock. ! 286: (setq hashcollect 0) ! 287: (setq reqstruct nil) ! 288: ! 289: ; Check for hashing marks first. ! 290: (while (selectq slotname ! 291: ; First starred slot used for > hashing if no & present. ! 292: (* (and (\=& 0 first*edslot) ! 293: (setq first*edslot (minus slotnum))) ! 294: (addhash* hashcollect)) ! 295: (** (addhash** hashcollect)) ! 296: (*** (addhash*** hashcollect)) ! 297: (& (cond ((not (\=& 0 hashalias)) ! 298: (msg t "CREATE: Only 1 hash alias (&) or " ! 299: "selected slot (^) allowed in: " ! 300: newname t) ! 301: t) ! 302: ( t (setq hashalias slotnum)))) ! 303: (^ (cond ((not (\=& 0 hashalias)) ! 304: (msg t "CREATE: Only 1 hash alias (&) or " ! 305: "selected slot (^) allowed in: " ! 306: newname t) ! 307: t) ! 308: ( t (setq hashalias (minus slotnum))))) ! 309: (&& (cond ((not (\=& 0 hashfocus)) ! 310: (msg t "CREATE: Only 1 hash focus (&&) " ! 311: "allowed in: " newname t) ! 312: t) ! 313: ( t (setq reqstruct t) ! 314: (setq hashfocus slotnum)))) ! 315: (: (addhash: hashcollect)) ! 316: (:: (addhash:: hashcollect)) ! 317: (> (addhash> hashcollect)) ! 318: (< (addhash< hashcollect))) ! 319: (setq slotname (pop slot))) ! 320: (and (\=& 0 (length slot)) ! 321: (progn (msg t "CREATE: Missing slot name and/or type in slot number " ! 322: slotnum " of structure: " newname t) ! 323: (pearlbreak))) ! 324: ! 325: ; Slotname now holds the slotname. Should be checked for duplicates!! ! 326: (putslotname slotnum (ncons slotname) defblock) ! 327: ! 328: ; Now look for the type. ! 329: (setq typenum 0) ! 330: (setq slottype (pop slot)) ! 331: (while (selectq slottype ! 332: (struct (setq reqstruct nil) ! 333: nil) ; i. e., add 0 to TYPENUM. ! 334: (symbol (setq typenum (1+ typenum)) nil) ! 335: (int (setq typenum (+ 2 typenum)) nil) ! 336: (lisp (cond ((not (\=& 0 typenum)) ! 337: (msg t "CREATE: <setof lisp> not allowed. " ! 338: "Type changed to <lisp> in slot " ! 339: slotname " of " newname t) ! 340: (setq typenum 3) nil) ! 341: ((not (\=& 0 hashcollect)) ! 342: (setq hashcollect 0) ! 343: (msg t "CREATE: No hashing allowed on " ! 344: "<lisp> slots in slot " slotname ! 345: " of " newname t))) ! 346: (setq typenum 3) nil) ! 347: (setof (setq typenum (+ 4 typenum)) t) ! 348: (otherwise ! 349: ; Either an ordinal type ==> integer, ! 350: ; or a structure name ==> struct, or an error. ! 351: (cond ((memq slottype *ordinalnames*) ! 352: (setq typenum (+ 2 typenum)) nil) ! 353: ((structurenamep slottype) ! 354: (setq reqstruct nil) ! 355: nil) ; i. e., add 0 to TYPENUM. ! 356: ( t (msg t "CREATE: Illegal type: " slottype ! 357: " in slot: " slotname " of " newname t) ! 358: nil)))) ! 359: (setq slottype (pop slot))) ! 360: (and reqstruct ! 361: (progn (msg t "CREATE: && hashing only allowed on STRUCT slots." ! 362: t " Bad slot is called " slotname ! 363: " and is of type " slottype t) ! 364: (pearlbreak))) ! 365: ; Save the last word of the type which is possibly a structure or ! 366: ; ordinal type name for future use. ! 367: (putppset slotnum slottype defblock) ! 368: (putslottype slotnum typenum defblock) ! 369: ! 370: ; Next, look for a value, or ^ to inherit from above; ! 371: ; these may be preceded by := or == to determine future ! 372: ; "enforcing" (should be less strong term) of this default. ! 373: (setq slotvalue nil) ! 374: (setq valuetype nil) ! 375: (setq enforce (pop slot)) ! 376: (selectq enforce ! 377: (:\= (cond ((eq (car slot) '^) ! 378: (setq slot (cdr slot)) ! 379: (inheritvalue nil)) ! 380: ( t (constructvalue)))) ! 381: (\=\= (addenforce hashcollect) ! 382: (cond ((eq (car slot) '^) ! 383: (setq slot (cdr slot)) ! 384: (inheritvalue nil)) ! 385: ( t (constructvalue)))) ! 386: ((^ nil) ! 387: (addenforce hashcollect) ! 388: (inheritvalue nil)) ! 389: (otherwise (push enforce slot) ! 390: (addenforce hashcollect) ! 391: (constructvalue))) ! 392: ! 393: (handlepossibleadjunctvar) ! 394: ! 395: ; Hash, enforce, slotvalue and valuetype can now be installed. ! 396: (puthashandenforce slotnum hashcollect defblock) ! 397: (putslotvaluetype slotnum valuetype valblock) ! 398: (putslotvalue slotnum slotvalue valblock) ! 399: ! 400: (handlepredicatesandhooks))) ! 401: ! 402: ; Create a new structure of type BASE: a structure with ALL NEW slots. ! 403: (de createbase (newname abbrev slots) ! 404: (and (eq newname 'nilstruct) ! 405: (boundp (defatom 'nilstruct)) ! 406: (progn (msg t "CREATE BASE: Cannot redefine nilstruct." t) ! 407: (pearlbreak))) ! 408: (and (structurenamep newname) ! 409: *warn* ! 410: (msg t "CREATE BASE: Warning: Creating a new definition" ! 411: " of an existing structure: " newname t)) ! 412: (prog (defblock slotname slottype enforce fcn ppset slot length isa ! 413: typenum valblock predlist slothooklist ! 414: first*edslot basehooks basehookbefore newvalue reqstruct ! 415: hashalias hashfocus hashcollect slotvalue valuetype) ! 416: ! 417: ; Process base hooks if the first "slot" is named "if" or "hook". ! 418: (cond ((memq (caar slots) '(if hook)) ! 419: (setq basehookbefore (cdr (pop slots))) ! 420: (setq basehooks (ncons nil)) ! 421: ! 422: ; Use tconc to preserve order. ! 423: (while basehookbefore ; is not NIL ! 424: (tconc basehooks (cons (pop basehookbefore) ! 425: (pop basehookbefore)))) ! 426: (setq basehooks (car basehooks))) ! 427: ( t (setq basehooks nil))) ! 428: ! 429: ; Allocate hunks for definition and default instance (valblock) ! 430: ; based on number of slots. ! 431: (setq defblock (allocdef (setq length (length slots)))) ! 432: (setq valblock (allocval length)) ! 433: (puttypetag '*pearldef* defblock) ! 434: (puttypetag '*pearlinst* valblock) ! 435: (cond (*toplevelp* (setq *currenttopcreated* valblock) ! 436: (setq *currentpearlstructure* valblock) ! 437: (initbothalists valblock) ! 438: (setq *currenttopalists* (getbothalists valblock)) ! 439: ; Include the current environment in ! 440: ; the variable assoc-list. ! 441: (and *blockstack* ! 442: (putalist (cdar *blockstack*) valblock)) ! 443: (setq *toplevelp* nil)) ! 444: ( t (putbothalists *currenttopalists* valblock))) ! 445: ! 446: (putdef defblock valblock) ! 447: (putdefaultinst valblock defblock) ! 448: (set (instatom newname) valblock) ! 449: (set (defatom newname) defblock) ! 450: (and abbrev ! 451: (cond ((eq abbrev '*buildabbrev*) ! 452: (putabbrev (instatom newname) valblock)) ! 453: ( t (putabbrev abbrev valblock)))) ! 454: (putuniquenum (newnum) defblock) ! 455: (putstructlength length defblock) ! 456: (putisa nil defblock) ! 457: (putexpansionlist nil defblock) ! 458: (putbasehooks basehooks defblock) ! 459: (putpname newname defblock) ! 460: ! 461: (setq hashalias 0) ! 462: (setq hashfocus 0) ! 463: (setq first*edslot 0) ! 464: (for slotnum 1 length ! 465: (setq slot (pop slots)) ! 466: (buildslot)) ! 467: ! 468: (cond ((\=& 0 hashalias) (puthashalias first*edslot defblock)) ! 469: ( t (puthashalias hashalias defblock))) ! 470: (puthashfocus hashfocus defblock) ! 471: ! 472: (return valblock))) ! 473: ! 474: ; Create a new individual just for this slot. ! 475: (defmacro buildstructvalue (struct) ! 476: `(cond ((and (atom ,struct) ; if an atom ! 477: (boundp ,struct) ; and bound ! 478: (structurep (eval ,struct))) ; to a structure, ! 479: (eval ,struct)) ; evaluate it. ! 480: ; Otherwise, recursively call create. ! 481: ( t (selectq (car ,struct) ! 482: ; New create type in slot. ! 483: ((ind individual pat pattern fn function ! 484: base exp expanded) ! 485: (let ((*currentcreatetype* (car ,struct))) ! 486: (apply (function insidecreate) ,struct))) ! 487: (otherwise ! 488: ; Otherwise, use current create type. ! 489: (apply (function insidecreate) ! 490: (cons *currentcreatetype* ,struct))))))) ! 491: ! 492: ; Get a pointer to the symbol. ! 493: (defmacro buildsymbolvalue (sym) ! 494: `(cond ((symbolnamep ,sym) (eval (symatom ,sym))) ! 495: ; If not a symbol name, then ... ! 496: ((and (atom ,sym) ; if an atom ! 497: (boundp ,sym) ; and bound ! 498: (psymbolp (eval ,sym))) ; to a symbol, ! 499: (eval ,sym)) ; evaluate it. ! 500: ; Otherwise, error. ! 501: ( t (msg t "CREATE: " ,sym " is used in a slot of type SYMBOL but " ! 502: "neither is the name of a symbol nor evaluates to one." t) ! 503: (pearlbreak)))) ! 504: ! 505: ; Get an integer using PPSET if not an integer. ! 506: (defmacro buildintvalue (intval bppset) ! 507: `(let (assocval) ! 508: (cond ((numberp ,intval) ,intval) ! 509: ; Ordinal type given for ppset. ! 510: ((and ,bppset ; is not NIL. ! 511: (setq assocval (assq ,intval (eval (ordatom ,bppset))))) ! 512: (cdr assocval)) ! 513: ; Some other atom which is bound to an integer. ! 514: ((and (atom ,intval) ! 515: (boundp ,intval) ! 516: (numberp (eval ,intval))) ! 517: (eval ,intval)) ! 518: ; Otherwise, error. ! 519: ( t (msg t "CREATE: Unbound atom or non-integer value: " ! 520: ,intval " in integer slot." t) ! 521: (pearlbreak))))) ! 522: ! 523: ; Construct a new value of the specified type using the pplist if necessary ! 524: (de buildvalue (value typenum ppset) ! 525: (selectq typenum ! 526: (0 (buildstructvalue value)) ! 527: (1 (buildsymbolvalue value)) ! 528: (2 (buildintvalue value ppset)) ! 529: (3 value) ; i.e., could be anything they want. ! 530: (otherwise ! 531: (cond ((and (atom value) ! 532: (boundp value) ! 533: (enforcetype (eval value) typenum)) ! 534: (eval value)) ! 535: ( t (mapcar (funl (singlevalue) ! 536: (buildvalue singlevalue ! 537: (- typenum 4) ppset)) ! 538: value)))))) ! 539: ! 540: ; Return the position number of SLOTNAME in structure DEFBLOCK. ! 541: (defmacro slotnametonumber (slotname defblock) ! 542: `(progn ! 543: (setq slotlocation 0) ! 544: (for slotnum 1 (getstructlength ,defblock) ! 545: (and (memq ,slotname (getslotname slotnum ,defblock)) ! 546: (setq slotlocation slotnum))) ! 547: slotlocation)) ! 548: ! 549: ; Find the slotname in SLOT, put it in SLOTNAME, and find its SLOTNUM. ! 550: (dm findslotnum (none) ! 551: '(progn ! 552: (setq slotname slot) ! 553: (while (memq (car slotname) '(* ** *** & ^ && : :: < > +)) ! 554: (setq slotname (cdr slotname))) ! 555: (cond ((and (dtpr (cadr slotname)) ! 556: (eq '*slot* (car (cadr slotname)))) ! 557: (setq slotname (cadr (cadr slotname))) ! 558: (minus (slotnametonumber slotname olddefblock))) ! 559: ( t (setq slotname (car slotname)) ! 560: (slotnametonumber slotname olddefblock))))) ! 561: ! 562: ; Look up through ISA links and add name to Expansion Lists. ! 563: ; Assumes PROG vars NEWNAME and OLDDEFBLOCK. ! 564: (dm addtoexpansionlists (none) ! 565: '(progn ! 566: (setq isa olddefblock) ! 567: (while isa ; is not null ! 568: (putexpansionlist (cons defblock (getexpansionlist isa)) isa) ! 569: (setq isa (getisa isa))))) ! 570: ! 571: ; Copy definition for one slot. ! 572: (dm copyslice (none) ! 573: '(progn ! 574: (putslottype slotnum (getslottype slotnum olddefblock) defblock) ! 575: (putslotname slotnum (getslotname slotnum olddefblock) defblock) ! 576: (putppset slotnum (getppset slotnum olddefblock) defblock) ! 577: (puthashandformat slotnum (gethashandformat slotnum olddefblock) defblock))) ! 578: ! 579: ; Copy default values, predicates, and hooks for one slot. ! 580: (dm copyslot (none) ! 581: '(progn ! 582: (putslotvaluetype slotnum (getslotvaluetype slotnum oldvalblock) valblock) ! 583: (putslotvalue slotnum (getslotvalue slotnum oldvalblock) valblock) ! 584: (putpred slotnum (getpred slotnum oldvalblock) valblock) ! 585: (putslothooks slotnum (getslothooks slotnum oldvalblock) valblock))) ! 586: ! 587: ; Copy an old slot from an ISA into the current structure. ! 588: (dm fillbaseslot (none) ! 589: '(progn ! 590: (cond ((<& slotnum 0) ! 591: (setq slotnum (minus slotnum)) ! 592: (setq newslotnamep t)) ! 593: ( t (setq newslotnamep nil))) ! 594: ! 595: ; First check for changed hashing. ! 596: (setq slotname (pop slot)) ! 597: (clearhashandformat slotnum defblock) ! 598: (setq hashcollect 0) ! 599: (while (selectq slotname ! 600: (* (and (\=& 0 first*edslot) ! 601: (setq first*edslot (minus slotnum))) ! 602: (addhash* hashcollect) t) ! 603: (** (addhash** hashcollect) t) ! 604: (*** (addhash*** hashcollect) t) ! 605: (& (cond ((not (\=& 0 hashalias)) ! 606: (msg t "CREATE EXPANDED: Only 1 hash alias " ! 607: "(&) or selected slot (^) allowed in: " ! 608: newname t) ! 609: t) ! 610: ( t (setq hashalias slotnum)))) ! 611: (^ (cond ((not (\=& 0 hashalias)) ! 612: (msg t "CREATE EXPANDED: Only 1 hash alias " ! 613: "(&) or selected slot (^) allowed in: " ! 614: newname t) ! 615: t) ! 616: ( t (setq hashalias (minus slotnum))))) ! 617: (&& (cond ((not (\=& 0 hashfocus)) ! 618: (msg t "CREATE EXPANDED: Only 1 hash focus " ! 619: "(&&) allowed in: " newname t) ! 620: t) ! 621: ( t (setq hashfocus slotnum)))) ! 622: (: (addhash: hashcollect) t) ! 623: (:: (addhash:: hashcollect) t) ! 624: (> (addhash> hashcollect) t) ! 625: (< (addhash< hashcollect) t) ! 626: (+ (setq hashcollect (gethashinfo slotnum olddefblock)) ! 627: t)) ! 628: (setq slotname (pop slot))) ! 629: ! 630: (and (\=& 0 (length slot)) ! 631: (progn (msg t "CREATE EXPANDED: Missing slot name and/or value in: " ! 632: newname t) ! 633: (pearlbreak))) ! 634: ! 635: (and newslotnamep ! 636: (pop slot) ! 637: (addslotname slotnum slotname defblock)) ! 638: ! 639: ; Next, check for value or ^, possibly preceded by := or ==. ! 640: (setq enforce (pop slot)) ! 641: (selectq enforce ! 642: (:\= (cond ((eq (car slot) '^) ; a waste. ! 643: (setq slot (cdr slot)) ! 644: (inheritvalue (getisa defblock))) ! 645: ( t (constructvalue)))) ! 646: (\=\= (addenforce hashcollect) ! 647: (cond ((eq (car slot) '^) ! 648: (setq slot (cdr slot)) ! 649: (inheritvalue (getisa defblock))) ! 650: ( t (constructvalue)))) ! 651: ((^ nil) (addenforce hashcollect) ! 652: (inheritvalue (getisa defblock))) ! 653: (otherwise (push enforce slot) ! 654: (addenforce hashcollect) ! 655: (constructvalue))) ! 656: ! 657: (handlepossibleadjunctvar) ! 658: ! 659: ; Hash, enforce, slotvalue and valuetype can now be installed. ! 660: (puthashandenforce slotnum hashcollect defblock) ! 661: (putslotvaluetype slotnum valuetype valblock) ! 662: (putslotvalue slotnum slotvalue valblock) ! 663: ! 664: (handlepredicatesandhooks))) ! 665: ! 666: ; Create a new structure of type EXPANDED: build new slots in ! 667: ; addition to slots inherited from a BASE or EXPANDED structure. ! 668: (de createexpanded (basename newname abbrev slots) ! 669: (and (eq newname 'nilstruct) ! 670: (progn (msg t "CREATE EXPANDED: Cannot redefine nilstruct." t) ! 671: (pearlbreak))) ! 672: (and (structurenamep newname) ! 673: *warn* ! 674: (msg t "CREATE EXPANDED: Warning: Creating a new definition of " ! 675: "an existing structure: " newname t)) ! 676: (or (structurenamep basename) ! 677: (progn (msg t "CREATE EXPANDED: " basename ! 678: " is not the name of a previously declared structure." t ! 679: " New name is " newname ". Slots are: " slots t) ! 680: (pearlbreak))) ! 681: (prog (defblock valblock oldvalblock olddefblock slotname ! 682: slottype enforce slot oldlength length slotnum ! 683: typenum slotnumlist beginslots predlist slothooklist ! 684: fcn ppset isa first*edslot slotlocation basehooks ! 685: basehookbefore newvalue result item reqstruct ! 686: newslotnamep hashalias hashfocus hashcollect ! 687: slotvalue valuetype) ! 688: (setq olddefblock (eval (defatom basename))) ! 689: (setq oldlength (getstructlength olddefblock)) ! 690: ! 691: ; Handle base hooks, if first "slot" is called "if" or "hook". ! 692: (cond ((memq (caar slots) '(if hook)) ! 693: (setq basehookbefore (cdr (pop slots))) ! 694: (setq basehooks (ncons nil)) ! 695: (while basehookbefore ; is not NIL ! 696: (tconc basehooks (cons (pop basehookbefore) ! 697: (pop basehookbefore)))) ! 698: (setq basehooks (nconc (car basehooks) ! 699: (getbasehooks olddefblock)))) ! 700: ( t (setq basehooks (getbasehooks olddefblock)))) ! 701: ! 702: ; Create a list of slotnumbers for the slotnames in SLOTS, ! 703: ; meanwhile also determining the LENGTH. ! 704: (setq beginslots slots) ; save to process again. ! 705: (setq slotnumlist (ncons nil)) ! 706: (setq length oldlength) ! 707: (while (setq slot (pop slots)) ! 708: (cond ((not (\=& 0 (setq slotnum (findslotnum)))) ! 709: ; Old slot name or new name for old slot (negative). ! 710: (tconc slotnumlist slotnum)) ! 711: ; Otherwise, new slot name: increase length. ! 712: ( t (setq length (1+ length)) ! 713: (tconc slotnumlist length)))) ! 714: (setq slotnumlist (car slotnumlist)) ! 715: (setq slots beginslots) ! 716: ! 717: ; Allocate new hunks. ! 718: (setq defblock (allocdef length)) ! 719: (setq valblock (allocval length)) ! 720: (puttypetag '*pearldef* defblock) ! 721: (puttypetag '*pearlinst* valblock) ! 722: (cond (*toplevelp* (setq *currenttopcreated* valblock) ! 723: (setq *currentpearlstructure* valblock) ! 724: (initbothalists valblock) ! 725: (setq *currenttopalists* (getbothalists valblock)) ! 726: ; Include the current environment in ! 727: ; the variable assoc-list. ! 728: (and *blockstack* ! 729: (putalist (cdar *blockstack*) valblock)) ! 730: (setq *toplevelp* nil)) ! 731: ( t (putbothalists *currenttopalists* valblock))) ! 732: ! 733: (putdef defblock valblock) ! 734: (putdefaultinst valblock defblock) ! 735: (set (instatom newname) valblock) ! 736: (set (defatom newname) defblock) ! 737: (and abbrev ! 738: (cond ((eq abbrev '*buildabbrev*) ! 739: (putabbrev (instatom newname) valblock)) ! 740: ( t (putabbrev abbrev valblock)))) ! 741: (putuniquenum (newnum) defblock) ! 742: (putstructlength length defblock) ! 743: ! 744: ; Set up the hierarchy of ISAs. ! 745: (putisa olddefblock defblock) ! 746: (putexpansionlist nil defblock) ! 747: (addtoexpansionlists) ! 748: ! 749: (putbasehooks basehooks defblock) ! 750: (putpname newname defblock) ! 751: (setq oldvalblock (getdefaultinst olddefblock)) ! 752: ! 753: ; (puthashalias 0 defblock) ! 754: (setq hashalias 0) ! 755: (setq hashfocus 0) ! 756: (or (<& (setq first*edslot (gethashalias olddefblock)) 0) ! 757: (setq first*edslot 0)) ! 758: ; Copy old slots in first. ! 759: (for slotnum 1 oldlength ! 760: (copyslice) ! 761: (copyslot olddefblock)) ! 762: ; Run base hooks attached to the base we are expanding. ! 763: (and (getbasehooks olddefblock) ! 764: (setq item valblock) ! 765: (checkrunhandlebasehooks1 '<expanded *runexpandedhooks*) ! 766: (setq valblock item)) ! 767: ! 768: ; For each slot, if it's new, build a new slot; ! 769: ; if it's old, fill it in differently. ! 770: (while (setq slot (pop slots)) ! 771: (setq slotnum (pop slotnumlist)) ! 772: (cond ((>& slotnum oldlength) ! 773: (buildslot)) ! 774: ( t (fillbaseslot)))) ! 775: (cond ((\=& 0 hashalias) (puthashalias first*edslot defblock)) ! 776: ( t (puthashalias hashalias defblock))) ! 777: (cond ((\=& 0 hashfocus) (puthashfocus (gethashfocus olddefblock) ! 778: defblock)) ! 779: ( t (puthashfocus hashfocus defblock))) ! 780: ! 781: ; Run base hooks attached to the base we are expanding. ! 782: (and (getbasehooks olddefblock) ! 783: (setq item valblock) ! 784: (checkrunhandlebasehooks1 '>expanded *runexpandedhooks*) ! 785: (setq valblock item)) ! 786: (return valblock))) ! 787: ! 788: ; Fill in an individual slot with the value specified. If the value is ! 789: ; prefaced by the character "^" then the value should be inherited from ! 790: ; above but there are still predicates and/or IFs to process. ! 791: (dm fillindivslot (none) ! 792: '(progn ! 793: (setq slotname (pop slot)) ! 794: ; Find slot number. ! 795: (and (\=& 0 (setq slotnum (slotnametonumber slotname defblock))) ! 796: (progn (msg t "CREATE: Undefined slot: " slotname ! 797: ", in individual or pattern: " basename) ! 798: (pearlbreak))) ! 799: (cond ((\=& 0 (length slot)) ! 800: (msg t "Missing value in: CREATE INDIVIDUAL (or PATTERN) " ! 801: basename ". Remaining slots are: " slots t) ! 802: (pearlbreak)) ! 803: ; If ^, inherit. ! 804: ((eq (car slot) '^) ! 805: (setq slot (cdr slot)) ! 806: (inheritvalue defblock)) ! 807: ; Otherwise, construct a new value and insert. ! 808: ( t (constructvalue))) ! 809: ! 810: (handlepossibleadjunctvar) ! 811: ! 812: ; Store type and value. ! 813: (putslotvaluetype slotnum valuetype valblock) ! 814: (putslotvalue slotnum slotvalue valblock) ! 815: ! 816: (handlepredicatesandhooks))) ! 817: ! 818: ; Create a new structure of type INDIVIDUAL: an instance of a ! 819: ; BASE or EXPANDED structure. Slots are either filled explicitly ! 820: ; or they inherit defaults from above. ! 821: (de createindividual (basename abbrev slots) ! 822: (or (structurenamep basename) ! 823: (progn (msg t "CREATE INDIVIDUAL: " basename ! 824: " is not the name of a previously declared structure." ! 825: t " Slots are: " slots t) ! 826: (pearlbreak))) ! 827: (prog (defblock valblock slotname length slotnum oldvalblock ! 828: isa typenum ppset slot predlist slothooklist fcn ! 829: slotlocation newvalue result item ! 830: slotvalue valuetype) ! 831: ! 832: ; Find definition and allocate hunk for individual. ! 833: (setq defblock (eval (defatom basename))) ! 834: (setq valblock (allocval (setq length (getstructlength defblock)))) ! 835: (puttypetag '*pearlinst* valblock) ! 836: (cond (*toplevelp* (setq *currenttopcreated* valblock) ! 837: (setq *currentpearlstructure* valblock) ! 838: (initbothalists valblock) ! 839: (setq *currenttopalists* (getbothalists valblock)) ! 840: ; Include the current environment in ! 841: ; the variable assoc-list. ! 842: (and *blockstack* ! 843: (putalist (cdar *blockstack*) valblock)) ! 844: (setq *toplevelp* nil)) ! 845: ( t (putbothalists *currenttopalists* valblock))) ! 846: ! 847: (and abbrev ! 848: (cond ((eq abbrev '*buildabbrev*) ! 849: (putabbrev (eval `(newsym ,(getpname defblock))) valblock)) ! 850: ( t (putabbrev abbrev valblock)))) ! 851: (putdef defblock valblock) ! 852: (setq oldvalblock (getdefaultinst defblock)) ! 853: ! 854: ; Copy slots from old structure first, then run base hooks. ! 855: (for slotnum 1 length ! 856: (copyslot defblock)) ! 857: (and (getbasehooks defblock) ! 858: (setq item valblock) ! 859: (checkrunhandlebasehooks1 '<individual *runindividualhooks*) ! 860: (setq valblock item)) ! 861: ! 862: ; Replace copied values for slots that are actually listed ! 863: ; then run base hooks. ! 864: (while (setq slot (pop slots)) ! 865: (fillindivslot)) ! 866: (and (getbasehooks defblock) ! 867: (setq item valblock) ! 868: (checkrunhandlebasehooks1 '>individual *runindividualhooks*) ! 869: (setq valblock item)) ! 870: (return valblock))) ! 871: ! 872: ; Copy default values, predicates, and hooks for one slot. ! 873: (dm copypatternslot (none) ! 874: '(progn ! 875: (putslotvaluetype slotnum 'LOCAL valblock) ! 876: (putslotvalue slotnum *any*conscell* valblock) ! 877: (putpred slotnum (getpred slotnum oldvalblock) valblock) ! 878: (putslothooks slotnum (getslothooks slotnum oldvalblock) valblock))) ! 879: ! 880: ; Create a new structure of type PATTERN: an instance of a BASE or ! 881: ; EXPANDED structure. Unspecified slots are filled with ?*ANY*. ! 882: (de createpattern (basename abbrev slots) ! 883: (prog (defblock valblock oldvalblock slotname length slotnum isa ! 884: slotlocation slot predlist slothooklist fcn typenum ! 885: ppset newvalue result item slotvalue valuetype) ! 886: (or (structurenamep basename) ! 887: (progn (msg t "CREATE PATTERN: " basename ! 888: " is not the name of a previously declared structure." ! 889: t) ! 890: (pearlbreak))) ! 891: ! 892: ; Get definition and allocate hunk for pattern. ! 893: (setq defblock (eval (defatom basename))) ! 894: (setq valblock (allocval (setq length (getstructlength defblock)))) ! 895: (setq oldvalblock (getdefaultinst defblock)) ! 896: (puttypetag '*pearlinst* valblock) ! 897: (cond (*toplevelp* (setq *currenttopcreated* valblock) ! 898: (setq *currentpearlstructure* valblock) ! 899: (initbothalists valblock) ! 900: (setq *currenttopalists* (getbothalists valblock)) ! 901: ; Include the current environment in ! 902: ; the variable assoc-list. ! 903: (and *blockstack* ! 904: (putalist (cdar *blockstack*) valblock)) ! 905: (setq *toplevelp* nil)) ! 906: ( t (putbothalists *currenttopalists* valblock))) ! 907: ! 908: (putdef defblock valblock) ! 909: (and abbrev ! 910: (cond ((eq abbrev '*buildabbrev*) ! 911: (putabbrev (eval `(newsym ,(getpname defblock))) valblock)) ! 912: ( t (putabbrev abbrev valblock)))) ! 913: ! 914: ; Copy slot values from base and run base hooks on base structure. ! 915: (for slotnum 1 length ! 916: (copypatternslot)) ! 917: (and (getbasehooks defblock) ! 918: (setq item valblock) ! 919: (checkrunhandlebasehooks1 '<pattern *runpatternhooks*) ! 920: (setq valblock item)) ! 921: ! 922: ; Fill in new values for any slots listed and run base hooks. ! 923: (while (setq slot (pop slots)) ! 924: (fillindivslot)) ! 925: (and (getbasehooks defblock) ! 926: (setq item valblock) ! 927: (checkrunhandlebasehooks1 '>pattern *runpatternhooks*) ! 928: (setq valblock item)) ! 929: (return valblock))) ! 930: ! 931: ; Create a new structure of type FUNCTION: a structure with slots ! 932: ; describing the arguments to the function of the same name. ! 933: (de createfunction (fcnname abbrev slots) ! 934: ; Function must already be defined and be a lambda (expr). ! 935: (cond ((islambda fcnname) ! 936: (putprop fcnname t 'functionstruct) ! 937: (createbase fcnname abbrev slots)) ! 938: ( t (msg t "CREATE FUNCTION: Only lambdas (exprs) allowed as " ! 939: "function structures: " fcnname slots t) ! 940: (pearlbreak)))) ! 941: ! 942: ; vi: set lisp:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.