diff options
| author | Stefan Monnier | 2011-04-01 13:19:52 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2011-04-01 13:19:52 -0400 |
| commit | 034086489cff2a23cb4d9f8c536e18456be617ef (patch) | |
| tree | 93fa6987e56af7b5fd452f7f909ea0653c5b47de /src/lread.c | |
| parent | 1c412c000a5d61d1be7f6fa7e632a517b89de95b (diff) | |
| parent | 7200d79c65c65686495dd95e9f6dd436cf6db55e (diff) | |
| download | emacs-034086489cff2a23cb4d9f8c536e18456be617ef.tar.gz emacs-034086489cff2a23cb4d9f8c536e18456be617ef.zip | |
Merge from lexical-binding branch.
* doc/lispref/eval.texi (Eval): Discourage the use of `eval'.
Document its new `lexical' argument.
* doc/lispref/variables.texi (Defining Variables): Mention the new meaning of `defvar'.
(Lexical Binding): New sub-section.
* lisp/Makefile.in (BIG_STACK_DEPTH, BIG_STACK_OPTS, BYTE_COMPILE_FLAGS):
New variables.
(compile-onefile, .el.elc, compile-calc, recompile): Use them.
(COMPILE_FIRST): Add macroexp and cconv.
* lisp/makefile.w32-in: Mirror changes in Makefile.in.
* lisp/vc/cvs-status.el:
* lisp/vc/diff-mode.el:
* lisp/vc/log-edit.el:
* lisp/vc/log-view.el:
* lisp/vc/smerge-mode.el:
* lisp/textmodes/bibtex-style.el:
* textmodes/css.el:
* lisp/startup.el:
* lisp/uniquify.el:
* lisp/minibuffer.el:
* lisp/newcomment.el:
* lisp/reveal.el:
* lisp/server.el:
* lisp/mpc.el:
* lisp/emacs-lisp/smie.el:
* lisp/doc-view.el:
* lisp/dired.el:
* lisp/abbrev.el: Use lexical binding.
* lisp/custom.el (custom-initialize-default, custom-declare-variable):
Use `defvar'.
* lisp/files.el (lexical-binding): Declare safe.
* lisp/help-fns.el (help-split-fundoc): Return nil if there's nothing else
than the arglist.
(help-add-fundoc-usage): Don't add `Not documented'.
(help-function-arglist): Handle closures, subroutines, and new
byte-code-functions.
(help-make-usage): Remove leading underscores.
(describe-function-1): Handle closures.
(describe-variable): Use special-variable-p for completion.
* lisp/simple.el (with-wrapper-hook, apply-partially): Move to subr.el.
* lisp/subr.el (apply-partially): Use new closures rather than CL.
(--dolist-tail--, --dotimes-limit--): Don't declare dynamic.
(dolist, dotimes): Use slightly different expansion for lexical code.
(functionp): Move to C.
(letrec): New macro.
(with-wrapper-hook): Use it and apply-partially instead of CL.
(eval-after-load): Preserve lexical-binding.
(save-window-excursion, with-output-to-temp-buffer): Turn them
into macros.
* lisp/emacs-lisp/advice.el (ad-arglist): Use help-function-arglist.
* lisp/emacs-lisp/autoload.el (make-autoload): Don't burp on trivial macros.
* lisp/emacs-lisp/byte-opt.el: Use lexical binding.
(byte-inline-lapcode): Remove (to bytecomp).
(byte-compile-inline-expand): Pay attention to inlining to/from
lexically bound code.
(byte-compile-unfold-lambda): Don't handle byte-code-functions
any more.
(byte-optimize-form-code-walker): Don't handle save-window-excursion
any more and don't call compiler-macros.
(byte-compile-splice-in-already-compiled-code): Remove.
(byte-code): Don't inline any more.
(disassemble-offset): Receive `bytes' as argument rather than via
dynamic scoping.
(byte-compile-tag-number): Declare before first use.
(byte-decompile-bytecode-1): Handle new byte-codes, don't change
`return' even if make-spliceable.
(byte-compile-side-effect-and-error-free-ops): Add stack-ref, remove
obsolete interactive-p.
(byte-optimize-lapcode): Optimize new lap-codes.
Don't trip up on new form of `byte-constant' lap code.
* lisp/emacs-lisp/byte-run.el (make-obsolete): Don't set the `byte-compile'
handler any more.
* lisp/emacs-lisp/bytecomp.el: Use lexical binding instead of
a "bytecomp-" prefix. Macroexpand everything as a separate phase.
(byte-compile-initial-macro-environment):
Handle declare-function here.
(byte-compile--lexical-environment): New var.
(byte-stack-ref, byte-stack-set, byte-discardN)
(byte-discardN-preserve-tos): New lap codes.
(byte-interactive-p): Don't use any more.
(byte-compile-push-bytecodes, byte-compile-push-bytecode-const2):
New macros.
(byte-compile-lapcode): Use them and handle new lap codes.
(byte-compile-obsolete): Remove.
(byte-compile-arglist-signature): Handle new byte-code arg"lists".
(byte-compile-arglist-warn): Check late def of inlinable funs.
(byte-compile-cl-warn): Don't silence warnings for compiler-macros
since they should have been expanded by now.
(byte-compile--outbuffer): Rename from bytecomp-outbuffer.
(byte-compile-from-buffer): Remove unused second arg.
(byte-compile-preprocess): New function.
(byte-compile-toplevel-file-form): New function to distinguish
file-form calls from outside from file-form calls from hunk-handlers.
(byte-compile-file-form): Simplify.
(byte-compile-file-form-defsubst): Remove.
(byte-compile-file-form-defmumble): Simplify now that
byte-compile-lambda always returns a byte-code-function.
(byte-compile): Preprocess.
(byte-compile-byte-code-maker, byte-compile-byte-code-unmake):
Remove, not used any more.
(byte-compile-arglist-vars, byte-compile-make-lambda-lexenv)
(byte-compile-make-args-desc): New funs.
(byte-compile-lambda): Handle lexical functions. Always return
a byte-code-function.
(byte-compile-reserved-constants): New var, to make up room for
closed-over variables.
(byte-compile-constants-vector): Obey it.
(byte-compile-top-level): New args `lexenv' and `reserved-csts'.
(byte-compile-macroexpand-declare-function): New function.
(byte-compile-form): Call byte-compile-unfold-bcf to inline immediate
byte-code-functions.
(byte-compile-form): Check obsolescence here.
(byte-compile-inline-lapcode, byte-compile-unfold-bcf): New functions.
(byte-compile-variable-ref): Remove.
(byte-compile-dynamic-variable-op): New fun.
(byte-compile-dynamic-variable-bind, byte-compile-variable-ref)
(byte-compile-variable-set): New funs.
(byte-compile-discard): Add 2 args.
(byte-compile-stack-ref, byte-compile-stack-set)
(byte-compile-make-closure, byte-compile-get-closed-var): New funs.
(byte-compile-funarg, byte-compile-funarg-2): Remove, handled in
macroexpand-all instead.
(byte-compile-quote-form): Remove.
(byte-compile-push-binding-init, byte-compile-not-lexical-var-p)
(byte-compile-bind, byte-compile-unbind): New funs.
(byte-compile-let): Handle let* and lexical binding.
(byte-compile-let*): Remove.
(byte-compile-catch, byte-compile-unwind-protect)
(byte-compile-track-mouse, byte-compile-condition-case):
Handle a new :fun-body form, used for lexical scoping.
(byte-compile-save-window-excursion)
(byte-compile-with-output-to-temp-buffer): Remove.
(byte-compile-defun): Simplify.
(byte-compile-stack-adjustment): New fun.
(byte-compile-out): Use it.
(byte-compile-refresh-preloaded): Don't reload byte-compiler files.
* lisp/emacs-lisp/cconv.el: New file.
* lisp/emacs-lisp/cl-extra.el (cl-macroexpand-all): Properly quote CL
closures.
* lisp/emacs-lisp/cl-macs.el (cl-byte-compile-block)
(cl-byte-compile-throw): Remove.
(cl-block-wrapper, cl-block-throw): Use compiler-macros instead.
* lisp/emacs-lisp/cl.el (pushnew): Silence warning.
* lisp/emacs-lisp/disass.el (disassemble-internal): Handle new
`closure' objects.
(disassemble-1): Handle new byte codes.
* lisp/emacs-lisp/edebug.el (edebug-eval-defun)
(edebug-eval-top-level-form): Use eval-sexp-add-defvars.
(edebug-toggle): Avoid `eval'.
* lisp/emacs-lisp/eieio-comp.el: Remove.
* lisp/emacs-lisp/eieio.el (byte-compile-file-form-defmethod):
Don't autoload.
(eieio-defgeneric-form-primary-only-one): Use `byte-compile' rather
than the internal `byte-compile-lambda'.
(defmethod): Don't hide code under quotes.
(eieio-defmethod): New `code' argument.
* lisp/emacs-lisp/float-sup.el (pi): Don't declare as dynamically bound.
* lisp/emacs-lisp/lisp-mode.el (eval-last-sexp-1):
Use eval-sexp-add-defvars.
(eval-sexp-add-defvars): New fun.
* lisp/emacs-lisp/macroexp.el: Use lexical binding.
(macroexpand-all-1): Check obsolete macros. Expand compiler-macros.
Don't convert ' to #' without checking that it's indeed quoting
a lambda.
* lisp/emacs-lisp/pcase.el: Don't use destructuring-bind.
(pcase--memoize): Rename from pcase-memoize. Change weakness.
(pcase): Add `let' pattern.
Change memoization so it actually works.
(pcase-mutually-exclusive-predicates): Add byte-code-function-p.
(pcase--u1) <guard, pred>: Fix possible shadowing problem.
<let>: New case.
* src/alloc.c (Fmake_symbol): Init new `declared_special' field.
* src/buffer.c (defvar_per_buffer): Set new `declared_special' field.
* src/bytecode.c (Bstack_ref, Bstack_set, Bstack_set2, BdiscardN):
New byte-codes.
(exec_byte_code): New function extracted from Fbyte_code to handle new
calling convention for byte-code-functions. Add new byte-codes.
* src/callint.c (Fcall_interactively): Preserve lexical-binding mode for
interactive spec.
* src/doc.c (Fdocumentation, store_function_docstring):
* src/data.c (Finteractive_form): Handle closures.
* src/eval.c (Fsetq): Handle lexical vars.
(Fdefun, Fdefmacro, Ffunction): Make closures when needed.
(Fdefconst, Fdefvaralias, Fdefvar): Mark as dynamic.
(FletX, Flet): Obey lexical binding.
(Fcommandp): Handle closures.
(Feval): New `lexical' arg.
(eval_sub): New function extracted from Feval. Use it almost
everywhere where Feval was used. Look up vars in lexical env.
Handle closures.
(Ffunctionp): Move from subr.el.
(Ffuncall): Handle closures.
(apply_lambda): Remove `eval_flags'.
(funcall_lambda): Handle closures and new byte-code-functions.
(Fspecial_variable_p): New function.
(syms_of_eval): Initialize the Vinternal_interpreter_environment var,
but without exporting it to Lisp.
* src/fns.c (concat, mapcar1): Accept byte-code-functions.
* src/image.c (parse_image_spec): Use Ffunctionp.
* src/keyboard.c (eval_dyn): New fun.
(menu_item_eval_property): Use it.
* src/lisp.h (struct Lisp_Symbol): New field `declared_special'.
* src/lread.c (lisp_file_lexically_bound_p): New function.
(Fload): Bind Qlexical_binding.
(readevalloop): Remove `evalfun' arg.
Bind Qinternal_interpreter_environment.
(Feval_buffer): Bind Qlexical_binding.
(defvar_int, defvar_bool, defvar_lisp_nopro, defvar_kboard):
Mark as dynamic.
(syms_of_lread): Declare `lexical-binding'.
* src/window.c (Ftemp_output_buffer_show): New fun.
(Fsave_window_excursion):
* src/print.c (Fwith_output_to_temp_buffer): Move to subr.el.
Diffstat (limited to 'src/lread.c')
| -rw-r--r-- | src/lread.c | 162 |
1 files changed, 154 insertions, 8 deletions
diff --git a/src/lread.c b/src/lread.c index a5fd1513c39..6a24569f552 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -73,6 +73,7 @@ Lisp_Object Qascii_character, Qload, Qload_file_name; | |||
| 73 | Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction; | 73 | Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction; |
| 74 | Lisp_Object Qinhibit_file_name_operation; | 74 | Lisp_Object Qinhibit_file_name_operation; |
| 75 | Lisp_Object Qeval_buffer_list; | 75 | Lisp_Object Qeval_buffer_list; |
| 76 | Lisp_Object Qlexical_binding; | ||
| 76 | Lisp_Object Qfile_truename, Qdo_after_load_evaluation; /* ACM 2006/5/16 */ | 77 | Lisp_Object Qfile_truename, Qdo_after_load_evaluation; /* ACM 2006/5/16 */ |
| 77 | 78 | ||
| 78 | /* Used instead of Qget_file_char while loading *.elc files compiled | 79 | /* Used instead of Qget_file_char while loading *.elc files compiled |
| @@ -81,6 +82,8 @@ static Lisp_Object Qget_emacs_mule_file_char; | |||
| 81 | 82 | ||
| 82 | static Lisp_Object Qload_force_doc_strings; | 83 | static Lisp_Object Qload_force_doc_strings; |
| 83 | 84 | ||
| 85 | extern Lisp_Object Qinternal_interpreter_environment; | ||
| 86 | |||
| 84 | static Lisp_Object Qload_in_progress; | 87 | static Lisp_Object Qload_in_progress; |
| 85 | 88 | ||
| 86 | /* The association list of objects read with the #n=object form. | 89 | /* The association list of objects read with the #n=object form. |
| @@ -147,8 +150,7 @@ static Lisp_Object Vloads_in_progress; | |||
| 147 | static int read_emacs_mule_char (int, int (*) (int, Lisp_Object), | 150 | static int read_emacs_mule_char (int, int (*) (int, Lisp_Object), |
| 148 | Lisp_Object); | 151 | Lisp_Object); |
| 149 | 152 | ||
| 150 | static void readevalloop (Lisp_Object, FILE*, Lisp_Object, | 153 | static void readevalloop (Lisp_Object, FILE*, Lisp_Object, int, |
| 151 | Lisp_Object (*) (Lisp_Object), int, | ||
| 152 | Lisp_Object, Lisp_Object, | 154 | Lisp_Object, Lisp_Object, |
| 153 | Lisp_Object, Lisp_Object); | 155 | Lisp_Object, Lisp_Object); |
| 154 | static Lisp_Object load_unwind (Lisp_Object); | 156 | static Lisp_Object load_unwind (Lisp_Object); |
| @@ -769,6 +771,116 @@ DEFUN ("get-file-char", Fget_file_char, Sget_file_char, 0, 0, 0, | |||
| 769 | 771 | ||
| 770 | 772 | ||
| 771 | 773 | ||
| 774 | |||
| 775 | /* Return true if the lisp code read using READCHARFUN defines a non-nil | ||
| 776 | `lexical-binding' file variable. After returning, the stream is | ||
| 777 | positioned following the first line, if it is a comment, otherwise | ||
| 778 | nothing is read. */ | ||
| 779 | |||
| 780 | static int | ||
| 781 | lisp_file_lexically_bound_p (Lisp_Object readcharfun) | ||
| 782 | { | ||
| 783 | int ch = READCHAR; | ||
| 784 | if (ch != ';') | ||
| 785 | /* The first line isn't a comment, just give up. */ | ||
| 786 | { | ||
| 787 | UNREAD (ch); | ||
| 788 | return 0; | ||
| 789 | } | ||
| 790 | else | ||
| 791 | /* Look for an appropriate file-variable in the first line. */ | ||
| 792 | { | ||
| 793 | int rv = 0; | ||
| 794 | enum { | ||
| 795 | NOMINAL, AFTER_FIRST_DASH, AFTER_ASTERIX, | ||
| 796 | } beg_end_state = NOMINAL; | ||
| 797 | int in_file_vars = 0; | ||
| 798 | |||
| 799 | #define UPDATE_BEG_END_STATE(ch) \ | ||
| 800 | if (beg_end_state == NOMINAL) \ | ||
| 801 | beg_end_state = (ch == '-' ? AFTER_FIRST_DASH : NOMINAL); \ | ||
| 802 | else if (beg_end_state == AFTER_FIRST_DASH) \ | ||
| 803 | beg_end_state = (ch == '*' ? AFTER_ASTERIX : NOMINAL); \ | ||
| 804 | else if (beg_end_state == AFTER_ASTERIX) \ | ||
| 805 | { \ | ||
| 806 | if (ch == '-') \ | ||
| 807 | in_file_vars = !in_file_vars; \ | ||
| 808 | beg_end_state = NOMINAL; \ | ||
| 809 | } | ||
| 810 | |||
| 811 | /* Skip until we get to the file vars, if any. */ | ||
| 812 | do | ||
| 813 | { | ||
| 814 | ch = READCHAR; | ||
| 815 | UPDATE_BEG_END_STATE (ch); | ||
| 816 | } | ||
| 817 | while (!in_file_vars && ch != '\n' && ch != EOF); | ||
| 818 | |||
| 819 | while (in_file_vars) | ||
| 820 | { | ||
| 821 | char var[100], *var_end, val[100], *val_end; | ||
| 822 | |||
| 823 | ch = READCHAR; | ||
| 824 | |||
| 825 | /* Read a variable name. */ | ||
| 826 | while (ch == ' ' || ch == '\t') | ||
| 827 | ch = READCHAR; | ||
| 828 | |||
| 829 | var_end = var; | ||
| 830 | while (ch != ':' && ch != '\n' && ch != EOF) | ||
| 831 | { | ||
| 832 | if (var_end < var + sizeof var - 1) | ||
| 833 | *var_end++ = ch; | ||
| 834 | UPDATE_BEG_END_STATE (ch); | ||
| 835 | ch = READCHAR; | ||
| 836 | } | ||
| 837 | |||
| 838 | while (var_end > var | ||
| 839 | && (var_end[-1] == ' ' || var_end[-1] == '\t')) | ||
| 840 | var_end--; | ||
| 841 | *var_end = '\0'; | ||
| 842 | |||
| 843 | if (ch == ':') | ||
| 844 | { | ||
| 845 | /* Read a variable value. */ | ||
| 846 | ch = READCHAR; | ||
| 847 | |||
| 848 | while (ch == ' ' || ch == '\t') | ||
| 849 | ch = READCHAR; | ||
| 850 | |||
| 851 | val_end = val; | ||
| 852 | while (ch != ';' && ch != '\n' && ch != EOF && in_file_vars) | ||
| 853 | { | ||
| 854 | if (val_end < val + sizeof val - 1) | ||
| 855 | *val_end++ = ch; | ||
| 856 | UPDATE_BEG_END_STATE (ch); | ||
| 857 | ch = READCHAR; | ||
| 858 | } | ||
| 859 | if (! in_file_vars) | ||
| 860 | /* The value was terminated by an end-marker, which | ||
| 861 | remove. */ | ||
| 862 | val_end -= 3; | ||
| 863 | while (val_end > val | ||
| 864 | && (val_end[-1] == ' ' || val_end[-1] == '\t')) | ||
| 865 | val_end--; | ||
| 866 | *val_end = '\0'; | ||
| 867 | |||
| 868 | if (strcmp (var, "lexical-binding") == 0) | ||
| 869 | /* This is it... */ | ||
| 870 | { | ||
| 871 | rv = (strcmp (val, "nil") != 0); | ||
| 872 | break; | ||
| 873 | } | ||
| 874 | } | ||
| 875 | } | ||
| 876 | |||
| 877 | while (ch != '\n' && ch != EOF) | ||
| 878 | ch = READCHAR; | ||
| 879 | |||
| 880 | return rv; | ||
| 881 | } | ||
| 882 | } | ||
| 883 | |||
| 772 | /* Value is a version number of byte compiled code if the file | 884 | /* Value is a version number of byte compiled code if the file |
| 773 | associated with file descriptor FD is a compiled Lisp file that's | 885 | associated with file descriptor FD is a compiled Lisp file that's |
| 774 | safe to load. Only files compiled with Emacs are safe to load. | 886 | safe to load. Only files compiled with Emacs are safe to load. |
| @@ -1033,6 +1145,12 @@ Return t if the file exists and loads successfully. */) | |||
| 1033 | Vloads_in_progress = Fcons (found, Vloads_in_progress); | 1145 | Vloads_in_progress = Fcons (found, Vloads_in_progress); |
| 1034 | } | 1146 | } |
| 1035 | 1147 | ||
| 1148 | /* All loads are by default dynamic, unless the file itself specifies | ||
| 1149 | otherwise using a file-variable in the first line. This is bound here | ||
| 1150 | so that it takes effect whether or not we use | ||
| 1151 | Vload_source_file_function. */ | ||
| 1152 | specbind (Qlexical_binding, Qnil); | ||
| 1153 | |||
| 1036 | /* Get the name for load-history. */ | 1154 | /* Get the name for load-history. */ |
| 1037 | hist_file_name = (! NILP (Vpurify_flag) | 1155 | hist_file_name = (! NILP (Vpurify_flag) |
| 1038 | ? Fconcat (2, (tmp[0] = Ffile_name_directory (file), | 1156 | ? Fconcat (2, (tmp[0] = Ffile_name_directory (file), |
| @@ -1157,15 +1275,20 @@ Return t if the file exists and loads successfully. */) | |||
| 1157 | load_descriptor_list | 1275 | load_descriptor_list |
| 1158 | = Fcons (make_number (fileno (stream)), load_descriptor_list); | 1276 | = Fcons (make_number (fileno (stream)), load_descriptor_list); |
| 1159 | specbind (Qload_in_progress, Qt); | 1277 | specbind (Qload_in_progress, Qt); |
| 1278 | |||
| 1279 | instream = stream; | ||
| 1280 | if (lisp_file_lexically_bound_p (Qget_file_char)) | ||
| 1281 | Fset (Qlexical_binding, Qt); | ||
| 1282 | |||
| 1160 | if (! version || version >= 22) | 1283 | if (! version || version >= 22) |
| 1161 | readevalloop (Qget_file_char, stream, hist_file_name, | 1284 | readevalloop (Qget_file_char, stream, hist_file_name, |
| 1162 | Feval, 0, Qnil, Qnil, Qnil, Qnil); | 1285 | 0, Qnil, Qnil, Qnil, Qnil); |
| 1163 | else | 1286 | else |
| 1164 | { | 1287 | { |
| 1165 | /* We can't handle a file which was compiled with | 1288 | /* We can't handle a file which was compiled with |
| 1166 | byte-compile-dynamic by older version of Emacs. */ | 1289 | byte-compile-dynamic by older version of Emacs. */ |
| 1167 | specbind (Qload_force_doc_strings, Qt); | 1290 | specbind (Qload_force_doc_strings, Qt); |
| 1168 | readevalloop (Qget_emacs_mule_file_char, stream, hist_file_name, Feval, | 1291 | readevalloop (Qget_emacs_mule_file_char, stream, hist_file_name, |
| 1169 | 0, Qnil, Qnil, Qnil, Qnil); | 1292 | 0, Qnil, Qnil, Qnil, Qnil); |
| 1170 | } | 1293 | } |
| 1171 | unbind_to (count, Qnil); | 1294 | unbind_to (count, Qnil); |
| @@ -1535,7 +1658,6 @@ static void | |||
| 1535 | readevalloop (Lisp_Object readcharfun, | 1658 | readevalloop (Lisp_Object readcharfun, |
| 1536 | FILE *stream, | 1659 | FILE *stream, |
| 1537 | Lisp_Object sourcename, | 1660 | Lisp_Object sourcename, |
| 1538 | Lisp_Object (*evalfun) (Lisp_Object), | ||
| 1539 | int printflag, | 1661 | int printflag, |
| 1540 | Lisp_Object unibyte, Lisp_Object readfun, | 1662 | Lisp_Object unibyte, Lisp_Object readfun, |
| 1541 | Lisp_Object start, Lisp_Object end) | 1663 | Lisp_Object start, Lisp_Object end) |
| @@ -1546,6 +1668,7 @@ readevalloop (Lisp_Object readcharfun, | |||
| 1546 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 1668 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 1547 | struct buffer *b = 0; | 1669 | struct buffer *b = 0; |
| 1548 | int continue_reading_p; | 1670 | int continue_reading_p; |
| 1671 | Lisp_Object lex_bound; | ||
| 1549 | /* Nonzero if reading an entire buffer. */ | 1672 | /* Nonzero if reading an entire buffer. */ |
| 1550 | int whole_buffer = 0; | 1673 | int whole_buffer = 0; |
| 1551 | /* 1 on the first time around. */ | 1674 | /* 1 on the first time around. */ |
| @@ -1571,6 +1694,14 @@ readevalloop (Lisp_Object readcharfun, | |||
| 1571 | record_unwind_protect (readevalloop_1, load_convert_to_unibyte ? Qt : Qnil); | 1694 | record_unwind_protect (readevalloop_1, load_convert_to_unibyte ? Qt : Qnil); |
| 1572 | load_convert_to_unibyte = !NILP (unibyte); | 1695 | load_convert_to_unibyte = !NILP (unibyte); |
| 1573 | 1696 | ||
| 1697 | /* If lexical binding is active (either because it was specified in | ||
| 1698 | the file's header, or via a buffer-local variable), create an empty | ||
| 1699 | lexical environment, otherwise, turn off lexical binding. */ | ||
| 1700 | lex_bound = find_symbol_value (Qlexical_binding); | ||
| 1701 | specbind (Qinternal_interpreter_environment, | ||
| 1702 | NILP (lex_bound) || EQ (lex_bound, Qunbound) | ||
| 1703 | ? Qnil : Fcons (Qt, Qnil)); | ||
| 1704 | |||
| 1574 | GCPRO4 (sourcename, readfun, start, end); | 1705 | GCPRO4 (sourcename, readfun, start, end); |
| 1575 | 1706 | ||
| 1576 | /* Try to ensure sourcename is a truename, except whilst preloading. */ | 1707 | /* Try to ensure sourcename is a truename, except whilst preloading. */ |
| @@ -1672,7 +1803,7 @@ readevalloop (Lisp_Object readcharfun, | |||
| 1672 | unbind_to (count1, Qnil); | 1803 | unbind_to (count1, Qnil); |
| 1673 | 1804 | ||
| 1674 | /* Now eval what we just read. */ | 1805 | /* Now eval what we just read. */ |
| 1675 | val = (*evalfun) (val); | 1806 | val = eval_sub (val); |
| 1676 | 1807 | ||
| 1677 | if (printflag) | 1808 | if (printflag) |
| 1678 | { | 1809 | { |
| @@ -1732,7 +1863,8 @@ This function preserves the position of point. */) | |||
| 1732 | specbind (Qstandard_output, tem); | 1863 | specbind (Qstandard_output, tem); |
| 1733 | record_unwind_protect (save_excursion_restore, save_excursion_save ()); | 1864 | record_unwind_protect (save_excursion_restore, save_excursion_save ()); |
| 1734 | BUF_TEMP_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf))); | 1865 | BUF_TEMP_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf))); |
| 1735 | readevalloop (buf, 0, filename, Feval, | 1866 | specbind (Qlexical_binding, lisp_file_lexically_bound_p (buf) ? Qt : Qnil); |
| 1867 | readevalloop (buf, 0, filename, | ||
| 1736 | !NILP (printflag), unibyte, Qnil, Qnil, Qnil); | 1868 | !NILP (printflag), unibyte, Qnil, Qnil, Qnil); |
| 1737 | unbind_to (count, Qnil); | 1869 | unbind_to (count, Qnil); |
| 1738 | 1870 | ||
| @@ -1753,6 +1885,7 @@ which is the input stream for reading characters. | |||
| 1753 | This function does not move point. */) | 1885 | This function does not move point. */) |
| 1754 | (Lisp_Object start, Lisp_Object end, Lisp_Object printflag, Lisp_Object read_function) | 1886 | (Lisp_Object start, Lisp_Object end, Lisp_Object printflag, Lisp_Object read_function) |
| 1755 | { | 1887 | { |
| 1888 | /* FIXME: Do the eval-sexp-add-defvars danse! */ | ||
| 1756 | int count = SPECPDL_INDEX (); | 1889 | int count = SPECPDL_INDEX (); |
| 1757 | Lisp_Object tem, cbuf; | 1890 | Lisp_Object tem, cbuf; |
| 1758 | 1891 | ||
| @@ -1766,7 +1899,7 @@ This function does not move point. */) | |||
| 1766 | specbind (Qeval_buffer_list, Fcons (cbuf, Veval_buffer_list)); | 1899 | specbind (Qeval_buffer_list, Fcons (cbuf, Veval_buffer_list)); |
| 1767 | 1900 | ||
| 1768 | /* readevalloop calls functions which check the type of start and end. */ | 1901 | /* readevalloop calls functions which check the type of start and end. */ |
| 1769 | readevalloop (cbuf, 0, BVAR (XBUFFER (cbuf), filename), Feval, | 1902 | readevalloop (cbuf, 0, BVAR (XBUFFER (cbuf), filename), |
| 1770 | !NILP (printflag), Qnil, read_function, | 1903 | !NILP (printflag), Qnil, read_function, |
| 1771 | start, end); | 1904 | start, end); |
| 1772 | 1905 | ||
| @@ -3838,6 +3971,7 @@ defvar_int (struct Lisp_Intfwd *i_fwd, | |||
| 3838 | sym = intern_c_string (namestring); | 3971 | sym = intern_c_string (namestring); |
| 3839 | i_fwd->type = Lisp_Fwd_Int; | 3972 | i_fwd->type = Lisp_Fwd_Int; |
| 3840 | i_fwd->intvar = address; | 3973 | i_fwd->intvar = address; |
| 3974 | XSYMBOL (sym)->declared_special = 1; | ||
| 3841 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; | 3975 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; |
| 3842 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)i_fwd); | 3976 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)i_fwd); |
| 3843 | } | 3977 | } |
| @@ -3852,6 +3986,7 @@ defvar_bool (struct Lisp_Boolfwd *b_fwd, | |||
| 3852 | sym = intern_c_string (namestring); | 3986 | sym = intern_c_string (namestring); |
| 3853 | b_fwd->type = Lisp_Fwd_Bool; | 3987 | b_fwd->type = Lisp_Fwd_Bool; |
| 3854 | b_fwd->boolvar = address; | 3988 | b_fwd->boolvar = address; |
| 3989 | XSYMBOL (sym)->declared_special = 1; | ||
| 3855 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; | 3990 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; |
| 3856 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)b_fwd); | 3991 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)b_fwd); |
| 3857 | Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); | 3992 | Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); |
| @@ -3870,6 +4005,7 @@ defvar_lisp_nopro (struct Lisp_Objfwd *o_fwd, | |||
| 3870 | sym = intern_c_string (namestring); | 4005 | sym = intern_c_string (namestring); |
| 3871 | o_fwd->type = Lisp_Fwd_Obj; | 4006 | o_fwd->type = Lisp_Fwd_Obj; |
| 3872 | o_fwd->objvar = address; | 4007 | o_fwd->objvar = address; |
| 4008 | XSYMBOL (sym)->declared_special = 1; | ||
| 3873 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; | 4009 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; |
| 3874 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)o_fwd); | 4010 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)o_fwd); |
| 3875 | } | 4011 | } |
| @@ -3893,6 +4029,7 @@ defvar_kboard (struct Lisp_Kboard_Objfwd *ko_fwd, | |||
| 3893 | sym = intern_c_string (namestring); | 4029 | sym = intern_c_string (namestring); |
| 3894 | ko_fwd->type = Lisp_Fwd_Kboard_Obj; | 4030 | ko_fwd->type = Lisp_Fwd_Kboard_Obj; |
| 3895 | ko_fwd->offset = offset; | 4031 | ko_fwd->offset = offset; |
| 4032 | XSYMBOL (sym)->declared_special = 1; | ||
| 3896 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; | 4033 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; |
| 3897 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd); | 4034 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd); |
| 3898 | } | 4035 | } |
| @@ -4320,6 +4457,15 @@ to load. See also `load-dangerous-libraries'. */); | |||
| 4320 | Vbytecomp_version_regexp | 4457 | Vbytecomp_version_regexp |
| 4321 | = make_pure_c_string ("^;;;.\\(in Emacs version\\|bytecomp version FSF\\)"); | 4458 | = make_pure_c_string ("^;;;.\\(in Emacs version\\|bytecomp version FSF\\)"); |
| 4322 | 4459 | ||
| 4460 | Qlexical_binding = intern ("lexical-binding"); | ||
| 4461 | staticpro (&Qlexical_binding); | ||
| 4462 | DEFVAR_LISP ("lexical-binding", Vlexical_binding, | ||
| 4463 | doc: /* If non-nil, use lexical binding when evaluating code. | ||
| 4464 | This only applies to code evaluated by `eval-buffer' and `eval-region'. | ||
| 4465 | This variable is automatically set from the file variables of an interpreted | ||
| 4466 | Lisp file read using `load'. */); | ||
| 4467 | Fmake_variable_buffer_local (Qlexical_binding); | ||
| 4468 | |||
| 4323 | DEFVAR_LISP ("eval-buffer-list", Veval_buffer_list, | 4469 | DEFVAR_LISP ("eval-buffer-list", Veval_buffer_list, |
| 4324 | doc: /* List of buffers being read from by calls to `eval-buffer' and `eval-region'. */); | 4470 | doc: /* List of buffers being read from by calls to `eval-buffer' and `eval-region'. */); |
| 4325 | Veval_buffer_list = Qnil; | 4471 | Veval_buffer_list = Qnil; |