mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-07 16:10:46 -08:00
Merge remote-tracking branch 'origin/scratch/bug-55156'
This commit is contained in:
commit
14cbb75455
3 changed files with 69 additions and 43 deletions
|
|
@ -527,10 +527,11 @@ If @var{symbol} has a buffer-local binding in the current buffer,
|
|||
rather than the buffer-local binding. It sets the default value if
|
||||
the default value is void. @xref{Buffer-Local Variables}.
|
||||
|
||||
If @var{symbol} is already lexically bound (e.g., if the @code{defvar}
|
||||
form occurs in a @code{let} form with lexical binding enabled), then
|
||||
@code{defvar} sets the dynamic value. The lexical binding remains in
|
||||
effect until its binding construct exits. @xref{Variable Scoping}.
|
||||
If @var{symbol} is already let bound (e.g., if the @code{defvar}
|
||||
form occurs in a @code{let} form), then @code{defvar} sets the toplevel
|
||||
default value, like @code{set-default-toplevel-value}.
|
||||
The let binding remains in effect until its binding construct exits.
|
||||
@xref{Variable Scoping}.
|
||||
|
||||
@cindex @code{eval-defun}, and @code{defvar} forms
|
||||
@cindex @code{eval-last-sexp}, and @code{defvar} forms
|
||||
|
|
|
|||
|
|
@ -4943,8 +4943,6 @@ binding slots have been popped."
|
|||
(push (nth 1 (nth 1 form)) byte-compile-global-not-obsolete-vars))
|
||||
(byte-compile-normal-call form))
|
||||
|
||||
(defconst byte-compile-tmp-var (make-symbol "def-tmp-var"))
|
||||
|
||||
(defun byte-compile-defvar (form)
|
||||
;; This is not used for file-level defvar/consts.
|
||||
(when (and (symbolp (nth 1 form))
|
||||
|
|
@ -4977,18 +4975,17 @@ binding slots have been popped."
|
|||
string
|
||||
"third arg to `%s %s' is not a string: %s"
|
||||
fun var string))
|
||||
;; Delegate the actual work to the function version of the
|
||||
;; special form, named with a "-1" suffix.
|
||||
(byte-compile-form-do-effect
|
||||
(if (cddr form) ; `value' provided
|
||||
;; Quote with `quote' to prevent byte-compiling the body,
|
||||
;; which would lead to an inf-loop.
|
||||
`(funcall '(lambda (,byte-compile-tmp-var)
|
||||
(,fun ,var ,byte-compile-tmp-var ,@(nthcdr 3 form)))
|
||||
,value)
|
||||
(if (eq fun 'defconst)
|
||||
;; This will signal an appropriate error at runtime.
|
||||
`(eval ',form)
|
||||
;; A simple (defvar foo) just returns foo.
|
||||
`',var)))))
|
||||
(cond
|
||||
((eq fun 'defconst) `(defconst-1 ',var ,@(nthcdr 2 form)))
|
||||
((not (cddr form)) `',var) ; A simple (defvar foo) just returns foo.
|
||||
(t `(defvar-1 ',var
|
||||
;; Don't eval `value' if `defvar' wouldn't eval it either.
|
||||
,(if (macroexp-const-p value) value
|
||||
`(if (boundp ',var) nil ,value))
|
||||
,@(nthcdr 3 form)))))))
|
||||
|
||||
(defun byte-compile-autoload (form)
|
||||
(and (macroexp-const-p (nth 1 form))
|
||||
|
|
|
|||
80
src/eval.c
80
src/eval.c
|
|
@ -756,6 +756,33 @@ value. */)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
static Lisp_Object
|
||||
defvar (Lisp_Object sym, Lisp_Object initvalue, Lisp_Object docstring, bool eval)
|
||||
{
|
||||
Lisp_Object tem;
|
||||
|
||||
CHECK_SYMBOL (sym);
|
||||
|
||||
tem = Fdefault_boundp (sym);
|
||||
|
||||
/* Do it before evaluating the initial value, for self-references. */
|
||||
Finternal__define_uninitialized_variable (sym, docstring);
|
||||
|
||||
if (NILP (tem))
|
||||
Fset_default (sym, eval ? eval_sub (initvalue) : initvalue);
|
||||
else
|
||||
{ /* Check if there is really a global binding rather than just a let
|
||||
binding that shadows the global unboundness of the var. */
|
||||
union specbinding *binding = default_toplevel_binding (sym);
|
||||
if (binding && EQ (specpdl_old_value (binding), Qunbound))
|
||||
{
|
||||
set_specpdl_old_value (binding,
|
||||
eval ? eval_sub (initvalue) : initvalue);
|
||||
}
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
|
||||
DEFUN ("defvar", Fdefvar, Sdefvar, 1, UNEVALLED, 0,
|
||||
doc: /* Define SYMBOL as a variable, and return SYMBOL.
|
||||
You are not required to define a variable in order to use it, but
|
||||
|
|
@ -770,12 +797,10 @@ value. If SYMBOL is buffer-local, its default value is what is set;
|
|||
buffer-local values are not affected. If INITVALUE is missing,
|
||||
SYMBOL's value is not set.
|
||||
|
||||
If SYMBOL has a local binding, then this form affects the local
|
||||
binding. This is usually not what you want. Thus, if you need to
|
||||
load a file defining variables, with this form or with `defconst' or
|
||||
`defcustom', you should always load that file _outside_ any bindings
|
||||
for these variables. (`defconst' and `defcustom' behave similarly in
|
||||
this respect.)
|
||||
If SYMBOL is let-bound, then this form does not affect the local let
|
||||
binding but the toplevel default binding instead, like
|
||||
`set-toplevel-default-binding`.
|
||||
(`defcustom' behaves similarly in this respect.)
|
||||
|
||||
The optional argument DOCSTRING is a documentation string for the
|
||||
variable.
|
||||
|
|
@ -786,7 +811,7 @@ To define a buffer-local variable, use `defvar-local'.
|
|||
usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */)
|
||||
(Lisp_Object args)
|
||||
{
|
||||
Lisp_Object sym, tem, tail;
|
||||
Lisp_Object sym, tail;
|
||||
|
||||
sym = XCAR (args);
|
||||
tail = XCDR (args);
|
||||
|
|
@ -798,24 +823,8 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */)
|
|||
if (!NILP (XCDR (tail)) && !NILP (XCDR (XCDR (tail))))
|
||||
error ("Too many arguments");
|
||||
Lisp_Object exp = XCAR (tail);
|
||||
|
||||
tem = Fdefault_boundp (sym);
|
||||
tail = XCDR (tail);
|
||||
|
||||
/* Do it before evaluating the initial value, for self-references. */
|
||||
Finternal__define_uninitialized_variable (sym, CAR (tail));
|
||||
|
||||
if (NILP (tem))
|
||||
Fset_default (sym, eval_sub (exp));
|
||||
else
|
||||
{ /* Check if there is really a global binding rather than just a let
|
||||
binding that shadows the global unboundness of the var. */
|
||||
union specbinding *binding = default_toplevel_binding (sym);
|
||||
if (binding && EQ (specpdl_old_value (binding), Qunbound))
|
||||
{
|
||||
set_specpdl_old_value (binding, eval_sub (exp));
|
||||
}
|
||||
}
|
||||
return defvar (sym, exp, CAR (tail), true);
|
||||
}
|
||||
else if (!NILP (Vinternal_interpreter_environment)
|
||||
&& (SYMBOLP (sym) && !XSYMBOL (sym)->u.s.declared_special))
|
||||
|
|
@ -834,6 +843,14 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */)
|
|||
return sym;
|
||||
}
|
||||
|
||||
DEFUN ("defvar-1", Fdefvar_1, Sdefvar_1, 2, 3, 0,
|
||||
doc: /* Like `defvar' but as a function.
|
||||
More specifically behaves like (defvar SYM 'INITVALUE DOCSTRING). */)
|
||||
(Lisp_Object sym, Lisp_Object initvalue, Lisp_Object docstring)
|
||||
{
|
||||
return defvar (sym, initvalue, docstring, false);
|
||||
}
|
||||
|
||||
DEFUN ("defconst", Fdefconst, Sdefconst, 2, UNEVALLED, 0,
|
||||
doc: /* Define SYMBOL as a constant variable.
|
||||
This declares that neither programs nor users should ever change the
|
||||
|
|
@ -863,9 +880,18 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */)
|
|||
error ("Too many arguments");
|
||||
docstring = XCAR (XCDR (XCDR (args)));
|
||||
}
|
||||
|
||||
Finternal__define_uninitialized_variable (sym, docstring);
|
||||
tem = eval_sub (XCAR (XCDR (args)));
|
||||
return Fdefconst_1 (sym, tem, docstring);
|
||||
}
|
||||
|
||||
DEFUN ("defconst-1", Fdefconst_1, Sdefconst_1, 2, 3, 0,
|
||||
doc: /* Like `defconst' but as a function.
|
||||
More specifically, behaves like (defconst SYM 'INITVALUE DOCSTRING). */)
|
||||
(Lisp_Object sym, Lisp_Object initvalue, Lisp_Object docstring)
|
||||
{
|
||||
CHECK_SYMBOL (sym);
|
||||
Lisp_Object tem = initvalue;
|
||||
Finternal__define_uninitialized_variable (sym, docstring);
|
||||
if (!NILP (Vpurify_flag))
|
||||
tem = Fpurecopy (tem);
|
||||
Fset_default (sym, tem); /* FIXME: set-default-toplevel-value? */
|
||||
|
|
@ -4333,9 +4359,11 @@ alist of active lexical bindings. */);
|
|||
defsubr (&Sdefault_toplevel_value);
|
||||
defsubr (&Sset_default_toplevel_value);
|
||||
defsubr (&Sdefvar);
|
||||
defsubr (&Sdefvar_1);
|
||||
defsubr (&Sdefvaralias);
|
||||
DEFSYM (Qdefvaralias, "defvaralias");
|
||||
defsubr (&Sdefconst);
|
||||
defsubr (&Sdefconst_1);
|
||||
defsubr (&Sinternal__define_uninitialized_variable);
|
||||
defsubr (&Smake_var_non_special);
|
||||
defsubr (&Slet);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue