mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-24 06:20:43 -08:00
Add native compiler-macro support.
* lisp/emacs-lisp/macroexp.el (macroexpand-all-1): Support compiler-macros directly. Properly follow aliases and apply the compiler macros more thoroughly. * lisp/emacs-lisp/cl.el: Don't copy compiler-macro properties any more since macroexpand now properly follows aliases. * lisp/emacs-lisp/cl-macs.el (toplevel, cl-define-compiler-macro) (cl-compiler-macroexpand): Use new prop. * lisp/emacs-lisp/byte-opt.el (featurep): Optimize earlier. * lisp/emacs-lisp/cl-lib.el (custom-print-functions): Add compatibility alias.
This commit is contained in:
parent
51a5f9d816
commit
57a7d50707
7 changed files with 80 additions and 58 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue