diff options
| author | Stefan Monnier | 2012-06-05 11:41:12 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2012-06-05 11:41:12 -0400 |
| commit | 57a7d50707c79e22f52a71d9c7f6d4a4773456c3 (patch) | |
| tree | b33484512136db9ae47c40e4b219fc2708cf997d | |
| parent | 51a5f9d8163744dab918e2b6fe3f452f5a4cddfd (diff) | |
| download | emacs-57a7d50707c79e22f52a71d9c7f6d4a4773456c3.tar.gz emacs-57a7d50707c79e22f52a71d9c7f6d4a4773456c3.zip | |
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.
| -rw-r--r-- | lisp/ChangeLog | 18 | ||||
| -rw-r--r-- | lisp/emacs-lisp/byte-opt.el | 18 | ||||
| -rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 14 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl-lib.el | 5 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl-macs.el | 29 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl.el | 6 | ||||
| -rw-r--r-- | lisp/emacs-lisp/macroexp.el | 48 |
7 files changed, 80 insertions, 58 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 9577d902a2d..38c4c74dab7 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,17 @@ | |||
| 1 | 2012-06-05 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | Add native compiler-macro support. | ||
| 4 | * emacs-lisp/macroexp.el (macroexpand-all-1): | ||
| 5 | Support compiler-macros directly. Properly follow aliases and apply | ||
| 6 | the compiler macros more thoroughly. | ||
| 7 | * emacs-lisp/cl.el: Don't copy compiler-macro properties any more since | ||
| 8 | macroexpand now properly follows aliases. | ||
| 9 | * emacs-lisp/cl-macs.el (toplevel, cl-define-compiler-macro) | ||
| 10 | (cl-compiler-macroexpand): Use new prop. | ||
| 11 | * emacs-lisp/byte-opt.el (featurep): Optimize earlier. | ||
| 12 | |||
| 13 | * emacs-lisp/cl-lib.el (custom-print-functions): Add alias. | ||
| 14 | |||
| 1 | 2012-06-05 Martin Rudalics <rudalics@gmx.at> | 15 | 2012-06-05 Martin Rudalics <rudalics@gmx.at> |
| 2 | 16 | ||
| 3 | * window.el (get-lru-window, get-mru-window, get-largest-window): | 17 | * window.el (get-lru-window, get-mru-window, get-largest-window): |
| @@ -5,8 +19,8 @@ | |||
| 5 | (window--display-buffer-1, window--display-buffer-2): Replace by | 19 | (window--display-buffer-1, window--display-buffer-2): Replace by |
| 6 | new function window--display-buffer | 20 | new function window--display-buffer |
| 7 | (display-buffer-same-window, display-buffer-reuse-window) | 21 | (display-buffer-same-window, display-buffer-reuse-window) |
| 8 | (display-buffer-pop-up-frame, display-buffer-pop-up-window): Use | 22 | (display-buffer-pop-up-frame, display-buffer-pop-up-window): |
| 9 | window--display-buffer. | 23 | Use window--display-buffer. |
| 10 | (display-buffer-use-some-window): Remove temporary dedication | 24 | (display-buffer-use-some-window): Remove temporary dedication |
| 11 | hack by calling get-lru-window and get-largest-window with | 25 | hack by calling get-lru-window and get-largest-window with |
| 12 | NOT-SELECTED argument non-nil. Call window--display-buffer. | 26 | NOT-SELECTED argument non-nil. Call window--display-buffer. |
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 7cb93890cb5..117e837f47f 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el | |||
| @@ -1159,15 +1159,15 @@ | |||
| 1159 | ;; optimize string-as-unibyte, string-as-multibyte, string-make-unibyte, | 1159 | ;; optimize string-as-unibyte, string-as-multibyte, string-make-unibyte, |
| 1160 | ;; string-make-multibyte for constant args. | 1160 | ;; string-make-multibyte for constant args. |
| 1161 | 1161 | ||
| 1162 | (put 'featurep 'byte-optimizer 'byte-optimize-featurep) | 1162 | (put 'featurep 'compiler-macro |
| 1163 | (defun byte-optimize-featurep (form) | 1163 | (lambda (form &rest _ignore) |
| 1164 | ;; Emacs-21's byte-code doesn't run under XEmacs or SXEmacs anyway, so we | 1164 | ;; Emacs-21's byte-code doesn't run under XEmacs or SXEmacs anyway, so |
| 1165 | ;; can safely optimize away this test. | 1165 | ;; we can safely optimize away this test. |
| 1166 | (if (member (cdr-safe form) '(((quote xemacs)) ((quote sxemacs)))) | 1166 | (if (member (cdr-safe form) '(((quote xemacs)) ((quote sxemacs)))) |
| 1167 | nil | 1167 | nil |
| 1168 | (if (member (cdr-safe form) '(((quote emacs)))) | 1168 | (if (member (cdr-safe form) '(((quote emacs)))) |
| 1169 | t | 1169 | t |
| 1170 | form))) | 1170 | form)))) |
| 1171 | 1171 | ||
| 1172 | (put 'set 'byte-optimizer 'byte-optimize-set) | 1172 | (put 'set 'byte-optimizer 'byte-optimize-set) |
| 1173 | (defun byte-optimize-set (form) | 1173 | (defun byte-optimize-set (form) |
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index bf6237cb120..c5f5faec765 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el | |||
| @@ -2874,14 +2874,12 @@ That command is designed for interactive use only" fn)) | |||
| 2874 | (byte-compile-log-warning | 2874 | (byte-compile-log-warning |
| 2875 | (format "Forgot to expand macro %s" (car form)) nil :error)) | 2875 | (format "Forgot to expand macro %s" (car form)) nil :error)) |
| 2876 | (if (and handler | 2876 | (if (and handler |
| 2877 | ;; Make sure that function exists. This is important | 2877 | ;; Make sure that function exists. |
| 2878 | ;; for CL compiler macros since the symbol may be | 2878 | (and (functionp handler) |
| 2879 | ;; `cl-byte-compile-compiler-macro' but if CL isn't | 2879 | ;; Ignore obsolete byte-compile function used by former |
| 2880 | ;; loaded, this function doesn't exist. | 2880 | ;; CL code to handle compiler macros (we do it |
| 2881 | (and (not (eq handler | 2881 | ;; differently now). |
| 2882 | ;; Already handled by macroexpand-all. | 2882 | (not (eq handler 'cl-byte-compile-compiler-macro)))) |
| 2883 | 'cl-byte-compile-compiler-macro)) | ||
| 2884 | (functionp handler))) | ||
| 2885 | (funcall handler form) | 2883 | (funcall handler form) |
| 2886 | (byte-compile-normal-call form)) | 2884 | (byte-compile-normal-call form)) |
| 2887 | (if (byte-compile-warning-enabled-p 'cl-functions) | 2885 | (if (byte-compile-warning-enabled-p 'cl-functions) |
diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el index 0dd8c9e1569..d70a98c1bc6 100644 --- a/lisp/emacs-lisp/cl-lib.el +++ b/lisp/emacs-lisp/cl-lib.el | |||
| @@ -94,6 +94,11 @@ | |||
| 94 | (defvar cl-optimize-speed 1) | 94 | (defvar cl-optimize-speed 1) |
| 95 | (defvar cl-optimize-safety 1) | 95 | (defvar cl-optimize-safety 1) |
| 96 | 96 | ||
| 97 | ;;;###autoload | ||
| 98 | (define-obsolete-variable-alias | ||
| 99 | ;; This alias is needed for compatibility with .elc files that use defstruct | ||
| 100 | ;; and were compiled with Emacs<24.2. | ||
| 101 | 'custom-print-functions 'cl-custom-print-functions "24.2") | ||
| 97 | 102 | ||
| 98 | ;;;###autoload | 103 | ;;;###autoload |
| 99 | (defvar cl-custom-print-functions nil | 104 | (defvar cl-custom-print-functions nil |
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index e1488ea0db4..cf5282fd8d6 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el | |||
| @@ -2922,28 +2922,24 @@ and then returning foo." | |||
| 2922 | (setq args (nconc (nreverse res) (and p (list '&rest p))))) | 2922 | (setq args (nconc (nreverse res) (and p (list '&rest p))))) |
| 2923 | `(cl-eval-when (compile load eval) | 2923 | `(cl-eval-when (compile load eval) |
| 2924 | ,(cl-transform-function-property | 2924 | ,(cl-transform-function-property |
| 2925 | func 'cl-compiler-macro | 2925 | func 'compiler-macro |
| 2926 | (cons (if (memq '&whole args) (delq '&whole args) | 2926 | (cons (if (memq '&whole args) (delq '&whole args) |
| 2927 | (cons '_cl-whole-arg args)) body)) | 2927 | (cons '_cl-whole-arg args)) body)) |
| 2928 | (or (get ',func 'byte-compile) | 2928 | ;; This is so that describe-function can locate |
| 2929 | (progn | 2929 | ;; the macro definition. |
| 2930 | (put ',func 'byte-compile | 2930 | (let ((file ,(or buffer-file-name |
| 2931 | 'cl-byte-compile-compiler-macro) | 2931 | (and (boundp 'byte-compile-current-file) |
| 2932 | ;; This is so that describe-function can locate | 2932 | (stringp byte-compile-current-file) |
| 2933 | ;; the macro definition. | 2933 | byte-compile-current-file)))) |
| 2934 | (let ((file ,(or buffer-file-name | 2934 | (if file (put ',func 'compiler-macro-file |
| 2935 | (and (boundp 'byte-compile-current-file) | 2935 | (purecopy (file-name-nondirectory file))))))) |
| 2936 | (stringp byte-compile-current-file) | ||
| 2937 | byte-compile-current-file)))) | ||
| 2938 | (if file (put ',func 'compiler-macro-file | ||
| 2939 | (purecopy (file-name-nondirectory file))))))))) | ||
| 2940 | 2936 | ||
| 2941 | ;;;###autoload | 2937 | ;;;###autoload |
| 2942 | (defun cl-compiler-macroexpand (form) | 2938 | (defun cl-compiler-macroexpand (form) |
| 2943 | (while | 2939 | (while |
| 2944 | (let ((func (car-safe form)) (handler nil)) | 2940 | (let ((func (car-safe form)) (handler nil)) |
| 2945 | (while (and (symbolp func) | 2941 | (while (and (symbolp func) |
| 2946 | (not (setq handler (get func 'cl-compiler-macro))) | 2942 | (not (setq handler (get func 'compiler-macro))) |
| 2947 | (fboundp func) | 2943 | (fboundp func) |
| 2948 | (or (not (eq (car-safe (symbol-function func)) 'autoload)) | 2944 | (or (not (eq (car-safe (symbol-function func)) 'autoload)) |
| 2949 | (load (nth 1 (symbol-function func))))) | 2945 | (load (nth 1 (symbol-function func))))) |
| @@ -3106,9 +3102,8 @@ surrounded by (cl-block NAME ...). | |||
| 3106 | 3102 | ||
| 3107 | (mapc (lambda (y) | 3103 | (mapc (lambda (y) |
| 3108 | (put (car y) 'side-effect-free t) | 3104 | (put (car y) 'side-effect-free t) |
| 3109 | (put (car y) 'byte-compile 'cl-byte-compile-compiler-macro) | 3105 | (put (car y) 'compiler-macro |
| 3110 | (put (car y) 'cl-compiler-macro | 3106 | `(lambda (_w x) |
| 3111 | `(lambda (w x) | ||
| 3112 | ,(if (symbolp (cadr y)) | 3107 | ,(if (symbolp (cadr y)) |
| 3113 | `(list ',(cadr y) | 3108 | `(list ',(cadr y) |
| 3114 | (list ',(cl-caddr y) x)) | 3109 | (list ',(cl-caddr y) x)) |
diff --git a/lisp/emacs-lisp/cl.el b/lisp/emacs-lisp/cl.el index 3b83a713402..14eb15fa578 100644 --- a/lisp/emacs-lisp/cl.el +++ b/lisp/emacs-lisp/cl.el | |||
| @@ -321,13 +321,11 @@ | |||
| 321 | (intern (format "cl-%s" fun))))) | 321 | (intern (format "cl-%s" fun))))) |
| 322 | (defalias fun new) | 322 | (defalias fun new) |
| 323 | ;; If `cl-foo' is declare inline, then make `foo' inline as well, and | 323 | ;; If `cl-foo' is declare inline, then make `foo' inline as well, and |
| 324 | ;; similarly, if `cl-foo' has a compiler-macro, make it available for `foo' | 324 | ;; similarly. Same for edebug specifications, indent rules and |
| 325 | ;; as well. Same for edebug specifications, indent rules and | ||
| 326 | ;; doc-string position. | 325 | ;; doc-string position. |
| 327 | ;; FIXME: For most of them, we should instead follow aliases | 326 | ;; FIXME: For most of them, we should instead follow aliases |
| 328 | ;; where applicable. | 327 | ;; where applicable. |
| 329 | (dolist (prop '(byte-optimizer byte-compile cl-compiler-macro | 328 | (dolist (prop '(byte-optimizer doc-string-elt edebug-form-spec |
| 330 | doc-string-elt edebug-form-spec | ||
| 331 | lisp-indent-function)) | 329 | lisp-indent-function)) |
| 332 | (if (get new prop) | 330 | (if (get new prop) |
| 333 | (put fun prop (get new prop)))))) | 331 | (put fun prop (get new prop)))))) |
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'." | |||
| 177 | (cons (macroexpand-all-1 | 177 | (cons (macroexpand-all-1 |
| 178 | (list 'function f)) | 178 | (list 'function f)) |
| 179 | (macroexpand-all-forms args))))) | 179 | (macroexpand-all-forms args))))) |
| 180 | ;; Macro expand compiler macros. This cannot be delayed to | 180 | (`(,func . ,_) |
| 181 | ;; byte-optimize-form because the output of the compiler-macro can | 181 | ;; Macro expand compiler macros. This cannot be delayed to |
| 182 | ;; use macros. | 182 | ;; byte-optimize-form because the output of the compiler-macro can |
| 183 | ;; FIXME: Don't depend on CL. | 183 | ;; use macros. |
| 184 | (`(,(pred (lambda (fun) | 184 | (let ((handler nil)) |
| 185 | (and (symbolp fun) | 185 | (while (and (symbolp func) |
| 186 | (eq (get fun 'byte-compile) | 186 | (not (setq handler (get func 'compiler-macro))) |
| 187 | 'cl-byte-compile-compiler-macro) | 187 | (fboundp func) |
| 188 | (functionp 'cl-compiler-macroexpand)))) | 188 | (or (not (eq (car-safe (symbol-function func)) |
| 189 | . ,_) | 189 | 'autoload)) |
| 190 | (let ((newform (with-no-warnings (cl-compiler-macroexpand form)))) | 190 | (load (nth 1 (symbol-function func))))) |
| 191 | (if (eq form newform) | 191 | ;; Follow the sequence of aliases. |
| 192 | (setq func (symbol-function func))) | ||
| 193 | (if (null handler) | ||
| 194 | ;; No compiler macro. We just expand each argument (for | ||
| 195 | ;; setq/setq-default this works alright because the variable names | ||
| 196 | ;; are symbols). | ||
| 192 | (macroexpand-all-forms form 1) | 197 | (macroexpand-all-forms form 1) |
| 193 | (macroexpand-all-1 newform)))) | 198 | (let ((newform (apply handler form (cdr form)))) |
| 194 | (`(,_ . ,_) | 199 | (if (eq form newform) |
| 195 | ;; For every other list, we just expand each argument (for | 200 | ;; The compiler macro did not find anything to do. |
| 196 | ;; setq/setq-default this works alright because the variable names | 201 | (if (equal form (setq newform (macroexpand-all-forms form 1))) |
| 197 | ;; are symbols). | 202 | form |
| 198 | (macroexpand-all-forms form 1)) | 203 | ;; Maybe after processing the args, some new opportunities |
| 204 | ;; appeared, so let's try the compiler macro again. | ||
| 205 | (if (eq newform | ||
| 206 | (setq form (apply handler newform (cdr newform)))) | ||
| 207 | newform | ||
| 208 | (macroexpand-all-1 newform))) | ||
| 209 | (macroexpand-all-1 newform)))))) | ||
| 210 | |||
| 199 | (t form)))) | 211 | (t form)))) |
| 200 | 212 | ||
| 201 | ;;;###autoload | 213 | ;;;###autoload |