diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-08-23 09:50:39 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-08-23 09:50:39 -0700 |
commit | 6d0af6ae2af0003716581ed23b486f26ac809e0c (patch) | |
tree | d7b87cfcbb89f31ba2bcd8ad99e524244d18443d /args.h | |
parent | 115b8bc97f8d0d2ec8ed3cde46d8b567ea437e81 (diff) | |
download | txr-6d0af6ae2af0003716581ed23b486f26ac809e0c.tar.gz txr-6d0af6ae2af0003716581ed23b486f26ac809e0c.tar.bz2 txr-6d0af6ae2af0003716581ed23b486f26ac809e0c.zip |
Large scale conversion to new way of handling arguments.
Function arguments are now allocated on the stack using alloca,
in conjunction with the struct alloc header structure.
The generic_funcall and apply functions are refactored
for this, as are most functions that take variadic arguments.
* args.c (args_add_list, args_cons_list): Functions removed.
(args_normalize, args_normalize_fill): New functions.
(args_get_checked): Draw arguments from list when array runs out.
(args_copy, args_copy_zap): New functions.
* args.h (ARGS_MAX): Reduced to 32.
(ARGS_MIN): New preprocessor symbol.
(args_init): Call args_init_list.
(args_add2, args_add3, args_add4): New inline functions.
(args_more): Take into account list, which may hold additional arguments.
(args_two_more): New inline function.
(args_normalize, args_normalize_fill): Declared.
(args_get_list): Normalize all arguments into one list and return it.
(args_get_rest, args_at, args_atz): New inline functions.
(args_get): Draw arguments from list when array runs out.
(args_clear): New inline function.
* arith.c (maskv): Convert to new args.
* eval.c (APPLY_ARGS): Preprocessor symbol removed.
(bind_args): Converted to accept struct args.
(apply): Function reduced down to trivial adapter which
converts a list of arguments to args, and calls the new
generic_funcall.
(applyv): New static function: struct args wrapper
around apply_intrinsic.
(iapply): Converted to struct args.
(call): Static function removed. The call intrinsic
function binding now goes directly to generic_funcall.
(list_star_intrinsic, interp_fun): Converted to struct args.
(op_catch): Adjustments for bind_args, which requires
a struct args arglist.
(me_op): Must use the new minl and maxl, since minv and maxv
don't take lists any more.
(mapcarv, mappendv, lazy_mapcarv, lazy_mappendv, mapdov,
weavev, or_fun, and_fun, tf, nilf, do_retf, do_apf,
do_ipf, callf, do_mapf, mapf): Converted.
(mapcarl): New function, like the old mapcarv.
(eval_init): call_f initialized from generic_funcall
rather than call. apply registered to applyv rather than
apply_intrinsic. Registrations for zip, hash_from_pairs, vec,
alist-remove, alist-nremove, and throw similarly updated to
new or renamed functions.
* eval.h (interp_fun, mapcarv): Declarations updated.
(mapcarl): Declard.
* hash.c (hashv): Converted to struct args.
(hashl): New function.
(hash_construct): Use hashl, not hashv.
(hash_from_pairs, hash_list, group_by): Converted.
* hash.h (hashv, hash_construct, hash_from_pairs, hash_list,
group_by): Declarations updated.
(hashl): Declared.
* lib.c (appendv, nconcv, lazy_appendv): Converted to
struct args.
(lazy_appendl): New function.
(multi): Converted.
(listv): New function.
(nary_op, plusv, mulv, logandv, logiorv, gtv, ltv, gev, lev,
numeqv, numneqv, maxv, minv): Converted.
(maxl, minl): New functions, like old maxv and minv.
(exptv, gcdv, lcmv, lessv, greaterv, lequalv, gequalv): Converted.
(func_f0v, func_f1v, func_f2v, func_f3v, func_f4v): Converted.
(func_n0v, func_n1v, func_n2v, func_n3v, func_n4v): Converted.
(func_n0v, func_n1v, func_n2v, func_n3v, func_n4v): Converted.
(func_n1ov, func_n2ov, func_n3ov): Converted.
(generic_funcall): Converted to take struct args.
(funcall, funcall1, funcall2, funcall4): Pass stack-allocated
struct args as trailing arguments to variadic functions, and to
generic_funcall.
(do_curry_12_1_v): New struct-args-based static function,
needed to implement curry_12_1_v now.
(curry_12_1_v): Converted.
(transposev): New function based on previous tranpose.
(transpose): Now a wrapper for transposev.
(do_chain, chainv, do_chand, chandv, do_juxt, juxtv,
do_and, andv, do_or, orv, do_not, do_iff): Converted.
(vectorv): New function. Implementation basis for vec intrinsic function.
(alist_removev, alist_nremovev): New functions.
(multi_sort): Switch from mapcarv to mapcarl.
(unique): Converted.
(uniq): Allocate struct args for calling unique.
(obj_init): list_f function now based on new listv, rather than
identity.
* list.h (varg): New typedef.
(struct func): All variadic function pointers converted to use
struct args.
(appendv, nconcv, lazy_appendv, multi, nary_op, plusv, minusv,
mulv, gtv, ltv, gev, lev, numeqv, numneqv, maxv, minv, exptv,
gcdv, lcmv, logadnv, logiorv, maskv, lessv, greaterv, lequalv,
gequalv, func_f0v, func_f1v, func_f2v, func_f3v, func_f4v,
func_n0v, func_n1v, func_n2v, func_n3v, func_n4v, func_n0v,
func_n1v, func_n2v, func_n3v, func_n4v, func_n1ov, func_n2ov,
func_n3ov, generic_funcall, chainv, chandv, juxtv, adnv, orv,
unique): Declarations updated.
(lazy_appendl, listv, maxl, minl, transposev,
vectorv, alist_removev, alist_nremovev): Declared.
* stream.c (make_catenated_stream_v): New function.
(aformat): Renamed to formatv. The recognition of the nil
and t streams (standard output and string) is done here now.
(vformat): Follow rename of aformat to formatv.
(formatv): Function removed. Nobody calls this anymore.
(stream_init): make-catenated-stream re-registered to new
make_catenated_stream_v function.
* stream.h (formatv): Declaration updated.
(make_catenated_v): Declared.
* syslog.c (syslog_init): syslog registred to syslog_wrapv.
(syslog_wrapv): New function based on syslog_wrap converted to struct
args.
(syslog_wrap): Now wrapper for syslog_wrapv.
* syslog.h (syslog_wrapv): Declared.
* unwind.h (uw_throwv): New function.
(uw_throwfv, uw_errorfv): Converted to struct args.
* unwind.h (uw_throwv): Declared.
(uw_throwfv, uw_errorfv): Declarations updated.
Diffstat (limited to 'args.h')
-rw-r--r-- | args.h | 93 |
1 files changed, 81 insertions, 12 deletions
@@ -33,7 +33,8 @@ struct args { typedef int arg_index; -#define ARGS_MAX 1024 +#define ARGS_MAX 32 +#define ARGS_MIN 4 #define args_alloc(N) \ (coerce(struct args *, \ @@ -41,18 +42,16 @@ typedef int arg_index; cnum args_limit(val name, cnum in); -INLINE void args_init(struct args *args, cnum argc) +INLINE void args_init_list(struct args *args, cnum argc, val list) { args->argc = argc; args->fill = 0; - args->list = nil; + args->list = list; } -INLINE void args_init_list(struct args *args, cnum argc, val list) +INLINE void args_init(struct args *args, cnum argc) { - args->argc = argc; - args->fill = 0; - args->list = list; + args_init_list(args, argc, nil); } INLINE val args_add(struct args *args, val arg) @@ -60,24 +59,94 @@ INLINE val args_add(struct args *args, val arg) return args->arg[args->fill++] = arg; } -void args_add_list(struct args *args, val list); +INLINE void args_add2(struct args *args, val arg1, val arg2) +{ + val *arg = args->arg + args->fill; + args->fill += 2; + *arg++ = arg1; + *arg++ = arg2; +} + +INLINE void args_add3(struct args *args, val arg1, val arg2, val arg3) +{ + val *arg = args->arg + args->fill; + args->fill += 3; + *arg++ = arg1; + *arg++ = arg2; + *arg++ = arg3; +} + +INLINE void args_add4(struct args *args, val arg1, val arg2, val arg3, val arg4) +{ + val *arg = args->arg + args->fill; + args->fill += 4; + *arg++ = arg1; + *arg++ = arg2; + *arg++ = arg3; + *arg++ = arg4; +} val args_add_checked(val name, struct args *args, val arg); INLINE int args_more(struct args *args, cnum index) { - return index < args->fill; + return index < args->fill || args->list; +} + +INLINE int args_two_more(struct args *args, cnum index) +{ + return + index + 1 < args->fill || + (index + 1 == args->fill && args->list) || + cdr(args->list); } +void args_normalize(struct args *args, cnum fill); +void args_normalize_fill(struct args *args, cnum minfill, cnum maxfill); + INLINE val args_get_list(struct args *args) { - extern val args_cons_list(struct args *args); - return (args->fill == 0 || args->list) ? args->list : args_cons_list(args); + if (args->fill == 0) + return z(args->list); + args_normalize(args, 0); + return z(args->list); +} + +INLINE val args_get_rest(struct args *args, cnum index) +{ + if (args->fill == index) + return z(args->list); + args_normalize(args, index); + return z(args->list); +} + + +INLINE val args_at(struct args *args, cnum arg_index) +{ + if (arg_index < args->fill) + return args->arg[arg_index]; + return car(args->list); +} + +INLINE val args_atz(struct args *args, cnum arg_index) +{ + if (arg_index < args->fill) + return z(args->arg[arg_index]); + return car(z(args->list)); } INLINE val args_get(struct args *args, cnum *arg_index) { - return args->arg[(*arg_index)++]; + if (*arg_index < args->fill) + return z(args->arg[(*arg_index)++]); + return pop(&args->list); +} + +INLINE void args_clear(struct args *args) +{ + args->fill = 0; } val args_get_checked(val name, struct args *args, cnum *arg_index); +struct args *args_copy(struct args *to, struct args *from); +struct args *args_copy_zap(struct args *to, struct args *from); |