root/trunk/lisp/emacs-lisp/cl-macs.el

Revision 4220, 98.9 kB (checked in by miyoshi, 9 months ago)

Sync up with Emacs22.2.

  • Property svn:eol-style set to LF
Line 
1 ;;; cl-macs.el --- Common Lisp macros -*-byte-compile-dynamic: t;-*-
2
3 ;; Copyright (C) 1993, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;;   Free Software Foundation, Inc.
5
6 ;; Author: Dave Gillespie <daveg@synaptics.com>
7 ;; Version: 2.02
8 ;; Keywords: extensions
9
10 ;; This file is part of GNU Emacs.
11
12 ;; GNU Emacs is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; any later version.
16
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ;; GNU General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
26
27 ;;; Commentary:
28
29 ;; These are extensions to Emacs Lisp that provide a degree of
30 ;; Common Lisp compatibility, beyond what is already built-in
31 ;; in Emacs Lisp.
32 ;;
33 ;; This package was written by Dave Gillespie; it is a complete
34 ;; rewrite of Cesar Quiroz's original cl.el package of December 1986.
35 ;;
36 ;; Bug reports, comments, and suggestions are welcome!
37
38 ;; This file contains the portions of the Common Lisp extensions
39 ;; package which should be autoloaded, but need only be present
40 ;; if the compiler or interpreter is used---this file is not
41 ;; necessary for executing compiled code.
42
43 ;; See cl.el for Change Log.
44
45
46 ;;; Code:
47
48 (or (memq 'cl-19 features)
49     (error "Tried to load `cl-macs' before `cl'!"))
50
51
52 (defmacro cl-pop2 (place)
53   (list 'prog1 (list 'car (list 'cdr place))
54         (list 'setq place (list 'cdr (list 'cdr place)))))
55 (put 'cl-pop2 'edebug-form-spec 'edebug-sexps)
56
57 (defvar cl-optimize-safety)
58 (defvar cl-optimize-speed)
59
60
61 ;;; This kludge allows macros which use cl-transform-function-property
62 ;;; to be called at compile-time.
63
64 (require
65  (progn
66    (or (fboundp 'cl-transform-function-property)
67        (defalias 'cl-transform-function-property
68          (function (lambda (n p f)
69                      (list 'put (list 'quote n) (list 'quote p)
70                            (list 'function (cons 'lambda f)))))))
71    (car (or features (setq features (list 'cl-kludge))))))
72
73
74 ;;; Initialization.
75
76 (defvar cl-old-bc-file-form nil)
77
78 (defun cl-compile-time-init ()
79   (run-hooks 'cl-hack-bytecomp-hook))
80
81
82 ;;; Some predicates for analyzing Lisp forms.  These are used by various
83 ;;; macro expanders to optimize the results in certain common cases.
84
85 (defconst cl-simple-funcs '(car cdr nth aref elt if and or + - 1+ 1- min max
86                             car-safe cdr-safe progn prog1 prog2))
87 (defconst cl-safe-funcs '(* / % length memq list vector vectorp
88                           < > <= >= = error))
89
90 ;;; Check if no side effects, and executes quickly.
91 (defun cl-simple-expr-p (x &optional size)
92   (or size (setq size 10))
93   (if (and (consp x) (not (memq (car x) '(quote function function*))))
94       (and (symbolp (car x))
95            (or (memq (car x) cl-simple-funcs)
96                (get (car x) 'side-effect-free))
97            (progn
98              (setq size (1- size))
99              (while (and (setq x (cdr x))
100                          (setq size (cl-simple-expr-p (car x) size))))
101              (and (null x) (>= size 0) size)))
102     (and (> size 0) (1- size))))
103
104 (defun cl-simple-exprs-p (xs)
105   (while (and xs (cl-simple-expr-p (car xs)))
106     (setq xs (cdr xs)))
107   (not xs))
108
109 ;;; Check if no side effects.
110 (defun cl-safe-expr-p (x)
111   (or (not (and (consp x) (not (memq (car x) '(quote function function*)))))
112       (and (symbolp (car x))
113            (or (memq (car x) cl-simple-funcs)
114                (memq (car x) cl-safe-funcs)
115                (get (car x) 'side-effect-free))
116            (progn
117              (while (and (setq x (cdr x)) (cl-safe-expr-p (car x))))
118              (null x)))))
119
120 ;;; Check if constant (i.e., no side effects or dependencies).
121 (defun cl-const-expr-p (x)
122   (cond ((consp x)
123          (or (eq (car x) 'quote)
124              (and (memq (car x) '(function function*))
125                   (or (symbolp (nth 1 x))
126                       (and (eq (car-safe (nth 1 x)) 'lambda) 'func)))))
127         ((symbolp x) (and (memq x '(nil t)) t))
128         (t t)))
129
130 (defun cl-const-exprs-p (xs)
131   (while (and xs (cl-const-expr-p (car xs)))
132     (setq xs (cdr xs)))
133   (not xs))
134
135 (defun cl-const-expr-val (x)
136   (and (eq (cl-const-expr-p x) t) (if (consp x) (nth 1 x) x)))
137
138 (defun cl-expr-access-order (x v)
139   (if (cl-const-expr-p x) v
140     (if (consp x)
141         (progn
142           (while (setq x (cdr x)) (setq v (cl-expr-access-order (car x) v)))
143           v)
144       (if (eq x (car v)) (cdr v) '(t)))))
145
146 ;;; Count number of times X refers to Y.  Return nil for 0 times.
147 (defun cl-expr-contains (x y)
148   (cond ((equal y x) 1)
149         ((and (consp x) (not (memq (car-safe x) '(quote function function*))))
150          (let ((sum 0))
151            (while x
152              (setq sum (+ sum (or (cl-expr-contains (pop x) y) 0))))
153            (and (> sum 0) sum)))
154         (t nil)))
155
156 (defun cl-expr-contains-any (x y)
157   (while (and y (not (cl-expr-contains x (car y)))) (pop y))
158   y)
159
160 ;;; Check whether X may depend on any of the symbols in Y.
161 (defun cl-expr-depends-p (x y)
162   (and (not (cl-const-expr-p x))
163        (or (not (cl-safe-expr-p x)) (cl-expr-contains-any x y))))
164
165 ;;; Symbols.
166
167 (defvar *gensym-counter*)
168 (defun gensym (&optional prefix)
169   "Generate a new uninterned symbol.
170 The name is made by appending a number to PREFIX, default \"G\"."
171   (let ((pfix (if (stringp prefix) prefix "G"))
172         (num (if (integerp prefix) prefix
173                (prog1 *gensym-counter*
174                  (setq *gensym-counter* (1+ *gensym-counter*))))))
175     (make-symbol (format "%s%d" pfix num))))
176
177 (defun gentemp (&optional prefix)
178   "Generate a new interned symbol with a unique name.
179 The name is made by appending a number to PREFIX, default \"G\"."
180   (let ((pfix (if (stringp prefix) prefix "G"))
181         name)
182     (while (intern-soft (setq name (format "%s%d" pfix *gensym-counter*)))
183       (setq *gensym-counter* (1+ *gensym-counter*)))
184     (intern name)))
185
186
187 ;;; Program structure.
188
189 (defmacro defun* (name args &rest body)
190   "Define NAME as a function.
191 Like normal `defun', except ARGLIST allows full Common Lisp conventions,
192 and BODY is implicitly surrounded by (block NAME ...).
193
194 \(fn NAME ARGLIST [DOCSTRING] BODY...)"
195   (let* ((res (cl-transform-lambda (cons args body) name))
196          (form (list* 'defun name (cdr res))))
197     (if (car res) (list 'progn (car res) form) form)))
198
199 (defmacro defmacro* (name args &rest body)
200   "Define NAME as a macro.
201 Like normal `defmacro', except ARGLIST allows full Common Lisp conventions,
202 and BODY is implicitly surrounded by (block NAME ...).
203
204 \(fn NAME ARGLIST [DOCSTRING] BODY...)"
205   (let* ((res (cl-transform-lambda (cons args body) name))
206          (form (list* 'defmacro name (cdr res))))
207     (if (car res) (list 'progn (car res) form) form)))
208
209 (defmacro function* (func)
210   "Introduce a function.
211 Like normal `function', except that if argument is a lambda form,
212 its argument list allows full Common Lisp conventions."
213   (if (eq (car-safe func) 'lambda)
214       (let* ((res (cl-transform-lambda (cdr func) 'cl-none))
215              (form (list 'function (cons 'lambda (cdr res)))))
216         (if (car res) (list 'progn (car res) form) form))
217     (list 'function func)))
218
219 (defun cl-transform-function-property (func prop form)
220   (let ((res (cl-transform-lambda form func)))
221     (append '(progn) (cdr (cdr (car res)))
222             (list (list 'put (list 'quote func) (list 'quote prop)
223                         (list 'function (cons 'lambda (cdr res))))))))
224
225 (defconst lambda-list-keywords
226   '(&optional &rest &key &allow-other-keys &aux &whole &body &environment))
227
228 (defvar cl-macro-environment nil)
229 (defvar bind-block) (defvar bind-defs) (defvar bind-enquote)
230 (defvar bind-inits) (defvar bind-lets) (defvar bind-forms)
231
232 (defun cl-transform-lambda (form bind-block)
233   (let* ((args (car form)) (body (cdr form)) (orig-args args)
234          (bind-defs nil) (bind-enquote nil)
235          (bind-inits nil) (bind-lets nil) (bind-forms nil)
236          (header nil) (simple-args nil))
237     (while (or (stringp (car body))
238                (memq (car-safe (car body)) '(interactive declare)))
239       (push (pop body) header))
240     (setq args (if (listp args) (copy-list args) (list '&rest args)))
241     (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p)))))
242     (if (setq bind-defs (cadr (memq '&cl-defs args)))
243         (setq args (delq '&cl-defs (delq bind-defs args))
244               bind-defs (cadr bind-defs)))
245     (if (setq bind-enquote (memq '&cl-quote args))
246         (setq args (delq '&cl-quote args)))
247     (if (memq '&whole args) (error "&whole not currently implemented"))
248     (let* ((p (memq '&environment args)) (v (cadr p)))
249       (if p (setq args (nconc (delq (car p) (delq v args))
250                               (list '&aux (list v 'cl-macro-environment))))))
251     (while (and args (symbolp (car args))
252                 (not (memq (car args) '(nil &rest &body &key &aux)))
253                 (not (and (eq (car args) '&optional)
254                           (or bind-defs (consp (cadr args))))))
255       (push (pop args) simple-args))
256     (or (eq bind-block 'cl-none)
257         (setq body (list (list* 'block bind-block body))))
258     (if (null args)
259         (list* nil (nreverse simple-args) (nconc (nreverse header) body))
260       (if (memq '&optional simple-args) (push '&optional args))
261       (cl-do-arglist args nil (- (length simple-args)
262                                  (if (memq '&optional simple-args) 1 0)))
263       (setq bind-lets (nreverse bind-lets))
264       (list* (and bind-inits (list* 'eval-when '(compile load eval)
265                                     (nreverse bind-inits)))
266              (nconc (nreverse simple-args)
267                     (list '&rest (car (pop bind-lets))))
268              (nconc (let ((hdr (nreverse header)))
269                       ;; Macro expansion can take place in the middle of
270                       ;; apparently harmless computation, so it should not
271                       ;; touch the match-data.
272                       (save-match-data
273                         (require 'help-fns)
274                         (cons (help-add-fundoc-usage
275                                (if (stringp (car hdr)) (pop hdr))
276                                ;; orig-args can contain &cl-defs (an internal
277                                ;; CL thingy I don't understand), so remove it.
278                                (let ((x (memq '&cl-defs orig-args)))
279                                  (if (null x) orig-args
280                                    (delq (car x) (remq (cadr x) orig-args)))))
281                               hdr)))
282                     (list (nconc (list 'let* bind-lets)
283                                  (nreverse bind-forms) body)))))))
284
285 (defun cl-do-arglist (args expr &optional num)   ; uses bind-*
286   (if (nlistp args)
287       (if (or (memq args lambda-list-keywords) (not (symbolp args)))
288           (error "Invalid argument name: %s" args)
289         (push (list args expr) bind-lets))
290     (setq args (copy-list args))
291     (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p)))))
292     (let ((p (memq '&body args))) (if p (setcar p '&rest)))
293     (if (memq '&environment args) (error "&environment used incorrectly"))
294     (let ((save-args args)
295           (restarg (memq '&rest args))
296           (safety (if (cl-compiling-file) cl-optimize-safety 3))
297           (keys nil)
298           (laterarg nil) (exactarg nil) minarg)
299       (or num (setq num 0))
300       (if (listp (cadr restarg))
301           (setq restarg (make-symbol "--cl-rest--"))
302         (setq restarg (cadr restarg)))
303       (push (list restarg expr) bind-lets)
304       (if (eq (car args) '&whole)
305           (push (list (cl-pop2 args) restarg) bind-lets))
306       (let ((p args))
307         (setq minarg restarg)
308         (while (and p (not (memq (car p) lambda-list-keywords)))
309           (or (eq p args) (setq minarg (list 'cdr minarg)))
310           (setq p (cdr p)))
311         (if (memq (car p) '(nil &aux))
312             (setq minarg (list '= (list 'length restarg)
313                                (length (ldiff args p)))
314                   exactarg (not (eq args p)))))
315       (while (and args (not (memq (car args) lambda-list-keywords)))
316         (let ((poparg (list (if (or (cdr args) (not exactarg)) 'pop 'car)
317                             restarg)))
318           (cl-do-arglist
319            (pop args)
320            (if (or laterarg (= safety 0)) poparg
321              (list 'if minarg poparg
322                    (list 'signal '(quote wrong-number-of-arguments)
323                          (list 'list (and (not (eq bind-block 'cl-none))
324                                           (list 'quote bind-block))
325                                (list 'length restarg)))))))
326         (setq num (1+ num) laterarg t))
327       (while (and (eq (car args) '&optional) (pop args))
328         (while (and args (not (memq (car args) lambda-list-keywords)))
329           (let ((arg (pop args)))
330             (or (consp arg) (setq arg (list arg)))
331             (if (cddr arg) (cl-do-arglist (nth 2 arg) (list 'and restarg t)))
332             (let ((def (if (cdr arg) (nth 1 arg)
333                          (or (car bind-defs)
334                              (nth 1 (assq (car arg) bind-defs)))))
335                   (poparg (list 'pop restarg)))
336               (and def bind-enquote (setq def (list 'quote def)))
337               (cl-do-arglist (car arg)
338                              (if def (list 'if restarg poparg def) poparg))
339               (setq num (1+ num))))))
340       (if (eq (car args) '&rest)
341           (let ((arg (cl-pop2 args)))
342             (if (consp arg) (cl-do-arglist arg restarg)))
343         (or (eq (car args) '&key) (= safety 0) exactarg
344             (push (list 'if restarg
345                            (list 'signal '(quote wrong-number-of-arguments)
346                                  (list 'list
347                                        (and (not (eq bind-block 'cl-none))
348                                             (list 'quote bind-block))
349                                        (list '+ num (list 'length restarg)))))
350                      bind-forms)))
351       (while (and (eq (car args) '&key) (pop args))
352         (while (and args (not (memq (car args) lambda-list-keywords)))
353           (let ((arg (pop args)))
354             (or (consp arg) (setq arg (list arg)))
355             (let* ((karg (if (consp (car arg)) (caar arg)
356                            (intern (format ":%s" (car arg)))))
357                    (varg (if (consp (car arg)) (cadar arg) (car arg)))
358                    (def (if (cdr arg) (cadr arg)
359                           (or (car bind-defs) (cadr (assq varg bind-defs)))))
360                    (look (list 'memq (list 'quote karg) restarg)))
361               (and def bind-enquote (setq def (list 'quote def)))
362               (if (cddr arg)
363                   (let* ((temp (or (nth 2 arg) (make-symbol "--cl-var--")))
364                          (val (list 'car (list 'cdr temp))))
365                     (cl-do-arglist temp look)
366                     (cl-do-arglist varg
367                                    (list 'if temp
368                                          (list 'prog1 val (list 'setq temp t))
369                                          def)))
370                 (cl-do-arglist
371                  varg
372                  (list 'car
373                        (list 'cdr
374                              (if (null def)
375                                  look
376                                (list 'or look
377                                      (if (eq (cl-const-expr-p def) t)
378                                          (list
379                                           'quote
380                                           (list nil (cl-const-expr-val def)))
381                                        (list 'list nil def))))))))
382               (push karg keys)))))
383       (setq keys (nreverse keys))
384       (or (and (eq (car args) '&allow-other-keys) (pop args))
385           (null keys) (= safety 0)
386           (let* ((var (make-symbol "--cl-keys--"))
387                  (allow '(:allow-other-keys))
388                  (check (list
389                          'while var
390                          (list
391                           'cond
392                           (list (list 'memq (list 'car var)
393                                       (list 'quote (append keys allow)))
394                                 (list 'setq var (list 'cdr (list 'cdr var))))
395                           (list (list 'car
396                                       (list 'cdr
397                                             (list 'memq (cons 'quote allow)
398                                                   restarg)))
399                                 (list 'setq var nil))
400                           (list t
401                                 (list
402                                  'error
403                                  (format "Keyword argument %%s not one of %s"
404                                          keys)
405                                  (list 'car var)))))))
406             (push (list 'let (list (list var restarg)) check) bind-forms)))
407       (while (and (eq (car args) '&aux) (pop args))
408         (while (and args (not (memq (car args) lambda-list-keywords)))
409           (if (consp (car args))
410               (if (and bind-enquote (cadar args))
411                   (cl-do-arglist (caar args)
412                                  (list 'quote (cadr (pop args))))
413                 (cl-do-arglist (caar args) (cadr (pop args))))
414             (cl-do-arglist (pop args) nil))))
415       (if args (error "Malformed argument list %s" save-args)))))
416
417 (defun cl-arglist-args (args)
418   (if (nlistp args) (list args)
419     (let ((res nil) (kind nil) arg)
420       (while (consp args)
421         (setq arg (pop args))
422         (if (memq arg lambda-list-keywords) (setq kind arg)
423           (if (eq arg '&cl-defs) (pop args)
424             (and (consp arg) kind (setq arg (car arg)))
425             (and (consp arg) (cdr arg) (eq kind '&key) (setq arg (cadr arg)))
426             (setq res (nconc res (cl-arglist-args arg))))))
427       (nconc res (and args (list args))))))
428
429 (defmacro destructuring-bind (args expr &rest body)
430   (let* ((bind-lets nil) (bind-forms nil) (bind-inits nil)
431          (bind-defs nil) (bind-block 'cl-none))
432     (cl-do-arglist (or args '(&aux)) expr)
433     (append '(progn) bind-inits
434             (list (nconc (list 'let* (nreverse bind-lets))
435                          (nreverse bind-forms) body)))))
436
437
438 ;;; The `eval-when' form.
439
440 (defvar cl-not-toplevel nil)
441
442 (defmacro eval-when (when &rest body)
443   "Control when BODY is evaluated.
444 If `compile' is in WHEN, BODY is evaluated when compiled at top-level.
445 If `load' is in WHEN, BODY is evaluated when loaded after top-level compile.
446 If `eval' is in WHEN, BODY is evaluated when interpreted or at non-top-level.
447
448 \(fn (WHEN...) BODY...)"
449   (if (and (fboundp 'cl-compiling-file) (cl-compiling-file)
450            (not cl-not-toplevel) (not (boundp 'for-effect)))  ; horrible kludge
451       (let ((comp (or (memq 'compile when) (memq :compile-toplevel when)))
452             (cl-not-toplevel t))
453         (if (or (memq 'load when) (memq :load-toplevel when))
454             (if comp (cons 'progn (mapcar 'cl-compile-time-too body))
455               (list* 'if nil nil body))
456           (progn (if comp (eval (cons 'progn body))) nil)))
457     (and (or (memq 'eval when) (memq :execute when))
458          (cons 'progn body))))
459
460 (defun cl-compile-time-too (form)
461   (or (and (symbolp (car-safe form)) (get (car-safe form) 'byte-hunk-handler))
462       (setq form (macroexpand
463                   form (cons '(eval-when) byte-compile-macro-environment))))
464   (cond ((eq (car-safe form) 'progn)
465          (cons 'progn (mapcar 'cl-compile-time-too (cdr form))))
466         ((eq (car-safe form) 'eval-when)
467          (let ((when (nth 1 form)))
468            (if (or (memq 'eval when) (memq :execute when))
469                (list* 'eval-when (cons 'compile when) (cddr form))
470              form)))
471         (t (eval form) form)))
472
473 (defmacro load-time-value (form &optional read-only)
474   "Like `progn', but evaluates the body at load time.
475 The result of the body appears to the compiler as a quoted constant."
476   (if (cl-compiling-file)
477       (let* ((temp (gentemp "--cl-load-time--"))
478              (set (list 'set (list 'quote temp) form)))
479         (if (and (fboundp 'byte-compile-file-form-defmumble)
480                  (boundp 'this-kind) (boundp 'that-one))
481             (fset 'byte-compile-file-form
482                   (list 'lambda '(form)
483                         (list 'fset '(quote byte-compile-file-form)
484                               (list 'quote
485                                     (symbol-function 'byte-compile-file-form)))
486                         (list 'byte-compile-file-form (list 'quote set))
487                         '(byte-compile-file-form form)))
488           (print set (symbol-value 'outbuffer)))
489         (list 'symbol-value (list 'quote temp)))
490     (list 'quote (eval form))))
491
492
493 ;;; Conditional control structures.
494
495 (defmacro case (expr &rest clauses)
496   "Eval EXPR and choose among clauses on that value.
497 Each clause looks like (KEYLIST BODY...).  EXPR is evaluated and compared
498 against each key in each KEYLIST; the corresponding BODY is evaluated.
499 If no clause succeeds, case returns nil.  A single atom may be used in
500 place of a KEYLIST of one atom.  A KEYLIST of t or `otherwise' is
501 allowed only in the final clause, and matches if no other keys match.
502 Key values are compared by `eql'.
503 \n(fn EXPR (KEYLIST BODY...)...)"
504   (let* ((temp (if (cl-simple-expr-p expr 3) expr (make-symbol "--cl-var--")))
505          (head-list nil)
506          (body (cons
507                 'cond
508                 (mapcar
509                  (function
510                   (lambda (c)
511                     (cons (cond ((memq (car c) '(t otherwise)) t)
512                                 ((eq (car c) 'ecase-error-flag)
513                                  (list 'error "ecase failed: %s, %s"
514                                        temp (list 'quote (reverse head-list))))
515                                 ((listp (car c))
516                                  (setq head-list (append (car c) head-list))
517                                  (list 'member* temp (list 'quote (car c))))
518                                 (t
519                                  (if (memq (car c) head-list)
520                                      (error "Duplicate key in case: %s"
521                                             (car c)))
522                                  (push (car c) head-list)
523                                  (list 'eql temp (list 'quote (car c)))))
524                           (or (cdr c) '(nil)))))
525                  clauses))))
526     (if (eq temp expr) body
527       (list 'let (list (list temp expr)) body))))
528
529 (defmacro ecase (expr &rest clauses)
530   "Like `case', but error if no case fits.
531 `otherwise'-clauses are not allowed.
532 \n(fn EXPR (KEYLIST BODY...)...)"
533   (list* 'case expr (append clauses '((ecase-error-flag)))))
534
535 (defmacro typecase (expr &rest clauses)
536   "Evals EXPR, chooses among clauses on that value.
537 Each clause looks like (TYPE BODY...).  EXPR is evaluated and, if it
538 satisfies TYPE, the corresponding BODY is evaluated.  If no clause succeeds,
539 typecase returns nil.  A TYPE of t or `otherwise' is allowed only in the
540 final clause, and matches if no other keys match.
541 \n(fn EXPR (TYPE BODY...)...)"
542   (let* ((temp (if (cl-simple-expr-p expr 3) expr (make-symbol "--cl-var--")))
543          (type-list nil)
544          (body (cons
545                 'cond
546                 (mapcar
547                  (function
548                   (lambda (c)
549                     (cons (cond ((eq (car c) 'otherwise) t)
550                                 ((eq (car c) 'ecase-error-flag)
551                                  (list 'error "etypecase failed: %s, %s"
552                                        temp (list 'quote (reverse type-list))))
553                                 (t
554                                  (push (car c) type-list)
555                                  (cl-make-type-test temp (car c))))
556                           (or (cdr c) '(nil)))))
557                  clauses))))
558     (if (eq temp expr) body
559       (list 'let (list (list temp expr)) body))))
560
561 (defmacro etypecase (expr &rest clauses)
562   "Like `typecase', but error if no case fits.
563 `otherwise'-clauses are not allowed.
564 \n(fn EXPR (TYPE BODY...)...)"
565   (list* 'typecase expr (append clauses '((ecase-error-flag)))))
566
567
568 ;;; Blocks and exits.
569
570 (defmacro block (name &rest body)
571   "Define a lexically-scoped block named NAME.
572 NAME may be any symbol.  Code inside the BODY forms can call `return-from'
573 to jump prematurely out of the block.  This differs from `catch' and `throw'
574 in two respects:  First, the NAME is an unevaluated symbol rather than a
575 quoted symbol or other form; and second, NAME is lexically rather than
576 dynamically scoped:  Only references to it within BODY will work.  These
577 references may appear inside macro expansions, but not inside functions
578 called from BODY."
579   (if (cl-safe-expr-p (cons 'progn body)) (cons 'progn body)
580     (list 'cl-block-wrapper
581           (list* 'catch (list 'quote (intern (format "--cl-block-%s--" name)))
582                  body))))
583
584 (defvar cl-active-block-names nil)
585
586 (put 'cl-block-wrapper 'byte-compile 'cl-byte-compile-block)
587 (defun cl-byte-compile-block (cl-form)
588   (if (fboundp 'byte-compile-form-do-effect)  ; Check for optimizing compiler
589       (progn
590         (let* ((cl-entry (cons (nth 1 (nth 1 (nth 1 cl-form))) nil))
591                (cl-active-block-names (cons cl-entry cl-active-block-names))
592                (cl-body (byte-compile-top-level
593                          (cons 'progn (cddr (nth 1 cl-form))))))
594           (if (cdr cl-entry)
595               (byte-compile-form (list 'catch (nth 1 (nth 1 cl-form)) cl-body))
596             (byte-compile-form cl-body))))
597     (byte-compile-form (nth 1 cl-form))))
598
599 (put 'cl-block-throw 'byte-compile 'cl-byte-compile-throw)
600 (defun cl-byte-compile-throw (cl-form)
601   (let ((cl-found (assq (nth 1 (nth 1 cl-form)) cl-active-block-names)))
602     (if cl-found (setcdr cl-found t)))
603   (byte-compile-normal-call (cons 'throw (cdr cl-form))))
604
605 (defmacro return (&optional result)
606   "Return from the block named nil.
607 This is equivalent to `(return-from nil RESULT)'."
608   (list 'return-from nil result))
609
610 (defmacro return-from (name &optional result)
611   "Return from the block named NAME.
612 This jump out to the innermost enclosing `(block NAME ...)' form,
613 returning RESULT from that form (or nil if RESULT is omitted).
614 This is compatible with Common Lisp, but note that `defun' and
615 `defmacro' do not create implicit blocks as they do in Common Lisp."
616   (let ((name2 (intern (format "--cl-block-%s--" name))))
617     (list 'cl-block-throw (list 'quote name2) result)))
618
619
620 ;;; The "loop" macro.
621
622 (defvar args) (defvar loop-accum-var) (defvar loop-accum-vars)
623 (defvar loop-bindings) (defvar loop-body) (defvar loop-destr-temps)
624 (defvar loop-finally) (defvar loop-finish-flag) (defvar loop-first-flag)
625 (defvar loop-initially) (defvar loop-map-form) (defvar loop-name)
626 (defvar loop-result) (defvar loop-result-explicit)
627 (defvar loop-result-var) (defvar loop-steps) (defvar loop-symbol-macs)
628
629 (defmacro loop (&rest args)
630   "The Common Lisp `loop' macro.
631 Valid clauses are:
632   for VAR from/upfrom/downfrom NUM to/upto/downto/above/below NUM by NUM,
633   for VAR in LIST by FUNC, for VAR on LIST by FUNC, for VAR = INIT then EXPR,
634   for VAR across ARRAY, repeat NUM, with VAR = INIT, while COND, until COND,
635   always COND, never COND, thereis COND, collect EXPR into VAR,
636   append EXPR into VAR, nconc EXPR into VAR, sum EXPR into VAR,
637   count EXPR into VAR, maximize EXPR into VAR, minimize EXPR into VAR,
638   if COND CLAUSE [and CLAUSE]... else CLAUSE [and CLAUSE...],
639   unless COND CLAUSE [and CLAUSE]... else CLAUSE [and CLAUSE...],
640   do EXPRS..., initially EXPRS..., finally EXPRS..., return EXPR,
641   finally return EXPR, named NAME.
642
643 \(fn CLAUSE...)"
644   (if (not (memq t (mapcar 'symbolp (delq nil (delq t (copy-list args))))))
645       (list 'block nil (list* 'while t args))
646     (let ((loop-name nil)       (loop-bindings nil)
647           (loop-body nil)       (loop-steps nil)
648           (loop-result nil)     (loop-result-explicit nil)
649           (loop-result-var nil) (loop-finish-flag nil)
650           (loop-accum-var nil)  (loop-accum-vars nil)
651           (loop-initially nil)  (loop-finally nil)
652           (loop-map-form nil)   (loop-first-flag nil)
653           (loop-destr-temps nil) (loop-symbol-macs nil))
654       (setq args (append args '(cl-end-loop)))
655       (while (not (eq (car args) 'cl-end-loop)) (cl-parse-loop-clause))
656       (if loop-finish-flag
657           (push `((,loop-finish-flag t)) loop-bindings))
658       (if loop-first-flag
659           (progn (push `((,loop-first-flag t)) loop-bindings)
660                  (push `(setq ,loop-first-flag nil) loop-steps)))
661       (let* ((epilogue (nconc (nreverse loop-finally)
662                               (list (or loop-result-explicit loop-result))))
663              (ands (cl-loop-build-ands (nreverse loop-body)))
664              (while-body (nconc (cadr ands) (nreverse loop-steps)))
665              (body (append
666                     (nreverse loop-initially)
667                     (list (if loop-map-form
668                               (list 'block '--cl-finish--
669                                     (subst
670                                      (if (eq (car ands) t) while-body
671                                        (cons `(or ,(car ands)
672                                                   (return-from --cl-finish--
673                                                     nil))
674                                              while-body))
675                                      '--cl-map loop-map-form))
676                             (list* 'while (car ands) while-body)))
677                     (if loop-finish-flag
678                         (if (equal epilogue '(nil)) (list loop-result-var)
679                           `((if ,loop-finish-flag
680                                 (progn ,@epilogue) ,loop-result-var)))
681                       epilogue))))
682         (if loop-result-var (push (list loop-result-var) loop-bindings))
683         (while loop-bindings
684           (if (cdar loop-bindings)
685               (setq body (list (cl-loop-let (pop loop-bindings) body t)))
686             (let ((lets nil))
687               (while (and loop-bindings
688                           (not (cdar loop-bindings)))
689                 (push (car (pop loop-bindings)) lets))
690               (setq body (list (cl-loop-let lets body nil))))))
691         (if loop-symbol-macs
692             (setq body (list (list* 'symbol-macrolet loop-symbol-macs body))))
693         (list* 'block loop-name body)))))
694
695 (defun cl-parse-loop-clause ()          ; uses args, loop-*
696   (let ((word (pop args))
697         (hash-types '(hash-key hash-keys hash-value hash-values))
698         (key-types '(key-code key-codes key-seq key-seqs
699                      key-binding key-bindings)))
700     (cond
701
702      ((null args)
703       (error "Malformed `loop' macro"))
704
705      ((eq word 'named)
706       (setq loop-name (pop args)))
707
708      ((eq word 'initially)
709       (if (memq (car args) '(do doing)) (pop args))
710       (or (consp (car args)) (error "Syntax error on `initially' clause"))
711       (while (consp (car args))
712         (push (pop args) loop-initially)))
713
714      ((eq word 'finally)
715       (if (eq (car args) 'return)
716           (setq loop-result-explicit (or (cl-pop2 args) '(quote nil)))
717         (if (memq (car args) '(do doing)) (pop args))
718         (or (consp (car args)) (error "Syntax error on `finally' clause"))
719         (if (and (eq (caar args) 'return) (null loop-name))
720             (setq loop-result-explicit (or (nth 1 (pop args)) '(quote nil)))
721           (while (consp (car args))
722             (push (pop args) loop-finally)))))
723
724      ((memq word '(for as))
725       (let ((loop-for-bindings nil) (loop-for-sets nil) (loop-for-steps nil)
726             (ands nil))
727         (while
728             ;; Use `gensym' rather than `make-symbol'.  It's important that
729             ;; (not (eq (symbol-name var1) (symbol-name var2))) because
730             ;; these vars get added to the cl-macro-environment.
731             (let ((var (or (pop args) (gensym "--cl-var--"))))
732               (setq word (pop args))
733               (if (eq word 'being) (setq word (pop args)))
734               (if (memq word '(the each)) (setq word (pop args)))
735               (if (memq word '(buffer buffers))
736                   (setq word 'in args (cons '(buffer-list) args)))
737               (cond
738
739                ((memq word '(from downfrom upfrom to downto upto
740                              above below by))
741                 (push word args)
742                 (if (memq (car args) '(downto above))
743                     (error "Must specify `from' value for downward loop"))
744                 (let* ((down (or (eq (car args) 'downfrom)
745                                  (memq (caddr args) '(downto above))))
746                        (excl (or (memq (car args) '(above below))
747                                  (memq (caddr args) '(above below))))
748                        (start (and (memq (car args) '(from upfrom downfrom))
749                                    (cl-pop2 args)))
750                        (end (and (memq (car args)
751                                        '(to upto downto above below))
752                                  (cl-pop2 args)))
753                        (step (and (eq (car args) 'by) (cl-pop2 args)))
754                        (end-var (and (not (cl-const-expr-p end))
755                                      (make-symbol "--cl-var--")))
756                        (step-var (and (not (cl-const-expr-p step))