diff options
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 128 |
1 files changed, 67 insertions, 61 deletions
diff --git a/src/eval.c b/src/eval.c index e5900382dee..fe2708b1bbc 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -354,10 +354,11 @@ usage: (or CONDITIONS...) */) | |||
| 354 | 354 | ||
| 355 | while (CONSP (args)) | 355 | while (CONSP (args)) |
| 356 | { | 356 | { |
| 357 | val = eval_sub (XCAR (args)); | 357 | Lisp_Object arg = XCAR (args); |
| 358 | args = XCDR (args); | ||
| 359 | val = eval_sub (arg); | ||
| 358 | if (!NILP (val)) | 360 | if (!NILP (val)) |
| 359 | break; | 361 | break; |
| 360 | args = XCDR (args); | ||
| 361 | } | 362 | } |
| 362 | 363 | ||
| 363 | return val; | 364 | return val; |
| @@ -374,10 +375,11 @@ usage: (and CONDITIONS...) */) | |||
| 374 | 375 | ||
| 375 | while (CONSP (args)) | 376 | while (CONSP (args)) |
| 376 | { | 377 | { |
| 377 | val = eval_sub (XCAR (args)); | 378 | Lisp_Object arg = XCAR (args); |
| 379 | args = XCDR (args); | ||
| 380 | val = eval_sub (arg); | ||
| 378 | if (NILP (val)) | 381 | if (NILP (val)) |
| 379 | break; | 382 | break; |
| 380 | args = XCDR (args); | ||
| 381 | } | 383 | } |
| 382 | 384 | ||
| 383 | return val; | 385 | return val; |
| @@ -397,7 +399,7 @@ usage: (if COND THEN ELSE...) */) | |||
| 397 | 399 | ||
| 398 | if (!NILP (cond)) | 400 | if (!NILP (cond)) |
| 399 | return eval_sub (Fcar (XCDR (args))); | 401 | return eval_sub (Fcar (XCDR (args))); |
| 400 | return Fprogn (XCDR (XCDR (args))); | 402 | return Fprogn (Fcdr (XCDR (args))); |
| 401 | } | 403 | } |
| 402 | 404 | ||
| 403 | DEFUN ("cond", Fcond, Scond, 0, UNEVALLED, 0, | 405 | DEFUN ("cond", Fcond, Scond, 0, UNEVALLED, 0, |
| @@ -439,8 +441,9 @@ usage: (progn BODY...) */) | |||
| 439 | 441 | ||
| 440 | while (CONSP (body)) | 442 | while (CONSP (body)) |
| 441 | { | 443 | { |
| 442 | val = eval_sub (XCAR (body)); | 444 | Lisp_Object form = XCAR (body); |
| 443 | body = XCDR (body); | 445 | body = XCDR (body); |
| 446 | val = eval_sub (form); | ||
| 444 | } | 447 | } |
| 445 | 448 | ||
| 446 | return val; | 449 | return val; |
| @@ -488,35 +491,26 @@ The return value of the `setq' form is the value of the last VAL. | |||
| 488 | usage: (setq [SYM VAL]...) */) | 491 | usage: (setq [SYM VAL]...) */) |
| 489 | (Lisp_Object args) | 492 | (Lisp_Object args) |
| 490 | { | 493 | { |
| 491 | Lisp_Object val, sym, lex_binding; | 494 | Lisp_Object val = args, tail = args; |
| 492 | 495 | ||
| 493 | val = args; | 496 | for (EMACS_INT nargs = 0; CONSP (tail); nargs += 2) |
| 494 | if (CONSP (args)) | ||
| 495 | { | 497 | { |
| 496 | Lisp_Object args_left = args; | 498 | Lisp_Object sym = XCAR (tail), lex_binding; |
| 497 | Lisp_Object numargs = Flength (args); | 499 | tail = XCDR (tail); |
| 498 | 500 | if (!CONSP (tail)) | |
| 499 | if (XINT (numargs) & 1) | 501 | xsignal2 (Qwrong_number_of_arguments, Qsetq, make_number (nargs + 1)); |
| 500 | xsignal2 (Qwrong_number_of_arguments, Qsetq, numargs); | 502 | Lisp_Object arg = XCAR (tail); |
| 501 | 503 | tail = XCDR (tail); | |
| 502 | do | 504 | val = eval_sub (arg); |
| 503 | { | 505 | /* Like for eval_sub, we do not check declared_special here since |
| 504 | val = eval_sub (Fcar (XCDR (args_left))); | 506 | it's been done when let-binding. */ |
| 505 | sym = XCAR (args_left); | 507 | if (!NILP (Vinternal_interpreter_environment) /* Mere optimization! */ |
| 506 | 508 | && SYMBOLP (sym) | |
| 507 | /* Like for eval_sub, we do not check declared_special here since | 509 | && !NILP (lex_binding |
| 508 | it's been done when let-binding. */ | 510 | = Fassq (sym, Vinternal_interpreter_environment))) |
| 509 | if (!NILP (Vinternal_interpreter_environment) /* Mere optimization! */ | 511 | XSETCDR (lex_binding, val); /* SYM is lexically bound. */ |
| 510 | && SYMBOLP (sym) | 512 | else |
| 511 | && !NILP (lex_binding | 513 | Fset (sym, val); /* SYM is dynamically bound. */ |
| 512 | = Fassq (sym, Vinternal_interpreter_environment))) | ||
| 513 | XSETCDR (lex_binding, val); /* SYM is lexically bound. */ | ||
| 514 | else | ||
| 515 | Fset (sym, val); /* SYM is dynamically bound. */ | ||
| 516 | |||
| 517 | args_left = Fcdr (XCDR (args_left)); | ||
| 518 | } | ||
| 519 | while (CONSP (args_left)); | ||
| 520 | } | 514 | } |
| 521 | 515 | ||
| 522 | return val; | 516 | return val; |
| @@ -535,7 +529,7 @@ of unexpected results when a quoted object is modified. | |||
| 535 | usage: (quote ARG) */) | 529 | usage: (quote ARG) */) |
| 536 | (Lisp_Object args) | 530 | (Lisp_Object args) |
| 537 | { | 531 | { |
| 538 | if (CONSP (XCDR (args))) | 532 | if (!NILP (XCDR (args))) |
| 539 | xsignal2 (Qwrong_number_of_arguments, Qquote, Flength (args)); | 533 | xsignal2 (Qwrong_number_of_arguments, Qquote, Flength (args)); |
| 540 | return XCAR (args); | 534 | return XCAR (args); |
| 541 | } | 535 | } |
| @@ -549,7 +543,7 @@ usage: (function ARG) */) | |||
| 549 | { | 543 | { |
| 550 | Lisp_Object quoted = XCAR (args); | 544 | Lisp_Object quoted = XCAR (args); |
| 551 | 545 | ||
| 552 | if (CONSP (XCDR (args))) | 546 | if (!NILP (XCDR (args))) |
| 553 | xsignal2 (Qwrong_number_of_arguments, Qfunction, Flength (args)); | 547 | xsignal2 (Qwrong_number_of_arguments, Qfunction, Flength (args)); |
| 554 | 548 | ||
| 555 | if (!NILP (Vinternal_interpreter_environment) | 549 | if (!NILP (Vinternal_interpreter_environment) |
| @@ -734,9 +728,9 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) | |||
| 734 | sym = XCAR (args); | 728 | sym = XCAR (args); |
| 735 | tail = XCDR (args); | 729 | tail = XCDR (args); |
| 736 | 730 | ||
| 737 | if (CONSP (tail)) | 731 | if (!NILP (tail)) |
| 738 | { | 732 | { |
| 739 | if (CONSP (XCDR (tail)) && CONSP (XCDR (XCDR (tail)))) | 733 | if (!NILP (XCDR (tail)) && !NILP (XCDR (XCDR (tail)))) |
| 740 | error ("Too many arguments"); | 734 | error ("Too many arguments"); |
| 741 | 735 | ||
| 742 | tem = Fdefault_boundp (sym); | 736 | tem = Fdefault_boundp (sym); |
| @@ -803,20 +797,24 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */) | |||
| 803 | Lisp_Object sym, tem; | 797 | Lisp_Object sym, tem; |
| 804 | 798 | ||
| 805 | sym = XCAR (args); | 799 | sym = XCAR (args); |
| 806 | if (CONSP (Fcdr (XCDR (XCDR (args))))) | 800 | Lisp_Object docstring = Qnil; |
| 807 | error ("Too many arguments"); | 801 | if (!NILP (XCDR (XCDR (args)))) |
| 802 | { | ||
| 803 | if (!NILP (XCDR (XCDR (XCDR (args))))) | ||
| 804 | error ("Too many arguments"); | ||
| 805 | docstring = XCAR (XCDR (XCDR (args))); | ||
| 806 | } | ||
| 808 | 807 | ||
| 809 | tem = eval_sub (Fcar (XCDR (args))); | 808 | tem = eval_sub (XCAR (XCDR (args))); |
| 810 | if (!NILP (Vpurify_flag)) | 809 | if (!NILP (Vpurify_flag)) |
| 811 | tem = Fpurecopy (tem); | 810 | tem = Fpurecopy (tem); |
| 812 | Fset_default (sym, tem); | 811 | Fset_default (sym, tem); |
| 813 | XSYMBOL (sym)->declared_special = 1; | 812 | XSYMBOL (sym)->declared_special = 1; |
| 814 | tem = Fcar (XCDR (XCDR (args))); | 813 | if (!NILP (docstring)) |
| 815 | if (!NILP (tem)) | ||
| 816 | { | 814 | { |
| 817 | if (!NILP (Vpurify_flag)) | 815 | if (!NILP (Vpurify_flag)) |
| 818 | tem = Fpurecopy (tem); | 816 | docstring = Fpurecopy (docstring); |
| 819 | Fput (sym, Qvariable_documentation, tem); | 817 | Fput (sym, Qvariable_documentation, docstring); |
| 820 | } | 818 | } |
| 821 | Fput (sym, Qrisky_local_variable, Qt); | 819 | Fput (sym, Qrisky_local_variable, Qt); |
| 822 | LOADHIST_ATTACH (sym); | 820 | LOADHIST_ATTACH (sym); |
| @@ -844,27 +842,29 @@ Each VALUEFORM can refer to the symbols already bound by this VARLIST. | |||
| 844 | usage: (let* VARLIST BODY...) */) | 842 | usage: (let* VARLIST BODY...) */) |
| 845 | (Lisp_Object args) | 843 | (Lisp_Object args) |
| 846 | { | 844 | { |
| 847 | Lisp_Object varlist, var, val, elt, lexenv; | 845 | Lisp_Object var, val, elt, lexenv; |
| 848 | ptrdiff_t count = SPECPDL_INDEX (); | 846 | ptrdiff_t count = SPECPDL_INDEX (); |
| 849 | 847 | ||
| 850 | lexenv = Vinternal_interpreter_environment; | 848 | lexenv = Vinternal_interpreter_environment; |
| 851 | 849 | ||
| 852 | for (varlist = XCAR (args); CONSP (varlist); varlist = XCDR (varlist)) | 850 | Lisp_Object varlist = XCAR (args); |
| 851 | while (CONSP (varlist)) | ||
| 853 | { | 852 | { |
| 854 | maybe_quit (); | 853 | maybe_quit (); |
| 855 | 854 | ||
| 856 | elt = XCAR (varlist); | 855 | elt = XCAR (varlist); |
| 856 | varlist = XCDR (varlist); | ||
| 857 | if (SYMBOLP (elt)) | 857 | if (SYMBOLP (elt)) |
| 858 | { | 858 | { |
| 859 | var = elt; | 859 | var = elt; |
| 860 | val = Qnil; | 860 | val = Qnil; |
| 861 | } | 861 | } |
| 862 | else if (! NILP (Fcdr (Fcdr (elt)))) | ||
| 863 | signal_error ("`let' bindings can have only one value-form", elt); | ||
| 864 | else | 862 | else |
| 865 | { | 863 | { |
| 866 | var = Fcar (elt); | 864 | var = Fcar (elt); |
| 867 | val = eval_sub (Fcar (Fcdr (elt))); | 865 | if (! NILP (Fcdr (XCDR (elt)))) |
| 866 | signal_error ("`let' bindings can have only one value-form", elt); | ||
| 867 | val = eval_sub (Fcar (XCDR (elt))); | ||
| 868 | } | 868 | } |
| 869 | 869 | ||
| 870 | if (!NILP (lexenv) && SYMBOLP (var) | 870 | if (!NILP (lexenv) && SYMBOLP (var) |
| @@ -911,33 +911,37 @@ usage: (let VARLIST BODY...) */) | |||
| 911 | CHECK_LIST (varlist); | 911 | CHECK_LIST (varlist); |
| 912 | 912 | ||
| 913 | /* Make space to hold the values to give the bound variables. */ | 913 | /* Make space to hold the values to give the bound variables. */ |
| 914 | elt = Flength (varlist); | 914 | EMACS_INT varlist_len = XFASTINT (Flength (varlist)); |
| 915 | SAFE_ALLOCA_LISP (temps, XFASTINT (elt)); | 915 | SAFE_ALLOCA_LISP (temps, varlist_len); |
| 916 | ptrdiff_t nvars = varlist_len; | ||
| 916 | 917 | ||
| 917 | /* Compute the values and store them in `temps'. */ | 918 | /* Compute the values and store them in `temps'. */ |
| 918 | 919 | ||
| 919 | for (argnum = 0; CONSP (varlist); varlist = XCDR (varlist)) | 920 | for (argnum = 0; argnum < nvars && CONSP (varlist); argnum++) |
| 920 | { | 921 | { |
| 921 | maybe_quit (); | 922 | maybe_quit (); |
| 922 | elt = XCAR (varlist); | 923 | elt = XCAR (varlist); |
| 924 | varlist = XCDR (varlist); | ||
| 923 | if (SYMBOLP (elt)) | 925 | if (SYMBOLP (elt)) |
| 924 | temps [argnum++] = Qnil; | 926 | temps[argnum] = Qnil; |
| 925 | else if (! NILP (Fcdr (Fcdr (elt)))) | 927 | else if (! NILP (Fcdr (Fcdr (elt)))) |
| 926 | signal_error ("`let' bindings can have only one value-form", elt); | 928 | signal_error ("`let' bindings can have only one value-form", elt); |
| 927 | else | 929 | else |
| 928 | temps [argnum++] = eval_sub (Fcar (Fcdr (elt))); | 930 | temps[argnum] = eval_sub (Fcar (Fcdr (elt))); |
| 929 | } | 931 | } |
| 932 | nvars = argnum; | ||
| 930 | 933 | ||
| 931 | lexenv = Vinternal_interpreter_environment; | 934 | lexenv = Vinternal_interpreter_environment; |
| 932 | 935 | ||
| 933 | varlist = XCAR (args); | 936 | varlist = XCAR (args); |
| 934 | for (argnum = 0; CONSP (varlist); varlist = XCDR (varlist)) | 937 | for (argnum = 0; argnum < nvars && CONSP (varlist); argnum++) |
| 935 | { | 938 | { |
| 936 | Lisp_Object var; | 939 | Lisp_Object var; |
| 937 | 940 | ||
| 938 | elt = XCAR (varlist); | 941 | elt = XCAR (varlist); |
| 942 | varlist = XCDR (varlist); | ||
| 939 | var = SYMBOLP (elt) ? elt : Fcar (elt); | 943 | var = SYMBOLP (elt) ? elt : Fcar (elt); |
| 940 | tem = temps[argnum++]; | 944 | tem = temps[argnum]; |
| 941 | 945 | ||
| 942 | if (!NILP (lexenv) && SYMBOLP (var) | 946 | if (!NILP (lexenv) && SYMBOLP (var) |
| 943 | && !XSYMBOL (var)->declared_special | 947 | && !XSYMBOL (var)->declared_special |
| @@ -2135,6 +2139,7 @@ eval_sub (Lisp_Object form) | |||
| 2135 | 2139 | ||
| 2136 | original_fun = XCAR (form); | 2140 | original_fun = XCAR (form); |
| 2137 | original_args = XCDR (form); | 2141 | original_args = XCDR (form); |
| 2142 | CHECK_LIST (original_args); | ||
| 2138 | 2143 | ||
| 2139 | /* This also protects them from gc. */ | 2144 | /* This also protects them from gc. */ |
| 2140 | count = record_in_backtrace (original_fun, &original_args, UNEVALLED); | 2145 | count = record_in_backtrace (original_fun, &original_args, UNEVALLED); |
| @@ -2176,15 +2181,16 @@ eval_sub (Lisp_Object form) | |||
| 2176 | 2181 | ||
| 2177 | SAFE_ALLOCA_LISP (vals, XINT (numargs)); | 2182 | SAFE_ALLOCA_LISP (vals, XINT (numargs)); |
| 2178 | 2183 | ||
| 2179 | while (!NILP (args_left)) | 2184 | while (CONSP (args_left) && argnum < XINT (numargs)) |
| 2180 | { | 2185 | { |
| 2181 | vals[argnum++] = eval_sub (Fcar (args_left)); | 2186 | Lisp_Object arg = XCAR (args_left); |
| 2182 | args_left = Fcdr (args_left); | 2187 | args_left = XCDR (args_left); |
| 2188 | vals[argnum++] = eval_sub (arg); | ||
| 2183 | } | 2189 | } |
| 2184 | 2190 | ||
| 2185 | set_backtrace_args (specpdl + count, vals, XINT (numargs)); | 2191 | set_backtrace_args (specpdl + count, vals, argnum); |
| 2186 | 2192 | ||
| 2187 | val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals); | 2193 | val = XSUBR (fun)->function.aMANY (argnum, vals); |
| 2188 | 2194 | ||
| 2189 | check_cons_list (); | 2195 | check_cons_list (); |
| 2190 | lisp_eval_depth--; | 2196 | lisp_eval_depth--; |