summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/macroexp.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp/macroexp.el')
-rw-r--r--lisp/emacs-lisp/macroexp.el48
1 files changed, 30 insertions, 18 deletions
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index be51b5c3dd3..953b4b7eab5 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -177,25 +177,37 @@ Assumes the caller has bound `macroexpand-all-environment'."
(cons (macroexpand-all-1
(list 'function f))
(macroexpand-all-forms args)))))
- ;; Macro expand compiler macros. This cannot be delayed to
- ;; byte-optimize-form because the output of the compiler-macro can
- ;; use macros.
- ;; FIXME: Don't depend on CL.
- (`(,(pred (lambda (fun)
- (and (symbolp fun)
- (eq (get fun 'byte-compile)
- 'cl-byte-compile-compiler-macro)
- (functionp 'cl-compiler-macroexpand))))
- . ,_)
- (let ((newform (with-no-warnings (cl-compiler-macroexpand form))))
- (if (eq form newform)
+ (`(,func . ,_)
+ ;; Macro expand compiler macros. This cannot be delayed to
+ ;; byte-optimize-form because the output of the compiler-macro can
+ ;; use macros.
+ (let ((handler nil))
+ (while (and (symbolp func)
+ (not (setq handler (get func 'compiler-macro)))
+ (fboundp func)
+ (or (not (eq (car-safe (symbol-function func))
+ 'autoload))
+ (load (nth 1 (symbol-function func)))))
+ ;; Follow the sequence of aliases.
+ (setq func (symbol-function func)))
+ (if (null handler)
+ ;; No compiler macro. We just expand each argument (for
+ ;; setq/setq-default this works alright because the variable names
+ ;; are symbols).
(macroexpand-all-forms form 1)
- (macroexpand-all-1 newform))))
- (`(,_ . ,_)
- ;; For every other list, we just expand each argument (for
- ;; setq/setq-default this works alright because the variable names
- ;; are symbols).
- (macroexpand-all-forms form 1))
+ (let ((newform (apply handler form (cdr form))))
+ (if (eq form newform)
+ ;; The compiler macro did not find anything to do.
+ (if (equal form (setq newform (macroexpand-all-forms form 1)))
+ form
+ ;; Maybe after processing the args, some new opportunities
+ ;; appeared, so let's try the compiler macro again.
+ (if (eq newform
+ (setq form (apply handler newform (cdr newform))))
+ newform
+ (macroexpand-all-1 newform)))
+ (macroexpand-all-1 newform))))))
+
(t form))))
;;;###autoload