mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-23 20:15:05 +02:00
More cleanup, generalize apply_va logic
This commit is contained in:
parent
4f65fdb6e2
commit
9cf016e1a6
1 changed files with 46 additions and 42 deletions
88
runtime.c
88
runtime.c
|
@ -3230,24 +3230,6 @@ void _call_95cc(void *data, object cont, object args)
|
|||
return_closcall2(data, __glo_call_95cc_scheme_base, cont, car(args));
|
||||
}
|
||||
|
||||
void apply_va(void *data, object cont, int argc, object func, ...)
|
||||
{
|
||||
object tmp = NULL;
|
||||
int i;
|
||||
va_list ap;
|
||||
va_start(ap, func);
|
||||
for (i = 1; i < argc; i++) {
|
||||
tmp = va_arg(ap, object);
|
||||
}
|
||||
va_end(ap);
|
||||
// fprintf(stdout, "DEBUG applying argc %d, func ", argc);
|
||||
// Cyc_display(func, stdout);
|
||||
// fprintf(stdout, " to values ");
|
||||
// Cyc_display(tmp, stdout);
|
||||
// fprintf(stdout, "\n");
|
||||
apply(data, cont, func, tmp);
|
||||
}
|
||||
|
||||
// Prepend value to the given list
|
||||
#define stack_prepend(lis, value) { \
|
||||
pair_type *tmp2 = alloca(sizeof(pair_type)); \
|
||||
|
@ -3265,38 +3247,60 @@ void apply_va(void *data, object cont, int argc, object func, ...)
|
|||
} \
|
||||
}
|
||||
|
||||
// Front-end to apply
|
||||
//
|
||||
// Core of va processing is done here, because we need different
|
||||
// functions for apply_va and dispatch_apply_va, and those functions
|
||||
// need to start and end va. BUT, we need to allocate new objects
|
||||
// so this stuff can't be returned, so a workaround is to put it in
|
||||
// this macro.
|
||||
//
|
||||
// Fast path is just to take list, if we only have func and 1 arg.
|
||||
// Otherwise append all args together into a single list, per r7rs.
|
||||
#define do_apply_va \
|
||||
va_start(ap, func); \
|
||||
if (argc == 2) { \
|
||||
lis = va_arg(ap, object); \
|
||||
Cyc_check_pair_or_null(data, lis); \
|
||||
} else { \
|
||||
for (i = 1; i < argc; i++) { \
|
||||
tmp = va_arg(ap, object); \
|
||||
if (tmp == NULL){ \
|
||||
continue; \
|
||||
} else if (is_object_type(tmp) && type_of(tmp) == pair_tag) { \
|
||||
l = tmp; \
|
||||
stack_list_prepend(l, lis); \
|
||||
} else { \
|
||||
stack_prepend(lis, tmp); \
|
||||
} \
|
||||
} \
|
||||
l = lis; \
|
||||
lis = NULL; \
|
||||
stack_list_prepend(l, lis); \
|
||||
} \
|
||||
va_end(ap);
|
||||
|
||||
void dispatch_apply_va(void *data, int argc, object clo, object cont, object func, ...)
|
||||
{
|
||||
list lis = NULL, tmp, l;
|
||||
list lis = NULL, l;
|
||||
object tmp;
|
||||
int i;
|
||||
va_list ap;
|
||||
argc = argc - 1; // Required for "dispatch" function
|
||||
va_start(ap, func);
|
||||
if (argc == 2) {
|
||||
// Fast path, nothing to append
|
||||
lis = va_arg(ap, object);
|
||||
Cyc_check_pair_or_null(data, lis);
|
||||
} else {
|
||||
for (i = 1; i < argc; i++) {
|
||||
tmp = va_arg(ap, object);
|
||||
if (tmp == NULL){
|
||||
continue;
|
||||
} else if (is_object_type(tmp) && type_of(tmp) == pair_tag) {
|
||||
l = tmp;
|
||||
stack_list_prepend(l, lis);
|
||||
} else {
|
||||
stack_prepend(lis, tmp);
|
||||
}
|
||||
}
|
||||
// Reverse lis
|
||||
l = lis;
|
||||
lis = NULL;
|
||||
stack_list_prepend(l, lis);
|
||||
}
|
||||
va_end(ap);
|
||||
do_apply_va
|
||||
apply(data, cont, func, lis);
|
||||
}
|
||||
|
||||
void apply_va(void *data, object cont, int argc, object func, ...)
|
||||
{
|
||||
list lis = NULL, l;
|
||||
object tmp;
|
||||
int i;
|
||||
va_list ap;
|
||||
do_apply_va
|
||||
apply(data, cont, func, tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param cont - Continuation for the function to call into
|
||||
* @param func - Function to execute
|
||||
|
|
Loading…
Add table
Reference in a new issue