Simplify num argument checks for apply

Avoid calling (length) twice, cleanup, and simplify related code.
This commit is contained in:
Justin Ethier 2021-05-24 12:41:19 -04:00
parent 8526a0676f
commit 6ac96ea5c2
2 changed files with 10 additions and 20 deletions

View file

@ -66,12 +66,11 @@ void gc_init_heap(long heap_size);
* *
*/ */
/**@{*/ /**@{*/
#define Cyc_check_num_args(data, fnc_name, num_args, args) { \ #define Cyc_check_num_args(data, fnc_name, num_expected_args, args, args_len) { \
object l = Cyc_length(data, args); \ if (num_expected_args > args_len) { \
if (num_args > obj_obj2int(l)) { \
char buf[128]; \ char buf[128]; \
snprintf(buf, 127, "Expected %d arguments to %s but received %ld", \ snprintf(buf, 127, "Expected %d arguments to %s but received %d", \
num_args, fnc_name, obj_obj2int(l)); \ num_expected_args, fnc_name, args_len); \
Cyc_rt_raise_msg(data, buf); \ Cyc_rt_raise_msg(data, buf); \
} \ } \
} }

View file

@ -5781,16 +5781,11 @@ object apply_va(void *data, object cont, int argc, object func, ...)
*/ */
object apply(void *data, object cont, object func, object args) object apply(void *data, object cont, object func, object args)
{ {
object count; int count;
//printf("DEBUG apply: ");
//Cyc_display(data, args);
//printf("\n");
if (!is_object_type(func)) { if (!is_object_type(func)) {
Cyc_rt_raise2(data, "Call of non-procedure: ", func); Cyc_rt_raise2(data, "Call of non-procedure: ", func);
} }
// Causes problems...
//Cyc_check_pair_or_null(args);
switch (type_of(func)) { switch (type_of(func)) {
case primitive_tag: case primitive_tag:
@ -5798,18 +5793,14 @@ object apply(void *data, object cont, object func, object args)
case closure0_tag: case closure0_tag:
case closure1_tag: case closure1_tag:
case closureN_tag: case closureN_tag:
count = Cyc_length(data, args); count = obj_obj2int(Cyc_length(data, args));
if (func == Cyc_glo_call_cc) { if (func == Cyc_glo_call_cc) {
// make_pair(c, cont, args); Cyc_check_num_args(data, "<procedure>", 1, args, count);
//Cyc_display(data, args, stderr); dispatch(data, count, ((closure) func)->fn, func, cont,
// args = &c;
//Cyc_display(data, &c, stderr);
Cyc_check_num_args(data, "<procedure>", 1, args);
dispatch(data, obj_obj2int(count), ((closure) func)->fn, func, cont,
args); args);
} else { } else {
Cyc_check_num_args(data, "<procedure>", ((closure) func)->num_args, args); // TODO: could be more efficient, eg: cyc_length(args) is called twice. Cyc_check_num_args(data, "<procedure>", ((closure) func)->num_args, args, count);
dispatch(data, obj_obj2int(count), ((closure) func)->fn, func, cont, args); dispatch(data, count, ((closure) func)->fn, func, cont, args);
} }
break; break;