aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorJim Blandy1992-11-07 06:11:16 +0000
committerJim Blandy1992-11-07 06:11:16 +0000
commit0761aafc4586a806cc7b9d341f52957239c3e235 (patch)
tree714e47a7d6e1e3f86f621f691423c8a94772faf0 /lisp
parent448933608477ddfb8158097cfc6dca62ad8d7b88 (diff)
downloademacs-0761aafc4586a806cc7b9d341f52957239c3e235.tar.gz
emacs-0761aafc4586a806cc7b9d341f52957239c3e235.zip
* cl.el: New version - 3.0 - from Cesar Quiroz.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/cl.el601
1 files changed, 359 insertions, 242 deletions
diff --git a/lisp/cl.el b/lisp/cl.el
index 22fda0f4b94..f8de1550561 100644
--- a/lisp/cl.el
+++ b/lisp/cl.el
@@ -1,11 +1,10 @@
1;;; cl.el --- Common-Lisp extensions for GNU Emacs Lisp. 1;; Common-Lisp extensions for GNU Emacs Lisp.
2 2;; Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
3;; Copyright (C) 1987, 1988, 1989 Free Software Foundation, Inc.
4 3
5;; Author: Cesar Quiroz <quiroz@cs.rochester.edu> 4;; Author: Cesar Quiroz <quiroz@cs.rochester.edu>
6;; Keywords: extensions 5;; Keywords: extensions
7 6
8(defvar cl-version "2.0 beta 29 October 1989") 7(defvar cl-version "3.0 beta 01 November 1992")
9 8
10;; This file is part of GNU Emacs. 9;; This file is part of GNU Emacs.
11 10
@@ -24,6 +23,29 @@
24;; file named COPYING. Among other things, the copyright notice 23;; file named COPYING. Among other things, the copyright notice
25;; and this notice must be preserved on all copies. 24;; and this notice must be preserved on all copies.
26 25
26;;; Notes from Rob Austein on his mods
27;; yaya:/usr/u/sra/cl/cl.el, 5-May-1991 16:01:34, sra
28;;
29;; Slightly hacked copy of cl.el 2.0 beta 27.
30;;
31;; Various minor performance improvements:
32;; a) Don't use MAPCAR when we're going to discard its results.
33;; b) Make various macros a little more clever about optimizing
34;; generated code in common cases.
35;; c) Fix DEFSETF to expand to the right code at compile-time.
36;; d) Make various macros cleverer about generating reasonable
37;; code when compiled, particularly forms like DEFSTRUCT which
38;; are usually used at top-level and thus are only compiled if
39;; you use Hallvard Furuseth's hacked bytecomp.el.
40;;
41;; New features: GETF, REMF, and REMPROP.
42;;
43;; Notes:
44;; 1) I'm sceptical about the FBOUNDP checks in SETF. Why should
45;; the SETF expansion fail because the SETF method isn't defined
46;; at compile time? Lisp is going to check for a binding at run-time
47;; anyway, so maybe we should just assume the user's right here.
48
27;;; Commentary: 49;;; Commentary:
28 50
29;;;; These are extensions to Emacs Lisp that provide some form of 51;;;; These are extensions to Emacs Lisp that provide some form of
@@ -47,6 +69,9 @@
47;;;; the files are concatenated together one cannot ensure that 69;;;; the files are concatenated together one cannot ensure that
48;;;; declaration always precedes use. 70;;;; declaration always precedes use.
49;;;; 71;;;;
72;;;; Bug reports, suggestions and comments,
73;;;; to quiroz@cs.rochester.edu
74
50 75
51;;;; GLOBAL 76;;;; GLOBAL
52;;;; This file provides utilities and declarations that are global 77;;;; This file provides utilities and declarations that are global
@@ -64,29 +89,23 @@
64 89
65;;; Code: 90;;; Code:
66 91
67(defmacro psetq (&rest body) 92;;; This version is due to Hallvard Furuseth (hallvard@ifi.uio.no, 6 Jul 91)
68 "(psetq {var value }...) => nil 93(defmacro psetq (&rest args)
69Like setq, but all the values are computed before any assignment is made." 94 "(psetq {VARIABLE VALUE}...): In parallel, set each VARIABLE to its VALUE.
70 (let ((length (length body))) 95All the VALUEs are evaluated, and then all the VARIABLEs are set.
71 (cond ((/= (% length 2) 0) 96Aside from order of evaluation, this is the same as `setq'."
72 (error "psetq needs an even number of arguments, %d given" 97 ;; check there is a reasonable number of forms
73 length)) 98 (if (/= (% (length args) 2) 0)
74 ((null body) 99 (error "Odd number of arguments to `psetq'"))
75 '()) 100 (setq args (copy-sequence args)) ;for safety below
76 (t 101 (prog1 (cons 'setq args)
77 (list 'prog1 nil 102 (while (progn (if (not (symbolp (car args)))
78 (let ((setqs '()) 103 (error "`psetq' expected a symbol, found '%s'."
79 (bodyforms (reverse body))) 104 (prin1-to-string (car args))))
80 (while bodyforms 105 (cdr (cdr args)))
81 (let* ((value (car bodyforms)) 106 (setcdr args (list (list 'prog1 (nth 1 args)
82 (place (cadr bodyforms))) 107 (cons 'setq
83 (setq bodyforms (cddr bodyforms)) 108 (setq args (cdr (cdr args))))))))))
84 (if (null setqs)
85 (setq setqs (list 'setq place value))
86 (setq setqs (list 'setq place
87 (list 'prog1 value
88 setqs))))))
89 setqs))))))
90 109
91;;; utilities 110;;; utilities
92;;; 111;;;
@@ -111,8 +130,8 @@ symbols, the pairings list and the newsyms list are returned."
111(defun zip-lists (evens odds) 130(defun zip-lists (evens odds)
112 "Merge two lists EVENS and ODDS, taking elts from each list alternatingly. 131 "Merge two lists EVENS and ODDS, taking elts from each list alternatingly.
113EVENS and ODDS are two lists. ZIP-LISTS constructs a new list, whose 132EVENS and ODDS are two lists. ZIP-LISTS constructs a new list, whose
114even numbered elements (0,2,...) come from EVENS and whose odd numbered 133even numbered elements (0,2,...) come from EVENS and whose odd
115elements (1,3,...) come from ODDS. 134numbered elements (1,3,...) come from ODDS.
116The construction stops when the shorter list is exhausted." 135The construction stops when the shorter list is exhausted."
117 (do* ((p0 evens (cdr p0)) 136 (do* ((p0 evens (cdr p0))
118 (p1 odds (cdr p1)) 137 (p1 odds (cdr p1))
@@ -164,9 +183,11 @@ shortest list is exhausted."
164;;; larger lists. The fourth pass could be eliminated. 183;;; larger lists. The fourth pass could be eliminated.
165;;; 10 dec 1986. Emacs Lisp has no REMPROP, so I just eliminated the 184;;; 10 dec 1986. Emacs Lisp has no REMPROP, so I just eliminated the
166;;; 4th pass. 185;;; 4th pass.
186;;;
187;;; [22 April 1991, sra] REMPROP now in library, so restored 4th pass.
167(defun duplicate-symbols-p (list) 188(defun duplicate-symbols-p (list)
168 "Find all symbols appearing more than once in LIST. 189 "Find all symbols appearing more than once in LIST.
169Return a list of all such duplicates; nil if there are no duplicates." 190Return a list of all such duplicates; `nil' if there are no duplicates."
170 (let ((duplicates '()) ;result built here 191 (let ((duplicates '()) ;result built here
171 (propname (gensym)) ;we use a fresh property 192 (propname (gensym)) ;we use a fresh property
172 ) 193 )
@@ -184,8 +205,9 @@ Return a list of all such duplicates; nil if there are no duplicates."
184 (dolist (x list) 205 (dolist (x list)
185 (if (> (get x propname) 1) 206 (if (> (get x propname) 1)
186 (setq duplicates (cons x duplicates)))) 207 (setq duplicates (cons x duplicates))))
187 ;; pass 4: unmark. eliminated. 208 ;; pass 4: unmark.
188 ;; (dolist (x list) (remprop x propname)) 209 (dolist (x list)
210 (remprop x propname))
189 ;; return result 211 ;; return result
190 duplicates)) 212 duplicates))
191 213
@@ -203,14 +225,14 @@ Return a list of all such duplicates; nil if there are no duplicates."
203 225
204(defmacro defkeyword (x &optional docstring) 226(defmacro defkeyword (x &optional docstring)
205 "Make symbol X a keyword (symbol whose value is itself). 227 "Make symbol X a keyword (symbol whose value is itself).
206Optional second arg DOCSTRING is a documentation string for it." 228Optional second argument is a documentation string for it."
207 (cond ((symbolp x) 229 (cond ((symbolp x)
208 (list 'defconst x (list 'quote x) docstring)) 230 (list 'defconst x (list 'quote x) docstring))
209 (t 231 (t
210 (error "`%s' is not a symbol" (prin1-to-string x))))) 232 (error "`%s' is not a symbol" (prin1-to-string x)))))
211 233
212(defun keywordp (sym) 234(defun keywordp (sym)
213 "Return t if SYM is a keyword." 235 "t if SYM is a keyword."
214 (if (and (symbolp sym) (char-equal (aref (symbol-name sym) 0) ?\:)) 236 (if (and (symbolp sym) (char-equal (aref (symbol-name sym) 0) ?\:))
215 ;; looks like one, make sure value is right 237 ;; looks like one, make sure value is right
216 (set sym sym) 238 (set sym sym)
@@ -232,17 +254,17 @@ Otherwise it is a keyword whose name is `:' followed by SYM's name."
232;;; 254;;;
233 255
234(defvar *gentemp-index* 0 256(defvar *gentemp-index* 0
235 "Integer used by `gentemp' to produce new names.") 257 "Integer used by gentemp to produce new names.")
236 258
237(defvar *gentemp-prefix* "T$$_" 259(defvar *gentemp-prefix* "T$$_"
238 "Names generated by `gentemp begin' with this string by default.") 260 "Names generated by gentemp begin with this string by default.")
239 261
240(defun gentemp (&optional prefix oblist) 262(defun gentemp (&optional prefix oblist)
241 "Generate a fresh interned symbol. 263 "Generate a fresh interned symbol.
242There are two optional arguments, PREFIX and OBLIST. PREFIX is the string 264There are 2 optional arguments, PREFIX and OBLIST. PREFIX is the
243that begins the new name, OBLIST is the obarray used to search for old 265string that begins the new name, OBLIST is the obarray used to search for
244names. The defaults are just right, YOU SHOULD NEVER NEED THESE ARGUMENTS 266old names. The defaults are just right, YOU SHOULD NEVER NEED THESE
245IN YOUR OWN CODE." 267ARGUMENTS IN YOUR OWN CODE."
246 (if (null prefix) 268 (if (null prefix)
247 (setq prefix *gentemp-prefix*)) 269 (setq prefix *gentemp-prefix*))
248 (if (null oblist) 270 (if (null oblist)
@@ -257,15 +279,16 @@ IN YOUR OWN CODE."
257 newsymbol)) 279 newsymbol))
258 280
259(defvar *gensym-index* 0 281(defvar *gensym-index* 0
260 "Integer used by `gensym' to produce new names.") 282 "Integer used by gensym to produce new names.")
261 283
262(defvar *gensym-prefix* "G$$_" 284(defvar *gensym-prefix* "G$$_"
263 "Names generated by `gensym' begin with this string by default.") 285 "Names generated by gensym begin with this string by default.")
264 286
265(defun gensym (&optional prefix) 287(defun gensym (&optional prefix)
266 "Generate a fresh uninterned symbol. 288 "Generate a fresh uninterned symbol.
267Optional arg PREFIX is the string that begins the new name. Most people 289There is an optional argument, PREFIX. PREFIX is the
268take just the default, except when debugging needs suggest otherwise." 290string that begins the new name. Most people take just the default,
291except when debugging needs suggest otherwise."
269 (if (null prefix) 292 (if (null prefix)
270 (setq prefix *gensym-prefix*)) 293 (setq prefix *gensym-prefix*))
271 (let ((newsymbol nil) 294 (let ((newsymbol nil)
@@ -289,10 +312,10 @@ take just the default, except when debugging needs suggest otherwise."
289;;;; (quiroz@cs.rochester.edu) 312;;;; (quiroz@cs.rochester.edu)
290 313
291;;; indentation info 314;;; indentation info
292(put 'case 'lisp-indent-function 1) 315(put 'case 'lisp-indent-hook 1)
293(put 'ecase 'lisp-indent-function 1) 316(put 'ecase 'lisp-indent-hook 1)
294(put 'when 'lisp-indent-function 1) 317(put 'when 'lisp-indent-hook 1)
295(put 'unless 'lisp-indent-function 1) 318(put 'unless 'lisp-indent-hook 1)
296 319
297;;; WHEN and UNLESS 320;;; WHEN and UNLESS
298;;; These two forms are simplified ifs, with a single branch. 321;;; These two forms are simplified ifs, with a single branch.
@@ -408,29 +431,26 @@ reverse order."
408;;;; (quiroz@cs.rochester.edu) 431;;;; (quiroz@cs.rochester.edu)
409 432
410;;; some lisp-indentation information 433;;; some lisp-indentation information
411(put 'do 'lisp-indent-function 2) 434(put 'do 'lisp-indent-hook 2)
412(put 'do* 'lisp-indent-function 2) 435(put 'do* 'lisp-indent-hook 2)
413(put 'dolist 'lisp-indent-function 1) 436(put 'dolist 'lisp-indent-hook 1)
414(put 'dotimes 'lisp-indent-function 1) 437(put 'dotimes 'lisp-indent-hook 1)
415(put 'do-symbols 'lisp-indent-function 1) 438(put 'do-symbols 'lisp-indent-hook 1)
416(put 'do-all-symbols 'lisp-indent-function 1) 439(put 'do-all-symbols 'lisp-indent-hook 1)
417 440
418 441
419(defmacro do (stepforms endforms &rest body) 442(defmacro do (stepforms endforms &rest body)
420 "(do STEPFORMS ENDFORMS . BODY): Iterate BODY, stepping some local 443 "(do STEPFORMS ENDFORMS . BODY): Iterate BODY, stepping some local variables.
421variables. STEPFORMS must be a list of symbols or lists. In the second 444STEPFORMS must be a list of symbols or lists. In the second case, the
422case, the lists must start with a symbol and contain up to two more forms. 445lists must start with a symbol and contain up to two more forms. In
423In the STEPFORMS, a symbol is the same as a (symbol). The other two forms 446the STEPFORMS, a symbol is the same as a (symbol). The other 2 forms
424are the initial value (def. NIL) and the form to step (def. itself). 447are the initial value (def. NIL) and the form to step (def. itself).
425
426The values used by initialization and stepping are computed in parallel. 448The values used by initialization and stepping are computed in parallel.
427The ENDFORMS are a list (CONDITION . ENDBODY). If the CONDITION evaluates 449The ENDFORMS are a list (CONDITION . ENDBODY). If the CONDITION
428to true in any iteration, ENDBODY is evaluated and the last form in it is 450evaluates to true in any iteration, ENDBODY is evaluated and the last
429returned. 451form in it is returned.
430 452The BODY (which may be empty) is evaluated at every iteration, with
431The BODY (which may be empty) is evaluated at every iteration, with the 453the symbols of the STEPFORMS bound to the initial or stepped values."
432symbols of the STEPFORMS bound to the initial or stepped values."
433
434 ;; check the syntax of the macro 454 ;; check the syntax of the macro
435 (and (check-do-stepforms stepforms) 455 (and (check-do-stepforms stepforms)
436 (check-do-endforms endforms)) 456 (check-do-endforms endforms))
@@ -448,16 +468,13 @@ symbols of the STEPFORMS bound to the initial or stepped values."
448(defmacro do* (stepforms endforms &rest body) 468(defmacro do* (stepforms endforms &rest body)
449 "`do*' is to `do' as `let*' is to `let'. 469 "`do*' is to `do' as `let*' is to `let'.
450STEPFORMS must be a list of symbols or lists. In the second case, the 470STEPFORMS must be a list of symbols or lists. In the second case, the
451lists must start with a symbol and contain up to two more forms. In the 471lists must start with a symbol and contain up to two more forms. In
452STEPFORMS, a symbol is the same as a (symbol). The other two forms are 472the STEPFORMS, a symbol is the same as a (symbol). The other 2 forms
453the initial value (def. NIL) and the form to step (def. itself). 473are the initial value (def. NIL) and the form to step (def. itself).
454
455Initializations and steppings are done in the sequence they are written. 474Initializations and steppings are done in the sequence they are written.
456 475The ENDFORMS are a list (CONDITION . ENDBODY). If the CONDITION
457The ENDFORMS are a list (CONDITION . ENDBODY). If the CONDITION evaluates 476evaluates to true in any iteration, ENDBODY is evaluated and the last
458to true in any iteration, ENDBODY is evaluated and the last form in it is 477form in it is returned.
459returned.
460
461The BODY (which may be empty) is evaluated at every iteration, with 478The BODY (which may be empty) is evaluated at every iteration, with
462the symbols of the STEPFORMS bound to the initial or stepped values." 479the symbols of the STEPFORMS bound to the initial or stepped values."
463 ;; check the syntax of the macro 480 ;; check the syntax of the macro
@@ -501,8 +518,7 @@ the symbols of the STEPFORMS bound to the initial or stepped values."
501 518
502(defun extract-do-inits (forms) 519(defun extract-do-inits (forms)
503 "Returns a list of the initializations (for do) in FORMS 520 "Returns a list of the initializations (for do) in FORMS
504(a stepforms, see the do macro). 521--a stepforms, see the do macro--. FORMS is assumed syntactically valid."
505FORMS is assumed syntactically valid."
506 (mapcar 522 (mapcar
507 (function 523 (function
508 (lambda (entry) 524 (lambda (entry)
@@ -516,15 +532,17 @@ FORMS is assumed syntactically valid."
516;;; DO*. The writing of PSETQ has made it largely unnecessary. 532;;; DO*. The writing of PSETQ has made it largely unnecessary.
517 533
518(defun extract-do-steps (forms) 534(defun extract-do-steps (forms)
519 "EXTRACT-DO-STEPS FORMS => an s-expr. 535 "EXTRACT-DO-STEPS FORMS => an s-expr
520FORMS is the stepforms part of a DO macro (q.v.). This function constructs 536FORMS is the stepforms part of a DO macro (q.v.). This function
521an s-expression that does the stepping at the end of an iteration." 537constructs an s-expression that does the stepping at the end of an
538iteration."
522 (list (cons 'psetq (select-stepping-forms forms)))) 539 (list (cons 'psetq (select-stepping-forms forms))))
523 540
524(defun extract-do*-steps (forms) 541(defun extract-do*-steps (forms)
525 "EXTRACT-DO*-STEPS FORMS => an s-expr. 542 "EXTRACT-DO*-STEPS FORMS => an s-expr
526FORMS is the stepforms part of a DO* macro (q.v.). This function constructs 543FORMS is the stepforms part of a DO* macro (q.v.). This function
527an s-expression that does the stepping at the end of an iteration." 544constructs an s-expression that does the stepping at the end of an
545iteration."
528 (list (cons 'setq (select-stepping-forms forms)))) 546 (list (cons 'setq (select-stepping-forms forms))))
529 547
530(defun select-stepping-forms (forms) 548(defun select-stepping-forms (forms)
@@ -546,8 +564,8 @@ an s-expression that does the stepping at the end of an iteration."
546 564
547(defmacro dolist (stepform &rest body) 565(defmacro dolist (stepform &rest body)
548 "(dolist (VAR LIST [RESULTFORM]) . BODY): do BODY for each elt of LIST. 566 "(dolist (VAR LIST [RESULTFORM]) . BODY): do BODY for each elt of LIST.
549The RESULTFORM defaults to nil. The VAR is bound to successive elements 567The RESULTFORM defaults to nil. The VAR is bound to successive
550of the value of LIST and remains bound (to the nil value) when the 568elements of the value of LIST and remains bound (to the nil value) when the
551RESULTFORM is evaluated." 569RESULTFORM is evaluated."
552 ;; check sanity 570 ;; check sanity
553 (cond 571 (cond
@@ -563,23 +581,27 @@ RESULTFORM is evaluated."
563 ;; generate code 581 ;; generate code
564 (let* ((var (car stepform)) 582 (let* ((var (car stepform))
565 (listform (cadr stepform)) 583 (listform (cadr stepform))
566 (resultform (caddr stepform))) 584 (resultform (caddr stepform))
567 (list 'progn 585 (listsym (gentemp)))
568 (list 'mapcar 586 (nconc
569 (list 'function 587 (list 'let (list var (list listsym listform))
570 (cons 'lambda (cons (list var) body))) 588 (nconc
571 listform) 589 (list 'while listsym
572 (list 'let 590 (list 'setq
573 (list (list var nil)) 591 var (list 'car listsym)
574 resultform)))) 592 listsym (list 'cdr listsym)))
593 body))
594 (and resultform
595 (cons (list 'setq var nil)
596 (list resultform))))))
575 597
576(defmacro dotimes (stepform &rest body) 598(defmacro dotimes (stepform &rest body)
577 "(dotimes (VAR COUNTFORM [RESULTFORM]) . BODY): Repeat BODY, counting in VAR. 599 "(dotimes (VAR COUNTFORM [RESULTFORM]) . BODY): Repeat BODY, counting in VAR.
578The COUNTFORM should return a positive integer. The VAR is bound to 600The COUNTFORM should return a positive integer. The VAR is bound to
579successive integers from 0 to COUNTFORM - 1 and the BODY is repeated for 601successive integers from 0 to COUNTFORM-1 and the BODY is repeated for
580each of them. At the end, the RESULTFORM is evaluated and its value 602each of them. At the end, the RESULTFORM is evaluated and its value
581returned. During this last evaluation, the VAR is still bound, and its 603returned. During this last evaluation, the VAR is still bound, and its
582value is the number of times the iteration occurred. An omitted RESULTFORM 604value is the number of times the iteration occurred. An omitted RESULTFORM
583defaults to nil." 605defaults to nil."
584 ;; check sanity 606 ;; check sanity
585 (cond 607 (cond
@@ -596,14 +618,16 @@ defaults to nil."
596 (let* ((var (car stepform)) 618 (let* ((var (car stepform))
597 (countform (cadr stepform)) 619 (countform (cadr stepform))
598 (resultform (caddr stepform)) 620 (resultform (caddr stepform))
599 (newsym (gentemp))) 621 (testsym (if (consp countform) (gentemp) countform)))
622 (nconc
600 (list 623 (list
601 'let* (list (list newsym countform)) 624 'let (cons (list var -1)
602 (list* 625 (and (not (eq countform testsym))
603 'do* 626 (list (list testsym countform))))
604 (list (list var 0 (list '+ var 1))) 627 (nconc
605 (list (list '>= var newsym) resultform) 628 (list 'while (list '< (list 'setq var (list '1+ var)) testsym))
606 body)))) 629 body))
630 (and resultform (list resultform)))))
607 631
608(defmacro do-symbols (stepform &rest body) 632(defmacro do-symbols (stepform &rest body)
609 "(do_symbols (VAR [OBARRAY [RESULTFORM]]) . BODY) 633 "(do_symbols (VAR [OBARRAY [RESULTFORM]]) . BODY)
@@ -671,11 +695,6 @@ The forms in BODY should be lists, as non-lists are reserved for new features."
671;;;; Cesar Quiroz @ UofR DofCSc - Dec. 1986 695;;;; Cesar Quiroz @ UofR DofCSc - Dec. 1986
672;;;; (quiroz@cs.rochester.edu) 696;;;; (quiroz@cs.rochester.edu)
673 697
674
675
676;;; To make these faster, we define them using defsubst. This directs the
677;;; compiler to open-code these functions.
678
679;;; Synonyms for list functions 698;;; Synonyms for list functions
680(defsubst first (x) 699(defsubst first (x)
681 "Synonym for `car'" 700 "Synonym for `car'"
@@ -721,7 +740,7 @@ The forms in BODY should be lists, as non-lists are reserved for new features."
721 "Synonym for `cdr'" 740 "Synonym for `cdr'"
722 (cdr x)) 741 (cdr x))
723 742
724(defun endp (x) 743(defsubst endp (x)
725 "t if X is nil, nil if X is a cons; error otherwise." 744 "t if X is nil, nil if X is a cons; error otherwise."
726 (if (listp x) 745 (if (listp x)
727 (null x) 746 (null x)
@@ -758,18 +777,20 @@ The forms in BODY should be lists, as non-lists are reserved for new features."
758 "Return a new list like LIST but sans the last N elements. 777 "Return a new list like LIST but sans the last N elements.
759N defaults to 1. If the list doesn't have N elements, nil is returned." 778N defaults to 1. If the list doesn't have N elements, nil is returned."
760 (if (null n) (setq n 1)) 779 (if (null n) (setq n 1))
761 (reverse (nthcdr n (reverse list)))) 780 (nreverse (nthcdr n (reverse list)))) ;optim. due to macrakis@osf.org
762 781
782;;; This version due to Aaron Larson (alarson@src.honeywell.com, 26 Jul 91)
763(defun list* (arg &rest others) 783(defun list* (arg &rest others)
764 "Return a new list containing the first arguments consed onto the last arg. 784 "Return a new list containing the first arguments consed onto the last arg.
765Thus, (list* 1 2 3 '(a b)) returns (1 2 3 a b)." 785Thus, (list* 1 2 3 '(a b)) returns (1 2 3 a b)."
766 (if (null others) 786 (if (null others)
767 arg 787 arg
768 (let* ((allargs (cons arg others)) 788 (let* ((others (cons arg (copy-sequence others)))
769 (front (butlast allargs)) 789 (a others))
770 (back (last allargs))) 790 (while (cdr (cdr a))
771 (rplacd (last front) (car back)) 791 (setq a (cdr a)))
772 front))) 792 (setcdr a (car (cdr a)))
793 others)))
773 794
774(defun adjoin (item list) 795(defun adjoin (item list)
775 "Return a list which contains ITEM but is otherwise like LIST. 796 "Return a list which contains ITEM but is otherwise like LIST.
@@ -790,8 +811,8 @@ SUBLIST must be one of the links in LIST; otherwise the value is LIST itself."
790 811
791;;; The popular c[ad]*r functions and other list accessors. 812;;; The popular c[ad]*r functions and other list accessors.
792 813
793;;; To implement this efficiently, we define them using defsubst, 814;;; To implement this efficiently, a new byte compile handler is used to
794;;; which directs the compiler to open-code these functions. 815;;; generate the minimal code, saving one function call.
795 816
796(defsubst caar (X) 817(defsubst caar (X)
797 "Return the car of the car of X." 818 "Return the car of the car of X."
@@ -907,25 +928,26 @@ SUBLIST must be one of the links in LIST; otherwise the value is LIST itself."
907 928
908;;; some inverses of the accessors are needed for setf purposes 929;;; some inverses of the accessors are needed for setf purposes
909 930
910(defun setnth (n list newval) 931(defsubst setnth (n list newval)
911 "Set (nth N LIST) to NEWVAL. Returns NEWVAL." 932 "Set (nth N LIST) to NEWVAL. Returns NEWVAL."
912 (rplaca (nthcdr n list) newval)) 933 (rplaca (nthcdr n list) newval))
913 934
914(defun setnthcdr (n list newval) 935(defun setnthcdr (n list newval)
915 "(setnthcdr N LIST NEWVAL) => NEWVAL 936 "(setnthcdr N LIST NEWVAL) => NEWVAL
916As a side effect, sets the Nth cdr of LIST to NEWVAL." 937As a side effect, sets the Nth cdr of LIST to NEWVAL."
917 (cond ((< n 0) 938 (when (< n 0)
918 (error "N must be 0 or greater, not %d" n)) 939 (error "N must be 0 or greater, not %d" n))
919 ((= n 0) 940 (while (> n 0)
920 (rplaca list (car newval)) 941 (setq list (cdr list)
921 (rplacd list (cdr newval)) 942 n (- n 1)))
922 newval) 943 ;; here only if (zerop n)
923 (t 944 (rplaca list (car newval))
924 (rplacd (nthcdr (- n 1) list) newval)))) 945 (rplacd list (cdr newval))
946 newval)
925 947
926;;; A-lists machinery 948;;; A-lists machinery
927 949
928(defun acons (key item alist) 950(defsubst acons (key item alist)
929 "Return a new alist with KEY paired with ITEM; otherwise like ALIST. 951 "Return a new alist with KEY paired with ITEM; otherwise like ALIST.
930Does not copy ALIST." 952Does not copy ALIST."
931 (cons (cons key item) alist)) 953 (cons (cons key item) alist))
@@ -945,6 +967,7 @@ have the same length."
945 ((endp kptr) result) 967 ((endp kptr) result)
946 (setq result (acons key item result)))) 968 (setq result (acons key item result))))
947 969
970;;;; end of cl-lists.el
948 971
949;;;; SEQUENCES 972;;;; SEQUENCES
950;;;; Emacs Lisp provides many of the 'sequences' functionality of 973;;;; Emacs Lisp provides many of the 'sequences' functionality of
@@ -952,18 +975,19 @@ have the same length."
952;;;; 975;;;;
953 976
954 977
955(defkeyword :test "Used to designate positive (selection) tests.") 978(defkeyword :test "Used to designate positive (selection) tests.")
956(defkeyword :test-not "Used to designate negative (rejection) tests.") 979(defkeyword :test-not "Used to designate negative (rejection) tests.")
957(defkeyword :key "Used to designate component extractions.") 980(defkeyword :key "Used to designate component extractions.")
958(defkeyword :predicate "Used to define matching of sequence components.") 981(defkeyword :predicate "Used to define matching of sequence components.")
959(defkeyword :start "Inclusive low index in sequence") 982(defkeyword :start "Inclusive low index in sequence")
960(defkeyword :end "Exclusive high index in sequence") 983(defkeyword :end "Exclusive high index in sequence")
961(defkeyword :start1 "Inclusive low index in first of two sequences.") 984(defkeyword :start1 "Inclusive low index in first of two sequences.")
962(defkeyword :start2 "Inclusive low index in second of two sequences.") 985(defkeyword :start2 "Inclusive low index in second of two sequences.")
963(defkeyword :end1 "Exclusive high index in first of two sequences.") 986(defkeyword :end1 "Exclusive high index in first of two sequences.")
964(defkeyword :end2 "Exclusive high index in second of two sequences.") 987(defkeyword :end2 "Exclusive high index in second of two sequences.")
965(defkeyword :count "Number of elements to affect.") 988(defkeyword :count "Number of elements to affect.")
966(defkeyword :from-end "T when counting backwards.") 989(defkeyword :from-end "T when counting backwards.")
990(defkeyword :initial-value "For the syntax of #'reduce")
967 991
968(defun some (pred seq &rest moreseqs) 992(defun some (pred seq &rest moreseqs)
969 "Test PREDICATE on each element of SEQUENCE; is it ever non-nil? 993 "Test PREDICATE on each element of SEQUENCE; is it ever non-nil?
@@ -1195,7 +1219,7 @@ True if an -if style function was called and ITEM satisfies the
1195predicate under :predicate in KLIST." 1219predicate under :predicate in KLIST."
1196 (let ((predicate (extract-from-klist klist :predicate)) 1220 (let ((predicate (extract-from-klist klist :predicate))
1197 (keyfn (extract-from-klist klist :key 'identity))) 1221 (keyfn (extract-from-klist klist :key 'identity)))
1198 (funcall predicate item (funcall keyfn elt)))) 1222 (funcall predicate (funcall keyfn item))))
1199 1223
1200(defun elt-satisfies-if-not-p (item klist) 1224(defun elt-satisfies-if-not-p (item klist)
1201 "(elt-satisfies-if-not-p ITEM KLIST) => t or nil 1225 "(elt-satisfies-if-not-p ITEM KLIST) => t or nil
@@ -1204,7 +1228,7 @@ True if an -if-not style function was called and ITEM does not satisfy
1204the predicate under :predicate in KLIST." 1228the predicate under :predicate in KLIST."
1205 (let ((predicate (extract-from-klist klist :predicate)) 1229 (let ((predicate (extract-from-klist klist :predicate))
1206 (keyfn (extract-from-klist klist :key 'identity))) 1230 (keyfn (extract-from-klist klist :key 'identity)))
1207 (not (funcall predicate item (funcall keyfn elt))))) 1231 (not (funcall predicate (funcall keyfn item)))))
1208 1232
1209(defun elts-match-under-klist-p (e1 e2 klist) 1233(defun elts-match-under-klist-p (e1 e2 klist)
1210 "(elts-match-under-klist-p E1 E2 KLIST) => t or nil 1234 "(elts-match-under-klist-p E1 E2 KLIST) => t or nil
@@ -1313,7 +1337,7 @@ if clumsier, control over this feature."
1313 allow-other-keys))) 1337 allow-other-keys)))
1314 (nreverse forms))) 1338 (nreverse forms)))
1315 body)))) 1339 body))))
1316(put 'with-keyword-args 'lisp-indent-function 1) 1340(put 'with-keyword-args 'lisp-indent-hook 1)
1317 1341
1318 1342
1319;;; REDUCE 1343;;; REDUCE
@@ -1394,14 +1418,15 @@ returned."
1394 1418
1395(defun member (item list &rest kargs) 1419(defun member (item list &rest kargs)
1396 "Look for ITEM in LIST; return first tail of LIST the car of whose first 1420 "Look for ITEM in LIST; return first tail of LIST the car of whose first
1397cons cell tests the same as ITEM. Admits arguments :key, :test, and :test-not." 1421cons cell tests the same as ITEM. Admits arguments :key, :test, and
1422:test-not."
1398 (if (null kargs) ;treat this fast for efficiency 1423 (if (null kargs) ;treat this fast for efficiency
1399 (memq item list) 1424 (memq item list)
1400 (let* ((klist (build-klist kargs '(:test :test-not :key))) 1425 (let* ((klist (build-klist kargs '(:test :test-not :key)))
1401 (test (extract-from-klist klist :test)) 1426 (test (extract-from-klist klist :test))
1402 (testnot (extract-from-klist klist :test-not)) 1427 (testnot (extract-from-klist klist :test-not))
1403 (key (extract-from-klist klist :key 'identity))) 1428 (key (extract-from-klist klist :key 'identity)))
1404 ;; another workaround allegledly for speed 1429 ;; another workaround allegedly for speed, BLAH
1405 (if (and (or (eq test 'eq) (eq test 'eql) 1430 (if (and (or (eq test 'eq) (eq test 'eql)
1406 (eq test (symbol-function 'eq)) 1431 (eq test (symbol-function 'eq))
1407 (eq test (symbol-function 'eql))) 1432 (eq test (symbol-function 'eql)))
@@ -1448,11 +1473,11 @@ cons cell tests the same as ITEM. Admits arguments :key, :test, and :test-not."
1448;;;; (quiroz@cs.rochester.edu) 1473;;;; (quiroz@cs.rochester.edu)
1449 1474
1450;;; Lisp indentation information 1475;;; Lisp indentation information
1451(put 'multiple-value-bind 'lisp-indent-function 2) 1476(put 'multiple-value-bind 'lisp-indent-hook 2)
1452(put 'multiple-value-setq 'lisp-indent-function 2) 1477(put 'multiple-value-setq 'lisp-indent-hook 2)
1453(put 'multiple-value-list 'lisp-indent-function nil) 1478(put 'multiple-value-list 'lisp-indent-hook nil)
1454(put 'multiple-value-call 'lisp-indent-function 1) 1479(put 'multiple-value-call 'lisp-indent-hook 1)
1455(put 'multiple-value-prog1 'lisp-indent-function 1) 1480(put 'multiple-value-prog1 'lisp-indent-hook 1)
1456 1481
1457;;; Global state of the package is kept here 1482;;; Global state of the package is kept here
1458(defvar *mvalues-values* nil 1483(defvar *mvalues-values* nil
@@ -1478,7 +1503,7 @@ the first value."
1478 (car *mvalues-values*)) 1503 (car *mvalues-values*))
1479 1504
1480(defun values-list (&optional val-forms) 1505(defun values-list (&optional val-forms)
1481 "Produce multiple values (zero or mode). Each element of LIST is one value. 1506 "Produce multiple values (zero or more). Each element of LIST is one value.
1482This is equivalent to (apply 'values LIST)." 1507This is equivalent to (apply 'values LIST)."
1483 (cond ((nlistp val-forms) 1508 (cond ((nlistp val-forms)
1484 (error "Argument to values-list must be a list, not `%s'" 1509 (error "Argument to values-list must be a list, not `%s'"
@@ -1589,29 +1614,29 @@ the length of VARS (a list of symbols). VALS is just a fresh symbol."
1589;;;; (quiroz@cs.rochester.edu) 1614;;;; (quiroz@cs.rochester.edu)
1590 1615
1591 1616
1592(defun plusp (number) 1617(defsubst plusp (number)
1593 "True if NUMBER is strictly greater than zero." 1618 "True if NUMBER is strictly greater than zero."
1594 (> number 0)) 1619 (> number 0))
1595 1620
1596(defun minusp (number) 1621(defsubst minusp (number)
1597 "True if NUMBER is strictly less than zero." 1622 "True if NUMBER is strictly less than zero."
1598 (< number 0)) 1623 (< number 0))
1599 1624
1600(defun oddp (number) 1625(defsubst oddp (number)
1601 "True if INTEGER is not divisible by 2." 1626 "True if INTEGER is not divisible by 2."
1602 (/= (% number 2) 0)) 1627 (/= (% number 2) 0))
1603 1628
1604(defun evenp (number) 1629(defsubst evenp (number)
1605 "True if INTEGER is divisible by 2." 1630 "True if INTEGER is divisible by 2."
1606 (= (% number 2) 0)) 1631 (= (% number 2) 0))
1607 1632
1608(defun abs (number) 1633(defsubst abs (number)
1609 "Return the absolute value of NUMBER." 1634 "Return the absolute value of NUMBER."
1610 (if (< number 0) 1635 (if (< number 0)
1611 (- number) 1636 (- number)
1612 number)) 1637 number))
1613 1638
1614(defun signum (number) 1639(defsubst signum (number)
1615 "Return -1, 0 or 1 according to the sign of NUMBER." 1640 "Return -1, 0 or 1 according to the sign of NUMBER."
1616 (cond ((< number 0) 1641 (cond ((< number 0)
1617 -1) 1642 -1)
@@ -1701,59 +1726,56 @@ equal to the real square root of the argument."
1701(defun floor (number &optional divisor) 1726(defun floor (number &optional divisor)
1702 "Divide DIVIDEND by DIVISOR, rounding toward minus infinity. 1727 "Divide DIVIDEND by DIVISOR, rounding toward minus infinity.
1703DIVISOR defaults to 1. The remainder is produced as a second value." 1728DIVISOR defaults to 1. The remainder is produced as a second value."
1704 (cond 1729 (cond ((and (null divisor) ; trivial case
1705 ((and (null divisor) ; trivial case 1730 (numberp number))
1706 (numberp number)) 1731 (values number 0))
1707 (values number 0)) 1732 (t ; do the division
1708 (t ; do the division 1733 (multiple-value-bind
1709 (multiple-value-bind 1734 (q r s)
1710 (q r s) 1735 (safe-idiv number divisor)
1711 (safe-idiv number divisor) 1736 (cond ((zerop s)
1712 (cond ((zerop s) 1737 (values 0 0))
1713 (values 0 0)) 1738 ((plusp s)
1714 ((plusp s) 1739 (values q r))
1715 (values q r)) 1740 (t ;opposite-signs case
1716 (t ;opposite-signs case 1741 (if (zerop r)
1717 (if (zerop r) 1742 (values (- q) 0)
1718 (values (- q) 0) 1743 (let ((q (- (+ q 1))))
1719 (let ((q (- (+ q 1)))) 1744 (values q (- number (* q divisor)))))))))))
1720 (values q (- number (* q divisor)))))))))))
1721 1745
1722(defun ceiling (number &optional divisor) 1746(defun ceiling (number &optional divisor)
1723 "Divide DIVIDEND by DIVISOR, rounding toward plus infinity. 1747 "Divide DIVIDEND by DIVISOR, rounding toward plus infinity.
1724DIVISOR defaults to 1. The remainder is produced as a second value." 1748DIVISOR defaults to 1. The remainder is produced as a second value."
1725 (cond 1749 (cond ((and (null divisor) ; trivial case
1726 ((and (null divisor) ; trivial case 1750 (numberp number))
1727 (numberp number)) 1751 (values number 0))
1728 (values number 0)) 1752 (t ; do the division
1729 (t ; do the division 1753 (multiple-value-bind
1730 (multiple-value-bind 1754 (q r s)
1731 (q r s) 1755 (safe-idiv number divisor)
1732 (safe-idiv number divisor) 1756 (cond ((zerop s)
1733 (cond ((zerop s) 1757 (values 0 0))
1734 (values 0 0)) 1758 ((plusp s)
1735 ((plusp s) 1759 (values (+ q 1) (- r divisor)))
1736 (values (+ q 1) (- r divisor))) 1760 (t
1737 (t 1761 (values (- q) (+ number (* q divisor)))))))))
1738 (values (- q) (+ number (* q divisor)))))))))
1739 1762
1740(defun truncate (number &optional divisor) 1763(defun truncate (number &optional divisor)
1741 "Divide DIVIDEND by DIVISOR, rounding toward zero. 1764 "Divide DIVIDEND by DIVISOR, rounding toward zero.
1742DIVISOR defaults to 1. The remainder is produced as a second value." 1765DIVISOR defaults to 1. The remainder is produced as a second value."
1743 (cond 1766 (cond ((and (null divisor) ; trivial case
1744 ((and (null divisor) ; trivial case 1767 (numberp number))
1745 (numberp number)) 1768 (values number 0))
1746 (values number 0)) 1769 (t ; do the division
1747 (t ; do the division 1770 (multiple-value-bind
1748 (multiple-value-bind 1771 (q r s)
1749 (q r s) 1772 (safe-idiv number divisor)
1750 (safe-idiv number divisor) 1773 (cond ((zerop s)
1751 (cond ((zerop s) 1774 (values 0 0))
1752 (values 0 0)) 1775 ((plusp s) ;same as floor
1753 ((plusp s) ;same as floor 1776 (values q r))
1754 (values q r)) 1777 (t ;same as ceiling
1755 (t ;same as ceiling 1778 (values (- q) (+ number (* q divisor)))))))))
1756 (values (- q) (+ number (* q divisor)))))))))
1757 1779
1758(defun round (number &optional divisor) 1780(defun round (number &optional divisor)
1759 "Divide DIVIDEND by DIVISOR, rounding to nearest integer. 1781 "Divide DIVIDEND by DIVISOR, rounding to nearest integer.
@@ -1778,18 +1800,25 @@ DIVISOR defaults to 1. The remainder is produced as a second value."
1778 (setq r (- number (* q divisor))) 1800 (setq r (- number (* q divisor)))
1779 (values q r)))))) 1801 (values q r))))))
1780 1802
1803;;; These two functions access the implementation-dependent representation of
1804;;; the multiple value returns.
1805
1781(defun mod (number divisor) 1806(defun mod (number divisor)
1782 "Return remainder of X by Y (rounding quotient toward minus infinity). 1807 "Return remainder of X by Y (rounding quotient toward minus infinity).
1783That is, the remainder goes with the quotient produced by `floor'." 1808That is, the remainder goes with the quotient produced by `floor'.
1784 (multiple-value-bind (q r) (floor number divisor) 1809Emacs Lisp hint:
1785 r)) 1810If you know that both arguments are positive, use `%' instead for speed."
1811 (floor number divisor)
1812 (cadr *mvalues-values*))
1786 1813
1787(defun rem (number divisor) 1814(defun rem (number divisor)
1788 "Return remainder of X by Y (rounding quotient toward zero). 1815 "Return remainder of X by Y (rounding quotient toward zero).
1789That is, the remainder goes with the quotient produced by `truncate'." 1816That is, the remainder goes with the quotient produced by `truncate'.
1790 (multiple-value-bind (q r) (truncate number divisor) 1817Emacs Lisp hint:
1791 r)) 1818If you know that both arguments are positive, use `%' instead for speed."
1792 1819 (truncate number divisor)
1820 (cadr *mvalues-values*))
1821
1793;;; internal utilities 1822;;; internal utilities
1794;;; 1823;;;
1795;;; safe-idiv performs an integer division with positive numbers only. 1824;;; safe-idiv performs an integer division with positive numbers only.
@@ -1801,16 +1830,14 @@ That is, the remainder goes with the quotient produced by `truncate'."
1801 1830
1802(defun safe-idiv (a b) 1831(defun safe-idiv (a b)
1803 "SAFE-IDIV A B => Q R S 1832 "SAFE-IDIV A B => Q R S
1804Q=|A|/|B|, R is the rest, S is the sign of A/B." 1833Q=|A|/|B|, S is the sign of A/B, R is the rest A - S*Q*B."
1805 (unless (and (numberp a) (numberp b)) 1834 ;; (unless (and (numberp a) (numberp b))
1806 (error "arguments to `safe-idiv' must be numbers")) 1835 ;; (error "arguments to `safe-idiv' must be numbers"))
1807 (when (zerop b) 1836 ;; (when (zerop b)
1808 (error "cannot divide %d by zero" a)) 1837 ;; (error "cannot divide %d by zero" a))
1809 (let* ((absa (abs a)) 1838 (let* ((q (/ (abs a) (abs b)))
1810 (absb (abs b)) 1839 (s (* (signum a) (signum b)))
1811 (q (/ absa absb)) 1840 (r (- a (* s q b))))
1812 (s (* (signum a) (signum b)))
1813 (r (- a (* (* s q) b))))
1814 (values q r s))) 1841 (values q r s)))
1815 1842
1816;;;; end of cl-arith.el 1843;;;; end of cl-arith.el
@@ -1871,22 +1898,29 @@ the next PLACE is evaluated."
1871 (setq head (car place)) 1898 (setq head (car place))
1872 (symbolp head) 1899 (symbolp head)
1873 (setq updatefn (get head :setf-update-fn))) 1900 (setq updatefn (get head :setf-update-fn)))
1874 (if (or (and (consp updatefn) (eq (car updatefn) 'lambda)) 1901 ;; dispatch on the type of update function
1875 (and (symbolp updatefn) 1902 (cond ((and (consp updatefn) (eq (car updatefn) 'lambda))
1876 (fboundp updatefn) 1903 (cons 'funcall
1877 (let ((defn (symbol-function updatefn))) 1904 (cons (list 'function updatefn)
1878 (or (subrp defn) 1905 (append (cdr place) (list value)))))
1879 (and (consp defn) 1906 ((and (symbolp updatefn)
1880 (eq (car defn) 'lambda)))))) 1907 (fboundp updatefn)
1881 (cons updatefn (append (cdr place) (list value))) 1908 (let ((defn (symbol-function updatefn)))
1882 (multiple-value-bind 1909 (or (subrp defn)
1883 (bindings newsyms) 1910 (and (consp defn)
1884 (pair-with-newsyms (append (cdr place) (list value))) 1911 (or (eq (car defn) 'lambda)
1885 ;; this let gets new symbols to ensure adequate 1912 (eq (car defn) 'macro))))))
1886 ;; order of evaluation of the subforms. 1913 (cons updatefn (append (cdr place) (list value))))
1887 (list 'let 1914 (t
1888 bindings 1915 (multiple-value-bind
1889 (cons updatefn newsyms))))) 1916 (bindings newsyms)
1917 (pair-with-newsyms
1918 (append (cdr place) (list value)))
1919 ;; this let gets new symbols to ensure adequate
1920 ;; order of evaluation of the subforms.
1921 (list 'let
1922 bindings
1923 (cons updatefn newsyms))))))
1890 (t 1924 (t
1891 (error "no `setf' update-function for `%s'" 1925 (error "no `setf' update-function for `%s'"
1892 (prin1-to-string place))))))))) 1926 (prin1-to-string place)))))))))
@@ -2242,6 +2276,70 @@ Thus, the values rotate through the PLACEs. Returns nil."
2242 (append (cdr newsyms) (list (car newsyms))))) 2276 (append (cdr newsyms) (list (car newsyms)))))
2243 nil)))) 2277 nil))))
2244 2278
2279;;; GETF, REMF, and REMPROP
2280;;;
2281
2282(defun getf (place indicator &optional default)
2283 "Return PLACE's PROPNAME property, or DEFAULT if not present."
2284 (while (and place (not (eq (car place) indicator)))
2285 (setq place (cdr (cdr place))))
2286 (if place
2287 (car (cdr place))
2288 default))
2289
2290(defmacro getf$setf$method (place indicator default &rest newval)
2291 "SETF method for GETF. Not for public use."
2292 (case (length newval)
2293 (0 (setq newval default default nil))
2294 (1 (setq newval (car newval)))
2295 (t (error "Wrong number of arguments to (setf (getf ...)) form")))
2296 (let ((psym (gentemp)) (isym (gentemp)) (vsym (gentemp)))
2297 (list 'let (list (list psym place)
2298 (list isym indicator)
2299 (list vsym newval))
2300 (list 'while
2301 (list 'and psym
2302 (list 'not
2303 (list 'eq (list 'car psym) isym)))
2304 (list 'setq psym (list 'cdr (list 'cdr psym))))
2305 (list 'if psym
2306 (list 'setcar (list 'cdr psym) vsym)
2307 (list 'setf place
2308 (list 'nconc place (list 'list isym newval))))
2309 vsym)))
2310
2311(defsetf getf
2312 getf$setf$method)
2313
2314(defmacro remf (place indicator)
2315 "Remove from the property list at PLACE its PROPNAME property.
2316Returns non-nil if and only if the property existed."
2317 (let ((psym (gentemp)) (isym (gentemp)))
2318 (list 'let (list (list psym place) (list isym indicator))
2319 (list 'cond
2320 (list (list 'eq isym (list 'car psym))
2321 (list 'setf place (list 'cdr (list 'cdr psym)))
2322 t)
2323 (list t
2324 (list 'setq psym (list 'cdr psym))
2325 (list 'while
2326 (list 'and (list 'cdr psym)
2327 (list 'not
2328 (list 'eq (list 'car (list 'cdr psym))
2329 isym)))
2330 (list 'setq psym (list 'cdr (list 'cdr psym))))
2331 (list 'cond
2332 (list (list 'cdr psym)
2333 (list 'setcdr psym
2334 (list 'cdr
2335 (list 'cdr (list 'cdr psym))))
2336 t)))))))
2337
2338(defun remprop (symbol indicator)
2339 "Remove SYMBOL's PROPNAME property, returning non-nil if it was present."
2340 (remf (symbol-plist symbol) indicator))
2341
2342
2245;;;; STRUCTS 2343;;;; STRUCTS
2246;;;; This file provides the structures mechanism. See the 2344;;;; This file provides the structures mechanism. See the
2247;;;; documentation for Common-Lisp's defstruct. Mine doesn't 2345;;;; documentation for Common-Lisp's defstruct. Mine doesn't
@@ -2402,9 +2500,7 @@ them. `setf' of the accessors sets their values."
2402 (list 'quote name) 2500 (list 'quote name)
2403 'args)))) 2501 'args))))
2404 (list 'fset (list 'quote copier) 2502 (list 'fset (list 'quote copier)
2405 (list 'function 2503 (list 'function 'copy-sequence))
2406 (list 'lambda (list 'struct)
2407 (list 'copy-sequence 'struct))))
2408 (let ((typetag (gensym))) 2504 (let ((typetag (gensym)))
2409 (list 'fset (list 'quote predicate) 2505 (list 'fset (list 'quote predicate)
2410 (list 2506 (list
@@ -2441,7 +2537,7 @@ them. `setf' of the accessors sets their values."
2441 (list 2537 (list
2442 (cons 'vector 2538 (cons 'vector
2443 (mapcar 2539 (mapcar
2444 '(lambda (x) (list 'quote x)) 2540 (function (lambda (x) (list 'quote x)))
2445 (cons name slots))))) 2541 (cons name slots)))))
2446 ;; generate code 2542 ;; generate code
2447 (cons 'progn 2543 (cons 'progn
@@ -2891,7 +2987,7 @@ Beware: nconc destroys its first argument! See copy-list."
2891 2987
2892;;; Copiers 2988;;; Copiers
2893 2989
2894(defun copy-list (list) 2990(defsubst copy-list (list)
2895 "Build a copy of LIST" 2991 "Build a copy of LIST"
2896 (append list '())) 2992 (append list '()))
2897 2993
@@ -3037,7 +3133,28 @@ returns false, that tail of the list if returned. Else NIL."
3037No checking is even attempted. This is just for compatibility with 3133No checking is even attempted. This is just for compatibility with
3038Common-Lisp codes." 3134Common-Lisp codes."
3039 form) 3135 form)
3136
3137;;; Due to Aaron Larson (alarson@src.honeywell.com, 26 Jul 91)
3138(put 'progv 'common-lisp-indent-hook '(4 4 &body))
3139(defmacro progv (vars vals &rest body)
3140 "progv vars vals &body forms
3141bind vars to vals then execute forms.
3142If there are more vars than vals, the extra vars are unbound, if
3143there are more vals than vars, the extra vals are just ignored."
3144 (` (progv$runtime (, vars) (, vals) (function (lambda () (,@ body))))))
3145
3146;;; To do this efficiently, it really needs to be a special form...
3147(defun progv$runtime (vars vals body)
3148 (eval (let ((vars-n-vals nil)
3149 (unbind-forms nil))
3150 (do ((r vars (cdr r))
3151 (l vals (cdr l)))
3152 ((endp r))
3153 (push (list (car r) (list 'quote (car l))) vars-n-vals)
3154 (if (null l)
3155 (push (` (makunbound '(, (car r)))) unbind-forms)))
3156 (` (let (, vars-n-vals) (,@ unbind-forms) (funcall '(, body)))))))
3040 3157
3041(provide 'cl) 3158(provide 'cl)
3042 3159
3043;;; cl.el ends here 3160;;;; end of cl.el