diff options
| author | Paul Eggert | 2011-04-01 13:19:36 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-04-01 13:19:36 -0700 |
| commit | 6ddae4efd9e8a3035eb610c39fb2c8f79e7f9893 (patch) | |
| tree | 1b704b34e4f2f2bd4a6f13e4d1dd058c61c8a6ff /src | |
| parent | 0b918413f336dbfa9a9c266ae857bce103556c57 (diff) | |
| parent | 034086489cff2a23cb4d9f8c536e18456be617ef (diff) | |
| download | emacs-6ddae4efd9e8a3035eb610c39fb2c8f79e7f9893.tar.gz emacs-6ddae4efd9e8a3035eb610c39fb2c8f79e7f9893.zip | |
Merge from mainline.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 58 | ||||
| -rw-r--r-- | src/alloc.c | 14 | ||||
| -rw-r--r-- | src/buffer.c | 1 | ||||
| -rw-r--r-- | src/bytecode.c | 163 | ||||
| -rw-r--r-- | src/callint.c | 13 | ||||
| -rw-r--r-- | src/data.c | 8 | ||||
| -rw-r--r-- | src/doc.c | 7 | ||||
| -rw-r--r-- | src/eval.c | 382 | ||||
| -rw-r--r-- | src/fns.c | 4 | ||||
| -rw-r--r-- | src/image.c | 4 | ||||
| -rw-r--r-- | src/keyboard.c | 12 | ||||
| -rw-r--r-- | src/lisp.h | 12 | ||||
| -rw-r--r-- | src/lread.c | 162 | ||||
| -rw-r--r-- | src/minibuf.c | 3 | ||||
| -rw-r--r-- | src/print.c | 57 | ||||
| -rw-r--r-- | src/window.c | 34 | ||||
| -rw-r--r-- | src/window.h | 1 |
17 files changed, 729 insertions, 206 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 99447fd8748..56400fbb08f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -35,6 +35,64 @@ | |||
| 35 | * deps.mk (sysdep.o): Depend on ../lib/allocator.h and on | 35 | * deps.mk (sysdep.o): Depend on ../lib/allocator.h and on |
| 36 | ../lib/careadlinkat.h. | 36 | ../lib/careadlinkat.h. |
| 37 | 37 | ||
| 38 | 2011-04-01 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 39 | |||
| 40 | Add lexical binding. | ||
| 41 | |||
| 42 | * window.c (Ftemp_output_buffer_show): New fun. | ||
| 43 | (Fsave_window_excursion): | ||
| 44 | * print.c (Fwith_output_to_temp_buffer): Move to subr.el. | ||
| 45 | |||
| 46 | * lread.c (lisp_file_lexically_bound_p): New function. | ||
| 47 | (Fload): Bind Qlexical_binding. | ||
| 48 | (readevalloop): Remove `evalfun' arg. | ||
| 49 | Bind Qinternal_interpreter_environment. | ||
| 50 | (Feval_buffer): Bind Qlexical_binding. | ||
| 51 | (defvar_int, defvar_bool, defvar_lisp_nopro, defvar_kboard): | ||
| 52 | Mark as dynamic. | ||
| 53 | (syms_of_lread): Declare `lexical-binding'. | ||
| 54 | |||
| 55 | * lisp.h (struct Lisp_Symbol): New field `declared_special'. | ||
| 56 | |||
| 57 | * keyboard.c (eval_dyn): New fun. | ||
| 58 | (menu_item_eval_property): Use it. | ||
| 59 | |||
| 60 | * image.c (parse_image_spec): Use Ffunctionp. | ||
| 61 | |||
| 62 | * fns.c (concat, mapcar1): Accept byte-code-functions. | ||
| 63 | |||
| 64 | * eval.c (Fsetq): Handle lexical vars. | ||
| 65 | (Fdefun, Fdefmacro, Ffunction): Make closures when needed. | ||
| 66 | (Fdefconst, Fdefvaralias, Fdefvar): Mark as dynamic. | ||
| 67 | (FletX, Flet): Obey lexical binding. | ||
| 68 | (Fcommandp): Handle closures. | ||
| 69 | (Feval): New `lexical' arg. | ||
| 70 | (eval_sub): New function extracted from Feval. Use it almost | ||
| 71 | everywhere where Feval was used. Look up vars in lexical env. | ||
| 72 | Handle closures. | ||
| 73 | (Ffunctionp): Move from subr.el. | ||
| 74 | (Ffuncall): Handle closures. | ||
| 75 | (apply_lambda): Remove `eval_flags'. | ||
| 76 | (funcall_lambda): Handle closures and new byte-code-functions. | ||
| 77 | (Fspecial_variable_p): New function. | ||
| 78 | (syms_of_eval): Initialize the Vinternal_interpreter_environment var, | ||
| 79 | but without exporting it to Lisp. | ||
| 80 | |||
| 81 | * doc.c (Fdocumentation, store_function_docstring): | ||
| 82 | * data.c (Finteractive_form): Handle closures. | ||
| 83 | |||
| 84 | * callint.c (Fcall_interactively): Preserve lexical-binding mode for | ||
| 85 | interactive spec. | ||
| 86 | |||
| 87 | * bytecode.c (Bstack_ref, Bstack_set, Bstack_set2, BdiscardN): New | ||
| 88 | byte-codes. | ||
| 89 | (exec_byte_code): New function extracted from Fbyte_code to handle new | ||
| 90 | calling convention for byte-code-functions. Add new byte-codes. | ||
| 91 | |||
| 92 | * buffer.c (defvar_per_buffer): Set new `declared_special' field. | ||
| 93 | |||
| 94 | * alloc.c (Fmake_symbol): Init new `declared_special' field. | ||
| 95 | |||
| 38 | 2011-03-31 Juanma Barranquero <lekktu@gmail.com> | 96 | 2011-03-31 Juanma Barranquero <lekktu@gmail.com> |
| 39 | 97 | ||
| 40 | * xdisp.c (redisplay_internal): Fix prototype. | 98 | * xdisp.c (redisplay_internal): Fix prototype. |
diff --git a/src/alloc.c b/src/alloc.c index 177a2266fb6..07f1caae46b 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -2940,10 +2940,19 @@ usage: (vector &rest OBJECTS) */) | |||
| 2940 | 2940 | ||
| 2941 | DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, | 2941 | DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, |
| 2942 | doc: /* Create a byte-code object with specified arguments as elements. | 2942 | doc: /* Create a byte-code object with specified arguments as elements. |
| 2943 | The arguments should be the arglist, bytecode-string, constant vector, | 2943 | The arguments should be the ARGLIST, bytecode-string BYTE-CODE, constant |
| 2944 | stack size, (optional) doc string, and (optional) interactive spec. | 2944 | vector CONSTANTS, maximum stack size DEPTH, (optional) DOCSTRING, |
| 2945 | and (optional) INTERACTIVE-SPEC. | ||
| 2945 | The first four arguments are required; at most six have any | 2946 | The first four arguments are required; at most six have any |
| 2946 | significance. | 2947 | significance. |
| 2948 | The ARGLIST can be either like the one of `lambda', in which case the arguments | ||
| 2949 | will be dynamically bound before executing the byte code, or it can be an | ||
| 2950 | integer of the form NNNNNNNRMMMMMMM where the 7bit MMMMMMM specifies the | ||
| 2951 | minimum number of arguments, the 7-bit NNNNNNN specifies the maximum number | ||
| 2952 | of arguments (ignoring &rest) and the R bit specifies whether there is a &rest | ||
| 2953 | argument to catch the left-over arguments. If such an integer is used, the | ||
| 2954 | arguments will not be dynamically bound but will be instead pushed on the | ||
| 2955 | stack before executing the byte-code. | ||
| 2947 | usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INTERACTIVE-SPEC &rest ELEMENTS) */) | 2956 | usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INTERACTIVE-SPEC &rest ELEMENTS) */) |
| 2948 | (register size_t nargs, Lisp_Object *args) | 2957 | (register size_t nargs, Lisp_Object *args) |
| 2949 | { | 2958 | { |
| @@ -3071,6 +3080,7 @@ Its value and function definition are void, and its property list is nil. */) | |||
| 3071 | p->gcmarkbit = 0; | 3080 | p->gcmarkbit = 0; |
| 3072 | p->interned = SYMBOL_UNINTERNED; | 3081 | p->interned = SYMBOL_UNINTERNED; |
| 3073 | p->constant = 0; | 3082 | p->constant = 0; |
| 3083 | p->declared_special = 0; | ||
| 3074 | consing_since_gc += sizeof (struct Lisp_Symbol); | 3084 | consing_since_gc += sizeof (struct Lisp_Symbol); |
| 3075 | symbols_consed++; | 3085 | symbols_consed++; |
| 3076 | return val; | 3086 | return val; |
diff --git a/src/buffer.c b/src/buffer.c index 8b56b285e48..cdcd2ccecff 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -5240,6 +5240,7 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, | |||
| 5240 | bo_fwd->type = Lisp_Fwd_Buffer_Obj; | 5240 | bo_fwd->type = Lisp_Fwd_Buffer_Obj; |
| 5241 | bo_fwd->offset = offset; | 5241 | bo_fwd->offset = offset; |
| 5242 | bo_fwd->slottype = type; | 5242 | bo_fwd->slottype = type; |
| 5243 | sym->declared_special = 1; | ||
| 5243 | sym->redirect = SYMBOL_FORWARDED; | 5244 | sym->redirect = SYMBOL_FORWARDED; |
| 5244 | { | 5245 | { |
| 5245 | /* I tried to do the job without a cast, but it seems impossible. | 5246 | /* I tried to do the job without a cast, but it seems impossible. |
diff --git a/src/bytecode.c b/src/bytecode.c index 5a62c913a40..5879d312b07 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -80,9 +80,11 @@ Lisp_Object Qbyte_code_meter; | |||
| 80 | 80 | ||
| 81 | 81 | ||
| 82 | Lisp_Object Qbytecode; | 82 | Lisp_Object Qbytecode; |
| 83 | extern Lisp_Object Qand_optional, Qand_rest; | ||
| 83 | 84 | ||
| 84 | /* Byte codes: */ | 85 | /* Byte codes: */ |
| 85 | 86 | ||
| 87 | #define Bstack_ref 0 /* Actually, Bstack_ref+0 is not implemented: use dup. */ | ||
| 86 | #define Bvarref 010 | 88 | #define Bvarref 010 |
| 87 | #define Bvarset 020 | 89 | #define Bvarset 020 |
| 88 | #define Bvarbind 030 | 90 | #define Bvarbind 030 |
| @@ -132,7 +134,7 @@ Lisp_Object Qbytecode; | |||
| 132 | 134 | ||
| 133 | #define Bpoint 0140 | 135 | #define Bpoint 0140 |
| 134 | /* Was Bmark in v17. */ | 136 | /* Was Bmark in v17. */ |
| 135 | #define Bsave_current_buffer 0141 | 137 | #define Bsave_current_buffer 0141 /* Obsolete. */ |
| 136 | #define Bgoto_char 0142 | 138 | #define Bgoto_char 0142 |
| 137 | #define Binsert 0143 | 139 | #define Binsert 0143 |
| 138 | #define Bpoint_max 0144 | 140 | #define Bpoint_max 0144 |
| @@ -158,7 +160,7 @@ Lisp_Object Qbytecode; | |||
| 158 | #ifdef BYTE_CODE_SAFE | 160 | #ifdef BYTE_CODE_SAFE |
| 159 | #define Bset_mark 0163 /* this loser is no longer generated as of v18 */ | 161 | #define Bset_mark 0163 /* this loser is no longer generated as of v18 */ |
| 160 | #endif | 162 | #endif |
| 161 | #define Binteractive_p 0164 /* Needed since interactive-p takes unevalled args */ | 163 | #define Binteractive_p 0164 /* Obsolete since Emacs-24.1. */ |
| 162 | 164 | ||
| 163 | #define Bforward_char 0165 | 165 | #define Bforward_char 0165 |
| 164 | #define Bforward_word 0166 | 166 | #define Bforward_word 0166 |
| @@ -183,16 +185,16 @@ Lisp_Object Qbytecode; | |||
| 183 | #define Bdup 0211 | 185 | #define Bdup 0211 |
| 184 | 186 | ||
| 185 | #define Bsave_excursion 0212 | 187 | #define Bsave_excursion 0212 |
| 186 | #define Bsave_window_excursion 0213 | 188 | #define Bsave_window_excursion 0213 /* Obsolete since Emacs-24.1. */ |
| 187 | #define Bsave_restriction 0214 | 189 | #define Bsave_restriction 0214 |
| 188 | #define Bcatch 0215 | 190 | #define Bcatch 0215 |
| 189 | 191 | ||
| 190 | #define Bunwind_protect 0216 | 192 | #define Bunwind_protect 0216 |
| 191 | #define Bcondition_case 0217 | 193 | #define Bcondition_case 0217 |
| 192 | #define Btemp_output_buffer_setup 0220 | 194 | #define Btemp_output_buffer_setup 0220 /* Obsolete since Emacs-24.1. */ |
| 193 | #define Btemp_output_buffer_show 0221 | 195 | #define Btemp_output_buffer_show 0221 /* Obsolete since Emacs-24.1. */ |
| 194 | 196 | ||
| 195 | #define Bunbind_all 0222 | 197 | #define Bunbind_all 0222 /* Obsolete. Never used. */ |
| 196 | 198 | ||
| 197 | #define Bset_marker 0223 | 199 | #define Bset_marker 0223 |
| 198 | #define Bmatch_beginning 0224 | 200 | #define Bmatch_beginning 0224 |
| @@ -228,6 +230,11 @@ Lisp_Object Qbytecode; | |||
| 228 | #define BconcatN 0260 | 230 | #define BconcatN 0260 |
| 229 | #define BinsertN 0261 | 231 | #define BinsertN 0261 |
| 230 | 232 | ||
| 233 | /* Bstack_ref is code 0. */ | ||
| 234 | #define Bstack_set 0262 | ||
| 235 | #define Bstack_set2 0263 | ||
| 236 | #define BdiscardN 0266 | ||
| 237 | |||
| 231 | #define Bconstant 0300 | 238 | #define Bconstant 0300 |
| 232 | 239 | ||
| 233 | /* Whether to maintain a `top' and `bottom' field in the stack frame. */ | 240 | /* Whether to maintain a `top' and `bottom' field in the stack frame. */ |
| @@ -414,6 +421,21 @@ the third, MAXDEPTH, the maximum stack depth used in this function. | |||
| 414 | If the third argument is incorrect, Emacs may crash. */) | 421 | If the third argument is incorrect, Emacs may crash. */) |
| 415 | (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth) | 422 | (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth) |
| 416 | { | 423 | { |
| 424 | return exec_byte_code (bytestr, vector, maxdepth, Qnil, 0, NULL); | ||
| 425 | } | ||
| 426 | |||
| 427 | /* Execute the byte-code in BYTESTR. VECTOR is the constant vector, and | ||
| 428 | MAXDEPTH is the maximum stack depth used (if MAXDEPTH is incorrect, | ||
| 429 | emacs may crash!). If ARGS_TEMPLATE is non-nil, it should be a lisp | ||
| 430 | argument list (including &rest, &optional, etc.), and ARGS, of size | ||
| 431 | NARGS, should be a vector of the actual arguments. The arguments in | ||
| 432 | ARGS are pushed on the stack according to ARGS_TEMPLATE before | ||
| 433 | executing BYTESTR. */ | ||
| 434 | |||
| 435 | Lisp_Object | ||
| 436 | exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | ||
| 437 | Lisp_Object args_template, int nargs, Lisp_Object *args) | ||
| 438 | { | ||
| 417 | int count = SPECPDL_INDEX (); | 439 | int count = SPECPDL_INDEX (); |
| 418 | #ifdef BYTE_CODE_METER | 440 | #ifdef BYTE_CODE_METER |
| 419 | int this_op = 0; | 441 | int this_op = 0; |
| @@ -475,6 +497,52 @@ If the third argument is incorrect, Emacs may crash. */) | |||
| 475 | stacke = stack.bottom - 1 + XFASTINT (maxdepth); | 497 | stacke = stack.bottom - 1 + XFASTINT (maxdepth); |
| 476 | #endif | 498 | #endif |
| 477 | 499 | ||
| 500 | if (INTEGERP (args_template)) | ||
| 501 | { | ||
| 502 | int at = XINT (args_template); | ||
| 503 | int rest = at & 128; | ||
| 504 | int mandatory = at & 127; | ||
| 505 | int nonrest = at >> 8; | ||
| 506 | eassert (mandatory <= nonrest); | ||
| 507 | if (nargs <= nonrest) | ||
| 508 | { | ||
| 509 | int i; | ||
| 510 | for (i = 0 ; i < nargs; i++, args++) | ||
| 511 | PUSH (*args); | ||
| 512 | if (nargs < mandatory) | ||
| 513 | /* Too few arguments. */ | ||
| 514 | Fsignal (Qwrong_number_of_arguments, | ||
| 515 | Fcons (Fcons (make_number (mandatory), | ||
| 516 | rest ? Qand_rest : make_number (nonrest)), | ||
| 517 | Fcons (make_number (nargs), Qnil))); | ||
| 518 | else | ||
| 519 | { | ||
| 520 | for (; i < nonrest; i++) | ||
| 521 | PUSH (Qnil); | ||
| 522 | if (rest) | ||
| 523 | PUSH (Qnil); | ||
| 524 | } | ||
| 525 | } | ||
| 526 | else if (rest) | ||
| 527 | { | ||
| 528 | int i; | ||
| 529 | for (i = 0 ; i < nonrest; i++, args++) | ||
| 530 | PUSH (*args); | ||
| 531 | PUSH (Flist (nargs - nonrest, args)); | ||
| 532 | } | ||
| 533 | else | ||
| 534 | /* Too many arguments. */ | ||
| 535 | Fsignal (Qwrong_number_of_arguments, | ||
| 536 | Fcons (Fcons (make_number (mandatory), | ||
| 537 | make_number (nonrest)), | ||
| 538 | Fcons (make_number (nargs), Qnil))); | ||
| 539 | } | ||
| 540 | else if (! NILP (args_template)) | ||
| 541 | /* We should push some arguments on the stack. */ | ||
| 542 | { | ||
| 543 | error ("Unknown args template!"); | ||
| 544 | } | ||
| 545 | |||
| 478 | while (1) | 546 | while (1) |
| 479 | { | 547 | { |
| 480 | #ifdef BYTE_CODE_SAFE | 548 | #ifdef BYTE_CODE_SAFE |
| @@ -735,7 +803,7 @@ If the third argument is incorrect, Emacs may crash. */) | |||
| 735 | AFTER_POTENTIAL_GC (); | 803 | AFTER_POTENTIAL_GC (); |
| 736 | break; | 804 | break; |
| 737 | 805 | ||
| 738 | case Bunbind_all: | 806 | case Bunbind_all: /* Obsolete. Never used. */ |
| 739 | /* To unbind back to the beginning of this frame. Not used yet, | 807 | /* To unbind back to the beginning of this frame. Not used yet, |
| 740 | but will be needed for tail-recursion elimination. */ | 808 | but will be needed for tail-recursion elimination. */ |
| 741 | BEFORE_POTENTIAL_GC (); | 809 | BEFORE_POTENTIAL_GC (); |
| @@ -863,37 +931,43 @@ If the third argument is incorrect, Emacs may crash. */) | |||
| 863 | save_excursion_save ()); | 931 | save_excursion_save ()); |
| 864 | break; | 932 | break; |
| 865 | 933 | ||
| 866 | case Bsave_current_buffer: | 934 | case Bsave_current_buffer: /* Obsolete since ??. */ |
| 867 | case Bsave_current_buffer_1: | 935 | case Bsave_current_buffer_1: |
| 868 | record_unwind_protect (set_buffer_if_live, Fcurrent_buffer ()); | 936 | record_unwind_protect (set_buffer_if_live, Fcurrent_buffer ()); |
| 869 | break; | 937 | break; |
| 870 | 938 | ||
| 871 | case Bsave_window_excursion: | 939 | case Bsave_window_excursion: /* Obsolete since 24.1. */ |
| 872 | BEFORE_POTENTIAL_GC (); | 940 | { |
| 873 | TOP = Fsave_window_excursion (TOP); | 941 | register int count = SPECPDL_INDEX (); |
| 874 | AFTER_POTENTIAL_GC (); | 942 | record_unwind_protect (Fset_window_configuration, |
| 875 | break; | 943 | Fcurrent_window_configuration (Qnil)); |
| 944 | BEFORE_POTENTIAL_GC (); | ||
| 945 | TOP = Fprogn (TOP); | ||
| 946 | unbind_to (count, TOP); | ||
| 947 | AFTER_POTENTIAL_GC (); | ||
| 948 | break; | ||
| 949 | } | ||
| 876 | 950 | ||
| 877 | case Bsave_restriction: | 951 | case Bsave_restriction: |
| 878 | record_unwind_protect (save_restriction_restore, | 952 | record_unwind_protect (save_restriction_restore, |
| 879 | save_restriction_save ()); | 953 | save_restriction_save ()); |
| 880 | break; | 954 | break; |
| 881 | 955 | ||
| 882 | case Bcatch: | 956 | case Bcatch: /* FIXME: ill-suited for lexbind */ |
| 883 | { | 957 | { |
| 884 | Lisp_Object v1; | 958 | Lisp_Object v1; |
| 885 | BEFORE_POTENTIAL_GC (); | 959 | BEFORE_POTENTIAL_GC (); |
| 886 | v1 = POP; | 960 | v1 = POP; |
| 887 | TOP = internal_catch (TOP, Feval, v1); | 961 | TOP = internal_catch (TOP, eval_sub, v1); |
| 888 | AFTER_POTENTIAL_GC (); | 962 | AFTER_POTENTIAL_GC (); |
| 889 | break; | 963 | break; |
| 890 | } | 964 | } |
| 891 | 965 | ||
| 892 | case Bunwind_protect: | 966 | case Bunwind_protect: /* FIXME: avoid closure for lexbind */ |
| 893 | record_unwind_protect (Fprogn, POP); | 967 | record_unwind_protect (Fprogn, POP); |
| 894 | break; | 968 | break; |
| 895 | 969 | ||
| 896 | case Bcondition_case: | 970 | case Bcondition_case: /* FIXME: ill-suited for lexbind */ |
| 897 | { | 971 | { |
| 898 | Lisp_Object handlers, body; | 972 | Lisp_Object handlers, body; |
| 899 | handlers = POP; | 973 | handlers = POP; |
| @@ -904,7 +978,7 @@ If the third argument is incorrect, Emacs may crash. */) | |||
| 904 | break; | 978 | break; |
| 905 | } | 979 | } |
| 906 | 980 | ||
| 907 | case Btemp_output_buffer_setup: | 981 | case Btemp_output_buffer_setup: /* Obsolete since 24.1. */ |
| 908 | BEFORE_POTENTIAL_GC (); | 982 | BEFORE_POTENTIAL_GC (); |
| 909 | CHECK_STRING (TOP); | 983 | CHECK_STRING (TOP); |
| 910 | temp_output_buffer_setup (SSDATA (TOP)); | 984 | temp_output_buffer_setup (SSDATA (TOP)); |
| @@ -912,7 +986,7 @@ If the third argument is incorrect, Emacs may crash. */) | |||
| 912 | TOP = Vstandard_output; | 986 | TOP = Vstandard_output; |
| 913 | break; | 987 | break; |
| 914 | 988 | ||
| 915 | case Btemp_output_buffer_show: | 989 | case Btemp_output_buffer_show: /* Obsolete since 24.1. */ |
| 916 | { | 990 | { |
| 917 | Lisp_Object v1; | 991 | Lisp_Object v1; |
| 918 | BEFORE_POTENTIAL_GC (); | 992 | BEFORE_POTENTIAL_GC (); |
| @@ -1384,7 +1458,7 @@ If the third argument is incorrect, Emacs may crash. */) | |||
| 1384 | AFTER_POTENTIAL_GC (); | 1458 | AFTER_POTENTIAL_GC (); |
| 1385 | break; | 1459 | break; |
| 1386 | 1460 | ||
| 1387 | case Binteractive_p: | 1461 | case Binteractive_p: /* Obsolete since 24.1. */ |
| 1388 | PUSH (Finteractive_p ()); | 1462 | PUSH (Finteractive_p ()); |
| 1389 | break; | 1463 | break; |
| 1390 | 1464 | ||
| @@ -1674,8 +1748,57 @@ If the third argument is incorrect, Emacs may crash. */) | |||
| 1674 | #endif | 1748 | #endif |
| 1675 | 1749 | ||
| 1676 | case 0: | 1750 | case 0: |
| 1751 | /* Actually this is Bstack_ref with offset 0, but we use Bdup | ||
| 1752 | for that instead. */ | ||
| 1753 | /* case Bstack_ref: */ | ||
| 1677 | abort (); | 1754 | abort (); |
| 1678 | 1755 | ||
| 1756 | /* Handy byte-codes for lexical binding. */ | ||
| 1757 | case Bstack_ref+1: | ||
| 1758 | case Bstack_ref+2: | ||
| 1759 | case Bstack_ref+3: | ||
| 1760 | case Bstack_ref+4: | ||
| 1761 | case Bstack_ref+5: | ||
| 1762 | { | ||
| 1763 | Lisp_Object *ptr = top - (op - Bstack_ref); | ||
| 1764 | PUSH (*ptr); | ||
| 1765 | break; | ||
| 1766 | } | ||
| 1767 | case Bstack_ref+6: | ||
| 1768 | { | ||
| 1769 | Lisp_Object *ptr = top - (FETCH); | ||
| 1770 | PUSH (*ptr); | ||
| 1771 | break; | ||
| 1772 | } | ||
| 1773 | case Bstack_ref+7: | ||
| 1774 | { | ||
| 1775 | Lisp_Object *ptr = top - (FETCH2); | ||
| 1776 | PUSH (*ptr); | ||
| 1777 | break; | ||
| 1778 | } | ||
| 1779 | /* stack-set-0 = discard; stack-set-1 = discard-1-preserve-tos. */ | ||
| 1780 | case Bstack_set: | ||
| 1781 | { | ||
| 1782 | Lisp_Object *ptr = top - (FETCH); | ||
| 1783 | *ptr = POP; | ||
| 1784 | break; | ||
| 1785 | } | ||
| 1786 | case Bstack_set2: | ||
| 1787 | { | ||
| 1788 | Lisp_Object *ptr = top - (FETCH2); | ||
| 1789 | *ptr = POP; | ||
| 1790 | break; | ||
| 1791 | } | ||
| 1792 | case BdiscardN: | ||
| 1793 | op = FETCH; | ||
| 1794 | if (op & 0x80) | ||
| 1795 | { | ||
| 1796 | op &= 0x7F; | ||
| 1797 | top[-op] = TOP; | ||
| 1798 | } | ||
| 1799 | DISCARD (op); | ||
| 1800 | break; | ||
| 1801 | |||
| 1679 | case 255: | 1802 | case 255: |
| 1680 | default: | 1803 | default: |
| 1681 | #ifdef BYTE_CODE_SAFE | 1804 | #ifdef BYTE_CODE_SAFE |
diff --git a/src/callint.c b/src/callint.c index 40d89acd16c..60570369d9e 100644 --- a/src/callint.c +++ b/src/callint.c | |||
| @@ -121,8 +121,9 @@ usage: (interactive &optional ARGS) */) | |||
| 121 | static Lisp_Object | 121 | static Lisp_Object |
| 122 | quotify_arg (register Lisp_Object exp) | 122 | quotify_arg (register Lisp_Object exp) |
| 123 | { | 123 | { |
| 124 | if (!INTEGERP (exp) && !STRINGP (exp) | 124 | if (CONSP (exp) |
| 125 | && !NILP (exp) && !EQ (exp, Qt)) | 125 | || (SYMBOLP (exp) |
| 126 | && !NILP (exp) && !EQ (exp, Qt))) | ||
| 126 | return Fcons (Qquote, Fcons (exp, Qnil)); | 127 | return Fcons (Qquote, Fcons (exp, Qnil)); |
| 127 | 128 | ||
| 128 | return exp; | 129 | return exp; |
| @@ -169,6 +170,9 @@ check_mark (int for_region) | |||
| 169 | static void | 170 | static void |
| 170 | fix_command (Lisp_Object input, Lisp_Object values) | 171 | fix_command (Lisp_Object input, Lisp_Object values) |
| 171 | { | 172 | { |
| 173 | /* FIXME: Instead of this ugly hack, we should provide a way for an | ||
| 174 | interactive spec to return an expression/function that will re-build the | ||
| 175 | args without user intervention. */ | ||
| 172 | if (CONSP (input)) | 176 | if (CONSP (input)) |
| 173 | { | 177 | { |
| 174 | Lisp_Object car; | 178 | Lisp_Object car; |
| @@ -332,11 +336,14 @@ invoke it. If KEYS is omitted or nil, the return value of | |||
| 332 | else | 336 | else |
| 333 | { | 337 | { |
| 334 | Lisp_Object input; | 338 | Lisp_Object input; |
| 339 | Lisp_Object funval = Findirect_function (function, Qt); | ||
| 335 | i = num_input_events; | 340 | i = num_input_events; |
| 336 | input = specs; | 341 | input = specs; |
| 337 | /* Compute the arg values using the user's expression. */ | 342 | /* Compute the arg values using the user's expression. */ |
| 338 | GCPRO2 (input, filter_specs); | 343 | GCPRO2 (input, filter_specs); |
| 339 | specs = Feval (specs); | 344 | specs = Feval (specs, |
| 345 | CONSP (funval) && EQ (Qclosure, XCAR (funval)) | ||
| 346 | ? Qt : Qnil); | ||
| 340 | UNGCPRO; | 347 | UNGCPRO; |
| 341 | if (i != num_input_events || !NILP (record_flag)) | 348 | if (i != num_input_events || !NILP (record_flag)) |
| 342 | { | 349 | { |
diff --git a/src/data.c b/src/data.c index ba7ae58d7b2..4b9d2ec0387 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -745,7 +745,9 @@ Value, if non-nil, is a list \(interactive SPEC). */) | |||
| 745 | else if (CONSP (fun)) | 745 | else if (CONSP (fun)) |
| 746 | { | 746 | { |
| 747 | Lisp_Object funcar = XCAR (fun); | 747 | Lisp_Object funcar = XCAR (fun); |
| 748 | if (EQ (funcar, Qlambda)) | 748 | if (EQ (funcar, Qclosure)) |
| 749 | return Fassq (Qinteractive, Fcdr (Fcdr (XCDR (fun)))); | ||
| 750 | else if (EQ (funcar, Qlambda)) | ||
| 749 | return Fassq (Qinteractive, Fcdr (XCDR (fun))); | 751 | return Fassq (Qinteractive, Fcdr (XCDR (fun))); |
| 750 | else if (EQ (funcar, Qautoload)) | 752 | else if (EQ (funcar, Qautoload)) |
| 751 | { | 753 | { |
| @@ -1431,7 +1433,7 @@ usage: (setq-default [VAR VALUE]...) */) | |||
| 1431 | 1433 | ||
| 1432 | do | 1434 | do |
| 1433 | { | 1435 | { |
| 1434 | val = Feval (Fcar (Fcdr (args_left))); | 1436 | val = eval_sub (Fcar (Fcdr (args_left))); |
| 1435 | symbol = XCAR (args_left); | 1437 | symbol = XCAR (args_left); |
| 1436 | Fset_default (symbol, val); | 1438 | Fset_default (symbol, val); |
| 1437 | args_left = Fcdr (XCDR (args_left)); | 1439 | args_left = Fcdr (XCDR (args_left)); |
| @@ -2101,7 +2103,7 @@ or a byte-code object. IDX starts at 0. */) | |||
| 2101 | 2103 | ||
| 2102 | if (idxval < 0 || idxval >= size) | 2104 | if (idxval < 0 || idxval >= size) |
| 2103 | args_out_of_range (array, idx); | 2105 | args_out_of_range (array, idx); |
| 2104 | return XVECTOR (array)->contents[idxval]; | 2106 | return AREF (array, idxval); |
| 2105 | } | 2107 | } |
| 2106 | } | 2108 | } |
| 2107 | 2109 | ||
| @@ -36,6 +36,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 36 | 36 | ||
| 37 | Lisp_Object Qfunction_documentation; | 37 | Lisp_Object Qfunction_documentation; |
| 38 | 38 | ||
| 39 | extern Lisp_Object Qclosure; | ||
| 39 | /* Buffer used for reading from documentation file. */ | 40 | /* Buffer used for reading from documentation file. */ |
| 40 | static char *get_doc_string_buffer; | 41 | static char *get_doc_string_buffer; |
| 41 | static int get_doc_string_buffer_size; | 42 | static int get_doc_string_buffer_size; |
| @@ -374,6 +375,7 @@ string is passed through `substitute-command-keys'. */) | |||
| 374 | else if (EQ (funcar, Qkeymap)) | 375 | else if (EQ (funcar, Qkeymap)) |
| 375 | return build_string ("Prefix command (definition is a keymap associating keystrokes with commands)."); | 376 | return build_string ("Prefix command (definition is a keymap associating keystrokes with commands)."); |
| 376 | else if (EQ (funcar, Qlambda) | 377 | else if (EQ (funcar, Qlambda) |
| 378 | || (EQ (funcar, Qclosure) && (fun = XCDR (fun), 1)) | ||
| 377 | || EQ (funcar, Qautoload)) | 379 | || EQ (funcar, Qautoload)) |
| 378 | { | 380 | { |
| 379 | Lisp_Object tem1 = Fcdr (Fcdr (fun)); | 381 | Lisp_Object tem1 = Fcdr (Fcdr (fun)); |
| @@ -480,7 +482,7 @@ aren't strings. */) | |||
| 480 | } | 482 | } |
| 481 | else if (!STRINGP (tem)) | 483 | else if (!STRINGP (tem)) |
| 482 | /* Feval protects its argument. */ | 484 | /* Feval protects its argument. */ |
| 483 | tem = Feval (tem); | 485 | tem = Feval (tem, Qnil); |
| 484 | 486 | ||
| 485 | if (NILP (raw) && STRINGP (tem)) | 487 | if (NILP (raw) && STRINGP (tem)) |
| 486 | tem = Fsubstitute_command_keys (tem); | 488 | tem = Fsubstitute_command_keys (tem); |
| @@ -507,7 +509,8 @@ store_function_docstring (Lisp_Object fun, EMACS_INT offset) | |||
| 507 | Lisp_Object tem; | 509 | Lisp_Object tem; |
| 508 | 510 | ||
| 509 | tem = XCAR (fun); | 511 | tem = XCAR (fun); |
| 510 | if (EQ (tem, Qlambda) || EQ (tem, Qautoload)) | 512 | if (EQ (tem, Qlambda) || EQ (tem, Qautoload) |
| 513 | || (EQ (tem, Qclosure) && (fun = XCDR (fun), 1))) | ||
| 511 | { | 514 | { |
| 512 | tem = Fcdr (Fcdr (fun)); | 515 | tem = Fcdr (Fcdr (fun)); |
| 513 | if (CONSP (tem) && INTEGERP (XCAR (tem))) | 516 | if (CONSP (tem) && INTEGERP (XCAR (tem))) |
diff --git a/src/eval.c b/src/eval.c index 718e58c693f..948c2e4d158 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -64,6 +64,8 @@ Lisp_Object Qinhibit_quit; | |||
| 64 | Lisp_Object Qand_rest, Qand_optional; | 64 | Lisp_Object Qand_rest, Qand_optional; |
| 65 | Lisp_Object Qdebug_on_error; | 65 | Lisp_Object Qdebug_on_error; |
| 66 | Lisp_Object Qdeclare; | 66 | Lisp_Object Qdeclare; |
| 67 | Lisp_Object Qinternal_interpreter_environment, Qclosure; | ||
| 68 | |||
| 67 | Lisp_Object Qdebug; | 69 | Lisp_Object Qdebug; |
| 68 | 70 | ||
| 69 | /* This holds either the symbol `run-hooks' or nil. | 71 | /* This holds either the symbol `run-hooks' or nil. |
| @@ -115,10 +117,10 @@ Lisp_Object Vsignaling_function; | |||
| 115 | 117 | ||
| 116 | int handling_signal; | 118 | int handling_signal; |
| 117 | 119 | ||
| 118 | static Lisp_Object funcall_lambda (Lisp_Object, size_t, Lisp_Object*); | 120 | static Lisp_Object funcall_lambda (Lisp_Object, size_t, Lisp_Object *); |
| 119 | static void unwind_to_catch (struct catchtag *, Lisp_Object) NO_RETURN; | 121 | static void unwind_to_catch (struct catchtag *, Lisp_Object) NO_RETURN; |
| 120 | static int interactive_p (int); | 122 | static int interactive_p (int); |
| 121 | static Lisp_Object apply_lambda (Lisp_Object, Lisp_Object, int); | 123 | static Lisp_Object apply_lambda (Lisp_Object fun, Lisp_Object args); |
| 122 | 124 | ||
| 123 | void | 125 | void |
| 124 | init_eval_once (void) | 126 | init_eval_once (void) |
| @@ -127,7 +129,7 @@ init_eval_once (void) | |||
| 127 | specpdl = (struct specbinding *) xmalloc (specpdl_size * sizeof (struct specbinding)); | 129 | specpdl = (struct specbinding *) xmalloc (specpdl_size * sizeof (struct specbinding)); |
| 128 | specpdl_ptr = specpdl; | 130 | specpdl_ptr = specpdl; |
| 129 | /* Don't forget to update docs (lispref node "Local Variables"). */ | 131 | /* Don't forget to update docs (lispref node "Local Variables"). */ |
| 130 | max_specpdl_size = 1000; | 132 | max_specpdl_size = 1300; /* 1000 is not enough for CEDET's c-by.el. */ |
| 131 | max_lisp_eval_depth = 600; | 133 | max_lisp_eval_depth = 600; |
| 132 | 134 | ||
| 133 | Vrun_hooks = Qnil; | 135 | Vrun_hooks = Qnil; |
| @@ -244,7 +246,7 @@ usage: (or CONDITIONS...) */) | |||
| 244 | 246 | ||
| 245 | while (CONSP (args)) | 247 | while (CONSP (args)) |
| 246 | { | 248 | { |
| 247 | val = Feval (XCAR (args)); | 249 | val = eval_sub (XCAR (args)); |
| 248 | if (!NILP (val)) | 250 | if (!NILP (val)) |
| 249 | break; | 251 | break; |
| 250 | args = XCDR (args); | 252 | args = XCDR (args); |
| @@ -268,7 +270,7 @@ usage: (and CONDITIONS...) */) | |||
| 268 | 270 | ||
| 269 | while (CONSP (args)) | 271 | while (CONSP (args)) |
| 270 | { | 272 | { |
| 271 | val = Feval (XCAR (args)); | 273 | val = eval_sub (XCAR (args)); |
| 272 | if (NILP (val)) | 274 | if (NILP (val)) |
| 273 | break; | 275 | break; |
| 274 | args = XCDR (args); | 276 | args = XCDR (args); |
| @@ -290,11 +292,11 @@ usage: (if COND THEN ELSE...) */) | |||
| 290 | struct gcpro gcpro1; | 292 | struct gcpro gcpro1; |
| 291 | 293 | ||
| 292 | GCPRO1 (args); | 294 | GCPRO1 (args); |
| 293 | cond = Feval (Fcar (args)); | 295 | cond = eval_sub (Fcar (args)); |
| 294 | UNGCPRO; | 296 | UNGCPRO; |
| 295 | 297 | ||
| 296 | if (!NILP (cond)) | 298 | if (!NILP (cond)) |
| 297 | return Feval (Fcar (Fcdr (args))); | 299 | return eval_sub (Fcar (Fcdr (args))); |
| 298 | return Fprogn (Fcdr (Fcdr (args))); | 300 | return Fprogn (Fcdr (Fcdr (args))); |
| 299 | } | 301 | } |
| 300 | 302 | ||
| @@ -318,7 +320,7 @@ usage: (cond CLAUSES...) */) | |||
| 318 | while (!NILP (args)) | 320 | while (!NILP (args)) |
| 319 | { | 321 | { |
| 320 | clause = Fcar (args); | 322 | clause = Fcar (args); |
| 321 | val = Feval (Fcar (clause)); | 323 | val = eval_sub (Fcar (clause)); |
| 322 | if (!NILP (val)) | 324 | if (!NILP (val)) |
| 323 | { | 325 | { |
| 324 | if (!EQ (XCDR (clause), Qnil)) | 326 | if (!EQ (XCDR (clause), Qnil)) |
| @@ -344,7 +346,7 @@ usage: (progn BODY...) */) | |||
| 344 | 346 | ||
| 345 | while (CONSP (args)) | 347 | while (CONSP (args)) |
| 346 | { | 348 | { |
| 347 | val = Feval (XCAR (args)); | 349 | val = eval_sub (XCAR (args)); |
| 348 | args = XCDR (args); | 350 | args = XCDR (args); |
| 349 | } | 351 | } |
| 350 | 352 | ||
| @@ -373,13 +375,12 @@ usage: (prog1 FIRST BODY...) */) | |||
| 373 | 375 | ||
| 374 | do | 376 | do |
| 375 | { | 377 | { |
| 378 | Lisp_Object tem = eval_sub (XCAR (args_left)); | ||
| 376 | if (!(argnum++)) | 379 | if (!(argnum++)) |
| 377 | val = Feval (Fcar (args_left)); | 380 | val = tem; |
| 378 | else | 381 | args_left = XCDR (args_left); |
| 379 | Feval (Fcar (args_left)); | ||
| 380 | args_left = Fcdr (args_left); | ||
| 381 | } | 382 | } |
| 382 | while (!NILP(args_left)); | 383 | while (CONSP (args_left)); |
| 383 | 384 | ||
| 384 | UNGCPRO; | 385 | UNGCPRO; |
| 385 | return val; | 386 | return val; |
| @@ -408,13 +409,12 @@ usage: (prog2 FORM1 FORM2 BODY...) */) | |||
| 408 | 409 | ||
| 409 | do | 410 | do |
| 410 | { | 411 | { |
| 412 | Lisp_Object tem = eval_sub (XCAR (args_left)); | ||
| 411 | if (!(argnum++)) | 413 | if (!(argnum++)) |
| 412 | val = Feval (Fcar (args_left)); | 414 | val = tem; |
| 413 | else | 415 | args_left = XCDR (args_left); |
| 414 | Feval (Fcar (args_left)); | ||
| 415 | args_left = Fcdr (args_left); | ||
| 416 | } | 416 | } |
| 417 | while (!NILP (args_left)); | 417 | while (CONSP (args_left)); |
| 418 | 418 | ||
| 419 | UNGCPRO; | 419 | UNGCPRO; |
| 420 | return val; | 420 | return val; |
| @@ -432,7 +432,7 @@ usage: (setq [SYM VAL]...) */) | |||
| 432 | (Lisp_Object args) | 432 | (Lisp_Object args) |
| 433 | { | 433 | { |
| 434 | register Lisp_Object args_left; | 434 | register Lisp_Object args_left; |
| 435 | register Lisp_Object val, sym; | 435 | register Lisp_Object val, sym, lex_binding; |
| 436 | struct gcpro gcpro1; | 436 | struct gcpro gcpro1; |
| 437 | 437 | ||
| 438 | if (NILP (args)) | 438 | if (NILP (args)) |
| @@ -443,9 +443,19 @@ usage: (setq [SYM VAL]...) */) | |||
| 443 | 443 | ||
| 444 | do | 444 | do |
| 445 | { | 445 | { |
| 446 | val = Feval (Fcar (Fcdr (args_left))); | 446 | val = eval_sub (Fcar (Fcdr (args_left))); |
| 447 | sym = Fcar (args_left); | 447 | sym = Fcar (args_left); |
| 448 | Fset (sym, val); | 448 | |
| 449 | /* Like for eval_sub, we do not check declared_special here since | ||
| 450 | it's been done when let-binding. */ | ||
| 451 | if (!NILP (Vinternal_interpreter_environment) /* Mere optimization! */ | ||
| 452 | && SYMBOLP (sym) | ||
| 453 | && !NILP (lex_binding | ||
| 454 | = Fassq (sym, Vinternal_interpreter_environment))) | ||
| 455 | XSETCDR (lex_binding, val); /* SYM is lexically bound. */ | ||
| 456 | else | ||
| 457 | Fset (sym, val); /* SYM is dynamically bound. */ | ||
| 458 | |||
| 449 | args_left = Fcdr (Fcdr (args_left)); | 459 | args_left = Fcdr (Fcdr (args_left)); |
| 450 | } | 460 | } |
| 451 | while (!NILP(args_left)); | 461 | while (!NILP(args_left)); |
| @@ -471,9 +481,21 @@ In byte compilation, `function' causes its argument to be compiled. | |||
| 471 | usage: (function ARG) */) | 481 | usage: (function ARG) */) |
| 472 | (Lisp_Object args) | 482 | (Lisp_Object args) |
| 473 | { | 483 | { |
| 484 | Lisp_Object quoted = XCAR (args); | ||
| 485 | |||
| 474 | if (!NILP (Fcdr (args))) | 486 | if (!NILP (Fcdr (args))) |
| 475 | xsignal2 (Qwrong_number_of_arguments, Qfunction, Flength (args)); | 487 | xsignal2 (Qwrong_number_of_arguments, Qfunction, Flength (args)); |
| 476 | return Fcar (args); | 488 | |
| 489 | if (!NILP (Vinternal_interpreter_environment) | ||
| 490 | && CONSP (quoted) | ||
| 491 | && EQ (XCAR (quoted), Qlambda)) | ||
| 492 | /* This is a lambda expression within a lexical environment; | ||
| 493 | return an interpreted closure instead of a simple lambda. */ | ||
| 494 | return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment, | ||
| 495 | XCDR (quoted))); | ||
| 496 | else | ||
| 497 | /* Simply quote the argument. */ | ||
| 498 | return quoted; | ||
| 477 | } | 499 | } |
| 478 | 500 | ||
| 479 | 501 | ||
| @@ -496,7 +518,7 @@ spec that specifies non-nil unconditionally (such as \"p\"); or (ii) | |||
| 496 | use `called-interactively-p'. */) | 518 | use `called-interactively-p'. */) |
| 497 | (void) | 519 | (void) |
| 498 | { | 520 | { |
| 499 | return (INTERACTIVE && interactive_p (1)) ? Qt : Qnil; | 521 | return interactive_p (1) ? Qt : Qnil; |
| 500 | } | 522 | } |
| 501 | 523 | ||
| 502 | 524 | ||
| @@ -589,6 +611,8 @@ usage: (defun NAME ARGLIST [DOCSTRING] BODY...) */) | |||
| 589 | fn_name = Fcar (args); | 611 | fn_name = Fcar (args); |
| 590 | CHECK_SYMBOL (fn_name); | 612 | CHECK_SYMBOL (fn_name); |
| 591 | defn = Fcons (Qlambda, Fcdr (args)); | 613 | defn = Fcons (Qlambda, Fcdr (args)); |
| 614 | if (!NILP (Vinternal_interpreter_environment)) /* Mere optimization! */ | ||
| 615 | defn = Ffunction (Fcons (defn, Qnil)); | ||
| 592 | if (!NILP (Vpurify_flag)) | 616 | if (!NILP (Vpurify_flag)) |
| 593 | defn = Fpurecopy (defn); | 617 | defn = Fpurecopy (defn); |
| 594 | if (CONSP (XSYMBOL (fn_name)->function) | 618 | if (CONSP (XSYMBOL (fn_name)->function) |
| @@ -660,7 +684,11 @@ usage: (defmacro NAME ARGLIST [DOCSTRING] [DECL] BODY...) */) | |||
| 660 | tail = Fcons (lambda_list, tail); | 684 | tail = Fcons (lambda_list, tail); |
| 661 | else | 685 | else |
| 662 | tail = Fcons (lambda_list, Fcons (doc, tail)); | 686 | tail = Fcons (lambda_list, Fcons (doc, tail)); |
| 663 | defn = Fcons (Qmacro, Fcons (Qlambda, tail)); | 687 | |
| 688 | defn = Fcons (Qlambda, tail); | ||
| 689 | if (!NILP (Vinternal_interpreter_environment)) /* Mere optimization! */ | ||
| 690 | defn = Ffunction (Fcons (defn, Qnil)); | ||
| 691 | defn = Fcons (Qmacro, defn); | ||
| 664 | 692 | ||
| 665 | if (!NILP (Vpurify_flag)) | 693 | if (!NILP (Vpurify_flag)) |
| 666 | defn = Fpurecopy (defn); | 694 | defn = Fpurecopy (defn); |
| @@ -720,6 +748,7 @@ The return value is BASE-VARIABLE. */) | |||
| 720 | error ("Don't know how to make a let-bound variable an alias"); | 748 | error ("Don't know how to make a let-bound variable an alias"); |
| 721 | } | 749 | } |
| 722 | 750 | ||
| 751 | sym->declared_special = 1; | ||
| 723 | sym->redirect = SYMBOL_VARALIAS; | 752 | sym->redirect = SYMBOL_VARALIAS; |
| 724 | SET_SYMBOL_ALIAS (sym, XSYMBOL (base_variable)); | 753 | SET_SYMBOL_ALIAS (sym, XSYMBOL (base_variable)); |
| 725 | sym->constant = SYMBOL_CONSTANT_P (base_variable); | 754 | sym->constant = SYMBOL_CONSTANT_P (base_variable); |
| @@ -765,6 +794,9 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) | |||
| 765 | tem = Fdefault_boundp (sym); | 794 | tem = Fdefault_boundp (sym); |
| 766 | if (!NILP (tail)) | 795 | if (!NILP (tail)) |
| 767 | { | 796 | { |
| 797 | /* Do it before evaluating the initial value, for self-references. */ | ||
| 798 | XSYMBOL (sym)->declared_special = 1; | ||
| 799 | |||
| 768 | if (SYMBOL_CONSTANT_P (sym)) | 800 | if (SYMBOL_CONSTANT_P (sym)) |
| 769 | { | 801 | { |
| 770 | /* For upward compatibility, allow (defvar :foo (quote :foo)). */ | 802 | /* For upward compatibility, allow (defvar :foo (quote :foo)). */ |
| @@ -778,7 +810,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) | |||
| 778 | } | 810 | } |
| 779 | 811 | ||
| 780 | if (NILP (tem)) | 812 | if (NILP (tem)) |
| 781 | Fset_default (sym, Feval (Fcar (tail))); | 813 | Fset_default (sym, eval_sub (Fcar (tail))); |
| 782 | else | 814 | else |
| 783 | { /* Check if there is really a global binding rather than just a let | 815 | { /* Check if there is really a global binding rather than just a let |
| 784 | binding that shadows the global unboundness of the var. */ | 816 | binding that shadows the global unboundness of the var. */ |
| @@ -804,6 +836,13 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) | |||
| 804 | } | 836 | } |
| 805 | LOADHIST_ATTACH (sym); | 837 | LOADHIST_ATTACH (sym); |
| 806 | } | 838 | } |
| 839 | else if (!NILP (Vinternal_interpreter_environment) | ||
| 840 | && !XSYMBOL (sym)->declared_special) | ||
| 841 | /* A simple (defvar foo) with lexical scoping does "nothing" except | ||
| 842 | declare that var to be dynamically scoped *locally* (i.e. within | ||
| 843 | the current file or let-block). */ | ||
| 844 | Vinternal_interpreter_environment = | ||
| 845 | Fcons (sym, Vinternal_interpreter_environment); | ||
| 807 | else | 846 | else |
| 808 | { | 847 | { |
| 809 | /* Simple (defvar <var>) should not count as a definition at all. | 848 | /* Simple (defvar <var>) should not count as a definition at all. |
| @@ -834,10 +873,11 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */) | |||
| 834 | if (!NILP (Fcdr (Fcdr (Fcdr (args))))) | 873 | if (!NILP (Fcdr (Fcdr (Fcdr (args))))) |
| 835 | error ("Too many arguments"); | 874 | error ("Too many arguments"); |
| 836 | 875 | ||
| 837 | tem = Feval (Fcar (Fcdr (args))); | 876 | tem = eval_sub (Fcar (Fcdr (args))); |
| 838 | if (!NILP (Vpurify_flag)) | 877 | if (!NILP (Vpurify_flag)) |
| 839 | tem = Fpurecopy (tem); | 878 | tem = Fpurecopy (tem); |
| 840 | Fset_default (sym, tem); | 879 | Fset_default (sym, tem); |
| 880 | XSYMBOL (sym)->declared_special = 1; | ||
| 841 | tem = Fcar (Fcdr (Fcdr (args))); | 881 | tem = Fcar (Fcdr (Fcdr (args))); |
| 842 | if (!NILP (tem)) | 882 | if (!NILP (tem)) |
| 843 | { | 883 | { |
| @@ -924,27 +964,53 @@ Each VALUEFORM can refer to the symbols already bound by this VARLIST. | |||
| 924 | usage: (let* VARLIST BODY...) */) | 964 | usage: (let* VARLIST BODY...) */) |
| 925 | (Lisp_Object args) | 965 | (Lisp_Object args) |
| 926 | { | 966 | { |
| 927 | Lisp_Object varlist, val, elt; | 967 | Lisp_Object varlist, var, val, elt, lexenv; |
| 928 | int count = SPECPDL_INDEX (); | 968 | int count = SPECPDL_INDEX (); |
| 929 | struct gcpro gcpro1, gcpro2, gcpro3; | 969 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 930 | 970 | ||
| 931 | GCPRO3 (args, elt, varlist); | 971 | GCPRO3 (args, elt, varlist); |
| 932 | 972 | ||
| 973 | lexenv = Vinternal_interpreter_environment; | ||
| 974 | |||
| 933 | varlist = Fcar (args); | 975 | varlist = Fcar (args); |
| 934 | while (!NILP (varlist)) | 976 | while (CONSP (varlist)) |
| 935 | { | 977 | { |
| 936 | QUIT; | 978 | QUIT; |
| 937 | elt = Fcar (varlist); | 979 | |
| 980 | elt = XCAR (varlist); | ||
| 938 | if (SYMBOLP (elt)) | 981 | if (SYMBOLP (elt)) |
| 939 | specbind (elt, Qnil); | 982 | { |
| 983 | var = elt; | ||
| 984 | val = Qnil; | ||
| 985 | } | ||
| 940 | else if (! NILP (Fcdr (Fcdr (elt)))) | 986 | else if (! NILP (Fcdr (Fcdr (elt)))) |
| 941 | signal_error ("`let' bindings can have only one value-form", elt); | 987 | signal_error ("`let' bindings can have only one value-form", elt); |
| 942 | else | 988 | else |
| 943 | { | 989 | { |
| 944 | val = Feval (Fcar (Fcdr (elt))); | 990 | var = Fcar (elt); |
| 945 | specbind (Fcar (elt), val); | 991 | val = eval_sub (Fcar (Fcdr (elt))); |
| 992 | } | ||
| 993 | |||
| 994 | if (!NILP (lexenv) && SYMBOLP (var) | ||
| 995 | && !XSYMBOL (var)->declared_special | ||
| 996 | && NILP (Fmemq (var, Vinternal_interpreter_environment))) | ||
| 997 | /* Lexically bind VAR by adding it to the interpreter's binding | ||
| 998 | alist. */ | ||
| 999 | { | ||
| 1000 | Lisp_Object newenv | ||
| 1001 | = Fcons (Fcons (var, val), Vinternal_interpreter_environment); | ||
| 1002 | if (EQ (Vinternal_interpreter_environment, lexenv)) | ||
| 1003 | /* Save the old lexical environment on the specpdl stack, | ||
| 1004 | but only for the first lexical binding, since we'll never | ||
| 1005 | need to revert to one of the intermediate ones. */ | ||
| 1006 | specbind (Qinternal_interpreter_environment, newenv); | ||
| 1007 | else | ||
| 1008 | Vinternal_interpreter_environment = newenv; | ||
| 946 | } | 1009 | } |
| 947 | varlist = Fcdr (varlist); | 1010 | else |
| 1011 | specbind (var, val); | ||
| 1012 | |||
| 1013 | varlist = XCDR (varlist); | ||
| 948 | } | 1014 | } |
| 949 | UNGCPRO; | 1015 | UNGCPRO; |
| 950 | val = Fprogn (Fcdr (args)); | 1016 | val = Fprogn (Fcdr (args)); |
| @@ -960,7 +1026,7 @@ All the VALUEFORMs are evalled before any symbols are bound. | |||
| 960 | usage: (let VARLIST BODY...) */) | 1026 | usage: (let VARLIST BODY...) */) |
| 961 | (Lisp_Object args) | 1027 | (Lisp_Object args) |
| 962 | { | 1028 | { |
| 963 | Lisp_Object *temps, tem; | 1029 | Lisp_Object *temps, tem, lexenv; |
| 964 | register Lisp_Object elt, varlist; | 1030 | register Lisp_Object elt, varlist; |
| 965 | int count = SPECPDL_INDEX (); | 1031 | int count = SPECPDL_INDEX (); |
| 966 | register size_t argnum; | 1032 | register size_t argnum; |
| @@ -987,22 +1053,36 @@ usage: (let VARLIST BODY...) */) | |||
| 987 | else if (! NILP (Fcdr (Fcdr (elt)))) | 1053 | else if (! NILP (Fcdr (Fcdr (elt)))) |
| 988 | signal_error ("`let' bindings can have only one value-form", elt); | 1054 | signal_error ("`let' bindings can have only one value-form", elt); |
| 989 | else | 1055 | else |
| 990 | temps [argnum++] = Feval (Fcar (Fcdr (elt))); | 1056 | temps [argnum++] = eval_sub (Fcar (Fcdr (elt))); |
| 991 | gcpro2.nvars = argnum; | 1057 | gcpro2.nvars = argnum; |
| 992 | } | 1058 | } |
| 993 | UNGCPRO; | 1059 | UNGCPRO; |
| 994 | 1060 | ||
| 1061 | lexenv = Vinternal_interpreter_environment; | ||
| 1062 | |||
| 995 | varlist = Fcar (args); | 1063 | varlist = Fcar (args); |
| 996 | for (argnum = 0; CONSP (varlist); varlist = XCDR (varlist)) | 1064 | for (argnum = 0; CONSP (varlist); varlist = XCDR (varlist)) |
| 997 | { | 1065 | { |
| 1066 | Lisp_Object var; | ||
| 1067 | |||
| 998 | elt = XCAR (varlist); | 1068 | elt = XCAR (varlist); |
| 1069 | var = SYMBOLP (elt) ? elt : Fcar (elt); | ||
| 999 | tem = temps[argnum++]; | 1070 | tem = temps[argnum++]; |
| 1000 | if (SYMBOLP (elt)) | 1071 | |
| 1001 | specbind (elt, tem); | 1072 | if (!NILP (lexenv) && SYMBOLP (var) |
| 1073 | && !XSYMBOL (var)->declared_special | ||
| 1074 | && NILP (Fmemq (var, Vinternal_interpreter_environment))) | ||
| 1075 | /* Lexically bind VAR by adding it to the lexenv alist. */ | ||
| 1076 | lexenv = Fcons (Fcons (var, tem), lexenv); | ||
| 1002 | else | 1077 | else |
| 1003 | specbind (Fcar (elt), tem); | 1078 | /* Dynamically bind VAR. */ |
| 1079 | specbind (var, tem); | ||
| 1004 | } | 1080 | } |
| 1005 | 1081 | ||
| 1082 | if (!EQ (lexenv, Vinternal_interpreter_environment)) | ||
| 1083 | /* Instantiate a new lexical environment. */ | ||
| 1084 | specbind (Qinternal_interpreter_environment, lexenv); | ||
| 1085 | |||
| 1006 | elt = Fprogn (Fcdr (args)); | 1086 | elt = Fprogn (Fcdr (args)); |
| 1007 | SAFE_FREE (); | 1087 | SAFE_FREE (); |
| 1008 | return unbind_to (count, elt); | 1088 | return unbind_to (count, elt); |
| @@ -1022,7 +1102,7 @@ usage: (while TEST BODY...) */) | |||
| 1022 | 1102 | ||
| 1023 | test = Fcar (args); | 1103 | test = Fcar (args); |
| 1024 | body = Fcdr (args); | 1104 | body = Fcdr (args); |
| 1025 | while (!NILP (Feval (test))) | 1105 | while (!NILP (eval_sub (test))) |
| 1026 | { | 1106 | { |
| 1027 | QUIT; | 1107 | QUIT; |
| 1028 | Fprogn (body); | 1108 | Fprogn (body); |
| @@ -1124,7 +1204,7 @@ usage: (catch TAG BODY...) */) | |||
| 1124 | struct gcpro gcpro1; | 1204 | struct gcpro gcpro1; |
| 1125 | 1205 | ||
| 1126 | GCPRO1 (args); | 1206 | GCPRO1 (args); |
| 1127 | tag = Feval (Fcar (args)); | 1207 | tag = eval_sub (Fcar (args)); |
| 1128 | UNGCPRO; | 1208 | UNGCPRO; |
| 1129 | return internal_catch (tag, Fprogn, Fcdr (args)); | 1209 | return internal_catch (tag, Fprogn, Fcdr (args)); |
| 1130 | } | 1210 | } |
| @@ -1254,7 +1334,7 @@ usage: (unwind-protect BODYFORM UNWINDFORMS...) */) | |||
| 1254 | int count = SPECPDL_INDEX (); | 1334 | int count = SPECPDL_INDEX (); |
| 1255 | 1335 | ||
| 1256 | record_unwind_protect (Fprogn, Fcdr (args)); | 1336 | record_unwind_protect (Fprogn, Fcdr (args)); |
| 1257 | val = Feval (Fcar (args)); | 1337 | val = eval_sub (Fcar (args)); |
| 1258 | return unbind_to (count, val); | 1338 | return unbind_to (count, val); |
| 1259 | } | 1339 | } |
| 1260 | 1340 | ||
| @@ -1355,7 +1435,7 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform, | |||
| 1355 | h.tag = &c; | 1435 | h.tag = &c; |
| 1356 | handlerlist = &h; | 1436 | handlerlist = &h; |
| 1357 | 1437 | ||
| 1358 | val = Feval (bodyform); | 1438 | val = eval_sub (bodyform); |
| 1359 | catchlist = c.next; | 1439 | catchlist = c.next; |
| 1360 | handlerlist = h.next; | 1440 | handlerlist = h.next; |
| 1361 | return val; | 1441 | return val; |
| @@ -1999,9 +2079,12 @@ then strings and vectors are not accepted. */) | |||
| 1999 | if (!CONSP (fun)) | 2079 | if (!CONSP (fun)) |
| 2000 | return Qnil; | 2080 | return Qnil; |
| 2001 | funcar = XCAR (fun); | 2081 | funcar = XCAR (fun); |
| 2002 | if (EQ (funcar, Qlambda)) | 2082 | if (EQ (funcar, Qclosure)) |
| 2083 | return (!NILP (Fassq (Qinteractive, Fcdr (Fcdr (XCDR (fun))))) | ||
| 2084 | ? Qt : if_prop); | ||
| 2085 | else if (EQ (funcar, Qlambda)) | ||
| 2003 | return !NILP (Fassq (Qinteractive, Fcdr (XCDR (fun)))) ? Qt : if_prop; | 2086 | return !NILP (Fassq (Qinteractive, Fcdr (XCDR (fun)))) ? Qt : if_prop; |
| 2004 | if (EQ (funcar, Qautoload)) | 2087 | else if (EQ (funcar, Qautoload)) |
| 2005 | return !NILP (Fcar (Fcdr (Fcdr (XCDR (fun))))) ? Qt : if_prop; | 2088 | return !NILP (Fcar (Fcdr (Fcdr (XCDR (fun))))) ? Qt : if_prop; |
| 2006 | else | 2089 | else |
| 2007 | return Qnil; | 2090 | return Qnil; |
| @@ -2119,9 +2202,21 @@ do_autoload (Lisp_Object fundef, Lisp_Object funname) | |||
| 2119 | } | 2202 | } |
| 2120 | 2203 | ||
| 2121 | 2204 | ||
| 2122 | DEFUN ("eval", Feval, Seval, 1, 1, 0, | 2205 | DEFUN ("eval", Feval, Seval, 1, 2, 0, |
| 2123 | doc: /* Evaluate FORM and return its value. */) | 2206 | doc: /* Evaluate FORM and return its value. |
| 2124 | (Lisp_Object form) | 2207 | If LEXICAL is t, evaluate using lexical scoping. */) |
| 2208 | (Lisp_Object form, Lisp_Object lexical) | ||
| 2209 | { | ||
| 2210 | int count = SPECPDL_INDEX (); | ||
| 2211 | specbind (Qinternal_interpreter_environment, | ||
| 2212 | NILP (lexical) ? Qnil : Fcons (Qt, Qnil)); | ||
| 2213 | return unbind_to (count, eval_sub (form)); | ||
| 2214 | } | ||
| 2215 | |||
| 2216 | /* Eval a sub-expression of the current expression (i.e. in the same | ||
| 2217 | lexical scope). */ | ||
| 2218 | Lisp_Object | ||
| 2219 | eval_sub (Lisp_Object form) | ||
| 2125 | { | 2220 | { |
| 2126 | Lisp_Object fun, val, original_fun, original_args; | 2221 | Lisp_Object fun, val, original_fun, original_args; |
| 2127 | Lisp_Object funcar; | 2222 | Lisp_Object funcar; |
| @@ -2132,7 +2227,20 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0, | |||
| 2132 | abort (); | 2227 | abort (); |
| 2133 | 2228 | ||
| 2134 | if (SYMBOLP (form)) | 2229 | if (SYMBOLP (form)) |
| 2135 | return Fsymbol_value (form); | 2230 | { |
| 2231 | /* Look up its binding in the lexical environment. | ||
| 2232 | We do not pay attention to the declared_special flag here, since we | ||
| 2233 | already did that when let-binding the variable. */ | ||
| 2234 | Lisp_Object lex_binding | ||
| 2235 | = !NILP (Vinternal_interpreter_environment) /* Mere optimization! */ | ||
| 2236 | ? Fassq (form, Vinternal_interpreter_environment) | ||
| 2237 | : Qnil; | ||
| 2238 | if (CONSP (lex_binding)) | ||
| 2239 | return XCDR (lex_binding); | ||
| 2240 | else | ||
| 2241 | return Fsymbol_value (form); | ||
| 2242 | } | ||
| 2243 | |||
| 2136 | if (!CONSP (form)) | 2244 | if (!CONSP (form)) |
| 2137 | return form; | 2245 | return form; |
| 2138 | 2246 | ||
| @@ -2216,7 +2324,7 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0, | |||
| 2216 | 2324 | ||
| 2217 | while (!NILP (args_left)) | 2325 | while (!NILP (args_left)) |
| 2218 | { | 2326 | { |
| 2219 | vals[argnum++] = Feval (Fcar (args_left)); | 2327 | vals[argnum++] = eval_sub (Fcar (args_left)); |
| 2220 | args_left = Fcdr (args_left); | 2328 | args_left = Fcdr (args_left); |
| 2221 | gcpro3.nvars = argnum; | 2329 | gcpro3.nvars = argnum; |
| 2222 | } | 2330 | } |
| @@ -2237,7 +2345,7 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0, | |||
| 2237 | maxargs = XSUBR (fun)->max_args; | 2345 | maxargs = XSUBR (fun)->max_args; |
| 2238 | for (i = 0; i < maxargs; args_left = Fcdr (args_left)) | 2346 | for (i = 0; i < maxargs; args_left = Fcdr (args_left)) |
| 2239 | { | 2347 | { |
| 2240 | argvals[i] = Feval (Fcar (args_left)); | 2348 | argvals[i] = eval_sub (Fcar (args_left)); |
| 2241 | gcpro3.nvars = ++i; | 2349 | gcpro3.nvars = ++i; |
| 2242 | } | 2350 | } |
| 2243 | 2351 | ||
| @@ -2297,7 +2405,7 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0, | |||
| 2297 | } | 2405 | } |
| 2298 | } | 2406 | } |
| 2299 | else if (COMPILEDP (fun)) | 2407 | else if (COMPILEDP (fun)) |
| 2300 | val = apply_lambda (fun, original_args, 1); | 2408 | val = apply_lambda (fun, original_args); |
| 2301 | else | 2409 | else |
| 2302 | { | 2410 | { |
| 2303 | if (EQ (fun, Qunbound)) | 2411 | if (EQ (fun, Qunbound)) |
| @@ -2313,9 +2421,10 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0, | |||
| 2313 | goto retry; | 2421 | goto retry; |
| 2314 | } | 2422 | } |
| 2315 | if (EQ (funcar, Qmacro)) | 2423 | if (EQ (funcar, Qmacro)) |
| 2316 | val = Feval (apply1 (Fcdr (fun), original_args)); | 2424 | val = eval_sub (apply1 (Fcdr (fun), original_args)); |
| 2317 | else if (EQ (funcar, Qlambda)) | 2425 | else if (EQ (funcar, Qlambda) |
| 2318 | val = apply_lambda (fun, original_args, 1); | 2426 | || EQ (funcar, Qclosure)) |
| 2427 | val = apply_lambda (fun, original_args); | ||
| 2319 | else | 2428 | else |
| 2320 | xsignal1 (Qinvalid_function, original_fun); | 2429 | xsignal1 (Qinvalid_function, original_fun); |
| 2321 | } | 2430 | } |
| @@ -2786,6 +2895,39 @@ call7 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, | |||
| 2786 | 2895 | ||
| 2787 | /* The caller should GCPRO all the elements of ARGS. */ | 2896 | /* The caller should GCPRO all the elements of ARGS. */ |
| 2788 | 2897 | ||
| 2898 | DEFUN ("functionp", Ffunctionp, Sfunctionp, 1, 1, 0, | ||
| 2899 | doc: /* Non-nil if OBJECT is a function. */) | ||
| 2900 | (Lisp_Object object) | ||
| 2901 | { | ||
| 2902 | if (SYMBOLP (object) && !NILP (Ffboundp (object))) | ||
| 2903 | { | ||
| 2904 | object = Findirect_function (object, Qt); | ||
| 2905 | |||
| 2906 | if (CONSP (object) && EQ (XCAR (object), Qautoload)) | ||
| 2907 | { | ||
| 2908 | /* Autoloaded symbols are functions, except if they load | ||
| 2909 | macros or keymaps. */ | ||
| 2910 | int i; | ||
| 2911 | for (i = 0; i < 4 && CONSP (object); i++) | ||
| 2912 | object = XCDR (object); | ||
| 2913 | |||
| 2914 | return (CONSP (object) && !NILP (XCAR (object))) ? Qnil : Qt; | ||
| 2915 | } | ||
| 2916 | } | ||
| 2917 | |||
| 2918 | if (SUBRP (object)) | ||
| 2919 | return (XSUBR (object)->max_args != UNEVALLED) ? Qt : Qnil; | ||
| 2920 | else if (COMPILEDP (object)) | ||
| 2921 | return Qt; | ||
| 2922 | else if (CONSP (object)) | ||
| 2923 | { | ||
| 2924 | Lisp_Object car = XCAR (object); | ||
| 2925 | return (EQ (car, Qlambda) || EQ (car, Qclosure)) ? Qt : Qnil; | ||
| 2926 | } | ||
| 2927 | else | ||
| 2928 | return Qnil; | ||
| 2929 | } | ||
| 2930 | |||
| 2789 | DEFUN ("funcall", Ffuncall, Sfuncall, 1, MANY, 0, | 2931 | DEFUN ("funcall", Ffuncall, Sfuncall, 1, MANY, 0, |
| 2790 | doc: /* Call first argument as a function, passing remaining arguments to it. | 2932 | doc: /* Call first argument as a function, passing remaining arguments to it. |
| 2791 | Return the value that function returns. | 2933 | Return the value that function returns. |
| @@ -2930,7 +3072,8 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2930 | funcar = XCAR (fun); | 3072 | funcar = XCAR (fun); |
| 2931 | if (!SYMBOLP (funcar)) | 3073 | if (!SYMBOLP (funcar)) |
| 2932 | xsignal1 (Qinvalid_function, original_fun); | 3074 | xsignal1 (Qinvalid_function, original_fun); |
| 2933 | if (EQ (funcar, Qlambda)) | 3075 | if (EQ (funcar, Qlambda) |
| 3076 | || EQ (funcar, Qclosure)) | ||
| 2934 | val = funcall_lambda (fun, numargs, args + 1); | 3077 | val = funcall_lambda (fun, numargs, args + 1); |
| 2935 | else if (EQ (funcar, Qautoload)) | 3078 | else if (EQ (funcar, Qautoload)) |
| 2936 | { | 3079 | { |
| @@ -2950,7 +3093,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2950 | } | 3093 | } |
| 2951 | 3094 | ||
| 2952 | static Lisp_Object | 3095 | static Lisp_Object |
| 2953 | apply_lambda (Lisp_Object fun, Lisp_Object args, int eval_flag) | 3096 | apply_lambda (Lisp_Object fun, Lisp_Object args) |
| 2954 | { | 3097 | { |
| 2955 | Lisp_Object args_left; | 3098 | Lisp_Object args_left; |
| 2956 | size_t numargs; | 3099 | size_t numargs; |
| @@ -2970,18 +3113,15 @@ apply_lambda (Lisp_Object fun, Lisp_Object args, int eval_flag) | |||
| 2970 | for (i = 0; i < numargs; ) | 3113 | for (i = 0; i < numargs; ) |
| 2971 | { | 3114 | { |
| 2972 | tem = Fcar (args_left), args_left = Fcdr (args_left); | 3115 | tem = Fcar (args_left), args_left = Fcdr (args_left); |
| 2973 | if (eval_flag) tem = Feval (tem); | 3116 | tem = eval_sub (tem); |
| 2974 | arg_vector[i++] = tem; | 3117 | arg_vector[i++] = tem; |
| 2975 | gcpro1.nvars = i; | 3118 | gcpro1.nvars = i; |
| 2976 | } | 3119 | } |
| 2977 | 3120 | ||
| 2978 | UNGCPRO; | 3121 | UNGCPRO; |
| 2979 | 3122 | ||
| 2980 | if (eval_flag) | 3123 | backtrace_list->args = arg_vector; |
| 2981 | { | 3124 | backtrace_list->nargs = i; |
| 2982 | backtrace_list->args = arg_vector; | ||
| 2983 | backtrace_list->nargs = i; | ||
| 2984 | } | ||
| 2985 | backtrace_list->evalargs = 0; | 3125 | backtrace_list->evalargs = 0; |
| 2986 | tem = funcall_lambda (fun, numargs, arg_vector); | 3126 | tem = funcall_lambda (fun, numargs, arg_vector); |
| 2987 | 3127 | ||
| @@ -3002,13 +3142,21 @@ static Lisp_Object | |||
| 3002 | funcall_lambda (Lisp_Object fun, size_t nargs, | 3142 | funcall_lambda (Lisp_Object fun, size_t nargs, |
| 3003 | register Lisp_Object *arg_vector) | 3143 | register Lisp_Object *arg_vector) |
| 3004 | { | 3144 | { |
| 3005 | Lisp_Object val, syms_left, next; | 3145 | Lisp_Object val, syms_left, next, lexenv; |
| 3006 | int count = SPECPDL_INDEX (); | 3146 | int count = SPECPDL_INDEX (); |
| 3007 | size_t i; | 3147 | size_t i; |
| 3008 | int optional, rest; | 3148 | int optional, rest; |
| 3009 | 3149 | ||
| 3010 | if (CONSP (fun)) | 3150 | if (CONSP (fun)) |
| 3011 | { | 3151 | { |
| 3152 | if (EQ (XCAR (fun), Qclosure)) | ||
| 3153 | { | ||
| 3154 | fun = XCDR (fun); /* Drop `closure'. */ | ||
| 3155 | lexenv = XCAR (fun); | ||
| 3156 | CHECK_LIST_CONS (fun, fun); | ||
| 3157 | } | ||
| 3158 | else | ||
| 3159 | lexenv = Qnil; | ||
| 3012 | syms_left = XCDR (fun); | 3160 | syms_left = XCDR (fun); |
| 3013 | if (CONSP (syms_left)) | 3161 | if (CONSP (syms_left)) |
| 3014 | syms_left = XCAR (syms_left); | 3162 | syms_left = XCAR (syms_left); |
| @@ -3016,7 +3164,30 @@ funcall_lambda (Lisp_Object fun, size_t nargs, | |||
| 3016 | xsignal1 (Qinvalid_function, fun); | 3164 | xsignal1 (Qinvalid_function, fun); |
| 3017 | } | 3165 | } |
| 3018 | else if (COMPILEDP (fun)) | 3166 | else if (COMPILEDP (fun)) |
| 3019 | syms_left = AREF (fun, COMPILED_ARGLIST); | 3167 | { |
| 3168 | syms_left = AREF (fun, COMPILED_ARGLIST); | ||
| 3169 | if (INTEGERP (syms_left)) | ||
| 3170 | /* A byte-code object with a non-nil `push args' slot means we | ||
| 3171 | shouldn't bind any arguments, instead just call the byte-code | ||
| 3172 | interpreter directly; it will push arguments as necessary. | ||
| 3173 | |||
| 3174 | Byte-code objects with either a non-existant, or a nil value for | ||
| 3175 | the `push args' slot (the default), have dynamically-bound | ||
| 3176 | arguments, and use the argument-binding code below instead (as do | ||
| 3177 | all interpreted functions, even lexically bound ones). */ | ||
| 3178 | { | ||
| 3179 | /* If we have not actually read the bytecode string | ||
| 3180 | and constants vector yet, fetch them from the file. */ | ||
| 3181 | if (CONSP (AREF (fun, COMPILED_BYTECODE))) | ||
| 3182 | Ffetch_bytecode (fun); | ||
| 3183 | return exec_byte_code (AREF (fun, COMPILED_BYTECODE), | ||
| 3184 | AREF (fun, COMPILED_CONSTANTS), | ||
| 3185 | AREF (fun, COMPILED_STACK_DEPTH), | ||
| 3186 | syms_left, | ||
| 3187 | nargs, arg_vector); | ||
| 3188 | } | ||
| 3189 | lexenv = Qnil; | ||
| 3190 | } | ||
| 3020 | else | 3191 | else |
| 3021 | abort (); | 3192 | abort (); |
| 3022 | 3193 | ||
| @@ -3033,17 +3204,29 @@ funcall_lambda (Lisp_Object fun, size_t nargs, | |||
| 3033 | rest = 1; | 3204 | rest = 1; |
| 3034 | else if (EQ (next, Qand_optional)) | 3205 | else if (EQ (next, Qand_optional)) |
| 3035 | optional = 1; | 3206 | optional = 1; |
| 3036 | else if (rest) | 3207 | else |
| 3037 | { | 3208 | { |
| 3038 | specbind (next, Flist (nargs - i, &arg_vector[i])); | 3209 | Lisp_Object val; |
| 3039 | i = nargs; | 3210 | if (rest) |
| 3211 | { | ||
| 3212 | val = Flist (nargs - i, &arg_vector[i]); | ||
| 3213 | i = nargs; | ||
| 3214 | } | ||
| 3215 | else if (i < nargs) | ||
| 3216 | val = arg_vector[i++]; | ||
| 3217 | else if (!optional) | ||
| 3218 | xsignal2 (Qwrong_number_of_arguments, fun, make_number (nargs)); | ||
| 3219 | else | ||
| 3220 | val = Qnil; | ||
| 3221 | |||
| 3222 | /* Bind the argument. */ | ||
| 3223 | if (!NILP (lexenv) && SYMBOLP (next)) | ||
| 3224 | /* Lexically bind NEXT by adding it to the lexenv alist. */ | ||
| 3225 | lexenv = Fcons (Fcons (next, val), lexenv); | ||
| 3226 | else | ||
| 3227 | /* Dynamically bind NEXT. */ | ||
| 3228 | specbind (next, val); | ||
| 3040 | } | 3229 | } |
| 3041 | else if (i < nargs) | ||
| 3042 | specbind (next, arg_vector[i++]); | ||
| 3043 | else if (!optional) | ||
| 3044 | xsignal2 (Qwrong_number_of_arguments, fun, make_number (nargs)); | ||
| 3045 | else | ||
| 3046 | specbind (next, Qnil); | ||
| 3047 | } | 3230 | } |
| 3048 | 3231 | ||
| 3049 | if (!NILP (syms_left)) | 3232 | if (!NILP (syms_left)) |
| @@ -3051,6 +3234,10 @@ funcall_lambda (Lisp_Object fun, size_t nargs, | |||
| 3051 | else if (i < nargs) | 3234 | else if (i < nargs) |
| 3052 | xsignal2 (Qwrong_number_of_arguments, fun, make_number (nargs)); | 3235 | xsignal2 (Qwrong_number_of_arguments, fun, make_number (nargs)); |
| 3053 | 3236 | ||
| 3237 | if (!EQ (lexenv, Vinternal_interpreter_environment)) | ||
| 3238 | /* Instantiate a new lexical environment. */ | ||
| 3239 | specbind (Qinternal_interpreter_environment, lexenv); | ||
| 3240 | |||
| 3054 | if (CONSP (fun)) | 3241 | if (CONSP (fun)) |
| 3055 | val = Fprogn (XCDR (XCDR (fun))); | 3242 | val = Fprogn (XCDR (XCDR (fun))); |
| 3056 | else | 3243 | else |
| @@ -3059,9 +3246,10 @@ funcall_lambda (Lisp_Object fun, size_t nargs, | |||
| 3059 | and constants vector yet, fetch them from the file. */ | 3246 | and constants vector yet, fetch them from the file. */ |
| 3060 | if (CONSP (AREF (fun, COMPILED_BYTECODE))) | 3247 | if (CONSP (AREF (fun, COMPILED_BYTECODE))) |
| 3061 | Ffetch_bytecode (fun); | 3248 | Ffetch_bytecode (fun); |
| 3062 | val = Fbyte_code (AREF (fun, COMPILED_BYTECODE), | 3249 | val = exec_byte_code (AREF (fun, COMPILED_BYTECODE), |
| 3063 | AREF (fun, COMPILED_CONSTANTS), | 3250 | AREF (fun, COMPILED_CONSTANTS), |
| 3064 | AREF (fun, COMPILED_STACK_DEPTH)); | 3251 | AREF (fun, COMPILED_STACK_DEPTH), |
| 3252 | Qnil, 0, 0); | ||
| 3065 | } | 3253 | } |
| 3066 | 3254 | ||
| 3067 | return unbind_to (count, val); | 3255 | return unbind_to (count, val); |
| @@ -3297,6 +3485,17 @@ unbind_to (int count, Lisp_Object value) | |||
| 3297 | UNGCPRO; | 3485 | UNGCPRO; |
| 3298 | return value; | 3486 | return value; |
| 3299 | } | 3487 | } |
| 3488 | |||
| 3489 | DEFUN ("special-variable-p", Fspecial_variable_p, Sspecial_variable_p, 1, 1, 0, | ||
| 3490 | doc: /* Return non-nil if SYMBOL's global binding has been declared special. | ||
| 3491 | A special variable is one that will be bound dynamically, even in a | ||
| 3492 | context where binding is lexical by default. */) | ||
| 3493 | (Lisp_Object symbol) | ||
| 3494 | { | ||
| 3495 | CHECK_SYMBOL (symbol); | ||
| 3496 | return XSYMBOL (symbol)->declared_special ? Qt : Qnil; | ||
| 3497 | } | ||
| 3498 | |||
| 3300 | 3499 | ||
| 3301 | DEFUN ("backtrace-debug", Fbacktrace_debug, Sbacktrace_debug, 2, 2, 0, | 3500 | DEFUN ("backtrace-debug", Fbacktrace_debug, Sbacktrace_debug, 2, 2, 0, |
| 3302 | doc: /* Set the debug-on-exit flag of eval frame LEVEL levels down to FLAG. | 3501 | doc: /* Set the debug-on-exit flag of eval frame LEVEL levels down to FLAG. |
| @@ -3437,6 +3636,8 @@ mark_backtrace (void) | |||
| 3437 | } | 3636 | } |
| 3438 | } | 3637 | } |
| 3439 | 3638 | ||
| 3639 | EXFUN (Funintern, 2); | ||
| 3640 | |||
| 3440 | void | 3641 | void |
| 3441 | syms_of_eval (void) | 3642 | syms_of_eval (void) |
| 3442 | { | 3643 | { |
| @@ -3509,6 +3710,9 @@ before making `inhibit-quit' nil. */); | |||
| 3509 | Qand_optional = intern_c_string ("&optional"); | 3710 | Qand_optional = intern_c_string ("&optional"); |
| 3510 | staticpro (&Qand_optional); | 3711 | staticpro (&Qand_optional); |
| 3511 | 3712 | ||
| 3713 | Qclosure = intern_c_string ("closure"); | ||
| 3714 | staticpro (&Qclosure); | ||
| 3715 | |||
| 3512 | Qdebug = intern_c_string ("debug"); | 3716 | Qdebug = intern_c_string ("debug"); |
| 3513 | staticpro (&Qdebug); | 3717 | staticpro (&Qdebug); |
| 3514 | 3718 | ||
| @@ -3576,6 +3780,28 @@ DECL is a list `(declare ...)' containing the declarations. | |||
| 3576 | The value the function returns is not used. */); | 3780 | The value the function returns is not used. */); |
| 3577 | Vmacro_declaration_function = Qnil; | 3781 | Vmacro_declaration_function = Qnil; |
| 3578 | 3782 | ||
| 3783 | /* When lexical binding is being used, | ||
| 3784 | vinternal_interpreter_environment is non-nil, and contains an alist | ||
| 3785 | of lexically-bound variable, or (t), indicating an empty | ||
| 3786 | environment. The lisp name of this variable would be | ||
| 3787 | `internal-interpreter-environment' if it weren't hidden. | ||
| 3788 | Every element of this list can be either a cons (VAR . VAL) | ||
| 3789 | specifying a lexical binding, or a single symbol VAR indicating | ||
| 3790 | that this variable should use dynamic scoping. */ | ||
| 3791 | Qinternal_interpreter_environment | ||
| 3792 | = intern_c_string ("internal-interpreter-environment"); | ||
| 3793 | staticpro (&Qinternal_interpreter_environment); | ||
| 3794 | DEFVAR_LISP ("internal-interpreter-environment", | ||
| 3795 | Vinternal_interpreter_environment, | ||
| 3796 | doc: /* If non-nil, the current lexical environment of the lisp interpreter. | ||
| 3797 | When lexical binding is not being used, this variable is nil. | ||
| 3798 | A value of `(t)' indicates an empty environment, otherwise it is an | ||
| 3799 | alist of active lexical bindings. */); | ||
| 3800 | Vinternal_interpreter_environment = Qnil; | ||
| 3801 | /* Don't export this variable to Elisp, so noone can mess with it | ||
| 3802 | (Just imagine if someone makes it buffer-local). */ | ||
| 3803 | Funintern (Qinternal_interpreter_environment, Qnil); | ||
| 3804 | |||
| 3579 | Vrun_hooks = intern_c_string ("run-hooks"); | 3805 | Vrun_hooks = intern_c_string ("run-hooks"); |
| 3580 | staticpro (&Vrun_hooks); | 3806 | staticpro (&Vrun_hooks); |
| 3581 | 3807 | ||
| @@ -3625,4 +3851,6 @@ The value the function returns is not used. */); | |||
| 3625 | defsubr (&Sbacktrace_debug); | 3851 | defsubr (&Sbacktrace_debug); |
| 3626 | defsubr (&Sbacktrace); | 3852 | defsubr (&Sbacktrace); |
| 3627 | defsubr (&Sbacktrace_frame); | 3853 | defsubr (&Sbacktrace_frame); |
| 3854 | defsubr (&Sspecial_variable_p); | ||
| 3855 | defsubr (&Sfunctionp); | ||
| 3628 | } | 3856 | } |
| @@ -510,7 +510,7 @@ concat (size_t nargs, Lisp_Object *args, | |||
| 510 | Lisp_Object ch; | 510 | Lisp_Object ch; |
| 511 | EMACS_INT this_len_byte; | 511 | EMACS_INT this_len_byte; |
| 512 | 512 | ||
| 513 | if (VECTORP (this)) | 513 | if (VECTORP (this) || COMPILEDP (this)) |
| 514 | for (i = 0; i < len; i++) | 514 | for (i = 0; i < len; i++) |
| 515 | { | 515 | { |
| 516 | ch = AREF (this, i); | 516 | ch = AREF (this, i); |
| @@ -2297,7 +2297,7 @@ mapcar1 (EMACS_INT leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq) | |||
| 2297 | 1) lists are not relocated and 2) the list is marked via `seq' so will not | 2297 | 1) lists are not relocated and 2) the list is marked via `seq' so will not |
| 2298 | be freed */ | 2298 | be freed */ |
| 2299 | 2299 | ||
| 2300 | if (VECTORP (seq)) | 2300 | if (VECTORP (seq) || COMPILEDP (seq)) |
| 2301 | { | 2301 | { |
| 2302 | for (i = 0; i < leni; i++) | 2302 | for (i = 0; i < leni; i++) |
| 2303 | { | 2303 | { |
diff --git a/src/image.c b/src/image.c index 25929d1004c..b37ba398d83 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -831,9 +831,7 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords, | |||
| 831 | 831 | ||
| 832 | case IMAGE_FUNCTION_VALUE: | 832 | case IMAGE_FUNCTION_VALUE: |
| 833 | value = indirect_function (value); | 833 | value = indirect_function (value); |
| 834 | if (SUBRP (value) | 834 | if (!NILP (Ffunctionp (value))) |
| 835 | || COMPILEDP (value) | ||
| 836 | || (CONSP (value) && EQ (XCAR (value), Qlambda))) | ||
| 837 | break; | 835 | break; |
| 838 | return 0; | 836 | return 0; |
| 839 | 837 | ||
diff --git a/src/keyboard.c b/src/keyboard.c index 70098d46ebb..d307250b868 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -1134,7 +1134,7 @@ command_loop_2 (Lisp_Object ignore) | |||
| 1134 | static Lisp_Object | 1134 | static Lisp_Object |
| 1135 | top_level_2 (void) | 1135 | top_level_2 (void) |
| 1136 | { | 1136 | { |
| 1137 | return Feval (Vtop_level); | 1137 | return Feval (Vtop_level, Qnil); |
| 1138 | } | 1138 | } |
| 1139 | 1139 | ||
| 1140 | Lisp_Object | 1140 | Lisp_Object |
| @@ -3095,7 +3095,7 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event | |||
| 3095 | help_form_saved_window_configs); | 3095 | help_form_saved_window_configs); |
| 3096 | record_unwind_protect (read_char_help_form_unwind, Qnil); | 3096 | record_unwind_protect (read_char_help_form_unwind, Qnil); |
| 3097 | 3097 | ||
| 3098 | tem0 = Feval (Vhelp_form); | 3098 | tem0 = Feval (Vhelp_form, Qnil); |
| 3099 | if (STRINGP (tem0)) | 3099 | if (STRINGP (tem0)) |
| 3100 | internal_with_output_to_temp_buffer ("*Help*", print_help, tem0); | 3100 | internal_with_output_to_temp_buffer ("*Help*", print_help, tem0); |
| 3101 | 3101 | ||
| @@ -7571,6 +7571,12 @@ menu_item_eval_property_1 (Lisp_Object arg) | |||
| 7571 | return Qnil; | 7571 | return Qnil; |
| 7572 | } | 7572 | } |
| 7573 | 7573 | ||
| 7574 | static Lisp_Object | ||
| 7575 | eval_dyn (Lisp_Object form) | ||
| 7576 | { | ||
| 7577 | return Feval (form, Qnil); | ||
| 7578 | } | ||
| 7579 | |||
| 7574 | /* Evaluate an expression and return the result (or nil if something | 7580 | /* Evaluate an expression and return the result (or nil if something |
| 7575 | went wrong). Used to evaluate dynamic parts of menu items. */ | 7581 | went wrong). Used to evaluate dynamic parts of menu items. */ |
| 7576 | Lisp_Object | 7582 | Lisp_Object |
| @@ -7579,7 +7585,7 @@ menu_item_eval_property (Lisp_Object sexpr) | |||
| 7579 | int count = SPECPDL_INDEX (); | 7585 | int count = SPECPDL_INDEX (); |
| 7580 | Lisp_Object val; | 7586 | Lisp_Object val; |
| 7581 | specbind (Qinhibit_redisplay, Qt); | 7587 | specbind (Qinhibit_redisplay, Qt); |
| 7582 | val = internal_condition_case_1 (Feval, sexpr, Qerror, | 7588 | val = internal_condition_case_1 (eval_dyn, sexpr, Qerror, |
| 7583 | menu_item_eval_property_1); | 7589 | menu_item_eval_property_1); |
| 7584 | return unbind_to (count, val); | 7590 | return unbind_to (count, val); |
| 7585 | } | 7591 | } |
diff --git a/src/lisp.h b/src/lisp.h index 63f346f6a25..dfaa3fd01f0 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -1016,6 +1016,10 @@ struct Lisp_Symbol | |||
| 1016 | /* Interned state of the symbol. This is an enumerator from | 1016 | /* Interned state of the symbol. This is an enumerator from |
| 1017 | enum symbol_interned. */ | 1017 | enum symbol_interned. */ |
| 1018 | unsigned interned : 2; | 1018 | unsigned interned : 2; |
| 1019 | |||
| 1020 | /* Non-zero means that this variable has been explicitly declared | ||
| 1021 | special (with `defvar' etc), and shouldn't be lexically bound. */ | ||
| 1022 | unsigned declared_special : 1; | ||
| 1019 | 1023 | ||
| 1020 | /* The symbol's name, as a Lisp string. | 1024 | /* The symbol's name, as a Lisp string. |
| 1021 | 1025 | ||
| @@ -2814,7 +2818,7 @@ extern void syms_of_lread (void); | |||
| 2814 | 2818 | ||
| 2815 | /* Defined in eval.c. */ | 2819 | /* Defined in eval.c. */ |
| 2816 | extern Lisp_Object Qautoload, Qexit, Qinteractive, Qcommandp, Qdefun, Qmacro; | 2820 | extern Lisp_Object Qautoload, Qexit, Qinteractive, Qcommandp, Qdefun, Qmacro; |
| 2817 | extern Lisp_Object Qinhibit_quit; | 2821 | extern Lisp_Object Qinhibit_quit, Qclosure; |
| 2818 | extern Lisp_Object Vautoload_queue; | 2822 | extern Lisp_Object Vautoload_queue; |
| 2819 | extern Lisp_Object Vsignaling_function; | 2823 | extern Lisp_Object Vsignaling_function; |
| 2820 | extern int handling_signal; | 2824 | extern int handling_signal; |
| @@ -2844,7 +2848,9 @@ extern void xsignal2 (Lisp_Object, Lisp_Object, Lisp_Object) NO_RETURN; | |||
| 2844 | extern void xsignal3 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) NO_RETURN; | 2848 | extern void xsignal3 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) NO_RETURN; |
| 2845 | extern void signal_error (const char *, Lisp_Object) NO_RETURN; | 2849 | extern void signal_error (const char *, Lisp_Object) NO_RETURN; |
| 2846 | EXFUN (Fcommandp, 2); | 2850 | EXFUN (Fcommandp, 2); |
| 2847 | EXFUN (Feval, 1); | 2851 | EXFUN (Ffunctionp, 1); |
| 2852 | EXFUN (Feval, 2); | ||
| 2853 | extern Lisp_Object eval_sub (Lisp_Object form); | ||
| 2848 | EXFUN (Fapply, MANY); | 2854 | EXFUN (Fapply, MANY); |
| 2849 | EXFUN (Ffuncall, MANY); | 2855 | EXFUN (Ffuncall, MANY); |
| 2850 | EXFUN (Fbacktrace, 0); | 2856 | EXFUN (Fbacktrace, 0); |
| @@ -3264,6 +3270,8 @@ extern struct byte_stack *byte_stack_list; | |||
| 3264 | extern void mark_byte_stack (void); | 3270 | extern void mark_byte_stack (void); |
| 3265 | #endif | 3271 | #endif |
| 3266 | extern void unmark_byte_stack (void); | 3272 | extern void unmark_byte_stack (void); |
| 3273 | extern Lisp_Object exec_byte_code (Lisp_Object, Lisp_Object, Lisp_Object, | ||
| 3274 | Lisp_Object, int, Lisp_Object *); | ||
| 3267 | 3275 | ||
| 3268 | /* Defined in macros.c */ | 3276 | /* Defined in macros.c */ |
| 3269 | extern Lisp_Object Qexecute_kbd_macro; | 3277 | extern Lisp_Object Qexecute_kbd_macro; |
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; |
diff --git a/src/minibuf.c b/src/minibuf.c index 7bed9bb2f2d..4adf665f8f4 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -971,7 +971,8 @@ Such arguments are used as in `read-from-minibuffer'.) */) | |||
| 971 | { | 971 | { |
| 972 | return Feval (read_minibuf (Vread_expression_map, initial_contents, | 972 | return Feval (read_minibuf (Vread_expression_map, initial_contents, |
| 973 | prompt, Qnil, 1, Qread_expression_history, | 973 | prompt, Qnil, 1, Qread_expression_history, |
| 974 | make_number (0), Qnil, 0, 0)); | 974 | make_number (0), Qnil, 0, 0), |
| 975 | Qnil); | ||
| 975 | } | 976 | } |
| 976 | 977 | ||
| 977 | /* Functions that use the minibuffer to read various things. */ | 978 | /* Functions that use the minibuffer to read various things. */ |
diff --git a/src/print.c b/src/print.c index dd3d1c9bbb2..3e0e168381b 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -521,6 +521,7 @@ temp_output_buffer_setup (const char *bufname) | |||
| 521 | specbind (Qstandard_output, buf); | 521 | specbind (Qstandard_output, buf); |
| 522 | } | 522 | } |
| 523 | 523 | ||
| 524 | /* FIXME: Use Lisp's with-output-to-temp-buffer instead! */ | ||
| 524 | Lisp_Object | 525 | Lisp_Object |
| 525 | internal_with_output_to_temp_buffer (const char *bufname, Lisp_Object (*function) (Lisp_Object), Lisp_Object args) | 526 | internal_with_output_to_temp_buffer (const char *bufname, Lisp_Object (*function) (Lisp_Object), Lisp_Object args) |
| 526 | { | 527 | { |
| @@ -542,60 +543,6 @@ internal_with_output_to_temp_buffer (const char *bufname, Lisp_Object (*function | |||
| 542 | 543 | ||
| 543 | return unbind_to (count, val); | 544 | return unbind_to (count, val); |
| 544 | } | 545 | } |
| 545 | |||
| 546 | DEFUN ("with-output-to-temp-buffer", | ||
| 547 | Fwith_output_to_temp_buffer, Swith_output_to_temp_buffer, | ||
| 548 | 1, UNEVALLED, 0, | ||
| 549 | doc: /* Bind `standard-output' to buffer BUFNAME, eval BODY, then show that buffer. | ||
| 550 | |||
| 551 | This construct makes buffer BUFNAME empty before running BODY. | ||
| 552 | It does not make the buffer current for BODY. | ||
| 553 | Instead it binds `standard-output' to that buffer, so that output | ||
| 554 | generated with `prin1' and similar functions in BODY goes into | ||
| 555 | the buffer. | ||
| 556 | |||
| 557 | At the end of BODY, this marks buffer BUFNAME unmodifed and displays | ||
| 558 | it in a window, but does not select it. The normal way to do this is | ||
| 559 | by calling `display-buffer', then running `temp-buffer-show-hook'. | ||
| 560 | However, if `temp-buffer-show-function' is non-nil, it calls that | ||
| 561 | function instead (and does not run `temp-buffer-show-hook'). The | ||
| 562 | function gets one argument, the buffer to display. | ||
| 563 | |||
| 564 | The return value of `with-output-to-temp-buffer' is the value of the | ||
| 565 | last form in BODY. If BODY does not finish normally, the buffer | ||
| 566 | BUFNAME is not displayed. | ||
| 567 | |||
| 568 | This runs the hook `temp-buffer-setup-hook' before BODY, | ||
| 569 | with the buffer BUFNAME temporarily current. It runs the hook | ||
| 570 | `temp-buffer-show-hook' after displaying buffer BUFNAME, with that | ||
| 571 | buffer temporarily current, and the window that was used to display it | ||
| 572 | temporarily selected. But it doesn't run `temp-buffer-show-hook' | ||
| 573 | if it uses `temp-buffer-show-function'. | ||
| 574 | |||
| 575 | usage: (with-output-to-temp-buffer BUFNAME BODY...) */) | ||
| 576 | (Lisp_Object args) | ||
| 577 | { | ||
| 578 | struct gcpro gcpro1; | ||
| 579 | Lisp_Object name; | ||
| 580 | int count = SPECPDL_INDEX (); | ||
| 581 | Lisp_Object buf, val; | ||
| 582 | |||
| 583 | GCPRO1(args); | ||
| 584 | name = Feval (Fcar (args)); | ||
| 585 | CHECK_STRING (name); | ||
| 586 | temp_output_buffer_setup (SSDATA (name)); | ||
| 587 | buf = Vstandard_output; | ||
| 588 | UNGCPRO; | ||
| 589 | |||
| 590 | val = Fprogn (XCDR (args)); | ||
| 591 | |||
| 592 | GCPRO1 (val); | ||
| 593 | temp_output_buffer_show (buf); | ||
| 594 | UNGCPRO; | ||
| 595 | |||
| 596 | return unbind_to (count, val); | ||
| 597 | } | ||
| 598 | |||
| 599 | 546 | ||
| 600 | static void print (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag); | 547 | static void print (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag); |
| 601 | static void print_preprocess (Lisp_Object obj); | 548 | static void print_preprocess (Lisp_Object obj); |
| @@ -2289,6 +2236,4 @@ priorities. */); | |||
| 2289 | 2236 | ||
| 2290 | print_prune_charset_plist = Qnil; | 2237 | print_prune_charset_plist = Qnil; |
| 2291 | staticpro (&print_prune_charset_plist); | 2238 | staticpro (&print_prune_charset_plist); |
| 2292 | |||
| 2293 | defsubr (&Swith_output_to_temp_buffer); | ||
| 2294 | } | 2239 | } |
diff --git a/src/window.c b/src/window.c index 0d299b7cd93..5ca46dd3316 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -3705,6 +3705,16 @@ temp_output_buffer_show (register Lisp_Object buf) | |||
| 3705 | } | 3705 | } |
| 3706 | } | 3706 | } |
| 3707 | } | 3707 | } |
| 3708 | |||
| 3709 | DEFUN ("internal-temp-output-buffer-show", | ||
| 3710 | Ftemp_output_buffer_show, Stemp_output_buffer_show, | ||
| 3711 | 1, 1, 0, | ||
| 3712 | doc: /* Internal function for `with-output-to-temp-buffer''. */) | ||
| 3713 | (Lisp_Object buf) | ||
| 3714 | { | ||
| 3715 | temp_output_buffer_show (buf); | ||
| 3716 | return Qnil; | ||
| 3717 | } | ||
| 3708 | 3718 | ||
| 3709 | static void | 3719 | static void |
| 3710 | make_dummy_parent (Lisp_Object window) | 3720 | make_dummy_parent (Lisp_Object window) |
| @@ -6390,28 +6400,6 @@ redirection (see `redirect-frame-focus'). */) | |||
| 6390 | return (tem); | 6400 | return (tem); |
| 6391 | } | 6401 | } |
| 6392 | 6402 | ||
| 6393 | DEFUN ("save-window-excursion", Fsave_window_excursion, Ssave_window_excursion, | ||
| 6394 | 0, UNEVALLED, 0, | ||
| 6395 | doc: /* Execute BODY, preserving window sizes and contents. | ||
| 6396 | Return the value of the last form in BODY. | ||
| 6397 | Restore which buffer appears in which window, where display starts, | ||
| 6398 | and the value of point and mark for each window. | ||
| 6399 | Also restore the choice of selected window. | ||
| 6400 | Also restore which buffer is current. | ||
| 6401 | Does not restore the value of point in current buffer. | ||
| 6402 | usage: (save-window-excursion BODY...) */) | ||
| 6403 | (Lisp_Object args) | ||
| 6404 | { | ||
| 6405 | register Lisp_Object val; | ||
| 6406 | register int count = SPECPDL_INDEX (); | ||
| 6407 | |||
| 6408 | record_unwind_protect (Fset_window_configuration, | ||
| 6409 | Fcurrent_window_configuration (Qnil)); | ||
| 6410 | val = Fprogn (args); | ||
| 6411 | return unbind_to (count, val); | ||
| 6412 | } | ||
| 6413 | |||
| 6414 | |||
| 6415 | 6403 | ||
| 6416 | /*********************************************************************** | 6404 | /*********************************************************************** |
| 6417 | Window Split Tree | 6405 | Window Split Tree |
| @@ -7167,6 +7155,7 @@ frame to be redrawn only if it is a tty frame. */); | |||
| 7167 | defsubr (&Sset_window_buffer); | 7155 | defsubr (&Sset_window_buffer); |
| 7168 | defsubr (&Sselect_window); | 7156 | defsubr (&Sselect_window); |
| 7169 | defsubr (&Sforce_window_update); | 7157 | defsubr (&Sforce_window_update); |
| 7158 | defsubr (&Stemp_output_buffer_show); | ||
| 7170 | defsubr (&Ssplit_window); | 7159 | defsubr (&Ssplit_window); |
| 7171 | defsubr (&Senlarge_window); | 7160 | defsubr (&Senlarge_window); |
| 7172 | defsubr (&Sshrink_window); | 7161 | defsubr (&Sshrink_window); |
| @@ -7185,7 +7174,6 @@ frame to be redrawn only if it is a tty frame. */); | |||
| 7185 | defsubr (&Swindow_configuration_frame); | 7174 | defsubr (&Swindow_configuration_frame); |
| 7186 | defsubr (&Sset_window_configuration); | 7175 | defsubr (&Sset_window_configuration); |
| 7187 | defsubr (&Scurrent_window_configuration); | 7176 | defsubr (&Scurrent_window_configuration); |
| 7188 | defsubr (&Ssave_window_excursion); | ||
| 7189 | defsubr (&Swindow_tree); | 7177 | defsubr (&Swindow_tree); |
| 7190 | defsubr (&Sset_window_margins); | 7178 | defsubr (&Sset_window_margins); |
| 7191 | defsubr (&Swindow_margins); | 7179 | defsubr (&Swindow_margins); |
diff --git a/src/window.h b/src/window.h index f788e126d6d..ad627aca340 100644 --- a/src/window.h +++ b/src/window.h | |||
| @@ -853,7 +853,6 @@ EXFUN (Fwindow_minibuffer_p, 1); | |||
| 853 | EXFUN (Fdelete_window, 1); | 853 | EXFUN (Fdelete_window, 1); |
| 854 | EXFUN (Fwindow_buffer, 1); | 854 | EXFUN (Fwindow_buffer, 1); |
| 855 | EXFUN (Fget_buffer_window, 2); | 855 | EXFUN (Fget_buffer_window, 2); |
| 856 | EXFUN (Fsave_window_excursion, UNEVALLED); | ||
| 857 | EXFUN (Fset_window_configuration, 1); | 856 | EXFUN (Fset_window_configuration, 1); |
| 858 | EXFUN (Fcurrent_window_configuration, 1); | 857 | EXFUN (Fcurrent_window_configuration, 1); |
| 859 | extern int compare_window_configurations (Lisp_Object, Lisp_Object, int); | 858 | extern int compare_window_configurations (Lisp_Object, Lisp_Object, int); |