diff options
| author | Daniel Colascione <dancol@dancol.org> | 2014-04-22 00:04:34 -0700 |
|---|---|---|
| committer | Daniel Colascione <dancol@dancol.org> | 2014-04-22 00:04:34 -0700 |
| commit | 12b1389c9039dd374951673ca43b1ddf65df400d (patch) | |
| tree | f4d36afc9d1ccdd72f3d801b350d79d25dd5e8bb /src | |
| parent | c98212f9e7cef496dded06eba4476033062c171f (diff) | |
| download | emacs-12b1389c9039dd374951673ca43b1ddf65df400d.tar.gz | |
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 @@ +2014-04-22 Daniel Colascione <dancol@dancol.org> + + * lread.c (readevalloop_eager_expand_eval): New function + that can recurse into toplevel forms. + (readevalloop): Call it. + * lisp.h: Declare Qprogn. + * callint.c (Qprogn): No longer static. + 2014-04-19 Stefan Monnier <monnier@iro.umontreal.ca> * 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; Lisp_Object Qmouse_leave_buffer_hook; -static Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion, Qprogn, Qif; -Lisp_Object Qwhen; +static Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion, Qif; +Lisp_Object Qwhen, Qprogn; static Lisp_Object preserved_fns; /* 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); /* Defined in callint.c. */ extern Lisp_Object Qminus, Qplus; +extern Lisp_Object Qprogn; extern Lisp_Object Qwhen; extern Lisp_Object Qmouse_leave_buffer_hook; 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) xsignal0 (Qend_of_file); } +static Lisp_Object +readevalloop_eager_expand_eval (Lisp_Object val, Lisp_Object macroexpand) +{ + /* If we macroexpand the toplevel form non-recursively and it ends + up being a `progn' (or if it was a progn to start), treat each + form in the progn as a top-level form. This way, if one form in + the progn defines a macro, that macro is in effect when we expand + the remaining forms. See similar code in bytecomp.el. */ + val = call2 (macroexpand, val, Qnil); + if (EQ (CAR_SAFE (val), Qprogn)) + { + Lisp_Object subforms = XCDR (val); + val = Qnil; + for (; CONSP (subforms); subforms = XCDR (subforms)) + val = readevalloop_eager_expand_eval (XCAR (subforms), + macroexpand); + } + else + val = eval_sub (call2 (macroexpand, val, Qt)); + + return val; +} + /* UNIBYTE specifies how to set load_convert_to_unibyte for this invocation. READFUN, if non-nil, is used instead of `read'. @@ -1930,8 +1953,9 @@ readevalloop (Lisp_Object readcharfun, /* Now eval what we just read. */ if (!NILP (macroexpand)) - val = call1 (macroexpand, val); - val = eval_sub (val); + val = readevalloop_eager_expand_eval (val, macroexpand); + else + val = eval_sub (val); if (printflag) { |
