diff options
| author | Daniel Colascione | 2014-04-22 00:04:34 -0700 |
|---|---|---|
| committer | Daniel Colascione | 2014-04-22 00:04:34 -0700 |
| commit | 12b1389c9039dd374951673ca43b1ddf65df400d (patch) | |
| tree | f4d36afc9d1ccdd72f3d801b350d79d25dd5e8bb /src | |
| parent | c98212f9e7cef496dded06eba4476033062c171f (diff) | |
| download | emacs-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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/callint.c | 4 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/lread.c | 28 |
4 files changed, 37 insertions, 4 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index bb05be04d3e..bb2e2bad555 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2014-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 | |||
| 1 | 2014-04-19 Stefan Monnier <monnier@iro.umontreal.ca> | 9 | 2014-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 | ||
| 39 | Lisp_Object Qmouse_leave_buffer_hook; | 39 | Lisp_Object Qmouse_leave_buffer_hook; |
| 40 | 40 | ||
| 41 | static Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion, Qprogn, Qif; | 41 | static Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion, Qif; |
| 42 | Lisp_Object Qwhen; | 42 | Lisp_Object Qwhen, Qprogn; |
| 43 | static Lisp_Object preserved_fns; | 43 | static 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 | ||
| 4029 | extern Lisp_Object Qminus, Qplus; | 4029 | extern Lisp_Object Qminus, Qplus; |
| 4030 | extern Lisp_Object Qprogn; | ||
| 4030 | extern Lisp_Object Qwhen; | 4031 | extern Lisp_Object Qwhen; |
| 4031 | extern Lisp_Object Qmouse_leave_buffer_hook; | 4032 | extern Lisp_Object Qmouse_leave_buffer_hook; |
| 4032 | extern void syms_of_callint (void); | 4033 | extern 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 | ||
| 1766 | static Lisp_Object | ||
| 1767 | readevalloop_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 | { |