|
|
1.1 ! root 1: .\" Copyright (c) 1980 Regents of the University of California. ! 2: .\" All rights reserved. The Berkeley software License Agreement ! 3: .\" specifies the terms and conditions for redistribution. ! 4: .\" ! 5: .\" @(#)ch2.n 6.2 (Berkeley) 5/14/86 ! 6: .\" ! 7: .\" $Header: ch2.n,v 1.7 83/07/30 14:42:38 layer Exp $ ! 8: .Lc Data\ Structure\ Access 2 ! 9: .pp ! 10: The following functions allow one to create and manipulate the various types ! 11: of lisp data structures. ! 12: Refer to \(sc1.2 for details of the data structures known to ! 13: .Fr . ! 14: .sh 2 Lists \n(ch 1 ! 15: .pp ! 16: The following functions exist for the creation and manipulating of lists. ! 17: Lists are composed of a linked list of objects called ! 18: either 'list cells', 'cons cells' or 'dtpr cells'. ! 19: Lists are normally terminated with the special symbol ! 20: .b nil . ! 21: .b nil ! 22: is both a symbol and a representation for the empty list (). ! 23: .sh 3 list\ creation ! 24: .Lf cons "'g_arg1 'g_arg2" ! 25: .Re ! 26: a new list cell whose car is g_arg1 and whose cdr is g_arg2. ! 27: .Lf xcons "'g_arg1 'g_arg2" ! 28: .Eq ! 29: \fI(cons 'g_arg2 'g_arg1)\fP ! 30: .Lf ncons "'g_arg" ! 31: .Eq ! 32: \fI(cons 'g_arg nil)\fP ! 33: .Lf list "['g_arg1 ... ]" ! 34: .Re ! 35: a list whose elements are the g_arg\fIi\fP. ! 36: .Lf append "'l_arg1 'l_arg2" ! 37: .Re ! 38: a list containing the elements of l_arg1 followed by l_arg2. ! 39: .No ! 40: To generate the result, the top level list cells of l_arg1 are duplicated ! 41: and the cdr of the last list cell is set to point to l_arg2. ! 42: Thus this is an expensive operation if l_arg1 is large. ! 43: See the descriptions of ! 44: .i nconc ! 45: and ! 46: .i tconc ! 47: for cheaper ways of doing the ! 48: .i append ! 49: if the list l_arg1 can be altered. ! 50: .Lf append1 "'l_arg1 'g_arg2" ! 51: .Re ! 52: a list like l_arg1 with g_arg2 as the last element. ! 53: .No ! 54: this is equivalent to (append 'l_arg1 (list 'g_arg2)). ! 55: .Eb ! 56: ; A common mistake is using append to add one element to the end of a list ! 57: \-> \fI(append '(a b c d) 'e)\fP ! 58: (a b c d . e) ! 59: ; The user intended to say: ! 60: \-> \fI(append '(a b c d) '(e)) ! 61: (a b c d e) ! 62: ; better is append1 ! 63: \-> \fI(append1 '(a b c d) 'e)\fP ! 64: (a b c d e) ! 65: .Ee ! 66: .Lf quote! "[g_qform\fIi\fP] ...[! 'g_eform\fIi\fP] ... [!! 'l_form\fIi\fP] ..." ! 67: .Re ! 68: The list resulting from the splicing and insertion process ! 69: described below. ! 70: .No ! 71: .i quote! ! 72: is the complement of the ! 73: .i list ! 74: function. ! 75: .i list ! 76: forms a list by evaluating each for in the argument list; evaluation is ! 77: suppressed if the form is \fIquote\fPed. In ! 78: .i quote!, ! 79: each form is implicitly \fIquote\fPed. To be evaluated, a form ! 80: must be preceded by one of the evaluate operations ! and !!. ! g_eform ! 81: evaluates g_form and the value is inserted in the place of the call; ! 82: !! l_form evaluates l_form and the value is spliced into the place of ! 83: the call. ! 84: .br ! 85: .sp ! 86: `Splicing in' means that the parentheses surrounding the list are removed ! 87: as the example below shows. ! 88: Use of the evaluate operators can occur at any level in a ! 89: form argument. ! 90: .br ! 91: .sp ! 92: Another way to get the effect of the \fIquote!\fP function is to use ! 93: the backquote character macro (see \(sc 8.3.3). ! 94: .Eb ! 95: \fI(quote! cons ! (cons 1 2) 3) = (cons (1 . 2) 3)\fP ! 96: \fI(quote! 1 !! (list 2 3 4) 5) = (1 2 3 4 5)\fP ! 97: \fI(setq quoted 'evaled)(quote! ! ((I am ! quoted))) = ((I am evaled))\fP ! 98: \fI(quote! try ! '(this ! one)) = (try (this ! one))\fP ! 99: .Ee ! 100: ! 101: .Lf bignum-to-list "'b_arg" ! 102: .Re ! 103: A list of the fixnums which are used to represent the bignum. ! 104: .No ! 105: the inverse of this function is ! 106: .i list-to-bignum. ! 107: .Lf list-to-bignum "'l_ints" ! 108: .Wh ! 109: l_ints is a list of fixnums. ! 110: .Re ! 111: a bignum constructed of the given fixnums. ! 112: .No ! 113: the inverse of this function is ! 114: .i bignum-to-list. ! 115: ! 116: .sh 3 list\ predicates ! 117: .Lf dtpr "'g_arg" ! 118: .Re ! 119: t iff g_arg is a list cell. ! 120: .No ! 121: that (dtpr '()) is nil. The name \fBdtpr\fP is ! 122: a contraction for ``dotted pair''. ! 123: .Lf listp "'g_arg" ! 124: .Re ! 125: t iff g_arg is a list object or nil. ! 126: .Lf tailp "'l_x 'l_y" ! 127: .Re ! 128: l_x, if a list cell ! 129: .i eq ! 130: to l_x is found by ! 131: .i cdr ing ! 132: down l_y zero or more times, nil otherwise. ! 133: .Eb ! 134: \-> \fI(setq x '(a b c d) y (cddr x))\fP ! 135: (c d) ! 136: \-> \fI(and (dtpr x) (listp x))\fP ; x and y are dtprs and lists ! 137: t ! 138: \-> \fI(dtpr '())\fP ; () is the same as nil and is not a dtpr ! 139: nil ! 140: \-> \fI(listp '())\fP ; however it is a list ! 141: t ! 142: \-> \fI(tailp y x)\fP ! 143: (c d) ! 144: .Ee ! 145: .Lf length "'l_arg" ! 146: .Re ! 147: the number of elements in the top level of list l_arg. ! 148: .sh 3 list\ accessing ! 149: .Lf car "'l_arg" ! 150: .Lx cdr "'l_arg" ! 151: .Re the appropriate part of ! 152: .i cons ! 153: cell. ! 154: (\fIcar\fP (\fIcons\fP x y)) is always x, ! 155: (\fIcdr\fP (\fIcons\fP x y)) is always y. ! 156: In ! 157: .Fr , ! 158: the cdr portion is located first in memory. ! 159: This is hardly noticeable, and we mention it ! 160: primarily as a curiosity. ! 161: .Lf c\.\.r "'lh_arg" ! 162: .Wh ! 163: the .. represents any positive number of \fBa\fP's and \fBd\fP's. ! 164: .Re ! 165: the result of accessing the list structure in the way determined by ! 166: the function name. ! 167: The \fBa\fP's and \fBd\fP's are read from right to left, a ! 168: .b d ! 169: directing the access down the cdr part of the list cell and an ! 170: .b a ! 171: down the car part. ! 172: .No ! 173: lh_arg may also be nil, and it is guaranteed that the car and cdr of nil ! 174: is nil. ! 175: If lh_arg is a hunk, then \fI(car\ 'lh_arg)\fP is the same as ! 176: \fI(cxr\ 1\ 'lh_arg)\fP and \fI(cdr\ 'lh_arg)\fP is the same ! 177: as \fI(cxr\ 0\ 'lh_arg)\fP. ! 178: .br ! 179: It is generally hard to read and understand the context ! 180: of functions with large strings of ! 181: .b a 's ! 182: and ! 183: .b d 's, ! 184: but these functions are supported by rapid accessing and open-compiling ! 185: (see Chapter 12). ! 186: .Lf nth "'x_index 'l_list" ! 187: .Re ! 188: the nth element of l_list, assuming zero-based index. ! 189: Thus (nth 0 l_list) is the same as (car l_list). ! 190: .i nth ! 191: is both a function, and a compiler macro, so that ! 192: more efficient code might be generated than for ! 193: .i nthelem ! 194: (described below). ! 195: .No ! 196: If x_arg1 is non-positive or greater than the length ! 197: of the list, nil is returned. ! 198: .Lf nthcdr "'x_index 'l_list" ! 199: .Re ! 200: the result of \fIcdr\fPing down the list l_list x_index times. ! 201: .No ! 202: If x_index is less than 0, then \fI(cons\ nil\ 'l_list)\fP is returned. ! 203: .Lf nthelem "'x_arg1 'l_arg2" ! 204: .Re ! 205: The x_arg1'\fIst\fP element of the list l_arg2. ! 206: .No ! 207: This function comes from the PDP-11 Lisp system. ! 208: .Lf last "'l_arg" ! 209: .Re ! 210: the last list cell in the list l_arg. ! 211: .Ex ! 212: \fIlast\fP does NOT return the last element of a list! ! 213: .br ! 214: \fI(last '(a b))\fP = (b) ! 215: .Lf ldiff "'l_x 'l_y" ! 216: .Re ! 217: a list of all ! 218: elements in l_x but not in l_y ! 219: , i.e., the list difference of ! 220: l_x and l_y. ! 221: .No ! 222: l_y must be a tail of l_x, i.e., ! 223: .i eq ! 224: to the result of applying some number of \fIcdr\fP's ! 225: to l_x. ! 226: Note that the value of \fIldiff\fP is always new list ! 227: structure unless l_y is nil, in which case \fI(ldiff l_x nil)\fP is l_x ! 228: itself. ! 229: If l_y is not a tail of l_x, \fIldiff\fP generates an error. ! 230: .Ex ! 231: \fI(ldiff 'l_x (member 'g_foo 'l_x))\fP gives all elements ! 232: in l_x up to the first g_foo. ! 233: .sh 3 list\ manipulation ! 234: .Lf rplaca "'lh_arg1 'g_arg2" ! 235: .Re ! 236: the modified lh_arg1. ! 237: .Se ! 238: the car of lh_arg1 is set to g_arg2. ! 239: If lh_arg1 is a hunk then the second element of the hunk is set to g_arg2. ! 240: .Lf rplacd "'lh_arg1 'g_arg2" ! 241: .Re ! 242: the modified lh_arg1. ! 243: .Se ! 244: the cdr of lh_arg2 is set to g_arg2. ! 245: If lh_arg1 is a hunk then the first element of the hunk is set to g_arg2. ! 246: ! 247: .Lf attach "'g_x 'l_l" ! 248: .Re ! 249: l_l whose ! 250: .i car ! 251: is now g_x, whose ! 252: .i cadr ! 253: is the original \fI(car\ l_l)\fP, ! 254: and whose ! 255: .i cddr ! 256: is the original \fI(cdr\ l_l)\fP. ! 257: .No ! 258: what happens is that g_x is added to the ! 259: beginning of list l_l yet maintaining the same list cell at the ! 260: beginning of the list. ! 261: .Lf delete "'g_val 'l_list ['x_count]" ! 262: .Re ! 263: the result of splicing g_val from the top level of ! 264: l_list no more than x_count times. ! 265: .No ! 266: x_count defaults to a very large number, thus if x_count is not given, all ! 267: occurrences of g_val are removed from the top level of l_list. ! 268: g_val is compared with successive ! 269: .i car 's ! 270: of l_list using the function ! 271: .i equal . ! 272: .Se ! 273: l_list is modified using rplacd, no new list cells are used. ! 274: .Lf delq "'g_val 'l_list ['x_count]" ! 275: .Lx dremove "'g_val 'l_list ['x_count]" ! 276: .Re ! 277: the result of splicing g_val from the top level of l_list no more than ! 278: x_count times. ! 279: .No ! 280: .i delq ! 281: (and ! 282: .i dremove ) ! 283: are the same as ! 284: .i delete ! 285: except that ! 286: .i eq ! 287: is used for comparison instead of ! 288: .i equal . ! 289: .Eb ! 290: ; note that you should use the value returned by \fIdelete\fP or \fIdelq\fP ! 291: ; and not assume that g_val will always show the deletions. ! 292: ; For example ! 293: ! 294: \-> \fI(setq test '(a b c a d e))\fP ! 295: (a b c a d e) ! 296: \-> \fI(delete 'a test)\fP ! 297: (b c d e) ; the value returned is what we would expect ! 298: \-> \fItest\fP ! 299: (a b c d e) ; but test still has the first a in the list! ! 300: .Ee ! 301: .Lf remq "'g_x 'l_l ['x_count]" ! 302: .Lx remove "'g_x 'l_l" ! 303: .Re ! 304: a ! 305: .i copy ! 306: of l_l with all top level elements ! 307: .i equal ! 308: to g_x removed. ! 309: .i remq ! 310: uses ! 311: .i eq ! 312: instead of ! 313: .i equal ! 314: for comparisons. ! 315: .No ! 316: remove does not modify its arguments like ! 317: .i delete , ! 318: and ! 319: .i delq ! 320: do. ! 321: .Lf insert "'g_object 'l_list 'u_comparefn 'g_nodups" ! 322: .Re ! 323: a list consisting of l_list with g_object destructively inserted ! 324: in a place determined by the ordering function u_comparefn. ! 325: .No ! 326: \fI(comparefn 'g_x 'g_y)\fP ! 327: should return something non-nil if g_x can precede g_y in sorted order, ! 328: nil if g_y must precede g_x. ! 329: If u_comparefn is nil, alphabetical order ! 330: will be used. ! 331: If g_nodups is non-nil, an element will not be inserted if an ! 332: equal element is already in the list. ! 333: .i insert ! 334: does binary search to determine where to insert the new element. ! 335: .Lf merge "'l_data1 'l_data2 'u_comparefn" ! 336: .Re ! 337: the merged list of the two input sorted lists l_data1 and l_data1 ! 338: using binary comparison function u_comparefn. ! 339: .No ! 340: \fI(comparefn 'g_x 'g_y)\fP ! 341: should return something non-nil if g_x can precede g_y in sorted order, ! 342: nil if g_y must precede g_x. If u_comparefn is nil, ! 343: alphabetical order ! 344: will be used. u_comparefn should be thought of as "less than or equal". ! 345: .i merge ! 346: changes both of its data arguments. ! 347: .Lf subst "'g_x 'g_y 'l_s" ! 348: .Lx dsubst "'g_x 'g_y 'l_s" ! 349: .Re ! 350: the result of substituting g_x for all ! 351: .i equal ! 352: occurrences of g_y at all levels in l_s. ! 353: .No ! 354: If g_y is a symbol, ! 355: .i eq ! 356: will be used for comparisons. ! 357: The function ! 358: .i subst ! 359: does not modify l_s ! 360: but the function ! 361: .i dsubst ! 362: (destructive substitution) ! 363: does. ! 364: .Lf lsubst "'l_x 'g_y 'l_s" ! 365: .Re ! 366: a copy of l_s with l_x spliced in for every occurrence of of g_y ! 367: at all levels. ! 368: Splicing in means that the parentheses surrounding the list l_x are removed ! 369: as the example below shows. ! 370: .Eb ! 371: \-> \fI(subst '(a b c) 'x '(x y z (x y z) (x y z)))\fP ! 372: ((a b c) y z ((a b c) y z) ((a b c) y z)) ! 373: \-> \fI(lsubst '(a b c) 'x '(x y z (x y z) (x y z)))\fP ! 374: (a b c y z (a b c y z) (a b c y z)) ! 375: .Ee ! 376: .Lf subpair "'l_old 'l_new 'l_expr" ! 377: .Wh ! 378: there are the same number of elements in l_old as l_new. ! 379: .Re ! 380: the list l_expr with all occurrences of a object in l_old replaced by ! 381: the corresponding one in l_new. ! 382: When a substitution is made, a copy of the value to substitute in ! 383: is not made. ! 384: .Ex ! 385: \fI(subpair '(a c)' (x y) '(a b c d)) = (x b y d)\fP ! 386: ! 387: .Lf nconc "'l_arg1 'l_arg2 ['l_arg3 ...]" ! 388: .Re ! 389: A list consisting of the elements of l_arg1 followed by the elements of ! 390: l_arg2 followed by l_arg3 and so on. ! 391: .No ! 392: The ! 393: .i cdr ! 394: of the last list cell of l_arg\fIi\fP is changed to point to ! 395: l_arg\fIi+1\fP. ! 396: .Eb ! 397: ; \fInconc\fP is faster than \fIappend\fP because it doesn't allocate new list cells. ! 398: \-> \fI(setq lis1 '(a b c))\fP ! 399: (a b c) ! 400: \-> \fI(setq lis2 '(d e f))\fP ! 401: (d e f) ! 402: \-> \fI(append lis1 lis2)\fP ! 403: (a b c d e f) ! 404: \-> \fIlis1\fP ! 405: (a b c) ; note that lis1 has not been changed by \fIappend\fP ! 406: \-> \fI(nconc lis1 lis2)\fP ! 407: (a b c d e f) ; \fInconc\fP returns the same value as \fIappend\fP ! 408: \-> \fIlis1\fP ! 409: (a b c d e f) ; but in doing so alters lis1 ! 410: .Ee ! 411: ! 412: .Lf reverse "'l_arg" ! 413: .Lx nreverse "'l_arg" ! 414: .Re ! 415: the list l_arg with the elements at the top ! 416: level in reverse order. ! 417: .No ! 418: The function ! 419: .i nreverse ! 420: does the reversal in place, ! 421: that is the list structure is modified. ! 422: .Lf nreconc "'l_arg 'g_arg" ! 423: .Eq ! 424: \fI(nconc (nreverse 'l_arg) 'g_arg)\fP ! 425: ! 426: .sh 2 Predicates ! 427: .pp ! 428: The following functions test for properties of data objects. ! 429: When the result of the test is either 'false' or 'true', then ! 430: \fBnil\fP will be returned for 'false' and something other than ! 431: \fBnil\fP (often \fBt\fP) will be returned for 'true'. ! 432: .Lf arrayp "'g_arg" ! 433: .Re ! 434: t iff g_arg is of type array. ! 435: .Lf atom "'g_arg" ! 436: .Re ! 437: t iff g_arg is not a list or hunk object. ! 438: .No ! 439: \fI(atom '())\fP returns t. ! 440: .Lf bcdp "'g_arg" ! 441: .Re ! 442: t iff g_arg is a data object of type binary. ! 443: .No ! 444: This function is a throwback to the PDP-11 Lisp system. ! 445: The name stands for binary code predicate. ! 446: .Lf bigp "'g_arg" ! 447: .Re ! 448: t iff g_arg is a bignum. ! 449: .Lf dtpr "'g_arg" ! 450: .Re ! 451: t iff g_arg is a list cell. ! 452: .No ! 453: that (dtpr '()) is nil. ! 454: .Lf hunkp "'g_arg" ! 455: .Re ! 456: t iff g_arg is a hunk. ! 457: .Lf listp "'g_arg" ! 458: .Re ! 459: t iff g_arg is a list object or nil. ! 460: .Lf stringp "'g_arg" ! 461: .Re ! 462: t iff g_arg is a string. ! 463: .Lf symbolp "'g_arg" ! 464: .Re ! 465: t iff g_arg is a symbol. ! 466: .Lf valuep "'g_arg" ! 467: .Re ! 468: t iff g_arg is a value cell ! 469: .Lf vectorp 'v_vector ! 470: .Re ! 471: \fBt\fP iff the argument is a vector. ! 472: .Lf vectorip 'v_vector ! 473: .Re ! 474: \fBt\fP iff the argument is an immediate-vector. ! 475: .Lf type "'g_arg" ! 476: .Lx typep "'g_arg" ! 477: .Re ! 478: a symbol whose pname describes the type of g_arg. ! 479: .Lf signp "s_test 'g_val" ! 480: .Re ! 481: t iff g_val is a number and the given test s_test on g_val returns true. ! 482: .No ! 483: The fact that ! 484: .i signp ! 485: simply returns nil if g_val is not a number is probably the most ! 486: important reason that ! 487: .i signp ! 488: is used. ! 489: The permitted values for s_test and what they mean are given in this table. ! 490: .(b ! 491: .TS ! 492: center box; ! 493: l l . ! 494: s_test tested ! 495: ! 496: = ! 497: l g_val < 0 ! 498: le g_val \(<= 0 ! 499: e g_val = 0 ! 500: n g_val \(!= 0 ! 501: ge g_val \(>= 0 ! 502: g g_val > 0 ! 503: .TE ! 504: .)b ! 505: .Lf eq "'g_arg1 'g_arg2" ! 506: .Re ! 507: t if g_arg1 and g_arg2 are the exact same lisp object. ! 508: .No ! 509: .i Eq ! 510: simply tests if g_arg1 and g_arg2 are located in the exact same ! 511: place in memory. ! 512: Lisp objects which print the same are not necessarily ! 513: .i eq . ! 514: The only objects guaranteed to be ! 515: .i eq ! 516: are interned symbols with the same print name. ! 517: [Unless a symbol is created in a special way (such as with ! 518: .i uconcat ! 519: or ! 520: .i maknam ) ! 521: it will be interned.] ! 522: .Lf neq "'g_x 'g_y" ! 523: .Re ! 524: t if g_x is not ! 525: .i eq ! 526: to g_y, otherwise nil. ! 527: .Lf equal "'g_arg1 'g_arg2" ! 528: .Lx eqstr "'g_arg1 'g_arg2" ! 529: .Re ! 530: t iff g_arg1 and g_arg2 have the same structure as described below. ! 531: .No ! 532: g_arg and g_arg2 are ! 533: .i equal ! 534: if ! 535: .np ! 536: they are \fIeq\fP. ! 537: .np ! 538: they are both fixnums with the same value ! 539: .np ! 540: they are both flonums with the same value ! 541: .np ! 542: they are both bignums with the same value ! 543: .np ! 544: they are both strings and are identical. ! 545: .np ! 546: they are both lists and their cars and cdrs are ! 547: .i equal . ! 548: .Eb ! 549: ; \fIeq\fP is much faster than \fIequal\fP, especially in compiled code, ! 550: ; however you cannot use \fIeq\fP to test for equality of numbers outside ! 551: ; of the range -1024 to 1023. \fIequal\fP will always work. ! 552: \-> \fI(eq 1023 1023)\fP ! 553: t ! 554: \-> \fI(eq 1024 1024)\fP ! 555: nil ! 556: \-> \fI(equal 1024 1024)\fP ! 557: t ! 558: .Ee ! 559: ! 560: .Lf not "'g_arg" ! 561: .Lx null "'g_arg" ! 562: .Re ! 563: t iff g_arg is nil. ! 564: ! 565: .Lf member "'g_arg1 'l_arg2" ! 566: .Lx memq "'g_arg1 'l_arg2" ! 567: .Re ! 568: that part of the l_arg2 beginning with the first occurrence ! 569: of g_arg1. ! 570: If g_arg1 is not in the top level of l_arg2, nil is returned. ! 571: .No ! 572: .i member ! 573: tests for equality with ! 574: .i equal , ! 575: .i memq ! 576: tests for equality with ! 577: .i eq . ! 578: ! 579: .sh 2 Symbols\ and\ Strings ! 580: .pp ! 581: In many of the following functions the distinction between symbols and ! 582: strings is somewhat blurred. ! 583: To remind ourselves of the difference, ! 584: a string is a null terminated sequence of characters, stored as ! 585: compactly as possible. ! 586: Strings are used as constants in ! 587: .Fr . ! 588: They ! 589: .i eval ! 590: to themselves. ! 591: A symbol has additional structure: ! 592: a value, property list, function binding, ! 593: as well as its external representation (or print-name). ! 594: If a symbol is given to one of the string manipulation functions below, its ! 595: print name will be used as the string. ! 596: .pp ! 597: Another popular way to represent strings in Lisp is as a list of fixnums ! 598: which represent characters. ! 599: The suffix 'n' to a string manipulation function indicates that it ! 600: returns a string in this form. ! 601: .sh 3 symbol\ and\ string\ creation ! 602: .Lf concat "['stn_arg1 ... ]" ! 603: .Lx uconcat "['stn_arg1 ... ]" ! 604: .Re ! 605: a symbol whose print name ! 606: is the result of concatenating the print names, ! 607: string characters or numerical representations ! 608: of the sn_arg\fIi\fP. ! 609: .No ! 610: If no arguments are given, a symbol with a null pname is returned. ! 611: \fIconcat\fP places the symbol created on the oblist, the function ! 612: .i uconcat ! 613: does the same thing but does not place the new symbol on the oblist. ! 614: .Ex ! 615: \fI(concat 'abc (add 3 4) "def")\fP = abc7def ! 616: .Lf concatl "'l_arg" ! 617: .Eq ! 618: \fI(apply 'concat 'l_arg)\fP ! 619: ! 620: .Lf implode "'l_arg" ! 621: .Lx maknam "'l_arg" ! 622: .Wh ! 623: l_arg is a list of symbols, strings and small fixnums. ! 624: .Re ! 625: The symbol whose print name is the result of concatenating the ! 626: first characters of the print names of the symbols and strings ! 627: in the list. ! 628: Any fixnums are converted to the equivalent ascii character. ! 629: In order to concatenate entire strings or print names, use the ! 630: function ! 631: .i concat . ! 632: .No ! 633: .i implode ! 634: interns the symbol it creates, ! 635: .i maknam ! 636: does not. ! 637: .Lf gensym "['s_leader]" ! 638: .Re ! 639: a new uninterned atom beginning with the first character of s_leader's ! 640: pname, or beginning with g if s_leader is not given. ! 641: .No ! 642: The symbol looks like x0nnnnn where x is s_leader's first character and ! 643: nnnnn is the number of times you have called gensym. ! 644: .Lf copysymbol "'s_arg 'g_pred" ! 645: .Re ! 646: an uninterned symbol with the same print name as s_arg. ! 647: If g_pred is non nil, then the value, function binding ! 648: and property list of the new symbol are made ! 649: .i eq ! 650: to those of s_arg. ! 651: ! 652: .Lf ascii "'x_charnum" ! 653: .Wh ! 654: x_charnum is between 0 and 255. ! 655: .Re ! 656: a symbol whose print name is the single character whose fixnum ! 657: representation is x_charnum. ! 658: ! 659: .Lf intern "'s_arg" ! 660: .Re ! 661: s_arg ! 662: .Se ! 663: s_arg is put on the oblist if it is not already there. ! 664: .Lf remob "'s_symbol" ! 665: .Re ! 666: s_symbol ! 667: .Se ! 668: s_symbol is removed from the oblist. ! 669: .Lf rematom "'s_arg" ! 670: .Re ! 671: t if s_arg is indeed an atom. ! 672: .Se ! 673: s_arg is put on the free atoms list, effectively reclaiming an ! 674: atom cell. ! 675: .No ! 676: This function does ! 677: .i not ! 678: check to see if s_arg is on the oblist or is referenced anywhere. ! 679: Thus calling ! 680: .i rematom ! 681: on an atom in the oblist may result in disaster when that atom cell ! 682: is reused! ! 683: .sh 3 string\ and\ symbol\ predicates ! 684: .Lf boundp "'s_name" ! 685: .Re ! 686: nil if s_name is unbound: that is, it has never been given a value. ! 687: If x_name has the value g_val, then (nil\ .\ g_val) is returned. ! 688: See also ! 689: .i makunbound . ! 690: .Lf alphalessp "'st_arg1 'st_arg2" ! 691: .Re ! 692: t iff the `name' of st_arg1 is alphabetically less than the ! 693: name of st_arg2. ! 694: If st_arg is a symbol then its `name' is its print name. ! 695: If st_arg is a string, then its `name' is the string itself. ! 696: .sh 3 symbol\ and\ string\ accessing ! 697: .Lf symeval "'s_arg" ! 698: .Re ! 699: the value of symbol s_arg. ! 700: .No ! 701: It is illegal to ask for the value of an unbound symbol. ! 702: This function has the same effect as ! 703: .i eval , ! 704: but compiles into much more efficient code. ! 705: .Lf get_pname "'s_arg" ! 706: .Re ! 707: the string which is the print name of s_arg. ! 708: .Lf plist "'s_arg" ! 709: .Re ! 710: the property list of s_arg. ! 711: .Lf getd "'s_arg" ! 712: .Re ! 713: the function definition of s_arg or nil if there is no function definition. ! 714: .No ! 715: the function definition may turn out to be an array header. ! 716: .Lf getchar "'s_arg 'x_index" ! 717: .Lx nthchar "'s_arg 'x_index" ! 718: .Lx getcharn "'s_arg 'x_index" ! 719: .Re ! 720: the x_index\fIth\fP character of the print name of s_arg or nil if x_index ! 721: is less than 1 or greater than the length of s_arg's print name. ! 722: .No ! 723: .i getchar ! 724: and ! 725: .i nthchar ! 726: return a symbol with a single character print name, ! 727: .i getcharn ! 728: returns the fixnum representation of the character. ! 729: .Lf substring "'st_string 'x_index ['x_length]" ! 730: .Lx substringn "'st_string 'x_index ['x_length]" ! 731: .Re ! 732: a string of length at most ! 733: x_length starting at x_index\fIth\fP character ! 734: in the string. ! 735: .No ! 736: If x_length is not given, all of the characters for x_index ! 737: to the end of the string are returned. ! 738: If x_index is negative the string begins at the ! 739: x_index\fIth\fP character from the end. ! 740: If x_index is out of bounds, nil is returned. ! 741: .No ! 742: .i substring ! 743: returns a list of symbols, ! 744: .i substringn ! 745: returns a list of fixnums. ! 746: If ! 747: .i substringn ! 748: is given a 0 x_length argument then a single fixnum ! 749: which is the x_index\fIth\fP character is returned. ! 750: .sh 3 symbol\ and\ string\ manipulation ! 751: .Lf set "'s_arg1 'g_arg2" ! 752: .Re ! 753: g_arg2. ! 754: .Se ! 755: the value of s_arg1 is set to g_arg2. ! 756: .Lf setq "s_atm1 'g_val1 [ s_atm2 'g_val2 ... ... ]" ! 757: .Wh ! 758: the arguments are pairs of atom names and expressions. ! 759: .Re ! 760: the last g_val\fIi\fP. ! 761: .Se ! 762: each s_atm\fIi\fP is set to have the value g_val\fIi\fP. ! 763: .No ! 764: .i set ! 765: evaluates all of its arguments, ! 766: .i setq ! 767: does not evaluate the s_atm\fIi\fP. ! 768: .Lf desetq "sl_pattern1 'g_exp1 [... ...]" ! 769: .Re ! 770: g_expn ! 771: .Se ! 772: This acts just like \fIsetq\fP if all the sl_pattern\fIi\fP are symbols. ! 773: If sl_pattern\fIi\fP is a list then it is a template which should ! 774: have the same structure as g_exp\fIi\fP ! 775: The symbols in sl_pattern are assigned to the corresponding ! 776: parts of g_exp. ! 777: (See also ! 778: .i setf ! 779: ) ! 780: .Ex ! 781: \fI(desetq (a b (c . d)) '(1 2 (3 4 5)))\fP ! 782: .br ! 783: sets a to 1, b to 2, c to 3, and d to (4 5). ! 784: ! 785: .Lf setplist "'s_atm 'l_plist" ! 786: .Re ! 787: l_plist. ! 788: .Se ! 789: the property list of s_atm is set to l_plist. ! 790: .Lf makunbound "'s_arg" ! 791: .Re ! 792: s_arg ! 793: .Se ! 794: the value of s_arg is made `unbound'. ! 795: If the interpreter attempts to evaluate s_arg before it is again ! 796: given a value, an unbound variable error will occur. ! 797: .Lf aexplode "'s_arg" ! 798: .Lx explode "'g_arg" ! 799: .Lx aexplodec "'s_arg" ! 800: .Lx explodec "'g_arg" ! 801: .Lx aexploden "'s_arg" ! 802: .Lx exploden "'g_arg" ! 803: .Re ! 804: a list of the characters used to print out s_arg or g_arg. ! 805: .No ! 806: The functions beginning with 'a' are internal functions which are limited ! 807: to symbol arguments. ! 808: The functions ! 809: .i aexplode ! 810: and ! 811: .i explode ! 812: return a list of characters which ! 813: .i print ! 814: would use to print the argument. ! 815: These characters include all necessary escape characters. ! 816: Functions ! 817: .i aexplodec ! 818: and ! 819: .i explodec ! 820: return a list of characters which ! 821: .i patom ! 822: would use to print the argument (i.e. no escape characters). ! 823: Functions ! 824: .i aexploden ! 825: and ! 826: .i exploden ! 827: are similar to ! 828: .i aexplodec ! 829: and ! 830: .i explodec ! 831: except that a list of fixnum equivalents of characters are returned. ! 832: .Eb ! 833: \-> \fI(setq x '|quote this \e| ok?|)\fP ! 834: |quote this \e| ok?| ! 835: \-> \fI(explode x)\fP ! 836: (q u o t e |\e\e| | | t h i s |\e\e| | | |\e\e| |\e|| |\e\e| | | o k ?) ! 837: ; note that |\e\e| just means the single character: backslash. ! 838: ; and |\e|| just means the single character: vertical bar ! 839: ; and | | means the single character: space ! 840: ! 841: \-> \fI(explodec x)\fP ! 842: (q u o t e | | t h i s | | |\e|| | | o k ?) ! 843: \-> \fI(exploden x)\fP ! 844: (113 117 111 116 101 32 116 104 105 115 32 124 32 111 107 63) ! 845: .Ee ! 846: .sh 2 Vectors ! 847: .pp ! 848: See Chapter 9 for a discussion of vectors. ! 849: They are less efficient that hunks but more efficient than arrays. ! 850: .sh 3 vector\ creation ! 851: .Lf new-vector "'x_size ['g_fill ['g_prop]]" ! 852: .Re ! 853: A \fBvector\fP of length x_size. ! 854: Each data entry is initialized to g_fill, or to nil, if the argument g_fill ! 855: is not present. ! 856: The vector's property is set to g_prop, or to nil, by default. ! 857: .Lf new-vectori-byte "'x_size ['g_fill ['g_prop]]" ! 858: .Lx new-vectori-word "'x_size ['g_fill ['g_prop]]" ! 859: .Lx new-vectori-long "'x_size ['g_fill ['g_prop]]" ! 860: .Re ! 861: A \fBvectori\fP with x_size elements in it. ! 862: The actual memory requirement is two long words + x_size*(n bytes), ! 863: where n is 1 for new-vector-byte, 2 for new-vector-word, or 4 for ! 864: new-vectori-long. ! 865: Each data entry is initialized to g_fill, or to zero, if the argument g_fill ! 866: is not present. ! 867: The vector's property is set to g_prop, or nil, by default. ! 868: .sp 2v ! 869: .lp ! 870: Vectors may be created by specifying multiple initial values: ! 871: .Lf vector "['g_val0 'g_val1 ...]" ! 872: .Re ! 873: a \fBvector\fP, with as many data elements as there are arguments. ! 874: It is quite possible to have a vector with no data elements. ! 875: The vector's property will be a null list. ! 876: .Lf vectori-byte "['x_val0 'x_val2 ...]" ! 877: .Lx vectori-word "['x_val0 'x_val2 ...]" ! 878: .Lx vectori-long "['x_val0 'x_val2 ...]" ! 879: .Re ! 880: a \fBvectori\fP, with as many data elements as there are arguments. ! 881: The arguments are required to be fixnums. ! 882: Only the low order byte or word is used in the case of vectori-byte ! 883: and vectori-word. ! 884: The vector's property will be null. ! 885: .sh 3 vector\ reference ! 886: .Lf vref "'v_vect 'x_index" ! 887: .Lx vrefi-byte "'V_vect 'x_bindex" ! 888: .Lx vrefi-word "'V_vect 'x_windex" ! 889: .Lx vrefi-long "'V_vect 'x_lindex" ! 890: .Re ! 891: the desired data element from a vector. ! 892: The indices must be fixnums. ! 893: Indexing is zero-based. ! 894: The vrefi functions sign extend the data. ! 895: .Lf vprop 'Vv_vect ! 896: .Re ! 897: The Lisp property associated with a vector. ! 898: .Lf vget "'Vv_vect 'g_ind" ! 899: .Re ! 900: The value stored under g_ind if the Lisp property associated ! 901: with 'Vv_vect is a disembodied property list. ! 902: .Lf vsize 'Vv_vect ! 903: .Lx vsize-byte 'V_vect ! 904: .Lx vsize-word 'V_vect ! 905: .Re ! 906: the number of data elements in the vector. For immediate-vectors, ! 907: the functions vsize-byte and vsize-word return the number of data elements, ! 908: if one thinks of the binary data as being comprised of bytes or words. ! 909: .sh 3 vector\ modfication ! 910: .Lf vset "'v_vect 'x_index 'g_val" ! 911: .Lx vseti-byte "'V_vect 'x_bindex 'x_val" ! 912: .Lx vseti-word "'V_vect 'x_windex 'x_val" ! 913: .Lx vseti-long "'V_vect 'x_lindex 'x_val" ! 914: .Re ! 915: the datum. ! 916: .Se ! 917: The indexed element of the vector is set to the value. ! 918: As noted above, for vseti-word and vseti-byte, the index ! 919: is construed as the number of the data element within ! 920: the vector. It is not a byte address. ! 921: Also, for those two functions, ! 922: the low order byte or word of x_val is what is stored. ! 923: .Lf vsetprop "'Vv_vect 'g_value" ! 924: .Re ! 925: g_value. This should be either a symbol ! 926: or a disembodied property list whose ! 927: .i car ! 928: is a symbol identifying the type of ! 929: the vector. ! 930: .Se ! 931: the property list of Vv_vect is set to g_value. ! 932: .Lf vputprop "'Vv_vect 'g_value 'g_ind" ! 933: .Re ! 934: g_value. ! 935: .Se ! 936: If the vector property of Vv_vect is a disembodied property list, ! 937: then vputprop adds the value g_value under the indicator g_ind. ! 938: Otherwise, the old vector property is made the first ! 939: element of the list. ! 940: .sh 2 Arrays ! 941: .pp ! 942: See Chapter 9 for a complete description of arrays. ! 943: Some of these functions are part of a Maclisp array ! 944: compatibility package representing only one simple way of using the ! 945: array structure of ! 946: .Fr . ! 947: .sh 3 array\ creation ! 948: .Lf marray "'g_data 's_access 'g_aux 'x_length 'x_delta" ! 949: .Re ! 950: an array type with the fields set up from the above arguments ! 951: in the obvious way (see \(sc 1.2.10). ! 952: .Lf *array "'s_name 's_type 'x_dim1 ... 'x_dim\fIn\fP" ! 953: .Lx array "s_name s_type x_dim1 ... x_dim\fIn\fP" ! 954: .Wh ! 955: s_type may be one of t, nil, fixnum, flonum, fixnum-block and ! 956: flonum-block. ! 957: .Re ! 958: an array of type s_type with n dimensions of extents given by the ! 959: x_dim\fIi\fP. ! 960: .Se ! 961: If s_name is non nil, the function definition of s_name is ! 962: set to the array structure returned. ! 963: .No ! 964: These ! 965: functions create a Maclisp compatible array. ! 966: In ! 967: .Fr ! 968: arrays of type t, nil, fixnum and flonum are equivalent and the elements ! 969: of these arrays can be any type of lisp object. ! 970: Fixnum-block and flonum-block arrays are restricted to fixnums and flonums ! 971: respectively and are used mainly to communicate with ! 972: foreign functions (see \(sc8.5). ! 973: .No ! 974: .i *array ! 975: evaluates its arguments, ! 976: .i array ! 977: does not. ! 978: .sh 3 array\ predicate ! 979: .Lf arrayp "'g_arg" ! 980: .Re ! 981: t iff g_arg is of type array. ! 982: .sh 3 array\ accessors ! 983: ! 984: .Lf getaccess "'a_array" ! 985: .Lx getaux "'a_array" ! 986: .Lx getdelta "'a_array" ! 987: .Lx getdata "'a_array" ! 988: .Lx getlength "'a_array" ! 989: .Re ! 990: the field of the array object a_array given by the function name. ! 991: .Lf arrayref "'a_name 'x_ind" ! 992: .Re ! 993: the x_ind\fIth\fP element of the array object a_name. ! 994: x_ind of zero accesses the first element. ! 995: .No ! 996: .i arrayref ! 997: uses the data, length and delta fields of a_name to determine which ! 998: object to return. ! 999: .Lf arraycall "s_type 'as_array 'x_ind1 ... " ! 1000: .Re ! 1001: the element selected by the indices from the array a_array ! 1002: of type s_type. ! 1003: .No ! 1004: If as_array is a symbol then the function binding of this symbol should ! 1005: contain an array object. ! 1006: .br ! 1007: s_type is ignored by ! 1008: .i arraycall ! 1009: but is included for compatibility with Maclisp. ! 1010: .Lf arraydims "'s_name" ! 1011: .Re ! 1012: a list of the type and bounds of the array s_name. ! 1013: .Lf listarray "'sa_array ['x_elements]" ! 1014: .Re ! 1015: a list of all of the elements in array sa_array. ! 1016: If x_elements ! 1017: is given, then only the first x_elements are returned. ! 1018: ! 1019: .Eb ! 1020: ; We will create a 3 by 4 array of general lisp objects ! 1021: \-> \fI(array ernie t 3 4)\fP ! 1022: array[12] ! 1023: ! 1024: ; the array header is stored in the function definition slot of the ! 1025: ; symbol ernie ! 1026: \-> \fI(arrayp (getd 'ernie))\fP ! 1027: t ! 1028: \-> \fI(arraydims (getd 'ernie))\fP ! 1029: (t 3 4) ! 1030: ! 1031: ; store in ernie[2][2] the list (test list) ! 1032: \-> \fI(store (ernie 2 2) '(test list))\fP ! 1033: (test list) ! 1034: ! 1035: ; check to see if it is there ! 1036: \-> \fI(ernie 2 2)\fP ! 1037: (test list) ! 1038: ! 1039: ; now use the low level function \fIarrayref\fP to find the same element ! 1040: ; arrays are 0 based and row-major (the last subscript varies the fastest) ! 1041: ; thus element [2][2] is the 10th element , (starting at 0). ! 1042: \-> \fI(arrayref (getd 'ernie) 10)\fP ! 1043: (ptr to)(test list) ; the result is a value cell (thus the (ptr to)) ! 1044: .Ee ! 1045: .sh 3 array\ manipulation ! 1046: .Lf putaccess "'a_array 'su_func" ! 1047: .Lx putaux "'a_array 'g_aux" ! 1048: .Lx putdata "'a_array 'g_arg" ! 1049: .Lx putdelta "'a_array 'x_delta" ! 1050: .Lx putlength "'a_array 'x_length" ! 1051: .Re ! 1052: the second argument to the function. ! 1053: .Se ! 1054: The field of the array object given by the function name is replaced ! 1055: by the second argument to the function. ! 1056: .Lf store "'l_arexp 'g_val" ! 1057: .Wh ! 1058: l_arexp is an expression ! 1059: which references an array element. ! 1060: .Re ! 1061: g_val ! 1062: .Se ! 1063: the array location which contains the element which l_arexp references is ! 1064: changed to contain g_val. ! 1065: .Lf fillarray "'s_array 'l_itms" ! 1066: .Re ! 1067: s_array ! 1068: .Se ! 1069: the array s_array is filled with elements from l_itms. ! 1070: If there are not enough elements in l_itms to fill the entire array, ! 1071: then the last element of l_itms is used to fill the remaining parts ! 1072: of the array. ! 1073: .sh 2 Hunks ! 1074: .pp ! 1075: Hunks are vector-like objects whose size can range from 1 to 128 elements. ! 1076: Internally, hunks are allocated in sizes which are powers of 2. ! 1077: In order to create hunks of a given size, ! 1078: a hunk with at least that many elements is allocated ! 1079: and a distinguished symbol \s-2EMPTY\s0 is placed in those ! 1080: elements not requested. ! 1081: Most hunk functions respect those distinguished symbols, but there are ! 1082: two ! 1083: .i (*makhunk ! 1084: and ! 1085: .i *rplacx ) ! 1086: which will overwrite the distinguished symbol. ! 1087: .sh 3 hunk\ creation ! 1088: .Lf hunk "'g_val1 ['g_val2 ... 'g_val\fIn\fP]" ! 1089: .Re ! 1090: a hunk of length n whose elements are initialized to the g_val\fIi\fP. ! 1091: .No ! 1092: the maximum size of a hunk is 128. ! 1093: .Ex ! 1094: \fI(hunk 4 'sharp 'keys)\fP = {4 sharp keys} ! 1095: .Lf makhunk "'xl_arg" ! 1096: .Re ! 1097: a hunk of length xl_arg initialized to all nils if xl_arg is a fixnum. ! 1098: If xl_arg is a list, then we return a hunk of size \fI(length\ 'xl_arg)\fP ! 1099: initialized to the elements in xl_arg. ! 1100: .No ! 1101: \fI(makhunk\ '(a\ b\ c))\fP is equivalent to \fI(hunk\ 'a\ 'b\ 'c)\fP. ! 1102: .Ex ! 1103: \fI(makhunk 4)\fP = \fI{nil nil nil nil}\fP ! 1104: .Lf *makhunk "'x_arg" ! 1105: .Re ! 1106: a hunk of size 2\*[x_arg\*] initialized to \s-2EMPTY\s0. ! 1107: .No ! 1108: This is only to be used by such functions as \fIhunk\fP and \fImakhunk\fP ! 1109: which create and initialize hunks for users. ! 1110: .sh 3 hunk\ accessor ! 1111: .Lf cxr "'x_ind 'h_hunk" ! 1112: .Re ! 1113: element x_ind (starting at 0) of hunk h_hunk. ! 1114: .Lf hunk-to-list 'h_hunk ! 1115: .Re ! 1116: a list consisting of the elements of h_hunk. ! 1117: .sh 3 hunk\ manipulators ! 1118: .Lf rplacx "'x_ind 'h_hunk 'g_val" ! 1119: .Lx *rplacx "'x_ind 'h_hunk 'g_val" ! 1120: .Re ! 1121: h_hunk ! 1122: .Se ! 1123: Element x_ind (starting at 0) of h_hunk is set to g_val. ! 1124: .No ! 1125: .i rplacx ! 1126: will not modify one of the distinguished (EMPTY) elements ! 1127: whereas ! 1128: .i *rplacx ! 1129: will. ! 1130: .Lf hunksize "'h_arg" ! 1131: .Re ! 1132: the size of the hunk h_arg. ! 1133: .Ex ! 1134: \fI(hunksize (hunk 1 2 3))\fP = 3 ! 1135: .sh 2 Bcds ! 1136: .pp ! 1137: A bcd object contains a pointer to compiled code and to the type of ! 1138: function object the compiled code represents. ! 1139: .Lf getdisc "'y_bcd" ! 1140: .Lx getentry "'y_bcd" ! 1141: .Re ! 1142: the field of the bcd object given by the function name. ! 1143: .Lf putdisc "'y_func 's_discipline" ! 1144: .Re ! 1145: s_discipline ! 1146: .Se ! 1147: Sets the discipline field of y_func to s_discipline. ! 1148: .sh 2 Structures ! 1149: .pp ! 1150: There are three common structures constructed out of list cells: the ! 1151: assoc list, the property list and the tconc list. ! 1152: The functions below manipulate these structures. ! 1153: .sh 3 assoc\ list ! 1154: .pp ! 1155: An `assoc list' (or alist) is a common lisp data structure. It has the ! 1156: form ! 1157: .br ! 1158: .ce 1 ! 1159: ((key1 . value1) (key2 . value2) (key3 . value3) ... (keyn . valuen)) ! 1160: .Lf assoc "'g_arg1 'l_arg2" ! 1161: .Lx assq "'g_arg1 'l_arg2" ! 1162: .Re ! 1163: the first top level element of l_arg2 whose ! 1164: .i car ! 1165: is ! 1166: .i equal ! 1167: (with ! 1168: .i assoc ) ! 1169: or ! 1170: .i eq ! 1171: (with ! 1172: .i assq ) ! 1173: to g_arg1. ! 1174: .No ! 1175: Usually l_arg2 has an ! 1176: .i a-list ! 1177: structure and g_arg1 acts as key. ! 1178: .Lf sassoc "'g_arg1 'l_arg2 'sl_func" ! 1179: .Re ! 1180: the result of \fI(cond\ ((assoc\ 'g_arg\ 'l_arg2)\ (apply\ 'sl_func\ nil)))\fP ! 1181: .No ! 1182: sassoc is written as a macro. ! 1183: .Lf sassq "'g_arg1 'l_arg2 'sl_func" ! 1184: .Re ! 1185: the result of \fI(cond\ ((assq\ 'g_arg\ 'l_arg2)\ (apply\ 'sl_func\ nil)))\fP ! 1186: .No ! 1187: sassq is written as a macro. ! 1188: ! 1189: .Eb ! 1190: ; \fIassoc\fP or \fIassq\fP is given a key and an assoc list and returns ! 1191: ; the key and value item if it exists, they differ only in how they test ! 1192: ; for equality of the keys. ! 1193: ! 1194: \-> \fI(setq alist '((alpha . a) ( (complex key) . b) (junk . x)))\fP ! 1195: ((alpha . a) ((complex key) . b) (junk . x)) ! 1196: ! 1197: ; we should use \fIassq\fP when the key is an atom ! 1198: \-> \fI(assq 'alpha alist)\fP ! 1199: (alpha . a) ! 1200: ! 1201: ; but it may not work when the key is a list ! 1202: \-> \fI(assq '(complex key) alist)\fP ! 1203: nil ! 1204: ! 1205: ; however \fIassoc\fP will always work ! 1206: \-> \fI(assoc '(complex key) alist)\fP ! 1207: ((complex key) . b) ! 1208: .Ee ! 1209: .Lf sublis "'l_alst 'l_exp" ! 1210: .Wh ! 1211: l_alst is an ! 1212: .i a-list . ! 1213: .Re ! 1214: the list l_exp with every occurrence of key\fIi\fP replaced by val\fIi\fP. ! 1215: .No ! 1216: new list structure is returned to prevent modification of l_exp. ! 1217: When a substitution is made, a copy of the value to substitute in ! 1218: is not made. ! 1219: .sh 3 property\ list ! 1220: .pp ! 1221: A property list consists of an alternating sequence of keys and ! 1222: values. Normally a property list is stored on a symbol. A list ! 1223: is a 'disembodied' property list if it contains an odd number of ! 1224: elements, the first of which is ignored. ! 1225: .Lf plist "'s_name" ! 1226: .Re ! 1227: the property list of s_name. ! 1228: .Lf setplist "'s_atm 'l_plist" ! 1229: .Re ! 1230: l_plist. ! 1231: .Se ! 1232: the property list of s_atm is set to l_plist. ! 1233: ! 1234: .Lf get "'ls_name 'g_ind" ! 1235: .Re ! 1236: the value under indicator g_ind in ls_name's property list if ls_name ! 1237: is a symbol. ! 1238: .No ! 1239: If there is no indicator g_ind in ls_name's property list nil is returned. ! 1240: If ls_name is a list of an odd number of elements then it is a disembodied ! 1241: property list. ! 1242: \fIget\fP searches a disembodied property list by starting at its ! 1243: \fIcdr\fP, and comparing every other element with g_ind, using ! 1244: \fIeq\fP. ! 1245: .Lf getl "'ls_name 'l_indicators" ! 1246: .Re ! 1247: the property list ls_name beginning at the first indicator which is ! 1248: a member of the list l_indicators, or nil if none of the indicators ! 1249: in l_indicators are on ls_name's property list. ! 1250: .No ! 1251: If ls_name is a list, then it is assumed to be a disembodied property ! 1252: list. ! 1253: ! 1254: .Lf putprop "'ls_name 'g_val 'g_ind" ! 1255: .Lx defprop "ls_name g_val g_ind" ! 1256: .Re ! 1257: g_val. ! 1258: .Se ! 1259: Adds to the property list of ls_name the value g_val under the indicator ! 1260: g_ind. ! 1261: .No ! 1262: .i putprop ! 1263: evaluates it arguments, ! 1264: .i defprop ! 1265: does not. ! 1266: ls_name may be a disembodied property list, see \fIget\fP. ! 1267: .Lf remprop "'ls_name 'g_ind" ! 1268: .Re ! 1269: the portion of ls_name's property list beginning with the ! 1270: property under the indicator g_ind. ! 1271: If there is no g_ind indicator in ls_name's plist, nil is returned. ! 1272: .Se ! 1273: the value under indicator g_ind and g_ind itself is removed from ! 1274: the property list of ls_name. ! 1275: .No ! 1276: ls_name may be a disembodied property list, see \fIget\fP. ! 1277: ! 1278: .Eb ! 1279: \-> \fI(putprop 'xlate 'a 'alpha)\fP ! 1280: a ! 1281: \-> \fI(putprop 'xlate 'b 'beta)\fP ! 1282: b ! 1283: \-> \fI(plist 'xlate)\fP ! 1284: (alpha a beta b) ! 1285: \-> \fI(get 'xlate 'alpha)\fP ! 1286: a ! 1287: ; use of a disembodied property list: ! 1288: \-> \fI(get '(nil fateman rjf sklower kls foderaro jkf) 'sklower)\fP ! 1289: kls ! 1290: .Ee ! 1291: .sh 3 tconc\ structure ! 1292: .pp ! 1293: A tconc structure is a special type of list designed to make it ! 1294: easy to add objects to the end. ! 1295: It consists of a list cell whose ! 1296: .i car ! 1297: points to a ! 1298: list of the elements added with ! 1299: .i tconc ! 1300: or ! 1301: .i lconc ! 1302: and whose ! 1303: .i cdr ! 1304: points to the last list cell of the list pointed to by the ! 1305: .i car. ! 1306: .Lf tconc "'l_ptr 'g_x" ! 1307: .Wh ! 1308: l_ptr is a tconc structure. ! 1309: .Re ! 1310: l_ptr with g_x added to the end. ! 1311: .Lf lconc "'l_ptr 'l_x" ! 1312: .Wh ! 1313: l_ptr is a tconc structure. ! 1314: .Re ! 1315: l_ptr with the list l_x spliced in at the end. ! 1316: .Eb ! 1317: ; A \fItconc\fP structure can be initialized in two ways. ! 1318: ; nil can be given to \fItconc\fP in which case \fItconc\fP will generate ! 1319: ; a \fItconc\fP structure. ! 1320: ! 1321: \->\fI(setq foo (tconc nil 1))\fP ! 1322: ((1) 1) ! 1323: ! 1324: ; Since \fItconc\fP destructively adds to ! 1325: ; the list, you can now add to foo without using \fIsetq\fP again. ! 1326: ! 1327: \->\fI(tconc foo 2)\fP ! 1328: ((1 2) 2) ! 1329: \->\fIfoo\fP ! 1330: ((1 2) 2) ! 1331: ! 1332: ; Another way to create a null \fItconc\fP structure ! 1333: ; is to use \fI(ncons\ nil)\fP. ! 1334: ! 1335: \->\fI(setq foo (ncons nil))\fP ! 1336: (nil) ! 1337: \->\fI(tconc foo 1)\fP ! 1338: ((1) 1) ! 1339: ! 1340: ; now see what \fIlconc\fP can do ! 1341: \-> \fI(lconc foo nil)\fP ! 1342: ((1) 1) ; no change ! 1343: \-> \fI(lconc foo '(2 3 4))\fP ! 1344: ((1 2 3 4) 4) ! 1345: .Ee ! 1346: .sh 3 fclosures ! 1347: .pp ! 1348: An fclosure is a functional object which admits some data ! 1349: manipulations. They are discussed in \(sc8.4. ! 1350: Internally, they are constructed from vectors. ! 1351: .Lf fclosure "'l_vars 'g_funobj" ! 1352: .Wh ! 1353: l_vars is a list of variables, g_funobj is any object ! 1354: that can be funcalled (including, fclosures). ! 1355: .Re ! 1356: A vector which is the fclosure. ! 1357: .Lf fclosure-alist "'v_fclosure" ! 1358: .Re ! 1359: An association list representing the variables in the fclosure. ! 1360: This is a snapshot of the current state of the fclosure. ! 1361: If the bindings in the fclosure are changed, any previously ! 1362: calculated results of ! 1363: .i fclosure-alist ! 1364: will not change. ! 1365: .Lf fclosure-function "'v_fclosure" ! 1366: .Re ! 1367: the functional object part of the fclosure. ! 1368: .Lf fclosurep "'v_fclosure" ! 1369: .Re ! 1370: t iff the argument is an fclosure. ! 1371: .Lf symeval-in-fclosure "'v_fclosure 's_symbol" ! 1372: .Re ! 1373: the current binding of a particular symbol in an fclosure. ! 1374: .Lf set-in-fclosure "'v_fclosure 's_symbol 'g_newvalue" ! 1375: .Re ! 1376: g_newvalue. ! 1377: .Se ! 1378: The variable s_symbol is bound in the fclosure to g_newvalue. ! 1379: .sh 2 Random\ functions ! 1380: .pp ! 1381: The following functions don't fall into any of the classifications above. ! 1382: .Lf bcdad "'s_funcname" ! 1383: .Re ! 1384: a fixnum which is the address in memory where the function ! 1385: s_funcname begins. ! 1386: If s_funcname is not a machine coded function (binary) then ! 1387: .i bcdad ! 1388: returns nil. ! 1389: .Lf copy "'g_arg" ! 1390: .Re ! 1391: A structure ! 1392: .i equal ! 1393: to g_arg but with new list cells. ! 1394: .Lf copyint* "'x_arg" ! 1395: .Re ! 1396: a fixnum with the same value as x_arg but in a freshly allocated cell. ! 1397: .Lf cpy1 "'xvt_arg" ! 1398: .Re ! 1399: a new cell of the same type as xvt_arg with the same value as xvt_arg. ! 1400: .Lf getaddress "'s_entry1 's_binder1 'st_discipline1 [... ... ...]" ! 1401: .Re ! 1402: the binary object which s_binder1's function field is set to. ! 1403: .No ! 1404: This looks in the running lisp's symbol table for a symbol with the same ! 1405: name as s_entry\fIi\fP. ! 1406: It then creates a binary object ! 1407: whose entry field points to s_entry\fIi\fP ! 1408: and whose discipline is st_discipline\fIi\fP. ! 1409: This binary object is stored in the function field of s_binder\fIi\fP. ! 1410: If st_discipline\fIi\fP is nil, then "subroutine" is used by default. ! 1411: This is especially useful for ! 1412: .i cfasl ! 1413: users. ! 1414: .Lf macroexpand "'g_form" ! 1415: .Re ! 1416: g_form after all macros in it are ! 1417: expanded. ! 1418: .No ! 1419: This function will only macroexpand ! 1420: expressions which could be evaluated ! 1421: and it does not know about the special nlambdas such as ! 1422: .i cond ! 1423: and ! 1424: .i do , ! 1425: thus it misses many macro expansions. ! 1426: .Lf ptr "'g_arg" ! 1427: .Re ! 1428: a value cell initialized to point to g_arg. ! 1429: .Lf quote "g_arg" ! 1430: .Re ! 1431: g_arg. ! 1432: .No ! 1433: the reader allows you to abbreviate (quote foo) as 'foo. ! 1434: .Lf kwote "'g_arg" ! 1435: .Re ! 1436: \fI(list (quote quote) g_arg)\fP. ! 1437: .Lf replace "'g_arg1 'g_arg2" ! 1438: .Wh ! 1439: g_arg1 and g_arg2 must be the same type of lispval and not symbols or hunks. ! 1440: .Re ! 1441: g_arg2. ! 1442: .Se ! 1443: The effect of ! 1444: .i replace ! 1445: is dependent on the type of the g_arg\fIi\fP although one will notice ! 1446: a similarity in the effects. ! 1447: To understand what ! 1448: .i replace ! 1449: does to fixnum and flonum arguments, ! 1450: you must first understand that ! 1451: such numbers are `boxed' in ! 1452: .Fr . ! 1453: What this means is that if the symbol x has a value 32412, then in ! 1454: memory the value element of x's symbol structure contains the address of ! 1455: another word of memory (called a box) with 32412 in it. ! 1456: .br ! 1457: .sp ! 1458: Thus, there are two ways of changing the value of x: ! 1459: the first is to change ! 1460: the value element of x's symbol structure to point to a word of memory ! 1461: with a different value. ! 1462: The second way is to change the value in the box which x points to. ! 1463: The former method is used almost all of the time, the latter is ! 1464: used very rarely and has the potential to cause great confusion. ! 1465: The function ! 1466: .i replace ! 1467: allows you to do the latter, i.e., to actually change the value in ! 1468: the box. ! 1469: .br ! 1470: .sp ! 1471: You should watch out for these situations. ! 1472: If you do \fI(setq\ y\ x)\fP, ! 1473: then both x and y will point to the same box. ! 1474: If you now \fI(replace\ x\ 12345)\fP, ! 1475: then y will also have the value 12345. ! 1476: And, in fact, there may be many other pointers to that box. ! 1477: .br ! 1478: .sp ! 1479: Another problem with replacing fixnums ! 1480: is that some boxes are read-only. ! 1481: The fixnums between -1024 and 1023 are stored in a read-only area ! 1482: and attempts to replace them will result in an "Illegal memory reference" ! 1483: error (see the description of ! 1484: .i copyint* ! 1485: for a way around this problem). ! 1486: .br ! 1487: .sp ! 1488: For the other valid types, the effect of ! 1489: .i replace ! 1490: is easy to understand. ! 1491: The fields of g_val1's structure are made eq to the corresponding fields of ! 1492: g_val2's structure. ! 1493: For example, if x and y have lists as values then the effect of ! 1494: \fI(replace\ x\ y)\fP is the same as ! 1495: \fI(rplaca\ x\ (car\ y))\fP and \fI(rplacd\ x\ (cdr\ y))\fP. ! 1496: .Lf scons "'x_arg 'bs_rest" ! 1497: .Wh ! 1498: bs_rest is a bignum or nil. ! 1499: .Re ! 1500: a bignum whose first bigit is x_arg ! 1501: and whose higher order bigits are bs_rest. ! 1502: .Lf setf "g_refexpr 'g_value" ! 1503: .No ! 1504: .i setf ! 1505: is a generalization of setq. Information may be stored by ! 1506: binding variables, replacing entries of arrays, and vectors, ! 1507: or being put on property lists, among others. ! 1508: Setf will allow the user to store data into some location, ! 1509: by mentioning the operation used to refer to the location. ! 1510: Thus, the first argument may be partially evaluated, but only ! 1511: to the extent needed to calculate a reference. ! 1512: .i setf ! 1513: returns g_value. ! 1514: (Compare to ! 1515: .i desetq ! 1516: ) ! 1517: .Eb ! 1518: (setf x 3) = (setq x 3) ! 1519: (setf (car x) 3) = (rplaca x 3) ! 1520: (setf (get foo 'bar) 3) = (putprop foo 3 'bar) ! 1521: (setf (vref vector index) value) = (vset vector index value) ! 1522: .Ee ! 1523: .Lf sort "'l_data 'u_comparefn" ! 1524: .Re ! 1525: a list of the elements of l_data ordered by the comparison ! 1526: function u_comparefn. ! 1527: .Se ! 1528: the list l_data is modified rather than allocated in new storage. ! 1529: .No ! 1530: \fI(comparefn 'g_x 'g_y)\fP should return something ! 1531: non-nil if g_x can precede g_y in sorted order; nil if g_y must precede ! 1532: g_x. ! 1533: If u_comparefn is nil, ! 1534: alphabetical order will be used. ! 1535: .Lf sortcar "'l_list 'u_comparefn" ! 1536: .Re ! 1537: a list of the elements of l_list with the ! 1538: .i car 's ! 1539: ordered by the sort function u_comparefn. ! 1540: .Se ! 1541: the list l_list is modified rather than copied. ! 1542: .No ! 1543: Like \fIsort\fP, ! 1544: if u_comparefn is nil, ! 1545: alphabetical order will be used.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.