aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Colascione2014-04-22 00:04:34 -0700
committerDaniel Colascione2014-04-22 00:04:34 -0700
commit12b1389c9039dd374951673ca43b1ddf65df400d (patch)
treef4d36afc9d1ccdd72f3d801b350d79d25dd5e8bb
parentc98212f9e7cef496dded06eba4476033062c171f (diff)
downloademacs-12b1389c9039dd374951673ca43b1ddf65df400d.tar.gz
emacs-12b1389c9039dd374951673ca43b1ddf65df400d.zip
Correctly macroexpand top-level forms during eager macroexpand
* lisp/emacs-lisp/byte-run.el (eval-when-compile, eval-and-compile): Improve docstrings. * lisp/emacs-lisp/macroexp.el (internal-macroexpand-for-load): Add `full-p' parameter; when nil, call `macroexpand' instead of `macroexpand-all'. * src/lread.c (readevalloop_eager_expand_eval): New function that can recurse into toplevel forms. (readevalloop): Call it. * src/lisp.h: Declare Qprogn. * src/callint.c (Qprogn): No longer static. * test/automated/bytecomp-tests.el (test-byte-comp-compile-and-load): Add compile flag. (test-byte-comp-macro-expansion) (test-byte-comp-macro-expansion-eval-and-compile) (test-byte-comp-macro-expansion-eval-when-compile) (test-byte-comp-macro-expand-lexical-override): Use it. (test-eager-load-macro-expansion) (test-eager-load-macro-expansion-eval-and-compile) (test-eager-load-macro-expansion-eval-when-compile) (test-eager-load-macro-expand-lexical-override): New tests.
-rw-r--r--lisp/ChangeLog7
-rw-r--r--lisp/emacs-lisp/byte-run.el13
-rw-r--r--lisp/emacs-lisp/macroexp.el6
-rw-r--r--src/ChangeLog8
-rw-r--r--src/callint.c4
-rw-r--r--src/lisp.h1
-rw-r--r--src/lread.c28
-rw-r--r--test/ChangeLog14
-rw-r--r--test/automated/bytecomp-tests.el56
9 files changed, 118 insertions, 19 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 38871c7ff32..06e2732becc 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,12 @@
12014-04-22 Daniel Colascione <dancol@dancol.org> 12014-04-22 Daniel Colascione <dancol@dancol.org>
2 2
3 * emacs-lisp/macroexp.el (internal-macroexpand-for-load): Add
4 `full-p' parameter; when nil, call `macroexpand' instead of
5 `macroexpand-all'.
6
7 * emacs-lisp/byte-run.el (eval-when-compile, eval-and-compile):
8 Improve docstrings.
9
3 * emacs-lisp/bytecomp.el (byte-compile-initial-macro-environment): 10 * emacs-lisp/bytecomp.el (byte-compile-initial-macro-environment):
4 Use lambda function values, not quoted lambdas. 11 Use lambda function values, not quoted lambdas.
5 (byte-compile-recurse-toplevel): Remove extraneous &optional. 12 (byte-compile-recurse-toplevel): Remove extraneous &optional.
diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el
index dc08b870569..be011e2146c 100644
--- a/lisp/emacs-lisp/byte-run.el
+++ b/lisp/emacs-lisp/byte-run.el
@@ -398,13 +398,20 @@ If you think you need this, you're probably making a mistake somewhere."
398 398
399(defmacro eval-when-compile (&rest body) 399(defmacro eval-when-compile (&rest body)
400 "Like `progn', but evaluates the body at compile time if you're compiling. 400 "Like `progn', but evaluates the body at compile time if you're compiling.
401Thus, the result of the body appears to the compiler as a quoted constant. 401Thus, the result of the body appears to the compiler as a quoted
402In interpreted code, this is entirely equivalent to `progn'." 402constant. In interpreted code, this is entirely equivalent to
403`progn', except that the value of the expression may be (but is
404not necessarily) computed at load time if eager macro expansion
405is enabled."
403 (declare (debug (&rest def-form)) (indent 0)) 406 (declare (debug (&rest def-form)) (indent 0))
404 (list 'quote (eval (cons 'progn body) lexical-binding))) 407 (list 'quote (eval (cons 'progn body) lexical-binding)))
405 408
406(defmacro eval-and-compile (&rest body) 409(defmacro eval-and-compile (&rest body)
407 "Like `progn', but evaluates the body at compile time and at load time." 410 "Like `progn', but evaluates the body at compile time and at
411load time. In interpreted code, this is entirely equivalent to
412`progn', except that the value of the expression may be (but is
413not necessarily) computed at load time if eager macro expansion
414is enabled."
408 (declare (debug t) (indent 0)) 415 (declare (debug t) (indent 0))
409 ;; When the byte-compiler expands code, this macro is not used, so we're 416 ;; When the byte-compiler expands code, this macro is not used, so we're
410 ;; either about to run `body' (plain interpretation) or we're doing eager 417 ;; either about to run `body' (plain interpretation) or we're doing eager
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index c2bfc891b72..44727daf76a 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -405,7 +405,7 @@ symbol itself."
405(defvar macroexp--pending-eager-loads nil 405(defvar macroexp--pending-eager-loads nil
406 "Stack of files currently undergoing eager macro-expansion.") 406 "Stack of files currently undergoing eager macro-expansion.")
407 407
408(defun internal-macroexpand-for-load (form) 408(defun internal-macroexpand-for-load (form full-p)
409 ;; Called from the eager-macroexpansion in readevalloop. 409 ;; Called from the eager-macroexpansion in readevalloop.
410 (cond 410 (cond
411 ;; Don't repeat the same warning for every top-level element. 411 ;; Don't repeat the same warning for every top-level element.
@@ -428,7 +428,9 @@ symbol itself."
428 (condition-case err 428 (condition-case err
429 (let ((macroexp--pending-eager-loads 429 (let ((macroexp--pending-eager-loads
430 (cons load-file-name macroexp--pending-eager-loads))) 430 (cons load-file-name macroexp--pending-eager-loads)))
431 (macroexpand-all form)) 431 (if full-p
432 (macroexpand-all form)
433 (macroexpand form)))
432 (error 434 (error
433 ;; Hopefully this shouldn't happen thanks to the cycle detection, 435 ;; Hopefully this shouldn't happen thanks to the cycle detection,
434 ;; but in case it does happen, let's catch the error and give the 436 ;; but in case it does happen, let's catch the error and give the
diff --git a/src/ChangeLog b/src/ChangeLog
index bb05be04d3e..bb2e2bad555 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
12014-04-22 Daniel Colascione <dancol@dancol.org>
2
3 * lread.c (readevalloop_eager_expand_eval): New function
4 that can recurse into toplevel forms.
5 (readevalloop): Call it.
6 * lisp.h: Declare Qprogn.
7 * callint.c (Qprogn): No longer static.
8
12014-04-19 Stefan Monnier <monnier@iro.umontreal.ca> 92014-04-19 Stefan Monnier <monnier@iro.umontreal.ca>
2 10
3 * intervals.c (rotate_right, rotate_left): Fix up length computation. 11 * intervals.c (rotate_right, rotate_left): Fix up length computation.
diff --git a/src/callint.c b/src/callint.c
index 35411bf9b5c..54f04cdee17 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -38,8 +38,8 @@ static Lisp_Object Qread_number;
38 38
39Lisp_Object Qmouse_leave_buffer_hook; 39Lisp_Object Qmouse_leave_buffer_hook;
40 40
41static Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion, Qprogn, Qif; 41static Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion, Qif;
42Lisp_Object Qwhen; 42Lisp_Object Qwhen, Qprogn;
43static Lisp_Object preserved_fns; 43static Lisp_Object preserved_fns;
44 44
45/* Marker used within call-interactively to refer to point. */ 45/* Marker used within call-interactively to refer to point. */
diff --git a/src/lisp.h b/src/lisp.h
index 6ef0f83aea4..4c310f69662 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4027,6 +4027,7 @@ extern void syms_of_minibuf (void);
4027/* Defined in callint.c. */ 4027/* Defined in callint.c. */
4028 4028
4029extern Lisp_Object Qminus, Qplus; 4029extern Lisp_Object Qminus, Qplus;
4030extern Lisp_Object Qprogn;
4030extern Lisp_Object Qwhen; 4031extern Lisp_Object Qwhen;
4031extern Lisp_Object Qmouse_leave_buffer_hook; 4032extern Lisp_Object Qmouse_leave_buffer_hook;
4032extern void syms_of_callint (void); 4033extern void syms_of_callint (void);
diff --git a/src/lread.c b/src/lread.c
index 4990d25eda1..4edd1177fb4 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1763,6 +1763,29 @@ end_of_file_error (void)
1763 xsignal0 (Qend_of_file); 1763 xsignal0 (Qend_of_file);
1764} 1764}
1765 1765
1766static Lisp_Object
1767readevalloop_eager_expand_eval (Lisp_Object val, Lisp_Object macroexpand)
1768{
1769 /* If we macroexpand the toplevel form non-recursively and it ends
1770 up being a `progn' (or if it was a progn to start), treat each
1771 form in the progn as a top-level form. This way, if one form in
1772 the progn defines a macro, that macro is in effect when we expand
1773 the remaining forms. See similar code in bytecomp.el. */
1774 val = call2 (macroexpand, val, Qnil);
1775 if (EQ (CAR_SAFE (val), Qprogn))
1776 {
1777 Lisp_Object subforms = XCDR (val);
1778 val = Qnil;
1779 for (; CONSP (subforms); subforms = XCDR (subforms))
1780 val = readevalloop_eager_expand_eval (XCAR (subforms),
1781 macroexpand);
1782 }
1783 else
1784 val = eval_sub (call2 (macroexpand, val, Qt));
1785
1786 return val;
1787}
1788
1766/* UNIBYTE specifies how to set load_convert_to_unibyte 1789/* UNIBYTE specifies how to set load_convert_to_unibyte
1767 for this invocation. 1790 for this invocation.
1768 READFUN, if non-nil, is used instead of `read'. 1791 READFUN, if non-nil, is used instead of `read'.
@@ -1930,8 +1953,9 @@ readevalloop (Lisp_Object readcharfun,
1930 1953
1931 /* Now eval what we just read. */ 1954 /* Now eval what we just read. */
1932 if (!NILP (macroexpand)) 1955 if (!NILP (macroexpand))
1933 val = call1 (macroexpand, val); 1956 val = readevalloop_eager_expand_eval (val, macroexpand);
1934 val = eval_sub (val); 1957 else
1958 val = eval_sub (val);
1935 1959
1936 if (printflag) 1960 if (printflag)
1937 { 1961 {
diff --git a/test/ChangeLog b/test/ChangeLog
index 1163402fd19..1caf0b3eb85 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,7 +1,19 @@
12014-04-22 Daniel Colascione <dancol@dancol.org> 12014-04-22 Daniel Colascione <dancol@dancol.org>
2 2
3 * automated/bytecomp-tests.el (test-byte-comp-compile-and-load):
4 Add compile flag.
5 (test-byte-comp-macro-expansion)
6 (test-byte-comp-macro-expansion-eval-and-compile)
7 (test-byte-comp-macro-expansion-eval-when-compile)
8 (test-byte-comp-macro-expand-lexical-override): Use it.
9 (test-eager-load-macro-expansion)
10 (test-eager-load-macro-expansion-eval-and-compile)
11 (test-eager-load-macro-expansion-eval-when-compile)
12 (test-eager-load-macro-expand-lexical-override): New tests.
13
3 * automated/cl-lib.el (cl-lib-struct-accessors): Fix test to 14 * automated/cl-lib.el (cl-lib-struct-accessors): Fix test to
4 account for removal of `cl-struct-set-slot-value'. 15 account for removal of `cl-struct-set-slot-value'. Also, move
16 the defstruct to top level.
5 17
62014-04-21 Daniel Colascione <dancol@dancol.org> 182014-04-21 Daniel Colascione <dancol@dancol.org>
7 19
diff --git a/test/automated/bytecomp-tests.el b/test/automated/bytecomp-tests.el
index e61c7c3a41d..a7fbdbe2e7f 100644
--- a/test/automated/bytecomp-tests.el
+++ b/test/automated/bytecomp-tests.el
@@ -305,30 +305,33 @@ Subtests signal errors if something goes wrong."
305 'face fail-face))) 305 'face fail-face)))
306 (insert "\n")))) 306 (insert "\n"))))
307 307
308(defun test-byte-comp-compile-and-load (&rest forms) 308(defun test-byte-comp-compile-and-load (compile &rest forms)
309 (let ((elfile nil) 309 (let ((elfile nil)
310 (elcfile nil)) 310 (elcfile nil))
311 (unwind-protect 311 (unwind-protect
312 (progn 312 (progn
313 (setf elfile (make-temp-file "test-bytecomp" nil ".el")) 313 (setf elfile (make-temp-file "test-bytecomp" nil ".el"))
314 (setf elcfile (make-temp-file "test-bytecomp" nil ".elc")) 314 (when compile
315 (setf elcfile (make-temp-file "test-bytecomp" nil ".elc")))
315 (with-temp-buffer 316 (with-temp-buffer
316 (dolist (form forms) 317 (dolist (form forms)
317 (print form (current-buffer))) 318 (print form (current-buffer)))
318 (write-region (point-min) (point-max) elfile)) 319 (write-region (point-min) (point-max) elfile))
319 (let ((byte-compile-dest-file elcfile)) 320 (if compile
320 (byte-compile-file elfile t))) 321 (let ((byte-compile-dest-file elcfile))
322 (byte-compile-file elfile t))
323 (load elfile)))
321 (when elfile (delete-file elfile)) 324 (when elfile (delete-file elfile))
322 (when elcfile (delete-file elcfile))))) 325 (when elcfile (delete-file elcfile)))))
323(put 'test-byte-comp-compile-and-load 'lisp-indent-function 0) 326(put 'test-byte-comp-compile-and-load 'lisp-indent-function 1)
324 327
325(ert-deftest test-byte-comp-macro-expansion () 328(ert-deftest test-byte-comp-macro-expansion ()
326 (test-byte-comp-compile-and-load 329 (test-byte-comp-compile-and-load t
327 '(progn (defmacro abc (arg) 1) (defun def () (abc 2)))) 330 '(progn (defmacro abc (arg) 1) (defun def () (abc 2))))
328 (should (equal (funcall 'def) 1))) 331 (should (equal (funcall 'def) 1)))
329 332
330(ert-deftest test-byte-comp-macro-expansion-eval-and-compile () 333(ert-deftest test-byte-comp-macro-expansion-eval-and-compile ()
331 (test-byte-comp-compile-and-load 334 (test-byte-comp-compile-and-load t
332 '(eval-and-compile (defmacro abc (arg) -1) (defun def () (abc 2)))) 335 '(eval-and-compile (defmacro abc (arg) -1) (defun def () (abc 2))))
333 (should (equal (funcall 'def) -1))) 336 (should (equal (funcall 'def) -1)))
334 337
@@ -336,7 +339,7 @@ Subtests signal errors if something goes wrong."
336 ;; Make sure we interpret eval-when-compile forms properly. CLISP 339 ;; Make sure we interpret eval-when-compile forms properly. CLISP
337 ;; and SBCL interpreter eval-when-compile (well, the CL equivalent) 340 ;; and SBCL interpreter eval-when-compile (well, the CL equivalent)
338 ;; in the same way. 341 ;; in the same way.
339 (test-byte-comp-compile-and-load 342 (test-byte-comp-compile-and-load t
340 '(eval-when-compile 343 '(eval-when-compile
341 (defmacro abc (arg) -10) 344 (defmacro abc (arg) -10)
342 (defun abc-1 () (abc 2))) 345 (defun abc-1 () (abc 2)))
@@ -349,13 +352,48 @@ Subtests signal errors if something goes wrong."
349 ;; macrolet since macrolet's is explicitly called out as being 352 ;; macrolet since macrolet's is explicitly called out as being
350 ;; equivalent to toplevel, but CLISP and SBCL both evaluate the form 353 ;; equivalent to toplevel, but CLISP and SBCL both evaluate the form
351 ;; this way, so we should too. 354 ;; this way, so we should too.
352 (test-byte-comp-compile-and-load 355 (test-byte-comp-compile-and-load t
353 '(require 'cl-lib) 356 '(require 'cl-lib)
354 '(cl-macrolet ((m () 4)) 357 '(cl-macrolet ((m () 4))
355 (defmacro m () 5) 358 (defmacro m () 5)
356 (defun def () (m)))) 359 (defun def () (m))))
357 (should (equal (funcall 'def) 4))) 360 (should (equal (funcall 'def) 4)))
358 361
362(ert-deftest test-eager-load-macro-expansion ()
363 (test-byte-comp-compile-and-load nil
364 '(progn (defmacro abc (arg) 1) (defun def () (abc 2))))
365 (should (equal (funcall 'def) 1)))
366
367(ert-deftest test-eager-load-macro-expansion-eval-and-compile ()
368 (test-byte-comp-compile-and-load nil
369 '(eval-and-compile (defmacro abc (arg) -1) (defun def () (abc 2))))
370 (should (equal (funcall 'def) -1)))
371
372(ert-deftest test-eager-load-macro-expansion-eval-when-compile ()
373 ;; Make sure we interpret eval-when-compile forms properly. CLISP
374 ;; and SBCL interpreter eval-when-compile (well, the CL equivalent)
375 ;; in the same way.
376 (test-byte-comp-compile-and-load nil
377 '(eval-when-compile
378 (defmacro abc (arg) -10)
379 (defun abc-1 () (abc 2)))
380 '(defmacro abc-2 () (abc-1))
381 '(defun def () (abc-2)))
382 (should (equal (funcall 'def) -10)))
383
384(ert-deftest test-eager-load-macro-expand-lexical-override ()
385 ;; Intuitively, one might expect the defmacro to override the
386 ;; macrolet since macrolet's is explicitly called out as being
387 ;; equivalent to toplevel, but CLISP and SBCL both evaluate the form
388 ;; this way, so we should too.
389 (test-byte-comp-compile-and-load nil
390 '(require 'cl-lib)
391 '(cl-macrolet ((m () 4))
392 (defmacro m () 5)
393 (defun def () (m))))
394 (should (equal (funcall 'def) 4)))
395
396
359;; Local Variables: 397;; Local Variables:
360;; no-byte-compile: t 398;; no-byte-compile: t
361;; End: 399;; End: