diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2010-12-15 12:46:59 -0500 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2010-12-15 12:46:59 -0500 |
commit | a0ee6f2751acba71df443d4d795bb350eb6421dd (patch) | |
tree | e4f47d66877b1b00b9ce00a304b509dee840868a /src | |
parent | defb141157dfa37c33cdcbfa4b29c702a8fc9edf (diff) |
Obey lexical-binding in interactive evaluation commands.
* lisp/emacs-lisp/edebug.el (edebug-eval-defun, edebug-eval):
* lisp/emacs-lisp/lisp-mode.el (eval-last-sexp-1, eval-defun-1):
* lisp/ielm.el (ielm-eval-input):
* lisp/simple.el (eval-expression): Use new eval arg to obey lexical-binding.
* src/eval.c (Feval): Add `lexical' argument. Adjust callers.
(Ffuncall, eval_sub): Avoid goto.
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 5 | ||||
-rw-r--r-- | src/bytecode.c | 2 | ||||
-rw-r--r-- | src/callint.c | 2 | ||||
-rw-r--r-- | src/doc.c | 2 | ||||
-rw-r--r-- | src/eval.c | 267 | ||||
-rw-r--r-- | src/keyboard.c | 12 | ||||
-rw-r--r-- | src/lisp.h | 2 | ||||
-rw-r--r-- | src/minibuf.c | 4 |
8 files changed, 152 insertions, 144 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index c333b6388c..2de6a5ed66 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2010-12-15 Stefan Monnier <monnier@iro.umontreal.ca> + + * eval.c (Feval): Add `lexical' argument. Adjust callers. + (Ffuncall, eval_sub): Avoid goto. + 2010-12-14 Stefan Monnier <monnier@iro.umontreal.ca> Try and be more careful about propagation of lexical environment. diff --git a/src/bytecode.c b/src/bytecode.c index 01fce0577b..eb12b9c496 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -915,7 +915,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, Lisp_Object v1; BEFORE_POTENTIAL_GC (); v1 = POP; - TOP = internal_catch (TOP, Feval, v1); /* FIXME: lexbind */ + TOP = internal_catch (TOP, eval_sub, v1); /* FIXME: lexbind */ AFTER_POTENTIAL_GC (); break; } diff --git a/src/callint.c b/src/callint.c index 960158029c..5eb65b31cb 100644 --- a/src/callint.c +++ b/src/callint.c @@ -342,7 +342,7 @@ invoke it. If KEYS is omitted or nil, the return value of input = specs; /* Compute the arg values using the user's expression. */ GCPRO2 (input, filter_specs); - specs = Feval (specs); /* FIXME: lexbind */ + specs = Feval (specs, Qnil); /* FIXME: lexbind */ UNGCPRO; if (i != num_input_events || !NILP (record_flag)) { @@ -490,7 +490,7 @@ aren't strings. */) } else if (!STRINGP (tem)) /* Feval protects its argument. */ - tem = Feval (tem); + tem = Feval (tem, Qnil); if (NILP (raw) && STRINGP (tem)) tem = Fsubstitute_command_keys (tem); diff --git a/src/eval.c b/src/eval.c index 485ba00c1e..7104a8a839 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2311,12 +2311,14 @@ do_autoload (Lisp_Object fundef, Lisp_Object funname) } -DEFUN ("eval", Feval, Seval, 1, 1, 0, - doc: /* Evaluate FORM and return its value. */) - (Lisp_Object form) +DEFUN ("eval", Feval, Seval, 1, 2, 0, + doc: /* Evaluate FORM and return its value. +If LEXICAL is t, evaluate using lexical scoping. */) + (Lisp_Object form, Lisp_Object lexical) { int count = SPECPDL_INDEX (); - specbind (Qinternal_interpreter_environment, Qnil); + specbind (Qinternal_interpreter_environment, + NILP (lexical) ? Qnil : Fcons (Qt, Qnil)); return unbind_to (count, eval_sub (form)); } @@ -2414,10 +2416,8 @@ eval_sub (Lisp_Object form) { backtrace.evalargs = 0; val = (XSUBR (fun)->function.aUNEVALLED) (args_left); - goto done; } - - if (XSUBR (fun)->max_args == MANY) + else if (XSUBR (fun)->max_args == MANY) { /* Pass a vector of evaluated arguments */ Lisp_Object *vals; @@ -2443,73 +2443,74 @@ eval_sub (Lisp_Object form) val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals); UNGCPRO; SAFE_FREE (); - goto done; } - - GCPRO3 (args_left, fun, fun); - gcpro3.var = argvals; - gcpro3.nvars = 0; - - maxargs = XSUBR (fun)->max_args; - for (i = 0; i < maxargs; args_left = Fcdr (args_left)) + else { - argvals[i] = eval_sub (Fcar (args_left)); - gcpro3.nvars = ++i; - } - - UNGCPRO; + GCPRO3 (args_left, fun, fun); + gcpro3.var = argvals; + gcpro3.nvars = 0; + + maxargs = XSUBR (fun)->max_args; + for (i = 0; i < maxargs; args_left = Fcdr (args_left)) + { + argvals[i] = eval_sub (Fcar (args_left)); + gcpro3.nvars = ++i; + } + + UNGCPRO; - backtrace.args = argvals; - backtrace.nargs = XINT (numargs); + backtrace.args = argvals; + backtrace.nargs = XINT (numargs); - switch (i) - { - case 0: - val = (XSUBR (fun)->function.a0) (); - goto done; - case 1: - val = (XSUBR (fun)->function.a1) (argvals[0]); - goto done; - case 2: - val = (XSUBR (fun)->function.a2) (argvals[0], argvals[1]); - goto done; - case 3: - val = (XSUBR (fun)->function.a3) (argvals[0], argvals[1], - argvals[2]); - goto done; - case 4: - val = (XSUBR (fun)->function.a4) (argvals[0], argvals[1], - argvals[2], argvals[3]); - goto done; - case 5: - val = (XSUBR (fun)->function.a5) (argvals[0], argvals[1], argvals[2], - argvals[3], argvals[4]); - goto done; - case 6: - val = (XSUBR (fun)->function.a6) (argvals[0], argvals[1], argvals[2], - argvals[3], argvals[4], argvals[5]); - goto done; - case 7: - val = (XSUBR (fun)->function.a7) (argvals[0], argvals[1], argvals[2], - argvals[3], argvals[4], argvals[5], - argvals[6]); - goto done; - - case 8: - val = (XSUBR (fun)->function.a8) (argvals[0], argvals[1], argvals[2], - argvals[3], argvals[4], argvals[5], - argvals[6], argvals[7]); - goto done; - - default: - /* Someone has created a subr that takes more arguments than - is supported by this code. We need to either rewrite the - subr to use a different argument protocol, or add more - cases to this switch. */ - abort (); + switch (i) + { + case 0: + val = (XSUBR (fun)->function.a0) (); + break; + case 1: + val = (XSUBR (fun)->function.a1) (argvals[0]); + break; + case 2: + val = (XSUBR (fun)->function.a2) (argvals[0], argvals[1]); + break; + case 3: + val = (XSUBR (fun)->function.a3) (argvals[0], argvals[1], + argvals[2]); + break; + case 4: + val = (XSUBR (fun)->function.a4) (argvals[0], argvals[1], + argvals[2], argvals[3]); + break; + case 5: + val = (XSUBR (fun)->function.a5) (argvals[0], argvals[1], argvals[2], + argvals[3], argvals[4]); + break; + case 6: + val = (XSUBR (fun)->function.a6) (argvals[0], argvals[1], argvals[2], + argvals[3], argvals[4], argvals[5]); + break; + case 7: + val = (XSUBR (fun)->function.a7) (argvals[0], argvals[1], argvals[2], + argvals[3], argvals[4], argvals[5], + argvals[6]); + + break; + case 8: + val = (XSUBR (fun)->function.a8) (argvals[0], argvals[1], argvals[2], + argvals[3], argvals[4], argvals[5], + argvals[6], argvals[7]); + + break; + default: + /* Someone has created a subr that takes more arguments than + is supported by this code. We need to either rewrite the + subr to use a different argument protocol, or add more + cases to this switch. */ + abort (); + } } } - if (FUNVECP (fun)) + else if (FUNVECP (fun)) val = apply_lambda (fun, original_args); else { @@ -2533,7 +2534,6 @@ eval_sub (Lisp_Object form) else xsignal1 (Qinvalid_function, original_fun); } - done: CHECK_CONS_LIST (); lisp_eval_depth--; @@ -3109,7 +3109,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) if (SUBRP (fun)) { - if (numargs < XSUBR (fun)->min_args + if (numargs < XSUBR (fun)->min_args || (XSUBR (fun)->max_args >= 0 && XSUBR (fun)->max_args < numargs)) { XSETFASTINT (lisp_numargs, numargs); @@ -3119,74 +3119,72 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) if (XSUBR (fun)->max_args == UNEVALLED) xsignal1 (Qinvalid_function, original_fun); - if (XSUBR (fun)->max_args == MANY) - { - val = (XSUBR (fun)->function.aMANY) (numargs, args + 1); - goto done; - } - - if (XSUBR (fun)->max_args > numargs) - { - internal_args = (Lisp_Object *) alloca (XSUBR (fun)->max_args * sizeof (Lisp_Object)); - memcpy (internal_args, args + 1, numargs * sizeof (Lisp_Object)); - for (i = numargs; i < XSUBR (fun)->max_args; i++) - internal_args[i] = Qnil; - } + else if (XSUBR (fun)->max_args == MANY) + val = (XSUBR (fun)->function.aMANY) (numargs, args + 1); else - internal_args = args + 1; - switch (XSUBR (fun)->max_args) { - case 0: - val = (XSUBR (fun)->function.a0) (); - goto done; - case 1: - val = (XSUBR (fun)->function.a1) (internal_args[0]); - goto done; - case 2: - val = (XSUBR (fun)->function.a2) (internal_args[0], internal_args[1]); - goto done; - case 3: - val = (XSUBR (fun)->function.a3) (internal_args[0], internal_args[1], - internal_args[2]); - goto done; - case 4: - val = (XSUBR (fun)->function.a4) (internal_args[0], internal_args[1], - internal_args[2], internal_args[3]); - goto done; - case 5: - val = (XSUBR (fun)->function.a5) (internal_args[0], internal_args[1], - internal_args[2], internal_args[3], - internal_args[4]); - goto done; - case 6: - val = (XSUBR (fun)->function.a6) (internal_args[0], internal_args[1], - internal_args[2], internal_args[3], - internal_args[4], internal_args[5]); - goto done; - case 7: - val = (XSUBR (fun)->function.a7) (internal_args[0], internal_args[1], - internal_args[2], internal_args[3], - internal_args[4], internal_args[5], - internal_args[6]); - goto done; - - case 8: - val = (XSUBR (fun)->function.a8) (internal_args[0], internal_args[1], - internal_args[2], internal_args[3], - internal_args[4], internal_args[5], - internal_args[6], internal_args[7]); - goto done; - - default: - - /* If a subr takes more than 8 arguments without using MANY - or UNEVALLED, we need to extend this function to support it. - Until this is done, there is no way to call the function. */ - abort (); + if (XSUBR (fun)->max_args > numargs) + { + internal_args = (Lisp_Object *) alloca (XSUBR (fun)->max_args * sizeof (Lisp_Object)); + memcpy (internal_args, args + 1, numargs * sizeof (Lisp_Object)); + for (i = numargs; i < XSUBR (fun)->max_args; i++) + internal_args[i] = Qnil; + } + else + internal_args = args + 1; + switch (XSUBR (fun)->max_args) + { + case 0: + val = (XSUBR (fun)->function.a0) (); + break; + case 1: + val = (XSUBR (fun)->function.a1) (internal_args[0]); + break; + case 2: + val = (XSUBR (fun)->function.a2) (internal_args[0], internal_args[1]); + break; + case 3: + val = (XSUBR (fun)->function.a3) (internal_args[0], internal_args[1], + internal_args[2]); + break; + case 4: + val = (XSUBR (fun)->function.a4) (internal_args[0], internal_args[1], + internal_args[2], internal_args[3]); + break; + case 5: + val = (XSUBR (fun)->function.a5) (internal_args[0], internal_args[1], + internal_args[2], internal_args[3], + internal_args[4]); + break; + case 6: + val = (XSUBR (fun)->function.a6) (internal_args[0], internal_args[1], + internal_args[2], internal_args[3], + internal_args[4], internal_args[5]); + break; + case 7: + val = (XSUBR (fun)->function.a7) (internal_args[0], internal_args[1], + internal_args[2], internal_args[3], + internal_args[4], internal_args[5], + internal_args[6]); + break; + + case 8: + val = (XSUBR (fun)->function.a8) (internal_args[0], internal_args[1], + internal_args[2], internal_args[3], + internal_args[4], internal_args[5], + internal_args[6], internal_args[7]); + break; + + default: + + /* If a subr takes more than 8 arguments without using MANY + or UNEVALLED, we need to extend this function to support it. + Until this is done, there is no way to call the function. */ + abort (); + } } } - - if (FUNVECP (fun)) + else if (FUNVECP (fun)) val = funcall_lambda (fun, numargs, args + 1); else { @@ -3209,7 +3207,6 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) else xsignal1 (Qinvalid_function, original_fun); } - done: CHECK_CONS_LIST (); lisp_eval_depth--; if (backtrace.debug_on_exit) diff --git a/src/keyboard.c b/src/keyboard.c index 1781917064..df69c526f7 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1327,7 +1327,7 @@ command_loop_2 (Lisp_Object ignore) Lisp_Object top_level_2 (void) { - return Feval (Vtop_level); + return Feval (Vtop_level, Qnil); } Lisp_Object @@ -3255,7 +3255,7 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event help_form_saved_window_configs); record_unwind_protect (read_char_help_form_unwind, Qnil); - tem0 = Feval (Vhelp_form); + tem0 = Feval (Vhelp_form, Qnil); if (STRINGP (tem0)) internal_with_output_to_temp_buffer ("*Help*", print_help, tem0); @@ -7696,6 +7696,12 @@ menu_item_eval_property_1 (Lisp_Object arg) return Qnil; } +static Lisp_Object +eval_dyn (Lisp_Object form) +{ + return Feval (form, Qnil); +} + /* Evaluate an expression and return the result (or nil if something went wrong). Used to evaluate dynamic parts of menu items. */ Lisp_Object @@ -7704,7 +7710,7 @@ menu_item_eval_property (Lisp_Object sexpr) int count = SPECPDL_INDEX (); Lisp_Object val; specbind (Qinhibit_redisplay, Qt); - val = internal_condition_case_1 (Feval, sexpr, Qerror, + val = internal_condition_case_1 (eval_dyn, sexpr, Qerror, menu_item_eval_property_1); return unbind_to (count, val); } diff --git a/src/lisp.h b/src/lisp.h index 20b50632c4..db78996be5 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2971,7 +2971,7 @@ extern void xsignal3 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) NO_RET extern void signal_error (const char *, Lisp_Object) NO_RETURN; EXFUN (Fautoload, 5); EXFUN (Fcommandp, 2); -EXFUN (Feval, 1); +EXFUN (Feval, 2); extern Lisp_Object eval_sub (Lisp_Object form); EXFUN (Fapply, MANY); EXFUN (Ffuncall, MANY); diff --git a/src/minibuf.c b/src/minibuf.c index 409f8a9a9e..9dd32a8bab 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -1026,10 +1026,10 @@ is a string to insert in the minibuffer before reading. Such arguments are used as in `read-from-minibuffer'.) */) (Lisp_Object prompt, Lisp_Object initial_contents) { - /* FIXME: lexbind. */ return Feval (read_minibuf (Vread_expression_map, initial_contents, prompt, Qnil, 1, Qread_expression_history, - make_number (0), Qnil, 0, 0)); + make_number (0), Qnil, 0, 0), + Qnil); } /* Functions that use the minibuffer to read various things. */ |