(make-autoload): Add usage info to docstring.
[bpt/emacs.git] / lisp / emacs-lisp / cl-macs.el
CommitLineData
73217411 1;;; cl-macs.el --- Common Lisp macros -*-byte-compile-dynamic: t;-*-
fcd73769
RS
2
3;; Copyright (C) 1993 Free Software Foundation, Inc.
4
5;; Author: Dave Gillespie <daveg@synaptics.com>
6;; Version: 2.02
7;; Keywords: extensions
8
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
7c938215 13;; the Free Software Foundation; either version 2, or (at your option)
fcd73769
RS
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
b578f267
EN
22;; along with GNU Emacs; see the file COPYING. If not, write to the
23;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24;; Boston, MA 02111-1307, USA.
fcd73769 25
07b3798c 26;;; Commentary:
fcd73769
RS
27
28;; These are extensions to Emacs Lisp that provide a degree of
29;; Common Lisp compatibility, beyond what is already built-in
30;; in Emacs Lisp.
31;;
32;; This package was written by Dave Gillespie; it is a complete
33;; rewrite of Cesar Quiroz's original cl.el package of December 1986.
34;;
fcd73769
RS
35;; Bug reports, comments, and suggestions are welcome!
36
37;; This file contains the portions of the Common Lisp extensions
38;; package which should be autoloaded, but need only be present
39;; if the compiler or interpreter is used---this file is not
40;; necessary for executing compiled code.
41
42;; See cl.el for Change Log.
43
44
07b3798c 45;;; Code:
fcd73769
RS
46
47(or (memq 'cl-19 features)
48 (error "Tried to load `cl-macs' before `cl'!"))
49
50
51;;; We define these here so that this file can compile without having
52;;; loaded the cl.el file already.
53
54(defmacro cl-push (x place) (list 'setq place (list 'cons x place)))
55(defmacro cl-pop (place)
56 (list 'car (list 'prog1 place (list 'setq place (list 'cdr place)))))
57(defmacro cl-pop2 (place)
58 (list 'prog1 (list 'car (list 'cdr place))
59 (list 'setq place (list 'cdr (list 'cdr place)))))
60(put 'cl-push 'edebug-form-spec 'edebug-sexps)
61(put 'cl-pop 'edebug-form-spec 'edebug-sexps)
62(put 'cl-pop2 'edebug-form-spec 'edebug-sexps)
63
fcd73769
RS
64(defvar cl-optimize-safety)
65(defvar cl-optimize-speed)
66
67
68;;; This kludge allows macros which use cl-transform-function-property
69;;; to be called at compile-time.
70
71(require
72 (progn
fcd73769
RS
73 (or (fboundp 'cl-transform-function-property)
74 (defalias 'cl-transform-function-property
75 (function (lambda (n p f)
76 (list 'put (list 'quote n) (list 'quote p)
77 (list 'function (cons 'lambda f)))))))
78 (car (or features (setq features (list 'cl-kludge))))))
79
80
81;;; Initialization.
82
83(defvar cl-old-bc-file-form nil)
84
fcd73769 85(defun cl-compile-time-init ()
fcd73769
RS
86 (run-hooks 'cl-hack-bytecomp-hook))
87
88
89;;; Symbols.
90
91(defvar *gensym-counter*)
92(defun gensym (&optional arg)
93 "Generate a new uninterned symbol.
94The name is made by appending a number to PREFIX, default \"G\"."
95 (let ((prefix (if (stringp arg) arg "G"))
96 (num (if (integerp arg) arg
97 (prog1 *gensym-counter*
98 (setq *gensym-counter* (1+ *gensym-counter*))))))
99 (make-symbol (format "%s%d" prefix num))))
100
101(defun gentemp (&optional arg)
102 "Generate a new interned symbol with a unique name.
103The name is made by appending a number to PREFIX, default \"G\"."
104 (let ((prefix (if (stringp arg) arg "G"))
105 name)
106 (while (intern-soft (setq name (format "%s%d" prefix *gensym-counter*)))
107 (setq *gensym-counter* (1+ *gensym-counter*)))
108 (intern name)))
109
110
111;;; Program structure.
112
113(defmacro defun* (name args &rest body)
114 "(defun* NAME ARGLIST [DOCSTRING] BODY...): define NAME as a function.
115Like normal `defun', except ARGLIST allows full Common Lisp conventions,
116and BODY is implicitly surrounded by (block NAME ...)."
117 (let* ((res (cl-transform-lambda (cons args body) name))
118 (form (list* 'defun name (cdr res))))
119 (if (car res) (list 'progn (car res) form) form)))
120
121(defmacro defmacro* (name args &rest body)
122 "(defmacro* NAME ARGLIST [DOCSTRING] BODY...): define NAME as a macro.
123Like normal `defmacro', except ARGLIST allows full Common Lisp conventions,
124and BODY is implicitly surrounded by (block NAME ...)."
125 (let* ((res (cl-transform-lambda (cons args body) name))
126 (form (list* 'defmacro name (cdr res))))
127 (if (car res) (list 'progn (car res) form) form)))
128
129(defmacro function* (func)
64a4c526 130 "Introduce a function.
fcd73769
RS
131Like normal `function', except that if argument is a lambda form, its
132ARGLIST allows full Common Lisp conventions."
133 (if (eq (car-safe func) 'lambda)
134 (let* ((res (cl-transform-lambda (cdr func) 'cl-none))
135 (form (list 'function (cons 'lambda (cdr res)))))
136 (if (car res) (list 'progn (car res) form) form))
137 (list 'function func)))
138
139(defun cl-transform-function-property (func prop form)
140 (let ((res (cl-transform-lambda form func)))
141 (append '(progn) (cdr (cdr (car res)))
142 (list (list 'put (list 'quote func) (list 'quote prop)
143 (list 'function (cons 'lambda (cdr res))))))))
144
145(defconst lambda-list-keywords
146 '(&optional &rest &key &allow-other-keys &aux &whole &body &environment))
147
148(defvar cl-macro-environment nil)
149(defvar bind-block) (defvar bind-defs) (defvar bind-enquote)
150(defvar bind-inits) (defvar bind-lets) (defvar bind-forms)
151
152(defun cl-transform-lambda (form bind-block)
153 (let* ((args (car form)) (body (cdr form))
154 (bind-defs nil) (bind-enquote nil)
155 (bind-inits nil) (bind-lets nil) (bind-forms nil)
156 (header nil) (simple-args nil))
157 (while (or (stringp (car body)) (eq (car-safe (car body)) 'interactive))
158 (cl-push (cl-pop body) header))
159 (setq args (if (listp args) (copy-list args) (list '&rest args)))
160 (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p)))))
161 (if (setq bind-defs (cadr (memq '&cl-defs args)))
162 (setq args (delq '&cl-defs (delq bind-defs args))
163 bind-defs (cadr bind-defs)))
164 (if (setq bind-enquote (memq '&cl-quote args))
165 (setq args (delq '&cl-quote args)))
166 (if (memq '&whole args) (error "&whole not currently implemented"))
167 (let* ((p (memq '&environment args)) (v (cadr p)))
168 (if p (setq args (nconc (delq (car p) (delq v args))
169 (list '&aux (list v 'cl-macro-environment))))))
170 (while (and args (symbolp (car args))
171 (not (memq (car args) '(nil &rest &body &key &aux)))
172 (not (and (eq (car args) '&optional)
173 (or bind-defs (consp (cadr args))))))
174 (cl-push (cl-pop args) simple-args))
175 (or (eq bind-block 'cl-none)
176 (setq body (list (list* 'block bind-block body))))
177 (if (null args)
178 (list* nil (nreverse simple-args) (nconc (nreverse header) body))
179 (if (memq '&optional simple-args) (cl-push '&optional args))
180 (cl-do-arglist args nil (- (length simple-args)
181 (if (memq '&optional simple-args) 1 0)))
182 (setq bind-lets (nreverse bind-lets))
183 (list* (and bind-inits (list* 'eval-when '(compile load eval)
184 (nreverse bind-inits)))
185 (nconc (nreverse simple-args)
186 (list '&rest (car (cl-pop bind-lets))))
187 (nconc (nreverse header)
188 (list (nconc (list 'let* bind-lets)
189 (nreverse bind-forms) body)))))))
190
191(defun cl-do-arglist (args expr &optional num) ; uses bind-*
192 (if (nlistp args)
193 (if (or (memq args lambda-list-keywords) (not (symbolp args)))
194 (error "Invalid argument name: %s" args)
195 (cl-push (list args expr) bind-lets))
196 (setq args (copy-list args))
197 (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p)))))
198 (let ((p (memq '&body args))) (if p (setcar p '&rest)))
199 (if (memq '&environment args) (error "&environment used incorrectly"))
200 (let ((save-args args)
201 (restarg (memq '&rest args))
202 (safety (if (cl-compiling-file) cl-optimize-safety 3))
203 (keys nil)
204 (laterarg nil) (exactarg nil) minarg)
205 (or num (setq num 0))
206 (if (listp (cadr restarg))
207 (setq restarg (gensym "--rest--"))
208 (setq restarg (cadr restarg)))
209 (cl-push (list restarg expr) bind-lets)
210 (if (eq (car args) '&whole)
211 (cl-push (list (cl-pop2 args) restarg) bind-lets))
212 (let ((p args))
213 (setq minarg restarg)
214 (while (and p (not (memq (car p) lambda-list-keywords)))
215 (or (eq p args) (setq minarg (list 'cdr minarg)))
216 (setq p (cdr p)))
217 (if (memq (car p) '(nil &aux))
218 (setq minarg (list '= (list 'length restarg)
219 (length (ldiff args p)))
220 exactarg (not (eq args p)))))
221 (while (and args (not (memq (car args) lambda-list-keywords)))
222 (let ((poparg (list (if (or (cdr args) (not exactarg)) 'pop 'car)
223 restarg)))
224 (cl-do-arglist
225 (cl-pop args)
226 (if (or laterarg (= safety 0)) poparg
227 (list 'if minarg poparg
228 (list 'signal '(quote wrong-number-of-arguments)
229 (list 'list (and (not (eq bind-block 'cl-none))
230 (list 'quote bind-block))
231 (list 'length restarg)))))))
232 (setq num (1+ num) laterarg t))
233 (while (and (eq (car args) '&optional) (cl-pop args))
234 (while (and args (not (memq (car args) lambda-list-keywords)))
235 (let ((arg (cl-pop args)))
236 (or (consp arg) (setq arg (list arg)))
237 (if (cddr arg) (cl-do-arglist (nth 2 arg) (list 'and restarg t)))
238 (let ((def (if (cdr arg) (nth 1 arg)
239 (or (car bind-defs)
240 (nth 1 (assq (car arg) bind-defs)))))
241 (poparg (list 'pop restarg)))
242 (and def bind-enquote (setq def (list 'quote def)))
243 (cl-do-arglist (car arg)
244 (if def (list 'if restarg poparg def) poparg))
245 (setq num (1+ num))))))
246 (if (eq (car args) '&rest)
247 (let ((arg (cl-pop2 args)))
248 (if (consp arg) (cl-do-arglist arg restarg)))
249 (or (eq (car args) '&key) (= safety 0) exactarg
250 (cl-push (list 'if restarg
251 (list 'signal '(quote wrong-number-of-arguments)
252 (list 'list
253 (and (not (eq bind-block 'cl-none))
254 (list 'quote bind-block))
255 (list '+ num (list 'length restarg)))))
256 bind-forms)))
257 (while (and (eq (car args) '&key) (cl-pop args))
258 (while (and args (not (memq (car args) lambda-list-keywords)))
259 (let ((arg (cl-pop args)))
dd441b46 260 (or (consp arg) (setq arg (list arg)))
fcd73769
RS
261 (let* ((karg (if (consp (car arg)) (caar arg)
262 (intern (format ":%s" (car arg)))))
263 (varg (if (consp (car arg)) (cadar arg) (car arg)))
264 (def (if (cdr arg) (cadr arg)
265 (or (car bind-defs) (cadr (assq varg bind-defs)))))
dd441b46 266 (look (list 'memq (list 'quote karg) restarg)))
fcd73769
RS
267 (and def bind-enquote (setq def (list 'quote def)))
268 (if (cddr arg)
269 (let* ((temp (or (nth 2 arg) (gensym)))
270 (val (list 'car (list 'cdr temp))))
271 (cl-do-arglist temp look)
272 (cl-do-arglist varg
273 (list 'if temp
274 (list 'prog1 val (list 'setq temp t))
275 def)))
276 (cl-do-arglist
277 varg
278 (list 'car
279 (list 'cdr
280 (if (null def)
281 look
282 (list 'or look
283 (if (eq (cl-const-expr-p def) t)
284 (list
285 'quote
286 (list nil (cl-const-expr-val def)))
287 (list 'list nil def))))))))
dd441b46 288 (cl-push karg keys)))))
fcd73769
RS
289 (setq keys (nreverse keys))
290 (or (and (eq (car args) '&allow-other-keys) (cl-pop args))
291 (null keys) (= safety 0)
292 (let* ((var (gensym "--keys--"))
293 (allow '(:allow-other-keys))
294 (check (list
295 'while var
296 (list
297 'cond
298 (list (list 'memq (list 'car var)
299 (list 'quote (append keys allow)))
300 (list 'setq var (list 'cdr (list 'cdr var))))
dd441b46
GM
301 (list (list 'car
302 (list 'cdr
303 (list 'memq (cons 'quote allow)
304 restarg)))
fcd73769
RS
305 (list 'setq var nil))
306 (list t
307 (list
308 'error
309 (format "Keyword argument %%s not one of %s"
310 keys)
311 (list 'car var)))))))
312 (cl-push (list 'let (list (list var restarg)) check) bind-forms)))
313 (while (and (eq (car args) '&aux) (cl-pop args))
314 (while (and args (not (memq (car args) lambda-list-keywords)))
315 (if (consp (car args))
316 (if (and bind-enquote (cadar args))
317 (cl-do-arglist (caar args)
318 (list 'quote (cadr (cl-pop args))))
319 (cl-do-arglist (caar args) (cadr (cl-pop args))))
320 (cl-do-arglist (cl-pop args) nil))))
321 (if args (error "Malformed argument list %s" save-args)))))
322
323(defun cl-arglist-args (args)
324 (if (nlistp args) (list args)
325 (let ((res nil) (kind nil) arg)
326 (while (consp args)
327 (setq arg (cl-pop args))
328 (if (memq arg lambda-list-keywords) (setq kind arg)
329 (if (eq arg '&cl-defs) (cl-pop args)
330 (and (consp arg) kind (setq arg (car arg)))
331 (and (consp arg) (cdr arg) (eq kind '&key) (setq arg (cadr arg)))
332 (setq res (nconc res (cl-arglist-args arg))))))
333 (nconc res (and args (list args))))))
334
335(defmacro destructuring-bind (args expr &rest body)
336 (let* ((bind-lets nil) (bind-forms nil) (bind-inits nil)
337 (bind-defs nil) (bind-block 'cl-none))
338 (cl-do-arglist (or args '(&aux)) expr)
339 (append '(progn) bind-inits
340 (list (nconc (list 'let* (nreverse bind-lets))
341 (nreverse bind-forms) body)))))
342
343
344;;; The `eval-when' form.
345
346(defvar cl-not-toplevel nil)
347
348(defmacro eval-when (when &rest body)
349 "(eval-when (WHEN...) BODY...): control when BODY is evaluated.
350If `compile' is in WHEN, BODY is evaluated when compiled at top-level.
351If `load' is in WHEN, BODY is evaluated when loaded after top-level compile.
352If `eval' is in WHEN, BODY is evaluated when interpreted or at non-top-level."
353 (if (and (fboundp 'cl-compiling-file) (cl-compiling-file)
354 (not cl-not-toplevel) (not (boundp 'for-effect))) ; horrible kludge
64a4c526 355 (let ((comp (or (memq 'compile when) (memq :compile-toplevel when)))
fcd73769 356 (cl-not-toplevel t))
64a4c526 357 (if (or (memq 'load when) (memq :load-toplevel when))
fcd73769
RS
358 (if comp (cons 'progn (mapcar 'cl-compile-time-too body))
359 (list* 'if nil nil body))
360 (progn (if comp (eval (cons 'progn body))) nil)))
64a4c526 361 (and (or (memq 'eval when) (memq :execute when))
fcd73769
RS
362 (cons 'progn body))))
363
364(defun cl-compile-time-too (form)
365 (or (and (symbolp (car-safe form)) (get (car-safe form) 'byte-hunk-handler))
366 (setq form (macroexpand
367 form (cons '(eval-when) byte-compile-macro-environment))))
368 (cond ((eq (car-safe form) 'progn)
369 (cons 'progn (mapcar 'cl-compile-time-too (cdr form))))
370 ((eq (car-safe form) 'eval-when)
371 (let ((when (nth 1 form)))
64a4c526 372 (if (or (memq 'eval when) (memq :execute when))
fcd73769
RS
373 (list* 'eval-when (cons 'compile when) (cddr form))
374 form)))
375 (t (eval form) form)))
376
fcd73769
RS
377(defmacro load-time-value (form &optional read-only)
378 "Like `progn', but evaluates the body at load time.
379The result of the body appears to the compiler as a quoted constant."
380 (if (cl-compiling-file)
381 (let* ((temp (gentemp "--cl-load-time--"))
382 (set (list 'set (list 'quote temp) form)))
383 (if (and (fboundp 'byte-compile-file-form-defmumble)
384 (boundp 'this-kind) (boundp 'that-one))
385 (fset 'byte-compile-file-form
386 (list 'lambda '(form)
387 (list 'fset '(quote byte-compile-file-form)
388 (list 'quote
389 (symbol-function 'byte-compile-file-form)))
390 (list 'byte-compile-file-form (list 'quote set))
391 '(byte-compile-file-form form)))
392 (print set (symbol-value 'outbuffer)))
393 (list 'symbol-value (list 'quote temp)))
394 (list 'quote (eval form))))
395
396
397;;; Conditional control structures.
398
399(defmacro case (expr &rest clauses)
64a4c526 400 "Eval EXPR and choose from CLAUSES on that value.
fcd73769
RS
401Each clause looks like (KEYLIST BODY...). EXPR is evaluated and compared
402against each key in each KEYLIST; the corresponding BODY is evaluated.
403If no clause succeeds, case returns nil. A single atom may be used in
404place of a KEYLIST of one atom. A KEYLIST of `t' or `otherwise' is
405allowed only in the final clause, and matches if no other keys match.
406Key values are compared by `eql'."
407 (let* ((temp (if (cl-simple-expr-p expr 3) expr (gensym)))
408 (head-list nil)
409 (body (cons
410 'cond
411 (mapcar
412 (function
413 (lambda (c)
414 (cons (cond ((memq (car c) '(t otherwise)) t)
415 ((eq (car c) 'ecase-error-flag)
416 (list 'error "ecase failed: %s, %s"
417 temp (list 'quote (reverse head-list))))
418 ((listp (car c))
419 (setq head-list (append (car c) head-list))
420 (list 'member* temp (list 'quote (car c))))
421 (t
422 (if (memq (car c) head-list)
423 (error "Duplicate key in case: %s"
424 (car c)))
425 (cl-push (car c) head-list)
426 (list 'eql temp (list 'quote (car c)))))
427 (or (cdr c) '(nil)))))
428 clauses))))
429 (if (eq temp expr) body
430 (list 'let (list (list temp expr)) body))))
431
432(defmacro ecase (expr &rest clauses)
64a4c526 433 "Like `case', but error if no case fits.
fcd73769
RS
434`otherwise'-clauses are not allowed."
435 (list* 'case expr (append clauses '((ecase-error-flag)))))
436
437(defmacro typecase (expr &rest clauses)
64a4c526 438 "Evals EXPR, chooses from CLAUSES on that value.
fcd73769
RS
439Each clause looks like (TYPE BODY...). EXPR is evaluated and, if it
440satisfies TYPE, the corresponding BODY is evaluated. If no clause succeeds,
441typecase returns nil. A TYPE of `t' or `otherwise' is allowed only in the
442final clause, and matches if no other keys match."
443 (let* ((temp (if (cl-simple-expr-p expr 3) expr (gensym)))
444 (type-list nil)
445 (body (cons
446 'cond
447 (mapcar
448 (function
449 (lambda (c)
450 (cons (cond ((eq (car c) 'otherwise) t)
451 ((eq (car c) 'ecase-error-flag)
452 (list 'error "etypecase failed: %s, %s"
453 temp (list 'quote (reverse type-list))))
454 (t
455 (cl-push (car c) type-list)
456 (cl-make-type-test temp (car c))))
457 (or (cdr c) '(nil)))))
458 clauses))))
459 (if (eq temp expr) body
460 (list 'let (list (list temp expr)) body))))
461
462(defmacro etypecase (expr &rest clauses)
64a4c526 463 "Like `typecase', but error if no case fits.
fcd73769
RS
464`otherwise'-clauses are not allowed."
465 (list* 'typecase expr (append clauses '((ecase-error-flag)))))
466
467
468;;; Blocks and exits.
469
470(defmacro block (name &rest body)
64a4c526 471 "Define a lexically-scoped block named NAME.
fcd73769
RS
472NAME may be any symbol. Code inside the BODY forms can call `return-from'
473to jump prematurely out of the block. This differs from `catch' and `throw'
474in two respects: First, the NAME is an unevaluated symbol rather than a
475quoted symbol or other form; and second, NAME is lexically rather than
476dynamically scoped: Only references to it within BODY will work. These
477references may appear inside macro expansions, but not inside functions
478called from BODY."
479 (if (cl-safe-expr-p (cons 'progn body)) (cons 'progn body)
480 (list 'cl-block-wrapper
481 (list* 'catch (list 'quote (intern (format "--cl-block-%s--" name)))
482 body))))
483
484(defvar cl-active-block-names nil)
485
486(put 'cl-block-wrapper 'byte-compile 'cl-byte-compile-block)
487(defun cl-byte-compile-block (cl-form)
488 (if (fboundp 'byte-compile-form-do-effect) ; Check for optimizing compiler
489 (progn
490 (let* ((cl-entry (cons (nth 1 (nth 1 (nth 1 cl-form))) nil))
491 (cl-active-block-names (cons cl-entry cl-active-block-names))
492 (cl-body (byte-compile-top-level
493 (cons 'progn (cddr (nth 1 cl-form))))))
494 (if (cdr cl-entry)
495 (byte-compile-form (list 'catch (nth 1 (nth 1 cl-form)) cl-body))
496 (byte-compile-form cl-body))))
497 (byte-compile-form (nth 1 cl-form))))
498
499(put 'cl-block-throw 'byte-compile 'cl-byte-compile-throw)
500(defun cl-byte-compile-throw (cl-form)
501 (let ((cl-found (assq (nth 1 (nth 1 cl-form)) cl-active-block-names)))
502 (if cl-found (setcdr cl-found t)))
503 (byte-compile-normal-call (cons 'throw (cdr cl-form))))
504
64a4c526
DL
505(defmacro return (&optional result)
506 "Return from the block named nil.
fcd73769 507This is equivalent to `(return-from nil RESULT)'."
64a4c526 508 (list 'return-from nil result))
fcd73769 509
64a4c526
DL
510(defmacro return-from (name &optional result)
511 "Return from the block named NAME.
fcd73769
RS
512This jump out to the innermost enclosing `(block NAME ...)' form,
513returning RESULT from that form (or nil if RESULT is omitted).
514This is compatible with Common Lisp, but note that `defun' and
515`defmacro' do not create implicit blocks as they do in Common Lisp."
516 (let ((name2 (intern (format "--cl-block-%s--" name))))
64a4c526 517 (list 'cl-block-throw (list 'quote name2) result)))
fcd73769
RS
518
519
520;;; The "loop" macro.
521
522(defvar args) (defvar loop-accum-var) (defvar loop-accum-vars)
523(defvar loop-bindings) (defvar loop-body) (defvar loop-destr-temps)
524(defvar loop-finally) (defvar loop-finish-flag) (defvar loop-first-flag)
525(defvar loop-initially) (defvar loop-map-form) (defvar loop-name)
526(defvar loop-result) (defvar loop-result-explicit)
527(defvar loop-result-var) (defvar loop-steps) (defvar loop-symbol-macs)
528
529(defmacro loop (&rest args)
530 "(loop CLAUSE...): The Common Lisp `loop' macro.
531Valid clauses are:
532 for VAR from/upfrom/downfrom NUM to/upto/downto/above/below NUM by NUM,
533 for VAR in LIST by FUNC, for VAR on LIST by FUNC, for VAR = INIT then EXPR,
534 for VAR across ARRAY, repeat NUM, with VAR = INIT, while COND, until COND,
535 always COND, never COND, thereis COND, collect EXPR into VAR,
536 append EXPR into VAR, nconc EXPR into VAR, sum EXPR into VAR,
537 count EXPR into VAR, maximize EXPR into VAR, minimize EXPR into VAR,
538 if COND CLAUSE [and CLAUSE]... else CLAUSE [and CLAUSE...],
539 unless COND CLAUSE [and CLAUSE]... else CLAUSE [and CLAUSE...],
540 do EXPRS..., initially EXPRS..., finally EXPRS..., return EXPR,
541 finally return EXPR, named NAME."
542 (if (not (memq t (mapcar 'symbolp (delq nil (delq t (copy-list args))))))
543 (list 'block nil (list* 'while t args))
544 (let ((loop-name nil) (loop-bindings nil)
545 (loop-body nil) (loop-steps nil)
546 (loop-result nil) (loop-result-explicit nil)
547 (loop-result-var nil) (loop-finish-flag nil)
548 (loop-accum-var nil) (loop-accum-vars nil)
549 (loop-initially nil) (loop-finally nil)
550 (loop-map-form nil) (loop-first-flag nil)
551 (loop-destr-temps nil) (loop-symbol-macs nil))
552 (setq args (append args '(cl-end-loop)))
553 (while (not (eq (car args) 'cl-end-loop)) (cl-parse-loop-clause))
554 (if loop-finish-flag
555 (cl-push (list (list loop-finish-flag t)) loop-bindings))
556 (if loop-first-flag
557 (progn (cl-push (list (list loop-first-flag t)) loop-bindings)
558 (cl-push (list 'setq loop-first-flag nil) loop-steps)))
559 (let* ((epilogue (nconc (nreverse loop-finally)
560 (list (or loop-result-explicit loop-result))))
561 (ands (cl-loop-build-ands (nreverse loop-body)))
562 (while-body (nconc (cadr ands) (nreverse loop-steps)))
563 (body (append
564 (nreverse loop-initially)
565 (list (if loop-map-form
566 (list 'block '--cl-finish--
567 (subst
568 (if (eq (car ands) t) while-body
569 (cons (list 'or (car ands)
570 '(return-from --cl-finish--
571 nil))
572 while-body))
573 '--cl-map loop-map-form))
574 (list* 'while (car ands) while-body)))
575 (if loop-finish-flag
576 (if (equal epilogue '(nil)) (list loop-result-var)
577 (list (list 'if loop-finish-flag
578 (cons 'progn epilogue) loop-result-var)))
579 epilogue))))
580 (if loop-result-var (cl-push (list loop-result-var) loop-bindings))
581 (while loop-bindings
582 (if (cdar loop-bindings)
583 (setq body (list (cl-loop-let (cl-pop loop-bindings) body t)))
584 (let ((lets nil))
585 (while (and loop-bindings
586 (not (cdar loop-bindings)))
587 (cl-push (car (cl-pop loop-bindings)) lets))
588 (setq body (list (cl-loop-let lets body nil))))))
589 (if loop-symbol-macs
590 (setq body (list (list* 'symbol-macrolet loop-symbol-macs body))))
591 (list* 'block loop-name body)))))
592
593(defun cl-parse-loop-clause () ; uses args, loop-*
594 (let ((word (cl-pop args))
595 (hash-types '(hash-key hash-keys hash-value hash-values))
596 (key-types '(key-code key-codes key-seq key-seqs
597 key-binding key-bindings)))
598 (cond
599
600 ((null args)
601 (error "Malformed `loop' macro"))
602
603 ((eq word 'named)
604 (setq loop-name (cl-pop args)))
605
606 ((eq word 'initially)
607 (if (memq (car args) '(do doing)) (cl-pop args))
608 (or (consp (car args)) (error "Syntax error on `initially' clause"))
609 (while (consp (car args))
610 (cl-push (cl-pop args) loop-initially)))
611
612 ((eq word 'finally)
613 (if (eq (car args) 'return)
614 (setq loop-result-explicit (or (cl-pop2 args) '(quote nil)))
615 (if (memq (car args) '(do doing)) (cl-pop args))
616 (or (consp (car args)) (error "Syntax error on `finally' clause"))
617 (if (and (eq (caar args) 'return) (null loop-name))
618 (setq loop-result-explicit (or (nth 1 (cl-pop args)) '(quote nil)))
619 (while (consp (car args))
620 (cl-push (cl-pop args) loop-finally)))))
621
622 ((memq word '(for as))
623 (let ((loop-for-bindings nil) (loop-for-sets nil) (loop-for-steps nil)
624 (ands nil))
625 (while
626 (let ((var (or (cl-pop args) (gensym))))
627 (setq word (cl-pop args))
628 (if (eq word 'being) (setq word (cl-pop args)))
629 (if (memq word '(the each)) (setq word (cl-pop args)))
630 (if (memq word '(buffer buffers))
631 (setq word 'in args (cons '(buffer-list) args)))
632 (cond
633
634 ((memq word '(from downfrom upfrom to downto upto
635 above below by))
636 (cl-push word args)
637 (if (memq (car args) '(downto above))
638 (error "Must specify `from' value for downward loop"))
639 (let* ((down (or (eq (car args) 'downfrom)
640 (memq (caddr args) '(downto above))))
641 (excl (or (memq (car args) '(above below))
642 (memq (caddr args) '(above below))))
643 (start (and (memq (car args) '(from upfrom downfrom))
644 (cl-pop2 args)))
645 (end (and (memq (car args)
646 '(to upto downto above below))
647 (cl-pop2 args)))
648 (step (and (eq (car args) 'by) (cl-pop2 args)))
649 (end-var (and (not (cl-const-expr-p end)) (gensym)))
650 (step-var (and (not (cl-const-expr-p step))
651 (gensym))))
652 (and step (numberp step) (<= step 0)
653 (error "Loop `by' value is not positive: %s" step))
654 (cl-push (list var (or start 0)) loop-for-bindings)
655 (if end-var (cl-push (list end-var end) loop-for-bindings))
656 (if step-var (cl-push (list step-var step)
657 loop-for-bindings))
658 (if end
659 (cl-push (list
660 (if down (if excl '> '>=) (if excl '< '<=))
661 var (or end-var end)) loop-body))
662 (cl-push (list var (list (if down '- '+) var
663 (or step-var step 1)))
664 loop-for-steps)))
665
666 ((memq word '(in in-ref on))
667 (let* ((on (eq word 'on))
668 (temp (if (and on (symbolp var)) var (gensym))))
669 (cl-push (list temp (cl-pop args)) loop-for-bindings)
670 (cl-push (list 'consp temp) loop-body)
671 (if (eq word 'in-ref)
672 (cl-push (list var (list 'car temp)) loop-symbol-macs)
673 (or (eq temp var)
674 (progn
675 (cl-push (list var nil) loop-for-bindings)
676 (cl-push (list var (if on temp (list 'car temp)))
677 loop-for-sets))))
678 (cl-push (list temp
679 (if (eq (car args) 'by)
680 (let ((step (cl-pop2 args)))
681 (if (and (memq (car-safe step)
682 '(quote function
683 function*))
684 (symbolp (nth 1 step)))
685 (list (nth 1 step) temp)
686 (list 'funcall step temp)))
687 (list 'cdr temp)))
688 loop-for-steps)))
689
690 ((eq word '=)
691 (let* ((start (cl-pop args))
692 (then (if (eq (car args) 'then) (cl-pop2 args) start)))
693 (cl-push (list var nil) loop-for-bindings)
694 (if (or ands (eq (car args) 'and))
695 (progn
696 (cl-push (list var
697 (list 'if
698 (or loop-first-flag
699 (setq loop-first-flag
700 (gensym)))
701 start var))
702 loop-for-sets)
703 (cl-push (list var then) loop-for-steps))
704 (cl-push (list var
705 (if (eq start then) start
706 (list 'if
707 (or loop-first-flag
708 (setq loop-first-flag (gensym)))
709 start then)))
710 loop-for-sets))))
711
712 ((memq word '(across across-ref))
713 (let ((temp-vec (gensym)) (temp-idx (gensym)))
714 (cl-push (list temp-vec (cl-pop args)) loop-for-bindings)
715 (cl-push (list temp-idx -1) loop-for-bindings)
716 (cl-push (list '< (list 'setq temp-idx (list '1+ temp-idx))
717 (list 'length temp-vec)) loop-body)
718 (if (eq word 'across-ref)
719 (cl-push (list var (list 'aref temp-vec temp-idx))
720 loop-symbol-macs)
721 (cl-push (list var nil) loop-for-bindings)
722 (cl-push (list var (list 'aref temp-vec temp-idx))
723 loop-for-sets))))
724
725 ((memq word '(element elements))
726 (let ((ref (or (memq (car args) '(in-ref of-ref))
727 (and (not (memq (car args) '(in of)))
728 (error "Expected `of'"))))
729 (seq (cl-pop2 args))
730 (temp-seq (gensym))
731 (temp-idx (if (eq (car args) 'using)
732 (if (and (= (length (cadr args)) 2)
733 (eq (caadr args) 'index))
734 (cadr (cl-pop2 args))
735 (error "Bad `using' clause"))
736 (gensym))))
737 (cl-push (list temp-seq seq) loop-for-bindings)
738 (cl-push (list temp-idx 0) loop-for-bindings)
739 (if ref
740 (let ((temp-len (gensym)))
741 (cl-push (list temp-len (list 'length temp-seq))
742 loop-for-bindings)
743 (cl-push (list var (list 'elt temp-seq temp-idx))
744 loop-symbol-macs)
745 (cl-push (list '< temp-idx temp-len) loop-body))
746 (cl-push (list var nil) loop-for-bindings)
747 (cl-push (list 'and temp-seq
748 (list 'or (list 'consp temp-seq)
749 (list '< temp-idx
750 (list 'length temp-seq))))
751 loop-body)
752 (cl-push (list var (list 'if (list 'consp temp-seq)
753 (list 'pop temp-seq)
754 (list 'aref temp-seq temp-idx)))
755 loop-for-sets))
756 (cl-push (list temp-idx (list '1+ temp-idx))
757 loop-for-steps)))
758
759 ((memq word hash-types)
760 (or (memq (car args) '(in of)) (error "Expected `of'"))
761 (let* ((table (cl-pop2 args))
762 (other (if (eq (car args) 'using)
763 (if (and (= (length (cadr args)) 2)
764 (memq (caadr args) hash-types)
765 (not (eq (caadr args) word)))
766 (cadr (cl-pop2 args))
767 (error "Bad `using' clause"))
768 (gensym))))
769 (if (memq word '(hash-value hash-values))
770 (setq var (prog1 other (setq other var))))
771 (setq loop-map-form
772 (list 'maphash (list 'function
773 (list* 'lambda (list var other)
774 '--cl-map)) table))))
775
776 ((memq word '(symbol present-symbol external-symbol
777 symbols present-symbols external-symbols))
778 (let ((ob (and (memq (car args) '(in of)) (cl-pop2 args))))
779 (setq loop-map-form
780 (list 'mapatoms (list 'function
781 (list* 'lambda (list var)
782 '--cl-map)) ob))))
783
784 ((memq word '(overlay overlays extent extents))
785 (let ((buf nil) (from nil) (to nil))
786 (while (memq (car args) '(in of from to))
787 (cond ((eq (car args) 'from) (setq from (cl-pop2 args)))
788 ((eq (car args) 'to) (setq to (cl-pop2 args)))
789 (t (setq buf (cl-pop2 args)))))
790 (setq loop-map-form
791 (list 'cl-map-extents
792 (list 'function (list 'lambda (list var (gensym))
793 '(progn . --cl-map) nil))
794 buf from to))))
795
796 ((memq word '(interval intervals))
797 (let ((buf nil) (prop nil) (from nil) (to nil)
798 (var1 (gensym)) (var2 (gensym)))
799 (while (memq (car args) '(in of property from to))
800 (cond ((eq (car args) 'from) (setq from (cl-pop2 args)))
801 ((eq (car args) 'to) (setq to (cl-pop2 args)))
802 ((eq (car args) 'property)
803 (setq prop (cl-pop2 args)))
804 (t (setq buf (cl-pop2 args)))))
805 (if (and (consp var) (symbolp (car var)) (symbolp (cdr var)))
806 (setq var1 (car var) var2 (cdr var))
807 (cl-push (list var (list 'cons var1 var2)) loop-for-sets))
808 (setq loop-map-form
809 (list 'cl-map-intervals
810 (list 'function (list 'lambda (list var1 var2)
811 '(progn . --cl-map)))
812 buf prop from to))))
813
814 ((memq word key-types)
815 (or (memq (car args) '(in of)) (error "Expected `of'"))
816 (let ((map (cl-pop2 args))
817 (other (if (eq (car args) 'using)
818 (if (and (= (length (cadr args)) 2)
819 (memq (caadr args) key-types)
820 (not (eq (caadr args) word)))
821 (cadr (cl-pop2 args))
822 (error "Bad `using' clause"))
823 (gensym))))
824 (if (memq word '(key-binding key-bindings))
825 (setq var (prog1 other (setq other var))))
826 (setq loop-map-form
827 (list (if (memq word '(key-seq key-seqs))
828 'cl-map-keymap-recursively 'cl-map-keymap)
829 (list 'function (list* 'lambda (list var other)
830 '--cl-map)) map))))
831
832 ((memq word '(frame frames screen screens))
833 (let ((temp (gensym)))
76f639b0 834 (cl-push (list var '(selected-frame))
fcd73769
RS
835 loop-for-bindings)
836 (cl-push (list temp nil) loop-for-bindings)
837 (cl-push (list 'prog1 (list 'not (list 'eq var temp))
838 (list 'or temp (list 'setq temp var)))
839 loop-body)
76f639b0 840 (cl-push (list var (list 'next-frame var))
fcd73769
RS
841 loop-for-steps)))
842
843 ((memq word '(window windows))
844 (let ((scr (and (memq (car args) '(in of)) (cl-pop2 args)))
845 (temp (gensym)))
846 (cl-push (list var (if scr
76f639b0 847 (list 'frame-selected-window scr)
fcd73769
RS
848 '(selected-window)))
849 loop-for-bindings)
850 (cl-push (list temp nil) loop-for-bindings)
851 (cl-push (list 'prog1 (list 'not (list 'eq var temp))
852 (list 'or temp (list 'setq temp var)))
853 loop-body)
854 (cl-push (list var (list 'next-window var)) loop-for-steps)))
855
856 (t
857 (let ((handler (and (symbolp word)
858 (get word 'cl-loop-for-handler))))
859 (if handler
860 (funcall handler var)
861 (error "Expected a `for' preposition, found %s" word)))))
862 (eq (car args) 'and))
863 (setq ands t)
864 (cl-pop args))
865 (if (and ands loop-for-bindings)
866 (cl-push (nreverse loop-for-bindings) loop-bindings)
867 (setq loop-bindings (nconc (mapcar 'list loop-for-bindings)
868 loop-bindings)))
869 (if loop-for-sets
870 (cl-push (list 'progn
871 (cl-loop-let (nreverse loop-for-sets) 'setq ands)
872 t) loop-body))
873 (if loop-for-steps
874 (cl-push (cons (if ands 'psetq 'setq)
875 (apply 'append (nreverse loop-for-steps)))
876 loop-steps))))
877
878 ((eq word 'repeat)
879 (let ((temp (gensym)))
880 (cl-push (list (list temp (cl-pop args))) loop-bindings)
881 (cl-push (list '>= (list 'setq temp (list '1- temp)) 0) loop-body)))
882
ae1aa776 883 ((memq word '(collect collecting))
fcd73769
RS
884 (let ((what (cl-pop args))
885 (var (cl-loop-handle-accum nil 'nreverse)))
886 (if (eq var loop-accum-var)
887 (cl-push (list 'progn (list 'push what var) t) loop-body)
888 (cl-push (list 'progn
889 (list 'setq var (list 'nconc var (list 'list what)))
890 t) loop-body))))
891
892 ((memq word '(nconc nconcing append appending))
893 (let ((what (cl-pop args))
894 (var (cl-loop-handle-accum nil 'nreverse)))
895 (cl-push (list 'progn
896 (list 'setq var
897 (if (eq var loop-accum-var)
898 (list 'nconc
899 (list (if (memq word '(nconc nconcing))
900 'nreverse 'reverse)
901 what)
902 var)
903 (list (if (memq word '(nconc nconcing))
904 'nconc 'append)
905 var what))) t) loop-body)))
906
907 ((memq word '(concat concating))
908 (let ((what (cl-pop args))
909 (var (cl-loop-handle-accum "")))
910 (cl-push (list 'progn (list 'callf 'concat var what) t) loop-body)))
911
912 ((memq word '(vconcat vconcating))
913 (let ((what (cl-pop args))
914 (var (cl-loop-handle-accum [])))
915 (cl-push (list 'progn (list 'callf 'vconcat var what) t) loop-body)))
916
917 ((memq word '(sum summing))
918 (let ((what (cl-pop args))
919 (var (cl-loop-handle-accum 0)))
920 (cl-push (list 'progn (list 'incf var what) t) loop-body)))
921
922 ((memq word '(count counting))
923 (let ((what (cl-pop args))
924 (var (cl-loop-handle-accum 0)))
925 (cl-push (list 'progn (list 'if what (list 'incf var)) t) loop-body)))
926
927 ((memq word '(minimize minimizing maximize maximizing))
928 (let* ((what (cl-pop args))
929 (temp (if (cl-simple-expr-p what) what (gensym)))
930 (var (cl-loop-handle-accum nil))
931 (func (intern (substring (symbol-name word) 0 3)))
932 (set (list 'setq var (list 'if var (list func var temp) temp))))
933 (cl-push (list 'progn (if (eq temp what) set
934 (list 'let (list (list temp what)) set))
935 t) loop-body)))
936
937 ((eq word 'with)
938 (let ((bindings nil))
939 (while (progn (cl-push (list (cl-pop args)
940 (and (eq (car args) '=) (cl-pop2 args)))
941 bindings)
942 (eq (car args) 'and))
943 (cl-pop args))
944 (cl-push (nreverse bindings) loop-bindings)))
945
946 ((eq word 'while)
947 (cl-push (cl-pop args) loop-body))
948
949 ((eq word 'until)
950 (cl-push (list 'not (cl-pop args)) loop-body))
951
952 ((eq word 'always)
953 (or loop-finish-flag (setq loop-finish-flag (gensym)))
954 (cl-push (list 'setq loop-finish-flag (cl-pop args)) loop-body)
955 (setq loop-result t))
956
957 ((eq word 'never)
958 (or loop-finish-flag (setq loop-finish-flag (gensym)))
959 (cl-push (list 'setq loop-finish-flag (list 'not (cl-pop args)))
960 loop-body)
961 (setq loop-result t))
962
963 ((eq word 'thereis)
964 (or loop-finish-flag (setq loop-finish-flag (gensym)))
965 (or loop-result-var (setq loop-result-var (gensym)))
966 (cl-push (list 'setq loop-finish-flag
967 (list 'not (list 'setq loop-result-var (cl-pop args))))
968 loop-body))
969
970 ((memq word '(if when unless))
971 (let* ((cond (cl-pop args))
972 (then (let ((loop-body nil))
973 (cl-parse-loop-clause)
974 (cl-loop-build-ands (nreverse loop-body))))
975 (else (let ((loop-body nil))
976 (if (eq (car args) 'else)
977 (progn (cl-pop args) (cl-parse-loop-clause)))
978 (cl-loop-build-ands (nreverse loop-body))))
979 (simple (and (eq (car then) t) (eq (car else) t))))
980 (if (eq (car args) 'end) (cl-pop args))
981 (if (eq word 'unless) (setq then (prog1 else (setq else then))))
982 (let ((form (cons (if simple (cons 'progn (nth 1 then)) (nth 2 then))
983 (if simple (nth 1 else) (list (nth 2 else))))))
984 (if (cl-expr-contains form 'it)
985 (let ((temp (gensym)))
986 (cl-push (list temp) loop-bindings)
987 (setq form (list* 'if (list 'setq temp cond)
988 (subst temp 'it form))))
989 (setq form (list* 'if cond form)))
990 (cl-push (if simple (list 'progn form t) form) loop-body))))
991
992 ((memq word '(do doing))
993 (let ((body nil))
994 (or (consp (car args)) (error "Syntax error on `do' clause"))
995 (while (consp (car args)) (cl-push (cl-pop args) body))
996 (cl-push (cons 'progn (nreverse (cons t body))) loop-body)))
997
998 ((eq word 'return)
999 (or loop-finish-flag (setq loop-finish-flag (gensym)))
1000 (or loop-result-var (setq loop-result-var (gensym)))
1001 (cl-push (list 'setq loop-result-var (cl-pop args)
1002 loop-finish-flag nil) loop-body))
1003
1004 (t
1005 (let ((handler (and (symbolp word) (get word 'cl-loop-handler))))
1006 (or handler (error "Expected a loop keyword, found %s" word))
1007 (funcall handler))))
1008 (if (eq (car args) 'and)
1009 (progn (cl-pop args) (cl-parse-loop-clause)))))
1010
1011(defun cl-loop-let (specs body par) ; uses loop-*
1012 (let ((p specs) (temps nil) (new nil))
1013 (while (and p (or (symbolp (car-safe (car p))) (null (cadar p))))
1014 (setq p (cdr p)))
1015 (and par p
1016 (progn
1017 (setq par nil p specs)
1018 (while p
1019 (or (cl-const-expr-p (cadar p))
1020 (let ((temp (gensym)))
1021 (cl-push (list temp (cadar p)) temps)
1022 (setcar (cdar p) temp)))
1023 (setq p (cdr p)))))
1024 (while specs
1025 (if (and (consp (car specs)) (listp (caar specs)))
1026 (let* ((spec (caar specs)) (nspecs nil)
1027 (expr (cadr (cl-pop specs)))
1028 (temp (cdr (or (assq spec loop-destr-temps)
f4cf76d3 1029 (car (cl-push (cons spec (or (last spec 0)
fcd73769
RS
1030 (gensym)))
1031 loop-destr-temps))))))
1032 (cl-push (list temp expr) new)
1033 (while (consp spec)
1034 (cl-push (list (cl-pop spec)
1035 (and expr (list (if spec 'pop 'car) temp)))
1036 nspecs))
1037 (setq specs (nconc (nreverse nspecs) specs)))
1038 (cl-push (cl-pop specs) new)))
1039 (if (eq body 'setq)
1040 (let ((set (cons (if par 'psetq 'setq) (apply 'nconc (nreverse new)))))
1041 (if temps (list 'let* (nreverse temps) set) set))
1042 (list* (if par 'let 'let*)
1043 (nconc (nreverse temps) (nreverse new)) body))))
1044
1045(defun cl-loop-handle-accum (def &optional func) ; uses args, loop-*
1046 (if (eq (car args) 'into)
1047 (let ((var (cl-pop2 args)))
1048 (or (memq var loop-accum-vars)
1049 (progn (cl-push (list (list var def)) loop-bindings)
1050 (cl-push var loop-accum-vars)))
1051 var)
1052 (or loop-accum-var
1053 (progn
1054 (cl-push (list (list (setq loop-accum-var (gensym)) def))
1055 loop-bindings)
1056 (setq loop-result (if func (list func loop-accum-var)
1057 loop-accum-var))
1058 loop-accum-var))))
1059
1060(defun cl-loop-build-ands (clauses)
1061 (let ((ands nil)
1062 (body nil))
1063 (while clauses
1064 (if (and (eq (car-safe (car clauses)) 'progn)
1065 (eq (car (last (car clauses))) t))
1066 (if (cdr clauses)
1067 (setq clauses (cons (nconc (butlast (car clauses))
1068 (if (eq (car-safe (cadr clauses))
1069 'progn)
1070 (cdadr clauses)
1071 (list (cadr clauses))))
1072 (cddr clauses)))
1073 (setq body (cdr (butlast (cl-pop clauses)))))
1074 (cl-push (cl-pop clauses) ands)))
1075 (setq ands (or (nreverse ands) (list t)))
1076 (list (if (cdr ands) (cons 'and ands) (car ands))
1077 body
1078 (let ((full (if body
1079 (append ands (list (cons 'progn (append body '(t)))))
1080 ands)))
1081 (if (cdr full) (cons 'and full) (car full))))))
1082
1083
1084;;; Other iteration control structures.
1085
1086(defmacro do (steps endtest &rest body)
1087 "The Common Lisp `do' loop.
1088Format is: (do ((VAR INIT [STEP])...) (END-TEST [RESULT...]) BODY...)"
1089 (cl-expand-do-loop steps endtest body nil))
1090
1091(defmacro do* (steps endtest &rest body)
1092 "The Common Lisp `do*' loop.
1093Format is: (do* ((VAR INIT [STEP])...) (END-TEST [RESULT...]) BODY...)"
1094 (cl-expand-do-loop steps endtest body t))
1095
1096(defun cl-expand-do-loop (steps endtest body star)
1097 (list 'block nil
1098 (list* (if star 'let* 'let)
1099 (mapcar (function (lambda (c)
1100 (if (consp c) (list (car c) (nth 1 c)) c)))
1101 steps)
1102 (list* 'while (list 'not (car endtest))
1103 (append body
1104 (let ((sets (mapcar
1105 (function
1106 (lambda (c)
1107 (and (consp c) (cdr (cdr c))
1108 (list (car c) (nth 2 c)))))
1109 steps)))
1110 (setq sets (delq nil sets))
1111 (and sets
1112 (list (cons (if (or star (not (cdr sets)))
1113 'setq 'psetq)
1114 (apply 'append sets)))))))
1115 (or (cdr endtest) '(nil)))))
1116
63744c0f
DL
1117(defmacro dolist (spec &rest body)
1118 "(dolist (VAR LIST [RESULT]) BODY...): loop over a list.
1119Evaluate BODY with VAR bound to each `car' from LIST, in turn.
1120Then evaluate RESULT to get return value, default nil."
1121 (let ((temp (gensym "--dolist-temp--")))
1122 (list 'block nil
1123 (list* 'let (list (list temp (nth 1 spec)) (car spec))
1124 (list* 'while temp (list 'setq (car spec) (list 'car temp))
1125 (append body (list (list 'setq temp
1126 (list 'cdr temp)))))
1127 (if (cdr (cdr spec))
1128 (cons (list 'setq (car spec) nil) (cdr (cdr spec)))
1129 '(nil))))))
1130
1131(defmacro dotimes (spec &rest body)
1132 "(dotimes (VAR COUNT [RESULT]) BODY...): loop a certain number of times.
1133Evaluate BODY with VAR bound to successive integers from 0, inclusive,
1134to COUNT, exclusive. Then evaluate RESULT to get return value, default
1135nil."
1136 (let ((temp (gensym "--dotimes-temp--")))
1137 (list 'block nil
1138 (list* 'let (list (list temp (nth 1 spec)) (list (car spec) 0))
1139 (list* 'while (list '< (car spec) temp)
1140 (append body (list (list 'incf (car spec)))))
1141 (or (cdr (cdr spec)) '(nil))))))
1142
fcd73769
RS
1143(defmacro do-symbols (spec &rest body)
1144 "(dosymbols (VAR [OBARRAY [RESULT]]) BODY...): loop over all symbols.
1145Evaluate BODY with VAR bound to each interned symbol, or to each symbol
1146from OBARRAY."
1147 ;; Apparently this doesn't have an implicit block.
1148 (list 'block nil
1149 (list 'let (list (car spec))
1150 (list* 'mapatoms
1151 (list 'function (list* 'lambda (list (car spec)) body))
1152 (and (cadr spec) (list (cadr spec))))
1153 (caddr spec))))
1154
1155(defmacro do-all-symbols (spec &rest body)
1156 (list* 'do-symbols (list (car spec) nil (cadr spec)) body))
1157
1158
1159;;; Assignments.
1160
1161(defmacro psetq (&rest args)
1162 "(psetq SYM VAL SYM VAL ...): set SYMs to the values VALs in parallel.
1163This is like `setq', except that all VAL forms are evaluated (in order)
1164before assigning any symbols SYM to the corresponding values."
1165 (cons 'psetf args))
1166
1167
1168;;; Binding control structures.
1169
1170(defmacro progv (symbols values &rest body)
64a4c526 1171 "Bind SYMBOLS to VALUES dynamically in BODY.
fcd73769
RS
1172The forms SYMBOLS and VALUES are evaluated, and must evaluate to lists.
1173Each SYMBOL in the first list is bound to the corresponding VALUE in the
1174second list (or made unbound if VALUES is shorter than SYMBOLS); then the
1175BODY forms are executed and their result is returned. This is much like
1176a `let' form, except that the list of symbols can be computed at run-time."
1177 (list 'let '((cl-progv-save nil))
1178 (list 'unwind-protect
1179 (list* 'progn (list 'cl-progv-before symbols values) body)
1180 '(cl-progv-after))))
1181
1182;;; This should really have some way to shadow 'byte-compile properties, etc.
1183(defmacro flet (bindings &rest body)
1184 "(flet ((FUNC ARGLIST BODY...) ...) FORM...): make temporary function defns.
1185This is an analogue of `let' that operates on the function cell of FUNC
1186rather than its value cell. The FORMs are evaluated with the specified
1187function definitions in place, then the definitions are undone (the FUNCs
1188go back to their previous definitions, or lack thereof)."
1189 (list* 'letf*
1190 (mapcar
1191 (function
1192 (lambda (x)
36f0f2b1
RS
1193 (if (or (and (fboundp (car x))
1194 (eq (car-safe (symbol-function (car x))) 'macro))
1195 (cdr (assq (car x) cl-macro-environment)))
1196 (error "Use `labels', not `flet', to rebind macro names"))
fcd73769
RS
1197 (let ((func (list 'function*
1198 (list 'lambda (cadr x)
1199 (list* 'block (car x) (cddr x))))))
1200 (if (and (cl-compiling-file)
1201 (boundp 'byte-compile-function-environment))
1202 (cl-push (cons (car x) (eval func))
1203 byte-compile-function-environment))
1204 (list (list 'symbol-function (list 'quote (car x))) func))))
1205 bindings)
1206 body))
1207
36f0f2b1
RS
1208(defmacro labels (bindings &rest body)
1209 "(labels ((FUNC ARGLIST BODY...) ...) FORM...): make temporary func bindings.
1210This is like `flet', except the bindings are lexical instead of dynamic.
1211Unlike `flet', this macro is fully complaint with the Common Lisp standard."
1212 (let ((vars nil) (sets nil) (cl-macro-environment cl-macro-environment))
1213 (while bindings
1214 (let ((var (gensym)))
1215 (cl-push var vars)
1216 (cl-push (list 'function* (cons 'lambda (cdar bindings))) sets)
1217 (cl-push var sets)
1218 (cl-push (list (car (cl-pop bindings)) 'lambda '(&rest cl-labels-args)
1219 (list 'list* '(quote funcall) (list 'quote var)
1220 'cl-labels-args))
1221 cl-macro-environment)))
1222 (cl-macroexpand-all (list* 'lexical-let vars (cons (cons 'setq sets) body))
1223 cl-macro-environment)))
fcd73769
RS
1224
1225;; The following ought to have a better definition for use with newer
1226;; byte compilers.
1227(defmacro macrolet (bindings &rest body)
1228 "(macrolet ((NAME ARGLIST BODY...) ...) FORM...): make temporary macro defns.
1229This is like `flet', but for macros instead of functions."
1230 (if (cdr bindings)
1231 (list 'macrolet
1232 (list (car bindings)) (list* 'macrolet (cdr bindings) body))
1233 (if (null bindings) (cons 'progn body)
1234 (let* ((name (caar bindings))
1235 (res (cl-transform-lambda (cdar bindings) name)))
1236 (eval (car res))
1237 (cl-macroexpand-all (cons 'progn body)
1238 (cons (list* name 'lambda (cdr res))
1239 cl-macro-environment))))))
1240
1241(defmacro symbol-macrolet (bindings &rest body)
1242 "(symbol-macrolet ((NAME EXPANSION) ...) FORM...): make symbol macro defns.
1243Within the body FORMs, references to the variable NAME will be replaced
1244by EXPANSION, and (setq NAME ...) will act like (setf EXPANSION ...)."
1245 (if (cdr bindings)
1246 (list 'symbol-macrolet
1247 (list (car bindings)) (list* 'symbol-macrolet (cdr bindings) body))
1248 (if (null bindings) (cons 'progn body)
1249 (cl-macroexpand-all (cons 'progn body)
1250 (cons (list (symbol-name (caar bindings))
1251 (cadar bindings))
1252 cl-macro-environment)))))
1253
1254(defvar cl-closure-vars nil)
1255(defmacro lexical-let (bindings &rest body)
64a4c526 1256 "Like `let', but lexically scoped.
fcd73769
RS
1257The main visible difference is that lambdas inside BODY will create
1258lexical closures as in Common Lisp."
1259 (let* ((cl-closure-vars cl-closure-vars)
1260 (vars (mapcar (function
1261 (lambda (x)
1262 (or (consp x) (setq x (list x)))
1263 (cl-push (gensym (format "--%s--" (car x)))
1264 cl-closure-vars)
70a036cf 1265 (set (car cl-closure-vars) [bad-lexical-ref])
fcd73769
RS
1266 (list (car x) (cadr x) (car cl-closure-vars))))
1267 bindings))
1268 (ebody
1269 (cl-macroexpand-all
1270 (cons 'progn body)
1271 (nconc (mapcar (function (lambda (x)
1272 (list (symbol-name (car x))
1273 (list 'symbol-value (caddr x))
1274 t))) vars)
1275 (list '(defun . cl-defun-expander))
1276 cl-macro-environment))))
1277 (if (not (get (car (last cl-closure-vars)) 'used))
1278 (list 'let (mapcar (function (lambda (x)
1279 (list (caddr x) (cadr x)))) vars)
1280 (sublis (mapcar (function (lambda (x)
1281 (cons (caddr x)
1282 (list 'quote (caddr x)))))
1283 vars)
1284 ebody))
1285 (list 'let (mapcar (function (lambda (x)
1286 (list (caddr x)
1287 (list 'make-symbol
1288 (format "--%s--" (car x))))))
1289 vars)
1290 (apply 'append '(setf)
1291 (mapcar (function
1292 (lambda (x)
1293 (list (list 'symbol-value (caddr x)) (cadr x))))
1294 vars))
1295 ebody))))
1296
1297(defmacro lexical-let* (bindings &rest body)
64a4c526 1298 "Like `let*', but lexically scoped.
fcd73769
RS
1299The main visible difference is that lambdas inside BODY will create
1300lexical closures as in Common Lisp."
1301 (if (null bindings) (cons 'progn body)
1302 (setq bindings (reverse bindings))
1303 (while bindings
1304 (setq body (list (list* 'lexical-let (list (cl-pop bindings)) body))))
1305 (car body)))
1306
1307(defun cl-defun-expander (func &rest rest)
1308 (list 'progn
1309 (list 'defalias (list 'quote func)
1310 (list 'function (cons 'lambda rest)))
1311 (list 'quote func)))
1312
1313
1314;;; Multiple values.
1315
1316(defmacro multiple-value-bind (vars form &rest body)
1317 "(multiple-value-bind (SYM SYM...) FORM BODY): collect multiple return values.
1318FORM must return a list; the BODY is then executed with the first N elements
1319of this list bound (`let'-style) to each of the symbols SYM in turn. This
1320is analogous to the Common Lisp `multiple-value-bind' macro, using lists to
1321simulate true multiple return values. For compatibility, (values A B C) is
1322a synonym for (list A B C)."
1323 (let ((temp (gensym)) (n -1))
1324 (list* 'let* (cons (list temp form)
1325 (mapcar (function
1326 (lambda (v)
1327 (list v (list 'nth (setq n (1+ n)) temp))))
1328 vars))
1329 body)))
1330
1331(defmacro multiple-value-setq (vars form)
1332 "(multiple-value-setq (SYM SYM...) FORM): collect multiple return values.
1333FORM must return a list; the first N elements of this list are stored in
1334each of the symbols SYM in turn. This is analogous to the Common Lisp
1335`multiple-value-setq' macro, using lists to simulate true multiple return
1336values. For compatibility, (values A B C) is a synonym for (list A B C)."
1337 (cond ((null vars) (list 'progn form nil))
1338 ((null (cdr vars)) (list 'setq (car vars) (list 'car form)))
1339 (t
1340 (let* ((temp (gensym)) (n 0))
1341 (list 'let (list (list temp form))
1342 (list 'prog1 (list 'setq (cl-pop vars) (list 'car temp))
1343 (cons 'setq (apply 'nconc
1344 (mapcar (function
1345 (lambda (v)
1346 (list v (list
1347 'nth
1348 (setq n (1+ n))
1349 temp))))
1350 vars)))))))))
1351
1352
1353;;; Declarations.
1354
1355(defmacro locally (&rest body) (cons 'progn body))
1356(defmacro the (type form) form)
1357
1358(defvar cl-proclaim-history t) ; for future compilers
1359(defvar cl-declare-stack t) ; for future compilers
1360
1361(defun cl-do-proclaim (spec hist)
1362 (and hist (listp cl-proclaim-history) (cl-push spec cl-proclaim-history))
1363 (cond ((eq (car-safe spec) 'special)
1364 (if (boundp 'byte-compile-bound-variables)
1365 (setq byte-compile-bound-variables
1366 (append (cdr spec) byte-compile-bound-variables))))
1367
1368 ((eq (car-safe spec) 'inline)
1369 (while (setq spec (cdr spec))
1370 (or (memq (get (car spec) 'byte-optimizer)
1371 '(nil byte-compile-inline-expand))
1372 (error "%s already has a byte-optimizer, can't make it inline"
1373 (car spec)))
1374 (put (car spec) 'byte-optimizer 'byte-compile-inline-expand)))
1375
1376 ((eq (car-safe spec) 'notinline)
1377 (while (setq spec (cdr spec))
1378 (if (eq (get (car spec) 'byte-optimizer)
1379 'byte-compile-inline-expand)
1380 (put (car spec) 'byte-optimizer nil))))
1381
1382 ((eq (car-safe spec) 'optimize)
1383 (let ((speed (assq (nth 1 (assq 'speed (cdr spec)))
1384 '((0 nil) (1 t) (2 t) (3 t))))
1385 (safety (assq (nth 1 (assq 'safety (cdr spec)))
1386 '((0 t) (1 t) (2 t) (3 nil)))))
1387 (if speed (setq cl-optimize-speed (car speed)
1388 byte-optimize (nth 1 speed)))
1389 (if safety (setq cl-optimize-safety (car safety)
1390 byte-compile-delete-errors (nth 1 safety)))))
1391
1392 ((and (eq (car-safe spec) 'warn) (boundp 'byte-compile-warnings))
1393 (if (eq byte-compile-warnings t)
1394 (setq byte-compile-warnings byte-compile-warning-types))
1395 (while (setq spec (cdr spec))
1396 (if (consp (car spec))
1397 (if (eq (cadar spec) 0)
1398 (setq byte-compile-warnings
1399 (delq (caar spec) byte-compile-warnings))
1400 (setq byte-compile-warnings
1401 (adjoin (caar spec) byte-compile-warnings)))))))
1402 nil)
1403
1404;;; Process any proclamations made before cl-macs was loaded.
1405(defvar cl-proclaims-deferred)
1406(let ((p (reverse cl-proclaims-deferred)))
1407 (while p (cl-do-proclaim (cl-pop p) t))
1408 (setq cl-proclaims-deferred nil))
1409
1410(defmacro declare (&rest specs)
1411 (if (cl-compiling-file)
1412 (while specs
1413 (if (listp cl-declare-stack) (cl-push (car specs) cl-declare-stack))
1414 (cl-do-proclaim (cl-pop specs) nil)))
1415 nil)
1416
1417
1418
1419;;; Generalized variables.
1420
1421(defmacro define-setf-method (func args &rest body)
1422 "(define-setf-method NAME ARGLIST BODY...): define a `setf' method.
1423This method shows how to handle `setf's to places of the form (NAME ARGS...).
1424The argument forms ARGS are bound according to ARGLIST, as if NAME were
1425going to be expanded as a macro, then the BODY forms are executed and must
1426return a list of five elements: a temporary-variables list, a value-forms
1427list, a store-variables list (of length one), a store-form, and an access-
1428form. See `defsetf' for a simpler way to define most setf-methods."
1429 (append '(eval-when (compile load eval))
1430 (if (stringp (car body))
1431 (list (list 'put (list 'quote func) '(quote setf-documentation)
1432 (cl-pop body))))
1433 (list (cl-transform-function-property
1434 func 'setf-method (cons args body)))))
6a78f30f 1435(defalias 'define-setf-expander 'define-setf-method)
fcd73769
RS
1436
1437(defmacro defsetf (func arg1 &rest args)
1438 "(defsetf NAME FUNC): define a `setf' method.
1439This macro is an easy-to-use substitute for `define-setf-method' that works
1440well for simple place forms. In the simple `defsetf' form, `setf's of
1441the form (setf (NAME ARGS...) VAL) are transformed to function or macro
1442calls of the form (FUNC ARGS... VAL). Example: (defsetf aref aset).
1443Alternate form: (defsetf NAME ARGLIST (STORE) BODY...).
1444Here, the above `setf' call is expanded by binding the argument forms ARGS
1445according to ARGLIST, binding the value form VAL to STORE, then executing
1446BODY, which must return a Lisp form that does the necessary `setf' operation.
1447Actually, ARGLIST and STORE may be bound to temporary variables which are
1448introduced automatically to preserve proper execution order of the arguments.
1449Example: (defsetf nth (n x) (v) (list 'setcar (list 'nthcdr n x) v))."
1450 (if (listp arg1)
1451 (let* ((largs nil) (largsr nil)
1452 (temps nil) (tempsr nil)
1453 (restarg nil) (rest-temps nil)
1454 (store-var (car (prog1 (car args) (setq args (cdr args)))))
1455 (store-temp (intern (format "--%s--temp--" store-var)))
1456 (lets1 nil) (lets2 nil)
1457 (docstr nil) (p arg1))
1458 (if (stringp (car args))
1459 (setq docstr (prog1 (car args) (setq args (cdr args)))))
1460 (while (and p (not (eq (car p) '&aux)))
1461 (if (eq (car p) '&rest)
1462 (setq p (cdr p) restarg (car p))
1463 (or (memq (car p) '(&optional &key &allow-other-keys))
1464 (setq largs (cons (if (consp (car p)) (car (car p)) (car p))
1465 largs)
1466 temps (cons (intern (format "--%s--temp--" (car largs)))
1467 temps))))
1468 (setq p (cdr p)))
1469 (setq largs (nreverse largs) temps (nreverse temps))
1470 (if restarg
1471 (setq largsr (append largs (list restarg))
1472 rest-temps (intern (format "--%s--temp--" restarg))
1473 tempsr (append temps (list rest-temps)))
1474 (setq largsr largs tempsr temps))
1475 (let ((p1 largs) (p2 temps))
1476 (while p1
1477 (setq lets1 (cons (list (car p2)
1478 (list 'gensym (format "--%s--" (car p1))))
1479 lets1)
1480 lets2 (cons (list (car p1) (car p2)) lets2)
1481 p1 (cdr p1) p2 (cdr p2))))
1482 (if restarg (setq lets2 (cons (list restarg rest-temps) lets2)))
1483 (append (list 'define-setf-method func arg1)
1484 (and docstr (list docstr))
1485 (list
1486 (list 'let*
1487 (nreverse
1488 (cons (list store-temp
1489 (list 'gensym (format "--%s--" store-var)))
1490 (if restarg
1491 (append
1492 (list
1493 (list rest-temps
1494 (list 'mapcar '(quote gensym)
1495 restarg)))
1496 lets1)
1497 lets1)))
1498 (list 'list ; 'values
1499 (cons (if restarg 'list* 'list) tempsr)
1500 (cons (if restarg 'list* 'list) largsr)
1501 (list 'list store-temp)
1502 (cons 'let*
1503 (cons (nreverse
1504 (cons (list store-var store-temp)
1505 lets2))
1506 args))
1507 (cons (if restarg 'list* 'list)
1508 (cons (list 'quote func) tempsr)))))))
1509 (list 'defsetf func '(&rest args) '(store)
1510 (let ((call (list 'cons (list 'quote arg1)
1511 '(append args (list store)))))
1512 (if (car args)
1513 (list 'list '(quote progn) call 'store)
1514 call)))))
1515
1516;;; Some standard place types from Common Lisp.
1517(defsetf aref aset)
1518(defsetf car setcar)
1519(defsetf cdr setcdr)
c382fb0a
GM
1520(defsetf caar (x) (val) (list 'setcar (list 'car x) val))
1521(defsetf cadr (x) (val) (list 'setcar (list 'cdr x) val))
1522(defsetf cdar (x) (val) (list 'setcdr (list 'car x) val))
1523(defsetf cddr (x) (val) (list 'setcdr (list 'cdr x) val))
fcd73769
RS
1524(defsetf elt (seq n) (store)
1525 (list 'if (list 'listp seq) (list 'setcar (list 'nthcdr n seq) store)
1526 (list 'aset seq n store)))
1527(defsetf get put)
1528(defsetf get* (x y &optional d) (store) (list 'put x y store))
1529(defsetf gethash (x h &optional d) (store) (list 'cl-puthash x store h))
1530(defsetf nth (n x) (store) (list 'setcar (list 'nthcdr n x) store))
1531(defsetf subseq (seq start &optional end) (new)
64a4c526 1532 (list 'progn (list 'replace seq new :start1 start :end1 end) new))
fcd73769
RS
1533(defsetf symbol-function fset)
1534(defsetf symbol-plist setplist)
1535(defsetf symbol-value set)
1536
1537;;; Various car/cdr aliases. Note that `cadr' is handled specially.
1538(defsetf first setcar)
1539(defsetf second (x) (store) (list 'setcar (list 'cdr x) store))
1540(defsetf third (x) (store) (list 'setcar (list 'cddr x) store))
1541(defsetf fourth (x) (store) (list 'setcar (list 'cdddr x) store))
1542(defsetf fifth (x) (store) (list 'setcar (list 'nthcdr 4 x) store))
1543(defsetf sixth (x) (store) (list 'setcar (list 'nthcdr 5 x) store))
1544(defsetf seventh (x) (store) (list 'setcar (list 'nthcdr 6 x) store))
1545(defsetf eighth (x) (store) (list 'setcar (list 'nthcdr 7 x) store))
1546(defsetf ninth (x) (store) (list 'setcar (list 'nthcdr 8 x) store))
1547(defsetf tenth (x) (store) (list 'setcar (list 'nthcdr 9 x) store))
1548(defsetf rest setcdr)
1549
1550;;; Some more Emacs-related place types.
1551(defsetf buffer-file-name set-visited-file-name t)
8146c81d
RS
1552(defsetf buffer-modified-p (&optional buf) (flag)
1553 (list 'with-current-buffer buf
1554 (list 'set-buffer-modified-p flag)))
fcd73769
RS
1555(defsetf buffer-name rename-buffer t)
1556(defsetf buffer-string () (store)
1557 (list 'progn '(erase-buffer) (list 'insert store)))
1558(defsetf buffer-substring cl-set-buffer-substring)
1559(defsetf current-buffer set-buffer)
1560(defsetf current-case-table set-case-table)
1561(defsetf current-column move-to-column t)
1562(defsetf current-global-map use-global-map t)
1563(defsetf current-input-mode () (store)
1564 (list 'progn (list 'apply 'set-input-mode store) store))
1565(defsetf current-local-map use-local-map t)
1566(defsetf current-window-configuration set-window-configuration t)
1567(defsetf default-file-modes set-default-file-modes t)
1568(defsetf default-value set-default)
1569(defsetf documentation-property put)
1570(defsetf extent-data set-extent-data)
1571(defsetf extent-face set-extent-face)
1572(defsetf extent-priority set-extent-priority)
1573(defsetf extent-end-position (ext) (store)
1574 (list 'progn (list 'set-extent-endpoints (list 'extent-start-position ext)
1575 store) store))
1576(defsetf extent-start-position (ext) (store)
1577 (list 'progn (list 'set-extent-endpoints store
1578 (list 'extent-end-position ext)) store))
1579(defsetf face-background (f &optional s) (x) (list 'set-face-background f x s))
1580(defsetf face-background-pixmap (f &optional s) (x)
1581 (list 'set-face-background-pixmap f x s))
1582(defsetf face-font (f &optional s) (x) (list 'set-face-font f x s))
1583(defsetf face-foreground (f &optional s) (x) (list 'set-face-foreground f x s))
1584(defsetf face-underline-p (f &optional s) (x)
1585 (list 'set-face-underline-p f x s))
1586(defsetf file-modes set-file-modes t)
1587(defsetf frame-height set-screen-height t)
1588(defsetf frame-parameters modify-frame-parameters t)
1589(defsetf frame-visible-p cl-set-frame-visible-p)
1590(defsetf frame-width set-screen-width t)
313b6c69 1591(defsetf frame-parameter set-frame-parameter)
fcd73769
RS
1592(defsetf getenv setenv t)
1593(defsetf get-register set-register)
1594(defsetf global-key-binding global-set-key)
1595(defsetf keymap-parent set-keymap-parent)
1596(defsetf local-key-binding local-set-key)
1597(defsetf mark set-mark t)
1598(defsetf mark-marker set-mark t)
1599(defsetf marker-position set-marker t)
cdef3323 1600(defsetf match-data set-match-data t)
fcd73769
RS
1601(defsetf mouse-position (scr) (store)
1602 (list 'set-mouse-position scr (list 'car store) (list 'cadr store)
1603 (list 'cddr store)))
1604(defsetf overlay-get overlay-put)
1605(defsetf overlay-start (ov) (store)
1606 (list 'progn (list 'move-overlay ov store (list 'overlay-end ov)) store))
1607(defsetf overlay-end (ov) (store)
1608 (list 'progn (list 'move-overlay ov (list 'overlay-start ov) store) store))
1609(defsetf point goto-char)
1610(defsetf point-marker goto-char t)
1611(defsetf point-max () (store)
1612 (list 'progn (list 'narrow-to-region '(point-min) store) store))
1613(defsetf point-min () (store)
1614 (list 'progn (list 'narrow-to-region store '(point-max)) store))
1615(defsetf process-buffer set-process-buffer)
1616(defsetf process-filter set-process-filter)
1617(defsetf process-sentinel set-process-sentinel)
1618(defsetf read-mouse-position (scr) (store)
1619 (list 'set-mouse-position scr (list 'car store) (list 'cdr store)))
1620(defsetf screen-height set-screen-height t)
1621(defsetf screen-width set-screen-width t)
1622(defsetf selected-window select-window)
1623(defsetf selected-screen select-screen)
1624(defsetf selected-frame select-frame)
1625(defsetf standard-case-table set-standard-case-table)
1626(defsetf syntax-table set-syntax-table)
1627(defsetf visited-file-modtime set-visited-file-modtime t)
1628(defsetf window-buffer set-window-buffer t)
1629(defsetf window-display-table set-window-display-table t)
1630(defsetf window-dedicated-p set-window-dedicated-p t)
1631(defsetf window-height () (store)
1632 (list 'progn (list 'enlarge-window (list '- store '(window-height))) store))
1633(defsetf window-hscroll set-window-hscroll)
1634(defsetf window-point set-window-point)
1635(defsetf window-start set-window-start)
1636(defsetf window-width () (store)
1637 (list 'progn (list 'enlarge-window (list '- store '(window-width)) t) store))
1638(defsetf x-get-cutbuffer x-store-cutbuffer t)
1639(defsetf x-get-cut-buffer x-store-cut-buffer t) ; groan.
1640(defsetf x-get-secondary-selection x-own-secondary-selection t)
1641(defsetf x-get-selection x-own-selection t)
1642
1643;;; More complex setf-methods.
1644;;; These should take &environment arguments, but since full arglists aren't
1645;;; available while compiling cl-macs, we fake it by referring to the global
1646;;; variable cl-macro-environment directly.
1647
1648(define-setf-method apply (func arg1 &rest rest)
1649 (or (and (memq (car-safe func) '(quote function function*))
1650 (symbolp (car-safe (cdr-safe func))))
1651 (error "First arg to apply in setf is not (function SYM): %s" func))
1652 (let* ((form (cons (nth 1 func) (cons arg1 rest)))
1653 (method (get-setf-method form cl-macro-environment)))
1654 (list (car method) (nth 1 method) (nth 2 method)
1655 (cl-setf-make-apply (nth 3 method) (cadr func) (car method))
1656 (cl-setf-make-apply (nth 4 method) (cadr func) (car method)))))
1657
1658(defun cl-setf-make-apply (form func temps)
1659 (if (eq (car form) 'progn)
1660 (list* 'progn (cl-setf-make-apply (cadr form) func temps) (cddr form))
1661 (or (equal (last form) (last temps))
1662 (error "%s is not suitable for use with setf-of-apply" func))
1663 (list* 'apply (list 'quote (car form)) (cdr form))))
1664
1665(define-setf-method nthcdr (n place)
1666 (let ((method (get-setf-method place cl-macro-environment))
1667 (n-temp (gensym "--nthcdr-n--"))
1668 (store-temp (gensym "--nthcdr-store--")))
1669 (list (cons n-temp (car method))
1670 (cons n (nth 1 method))
1671 (list store-temp)
1672 (list 'let (list (list (car (nth 2 method))
1673 (list 'cl-set-nthcdr n-temp (nth 4 method)
1674 store-temp)))
1675 (nth 3 method) store-temp)
1676 (list 'nthcdr n-temp (nth 4 method)))))
1677
1678(define-setf-method getf (place tag &optional def)
1679 (let ((method (get-setf-method place cl-macro-environment))
1680 (tag-temp (gensym "--getf-tag--"))
1681 (def-temp (gensym "--getf-def--"))
1682 (store-temp (gensym "--getf-store--")))
1683 (list (append (car method) (list tag-temp def-temp))
1684 (append (nth 1 method) (list tag def))
1685 (list store-temp)
1686 (list 'let (list (list (car (nth 2 method))
1687 (list 'cl-set-getf (nth 4 method)
1688 tag-temp store-temp)))
1689 (nth 3 method) store-temp)
1690 (list 'getf (nth 4 method) tag-temp def-temp))))
1691
1692(define-setf-method substring (place from &optional to)
1693 (let ((method (get-setf-method place cl-macro-environment))
1694 (from-temp (gensym "--substring-from--"))
1695 (to-temp (gensym "--substring-to--"))
1696 (store-temp (gensym "--substring-store--")))
1697 (list (append (car method) (list from-temp to-temp))
1698 (append (nth 1 method) (list from to))
1699 (list store-temp)
1700 (list 'let (list (list (car (nth 2 method))
1701 (list 'cl-set-substring (nth 4 method)
1702 from-temp to-temp store-temp)))
1703 (nth 3 method) store-temp)
1704 (list 'substring (nth 4 method) from-temp to-temp))))
1705
1706;;; Getting and optimizing setf-methods.
1707(defun get-setf-method (place &optional env)
1708 "Return a list of five values describing the setf-method for PLACE.
1709PLACE may be any Lisp form which can appear as the PLACE argument to
1710a macro like `setf' or `incf'."
1711 (if (symbolp place)
1712 (let ((temp (gensym "--setf--")))
1713 (list nil nil (list temp) (list 'setq place temp) place))
1714 (or (and (symbolp (car place))
1715 (let* ((func (car place))
1716 (name (symbol-name func))
1717 (method (get func 'setf-method))
1718 (case-fold-search nil))
1719 (or (and method
1720 (let ((cl-macro-environment env))
1721 (setq method (apply method (cdr place))))
1722 (if (and (consp method) (= (length method) 5))
1723 method
1724 (error "Setf-method for %s returns malformed method"
1725 func)))
ac05d33c
EN
1726 (and (save-match-data
1727 (string-match "\\`c[ad][ad][ad]?[ad]?r\\'" name))
fcd73769
RS
1728 (get-setf-method (compiler-macroexpand place)))
1729 (and (eq func 'edebug-after)
1730 (get-setf-method (nth (1- (length place)) place)
1731 env)))))
1732 (if (eq place (setq place (macroexpand place env)))
1733 (if (and (symbolp (car place)) (fboundp (car place))
1734 (symbolp (symbol-function (car place))))
1735 (get-setf-method (cons (symbol-function (car place))
1736 (cdr place)) env)
1737 (error "No setf-method known for %s" (car place)))
1738 (get-setf-method place env)))))
1739
1740(defun cl-setf-do-modify (place opt-expr)
1741 (let* ((method (get-setf-method place cl-macro-environment))
1742 (temps (car method)) (values (nth 1 method))
1743 (lets nil) (subs nil)
1744 (optimize (and (not (eq opt-expr 'no-opt))
1745 (or (and (not (eq opt-expr 'unsafe))
1746 (cl-safe-expr-p opt-expr))
1747 (cl-setf-simple-store-p (car (nth 2 method))
1748 (nth 3 method)))))
1749 (simple (and optimize (consp place) (cl-simple-exprs-p (cdr place)))))
1750 (while values
1751 (if (or simple (cl-const-expr-p (car values)))
1752 (cl-push (cons (cl-pop temps) (cl-pop values)) subs)
1753 (cl-push (list (cl-pop temps) (cl-pop values)) lets)))
1754 (list (nreverse lets)
1755 (cons (car (nth 2 method)) (sublis subs (nth 3 method)))
1756 (sublis subs (nth 4 method)))))
1757
1758(defun cl-setf-do-store (spec val)
1759 (let ((sym (car spec))
1760 (form (cdr spec)))
1761 (if (or (cl-const-expr-p val)
1762 (and (cl-simple-expr-p val) (eq (cl-expr-contains form sym) 1))
1763 (cl-setf-simple-store-p sym form))
1764 (subst val sym form)
1765 (list 'let (list (list sym val)) form))))
1766
1767(defun cl-setf-simple-store-p (sym form)
1768 (and (consp form) (eq (cl-expr-contains form sym) 1)
1769 (eq (nth (1- (length form)) form) sym)
1770 (symbolp (car form)) (fboundp (car form))
1771 (not (eq (car-safe (symbol-function (car form))) 'macro))))
1772
1773;;; The standard modify macros.
1774(defmacro setf (&rest args)
1775 "(setf PLACE VAL PLACE VAL ...): set each PLACE to the value of its VAL.
1776This is a generalized version of `setq'; the PLACEs may be symbolic
1777references such as (car x) or (aref x i), as well as plain symbols.
1778For example, (setf (cadar x) y) is equivalent to (setcar (cdar x) y).
1779The return value is the last VAL in the list."
1780 (if (cdr (cdr args))
1781 (let ((sets nil))
1782 (while args (cl-push (list 'setf (cl-pop args) (cl-pop args)) sets))
1783 (cons 'progn (nreverse sets)))
1784 (if (symbolp (car args))
1785 (and args (cons 'setq args))
1786 (let* ((method (cl-setf-do-modify (car args) (nth 1 args)))
1787 (store (cl-setf-do-store (nth 1 method) (nth 1 args))))
1788 (if (car method) (list 'let* (car method) store) store)))))
1789
1790(defmacro psetf (&rest args)
1791 "(psetf PLACE VAL PLACE VAL ...): set PLACEs to the values VALs in parallel.
1792This is like `setf', except that all VAL forms are evaluated (in order)
1793before assigning any PLACEs to the corresponding values."
1794 (let ((p args) (simple t) (vars nil))
1795 (while p
1796 (if (or (not (symbolp (car p))) (cl-expr-depends-p (nth 1 p) vars))
1797 (setq simple nil))
1798 (if (memq (car p) vars)
1799 (error "Destination duplicated in psetf: %s" (car p)))
1800 (cl-push (cl-pop p) vars)
1801 (or p (error "Odd number of arguments to psetf"))
1802 (cl-pop p))
1803 (if simple
1804 (list 'progn (cons 'setf args) nil)
1805 (setq args (reverse args))
1806 (let ((expr (list 'setf (cadr args) (car args))))
1807 (while (setq args (cddr args))
1808 (setq expr (list 'setf (cadr args) (list 'prog1 (car args) expr))))
1809 (list 'progn expr nil)))))
1810
1811(defun cl-do-pop (place)
1812 (if (cl-simple-expr-p place)
1813 (list 'prog1 (list 'car place) (list 'setf place (list 'cdr place)))
1814 (let* ((method (cl-setf-do-modify place t))
1815 (temp (gensym "--pop--")))
1816 (list 'let*
1817 (append (car method)
1818 (list (list temp (nth 2 method))))
1819 (list 'prog1
1820 (list 'car temp)
1821 (cl-setf-do-store (nth 1 method) (list 'cdr temp)))))))
1822
1823(defmacro remf (place tag)
64a4c526 1824 "Remove TAG from property list PLACE.
fcd73769
RS
1825PLACE may be a symbol, or any generalized variable allowed by `setf'.
1826The form returns true if TAG was found and removed, nil otherwise."
1827 (let* ((method (cl-setf-do-modify place t))
1828 (tag-temp (and (not (cl-const-expr-p tag)) (gensym "--remf-tag--")))
1829 (val-temp (and (not (cl-simple-expr-p place))
1830 (gensym "--remf-place--")))
1831 (ttag (or tag-temp tag))
1832 (tval (or val-temp (nth 2 method))))
1833 (list 'let*
1834 (append (car method)
1835 (and val-temp (list (list val-temp (nth 2 method))))
1836 (and tag-temp (list (list tag-temp tag))))
1837 (list 'if (list 'eq ttag (list 'car tval))
1838 (list 'progn
1839 (cl-setf-do-store (nth 1 method) (list 'cddr tval))
1840 t)
1841 (list 'cl-do-remf tval ttag)))))
1842
1843(defmacro shiftf (place &rest args)
1844 "(shiftf PLACE PLACE... VAL): shift left among PLACEs.
1845Example: (shiftf A B C) sets A to B, B to C, and returns the old A.
1846Each PLACE may be a symbol, or any generalized variable allowed by `setf'."
2fa5eef4
SM
1847 (cond
1848 ((null args) place)
1849 ((symbolp place) `(prog1 ,place (setq ,place (shiftf ,@args))))
1850 (t
1851 (let ((method (cl-setf-do-modify place 'unsafe)))
1852 `(let* ,(car method)
1853 (prog1 ,(nth 2 method)
1854 ,(cl-setf-do-store (nth 1 method) `(shiftf ,@args))))))))
fcd73769
RS
1855
1856(defmacro rotatef (&rest args)
1857 "(rotatef PLACE...): rotate left among PLACEs.
1858Example: (rotatef A B C) sets A to B, B to C, and C to A. It returns nil.
1859Each PLACE may be a symbol, or any generalized variable allowed by `setf'."
1860 (if (not (memq nil (mapcar 'symbolp args)))
1861 (and (cdr args)
1862 (let ((sets nil)
1863 (first (car args)))
1864 (while (cdr args)
1865 (setq sets (nconc sets (list (cl-pop args) (car args)))))
1866 (nconc (list 'psetf) sets (list (car args) first))))
1867 (let* ((places (reverse args))
1868 (temp (gensym "--rotatef--"))
1869 (form temp))
1870 (while (cdr places)
1871 (let ((method (cl-setf-do-modify (cl-pop places) 'unsafe)))
1872 (setq form (list 'let* (car method)
1873 (list 'prog1 (nth 2 method)
1874 (cl-setf-do-store (nth 1 method) form))))))
1875 (let ((method (cl-setf-do-modify (car places) 'unsafe)))
1876 (list 'let* (append (car method) (list (list temp (nth 2 method))))
1877 (cl-setf-do-store (nth 1 method) form) nil)))))
1878
1879(defmacro letf (bindings &rest body)
1880 "(letf ((PLACE VALUE) ...) BODY...): temporarily bind to PLACEs.
1881This is the analogue of `let', but with generalized variables (in the
1882sense of `setf') for the PLACEs. Each PLACE is set to the corresponding
1883VALUE, then the BODY forms are executed. On exit, either normally or
1884because of a `throw' or error, the PLACEs are set back to their original
1885values. Note that this macro is *not* available in Common Lisp.
1886As a special case, if `(PLACE)' is used instead of `(PLACE VALUE)',
1887the PLACE is not modified before executing BODY."
1888 (if (and (not (cdr bindings)) (cdar bindings) (symbolp (caar bindings)))
1889 (list* 'let bindings body)
1890 (let ((lets nil) (sets nil)
1891 (unsets nil) (rev (reverse bindings)))
1892 (while rev
1893 (let* ((place (if (symbolp (caar rev))
1894 (list 'symbol-value (list 'quote (caar rev)))
1895 (caar rev)))
1896 (value (cadar rev))
1897 (method (cl-setf-do-modify place 'no-opt))
1898 (save (gensym "--letf-save--"))
1899 (bound (and (memq (car place) '(symbol-value symbol-function))
1900 (gensym "--letf-bound--")))
1901 (temp (and (not (cl-const-expr-p value)) (cdr bindings)
1902 (gensym "--letf-val--"))))
1903 (setq lets (nconc (car method)
1904 (if bound
1905 (list (list bound
1906 (list (if (eq (car place)
1907 'symbol-value)
1908 'boundp 'fboundp)
1909 (nth 1 (nth 2 method))))
1910 (list save (list 'and bound
1911 (nth 2 method))))
1912 (list (list save (nth 2 method))))
1913 (and temp (list (list temp value)))
1914 lets)
1915 body (list
1916 (list 'unwind-protect
1917 (cons 'progn
1918 (if (cdr (car rev))
1919 (cons (cl-setf-do-store (nth 1 method)
1920 (or temp value))
1921 body)
1922 body))
1923 (if bound
1924 (list 'if bound
1925 (cl-setf-do-store (nth 1 method) save)
1926 (list (if (eq (car place) 'symbol-value)
1927 'makunbound 'fmakunbound)
1928 (nth 1 (nth 2 method))))
1929 (cl-setf-do-store (nth 1 method) save))))
1930 rev (cdr rev))))
1931 (list* 'let* lets body))))
1932
1933(defmacro letf* (bindings &rest body)
1934 "(letf* ((PLACE VALUE) ...) BODY...): temporarily bind to PLACEs.
1935This is the analogue of `let*', but with generalized variables (in the
1936sense of `setf') for the PLACEs. Each PLACE is set to the corresponding
1937VALUE, then the BODY forms are executed. On exit, either normally or
1938because of a `throw' or error, the PLACEs are set back to their original
1939values. Note that this macro is *not* available in Common Lisp.
1940As a special case, if `(PLACE)' is used instead of `(PLACE VALUE)',
1941the PLACE is not modified before executing BODY."
1942 (if (null bindings)
1943 (cons 'progn body)
1944 (setq bindings (reverse bindings))
1945 (while bindings
1946 (setq body (list (list* 'letf (list (cl-pop bindings)) body))))
1947 (car body)))
1948
1949(defmacro callf (func place &rest args)
1950 "(callf FUNC PLACE ARGS...): set PLACE to (FUNC PLACE ARGS...).
1951FUNC should be an unquoted function name. PLACE may be a symbol,
1952or any generalized variable allowed by `setf'."
1953 (let* ((method (cl-setf-do-modify place (cons 'list args)))
1954 (rargs (cons (nth 2 method) args)))
1955 (list 'let* (car method)
1956 (cl-setf-do-store (nth 1 method)
1957 (if (symbolp func) (cons func rargs)
1958 (list* 'funcall (list 'function func)
1959 rargs))))))
1960
1961(defmacro callf2 (func arg1 place &rest args)
1962 "(callf2 FUNC ARG1 PLACE ARGS...): set PLACE to (FUNC ARG1 PLACE ARGS...).
1963Like `callf', but PLACE is the second argument of FUNC, not the first."
1964 (if (and (cl-safe-expr-p arg1) (cl-simple-expr-p place) (symbolp func))
1965 (list 'setf place (list* func arg1 place args))
1966 (let* ((method (cl-setf-do-modify place (cons 'list args)))
1967 (temp (and (not (cl-const-expr-p arg1)) (gensym "--arg1--")))
1968 (rargs (list* (or temp arg1) (nth 2 method) args)))
1969 (list 'let* (append (and temp (list (list temp arg1))) (car method))
1970 (cl-setf-do-store (nth 1 method)
1971 (if (symbolp func) (cons func rargs)
1972 (list* 'funcall (list 'function func)
1973 rargs)))))))
1974
1975(defmacro define-modify-macro (name arglist func &optional doc)
64a4c526 1976 "Define a `setf'-like modify macro.
fcd73769
RS
1977If NAME is called, it combines its PLACE argument with the other arguments
1978from ARGLIST using FUNC: (define-modify-macro incf (&optional (n 1)) +)"
1979 (if (memq '&key arglist) (error "&key not allowed in define-modify-macro"))
1980 (let ((place (gensym "--place--")))
1981 (list 'defmacro* name (cons place arglist) doc
1982 (list* (if (memq '&rest arglist) 'list* 'list)
1983 '(quote callf) (list 'quote func) place
1984 (cl-arglist-args arglist)))))
1985
1986
1987;;; Structures.
1988
1989(defmacro defstruct (struct &rest descs)
1990 "(defstruct (NAME OPTIONS...) (SLOT SLOT-OPTS...)...): define a struct type.
1991This macro defines a new Lisp data type called NAME, which contains data
1992stored in SLOTs. This defines a `make-NAME' constructor, a `copy-NAME'
1993copier, a `NAME-p' predicate, and setf-able `NAME-SLOT' accessors."
1994 (let* ((name (if (consp struct) (car struct) struct))
1995 (opts (cdr-safe struct))
1996 (slots nil)
1997 (defaults nil)
1998 (conc-name (concat (symbol-name name) "-"))
1999 (constructor (intern (format "make-%s" name)))
2000 (constrs nil)
2001 (copier (intern (format "copy-%s" name)))
2002 (predicate (intern (format "%s-p" name)))
2003 (print-func nil) (print-auto nil)
2004 (safety (if (cl-compiling-file) cl-optimize-safety 3))
2005 (include nil)
2006 (tag (intern (format "cl-struct-%s" name)))
2007 (tag-symbol (intern (format "cl-struct-%s-tags" name)))
2008 (include-descs nil)
fcd73769
RS
2009 (side-eff nil)
2010 (type nil)
2011 (named nil)
2012 (forms nil)
2013 pred-form pred-check)
2014 (if (stringp (car descs))
2015 (cl-push (list 'put (list 'quote name) '(quote structure-documentation)
2016 (cl-pop descs)) forms))
2017 (setq descs (cons '(cl-tag-slot)
2018 (mapcar (function (lambda (x) (if (consp x) x (list x))))
2019 descs)))
2020 (while opts
2021 (let ((opt (if (consp (car opts)) (caar opts) (car opts)))
2022 (args (cdr-safe (cl-pop opts))))
64a4c526 2023 (cond ((eq opt :conc-name)
fcd73769
RS
2024 (if args
2025 (setq conc-name (if (car args)
2026 (symbol-name (car args)) ""))))
64a4c526 2027 ((eq opt :constructor)
fcd73769
RS
2028 (if (cdr args)
2029 (cl-push args constrs)
2030 (if args (setq constructor (car args)))))
64a4c526 2031 ((eq opt :copier)
fcd73769 2032 (if args (setq copier (car args))))
64a4c526 2033 ((eq opt :predicate)
fcd73769 2034 (if args (setq predicate (car args))))
64a4c526 2035 ((eq opt :include)
fcd73769
RS
2036 (setq include (car args)
2037 include-descs (mapcar (function
2038 (lambda (x)
2039 (if (consp x) x (list x))))
36f0f2b1 2040 (cdr args))))
64a4c526 2041 ((eq opt :print-function)
fcd73769 2042 (setq print-func (car args)))
64a4c526 2043 ((eq opt :type)
fcd73769 2044 (setq type (car args)))
64a4c526 2045 ((eq opt :named)
fcd73769 2046 (setq named t))
64a4c526 2047 ((eq opt :initial-offset)
fcd73769
RS
2048 (setq descs (nconc (make-list (car args) '(cl-skip-slot))
2049 descs)))
2050 (t
2051 (error "Slot option %s unrecognized" opt)))))
2052 (if print-func
2053 (setq print-func (list 'progn
2054 (list 'funcall (list 'function print-func)
2055 'cl-x 'cl-s 'cl-n) t))
2056 (or type (and include (not (get include 'cl-struct-print)))
2057 (setq print-auto t
2058 print-func (and (or (not (or include type)) (null print-func))
2059 (list 'progn
2060 (list 'princ (format "#S(%s" name)
2061 'cl-s))))))
2062 (if include
2063 (let ((inc-type (get include 'cl-struct-type))
2064 (old-descs (get include 'cl-struct-slots)))
2065 (or inc-type (error "%s is not a struct name" include))
2066 (and type (not (eq (car inc-type) type))
2067 (error ":type disagrees with :include for %s" name))
2068 (while include-descs
2069 (setcar (memq (or (assq (caar include-descs) old-descs)
2070 (error "No slot %s in included struct %s"
2071 (caar include-descs) include))
2072 old-descs)
2073 (cl-pop include-descs)))
2074 (setq descs (append old-descs (delq (assq 'cl-tag-slot descs) descs))
2075 type (car inc-type)
2076 named (assq 'cl-tag-slot descs))
2077 (if (cadr inc-type) (setq tag name named t))
36f0f2b1
RS
2078 (let ((incl include))
2079 (while incl
2080 (cl-push (list 'pushnew (list 'quote tag)
2081 (intern (format "cl-struct-%s-tags" incl)))
2082 forms)
2083 (setq incl (get incl 'cl-struct-include)))))
fcd73769
RS
2084 (if type
2085 (progn
2086 (or (memq type '(vector list))
2087 (error "Illegal :type specifier: %s" type))
2088 (if named (setq tag name)))
2089 (setq type 'vector named 'true)))
2090 (or named (setq descs (delq (assq 'cl-tag-slot descs) descs)))
2091 (cl-push (list 'defvar tag-symbol) forms)
2092 (setq pred-form (and named
2093 (let ((pos (- (length descs)
2094 (length (memq (assq 'cl-tag-slot descs)
2095 descs)))))
2096 (if (eq type 'vector)
2097 (list 'and '(vectorp cl-x)
2098 (list '>= '(length cl-x) (length descs))
2099 (list 'memq (list 'aref 'cl-x pos)
2100 tag-symbol))
2101 (if (= pos 0)
2102 (list 'memq '(car-safe cl-x) tag-symbol)
2103 (list 'and '(consp cl-x)
2104 (list 'memq (list 'nth pos 'cl-x)
2105 tag-symbol))))))
2106 pred-check (and pred-form (> safety 0)
2107 (if (and (eq (caadr pred-form) 'vectorp)
2108 (= safety 1))
2109 (cons 'and (cdddr pred-form)) pred-form)))
2110 (let ((pos 0) (descp descs))
2111 (while descp
2112 (let* ((desc (cl-pop descp))
2113 (slot (car desc)))
2114 (if (memq slot '(cl-tag-slot cl-skip-slot))
2115 (progn
2116 (cl-push nil slots)
2117 (cl-push (and (eq slot 'cl-tag-slot) (list 'quote tag))
2118 defaults))
2119 (if (assq slot descp)
2120 (error "Duplicate slots named %s in %s" slot name))
2121 (let ((accessor (intern (format "%s%s" conc-name slot))))
2122 (cl-push slot slots)
2123 (cl-push (nth 1 desc) defaults)
2124 (cl-push (list*
2125 'defsubst* accessor '(cl-x)
2126 (append
2127 (and pred-check
2128 (list (list 'or pred-check
2129 (list 'error
2130 (format "%s accessing a non-%s"
2131 accessor name)
2132 'cl-x))))
2133 (list (if (eq type 'vector) (list 'aref 'cl-x pos)
2134 (if (= pos 0) '(car cl-x)
2135 (list 'nth pos 'cl-x)))))) forms)
2136 (cl-push (cons accessor t) side-eff)
2137 (cl-push (list 'define-setf-method accessor '(cl-x)
64a4c526 2138 (if (cadr (memq :read-only (cddr desc)))
fcd73769
RS
2139 (list 'error (format "%s is a read-only slot"
2140 accessor))
2141 (list 'cl-struct-setf-expander 'cl-x
2142 (list 'quote name) (list 'quote accessor)
2143 (and pred-check (list 'quote pred-check))
2144 pos)))
2145 forms)
2146 (if print-auto
2147 (nconc print-func
2148 (list (list 'princ (format " %s" slot) 'cl-s)
2149 (list 'prin1 (list accessor 'cl-x) 'cl-s)))))))
2150 (setq pos (1+ pos))))
2151 (setq slots (nreverse slots)
2152 defaults (nreverse defaults))
2153 (and predicate pred-form
2154 (progn (cl-push (list 'defsubst* predicate '(cl-x)
2155 (if (eq (car pred-form) 'and)
2156 (append pred-form '(t))
2157 (list 'and pred-form t))) forms)
2158 (cl-push (cons predicate 'error-free) side-eff)))
2159 (and copier
2160 (progn (cl-push (list 'defun copier '(x) '(copy-sequence x)) forms)
2161 (cl-push (cons copier t) side-eff)))
2162 (if constructor
2163 (cl-push (list constructor
2164 (cons '&key (delq nil (copy-sequence slots))))
2165 constrs))
2166 (while constrs
2167 (let* ((name (caar constrs))
2168 (args (cadr (cl-pop constrs)))
2169 (anames (cl-arglist-args args))
2170 (make (mapcar* (function (lambda (s d) (if (memq s anames) s d)))
2171 slots defaults)))
2172 (cl-push (list 'defsubst* name
2173 (list* '&cl-defs (list 'quote (cons nil descs)) args)
2174 (cons type make)) forms)
2175 (if (cl-safe-expr-p (cons 'progn (mapcar 'second descs)))
2176 (cl-push (cons name t) side-eff))))
2177 (if print-auto (nconc print-func (list '(princ ")" cl-s) t)))
2178 (if print-func
2179 (cl-push (list 'push
2180 (list 'function
2181 (list 'lambda '(cl-x cl-s cl-n)
2182 (list 'and pred-form print-func)))
2183 'custom-print-functions) forms))
2184 (cl-push (list 'setq tag-symbol (list 'list (list 'quote tag))) forms)
2185 (cl-push (list* 'eval-when '(compile load eval)
2186 (list 'put (list 'quote name) '(quote cl-struct-slots)
2187 (list 'quote descs))
2188 (list 'put (list 'quote name) '(quote cl-struct-type)
2189 (list 'quote (list type (eq named t))))
36f0f2b1
RS
2190 (list 'put (list 'quote name) '(quote cl-struct-include)
2191 (list 'quote include))
fcd73769
RS
2192 (list 'put (list 'quote name) '(quote cl-struct-print)
2193 print-auto)
2194 (mapcar (function (lambda (x)
2195 (list 'put (list 'quote (car x))
2196 '(quote side-effect-free)
2197 (list 'quote (cdr x)))))
2198 side-eff))
2199 forms)
2200 (cons 'progn (nreverse (cons (list 'quote name) forms)))))
2201
2202(defun cl-struct-setf-expander (x name accessor pred-form pos)
2203 (let* ((temp (gensym "--x--")) (store (gensym "--store--")))
2204 (list (list temp) (list x) (list store)
2205 (append '(progn)
2206 (and pred-form
2207 (list (list 'or (subst temp 'cl-x pred-form)
2208 (list 'error
2209 (format
2210 "%s storing a non-%s" accessor name)
2211 temp))))
2212 (list (if (eq (car (get name 'cl-struct-type)) 'vector)
2213 (list 'aset temp pos store)
2214 (list 'setcar
2215 (if (<= pos 5)
2216 (let ((xx temp))
2217 (while (>= (setq pos (1- pos)) 0)
2218 (setq xx (list 'cdr xx)))
2219 xx)
2220 (list 'nthcdr pos temp))
2221 store))))
2222 (list accessor temp))))
2223
2224
2225;;; Types and assertions.
2226
64a4c526
DL
2227(defmacro deftype (name arglist &rest body)
2228 "Define NAME as a new data type.
fcd73769
RS
2229The type name can then be used in `typecase', `check-type', etc."
2230 (list 'eval-when '(compile load eval)
2231 (cl-transform-function-property
64a4c526 2232 name 'cl-deftype-handler (cons (list* '&cl-defs ''('*) arglist) body))))
fcd73769
RS
2233
2234(defun cl-make-type-test (val type)
fcd73769
RS
2235 (if (symbolp type)
2236 (cond ((get type 'cl-deftype-handler)
2237 (cl-make-type-test val (funcall (get type 'cl-deftype-handler))))
2238 ((memq type '(nil t)) type)
e0b16322
SM
2239 ((eq type 'null) `(null ,val))
2240 ((eq type 'float) `(floatp-safe ,val))
2241 ((eq type 'real) `(numberp ,val))
2242 ((eq type 'fixnum) `(integerp ,val))
2243 ;; FIXME: Should `character' accept things like ?\C-\M-a ? -stef
dc338e19 2244 ((memq type '(character string-char)) `(char-valid-p ,val))
fcd73769
RS
2245 (t
2246 (let* ((name (symbol-name type))
2247 (namep (intern (concat name "p"))))
2248 (if (fboundp namep) (list namep val)
2249 (list (intern (concat name "-p")) val)))))
2250 (cond ((get (car type) 'cl-deftype-handler)
2251 (cl-make-type-test val (apply (get (car type) 'cl-deftype-handler)
2252 (cdr type))))
e0b16322
SM
2253 ((memq (car type) '(integer float real number))
2254 (delq t (and (cl-make-type-test val (car type))
fcd73769
RS
2255 (if (memq (cadr type) '(* nil)) t
2256 (if (consp (cadr type)) (list '> val (caadr type))
2257 (list '>= val (cadr type))))
2258 (if (memq (caddr type) '(* nil)) t
2259 (if (consp (caddr type)) (list '< val (caaddr type))
2260 (list '<= val (caddr type)))))))
e0b16322 2261 ((memq (car type) '(and or not))
fcd73769
RS
2262 (cons (car type)
2263 (mapcar (function (lambda (x) (cl-make-type-test val x)))
2264 (cdr type))))
e0b16322 2265 ((memq (car type) '(member member*))
fcd73769 2266 (list 'and (list 'member* val (list 'quote (cdr type))) t))
e0b16322 2267 ((eq (car type) 'satisfies) (list (cadr type) val))
fcd73769
RS
2268 (t (error "Bad type spec: %s" type)))))
2269
2270(defun typep (val type) ; See compiler macro below.
2271 "Check that OBJECT is of type TYPE.
2272TYPE is a Common Lisp-style type specifier."
2273 (eval (cl-make-type-test 'val type)))
2274
2275(defmacro check-type (form type &optional string)
2276 "Verify that FORM is of type TYPE; signal an error if not.
2277STRING is an optional description of the desired type."
2278 (and (or (not (cl-compiling-file))
2279 (< cl-optimize-speed 3) (= cl-optimize-safety 3))
2280 (let* ((temp (if (cl-simple-expr-p form 3) form (gensym)))
2281 (body (list 'or (cl-make-type-test temp type)
2282 (list 'signal '(quote wrong-type-argument)
2283 (list 'list (or string (list 'quote type))
2284 temp (list 'quote form))))))
2285 (if (eq temp form) (list 'progn body nil)
2286 (list 'let (list (list temp form)) body nil)))))
2287
2288(defmacro assert (form &optional show-args string &rest args)
2289 "Verify that FORM returns non-nil; signal an error if not.
2290Second arg SHOW-ARGS means to include arguments of FORM in message.
2291Other args STRING and ARGS... are arguments to be passed to `error'.
2292They are not evaluated unless the assertion fails. If STRING is
2293omitted, a default message listing FORM itself is used."
2294 (and (or (not (cl-compiling-file))
2295 (< cl-optimize-speed 3) (= cl-optimize-safety 3))
2296 (let ((sargs (and show-args (delq nil (mapcar
2297 (function
2298 (lambda (x)
2299 (and (not (cl-const-expr-p x))
2300 x))) (cdr form))))))
2301 (list 'progn
2302 (list 'or form
2303 (if string
2304 (list* 'error string (append sargs args))
2305 (list 'signal '(quote cl-assertion-failed)
2306 (list* 'list (list 'quote form) sargs))))
2307 nil))))
2308
2309(defmacro ignore-errors (&rest body)
2310 "Execute FORMS; if an error occurs, return nil.
2311Otherwise, return result of last FORM."
313b6c69 2312 `(condition-case nil (progn ,@body) (error nil)))
fcd73769
RS
2313
2314
2315;;; Some predicates for analyzing Lisp forms. These are used by various
2316;;; macro expanders to optimize the results in certain common cases.
2317
2318(defconst cl-simple-funcs '(car cdr nth aref elt if and or + - 1+ 1- min max
2319 car-safe cdr-safe progn prog1 prog2))
2320(defconst cl-safe-funcs '(* / % length memq list vector vectorp
2321 < > <= >= = error))
2322
2323;;; Check if no side effects, and executes quickly.
2324(defun cl-simple-expr-p (x &optional size)
2325 (or size (setq size 10))
2326 (if (and (consp x) (not (memq (car x) '(quote function function*))))
2327 (and (symbolp (car x))
2328 (or (memq (car x) cl-simple-funcs)
2329 (get (car x) 'side-effect-free))
2330 (progn
2331 (setq size (1- size))
2332 (while (and (setq x (cdr x))
2333 (setq size (cl-simple-expr-p (car x) size))))
2334 (and (null x) (>= size 0) size)))
2335 (and (> size 0) (1- size))))
2336
2337(defun cl-simple-exprs-p (xs)
2338 (while (and xs (cl-simple-expr-p (car xs)))
2339 (setq xs (cdr xs)))
2340 (not xs))
2341
2342;;; Check if no side effects.
2343(defun cl-safe-expr-p (x)
2344 (or (not (and (consp x) (not (memq (car x) '(quote function function*)))))
2345 (and (symbolp (car x))
2346 (or (memq (car x) cl-simple-funcs)
2347 (memq (car x) cl-safe-funcs)
2348 (get (car x) 'side-effect-free))
2349 (progn
2350 (while (and (setq x (cdr x)) (cl-safe-expr-p (car x))))
2351 (null x)))))
2352
2353;;; Check if constant (i.e., no side effects or dependencies).
2354(defun cl-const-expr-p (x)
2355 (cond ((consp x)
2356 (or (eq (car x) 'quote)
2357 (and (memq (car x) '(function function*))
2358 (or (symbolp (nth 1 x))
2359 (and (eq (car-safe (nth 1 x)) 'lambda) 'func)))))
2360 ((symbolp x) (and (memq x '(nil t)) t))
2361 (t t)))
2362
2363(defun cl-const-exprs-p (xs)
2364 (while (and xs (cl-const-expr-p (car xs)))
2365 (setq xs (cdr xs)))
2366 (not xs))
2367
2368(defun cl-const-expr-val (x)
2369 (and (eq (cl-const-expr-p x) t) (if (consp x) (nth 1 x) x)))
2370
2371(defun cl-expr-access-order (x v)
2372 (if (cl-const-expr-p x) v
2373 (if (consp x)
2374 (progn
2375 (while (setq x (cdr x)) (setq v (cl-expr-access-order (car x) v)))
2376 v)
2377 (if (eq x (car v)) (cdr v) '(t)))))
2378
f0529b5b 2379;;; Count number of times X refers to Y. Return nil for 0 times.
fcd73769
RS
2380(defun cl-expr-contains (x y)
2381 (cond ((equal y x) 1)
2382 ((and (consp x) (not (memq (car-safe x) '(quote function function*))))
2383 (let ((sum 0))
2384 (while x
2385 (setq sum (+ sum (or (cl-expr-contains (cl-pop x) y) 0))))
2386 (and (> sum 0) sum)))
2387 (t nil)))
2388
2389(defun cl-expr-contains-any (x y)
2390 (while (and y (not (cl-expr-contains x (car y)))) (cl-pop y))
2391 y)
2392
2393;;; Check whether X may depend on any of the symbols in Y.
2394(defun cl-expr-depends-p (x y)
2395 (and (not (cl-const-expr-p x))
2396 (or (not (cl-safe-expr-p x)) (cl-expr-contains-any x y))))
2397
2398
2399;;; Compiler macros.
2400
2401(defmacro define-compiler-macro (func args &rest body)
64a4c526 2402 "Define a compiler-only macro.
fcd73769
RS
2403This is like `defmacro', but macro expansion occurs only if the call to
2404FUNC is compiled (i.e., not interpreted). Compiler macros should be used
2405for optimizing the way calls to FUNC are compiled; the form returned by
2406BODY should do the same thing as a call to the normal function called
2407FUNC, though possibly more efficiently. Note that, like regular macros,
2408compiler macros are expanded repeatedly until no further expansions are
2409possible. Unlike regular macros, BODY can decide to \"punt\" and leave the
2410original function call alone by declaring an initial `&whole foo' parameter
2411and then returning foo."
16c9c10f 2412 (let ((p args) (res nil))
fcd73769 2413 (while (consp p) (cl-push (cl-pop p) res))
16c9c10f 2414 (setq args (nconc (nreverse res) (and p (list '&rest p)))))
fcd73769
RS
2415 (list 'eval-when '(compile load eval)
2416 (cl-transform-function-property
2417 func 'cl-compiler-macro
2418 (cons (if (memq '&whole args) (delq '&whole args)
2419 (cons '--cl-whole-arg-- args)) body))
2420 (list 'or (list 'get (list 'quote func) '(quote byte-compile))
2421 (list 'put (list 'quote func) '(quote byte-compile)
2422 '(quote cl-byte-compile-compiler-macro)))))
2423
2424(defun compiler-macroexpand (form)
2425 (while
2426 (let ((func (car-safe form)) (handler nil))
2427 (while (and (symbolp func)
2428 (not (setq handler (get func 'cl-compiler-macro)))
2429 (fboundp func)
2430 (or (not (eq (car-safe (symbol-function func)) 'autoload))
2431 (load (nth 1 (symbol-function func)))))
2432 (setq func (symbol-function func)))
2433 (and handler
2434 (not (eq form (setq form (apply handler form (cdr form))))))))
2435 form)
2436
2437(defun cl-byte-compile-compiler-macro (form)
2438 (if (eq form (setq form (compiler-macroexpand form)))
2439 (byte-compile-normal-call form)
2440 (byte-compile-form form)))
2441
2442(defmacro defsubst* (name args &rest body)
2443 "(defsubst* NAME ARGLIST [DOCSTRING] BODY...): define NAME as a function.
2444Like `defun', except the function is automatically declared `inline',
2445ARGLIST allows full Common Lisp conventions, and BODY is implicitly
2446surrounded by (block NAME ...)."
2447 (let* ((argns (cl-arglist-args args)) (p argns)
2448 (pbody (cons 'progn body))
2449 (unsafe (not (cl-safe-expr-p pbody))))
2450 (while (and p (eq (cl-expr-contains args (car p)) 1)) (cl-pop p))
2451 (list 'progn
2452 (if p nil ; give up if defaults refer to earlier args
2453 (list 'define-compiler-macro name
2454 (list* '&whole 'cl-whole '&cl-quote args)
2455 (list* 'cl-defsubst-expand (list 'quote argns)
2456 (list 'quote (list* 'block name body))
2457 (not (or unsafe (cl-expr-access-order pbody argns)))
2458 (and (memq '&key args) 'cl-whole) unsafe argns)))
2459 (list* 'defun* name args body))))
2460
2461(defun cl-defsubst-expand (argns body simple whole unsafe &rest argvs)
2462 (if (and whole (not (cl-safe-expr-p (cons 'progn argvs)))) whole
2463 (if (cl-simple-exprs-p argvs) (setq simple t))
2464 (let ((lets (delq nil
2465 (mapcar* (function
2466 (lambda (argn argv)
2467 (if (or simple (cl-const-expr-p argv))
2468 (progn (setq body (subst argv argn body))
2469 (and unsafe (list argn argv)))
2470 (list argn argv))))
2471 argns argvs))))
2472 (if lets (list 'let lets body) body))))
2473
2474
2475;;; Compile-time optimizations for some functions defined in this package.
2476;;; Note that cl.el arranges to force cl-macs to be loaded at compile-time,
2477;;; mainly to make sure these macros will be present.
2478
2479(put 'eql 'byte-compile nil)
2480(define-compiler-macro eql (&whole form a b)
2481 (cond ((eq (cl-const-expr-p a) t)
2482 (let ((val (cl-const-expr-val a)))
2483 (if (and (numberp val) (not (integerp val)))
2484 (list 'equal a b)
2485 (list 'eq a b))))
2486 ((eq (cl-const-expr-p b) t)
2487 (let ((val (cl-const-expr-val b)))
2488 (if (and (numberp val) (not (integerp val)))
2489 (list 'equal a b)
2490 (list 'eq a b))))
2491 ((cl-simple-expr-p a 5)
2492 (list 'if (list 'numberp a)
2493 (list 'equal a b)
2494 (list 'eq a b)))
2495 ((and (cl-safe-expr-p a)
2496 (cl-simple-expr-p b 5))
2497 (list 'if (list 'numberp b)
2498 (list 'equal a b)
2499 (list 'eq a b)))
2500 (t form)))
2501
2502(define-compiler-macro member* (&whole form a list &rest keys)
64a4c526 2503 (let ((test (and (= (length keys) 2) (eq (car keys) :test)
fcd73769
RS
2504 (cl-const-expr-val (nth 1 keys)))))
2505 (cond ((eq test 'eq) (list 'memq a list))
2506 ((eq test 'equal) (list 'member a list))
2507 ((or (null keys) (eq test 'eql))
2508 (if (eq (cl-const-expr-p a) t)
2509 (list (if (floatp-safe (cl-const-expr-val a)) 'member 'memq)
2510 a list)
2511 (if (eq (cl-const-expr-p list) t)
2512 (let ((p (cl-const-expr-val list)) (mb nil) (mq nil))
2513 (if (not (cdr p))
2514 (and p (list 'eql a (list 'quote (car p))))
2515 (while p
2516 (if (floatp-safe (car p)) (setq mb t)
2517 (or (integerp (car p)) (symbolp (car p)) (setq mq t)))
2518 (setq p (cdr p)))
2519 (if (not mb) (list 'memq a list)
2520 (if (not mq) (list 'member a list) form))))
2521 form)))
2522 (t form))))
2523
2524(define-compiler-macro assoc* (&whole form a list &rest keys)
64a4c526 2525 (let ((test (and (= (length keys) 2) (eq (car keys) :test)
fcd73769
RS
2526 (cl-const-expr-val (nth 1 keys)))))
2527 (cond ((eq test 'eq) (list 'assq a list))
2528 ((eq test 'equal) (list 'assoc a list))
2529 ((and (eq (cl-const-expr-p a) t) (or (null keys) (eq test 'eql)))
2530 (if (floatp-safe (cl-const-expr-val a))
2531 (list 'assoc a list) (list 'assq a list)))
2532 (t form))))
2533
2534(define-compiler-macro adjoin (&whole form a list &rest keys)
2535 (if (and (cl-simple-expr-p a) (cl-simple-expr-p list)
64a4c526 2536 (not (memq :key keys)))
fcd73769
RS
2537 (list 'if (list* 'member* a list keys) list (list 'cons a list))
2538 form))
2539
2540(define-compiler-macro list* (arg &rest others)
2541 (let* ((args (reverse (cons arg others)))
2542 (form (car args)))
2543 (while (setq args (cdr args))
2544 (setq form (list 'cons (car args) form)))
2545 form))
2546
2547(define-compiler-macro get* (sym prop &optional def)
2548 (if def
2549 (list 'getf (list 'symbol-plist sym) prop def)
2550 (list 'get sym prop)))
2551
2552(define-compiler-macro typep (&whole form val type)
2553 (if (cl-const-expr-p type)
2554 (let ((res (cl-make-type-test val (cl-const-expr-val type))))
2555 (if (or (memq (cl-expr-contains res val) '(nil 1))
2556 (cl-simple-expr-p val)) res
2557 (let ((temp (gensym)))
2558 (list 'let (list (list temp val)) (subst temp val res)))))
2559 form))
2560
2561
2562(mapcar (function
2563 (lambda (y)
2564 (put (car y) 'side-effect-free t)
2565 (put (car y) 'byte-compile 'cl-byte-compile-compiler-macro)
2566 (put (car y) 'cl-compiler-macro
2567 (list 'lambda '(w x)
2568 (if (symbolp (cadr y))
2569 (list 'list (list 'quote (cadr y))
2570 (list 'list (list 'quote (caddr y)) 'x))
2571 (cons 'list (cdr y)))))))
2572 '((first 'car x) (second 'cadr x) (third 'caddr x) (fourth 'cadddr x)
2573 (fifth 'nth 4 x) (sixth 'nth 5 x) (seventh 'nth 6 x)
2574 (eighth 'nth 7 x) (ninth 'nth 8 x) (tenth 'nth 9 x)
2575 (rest 'cdr x) (endp 'null x) (plusp '> x 0) (minusp '< x 0)
fcd73769
RS
2576 (caaar car caar) (caadr car cadr) (cadar car cdar)
2577 (caddr car cddr) (cdaar cdr caar) (cdadr cdr cadr)
2578 (cddar cdr cdar) (cdddr cdr cddr) (caaaar car caaar)
2579 (caaadr car caadr) (caadar car cadar) (caaddr car caddr)
2580 (cadaar car cdaar) (cadadr car cdadr) (caddar car cddar)
2581 (cadddr car cdddr) (cdaaar cdr caaar) (cdaadr cdr caadr)
2582 (cdadar cdr cadar) (cdaddr cdr caddr) (cddaar cdr cdaar)
2583 (cddadr cdr cdadr) (cdddar cdr cddar) (cddddr cdr cdddr) ))
2584
2585;;; Things that are inline.
2586(proclaim '(inline floatp-safe acons map concatenate notany notevery
2587 cl-set-elt revappend nreconc gethash))
2588
2589;;; Things that are side-effect-free.
2590(mapcar (function (lambda (x) (put x 'side-effect-free t)))
76f639b0 2591 '(oddp evenp signum last butlast ldiff pairlis gcd lcm
fcd73769 2592 isqrt floor* ceiling* truncate* round* mod* rem* subseq
76f639b0 2593 list-length get* getf))
fcd73769
RS
2594
2595;;; Things that are side-effect-and-error-free.
2596(mapcar (function (lambda (x) (put x 'side-effect-free 'error-free)))
2597 '(eql floatp-safe list* subst acons equalp random-state-p
76f639b0 2598 copy-tree sublis))
fcd73769
RS
2599
2600
2601(run-hooks 'cl-macs-load-hook)
2602
2603;;; cl-macs.el ends here