comparison lisp/cl-macs.el @ 2153:393039450288

[xemacs-hg @ 2004-06-26 21:25:23 by james] Synch with Emacs 21.3.
author james
date Sat, 26 Jun 2004 21:25:24 +0000
parents 15a9361e2781
children 13a418960a88
comparison
equal deleted inserted replaced
2152:d93fedcbf6be 2153:393039450288
1 ;;; cl-macs.el --- Common Lisp extensions for XEmacs Lisp (part four) 1 ;;; cl-macs.el --- Common Lisp extensions for XEmacs Lisp (part four)
2 2
3 ;; Copyright (C) 1993 Free Software Foundation, Inc. 3 ;; Copyright (C) 1993, 2003, 2004 Free Software Foundation, Inc.
4 ;; Copyright (C) 2002 Ben Wing. 4 ;; Copyright (C) 2002 Ben Wing.
5 5
6 ;; Author: Dave Gillespie <daveg@synaptics.com> 6 ;; Author: Dave Gillespie <daveg@synaptics.com>
7 ;; Version: 2.02 7 ;; Version: 2.02
8 ;; Keywords: extensions 8 ;; Keywords: extensions
22 ;; You should have received a copy of the GNU General Public License 22 ;; You should have received a copy of the GNU General Public License
23 ;; along with XEmacs; see the file COPYING. If not, write to the Free 23 ;; along with XEmacs; see the file COPYING. If not, write to the Free
24 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 24 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 ;; 02111-1307, USA. 25 ;; 02111-1307, USA.
26 26
27 ;;; Synched up with: FSF 19.34. 27 ;;; Synched up with: FSF 21.3.
28 28
29 ;;; Commentary: 29 ;;; Commentary:
30 30
31 ;; These are extensions to Emacs Lisp that provide a degree of 31 ;; These are extensions to Emacs Lisp that provide a degree of
32 ;; Common Lisp compatibility, beyond what is already built-in 32 ;; Common Lisp compatibility, beyond what is already built-in
33 ;; in Emacs Lisp. 33 ;; in Emacs Lisp.
34 ;; 34 ;;
35 ;; This package was written by Dave Gillespie; it is a complete 35 ;; This package was written by Dave Gillespie; it is a complete
36 ;; rewrite of Cesar Quiroz's original cl.el package of December 1986. 36 ;; rewrite of Cesar Quiroz's original cl.el package of December 1986.
37 ;; 37 ;;
38 ;; This package works with Emacs 18, Emacs 19, and Lucid Emacs 19.
39 ;;
40 ;; Bug reports, comments, and suggestions are welcome! 38 ;; Bug reports, comments, and suggestions are welcome!
41 39
42 ;; This file contains the portions of the Common Lisp extensions 40 ;; This file contains the portions of the Common Lisp extensions
43 ;; package which should be autoloaded, but need only be present 41 ;; package which should be autoloaded, but need only be present
44 ;; if the compiler or interpreter is used---this file is not 42 ;; if the compiler or interpreter is used---this file is not
51 49
52 (or (memq 'cl-19 features) 50 (or (memq 'cl-19 features)
53 (error "Tried to load `cl-macs' before `cl'!")) 51 (error "Tried to load `cl-macs' before `cl'!"))
54 52
55 53
56 ;;; We define these here so that this file can compile without having
57 ;;; loaded the cl.el file already.
58
59 (defmacro cl-push (x place) (list 'setq place (list 'cons x place)))
60 (defmacro cl-pop (place)
61 (list 'car (list 'prog1 place (list 'setq place (list 'cdr place)))))
62 (defmacro cl-pop2 (place) 54 (defmacro cl-pop2 (place)
63 (list 'prog1 (list 'car (list 'cdr place)) 55 (list 'prog1 (list 'car (list 'cdr place))
64 (list 'setq place (list 'cdr (list 'cdr place))))) 56 (list 'setq place (list 'cdr (list 'cdr place)))))
65 (put 'cl-push 'edebug-form-spec 'edebug-sexps)
66 (put 'cl-pop 'edebug-form-spec 'edebug-sexps)
67 (put 'cl-pop2 'edebug-form-spec 'edebug-sexps) 57 (put 'cl-pop2 'edebug-form-spec 'edebug-sexps)
68 58
69 (defvar cl-emacs-type)
70 (defvar cl-optimize-safety) 59 (defvar cl-optimize-safety)
71 (defvar cl-optimize-speed) 60 (defvar cl-optimize-speed)
72 61
73 62
74 ;;; This kludge allows macros which use cl-transform-function-property 63 ;;; This kludge allows macros which use cl-transform-function-property
75 ;;; to be called at compile-time. 64 ;;; to be called at compile-time.
76 65
77 (require 66 (require
78 (progn 67 (progn
79 (or (fboundp 'defalias) (fset 'defalias 'fset))
80 (or (fboundp 'cl-transform-function-property) 68 (or (fboundp 'cl-transform-function-property)
81 (defalias 'cl-transform-function-property 69 (defalias 'cl-transform-function-property
82 #'(lambda (n p f) 70 #'(lambda (n p f)
83 (list 'put (list 'quote n) (list 'quote p) 71 (list 'put (list 'quote n) (list 'quote p)
84 (list 'function (cons 'lambda f)))))) 72 (list 'function (cons 'lambda f))))))
87 75
88 ;;; Initialization. 76 ;;; Initialization.
89 77
90 (defvar cl-old-bc-file-form nil) 78 (defvar cl-old-bc-file-form nil)
91 79
92 ;; Patch broken Emacs 18 compiler (re top-level macros).
93 ;; Emacs 19 compiler doesn't need this patch.
94 ;; Also, undo broken definition of `eql' that uses same bytecode as `eq'.
95
96 ;;;###autoload 80 ;;;###autoload
97 (defun cl-compile-time-init () 81 (defun cl-compile-time-init ()
98 (setq cl-old-bc-file-form (symbol-function 'byte-compile-file-form))
99 (or (fboundp 'byte-compile-flush-pending) ; Emacs 19 compiler?
100 (defalias 'byte-compile-file-form
101 #'(lambda (form)
102 (setq form (macroexpand form byte-compile-macro-environment))
103 (if (eq (car-safe form) 'progn)
104 (cons 'progn (mapcar 'byte-compile-file-form (cdr form)))
105 (funcall cl-old-bc-file-form form)))))
106 (put 'eql 'byte-compile 'cl-byte-compile-compiler-macro)
107 (run-hooks 'cl-hack-bytecomp-hook)) 82 (run-hooks 'cl-hack-bytecomp-hook))
83
84
85 ;;; Some predicates for analyzing Lisp forms. These are used by various
86 ;;; macro expanders to optimize the results in certain common cases.
87
88 (defconst cl-simple-funcs '(car cdr nth aref elt if and or + - 1+ 1- min max
89 car-safe cdr-safe progn prog1 prog2))
90 (defconst cl-safe-funcs '(* / % length memq list vector vectorp
91 < > <= >= = error))
92
93 ;;; Check if no side effects, and executes quickly.
94 (defun cl-simple-expr-p (x &optional size)
95 (or size (setq size 10))
96 (if (and (consp x) (not (memq (car x) '(quote function function*))))
97 (and (symbolp (car x))
98 (or (memq (car x) cl-simple-funcs)
99 (get (car x) 'side-effect-free))
100 (progn
101 (setq size (1- size))
102 (while (and (setq x (cdr x))
103 (setq size (cl-simple-expr-p (car x) size))))
104 (and (null x) (>= size 0) size)))
105 (and (> size 0) (1- size))))
106
107 (defun cl-simple-exprs-p (xs)
108 (while (and xs (cl-simple-expr-p (car xs)))
109 (setq xs (cdr xs)))
110 (not xs))
111
112 ;;; Check if no side effects.
113 (defun cl-safe-expr-p (x)
114 (or (not (and (consp x) (not (memq (car x) '(quote function function*)))))
115 (and (symbolp (car x))
116 (or (memq (car x) cl-simple-funcs)
117 (memq (car x) cl-safe-funcs)
118 (get (car x) 'side-effect-free))
119 (progn
120 (while (and (setq x (cdr x)) (cl-safe-expr-p (car x))))
121 (null x)))))
122
123 ;;; Check if constant (i.e., no side effects or dependencies).
124 (defun cl-const-expr-p (x)
125 (cond ((consp x)
126 (or (eq (car x) 'quote)
127 (and (memq (car x) '(function function*))
128 (or (symbolp (nth 1 x))
129 (and (eq (car-safe (nth 1 x)) 'lambda) 'func)))))
130 ((symbolp x) (and (memq x '(nil t)) t))
131 (t t)))
132
133 (defun cl-const-exprs-p (xs)
134 (while (and xs (cl-const-expr-p (car xs)))
135 (setq xs (cdr xs)))
136 (not xs))
137
138 (defun cl-const-expr-val (x)
139 (and (eq (cl-const-expr-p x) t) (if (consp x) (nth 1 x) x)))
140
141 (defun cl-expr-access-order (x v)
142 (if (cl-const-expr-p x) v
143 (if (consp x)
144 (progn
145 (while (setq x (cdr x)) (setq v (cl-expr-access-order (car x) v)))
146 v)
147 (if (eq x (car v)) (cdr v) '(t)))))
148
149 ;;; Count number of times X refers to Y. Return nil for 0 times.
150 (defun cl-expr-contains (x y)
151 (cond ((equal y x) 1)
152 ((and (consp x) (not (memq (car-safe x) '(quote function function*))))
153 (let ((sum 0))
154 (while x
155 (setq sum (+ sum (or (cl-expr-contains (pop x) y) 0))))
156 (and (> sum 0) sum)))
157 (t nil)))
158
159 (defun cl-expr-contains-any (x y)
160 (while (and y (not (cl-expr-contains x (car y)))) (pop y))
161 y)
162
163 ;;; Check whether X may depend on any of the symbols in Y.
164 (defun cl-expr-depends-p (x y)
165 (and (not (cl-const-expr-p x))
166 (or (not (cl-safe-expr-p x)) (cl-expr-contains-any x y))))
167
168 ;;; Symbols.
169
170 (defvar *gensym-counter*)
171
172 ;; XEmacs change: gensym and gentemp have been moved to cl.el.
108 173
109 174
110 ;;; Program structure. 175 ;;; Program structure.
111 176
112 ;;;###autoload 177 ;;;###autoload
221 ;; Do not upcase &optional, &key etc. 286 ;; Do not upcase &optional, &key etc.
222 (if (memq arg lambda-list-keywords) arg 287 (if (memq arg lambda-list-keywords) arg
223 (intern (upcase (symbol-name arg))))) 288 (intern (upcase (symbol-name arg)))))
224 ((listp arg) 289 ((listp arg)
225 (if (memq arg arglist-visited) (error 'circular-list '(arg))) 290 (if (memq arg arglist-visited) (error 'circular-list '(arg)))
226 (cl-push arg arglist-visited) 291 (push arg arglist-visited)
227 (let ((arg (copy-list arg)) junk) 292 (let ((arg (copy-list arg)) junk)
228 ;; Clean the list 293 ;; Clean the list
229 (let ((p (last arg))) (if (cdr p) (setcdr p (list '&rest (cdr p))))) 294 (let ((p (last arg))) (if (cdr p) (setcdr p (list '&rest (cdr p)))))
230 (if (setq junk (cadr (memq '&cl-defs arg))) 295 (if (setq junk (cadr (memq '&cl-defs arg)))
231 (setq arg (delq '&cl-defs (delq junk arg)))) 296 (setq arg (delq '&cl-defs (delq junk arg))))
259 (header nil) (simple-args nil) 324 (header nil) (simple-args nil)
260 (doc "")) 325 (doc ""))
261 ;; Add CL lambda list to documentation. npak@ispras.ru 326 ;; Add CL lambda list to documentation. npak@ispras.ru
262 (if (and (stringp (car body)) 327 (if (and (stringp (car body))
263 (cdr body)) 328 (cdr body))
264 (setq doc (cl-pop body))) 329 (setq doc (pop body)))
265 (cl-push (concat doc 330 (push (concat doc
266 "\nCommon Lisp lambda list:\n" 331 "\nCommon Lisp lambda list:\n"
267 " " (cl-function-arglist bind-block args) 332 " " (cl-function-arglist bind-block args)
268 "\n\n") 333 "\n\n")
269 header) 334 header)
270 335
271 (while (or (stringp (car body)) (eq (car-safe (car body)) 'interactive)) 336 (while (or (stringp (car body)) (eq (car-safe (car body)) 'interactive))
272 (cl-push (cl-pop body) header)) 337 (push (pop body) header))
273 (setq args (if (listp args) (copy-list args) (list '&rest args))) 338 (setq args (if (listp args) (copy-list args) (list '&rest args)))
274 (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p))))) 339 (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p)))))
275 (if (setq bind-defs (cadr (memq '&cl-defs args))) 340 (if (setq bind-defs (cadr (memq '&cl-defs args)))
276 (setq args (delq '&cl-defs (delq bind-defs args)) 341 (setq args (delq '&cl-defs (delq bind-defs args))
277 bind-defs (cadr bind-defs))) 342 bind-defs (cadr bind-defs)))
283 (list '&aux (list v 'cl-macro-environment)))))) 348 (list '&aux (list v 'cl-macro-environment))))))
284 (while (and args (symbolp (car args)) 349 (while (and args (symbolp (car args))
285 (not (memq (car args) '(nil &rest &body &key &aux))) 350 (not (memq (car args) '(nil &rest &body &key &aux)))
286 (not (and (eq (car args) '&optional) 351 (not (and (eq (car args) '&optional)
287 (or bind-defs (consp (cadr args)))))) 352 (or bind-defs (consp (cadr args))))))
288 (cl-push (cl-pop args) simple-args)) 353 (push (pop args) simple-args))
289 (or (eq bind-block 'cl-none) 354 (or (eq bind-block 'cl-none)
290 (setq body (list (list* 'block bind-block body)))) 355 (setq body (list (list* 'block bind-block body))))
291 (if (null args) 356 (if (null args)
292 (list* nil (nreverse simple-args) (nconc (nreverse header) body)) 357 (list* nil (nreverse simple-args) (nconc (nreverse header) body))
293 (if (memq '&optional simple-args) (cl-push '&optional args)) 358 (if (memq '&optional simple-args) (push '&optional args))
294 (cl-do-arglist args nil (- (length simple-args) 359 (cl-do-arglist args nil (- (length simple-args)
295 (if (memq '&optional simple-args) 1 0))) 360 (if (memq '&optional simple-args) 1 0)))
296 (setq bind-lets (nreverse bind-lets)) 361 (setq bind-lets (nreverse bind-lets))
297 (list* (and bind-inits (list* 'eval-when '(compile load eval) 362 (list* (and bind-inits (list* 'eval-when '(compile load eval)
298 (nreverse bind-inits))) 363 (nreverse bind-inits)))
299 (nconc (nreverse simple-args) 364 (nconc (nreverse simple-args)
300 (list '&rest (car (cl-pop bind-lets)))) 365 (list '&rest (car (pop bind-lets))))
366 ;; XEmacs change: we add usage information using Nickolay's
367 ;; approach above
301 (nconc (nreverse header) 368 (nconc (nreverse header)
302 (list (nconc (list 'let* bind-lets) 369 (list (nconc (list 'let* bind-lets)
303 (nreverse bind-forms) body))))))) 370 (nreverse bind-forms) body)))))))
304 371
305 (defun cl-do-arglist (args expr &optional num) ; uses bind-* 372 (defun cl-do-arglist (args expr &optional num) ; uses bind-*
306 (if (nlistp args) 373 (if (nlistp args)
307 (if (or (memq args lambda-list-keywords) (not (symbolp args))) 374 (if (or (memq args lambda-list-keywords) (not (symbolp args)))
308 (error "Invalid argument name: %s" args) 375 (error "Invalid argument name: %s" args)
309 (cl-push (list args expr) bind-lets)) 376 (push (list args expr) bind-lets))
310 (setq args (copy-list args)) 377 (setq args (copy-list args))
311 (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p))))) 378 (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p)))))
312 (let ((p (memq '&body args))) (if p (setcar p '&rest))) 379 (let ((p (memq '&body args))) (if p (setcar p '&rest)))
313 (if (memq '&environment args) (error "&environment used incorrectly")) 380 (if (memq '&environment args) (error "&environment used incorrectly"))
314 (let ((save-args args) 381 (let ((save-args args)
318 (laterarg nil) (exactarg nil) minarg) 385 (laterarg nil) (exactarg nil) minarg)
319 (or num (setq num 0)) 386 (or num (setq num 0))
320 (if (listp (cadr restarg)) 387 (if (listp (cadr restarg))
321 (setq restarg (gensym "--rest--")) 388 (setq restarg (gensym "--rest--"))
322 (setq restarg (cadr restarg))) 389 (setq restarg (cadr restarg)))
323 (cl-push (list restarg expr) bind-lets) 390 (push (list restarg expr) bind-lets)
324 (if (eq (car args) '&whole) 391 (if (eq (car args) '&whole)
325 (cl-push (list (cl-pop2 args) restarg) bind-lets)) 392 (push (list (cl-pop2 args) restarg) bind-lets))
326 (let ((p args)) 393 (let ((p args))
327 (setq minarg restarg) 394 (setq minarg restarg)
328 (while (and p (not (memq (car p) lambda-list-keywords))) 395 (while (and p (not (memq (car p) lambda-list-keywords)))
329 (or (eq p args) (setq minarg (list 'cdr minarg))) 396 (or (eq p args) (setq minarg (list 'cdr minarg)))
330 (setq p (cdr p))) 397 (setq p (cdr p)))
334 exactarg (not (eq args p))))) 401 exactarg (not (eq args p)))))
335 (while (and args (not (memq (car args) lambda-list-keywords))) 402 (while (and args (not (memq (car args) lambda-list-keywords)))
336 (let ((poparg (list (if (or (cdr args) (not exactarg)) 'pop 'car) 403 (let ((poparg (list (if (or (cdr args) (not exactarg)) 'pop 'car)
337 restarg))) 404 restarg)))
338 (cl-do-arglist 405 (cl-do-arglist
339 (cl-pop args) 406 (pop args)
340 (if (or laterarg (= safety 0)) poparg 407 (if (or laterarg (= safety 0)) poparg
341 (list 'if minarg poparg 408 (list 'if minarg poparg
342 (list 'signal '(quote wrong-number-of-arguments) 409 (list 'signal '(quote wrong-number-of-arguments)
343 (list 'list (and (not (eq bind-block 'cl-none)) 410 (list 'list (and (not (eq bind-block 'cl-none))
344 (list 'quote bind-block)) 411 (list 'quote bind-block))
345 (list 'length restarg))))))) 412 (list 'length restarg)))))))
346 (setq num (1+ num) laterarg t)) 413 (setq num (1+ num) laterarg t))
347 (while (and (eq (car args) '&optional) (cl-pop args)) 414 (while (and (eq (car args) '&optional) (pop args))
348 (while (and args (not (memq (car args) lambda-list-keywords))) 415 (while (and args (not (memq (car args) lambda-list-keywords)))
349 (let ((arg (cl-pop args))) 416 (let ((arg (pop args)))
350 (or (consp arg) (setq arg (list arg))) 417 (or (consp arg) (setq arg (list arg)))
351 (if (cddr arg) (cl-do-arglist (nth 2 arg) (list 'and restarg t))) 418 (if (cddr arg) (cl-do-arglist (nth 2 arg) (list 'and restarg t)))
352 (let ((def (if (cdr arg) (nth 1 arg) 419 (let ((def (if (cdr arg) (nth 1 arg)
353 (or (car bind-defs) 420 (or (car bind-defs)
354 (nth 1 (assq (car arg) bind-defs))))) 421 (nth 1 (assq (car arg) bind-defs)))))
359 (setq num (1+ num)))))) 426 (setq num (1+ num))))))
360 (if (eq (car args) '&rest) 427 (if (eq (car args) '&rest)
361 (let ((arg (cl-pop2 args))) 428 (let ((arg (cl-pop2 args)))
362 (if (consp arg) (cl-do-arglist arg restarg))) 429 (if (consp arg) (cl-do-arglist arg restarg)))
363 (or (eq (car args) '&key) (= safety 0) exactarg 430 (or (eq (car args) '&key) (= safety 0) exactarg
364 (cl-push (list 'if restarg 431 (push (list 'if restarg
365 (list 'signal '(quote wrong-number-of-arguments) 432 (list 'signal '(quote wrong-number-of-arguments)
366 (list 'list 433 (list 'list
367 (and (not (eq bind-block 'cl-none)) 434 (and (not (eq bind-block 'cl-none))
368 (list 'quote bind-block)) 435 (list 'quote bind-block))
369 (list '+ num (list 'length restarg))))) 436 (list '+ num (list 'length restarg)))))
370 bind-forms))) 437 bind-forms)))
371 (while (and (eq (car args) '&key) (cl-pop args)) 438 (while (and (eq (car args) '&key) (pop args))
372 (while (and args (not (memq (car args) lambda-list-keywords))) 439 (while (and args (not (memq (car args) lambda-list-keywords)))
373 (let ((arg (cl-pop args))) 440 (let ((arg (pop args)))
374 (or (consp arg) (setq arg (list arg))) 441 (or (consp arg) (setq arg (list arg)))
375 (let* ((karg (if (consp (car arg)) (caar arg) 442 (let* ((karg (if (consp (car arg)) (caar arg)
376 (intern (format ":%s" (car arg))))) 443 (intern (format ":%s" (car arg)))))
377 (varg (if (consp (car arg)) (cadar arg) (car arg))) 444 (varg (if (consp (car arg)) (cadar arg) (car arg)))
378 (def (if (cdr arg) (cadr arg) 445 (def (if (cdr arg) (cadr arg)
397 (if (eq (cl-const-expr-p def) t) 464 (if (eq (cl-const-expr-p def) t)
398 (list 465 (list
399 'quote 466 'quote
400 (list nil (cl-const-expr-val def))) 467 (list nil (cl-const-expr-val def)))
401 (list 'list nil def)))))))) 468 (list 'list nil def))))))))
402 (cl-push karg keys) 469 (push karg keys)
470 ;; XEmacs addition
403 (if (= (aref (symbol-name karg) 0) ?:) 471 (if (= (aref (symbol-name karg) 0) ?:)
404 (progn (set karg karg) 472 (progn (set karg karg)
405 (cl-push (list 'setq karg (list 'quote karg)) 473 (push (list 'setq karg (list 'quote karg))
406 bind-inits))))))) 474 bind-inits)))))))
407 (setq keys (nreverse keys)) 475 (setq keys (nreverse keys))
408 (or (and (eq (car args) '&allow-other-keys) (cl-pop args)) 476 (or (and (eq (car args) '&allow-other-keys) (pop args))
409 (null keys) (= safety 0) 477 (null keys) (= safety 0)
410 (let* ((var (gensym "--keys--")) 478 (let* ((var (gensym "--keys--"))
411 (allow '(:allow-other-keys)) 479 (allow '(:allow-other-keys))
412 (check (list 480 (check (list
413 'while var 481 'while var
425 (list 493 (list
426 'error 494 'error
427 (format "Keyword argument %%s not one of %s" 495 (format "Keyword argument %%s not one of %s"
428 keys) 496 keys)
429 (list 'car var))))))) 497 (list 'car var)))))))
430 (cl-push (list 'let (list (list var restarg)) check) bind-forms))) 498 (push (list 'let (list (list var restarg)) check) bind-forms)))
431 (while (and (eq (car args) '&aux) (cl-pop args)) 499 (while (and (eq (car args) '&aux) (pop args))
432 (while (and args (not (memq (car args) lambda-list-keywords))) 500 (while (and args (not (memq (car args) lambda-list-keywords)))
433 (if (consp (car args)) 501 (if (consp (car args))
434 (if (and bind-enquote (cadar args)) 502 (if (and bind-enquote (cadar args))
435 (cl-do-arglist (caar args) 503 (cl-do-arglist (caar args)
436 (list 'quote (cadr (cl-pop args)))) 504 (list 'quote (cadr (pop args))))
437 (cl-do-arglist (caar args) (cadr (cl-pop args)))) 505 (cl-do-arglist (caar args) (cadr (pop args))))
438 (cl-do-arglist (cl-pop args) nil)))) 506 (cl-do-arglist (pop args) nil))))
439 (if args (error "Malformed argument list %s" save-args))))) 507 (if args (error "Malformed argument list %s" save-args)))))
440 508
441 (defun cl-arglist-args (args) 509 (defun cl-arglist-args (args)
442 (if (nlistp args) (list args) 510 (if (nlistp args) (list args)
443 (let ((res nil) (kind nil) arg) 511 (let ((res nil) (kind nil) arg)
444 (while (consp args) 512 (while (consp args)
445 (setq arg (cl-pop args)) 513 (setq arg (pop args))
446 (if (memq arg lambda-list-keywords) (setq kind arg) 514 (if (memq arg lambda-list-keywords) (setq kind arg)
447 (if (eq arg '&cl-defs) (cl-pop args) 515 (if (eq arg '&cl-defs) (pop args)
448 (and (consp arg) kind (setq arg (car arg))) 516 (and (consp arg) kind (setq arg (car arg)))
449 (and (consp arg) (cdr arg) (eq kind '&key) (setq arg (cadr arg))) 517 (and (consp arg) (cdr arg) (eq kind '&key) (setq arg (cadr arg)))
450 (setq res (nconc res (cl-arglist-args arg)))))) 518 (setq res (nconc res (cl-arglist-args arg))))))
451 (nconc res (and args (list args)))))) 519 (nconc res (and args (list args))))))
452 520
490 If `compile' is in WHEN, BODY is evaluated when compiled at top-level. 558 If `compile' is in WHEN, BODY is evaluated when compiled at top-level.
491 If `load' is in WHEN, BODY is evaluated when loaded after top-level compile. 559 If `load' is in WHEN, BODY is evaluated when loaded after top-level compile.
492 If `eval' is in WHEN, BODY is evaluated when interpreted or at non-top-level." 560 If `eval' is in WHEN, BODY is evaluated when interpreted or at non-top-level."
493 (if (and (fboundp 'cl-compiling-file) (cl-compiling-file) 561 (if (and (fboundp 'cl-compiling-file) (cl-compiling-file)
494 (not cl-not-toplevel) (not (boundp 'for-effect))) ; horrible kludge 562 (not cl-not-toplevel) (not (boundp 'for-effect))) ; horrible kludge
495 (let ((comp (or (memq 'compile when) (memq ':compile-toplevel when))) 563 (let ((comp (or (memq 'compile when) (memq :compile-toplevel when)))
496 (cl-not-toplevel t)) 564 (cl-not-toplevel t))
497 (if (or (memq 'load when) (memq ':load-toplevel when)) 565 (if (or (memq 'load when) (memq :load-toplevel when))
498 (if comp (cons 'progn (mapcar 'cl-compile-time-too body)) 566 (if comp (cons 'progn (mapcar 'cl-compile-time-too body))
499 (list* 'if nil nil body)) 567 (list* 'if nil nil body))
500 (progn (if comp (eval (cons 'progn body))) nil))) 568 (progn (if comp (eval (cons 'progn body))) nil)))
501 (and (or (memq 'eval when) (memq ':execute when)) 569 (and (or (memq 'eval when) (memq :execute when))
502 (cons 'progn body)))) 570 (cons 'progn body))))
503 571
504 (defun cl-compile-time-too (form) 572 (defun cl-compile-time-too (form)
505 (or (and (symbolp (car-safe form)) (get (car-safe form) 'byte-hunk-handler)) 573 (or (and (symbolp (car-safe form)) (get (car-safe form) 'byte-hunk-handler))
506 (setq form (macroexpand 574 (setq form (macroexpand
507 form (cons '(eval-when) byte-compile-macro-environment)))) 575 form (cons '(eval-when) byte-compile-macro-environment))))
508 (cond ((eq (car-safe form) 'progn) 576 (cond ((eq (car-safe form) 'progn)
509 (cons 'progn (mapcar 'cl-compile-time-too (cdr form)))) 577 (cons 'progn (mapcar 'cl-compile-time-too (cdr form))))
510 ((eq (car-safe form) 'eval-when) 578 ((eq (car-safe form) 'eval-when)
511 (let ((when (nth 1 form))) 579 (let ((when (nth 1 form)))
512 (if (or (memq 'eval when) (memq ':execute when)) 580 (if (or (memq 'eval when) (memq :execute when))
513 (list* 'eval-when (cons 'compile when) (cddr form)) 581 (list* 'eval-when (cons 'compile when) (cddr form))
514 form))) 582 form)))
515 (t (eval form) form))) 583 (t (eval form) form)))
516
517 (or (and (fboundp 'eval-when-compile)
518 (not (eq (car-safe (symbol-function 'eval-when-compile)) 'autoload)))
519 (eval '(defmacro eval-when-compile (&rest body)
520 "Like `progn', but evaluates the body at compile time.
521 The result of the body appears to the compiler as a quoted constant."
522 (list 'quote (eval (cons 'progn body))))))
523 584
524 ;;;###autoload 585 ;;;###autoload
525 (defmacro load-time-value (form &optional read-only) 586 (defmacro load-time-value (form &optional read-only)
526 "Like `progn', but evaluates the body at load time. 587 "Like `progn', but evaluates the body at load time.
527 The result of the body appears to the compiler as a quoted constant." 588 The result of the body appears to the compiler as a quoted constant."
562 (body (cons 623 (body (cons
563 'cond 624 'cond
564 (mapcar 625 (mapcar
565 #'(lambda (c) 626 #'(lambda (c)
566 (cons (cond ((memq (car c) '(t otherwise)) 627 (cons (cond ((memq (car c) '(t otherwise))
628 ;; XEmacs addition: check for last clause
567 (or (eq c last-clause) 629 (or (eq c last-clause)
568 (error 630 (error
569 "`%s' is allowed only as the last case clause" 631 "`%s' is allowed only as the last case clause"
570 (car c))) 632 (car c)))
571 t) 633 t)
577 (list 'member* temp (list 'quote (car c)))) 639 (list 'member* temp (list 'quote (car c))))
578 (t 640 (t
579 (if (memq (car c) head-list) 641 (if (memq (car c) head-list)
580 (error "Duplicate key in case: %s" 642 (error "Duplicate key in case: %s"
581 (car c))) 643 (car c)))
582 (cl-push (car c) head-list) 644 (push (car c) head-list)
583 (list 'eql temp (list 'quote (car c))))) 645 (list 'eql temp (list 'quote (car c)))))
584 (or (cdr c) '(nil)))) 646 (or (cdr c) '(nil))))
585 clauses)))) 647 clauses))))
586 (if (eq temp expr) body 648 (if (eq temp expr) body
587 (list 'let (list (list temp expr)) body)))) 649 (list 'let (list (list temp expr)) body))))
593 655
594 ;;;###autoload 656 ;;;###autoload
595 (defmacro ecase (expr &rest clauses) 657 (defmacro ecase (expr &rest clauses)
596 "(ecase EXPR CLAUSES...): like `case', but error if no case fits. 658 "(ecase EXPR CLAUSES...): like `case', but error if no case fits.
597 `otherwise'-clauses are not allowed." 659 `otherwise'-clauses are not allowed."
660 ;; XEmacs addition: disallow t and otherwise
598 (let ((disallowed (or (assq t clauses) 661 (let ((disallowed (or (assq t clauses)
599 (assq 'otherwise clauses)))) 662 (assq 'otherwise clauses))))
600 (if disallowed 663 (if disallowed
601 (error "`%s' is not allowed in ecase" (car disallowed)))) 664 (error "`%s' is not allowed in ecase" (car disallowed))))
602 (list* 'case expr (append clauses '((ecase-error-flag))))) 665 (list* 'case expr (append clauses '((ecase-error-flag)))))
617 (cons (cond ((eq (car c) 'otherwise) t) 680 (cons (cond ((eq (car c) 'otherwise) t)
618 ((eq (car c) 'ecase-error-flag) 681 ((eq (car c) 'ecase-error-flag)
619 (list 'error "etypecase failed: %s, %s" 682 (list 'error "etypecase failed: %s, %s"
620 temp (list 'quote (reverse type-list)))) 683 temp (list 'quote (reverse type-list))))
621 (t 684 (t
622 (cl-push (car c) type-list) 685 (push (car c) type-list)
623 (cl-make-type-test temp (car c)))) 686 (cl-make-type-test temp (car c))))
624 (or (cdr c) '(nil)))) 687 (or (cdr c) '(nil))))
625 clauses)))) 688 clauses))))
626 (if (eq temp expr) body 689 (if (eq temp expr) body
627 (list 'let (list (list temp expr)) body)))) 690 (list 'let (list (list temp expr)) body))))
670 (let ((cl-found (assq (nth 1 (nth 1 cl-form)) cl-active-block-names))) 733 (let ((cl-found (assq (nth 1 (nth 1 cl-form)) cl-active-block-names)))
671 (if cl-found (setcdr cl-found t))) 734 (if cl-found (setcdr cl-found t)))
672 (byte-compile-normal-call (cons 'throw (cdr cl-form)))) 735 (byte-compile-normal-call (cons 'throw (cdr cl-form))))
673 736
674 ;;;###autoload 737 ;;;###autoload
675 (defmacro return (&optional res) 738 (defmacro return (&optional result)
676 "(return [RESULT]): return from the block named nil. 739 "(return [RESULT]): return from the block named nil.
677 This is equivalent to `(return-from nil RESULT)'." 740 This is equivalent to `(return-from nil RESULT)'."
678 (list 'return-from nil res)) 741 (list 'return-from nil result))
679 742
680 ;;;###autoload 743 ;;;###autoload
681 (defmacro return-from (name &optional res) 744 (defmacro return-from (name &optional result)
682 "(return-from NAME [RESULT]): return from the block named NAME. 745 "(return-from NAME [RESULT]): return from the block named NAME.
683 This jumps out to the innermost enclosing `(block NAME ...)' form, 746 This jumps out to the innermost enclosing `(block NAME ...)' form,
684 returning RESULT from that form (or nil if RESULT is omitted). 747 returning RESULT from that form (or nil if RESULT is omitted).
685 This is compatible with Common Lisp, but note that `defun' and 748 This is compatible with Common Lisp, but note that `defun' and
686 `defmacro' do not create implicit blocks as they do in Common Lisp." 749 `defmacro' do not create implicit blocks as they do in Common Lisp."
687 (let ((name2 (intern (format "--cl-block-%s--" name)))) 750 (let ((name2 (intern (format "--cl-block-%s--" name))))
688 (list 'cl-block-throw (list 'quote name2) res))) 751 (list 'cl-block-throw (list 'quote name2) result)))
689 752
690 753
691 ;;; The "loop" macro. 754 ;;; The "loop" macro.
692 755
693 (defvar args) (defvar loop-accum-var) (defvar loop-accum-vars) 756 (defvar args) (defvar loop-accum-var) (defvar loop-accum-vars)
991 (loop-map-form nil) (loop-first-flag nil) 1054 (loop-map-form nil) (loop-first-flag nil)
992 (loop-destr-temps nil) (loop-symbol-macs nil)) 1055 (loop-destr-temps nil) (loop-symbol-macs nil))
993 (setq args (append args '(cl-end-loop))) 1056 (setq args (append args '(cl-end-loop)))
994 (while (not (eq (car args) 'cl-end-loop)) (cl-parse-loop-clause)) 1057 (while (not (eq (car args) 'cl-end-loop)) (cl-parse-loop-clause))
995 (if loop-finish-flag 1058 (if loop-finish-flag
996 (cl-push (list (list loop-finish-flag t)) loop-bindings)) 1059 (push (list (list loop-finish-flag t)) loop-bindings))
997 (if loop-first-flag 1060 (if loop-first-flag
998 (progn (cl-push (list (list loop-first-flag t)) loop-bindings) 1061 (progn (push (list (list loop-first-flag t)) loop-bindings)
999 (cl-push (list 'setq loop-first-flag nil) loop-steps))) 1062 (push (list 'setq loop-first-flag nil) loop-steps)))
1000 (let* ((epilogue (nconc (nreverse loop-finally) 1063 (let* ((epilogue (nconc (nreverse loop-finally)
1001 (list (or loop-result-explicit loop-result)))) 1064 (list (or loop-result-explicit loop-result))))
1002 (ands (cl-loop-build-ands (nreverse loop-body))) 1065 (ands (cl-loop-build-ands (nreverse loop-body)))
1003 (while-body (nconc (cadr ands) (nreverse loop-steps))) 1066 (while-body (nconc (cadr ands) (nreverse loop-steps)))
1004 (body (append 1067 (body (append
1025 (list (list 'if loop-finish-flag 1088 (list (list 'if loop-finish-flag
1026 loop-result-var loop-result-var)) 1089 loop-result-var loop-result-var))
1027 (list (list 'if loop-finish-flag 1090 (list (list 'if loop-finish-flag
1028 (cons 'progn epilogue) loop-result-var))) 1091 (cons 'progn epilogue) loop-result-var)))
1029 epilogue)))) 1092 epilogue))))
1030 (if loop-result-var (cl-push (list loop-result-var) loop-bindings)) 1093 (if loop-result-var (push (list loop-result-var) loop-bindings))
1031 (while loop-bindings 1094 (while loop-bindings
1032 (if (cdar loop-bindings) 1095 (if (cdar loop-bindings)
1033 (setq body (list (cl-loop-let (cl-pop loop-bindings) body t))) 1096 (setq body (list (cl-loop-let (pop loop-bindings) body t)))
1034 (let ((lets nil)) 1097 (let ((lets nil))
1035 (while (and loop-bindings 1098 (while (and loop-bindings
1036 (not (cdar loop-bindings))) 1099 (not (cdar loop-bindings)))
1037 (cl-push (car (cl-pop loop-bindings)) lets)) 1100 (push (car (pop loop-bindings)) lets))
1038 (setq body (list (cl-loop-let lets body nil)))))) 1101 (setq body (list (cl-loop-let lets body nil))))))
1039 (if loop-symbol-macs 1102 (if loop-symbol-macs
1040 (setq body (list (list* 'symbol-macrolet loop-symbol-macs body)))) 1103 (setq body (list (list* 'symbol-macrolet loop-symbol-macs body))))
1041 (list* 'block loop-name body))))) 1104 (list* 'block loop-name body)))))
1042 1105
1043 (defun cl-parse-loop-clause () ; uses args, loop-* 1106 (defun cl-parse-loop-clause () ; uses args, loop-*
1044 (let ((word (cl-pop args)) 1107 (let ((word (pop args))
1045 (hash-types '(hash-key hash-keys hash-value hash-values)) 1108 (hash-types '(hash-key hash-keys hash-value hash-values))
1046 (key-types '(key-code key-codes key-seq key-seqs 1109 (key-types '(key-code key-codes key-seq key-seqs
1047 key-binding key-bindings))) 1110 key-binding key-bindings)))
1048 (cond 1111 (cond
1049 1112
1050 ((null args) 1113 ((null args)
1051 (error "Malformed `loop' macro")) 1114 (error "Malformed `loop' macro"))
1052 1115
1053 ((eq word 'named) 1116 ((eq word 'named)
1054 (setq loop-name (cl-pop args))) 1117 (setq loop-name (pop args)))
1055 1118
1056 ((eq word 'initially) 1119 ((eq word 'initially)
1057 (if (memq (car args) '(do doing)) (cl-pop args)) 1120 (if (memq (car args) '(do doing)) (pop args))
1058 (or (consp (car args)) (error "Syntax error on `initially' clause")) 1121 (or (consp (car args)) (error "Syntax error on `initially' clause"))
1059 (while (consp (car args)) 1122 (while (consp (car args))
1060 (cl-push (cl-pop args) loop-initially))) 1123 (push (pop args) loop-initially)))
1061 1124
1062 ((eq word 'finally) 1125 ((eq word 'finally)
1063 (if (eq (car args) 'return) 1126 (if (eq (car args) 'return)
1064 (setq loop-result-explicit (or (cl-pop2 args) '(quote nil))) 1127 (setq loop-result-explicit (or (cl-pop2 args) '(quote nil)))
1065 (if (memq (car args) '(do doing)) (cl-pop args)) 1128 (if (memq (car args) '(do doing)) (pop args))
1066 (or (consp (car args)) (error "Syntax error on `finally' clause")) 1129 (or (consp (car args)) (error "Syntax error on `finally' clause"))
1067 (if (and (eq (caar args) 'return) (null loop-name)) 1130 (if (and (eq (caar args) 'return) (null loop-name))
1068 (setq loop-result-explicit (or (nth 1 (cl-pop args)) '(quote nil))) 1131 (setq loop-result-explicit (or (nth 1 (pop args)) '(quote nil)))
1069 (while (consp (car args)) 1132 (while (consp (car args))
1070 (cl-push (cl-pop args) loop-finally))))) 1133 (push (pop args) loop-finally)))))
1071 1134
1072 ((memq word '(for as)) 1135 ((memq word '(for as))
1073 (let ((loop-for-bindings nil) (loop-for-sets nil) (loop-for-steps nil) 1136 (let ((loop-for-bindings nil) (loop-for-sets nil) (loop-for-steps nil)
1074 (ands nil)) 1137 (ands nil))
1075 (while 1138 (while
1076 (let ((var (or (cl-pop args) (gensym)))) 1139 (let ((var (or (pop args) (gensym))))
1077 (setq word (cl-pop args)) 1140 (setq word (pop args))
1078 (if (eq word 'being) (setq word (cl-pop args))) 1141 (if (eq word 'being) (setq word (pop args)))
1079 (if (memq word '(the each)) (setq word (cl-pop args))) 1142 (if (memq word '(the each)) (setq word (pop args)))
1080 (if (memq word '(buffer buffers)) 1143 (if (memq word '(buffer buffers))
1081 (setq word 'in args (cons '(buffer-list) args))) 1144 (setq word 'in args (cons '(buffer-list) args)))
1082 (cond 1145 (cond
1083 1146
1084 ((memq word '(from downfrom upfrom to downto upto 1147 ((memq word '(from downfrom upfrom to downto upto
1085 above below by)) 1148 above below by))
1086 (cl-push word args) 1149 (push word args)
1087 (if (memq (car args) '(downto above)) 1150 (if (memq (car args) '(downto above))
1088 (error "Must specify `from' value for downward loop")) 1151 (error "Must specify `from' value for downward loop"))
1089 (let* ((down (or (eq (car args) 'downfrom) 1152 (let* ((down (or (eq (car args) 'downfrom)
1090 (memq (caddr args) '(downto above)))) 1153 (memq (caddr args) '(downto above))))
1091 (excl (or (memq (car args) '(above below)) 1154 (excl (or (memq (car args) '(above below))
1099 (end-var (and (not (cl-const-expr-p end)) (gensym))) 1162 (end-var (and (not (cl-const-expr-p end)) (gensym)))
1100 (step-var (and (not (cl-const-expr-p step)) 1163 (step-var (and (not (cl-const-expr-p step))
1101 (gensym)))) 1164 (gensym))))
1102 (and step (numberp step) (<= step 0) 1165 (and step (numberp step) (<= step 0)
1103 (error "Loop `by' value is not positive: %s" step)) 1166 (error "Loop `by' value is not positive: %s" step))
1104 (cl-push (list var (or start 0)) loop-for-bindings) 1167 (push (list var (or start 0)) loop-for-bindings)
1105 (if end-var (cl-push (list end-var end) loop-for-bindings)) 1168 (if end-var (push (list end-var end) loop-for-bindings))
1106 (if step-var (cl-push (list step-var step) 1169 (if step-var (push (list step-var step)
1107 loop-for-bindings)) 1170 loop-for-bindings))
1108 (if end 1171 (if end
1109 (cl-push (list 1172 (push (list
1110 (if down (if excl '> '>=) (if excl '< '<=)) 1173 (if down (if excl '> '>=) (if excl '< '<=))
1111 var (or end-var end)) loop-body)) 1174 var (or end-var end)) loop-body))
1112 (cl-push (list var (list (if down '- '+) var 1175 (push (list var (list (if down '- '+) var
1113 (or step-var step 1))) 1176 (or step-var step 1)))
1114 loop-for-steps))) 1177 loop-for-steps)))
1115 1178
1116 ((memq word '(in in-ref on)) 1179 ((memq word '(in in-ref on))
1117 (let* ((on (eq word 'on)) 1180 (let* ((on (eq word 'on))
1118 (temp (if (and on (symbolp var)) var (gensym)))) 1181 (temp (if (and on (symbolp var)) var (gensym))))
1119 (cl-push (list temp (cl-pop args)) loop-for-bindings) 1182 (push (list temp (pop args)) loop-for-bindings)
1120 (cl-push (list 'consp temp) loop-body) 1183 (push (list 'consp temp) loop-body)
1121 (if (eq word 'in-ref) 1184 (if (eq word 'in-ref)
1122 (cl-push (list var (list 'car temp)) loop-symbol-macs) 1185 (push (list var (list 'car temp)) loop-symbol-macs)
1123 (or (eq temp var) 1186 (or (eq temp var)
1124 (progn 1187 (progn
1125 (cl-push (list var nil) loop-for-bindings) 1188 (push (list var nil) loop-for-bindings)
1126 (cl-push (list var (if on temp (list 'car temp))) 1189 (push (list var (if on temp (list 'car temp)))
1127 loop-for-sets)))) 1190 loop-for-sets))))
1128 (cl-push (list temp 1191 (push (list temp
1129 (if (eq (car args) 'by) 1192 (if (eq (car args) 'by)
1130 (let ((step (cl-pop2 args))) 1193 (let ((step (cl-pop2 args)))
1131 (if (and (memq (car-safe step) 1194 (if (and (memq (car-safe step)
1132 '(quote function 1195 '(quote function
1133 function*)) 1196 function*))
1136 (list 'funcall step temp))) 1199 (list 'funcall step temp)))
1137 (list 'cdr temp))) 1200 (list 'cdr temp)))
1138 loop-for-steps))) 1201 loop-for-steps)))
1139 1202
1140 ((eq word '=) 1203 ((eq word '=)
1141 (let* ((start (cl-pop args)) 1204 (let* ((start (pop args))
1142 (then (if (eq (car args) 'then) (cl-pop2 args) start))) 1205 (then (if (eq (car args) 'then) (cl-pop2 args) start)))
1143 (cl-push (list var nil) loop-for-bindings) 1206 (push (list var nil) loop-for-bindings)
1144 (if (or ands (eq (car args) 'and)) 1207 (if (or ands (eq (car args) 'and))
1145 (progn 1208 (progn
1146 (cl-push (list var 1209 (push (list var
1147 (list 'if 1210 (list 'if
1148 (or loop-first-flag 1211 (or loop-first-flag
1149 (setq loop-first-flag 1212 (setq loop-first-flag
1150 (gensym))) 1213 (gensym)))
1151 start var)) 1214 start var))
1152 loop-for-sets) 1215 loop-for-sets)
1153 (cl-push (list var then) loop-for-steps)) 1216 (push (list var then) loop-for-steps))
1154 (cl-push (list var 1217 (push (list var
1155 (if (eq start then) start 1218 (if (eq start then) start
1156 (list 'if 1219 (list 'if
1157 (or loop-first-flag 1220 (or loop-first-flag
1158 (setq loop-first-flag (gensym))) 1221 (setq loop-first-flag (gensym)))
1159 start then))) 1222 start then)))
1160 loop-for-sets)))) 1223 loop-for-sets))))
1161 1224
1162 ((memq word '(across across-ref)) 1225 ((memq word '(across across-ref))
1163 (let ((temp-vec (gensym)) (temp-idx (gensym))) 1226 (let ((temp-vec (gensym)) (temp-idx (gensym)))
1164 (cl-push (list temp-vec (cl-pop args)) loop-for-bindings) 1227 (push (list temp-vec (pop args)) loop-for-bindings)
1165 (cl-push (list temp-idx -1) loop-for-bindings) 1228 (push (list temp-idx -1) loop-for-bindings)
1166 (cl-push (list '< (list 'setq temp-idx (list '1+ temp-idx)) 1229 (push (list '< (list 'setq temp-idx (list '1+ temp-idx))
1167 (list 'length temp-vec)) loop-body) 1230 (list 'length temp-vec)) loop-body)
1168 (if (eq word 'across-ref) 1231 (if (eq word 'across-ref)
1169 (cl-push (list var (list 'aref temp-vec temp-idx)) 1232 (push (list var (list 'aref temp-vec temp-idx))
1170 loop-symbol-macs) 1233 loop-symbol-macs)
1171 (cl-push (list var nil) loop-for-bindings) 1234 (push (list var nil) loop-for-bindings)
1172 (cl-push (list var (list 'aref temp-vec temp-idx)) 1235 (push (list var (list 'aref temp-vec temp-idx))
1173 loop-for-sets)))) 1236 loop-for-sets))))
1174 1237
1175 ((memq word '(element elements)) 1238 ((memq word '(element elements))
1176 (let ((ref (or (memq (car args) '(in-ref of-ref)) 1239 (let ((ref (or (memq (car args) '(in-ref of-ref))
1177 (and (not (memq (car args) '(in of))) 1240 (and (not (memq (car args) '(in of)))
1182 (if (and (= (length (cadr args)) 2) 1245 (if (and (= (length (cadr args)) 2)
1183 (eq (caadr args) 'index)) 1246 (eq (caadr args) 'index))
1184 (cadr (cl-pop2 args)) 1247 (cadr (cl-pop2 args))
1185 (error "Bad `using' clause")) 1248 (error "Bad `using' clause"))
1186 (gensym)))) 1249 (gensym))))
1187 (cl-push (list temp-seq seq) loop-for-bindings) 1250 (push (list temp-seq seq) loop-for-bindings)
1188 (cl-push (list temp-idx 0) loop-for-bindings) 1251 (push (list temp-idx 0) loop-for-bindings)
1189 (if ref 1252 (if ref
1190 (let ((temp-len (gensym))) 1253 (let ((temp-len (gensym)))
1191 (cl-push (list temp-len (list 'length temp-seq)) 1254 (push (list temp-len (list 'length temp-seq))
1192 loop-for-bindings) 1255 loop-for-bindings)
1193 (cl-push (list var (list 'elt temp-seq temp-idx)) 1256 (push (list var (list 'elt temp-seq temp-idx))
1194 loop-symbol-macs) 1257 loop-symbol-macs)
1195 (cl-push (list '< temp-idx temp-len) loop-body)) 1258 (push (list '< temp-idx temp-len) loop-body))
1196 (cl-push (list var nil) loop-for-bindings) 1259 (push (list var nil) loop-for-bindings)
1197 (cl-push (list 'and temp-seq 1260 (push (list 'and temp-seq
1198 (list 'or (list 'consp temp-seq) 1261 (list 'or (list 'consp temp-seq)
1199 (list '< temp-idx 1262 (list '< temp-idx
1200 (list 'length temp-seq)))) 1263 (list 'length temp-seq))))
1201 loop-body) 1264 loop-body)
1202 (cl-push (list var (list 'if (list 'consp temp-seq) 1265 (push (list var (list 'if (list 'consp temp-seq)
1203 (list 'pop temp-seq) 1266 (list 'pop temp-seq)
1204 (list 'aref temp-seq temp-idx))) 1267 (list 'aref temp-seq temp-idx)))
1205 loop-for-sets)) 1268 loop-for-sets))
1206 (cl-push (list temp-idx (list '1+ temp-idx)) 1269 (push (list temp-idx (list '1+ temp-idx))
1207 loop-for-steps))) 1270 loop-for-steps)))
1208 1271
1209 ((memq word hash-types) 1272 ((memq word hash-types)
1210 (or (memq (car args) '(in of)) (error "Expected `of'")) 1273 (or (memq (car args) '(in of)) (error "Expected `of'"))
1211 (let* ((table (cl-pop2 args)) 1274 (let* ((table (cl-pop2 args))
1252 ((eq (car args) 'property) 1315 ((eq (car args) 'property)
1253 (setq prop (cl-pop2 args))) 1316 (setq prop (cl-pop2 args)))
1254 (t (setq buf (cl-pop2 args))))) 1317 (t (setq buf (cl-pop2 args)))))
1255 (if (and (consp var) (symbolp (car var)) (symbolp (cdr var))) 1318 (if (and (consp var) (symbolp (car var)) (symbolp (cdr var)))
1256 (setq var1 (car var) var2 (cdr var)) 1319 (setq var1 (car var) var2 (cdr var))
1257 (cl-push (list var (list 'cons var1 var2)) loop-for-sets)) 1320 (push (list var (list 'cons var1 var2)) loop-for-sets))
1258 (setq loop-map-form 1321 (setq loop-map-form
1259 (list 'cl-map-intervals 1322 (list 'cl-map-intervals
1260 (list 'function (list 'lambda (list var1 var2) 1323 (list 'function (list 'lambda (list var1 var2)
1261 '(progn . --cl-map))) 1324 '(progn . --cl-map)))
1262 buf prop from to)))) 1325 buf prop from to))))
1271 key-types) 1334 key-types)
1272 (not (eq (caadr args) word))) 1335 (not (eq (caadr args) word)))
1273 (cadr (cl-pop2 args)) 1336 (cadr (cl-pop2 args))
1274 (error "Bad `using' clause")) 1337 (error "Bad `using' clause"))
1275 (gensym)))) 1338 (gensym))))
1339 ;; XEmacs addition: track other-word
1276 (when (memq word '(key-binding key-bindings)) 1340 (when (memq word '(key-binding key-bindings))
1277 (setq var (prog1 other (setq other var))) 1341 (setq var (prog1 other (setq other var)))
1278 (and other-word (setq word other-word))) 1342 (and other-word (setq word other-word)))
1279 (setq loop-map-form 1343 (setq loop-map-form
1280 (list (if (memq word '(key-seq key-seqs)) 1344 (list (if (memq word '(key-seq key-seqs))
1281 'cl-map-keymap-recursively 'cl-map-keymap) 1345 'cl-map-keymap-recursively 'map-keymap)
1282 (list 'function (list* 'lambda (list var other) 1346 (list 'function (list* 'lambda (list var other)
1283 '--cl-map)) map)))) 1347 '--cl-map)) map))))
1284 1348
1285 ((memq word '(frame frames screen screens)) 1349 ((memq word '(frame frames screen screens))
1286 (let ((temp (gensym))) 1350 (let ((temp (gensym)))
1287 (cl-push (list var '(selected-frame)) 1351 (push (list var '(selected-frame))
1288 loop-for-bindings) 1352 loop-for-bindings)
1289 (cl-push (list temp nil) loop-for-bindings) 1353 (push (list temp nil) loop-for-bindings)
1290 (cl-push (list 'prog1 (list 'not (list 'eq var temp)) 1354 (push (list 'prog1 (list 'not (list 'eq var temp))
1291 (list 'or temp (list 'setq temp var))) 1355 (list 'or temp (list 'setq temp var)))
1292 loop-body) 1356 loop-body)
1293 (cl-push (list var (list 'next-frame var)) 1357 (push (list var (list 'next-frame var))
1294 loop-for-steps))) 1358 loop-for-steps)))
1295 1359
1296 ((memq word '(window windows)) 1360 ((memq word '(window windows))
1297 (let ((scr (and (memq (car args) '(in of)) (cl-pop2 args))) 1361 (let ((scr (and (memq (car args) '(in of)) (cl-pop2 args)))
1298 (temp (gensym))) 1362 (temp (gensym)))
1299 (cl-push (list var (if scr 1363 (push (list var (if scr
1300 (list 'frame-selected-window scr) 1364 (list 'frame-selected-window scr)
1301 '(selected-window))) 1365 '(selected-window)))
1302 loop-for-bindings) 1366 loop-for-bindings)
1303 (cl-push (list temp nil) loop-for-bindings) 1367 (push (list temp nil) loop-for-bindings)
1304 (cl-push (list 'prog1 (list 'not (list 'eq var temp)) 1368 (push (list 'prog1 (list 'not (list 'eq var temp))
1305 (list 'or temp (list 'setq temp var))) 1369 (list 'or temp (list 'setq temp var)))
1306 loop-body) 1370 loop-body)
1307 (cl-push (list var (list 'next-window var)) loop-for-steps))) 1371 (push (list var (list 'next-window var)) loop-for-steps)))
1308 1372
1309 (t 1373 (t
1310 (let ((handler (and (symbolp word) 1374 (let ((handler (and (symbolp word)
1311 (get word 'cl-loop-for-handler)))) 1375 (get word 'cl-loop-for-handler))))
1312 (if handler 1376 (if handler
1313 (funcall handler var) 1377 (funcall handler var)
1314 (error "Expected a `for' preposition, found %s" word))))) 1378 (error "Expected a `for' preposition, found %s" word)))))
1315 (eq (car args) 'and)) 1379 (eq (car args) 'and))
1316 (setq ands t) 1380 (setq ands t)
1317 (cl-pop args)) 1381 (pop args))
1318 (if (and ands loop-for-bindings) 1382 (if (and ands loop-for-bindings)
1319 (cl-push (nreverse loop-for-bindings) loop-bindings) 1383 (push (nreverse loop-for-bindings) loop-bindings)
1320 (setq loop-bindings (nconc (mapcar 'list loop-for-bindings) 1384 (setq loop-bindings (nconc (mapcar 'list loop-for-bindings)
1321 loop-bindings))) 1385 loop-bindings)))
1322 (if loop-for-sets 1386 (if loop-for-sets
1323 (cl-push (list 'progn 1387 (push (list 'progn
1324 (cl-loop-let (nreverse loop-for-sets) 'setq ands) 1388 (cl-loop-let (nreverse loop-for-sets) 'setq ands)
1325 t) loop-body)) 1389 t) loop-body))
1326 (if loop-for-steps 1390 (if loop-for-steps
1327 (cl-push (cons (if ands 'psetq 'setq) 1391 (push (cons (if ands 'psetq 'setq)
1328 (apply 'append (nreverse loop-for-steps))) 1392 (apply 'append (nreverse loop-for-steps)))
1329 loop-steps)))) 1393 loop-steps))))
1330 1394
1331 ((eq word 'repeat) 1395 ((eq word 'repeat)
1332 (let ((temp (gensym))) 1396 (let ((temp (gensym)))
1333 (cl-push (list (list temp (cl-pop args))) loop-bindings) 1397 (push (list (list temp (pop args))) loop-bindings)
1334 (cl-push (list '>= (list 'setq temp (list '1- temp)) 0) loop-body))) 1398 (push (list '>= (list 'setq temp (list '1- temp)) 0) loop-body)))
1335 1399
1336 ((eq word 'collect) 1400 ((memq word '(collect collecting))
1337 (let ((what (cl-pop args)) 1401 (let ((what (pop args))
1338 (var (cl-loop-handle-accum nil 'nreverse))) 1402 (var (cl-loop-handle-accum nil 'nreverse)))
1339 (if (eq var loop-accum-var) 1403 (if (eq var loop-accum-var)
1340 (cl-push (list 'progn (list 'push what var) t) loop-body) 1404 (push (list 'progn (list 'push what var) t) loop-body)
1341 (cl-push (list 'progn 1405 (push (list 'progn
1342 (list 'setq var (list 'nconc var (list 'list what))) 1406 (list 'setq var (list 'nconc var (list 'list what)))
1343 t) loop-body)))) 1407 t) loop-body))))
1344 1408
1345 ((memq word '(nconc nconcing append appending)) 1409 ((memq word '(nconc nconcing append appending))
1346 (let ((what (cl-pop args)) 1410 (let ((what (pop args))
1347 (var (cl-loop-handle-accum nil 'nreverse))) 1411 (var (cl-loop-handle-accum nil 'nreverse)))
1348 (cl-push (list 'progn 1412 (push (list 'progn
1349 (list 'setq var 1413 (list 'setq var
1350 (if (eq var loop-accum-var) 1414 (if (eq var loop-accum-var)
1351 (list 'nconc 1415 (list 'nconc
1352 (list (if (memq word '(nconc nconcing)) 1416 (list (if (memq word '(nconc nconcing))
1353 'nreverse 'reverse) 1417 'nreverse 'reverse)
1356 (list (if (memq word '(nconc nconcing)) 1420 (list (if (memq word '(nconc nconcing))
1357 'nconc 'append) 1421 'nconc 'append)
1358 var what))) t) loop-body))) 1422 var what))) t) loop-body)))
1359 1423
1360 ((memq word '(concat concating)) 1424 ((memq word '(concat concating))
1361 (let ((what (cl-pop args)) 1425 (let ((what (pop args))
1362 (var (cl-loop-handle-accum ""))) 1426 (var (cl-loop-handle-accum "")))
1363 (cl-push (list 'progn (list 'callf 'concat var what) t) loop-body))) 1427 (push (list 'progn (list 'callf 'concat var what) t) loop-body)))
1364 1428
1365 ((memq word '(vconcat vconcating)) 1429 ((memq word '(vconcat vconcating))
1366 (let ((what (cl-pop args)) 1430 (let ((what (pop args))
1367 (var (cl-loop-handle-accum []))) 1431 (var (cl-loop-handle-accum [])))
1368 (cl-push (list 'progn (list 'callf 'vconcat var what) t) loop-body))) 1432 (push (list 'progn (list 'callf 'vconcat var what) t) loop-body)))
1369 1433
1434 ;; XEmacs addition: handle bit-vectors
1370 ((memq word '(bvconcat bvconcating)) 1435 ((memq word '(bvconcat bvconcating))
1371 (let ((what (cl-pop args)) 1436 (let ((what (pop args))
1372 (var (cl-loop-handle-accum #*))) 1437 (var (cl-loop-handle-accum #*)))
1373 (cl-push (list 'progn (list 'callf 'bvconcat var what) t) loop-body))) 1438 (push (list 'progn (list 'callf 'bvconcat var what) t) loop-body)))
1374 1439
1375 ((memq word '(sum summing)) 1440 ((memq word '(sum summing))
1376 (let ((what (cl-pop args)) 1441 (let ((what (pop args))
1377 (var (cl-loop-handle-accum 0))) 1442 (var (cl-loop-handle-accum 0)))
1378 (cl-push (list 'progn (list 'incf var what) t) loop-body))) 1443 (push (list 'progn (list 'incf var what) t) loop-body)))
1379 1444
1380 ((memq word '(count counting)) 1445 ((memq word '(count counting))
1381 (let ((what (cl-pop args)) 1446 (let ((what (pop args))
1382 (var (cl-loop-handle-accum 0))) 1447 (var (cl-loop-handle-accum 0)))
1383 (cl-push (list 'progn (list 'if what (list 'incf var)) t) loop-body))) 1448 (push (list 'progn (list 'if what (list 'incf var)) t) loop-body)))
1384 1449
1385 ((memq word '(minimize minimizing maximize maximizing)) 1450 ((memq word '(minimize minimizing maximize maximizing))
1386 (let* ((what (cl-pop args)) 1451 (let* ((what (pop args))
1387 (temp (if (cl-simple-expr-p what) what (gensym))) 1452 (temp (if (cl-simple-expr-p what) what (gensym)))
1388 (var (cl-loop-handle-accum nil)) 1453 (var (cl-loop-handle-accum nil))
1389 (func (intern (substring (symbol-name word) 0 3))) 1454 (func (intern (substring (symbol-name word) 0 3)))
1390 (set (list 'setq var (list 'if var (list func var temp) temp)))) 1455 (set (list 'setq var (list 'if var (list func var temp) temp))))
1391 (cl-push (list 'progn (if (eq temp what) set 1456 (push (list 'progn (if (eq temp what) set
1392 (list 'let (list (list temp what)) set)) 1457 (list 'let (list (list temp what)) set))
1393 t) loop-body))) 1458 t) loop-body)))
1394 1459
1395 ((eq word 'with) 1460 ((eq word 'with)
1396 (let ((bindings nil)) 1461 (let ((bindings nil))
1397 (while (progn (cl-push (list (cl-pop args) 1462 (while (progn (push (list (pop args)
1398 (and (eq (car args) '=) (cl-pop2 args))) 1463 (and (eq (car args) '=) (cl-pop2 args)))
1399 bindings) 1464 bindings)
1400 (eq (car args) 'and)) 1465 (eq (car args) 'and))
1401 (cl-pop args)) 1466 (pop args))
1402 (cl-push (nreverse bindings) loop-bindings))) 1467 (push (nreverse bindings) loop-bindings)))
1403 1468
1404 ((eq word 'while) 1469 ((eq word 'while)
1405 (cl-push (cl-pop args) loop-body)) 1470 (push (pop args) loop-body))
1406 1471
1407 ((eq word 'until) 1472 ((eq word 'until)
1408 (cl-push (list 'not (cl-pop args)) loop-body)) 1473 (push (list 'not (pop args)) loop-body))
1409 1474
1410 ((eq word 'always) 1475 ((eq word 'always)
1411 (or loop-finish-flag (setq loop-finish-flag (gensym))) 1476 (or loop-finish-flag (setq loop-finish-flag (gensym)))
1412 (cl-push (list 'setq loop-finish-flag (cl-pop args)) loop-body) 1477 (push (list 'setq loop-finish-flag (pop args)) loop-body)
1413 (setq loop-result t)) 1478 (setq loop-result t))
1414 1479
1415 ((eq word 'never) 1480 ((eq word 'never)
1416 (or loop-finish-flag (setq loop-finish-flag (gensym))) 1481 (or loop-finish-flag (setq loop-finish-flag (gensym)))
1417 (cl-push (list 'setq loop-finish-flag (list 'not (cl-pop args))) 1482 (push (list 'setq loop-finish-flag (list 'not (pop args)))
1418 loop-body) 1483 loop-body)
1419 (setq loop-result t)) 1484 (setq loop-result t))
1420 1485
1421 ((eq word 'thereis) 1486 ((eq word 'thereis)
1422 (or loop-finish-flag (setq loop-finish-flag (gensym))) 1487 (or loop-finish-flag (setq loop-finish-flag (gensym)))
1423 (or loop-result-var (setq loop-result-var (gensym))) 1488 (or loop-result-var (setq loop-result-var (gensym)))
1424 (cl-push (list 'setq loop-finish-flag 1489 (push (list 'setq loop-finish-flag
1425 (list 'not (list 'setq loop-result-var (cl-pop args)))) 1490 (list 'not (list 'setq loop-result-var (pop args))))
1426 loop-body)) 1491 loop-body))
1427 1492
1428 ((memq word '(if when unless)) 1493 ((memq word '(if when unless))
1429 (let* ((cond (cl-pop args)) 1494 (let* ((cond (pop args))
1430 (then (let ((loop-body nil)) 1495 (then (let ((loop-body nil))
1431 (cl-parse-loop-clause) 1496 (cl-parse-loop-clause)
1432 (cl-loop-build-ands (nreverse loop-body)))) 1497 (cl-loop-build-ands (nreverse loop-body))))
1433 (else (let ((loop-body nil)) 1498 (else (let ((loop-body nil))
1434 (if (eq (car args) 'else) 1499 (if (eq (car args) 'else)
1435 (progn (cl-pop args) (cl-parse-loop-clause))) 1500 (progn (pop args) (cl-parse-loop-clause)))
1436 (cl-loop-build-ands (nreverse loop-body)))) 1501 (cl-loop-build-ands (nreverse loop-body))))
1437 (simple (and (eq (car then) t) (eq (car else) t)))) 1502 (simple (and (eq (car then) t) (eq (car else) t))))
1438 (if (eq (car args) 'end) (cl-pop args)) 1503 (if (eq (car args) 'end) (pop args))
1439 (if (eq word 'unless) (setq then (prog1 else (setq else then)))) 1504 (if (eq word 'unless) (setq then (prog1 else (setq else then))))
1440 (let ((form (cons (if simple (cons 'progn (nth 1 then)) (nth 2 then)) 1505 (let ((form (cons (if simple (cons 'progn (nth 1 then)) (nth 2 then))
1441 (if simple (nth 1 else) (list (nth 2 else)))))) 1506 (if simple (nth 1 else) (list (nth 2 else))))))
1442 (if (cl-expr-contains form 'it) 1507 (if (cl-expr-contains form 'it)
1443 (let ((temp (gensym))) 1508 (let ((temp (gensym)))
1444 (cl-push (list temp) loop-bindings) 1509 (push (list temp) loop-bindings)
1445 (setq form (list* 'if (list 'setq temp cond) 1510 (setq form (list* 'if (list 'setq temp cond)
1446 (subst temp 'it form)))) 1511 (subst temp 'it form))))
1447 (setq form (list* 'if cond form))) 1512 (setq form (list* 'if cond form)))
1448 (cl-push (if simple (list 'progn form t) form) loop-body)))) 1513 (push (if simple (list 'progn form t) form) loop-body))))
1449 1514
1450 ((memq word '(do doing)) 1515 ((memq word '(do doing))
1451 (let ((body nil)) 1516 (let ((body nil))
1452 (or (consp (car args)) (error "Syntax error on `do' clause")) 1517 (or (consp (car args)) (error "Syntax error on `do' clause"))
1453 (while (consp (car args)) (cl-push (cl-pop args) body)) 1518 (while (consp (car args)) (push (pop args) body))
1454 (cl-push (cons 'progn (nreverse (cons t body))) loop-body))) 1519 (push (cons 'progn (nreverse (cons t body))) loop-body)))
1455 1520
1456 ((eq word 'return) 1521 ((eq word 'return)
1457 (or loop-finish-flag (setq loop-finish-flag (gensym))) 1522 (or loop-finish-flag (setq loop-finish-flag (gensym)))
1458 (or loop-result-var (setq loop-result-var (gensym))) 1523 (or loop-result-var (setq loop-result-var (gensym)))
1459 (cl-push (list 'setq loop-result-var (cl-pop args) 1524 (push (list 'setq loop-result-var (pop args)
1460 loop-finish-flag nil) loop-body)) 1525 loop-finish-flag nil) loop-body))
1461 1526
1462 (t 1527 (t
1463 (let ((handler (and (symbolp word) (get word 'cl-loop-handler)))) 1528 (let ((handler (and (symbolp word) (get word 'cl-loop-handler))))
1464 (or handler (error "Expected a loop keyword, found %s" word)) 1529 (or handler (error "Expected a loop keyword, found %s" word))
1465 (funcall handler)))) 1530 (funcall handler))))
1466 (if (eq (car args) 'and) 1531 (if (eq (car args) 'and)
1467 (progn (cl-pop args) (cl-parse-loop-clause))))) 1532 (progn (pop args) (cl-parse-loop-clause)))))
1468 1533
1469 (defun cl-loop-let (specs body par) ; uses loop-* 1534 (defun cl-loop-let (specs body par) ; uses loop-*
1470 (let ((p specs) (temps nil) (new nil)) 1535 (let ((p specs) (temps nil) (new nil))
1471 (while (and p (or (symbolp (car-safe (car p))) (null (cadar p)))) 1536 (while (and p (or (symbolp (car-safe (car p))) (null (cadar p))))
1472 (setq p (cdr p))) 1537 (setq p (cdr p)))
1474 (progn 1539 (progn
1475 (setq par nil p specs) 1540 (setq par nil p specs)
1476 (while p 1541 (while p
1477 (or (cl-const-expr-p (cadar p)) 1542 (or (cl-const-expr-p (cadar p))
1478 (let ((temp (gensym))) 1543 (let ((temp (gensym)))
1479 (cl-push (list temp (cadar p)) temps) 1544 (push (list temp (cadar p)) temps)
1480 (setcar (cdar p) temp))) 1545 (setcar (cdar p) temp)))
1481 (setq p (cdr p))))) 1546 (setq p (cdr p)))))
1482 (while specs 1547 (while specs
1483 (if (and (consp (car specs)) (listp (caar specs))) 1548 (if (and (consp (car specs)) (listp (caar specs)))
1484 (let* ((spec (caar specs)) (nspecs nil) 1549 (let* ((spec (caar specs)) (nspecs nil)
1485 (expr (cadr (cl-pop specs))) 1550 (expr (cadr (pop specs)))
1486 (temp (cdr (or (assq spec loop-destr-temps) 1551 (temp (cdr (or (assq spec loop-destr-temps)
1487 (car (cl-push (cons spec (or (last spec 0) 1552 (car (push (cons spec (or (last spec 0)
1488 (gensym))) 1553 (gensym)))
1489 loop-destr-temps)))))) 1554 loop-destr-temps))))))
1490 (cl-push (list temp expr) new) 1555 (push (list temp expr) new)
1491 (while (consp spec) 1556 (while (consp spec)
1492 (cl-push (list (cl-pop spec) 1557 (push (list (pop spec)
1493 (and expr (list (if spec 'pop 'car) temp))) 1558 (and expr (list (if spec 'pop 'car) temp)))
1494 nspecs)) 1559 nspecs))
1495 (setq specs (nconc (nreverse nspecs) specs))) 1560 (setq specs (nconc (nreverse nspecs) specs)))
1496 (cl-push (cl-pop specs) new))) 1561 (push (pop specs) new)))
1497 (if (eq body 'setq) 1562 (if (eq body 'setq)
1498 (let ((set (cons (if par 'psetq 'setq) (apply 'nconc (nreverse new))))) 1563 (let ((set (cons (if par 'psetq 'setq) (apply 'nconc (nreverse new)))))
1499 (if temps (list 'let* (nreverse temps) set) set)) 1564 (if temps (list 'let* (nreverse temps) set) set))
1500 (list* (if par 'let 'let*) 1565 (list* (if par 'let 'let*)
1501 (nconc (nreverse temps) (nreverse new)) body)))) 1566 (nconc (nreverse temps) (nreverse new)) body))))
1502 1567
1503 (defun cl-loop-handle-accum (def &optional func) ; uses args, loop-* 1568 (defun cl-loop-handle-accum (def &optional func) ; uses args, loop-*
1504 (if (eq (car args) 'into) 1569 (if (eq (car args) 'into)
1505 (let ((var (cl-pop2 args))) 1570 (let ((var (cl-pop2 args)))
1506 (or (memq var loop-accum-vars) 1571 (or (memq var loop-accum-vars)
1507 (progn (cl-push (list (list var def)) loop-bindings) 1572 (progn (push (list (list var def)) loop-bindings)
1508 (cl-push var loop-accum-vars))) 1573 (push var loop-accum-vars)))
1509 var) 1574 var)
1510 (or loop-accum-var 1575 (or loop-accum-var
1511 (progn 1576 (progn
1512 (cl-push (list (list (setq loop-accum-var (gensym)) def)) 1577 (push (list (list (setq loop-accum-var (gensym)) def))
1513 loop-bindings) 1578 loop-bindings)
1514 (setq loop-result (if func (list func loop-accum-var) 1579 (setq loop-result (if func (list func loop-accum-var)
1515 loop-accum-var)) 1580 loop-accum-var))
1516 loop-accum-var)))) 1581 loop-accum-var))))
1517 1582
1526 (if (eq (car-safe (cadr clauses)) 1591 (if (eq (car-safe (cadr clauses))
1527 'progn) 1592 'progn)
1528 (cdadr clauses) 1593 (cdadr clauses)
1529 (list (cadr clauses)))) 1594 (list (cadr clauses))))
1530 (cddr clauses))) 1595 (cddr clauses)))
1531 (setq body (cdr (butlast (cl-pop clauses))))) 1596 (setq body (cdr (butlast (pop clauses)))))
1532 (cl-push (cl-pop clauses) ands))) 1597 (push (pop clauses) ands)))
1533 (setq ands (or (nreverse ands) (list t))) 1598 (setq ands (or (nreverse ands) (list t)))
1534 (list (if (cdr ands) (cons 'and ands) (car ands)) 1599 (list (if (cdr ands) (cons 'and ands) (car ands))
1535 body 1600 body
1536 (let ((full (if body 1601 (let ((full (if body
1537 (append ands (list (cons 'progn (append body '(t))))) 1602 (append ands (list (cons 'progn (append body '(t)))))
1661 (let ((func (list 'function* 1726 (let ((func (list 'function*
1662 (list 'lambda (cadr x) 1727 (list 'lambda (cadr x)
1663 (list* 'block (car x) (cddr x)))))) 1728 (list* 'block (car x) (cddr x))))))
1664 (if (and (cl-compiling-file) 1729 (if (and (cl-compiling-file)
1665 (boundp 'byte-compile-function-environment)) 1730 (boundp 'byte-compile-function-environment))
1666 (cl-push (cons (car x) (eval func)) 1731 (push (cons (car x) (eval func))
1667 byte-compile-function-environment)) 1732 byte-compile-function-environment))
1668 (list (list 'symbol-function (list 'quote (car x))) func))) 1733 (list (list 'symbol-function (list 'quote (car x))) func)))
1669 bindings) 1734 bindings)
1670 body)) 1735 body))
1671 1736
1675 This is like `flet', except the bindings are lexical instead of dynamic. 1740 This is like `flet', except the bindings are lexical instead of dynamic.
1676 Unlike `flet', this macro is fully compliant with the Common Lisp standard." 1741 Unlike `flet', this macro is fully compliant with the Common Lisp standard."
1677 (let ((vars nil) (sets nil) (cl-macro-environment cl-macro-environment)) 1742 (let ((vars nil) (sets nil) (cl-macro-environment cl-macro-environment))
1678 (while bindings 1743 (while bindings
1679 (let ((var (gensym))) 1744 (let ((var (gensym)))
1680 (cl-push var vars) 1745 (push var vars)
1681 (cl-push (list 'function* (cons 'lambda (cdar bindings))) sets) 1746 (push (list 'function* (cons 'lambda (cdar bindings))) sets)
1682 (cl-push var sets) 1747 (push var sets)
1683 (cl-push (list (car (cl-pop bindings)) 'lambda '(&rest cl-labels-args) 1748 (push (list (car (pop bindings)) 'lambda '(&rest cl-labels-args)
1684 (list 'list* '(quote funcall) (list 'quote var) 1749 (list 'list* '(quote funcall) (list 'quote var)
1685 'cl-labels-args)) 1750 'cl-labels-args))
1686 cl-macro-environment))) 1751 cl-macro-environment)))
1687 (cl-macroexpand-all (list* 'lexical-let vars (cons (cons 'setq sets) body)) 1752 (cl-macroexpand-all (list* 'lexical-let vars (cons (cons 'setq sets) body))
1688 cl-macro-environment))) 1753 cl-macro-environment)))
1725 The main visible difference is that lambdas inside BODY will create 1790 The main visible difference is that lambdas inside BODY will create
1726 lexical closures as in Common Lisp." 1791 lexical closures as in Common Lisp."
1727 (let* ((cl-closure-vars cl-closure-vars) 1792 (let* ((cl-closure-vars cl-closure-vars)
1728 (vars (mapcar #'(lambda (x) 1793 (vars (mapcar #'(lambda (x)
1729 (or (consp x) (setq x (list x))) 1794 (or (consp x) (setq x (list x)))
1730 (cl-push (gensym (format "--%s--" (car x))) 1795 (push (gensym (format "--%s--" (car x)))
1731 cl-closure-vars) 1796 cl-closure-vars)
1797 (set (car cl-closure-vars) [bad-lexical-ref])
1732 (list (car x) (cadr x) (car cl-closure-vars))) 1798 (list (car x) (cadr x) (car cl-closure-vars)))
1733 bindings)) 1799 bindings))
1734 (ebody 1800 (ebody
1735 (cl-macroexpand-all 1801 (cl-macroexpand-all
1736 (cons 'progn body) 1802 (cons 'progn body)
1764 The main visible difference is that lambdas inside BODY will create 1830 The main visible difference is that lambdas inside BODY will create
1765 lexical closures as in Common Lisp." 1831 lexical closures as in Common Lisp."
1766 (if (null bindings) (cons 'progn body) 1832 (if (null bindings) (cons 'progn body)
1767 (setq bindings (reverse bindings)) 1833 (setq bindings (reverse bindings))
1768 (while bindings 1834 (while bindings
1769 (setq body (list (list* 'lexical-let (list (cl-pop bindings)) body)))) 1835 (setq body (list (list* 'lexical-let (list (pop bindings)) body))))
1770 (car body))) 1836 (car body)))
1771 1837
1772 (defun cl-defun-expander (func &rest rest) 1838 (defun cl-defun-expander (func &rest rest)
1773 (list 'progn 1839 (list 'progn
1774 (list 'defalias (list 'quote func) 1840 (list 'defalias (list 'quote func)
1803 (cond ((null vars) (list 'progn form nil)) 1869 (cond ((null vars) (list 'progn form nil))
1804 ((null (cdr vars)) (list 'setq (car vars) (list 'car form))) 1870 ((null (cdr vars)) (list 'setq (car vars) (list 'car form)))
1805 (t 1871 (t
1806 (let* ((temp (gensym)) (n 0)) 1872 (let* ((temp (gensym)) (n 0))
1807 (list 'let (list (list temp form)) 1873 (list 'let (list (list temp form))
1808 (list 'prog1 (list 'setq (cl-pop vars) (list 'car temp)) 1874 (list 'prog1 (list 'setq (pop vars) (list 'car temp))
1809 (cons 'setq 1875 (cons 'setq
1810 (apply 'nconc 1876 (apply 'nconc
1811 (mapcar 1877 (mapcar
1812 #'(lambda (v) 1878 #'(lambda (v)
1813 (list v (list 1879 (list v (list
1826 1892
1827 (defvar cl-proclaim-history t) ; for future compilers 1893 (defvar cl-proclaim-history t) ; for future compilers
1828 (defvar cl-declare-stack t) ; for future compilers 1894 (defvar cl-declare-stack t) ; for future compilers
1829 1895
1830 (defun cl-do-proclaim (spec hist) 1896 (defun cl-do-proclaim (spec hist)
1831 (and hist (listp cl-proclaim-history) (cl-push spec cl-proclaim-history)) 1897 (and hist (listp cl-proclaim-history) (push spec cl-proclaim-history))
1832 (cond ((eq (car-safe spec) 'special) 1898 (cond ((eq (car-safe spec) 'special)
1833 (if (boundp 'byte-compile-bound-variables) 1899 (if (boundp 'byte-compile-bound-variables)
1834 (setq byte-compile-bound-variables 1900 (setq byte-compile-bound-variables
1835 (append 1901 (append
1902 ;; XEmacs change
1836 (mapcar #'(lambda (v) (cons v byte-compile-global-bit)) 1903 (mapcar #'(lambda (v) (cons v byte-compile-global-bit))
1837 (cdr spec)) 1904 (cdr spec))
1838 byte-compile-bound-variables)))) 1905 byte-compile-bound-variables))))
1839 1906
1840 ((eq (car-safe spec) 'inline) 1907 ((eq (car-safe spec) 'inline)
1877 nil) 1944 nil)
1878 1945
1879 ;;; Process any proclamations made before cl-macs was loaded. 1946 ;;; Process any proclamations made before cl-macs was loaded.
1880 (defvar cl-proclaims-deferred) 1947 (defvar cl-proclaims-deferred)
1881 (let ((p (reverse cl-proclaims-deferred))) 1948 (let ((p (reverse cl-proclaims-deferred)))
1882 (while p (cl-do-proclaim (cl-pop p) t)) 1949 (while p (cl-do-proclaim (pop p) t))
1883 (setq cl-proclaims-deferred nil)) 1950 (setq cl-proclaims-deferred nil))
1884 1951
1885 ;;;###autoload 1952 ;;;###autoload
1886 (defmacro declare (&rest specs) 1953 (defmacro declare (&rest specs)
1887 (if (cl-compiling-file) 1954 (if (cl-compiling-file)
1888 (while specs 1955 (while specs
1889 (if (listp cl-declare-stack) (cl-push (car specs) cl-declare-stack)) 1956 (if (listp cl-declare-stack) (push (car specs) cl-declare-stack))
1890 (cl-do-proclaim (cl-pop specs) nil))) 1957 (cl-do-proclaim (pop specs) nil)))
1891 nil) 1958 nil)
1892 1959
1893 1960
1894 1961
1895 ;;; Generalized variables. 1962 ;;; Generalized variables.
1904 list, a store-variables list (of length one), a store-form, and an access- 1971 list, a store-variables list (of length one), a store-form, and an access-
1905 form. See `defsetf' for a simpler way to define most setf-methods." 1972 form. See `defsetf' for a simpler way to define most setf-methods."
1906 (append '(eval-when (compile load eval)) 1973 (append '(eval-when (compile load eval))
1907 (if (stringp (car body)) 1974 (if (stringp (car body))
1908 (list (list 'put (list 'quote func) '(quote setf-documentation) 1975 (list (list 'put (list 'quote func) '(quote setf-documentation)
1909 (cl-pop body)))) 1976 (pop body))))
1910 (list (cl-transform-function-property 1977 (list (cl-transform-function-property
1911 func 'setf-method (cons args body))))) 1978 func 'setf-method (cons args body)))))
1979 (defalias 'define-setf-expander 'define-setf-method)
1912 1980
1913 ;;;###autoload 1981 ;;;###autoload
1914 (defmacro defsetf (func arg1 &rest args) 1982 (defmacro defsetf (func arg1 &rest args)
1915 "(defsetf NAME FUNC): define a `setf' method. 1983 "(defsetf NAME FUNC): define a `setf' method.
1916 This macro is an easy-to-use substitute for `define-setf-method' that works 1984 This macro is an easy-to-use substitute for `define-setf-method' that works
1989 (if (car args) 2057 (if (car args)
1990 (list 'list '(quote progn) call 'store) 2058 (list 'list '(quote progn) call 'store)
1991 call))))) 2059 call)))))
1992 2060
1993 ;;; Some standard place types from Common Lisp. 2061 ;;; Some standard place types from Common Lisp.
1994 (eval-when-compile (defvar ignored-arg)) ; Warning suppression 2062 (eval-when-compile (defvar ignored-arg)) ; XEmacs: warning suppression
1995 (defsetf aref aset) 2063 (defsetf aref aset)
1996 (defsetf car setcar) 2064 (defsetf car setcar)
1997 (defsetf cdr setcdr) 2065 (defsetf cdr setcdr)
2066 (defsetf caar (x) (val) (list 'setcar (list 'car x) val))
2067 (defsetf cadr (x) (val) (list 'setcar (list 'cdr x) val))
2068 (defsetf cdar (x) (val) (list 'setcdr (list 'car x) val))
2069 (defsetf cddr (x) (val) (list 'setcdr (list 'cdr x) val))
1998 (defsetf elt (seq n) (store) 2070 (defsetf elt (seq n) (store)
1999 (list 'if (list 'listp seq) (list 'setcar (list 'nthcdr n seq) store) 2071 (list 'if (list 'listp seq) (list 'setcar (list 'nthcdr n seq) store)
2000 (list 'aset seq n store))) 2072 (list 'aset seq n store)))
2073 ;; XEmacs change: ignore the optional DEFAULT arguments
2001 (defsetf get (x y &optional ignored-arg) (store) (list 'put x y store)) 2074 (defsetf get (x y &optional ignored-arg) (store) (list 'put x y store))
2002 (defsetf get* (x y &optional ignored-arg) (store) (list 'put x y store)) 2075 (defsetf get* (x y &optional ignored-arg) (store) (list 'put x y store))
2003 (defsetf gethash (x h &optional ignored-arg) (store) (list 'cl-puthash x store h)) 2076 (defsetf gethash (x h &optional ignored-arg) (store) (list 'puthash x store h))
2004 (defsetf nth (n x) (store) (list 'setcar (list 'nthcdr n x) store)) 2077 (defsetf nth (n x) (store) (list 'setcar (list 'nthcdr n x) store))
2005 (defsetf subseq (seq start &optional end) (new) 2078 (defsetf subseq (seq start &optional end) (new)
2006 (list 'progn (list 'replace seq new ':start1 start ':end1 end) new)) 2079 (list 'progn (list 'replace seq new :start1 start :end1 end) new))
2007 (defsetf symbol-function fset) 2080 (defsetf symbol-function fset)
2008 (defsetf symbol-plist setplist) 2081 (defsetf symbol-plist setplist)
2009 (defsetf symbol-value set) 2082 (defsetf symbol-value set)
2010 2083
2011 ;;; Various car/cdr aliases. Note that `cadr' is handled specially. 2084 ;;; Various car/cdr aliases. Note that `cadr' is handled specially.
2021 (defsetf tenth (x) (store) (list 'setcar (list 'nthcdr 9 x) store)) 2094 (defsetf tenth (x) (store) (list 'setcar (list 'nthcdr 9 x) store))
2022 (defsetf rest setcdr) 2095 (defsetf rest setcdr)
2023 2096
2024 ;;; Some more Emacs-related place types. 2097 ;;; Some more Emacs-related place types.
2025 (defsetf buffer-file-name set-visited-file-name t) 2098 (defsetf buffer-file-name set-visited-file-name t)
2099 ;; XEmacs change: we do not need to wrap this in with-current-buffer
2026 (defsetf buffer-modified-p set-buffer-modified-p t) 2100 (defsetf buffer-modified-p set-buffer-modified-p t)
2027 (defsetf buffer-name rename-buffer t) 2101 (defsetf buffer-name rename-buffer t)
2028 (defsetf buffer-string () (store) 2102 (defsetf buffer-string () (store)
2029 (list 'progn '(erase-buffer) (list 'insert store))) 2103 (list 'progn '(erase-buffer) (list 'insert store)))
2030 (defsetf buffer-substring cl-set-buffer-substring) 2104 (defsetf buffer-substring cl-set-buffer-substring)
2037 (defsetf current-local-map use-local-map t) 2111 (defsetf current-local-map use-local-map t)
2038 (defsetf current-window-configuration set-window-configuration t) 2112 (defsetf current-window-configuration set-window-configuration t)
2039 (defsetf default-file-modes set-default-file-modes t) 2113 (defsetf default-file-modes set-default-file-modes t)
2040 (defsetf default-value set-default) 2114 (defsetf default-value set-default)
2041 (defsetf documentation-property put) 2115 (defsetf documentation-property put)
2116 ;;(defsetf extent-data set-extent-data)
2042 (defsetf extent-face set-extent-face) 2117 (defsetf extent-face set-extent-face)
2043 (defsetf extent-priority set-extent-priority) 2118 (defsetf extent-priority set-extent-priority)
2119 ;; XEmacs addition
2044 (defsetf extent-property (x y &optional ignored-arg) (arg) 2120 (defsetf extent-property (x y &optional ignored-arg) (arg)
2045 (list 'set-extent-property x y arg)) 2121 (list 'set-extent-property x y arg))
2122 (defsetf extent-end-position (ext) (store)
2123 `(progn (set-extent-endpoints ,ext (extent-start-position ,ext) ,store)
2124 ,store))
2046 (defsetf extent-start-position (ext) (store) 2125 (defsetf extent-start-position (ext) (store)
2047 `(progn (set-extent-endpoints ,ext ,store (extent-end-position ,ext)) 2126 `(progn (set-extent-endpoints ,ext ,store (extent-end-position ,ext))
2048 ,store))
2049 (defsetf extent-end-position (ext) (store)
2050 `(progn (set-extent-endpoints ,ext (extent-start-position ,ext) ,store)
2051 ,store)) 2127 ,store))
2052 (defsetf face-background (f &optional s) (x) (list 'set-face-background f x s)) 2128 (defsetf face-background (f &optional s) (x) (list 'set-face-background f x s))
2053 (defsetf face-background-pixmap (f &optional s) (x) 2129 (defsetf face-background-pixmap (f &optional s) (x)
2054 (list 'set-face-background-pixmap f x s)) 2130 (list 'set-face-background-pixmap f x s))
2055 (defsetf face-font (f &optional s) (x) (list 'set-face-font f x s)) 2131 (defsetf face-font (f &optional s) (x) (list 'set-face-font f x s))
2056 (defsetf face-foreground (f &optional s) (x) (list 'set-face-foreground f x s)) 2132 (defsetf face-foreground (f &optional s) (x) (list 'set-face-foreground f x s))
2057 (defsetf face-underline-p (f &optional s) (x) 2133 (defsetf face-underline-p (f &optional s) (x)
2058 (list 'set-face-underline-p f x s)) 2134 (list 'set-face-underline-p f x s))
2059 (defsetf file-modes set-file-modes t) 2135 (defsetf file-modes set-file-modes t)
2136 (defsetf frame-height (&optional f) (v)
2137 `(progn (set-frame-height ,f ,v) ,v))
2060 (defsetf frame-parameters modify-frame-parameters t) 2138 (defsetf frame-parameters modify-frame-parameters t)
2061 (defsetf frame-visible-p cl-set-frame-visible-p) 2139 (defsetf frame-visible-p cl-set-frame-visible-p)
2140 (defsetf frame-width (&optional f) (v)
2141 `(progn (set-frame-width ,f ,v) ,v))
2142 ;; XEmacs change: frame-properties instead of frame-parameters
2062 (defsetf frame-properties (&optional f) (p) 2143 (defsetf frame-properties (&optional f) (p)
2063 `(progn (set-frame-properties ,f ,p) ,p)) 2144 `(progn (set-frame-properties ,f ,p) ,p))
2064 (defsetf frame-property (f p &optional ignored-arg) (v) 2145 (defsetf frame-property (f p &optional ignored-arg) (v)
2065 `(progn (set-frame-property ,f ,v) ,p)) 2146 `(progn (set-frame-property ,f ,v) ,p))
2066 (defsetf frame-width (&optional f) (v) 2147 ;; XEmacs addition
2067 `(progn (set-frame-width ,f ,v) ,v))
2068 (defsetf frame-height (&optional f) (v)
2069 `(progn (set-frame-height ,f ,v) ,v))
2070 (defsetf current-frame-configuration set-frame-configuration) 2148 (defsetf current-frame-configuration set-frame-configuration)
2071 2149
2072 ;; XEmacs: new stuff 2150 ;; XEmacs: new stuff
2073 ;; Consoles 2151 ;; Consoles
2074 (defsetf selected-console select-console t) 2152 (defsetf selected-console select-console t)
2136 ,v)) 2214 ,v))
2137 (defsetf trunc-stack-length set-trunc-stack-length) 2215 (defsetf trunc-stack-length set-trunc-stack-length)
2138 (defsetf trunc-stack-stack set-trunc-stack-stack) 2216 (defsetf trunc-stack-stack set-trunc-stack-stack)
2139 (defsetf undoable-stack-max set-undoable-stack-max) 2217 (defsetf undoable-stack-max set-undoable-stack-max)
2140 (defsetf weak-list-list set-weak-list-list) 2218 (defsetf weak-list-list set-weak-list-list)
2141 2219 ;; End of new XEmacs stuff
2142 2220
2143 (defsetf getenv setenv t) 2221 (defsetf getenv setenv t)
2144 (defsetf get-register set-register) 2222 (defsetf get-register set-register)
2145 (defsetf global-key-binding global-set-key) 2223 (defsetf global-key-binding global-set-key)
2146 (defsetf keymap-parent set-keymap-parent) 2224 (defsetf keymap-parent set-keymap-parent)
2225 ;; XEmacs addition: more keymap-related setf forms
2147 (defsetf keymap-name set-keymap-name) 2226 (defsetf keymap-name set-keymap-name)
2148 (defsetf keymap-prompt set-keymap-prompt) 2227 (defsetf keymap-prompt set-keymap-prompt)
2149 (defsetf keymap-default-binding set-keymap-default-binding) 2228 (defsetf keymap-default-binding set-keymap-default-binding)
2150 (defsetf local-key-binding local-set-key) 2229 (defsetf local-key-binding local-set-key)
2151 (defsetf mark set-mark t) 2230 (defsetf mark set-mark t)
2167 (defsetf point-min () (store) 2246 (defsetf point-min () (store)
2168 (list 'progn (list 'narrow-to-region store '(point-max)) store)) 2247 (list 'progn (list 'narrow-to-region store '(point-max)) store))
2169 (defsetf process-buffer set-process-buffer) 2248 (defsetf process-buffer set-process-buffer)
2170 (defsetf process-filter set-process-filter) 2249 (defsetf process-filter set-process-filter)
2171 (defsetf process-sentinel set-process-sentinel) 2250 (defsetf process-sentinel set-process-sentinel)
2251 ;;(defsetf process-get process-put)
2172 (defsetf read-mouse-position (scr) (store) 2252 (defsetf read-mouse-position (scr) (store)
2173 (list 'set-mouse-position scr (list 'car store) (list 'cdr store))) 2253 (list 'set-mouse-position scr (list 'car store) (list 'cdr store)))
2254 ;;(defsetf screen-height set-screen-height t)
2255 ;;(defsetf screen-width set-screen-width t)
2174 (defsetf selected-window select-window) 2256 (defsetf selected-window select-window)
2257 ;;(defsetf selected-screen select-screen)
2175 (defsetf selected-frame select-frame) 2258 (defsetf selected-frame select-frame)
2176 (defsetf standard-case-table set-standard-case-table) 2259 (defsetf standard-case-table set-standard-case-table)
2177 (defsetf syntax-table set-syntax-table) 2260 (defsetf syntax-table set-syntax-table)
2178 (defsetf visited-file-modtime set-visited-file-modtime t) 2261 (defsetf visited-file-modtime set-visited-file-modtime t)
2179 (defsetf window-buffer set-window-buffer t) 2262 (defsetf window-buffer set-window-buffer t)
2253 (list 'cl-set-substring (nth 4 method) 2336 (list 'cl-set-substring (nth 4 method)
2254 from-temp to-temp store-temp))) 2337 from-temp to-temp store-temp)))
2255 (nth 3 method) store-temp) 2338 (nth 3 method) store-temp)
2256 (list 'substring (nth 4 method) from-temp to-temp)))) 2339 (list 'substring (nth 4 method) from-temp to-temp))))
2257 2340
2341 ;; XEmacs addition
2258 (define-setf-method values (&rest args) 2342 (define-setf-method values (&rest args)
2259 (let ((methods (mapcar #'(lambda (x) 2343 (let ((methods (mapcar #'(lambda (x)
2260 (get-setf-method x cl-macro-environment)) 2344 (get-setf-method x cl-macro-environment))
2261 args)) 2345 args))
2262 (store-temp (gensym "--values-store--"))) 2346 (store-temp (gensym "--values-store--")))
2315 (cl-setf-simple-store-p (car (nth 2 method)) 2399 (cl-setf-simple-store-p (car (nth 2 method))
2316 (nth 3 method))))) 2400 (nth 3 method)))))
2317 (simple (and optimize (consp place) (cl-simple-exprs-p (cdr place))))) 2401 (simple (and optimize (consp place) (cl-simple-exprs-p (cdr place)))))
2318 (while values 2402 (while values
2319 (if (or simple (cl-const-expr-p (car values))) 2403 (if (or simple (cl-const-expr-p (car values)))
2320 (cl-push (cons (cl-pop temps) (cl-pop values)) subs) 2404 (push (cons (pop temps) (pop values)) subs)
2321 (cl-push (list (cl-pop temps) (cl-pop values)) lets))) 2405 (push (list (pop temps) (pop values)) lets)))
2322 (list (nreverse lets) 2406 (list (nreverse lets)
2323 (cons (car (nth 2 method)) (sublis subs (nth 3 method))) 2407 (cons (car (nth 2 method)) (sublis subs (nth 3 method)))
2324 (sublis subs (nth 4 method))))) 2408 (sublis subs (nth 4 method)))))
2325 2409
2326 (defun cl-setf-do-store (spec val) 2410 (defun cl-setf-do-store (spec val)
2346 references such as (car x) or (aref x i), as well as plain symbols. 2430 references such as (car x) or (aref x i), as well as plain symbols.
2347 For example, (setf (cadar x) y) is equivalent to (setcar (cdar x) y). 2431 For example, (setf (cadar x) y) is equivalent to (setcar (cdar x) y).
2348 The return value is the last VAL in the list." 2432 The return value is the last VAL in the list."
2349 (if (cdr (cdr args)) 2433 (if (cdr (cdr args))
2350 (let ((sets nil)) 2434 (let ((sets nil))
2351 (while args (cl-push (list 'setf (cl-pop args) (cl-pop args)) sets)) 2435 (while args (push (list 'setf (pop args) (pop args)) sets))
2352 (cons 'progn (nreverse sets))) 2436 (cons 'progn (nreverse sets)))
2353 (if (symbolp (car args)) 2437 (if (symbolp (car args))
2354 (and args (cons 'setq args)) 2438 (and args (cons 'setq args))
2355 (let* ((method (cl-setf-do-modify (car args) (nth 1 args))) 2439 (let* ((method (cl-setf-do-modify (car args) (nth 1 args)))
2356 (store (cl-setf-do-store (nth 1 method) (nth 1 args)))) 2440 (store (cl-setf-do-store (nth 1 method) (nth 1 args))))
2365 (while p 2449 (while p
2366 (if (or (not (symbolp (car p))) (cl-expr-depends-p (nth 1 p) vars)) 2450 (if (or (not (symbolp (car p))) (cl-expr-depends-p (nth 1 p) vars))
2367 (setq simple nil)) 2451 (setq simple nil))
2368 (if (memq (car p) vars) 2452 (if (memq (car p) vars)
2369 (error "Destination duplicated in psetf: %s" (car p))) 2453 (error "Destination duplicated in psetf: %s" (car p)))
2370 (cl-push (cl-pop p) vars) 2454 (push (pop p) vars)
2371 (or p (error "Odd number of arguments to psetf")) 2455 (or p (error "Odd number of arguments to psetf"))
2372 (cl-pop p)) 2456 (pop p))
2373 (if simple 2457 (if simple
2374 (list 'progn (cons 'setf args) nil) 2458 (list 'progn (cons 'setf args) nil)
2375 (setq args (reverse args)) 2459 (setq args (reverse args))
2376 (let ((expr (list 'setf (cadr args) (car args)))) 2460 (let ((expr (list 'setf (cadr args) (car args))))
2377 (while (setq args (cddr args)) 2461 (while (setq args (cddr args))
2415 ;;;###autoload 2499 ;;;###autoload
2416 (defmacro shiftf (place &rest args) 2500 (defmacro shiftf (place &rest args)
2417 "(shiftf PLACE PLACE... VAL): shift left among PLACEs. 2501 "(shiftf PLACE PLACE... VAL): shift left among PLACEs.
2418 Example: (shiftf A B C) sets A to B, B to C, and returns the old A. 2502 Example: (shiftf A B C) sets A to B, B to C, and returns the old A.
2419 Each PLACE may be a symbol, or any generalized variable allowed by `setf'." 2503 Each PLACE may be a symbol, or any generalized variable allowed by `setf'."
2504 ;; XEmacs change: use iteration instead of recursion
2420 (if (not (memq nil (mapcar 'symbolp (butlast (cons place args))))) 2505 (if (not (memq nil (mapcar 'symbolp (butlast (cons place args)))))
2421 (list* 'prog1 place 2506 (list* 'prog1 place
2422 (let ((sets nil)) 2507 (let ((sets nil))
2423 (while args 2508 (while args
2424 (cl-push (list 'setq place (car args)) sets) 2509 (push (list 'setq place (car args)) sets)
2425 (setq place (cl-pop args))) 2510 (setq place (pop args)))
2426 (nreverse sets))) 2511 (nreverse sets)))
2427 (let* ((places (reverse (cons place args))) 2512 (let* ((places (reverse (cons place args)))
2428 (form (cl-pop places))) 2513 (form (pop places)))
2429 (while places 2514 (while places
2430 (let ((method (cl-setf-do-modify (cl-pop places) 'unsafe))) 2515 (let ((method (cl-setf-do-modify (pop places) 'unsafe)))
2431 (setq form (list 'let* (car method) 2516 (setq form (list 'let* (car method)
2432 (list 'prog1 (nth 2 method) 2517 (list 'prog1 (nth 2 method)
2433 (cl-setf-do-store (nth 1 method) form)))))) 2518 (cl-setf-do-store (nth 1 method) form))))))
2434 form))) 2519 form)))
2435 2520
2441 (if (not (memq nil (mapcar 'symbolp args))) 2526 (if (not (memq nil (mapcar 'symbolp args)))
2442 (and (cdr args) 2527 (and (cdr args)
2443 (let ((sets nil) 2528 (let ((sets nil)
2444 (first (car args))) 2529 (first (car args)))
2445 (while (cdr args) 2530 (while (cdr args)
2446 (setq sets (nconc sets (list (cl-pop args) (car args))))) 2531 (setq sets (nconc sets (list (pop args) (car args)))))
2447 (nconc (list 'psetf) sets (list (car args) first)))) 2532 (nconc (list 'psetf) sets (list (car args) first))))
2448 (let* ((places (reverse args)) 2533 (let* ((places (reverse args))
2449 (temp (gensym "--rotatef--")) 2534 (temp (gensym "--rotatef--"))
2450 (form temp)) 2535 (form temp))
2451 (while (cdr places) 2536 (while (cdr places)
2452 (let ((method (cl-setf-do-modify (cl-pop places) 'unsafe))) 2537 (let ((method (cl-setf-do-modify (pop places) 'unsafe)))
2453 (setq form (list 'let* (car method) 2538 (setq form (list 'let* (car method)
2454 (list 'prog1 (nth 2 method) 2539 (list 'prog1 (nth 2 method)
2455 (cl-setf-do-store (nth 1 method) form)))))) 2540 (cl-setf-do-store (nth 1 method) form))))))
2456 (let ((method (cl-setf-do-modify (car places) 'unsafe))) 2541 (let ((method (cl-setf-do-modify (car places) 'unsafe)))
2457 (list 'let* (append (car method) (list (list temp (nth 2 method)))) 2542 (list 'let* (append (car method) (list (list temp (nth 2 method))))
2524 the PLACE is not modified before executing BODY." 2609 the PLACE is not modified before executing BODY."
2525 (if (null bindings) 2610 (if (null bindings)
2526 (cons 'progn body) 2611 (cons 'progn body)
2527 (setq bindings (reverse bindings)) 2612 (setq bindings (reverse bindings))
2528 (while bindings 2613 (while bindings
2529 (setq body (list (list* 'letf (list (cl-pop bindings)) body)))) 2614 (setq body (list (list* 'letf (list (pop bindings)) body))))
2530 (car body))) 2615 (car body)))
2531 2616
2532 ;;;###autoload 2617 ;;;###autoload
2533 (defmacro callf (func place &rest args) 2618 (defmacro callf (func place &rest args)
2534 "(callf FUNC PLACE ARGS...): set PLACE to (FUNC PLACE ARGS...). 2619 "(callf FUNC PLACE ARGS...): set PLACE to (FUNC PLACE ARGS...).
2597 (type nil) 2682 (type nil)
2598 (named nil) 2683 (named nil)
2599 (forms nil) 2684 (forms nil)
2600 pred-form pred-check) 2685 pred-form pred-check)
2601 (if (stringp (car descs)) 2686 (if (stringp (car descs))
2602 (cl-push (list 'put (list 'quote name) '(quote structure-documentation) 2687 (push (list 'put (list 'quote name) '(quote structure-documentation)
2603 (cl-pop descs)) forms)) 2688 (pop descs)) forms))
2604 (setq descs (cons '(cl-tag-slot) 2689 (setq descs (cons '(cl-tag-slot)
2605 (mapcar #'(lambda (x) (if (consp x) x (list x))) 2690 (mapcar #'(lambda (x) (if (consp x) x (list x)))
2606 descs))) 2691 descs)))
2607 (while opts 2692 (while opts
2608 (let ((opt (if (consp (car opts)) (caar opts) (car opts))) 2693 (let ((opt (if (consp (car opts)) (caar opts) (car opts)))
2609 (args (cdr-safe (cl-pop opts)))) 2694 (args (cdr-safe (pop opts))))
2610 (cond ((eq opt ':conc-name) 2695 (cond ((eq opt :conc-name)
2611 (if args 2696 (if args
2612 (setq conc-name (if (car args) 2697 (setq conc-name (if (car args)
2613 (symbol-name (car args)) "")))) 2698 (symbol-name (car args)) ""))))
2614 ((eq opt ':constructor) 2699 ((eq opt :constructor)
2615 (if (cdr args) 2700 (if (cdr args)
2616 (cl-push args constrs) 2701 (push args constrs)
2617 (if args (setq constructor (car args))))) 2702 (if args (setq constructor (car args)))))
2618 ((eq opt ':copier) 2703 ((eq opt :copier)
2619 (if args (setq copier (car args)))) 2704 (if args (setq copier (car args))))
2620 ((eq opt ':predicate) 2705 ((eq opt :predicate)
2621 (if args (setq predicate (car args)))) 2706 (if args (setq predicate (car args))))
2622 ((eq opt ':include) 2707 ((eq opt :include)
2623 (setq include (car args) 2708 (setq include (car args)
2624 include-descs (mapcar #'(lambda (x) 2709 include-descs (mapcar #'(lambda (x)
2625 (if (consp x) x (list x))) 2710 (if (consp x) x (list x)))
2626 (cdr args)))) 2711 (cdr args))))
2627 ((eq opt ':print-function) 2712 ((eq opt :print-function)
2628 (setq print-func (car args))) 2713 (setq print-func (car args)))
2629 ((eq opt ':type) 2714 ((eq opt :type)
2630 (setq type (car args))) 2715 (setq type (car args)))
2631 ((eq opt ':named) 2716 ((eq opt :named)
2632 (setq named t)) 2717 (setq named t))
2633 ((eq opt ':initial-offset) 2718 ((eq opt :initial-offset)
2634 (setq descs (nconc (make-list (car args) '(cl-skip-slot)) 2719 (setq descs (nconc (make-list (car args) '(cl-skip-slot))
2635 descs))) 2720 descs)))
2636 (t 2721 (t
2637 (error "Slot option %s unrecognized" opt))))) 2722 (error "Slot option %s unrecognized" opt)))))
2638 (if print-func 2723 (if print-func
2654 (while include-descs 2739 (while include-descs
2655 (setcar (memq (or (assq (caar include-descs) old-descs) 2740 (setcar (memq (or (assq (caar include-descs) old-descs)
2656 (error "No slot %s in included struct %s" 2741 (error "No slot %s in included struct %s"
2657 (caar include-descs) include)) 2742 (caar include-descs) include))
2658 old-descs) 2743 old-descs)
2659 (cl-pop include-descs))) 2744 (pop include-descs)))
2660 (setq descs (append old-descs (delq (assq 'cl-tag-slot descs) descs)) 2745 (setq descs (append old-descs (delq (assq 'cl-tag-slot descs) descs))
2661 type (car inc-type) 2746 type (car inc-type)
2662 named (assq 'cl-tag-slot descs)) 2747 named (assq 'cl-tag-slot descs))
2663 (if (cadr inc-type) (setq tag name named t)) 2748 (if (cadr inc-type) (setq tag name named t))
2664 (let ((incl include)) 2749 (let ((incl include))
2665 (while incl 2750 (while incl
2666 (cl-push (list 'pushnew (list 'quote tag) 2751 (push (list 'pushnew (list 'quote tag)
2667 (intern (format "cl-struct-%s-tags" incl))) 2752 (intern (format "cl-struct-%s-tags" incl)))
2668 forms) 2753 forms)
2669 (setq incl (get incl 'cl-struct-include))))) 2754 (setq incl (get incl 'cl-struct-include)))))
2670 (if type 2755 (if type
2671 (progn 2756 (progn
2672 (or (memq type '(vector list)) 2757 (or (memq type '(vector list))
2673 (error "Illegal :type specifier: %s" type)) 2758 (error "Illegal :type specifier: %s" type))
2674 (if named (setq tag name))) 2759 (if named (setq tag name)))
2675 (setq type 'vector named 'true))) 2760 (setq type 'vector named 'true)))
2676 (or named (setq descs (delq (assq 'cl-tag-slot descs) descs))) 2761 (or named (setq descs (delq (assq 'cl-tag-slot descs) descs)))
2677 (cl-push (list 'defvar tag-symbol) forms) 2762 (push (list 'defvar tag-symbol) forms)
2678 (setq pred-form (and named 2763 (setq pred-form (and named
2679 (let ((pos (- (length descs) 2764 (let ((pos (- (length descs)
2680 (length (memq (assq 'cl-tag-slot descs) 2765 (length (memq (assq 'cl-tag-slot descs)
2681 descs))))) 2766 descs)))))
2682 (if (eq type 'vector) 2767 (if (eq type 'vector)
2693 (if (and (eq (caadr pred-form) 'vectorp) 2778 (if (and (eq (caadr pred-form) 'vectorp)
2694 (= safety 1)) 2779 (= safety 1))
2695 (cons 'and (cdddr pred-form)) pred-form))) 2780 (cons 'and (cdddr pred-form)) pred-form)))
2696 (let ((pos 0) (descp descs)) 2781 (let ((pos 0) (descp descs))
2697 (while descp 2782 (while descp
2698 (let* ((desc (cl-pop descp)) 2783 (let* ((desc (pop descp))
2699 (slot (car desc))) 2784 (slot (car desc)))
2700 (if (memq slot '(cl-tag-slot cl-skip-slot)) 2785 (if (memq slot '(cl-tag-slot cl-skip-slot))
2701 (progn 2786 (progn
2702 (cl-push nil slots) 2787 (push nil slots)
2703 (cl-push (and (eq slot 'cl-tag-slot) (list 'quote tag)) 2788 (push (and (eq slot 'cl-tag-slot) (list 'quote tag))
2704 defaults)) 2789 defaults))
2705 (if (assq slot descp) 2790 (if (assq slot descp)
2706 (error "Duplicate slots named %s in %s" slot name)) 2791 (error "Duplicate slots named %s in %s" slot name))
2707 (let ((accessor (intern (format "%s%s" conc-name slot)))) 2792 (let ((accessor (intern (format "%s%s" conc-name slot))))
2708 (cl-push slot slots) 2793 (push slot slots)
2709 (cl-push (nth 1 desc) defaults) 2794 (push (nth 1 desc) defaults)
2710 (cl-push (list* 2795 (push (list*
2711 'defsubst* accessor '(cl-x) 2796 'defsubst* accessor '(cl-x)
2712 (append 2797 (append
2713 (and pred-check 2798 (and pred-check
2714 (list (list 'or pred-check 2799 (list (list 'or pred-check
2715 (list 'error 2800 (list 'error
2717 accessor name) 2802 accessor name)
2718 'cl-x)))) 2803 'cl-x))))
2719 (list (if (eq type 'vector) (list 'aref 'cl-x pos) 2804 (list (if (eq type 'vector) (list 'aref 'cl-x pos)
2720 (if (= pos 0) '(car cl-x) 2805 (if (= pos 0) '(car cl-x)
2721 (list 'nth pos 'cl-x)))))) forms) 2806 (list 'nth pos 'cl-x)))))) forms)
2722 (cl-push (cons accessor t) side-eff) 2807 (push (cons accessor t) side-eff)
2723 (cl-push (list 'define-setf-method accessor '(cl-x) 2808 (push (list 'define-setf-method accessor '(cl-x)
2724 (if (cadr (memq ':read-only (cddr desc))) 2809 (if (cadr (memq :read-only (cddr desc)))
2725 (list 'error (format "%s is a read-only slot" 2810 (list 'error (format "%s is a read-only slot"
2726 accessor)) 2811 accessor))
2727 (list 'cl-struct-setf-expander 'cl-x 2812 (list 'cl-struct-setf-expander 'cl-x
2728 (list 'quote name) (list 'quote accessor) 2813 (list 'quote name) (list 'quote accessor)
2729 (and pred-check (list 'quote pred-check)) 2814 (and pred-check (list 'quote pred-check))
2735 (list 'prin1 (list accessor 'cl-x) 'cl-s))))))) 2820 (list 'prin1 (list accessor 'cl-x) 'cl-s)))))))
2736 (setq pos (1+ pos)))) 2821 (setq pos (1+ pos))))
2737 (setq slots (nreverse slots) 2822 (setq slots (nreverse slots)
2738 defaults (nreverse defaults)) 2823 defaults (nreverse defaults))
2739 (and predicate pred-form 2824 (and predicate pred-form
2740 (progn (cl-push (list 'defsubst* predicate '(cl-x) 2825 (progn (push (list 'defsubst* predicate '(cl-x)
2741 (if (eq (car pred-form) 'and) 2826 (if (eq (car pred-form) 'and)
2742 (append pred-form '(t)) 2827 (append pred-form '(t))
2743 (list 'and pred-form t))) forms) 2828 (list 'and pred-form t))) forms)
2744 (cl-push (cons predicate 'error-free) side-eff))) 2829 (push (cons predicate 'error-free) side-eff)))
2745 (and copier 2830 (and copier
2746 (progn (cl-push (list 'defun copier '(x) '(copy-sequence x)) forms) 2831 (progn (push (list 'defun copier '(x) '(copy-sequence x)) forms)
2747 (cl-push (cons copier t) side-eff))) 2832 (push (cons copier t) side-eff)))
2748 (if constructor 2833 (if constructor
2749 (cl-push (list constructor 2834 (push (list constructor
2750 (cons '&key (delq nil (copy-sequence slots)))) 2835 (cons '&key (delq nil (copy-sequence slots))))
2751 constrs)) 2836 constrs))
2752 (while constrs 2837 (while constrs
2753 (let* ((name (caar constrs)) 2838 (let* ((name (caar constrs))
2754 (args (cadr (cl-pop constrs))) 2839 (args (cadr (pop constrs)))
2755 (anames (cl-arglist-args args)) 2840 (anames (cl-arglist-args args))
2756 (make (mapcar* #'(lambda (s d) (if (memq s anames) s d)) 2841 (make (mapcar* #'(lambda (s d) (if (memq s anames) s d))
2757 slots defaults))) 2842 slots defaults)))
2758 (cl-push (list 'defsubst* name 2843 (push (list 'defsubst* name
2759 (list* '&cl-defs (list 'quote (cons nil descs)) args) 2844 (list* '&cl-defs (list 'quote (cons nil descs)) args)
2760 (cons type make)) forms) 2845 (cons type make)) forms)
2761 (if (cl-safe-expr-p (cons 'progn (mapcar 'second descs))) 2846 (if (cl-safe-expr-p (cons 'progn (mapcar 'second descs)))
2762 (cl-push (cons name t) side-eff)))) 2847 (push (cons name t) side-eff))))
2763 (if print-auto (nconc print-func (list '(princ ")" cl-s) t))) 2848 (if print-auto (nconc print-func (list '(princ ")" cl-s) t)))
2764 (if print-func 2849 (if print-func
2765 (cl-push (list 'push 2850 (push (list 'push
2766 (list 'function 2851 (list 'function
2767 (list 'lambda '(cl-x cl-s cl-n) 2852 (list 'lambda '(cl-x cl-s cl-n)
2768 (list 'and pred-form print-func))) 2853 (list 'and pred-form print-func)))
2769 'custom-print-functions) forms)) 2854 'custom-print-functions) forms))
2770 (cl-push (list 'setq tag-symbol (list 'list (list 'quote tag))) forms) 2855 (push (list 'setq tag-symbol (list 'list (list 'quote tag))) forms)
2771 (cl-push (list* 'eval-when '(compile load eval) 2856 (push (list* 'eval-when '(compile load eval)
2772 (list 'put (list 'quote name) '(quote cl-struct-slots) 2857 (list 'put (list 'quote name) '(quote cl-struct-slots)
2773 (list 'quote descs)) 2858 (list 'quote descs))
2774 (list 'put (list 'quote name) '(quote cl-struct-type) 2859 (list 'put (list 'quote name) '(quote cl-struct-type)
2775 (list 'quote (list type (eq named t)))) 2860 (list 'quote (list type (eq named t))))
2776 (list 'put (list 'quote name) '(quote cl-struct-include) 2861 (list 'put (list 'quote name) '(quote cl-struct-include)
2810 2895
2811 2896
2812 ;;; Types and assertions. 2897 ;;; Types and assertions.
2813 2898
2814 ;;;###autoload 2899 ;;;###autoload
2815 (defmacro deftype (name args &rest body) 2900 (defmacro deftype (name arglist &rest body)
2816 "(deftype NAME ARGLIST BODY...): define NAME as a new data type. 2901 "(deftype NAME ARGLIST BODY...): define NAME as a new data type.
2817 The type name can then be used in `typecase', `check-type', etc." 2902 The type name can then be used in `typecase', `check-type', etc."
2818 (list 'eval-when '(compile load eval) 2903 (list 'eval-when '(compile load eval)
2819 (cl-transform-function-property 2904 (cl-transform-function-property
2820 name 'cl-deftype-handler (cons (list* '&cl-defs ''('*) args) body)))) 2905 name 'cl-deftype-handler (cons (list* '&cl-defs ''('*) arglist) body))))
2821 2906
2822 (defun cl-make-type-test (val type) 2907 (defun cl-make-type-test (val type)
2823 (if (symbolp type) 2908 (if (symbolp type)
2824 (cond ((get type 'cl-deftype-handler) 2909 (cond ((get type 'cl-deftype-handler)
2825 (cl-make-type-test val (funcall (get type 'cl-deftype-handler)))) 2910 (cl-make-type-test val (funcall (get type 'cl-deftype-handler))))
2826 ((memq type '(nil t)) type) 2911 ((memq type '(nil t)) type)
2827 ((eq type 'string-char) (list 'characterp val)) 2912 ((eq type 'null) `(null ,val))
2828 ((eq type 'null) (list 'null val)) 2913 ((eq type 'float) `(floatp-safe ,val))
2829 ((eq type 'float) (list 'floatp-safe val)) 2914 ((eq type 'real) `(numberp ,val))
2830 ((eq type 'real) (list 'numberp val)) 2915 ((eq type 'fixnum) `(integerp ,val))
2831 ((eq type 'fixnum) (list 'integerp val)) 2916 ;; XEmacs change: we do not have char-valid-p
2917 ((memq type '(character string-char)) `(characterp ,val))
2832 (t 2918 (t
2833 (let* ((name (symbol-name type)) 2919 (let* ((name (symbol-name type))
2834 (namep (intern (concat name "p")))) 2920 (namep (intern (concat name "p"))))
2835 (if (fboundp namep) (list namep val) 2921 (if (fboundp namep) (list namep val)
2836 (list (intern (concat name "-p")) val))))) 2922 (list (intern (concat name "-p")) val)))))
2862 2948
2863 ;;;###autoload 2949 ;;;###autoload
2864 (defmacro check-type (place type &optional string) 2950 (defmacro check-type (place type &optional string)
2865 "Verify that PLACE is of type TYPE; signal a continuable error if not. 2951 "Verify that PLACE is of type TYPE; signal a continuable error if not.
2866 STRING is an optional description of the desired type." 2952 STRING is an optional description of the desired type."
2867 (when (or (not (cl-compiling-file)) 2953 (and (or (not (cl-compiling-file))
2868 (< cl-optimize-speed 3) 2954 (< cl-optimize-speed 3) (= cl-optimize-safety 3))
2869 (= cl-optimize-safety 3)) 2955 (let* ((temp (if (cl-simple-expr-p place 3) place (gensym)))
2870 (let* ((temp (if (cl-simple-expr-p place 3) place (gensym))) 2956 (test (cl-make-type-test temp type))
2871 (test (cl-make-type-test temp type)) 2957 (signal-error `(signal 'wrong-type-argument
2872 (signal-error `(signal 'wrong-type-argument 2958 ,(list 'list (or string (list 'quote type))
2873 ,(list 'list (or string (list 'quote type)) 2959 temp (list 'quote place))))
2874 temp (list 'quote place)))) 2960 (body
2875 (body 2961 (condition-case nil
2876 (condition-case nil 2962 `(while (not ,test)
2877 `(while (not ,test) 2963 ,(macroexpand `(setf ,place ,signal-error)))
2878 ,(macroexpand `(setf ,place ,signal-error))) 2964 (error
2879 (error 2965 `(if ,test (progn ,signal-error nil))))))
2880 `(if ,test (progn ,signal-error nil)))))) 2966 (if (eq temp place) `(progn ,body nil)
2881 (if (eq temp place) 2967 `(let ((,temp ,place)) ,body nil)))))
2882 body
2883 `(let ((,temp ,place)) ,body)))))
2884 2968
2885 ;;;###autoload 2969 ;;;###autoload
2886 (defmacro assert (form &optional show-args string &rest args) 2970 (defmacro assert (form &optional show-args string &rest args)
2887 "Verify that FORM returns non-nil; signal an error if not. 2971 "Verify that FORM returns non-nil; signal an error if not.
2888 Second arg SHOW-ARGS means to include arguments of FORM in message. 2972 Second arg SHOW-ARGS means to include arguments of FORM in message.
2904 (list* 'list (list 'quote form) sargs)))) 2988 (list* 'list (list 'quote form) sargs))))
2905 nil)))) 2989 nil))))
2906 2990
2907 ;;;###autoload 2991 ;;;###autoload
2908 (defmacro ignore-errors (&rest body) 2992 (defmacro ignore-errors (&rest body)
2909 "Execute FORMS; if an error occurs, return nil. 2993 "Execute BODY; if an error occurs, return nil.
2910 Otherwise, return result of last FORM." 2994 Otherwise, return result of last form in BODY."
2911 `(condition-case nil (progn ,@body) (error nil))) 2995 `(condition-case nil (progn ,@body) (error nil)))
2912 2996
2997 ;; XEmacs addition
2913 ;;;###autoload 2998 ;;;###autoload
2914 (defmacro ignore-file-errors (&rest body) 2999 (defmacro ignore-file-errors (&rest body)
2915 "Execute FORMS; if an error of type `file-error' occurs, return nil. 3000 "Execute FORMS; if an error of type `file-error' occurs, return nil.
2916 Otherwise, return result of last FORM." 3001 Otherwise, return result of last FORM."
2917 `(condition-case nil (progn ,@body) (file-error nil))) 3002 `(condition-case nil (progn ,@body) (file-error nil)))
2918
2919 ;;; Some predicates for analyzing Lisp forms. These are used by various
2920 ;;; macro expanders to optimize the results in certain common cases.
2921
2922 (defconst cl-simple-funcs '(car cdr nth aref elt if and or + - 1+ 1- min max
2923 car-safe cdr-safe progn prog1 prog2))
2924 (defconst cl-safe-funcs '(* / % length memq list vector vectorp
2925 < > <= >= = error))
2926
2927 ;;; Check if no side effects, and executes quickly.
2928 (defun cl-simple-expr-p (x &optional size)
2929 (or size (setq size 10))
2930 (if (and (consp x) (not (memq (car x) '(quote function function*))))
2931 (and (symbolp (car x))
2932 (or (memq (car x) cl-simple-funcs)
2933 (get (car x) 'side-effect-free))
2934 (progn
2935 (setq size (1- size))
2936 (while (and (setq x (cdr x))
2937 (setq size (cl-simple-expr-p (car x) size))))
2938 (and (null x) (>= size 0) size)))
2939 (and (> size 0) (1- size))))
2940
2941 (defun cl-simple-exprs-p (xs)
2942 (while (and xs (cl-simple-expr-p (car xs)))
2943 (setq xs (cdr xs)))
2944 (not xs))
2945
2946 ;;; Check if no side effects.
2947 (defun cl-safe-expr-p (x)
2948 (or (not (and (consp x) (not (memq (car x) '(quote function function*)))))
2949 (and (symbolp (car x))
2950 (or (memq (car x) cl-simple-funcs)
2951 (memq (car x) cl-safe-funcs)
2952 (get (car x) 'side-effect-free))
2953 (progn
2954 (while (and (setq x (cdr x)) (cl-safe-expr-p (car x))))
2955 (null x)))))
2956
2957 ;;; Check if constant (i.e., no side effects or dependencies).
2958 (defun cl-const-expr-p (x)
2959 (cond ((consp x)
2960 (or (eq (car x) 'quote)
2961 (and (memq (car x) '(function function*))
2962 (or (symbolp (nth 1 x))
2963 (and (eq (car-safe (nth 1 x)) 'lambda) 'func)))))
2964 ((symbolp x) (and (memq x '(nil t)) t))
2965 (t t)))
2966
2967 (defun cl-const-exprs-p (xs)
2968 (while (and xs (cl-const-expr-p (car xs)))
2969 (setq xs (cdr xs)))
2970 (not xs))
2971
2972 (defun cl-const-expr-val (x)
2973 (and (eq (cl-const-expr-p x) t) (if (consp x) (nth 1 x) x)))
2974
2975 (defun cl-expr-access-order (x v)
2976 (if (cl-const-expr-p x) v
2977 (if (consp x)
2978 (progn
2979 (while (setq x (cdr x)) (setq v (cl-expr-access-order (car x) v)))
2980 v)
2981 (if (eq x (car v)) (cdr v) '(t)))))
2982
2983 ;;; Count number of times X refers to Y. Return NIL for 0 times.
2984 (defun cl-expr-contains (x y)
2985 (cond ((equal y x) 1)
2986 ((and (consp x) (not (memq (car-safe x) '(quote function function*))))
2987 (let ((sum 0))
2988 (while x
2989 (setq sum (+ sum (or (cl-expr-contains (cl-pop x) y) 0))))
2990 (and (> sum 0) sum)))
2991 (t nil)))
2992
2993 (defun cl-expr-contains-any (x y)
2994 (while (and y (not (cl-expr-contains x (car y)))) (cl-pop y))
2995 y)
2996
2997 ;;; Check whether X may depend on any of the symbols in Y.
2998 (defun cl-expr-depends-p (x y)
2999 (and (not (cl-const-expr-p x))
3000 (or (not (cl-safe-expr-p x)) (cl-expr-contains-any x y))))
3001 3003
3002 3004
3003 ;;; Compiler macros. 3005 ;;; Compiler macros.
3004 3006
3005 ;;;###autoload 3007 ;;;###autoload
3013 compiler macros are expanded repeatedly until no further expansions are 3015 compiler macros are expanded repeatedly until no further expansions are
3014 possible. Unlike regular macros, BODY can decide to \"punt\" and leave the 3016 possible. Unlike regular macros, BODY can decide to \"punt\" and leave the
3015 original function call alone by declaring an initial `&whole foo' parameter 3017 original function call alone by declaring an initial `&whole foo' parameter
3016 and then returning foo." 3018 and then returning foo."
3017 (let ((p (if (listp args) args (list '&rest args))) (res nil)) 3019 (let ((p (if (listp args) args (list '&rest args))) (res nil))
3018 (while (consp p) (cl-push (cl-pop p) res)) 3020 (while (consp p) (push (pop p) res))
3019 (setq args (nreverse res)) (setcdr res (and p (list '&rest p)))) 3021 (setq args (nconc (nreverse res) (and p (list '&rest p)))))
3020 (list 'eval-when '(compile load eval) 3022 (list 'eval-when '(compile load eval)
3021 (cl-transform-function-property 3023 (cl-transform-function-property
3022 func 'cl-compiler-macro 3024 func 'cl-compiler-macro
3023 (cons (if (memq '&whole args) (delq '&whole args) 3025 (cons (if (memq '&whole args) (delq '&whole args)
3024 (cons '--cl-whole-arg-- args)) body)) 3026 (cons '--cl-whole-arg-- args)) body))
3051 ARGLIST allows full Common Lisp conventions, and BODY is implicitly 3053 ARGLIST allows full Common Lisp conventions, and BODY is implicitly
3052 surrounded by (block NAME ...)." 3054 surrounded by (block NAME ...)."
3053 (let* ((argns (cl-arglist-args args)) (p argns) 3055 (let* ((argns (cl-arglist-args args)) (p argns)
3054 (pbody (cons 'progn body)) 3056 (pbody (cons 'progn body))
3055 (unsafe (not (cl-safe-expr-p pbody)))) 3057 (unsafe (not (cl-safe-expr-p pbody))))
3056 (while (and p (eq (cl-expr-contains args (car p)) 1)) (cl-pop p)) 3058 (while (and p (eq (cl-expr-contains args (car p)) 1)) (pop p))
3057 (list 'progn 3059 (list 'progn
3058 (if p nil ; give up if defaults refer to earlier args 3060 (if p nil ; give up if defaults refer to earlier args
3059 (list 'define-compiler-macro name 3061 (list 'define-compiler-macro name
3060 (list* '&whole 'cl-whole '&cl-quote args) 3062 (if (memq '&key args)
3063 (list* '&whole 'cl-whole '&cl-quote args)
3064 (cons '&cl-quote args))
3061 (list* 'cl-defsubst-expand (list 'quote argns) 3065 (list* 'cl-defsubst-expand (list 'quote argns)
3062 (list 'quote (list* 'block name body)) 3066 (list 'quote (list* 'block name body))
3063 (not (or unsafe (cl-expr-access-order pbody argns))) 3067 (not (or unsafe (cl-expr-access-order pbody argns)))
3064 (and (memq '&key args) 'cl-whole) unsafe argns))) 3068 (and (memq '&key args) 'cl-whole) unsafe argns)))
3065 (list* 'defun* name args body)))) 3069 (list* 'defun* name args body))))
3103 (list 'equal a b) 3107 (list 'equal a b)
3104 (list 'eq a b))) 3108 (list 'eq a b)))
3105 (t form))) 3109 (t form)))
3106 3110
3107 (define-compiler-macro member* (&whole form a list &rest keys) 3111 (define-compiler-macro member* (&whole form a list &rest keys)
3108 (let ((test (and (= (length keys) 2) (eq (car keys) ':test) 3112 (let ((test (and (= (length keys) 2) (eq (car keys) :test)
3109 (cl-const-expr-val (nth 1 keys))))) 3113 (cl-const-expr-val (nth 1 keys)))))
3110 (cond ((eq test 'eq) (list 'memq a list)) 3114 (cond ((eq test 'eq) (list 'memq a list))
3111 ((eq test 'equal) (list 'member a list)) 3115 ((eq test 'equal) (list 'member a list))
3112 ((or (null keys) (eq test 'eql)) 3116 ((or (null keys) (eq test 'eql))
3113 (if (eq (cl-const-expr-p a) t) 3117 (if (eq (cl-const-expr-p a) t)
3125 (if (not mq) (list 'member a list) form)))) 3129 (if (not mq) (list 'member a list) form))))
3126 form))) 3130 form)))
3127 (t form)))) 3131 (t form))))
3128 3132
3129 (define-compiler-macro assoc* (&whole form a list &rest keys) 3133 (define-compiler-macro assoc* (&whole form a list &rest keys)
3130 (let ((test (and (= (length keys) 2) (eq (car keys) ':test) 3134 (let ((test (and (= (length keys) 2) (eq (car keys) :test)
3131 (cl-const-expr-val (nth 1 keys))))) 3135 (cl-const-expr-val (nth 1 keys)))))
3132 (cond ((eq test 'eq) (list 'assq a list)) 3136 (cond ((eq test 'eq) (list 'assq a list))
3133 ((eq test 'equal) (list 'assoc a list)) 3137 ((eq test 'equal) (list 'assoc a list))
3134 ((and (eq (cl-const-expr-p a) t) (or (null keys) (eq test 'eql))) 3138 ((and (eq (cl-const-expr-p a) t) (or (null keys) (eq test 'eql)))
3135 (if (floatp-safe (cl-const-expr-val a)) 3139 (if (floatp-safe (cl-const-expr-val a))
3136 (list 'assoc a list) (list 'assq a list))) 3140 (list 'assoc a list) (list 'assq a list)))
3137 (t form)))) 3141 (t form))))
3138 3142
3139 (define-compiler-macro adjoin (&whole form a list &rest keys) 3143 (define-compiler-macro adjoin (&whole form a list &rest keys)
3140 (if (and (cl-simple-expr-p a) (cl-simple-expr-p list) 3144 (if (and (cl-simple-expr-p a) (cl-simple-expr-p list)
3141 (not (memq ':key keys))) 3145 (not (memq :key keys)))
3142 (list 'if (list* 'member* a list keys) list (list 'cons a list)) 3146 (list 'if (list* 'member* a list keys) list (list 'cons a list))
3143 form)) 3147 form))
3144 3148
3145 (define-compiler-macro list* (arg &rest others) 3149 (define-compiler-macro list* (arg &rest others)
3146 (let* ((args (reverse (cons arg others))) 3150 (let* ((args (reverse (cons arg others)))
3147 (form (car args))) 3151 (form (car args)))
3148 (while (setq args (cdr args)) 3152 (while (setq args (cdr args))
3149 (setq form (list 'cons (car args) form))) 3153 (setq form (list 'cons (car args) form)))
3150 form)) 3154 form))
3151 3155
3156 ;; XEmacs change: our builtin get takes the default argument
3152 (define-compiler-macro get* (sym prop &optional default) 3157 (define-compiler-macro get* (sym prop &optional default)
3153 (list 'get sym prop default)) 3158 (list 'get sym prop default))
3154 3159
3155 (define-compiler-macro getf (sym prop &optional default) 3160 (define-compiler-macro getf (sym prop &optional default)
3156 (list 'plist-get sym prop default)) 3161 (list 'plist-get sym prop default))
3191 (cdadar cdr cadar) (cdaddr cdr caddr) (cddaar cdr cdaar) 3196 (cdadar cdr cadar) (cdaddr cdr caddr) (cddaar cdr cdaar)
3192 (cddadr cdr cdadr) (cdddar cdr cddar) (cddddr cdr cdddr))) 3197 (cddadr cdr cdadr) (cdddar cdr cddar) (cddddr cdr cdddr)))
3193 3198
3194 ;;; Things that are inline. 3199 ;;; Things that are inline.
3195 (proclaim '(inline floatp-safe acons map concatenate notany notevery 3200 (proclaim '(inline floatp-safe acons map concatenate notany notevery
3196 ;; XEmacs change 3201 ;; XEmacs omission: gethash is builtin
3197 cl-set-elt revappend nreconc 3202 cl-set-elt revappend nreconc))
3198 ))
3199 3203
3200 ;;; Things that are side-effect-free. Moved to byte-optimize.el 3204 ;;; Things that are side-effect-free. Moved to byte-optimize.el
3201 ;(dolist (fun '(oddp evenp plusp minusp 3205 ;(mapcar (function (lambda (x) (put x 'side-effect-free t)))
3202 ; abs expt signum last butlast ldiff 3206 ; '(oddp evenp signum last butlast ldiff pairlis gcd lcm
3203 ; pairlis gcd lcm 3207 ; isqrt floor* ceiling* truncate* round* mod* rem* subseq
3204 ; isqrt floor* ceiling* truncate* round* mod* rem* subseq 3208 ; list-length get* getf))
3205 ; list-length getf))
3206 ; (put fun 'side-effect-free t))
3207 3209
3208 ;;; Things that are side-effect-and-error-free. Moved to byte-optimize.el 3210 ;;; Things that are side-effect-and-error-free. Moved to byte-optimize.el
3209 ;(dolist (fun '(eql floatp-safe list* subst acons equalp random-state-p 3211 ;(mapcar (function (lambda (x) (put x 'side-effect-free 'error-free)))
3210 ; copy-tree sublis)) 3212 ; '(eql floatp-safe list* subst acons equalp random-state-p
3211 ; (put fun 'side-effect-free 'error-free)) 3213 ; copy-tree sublis))
3212 3214
3213 3215
3214 (run-hooks 'cl-macs-load-hook) 3216 (run-hooks 'cl-macs-load-hook)
3215 3217
3218 ;;; arch-tag: afd947a6-b553-4df1-bba5-000be6388f46
3216 ;;; cl-macs.el ends here 3219 ;;; cl-macs.el ends here