diff options
author | Andy Wingo <wingo@pobox.com> | 2017-02-28 20:42:45 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2017-02-28 21:01:33 +0100 |
commit | 89ececea95bb4180384e897c0259a5128ed2fc15 (patch) | |
tree | c71fd3da394883223e49b268f4d24fe81ebec951 /libguile/vm-i-system.c | |
parent | f428e93ee7a4be76341444b228585755807b282f (diff) | |
download | guile-89ececea95bb4180384e897c0259a5128ed2fc15.tar.gz |
Better errors for odd-length keyword args
* libguile/vm-i-system.c (bind-kwargs):
* libguile/vm.c (vm_error_kwargs_missing_value):
* libguile/eval.c (error_missing_value)
(prepare_boot_closure_env_for_apply): Adapt to mirror VM behavior.
* libguile/keywords.c (scm_c_bind_keyword_arguments): Likewise.
* module/ice-9/eval.scm (primitive-eval): Update to error on (foo #:kw)
with a "Keyword argument has no value" instead of the horrible "odd
argument list length". Also adapts to the expected args format for
the keyword-argument-error exception printer in all cases. Matches
1.8 optargs behavior also.
* test-suite/standalone/test-scm-c-bind-keyword-arguments.c (test_missing_value):
(missing_value_error_handler): Update test.
* test-suite/tests/optargs.test: Add tests.
Diffstat (limited to 'libguile/vm-i-system.c')
-rw-r--r-- | libguile/vm-i-system.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/libguile/vm-i-system.c b/libguile/vm-i-system.c index 5057fb02b..936f1ee36 100644 --- a/libguile/vm-i-system.c +++ b/libguile/vm-i-system.c @@ -658,15 +658,11 @@ VM_DEFINE_INSTRUCTION (48, bind_kwargs, "bind-kwargs", 5, 0, 0) nkw += FETCH (); kw_and_rest_flags = FETCH (); - VM_ASSERT ((kw_and_rest_flags & F_REST) - || ((sp - (fp - 1) - nkw) % 2) == 0, - vm_error_kwargs_length_not_even (program)) - CHECK_OBJECT (idx); kw = OBJECT_REF (idx); /* Switch NKW to be a negative index below SP. */ - for (nkw = -(sp - (fp - 1) - nkw) + 1; nkw < 0; nkw++) + for (nkw = -(sp - (fp - 1) - nkw) + 1; nkw <= 0; nkw++) { SCM walk; @@ -677,6 +673,9 @@ VM_DEFINE_INSTRUCTION (48, bind_kwargs, "bind-kwargs", 5, 0, 0) if (scm_is_eq (SCM_CAAR (walk), sp[nkw])) { SCM si = SCM_CDAR (walk); + VM_ASSERT (nkw != 0 + || (kw_and_rest_flags & F_ALLOW_OTHER_KEYS), + vm_error_kwargs_missing_value (program, sp[nkw])); LOCAL_SET (SCM_I_INUMP (si) ? SCM_I_INUM (si) : scm_to_long (si), sp[nkw + 1]); break; |