aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2012-06-05 11:41:12 -0400
committerStefan Monnier2012-06-05 11:41:12 -0400
commit57a7d50707c79e22f52a71d9c7f6d4a4773456c3 (patch)
treeb33484512136db9ae47c40e4b219fc2708cf997d
parent51a5f9d8163744dab918e2b6fe3f452f5a4cddfd (diff)
downloademacs-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/ChangeLog18
-rw-r--r--lisp/emacs-lisp/byte-opt.el18
-rw-r--r--lisp/emacs-lisp/bytecomp.el14
-rw-r--r--lisp/emacs-lisp/cl-lib.el5
-rw-r--r--lisp/emacs-lisp/cl-macs.el29
-rw-r--r--lisp/emacs-lisp/cl.el6
-rw-r--r--lisp/emacs-lisp/macroexp.el48
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 @@
12012-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
12012-06-05 Martin Rudalics <rudalics@gmx.at> 152012-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