diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-03-22 18:50:40 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-03-22 18:50:40 -0700 |
commit | 2a8b1e4388daa00005cbc1e25913479075507ab2 (patch) | |
tree | 8804f6c4dc3b7d8f4888fe92e5fe559bb30cebb5 | |
parent | 24bfded1413e45bb949f6c1ee2b3e8ef34f12329 (diff) | |
download | txr-2a8b1e4388daa00005cbc1e25913479075507ab2.tar.gz txr-2a8b1e4388daa00005cbc1e25913479075507ab2.tar.bz2 txr-2a8b1e4388daa00005cbc1e25913479075507ab2.zip |
apf and ipf: take arguments that are inserted.
The apf and ipf functions now take arguments in addition to
the function that is being wrapped. If specified, these
arguments are inserted to the left the applied arguments.
* eval.c (do_args_apf, do_args_ipf): New static functions.
(apf, ipf): Use do_args_apf and do_args_ipf, respectively,
for handling the case when arguments are present.
Passing the stored arguments is done with the help of the new
DARG type, instead of consing up a list.
* txr.1: Documented new arguments of apf and ipf.
-rw-r--r-- | eval.c | 47 | ||||
-rw-r--r-- | txr.1 | 16 |
2 files changed, 54 insertions, 9 deletions
@@ -6042,9 +6042,25 @@ static val do_apf(val fun, struct args *args) return applyv(fun, args); } -static val apf(val fun) +static val do_args_apf(val dargs, struct args *args) { - return func_f0v(fun, do_apf); + val fun = dargs->a.car; + struct args *da = dargs->a.args; + cnum da_nargs = da->fill + c_num(length(da->list)); + args_decl(args_call, max(args->fill + da_nargs, ARGS_MIN)); + args_copy(args_call, da); + args_normalize_exact(args_call, da_nargs); + args_cat_zap_from(args_call, args, 0); + args_add_list(args_call, args->list); + return applyv(fun, args_call); +} + +static val apf(val fun, struct args *args) +{ + if (!args || !args_more(args, 0)) + return func_f0v(fun, do_apf); + else + return func_f0v(dyn_args(args, fun, nil), do_args_apf); } static val do_ipf(val fun, struct args *args) @@ -6052,15 +6068,32 @@ static val do_ipf(val fun, struct args *args) return iapply(fun, args); } -static val ipf(val fun) +static val do_args_ipf(val dargs, struct args *args) { - return func_f0v(fun, do_ipf); + val fun = dargs->a.car; + struct args *da = dargs->a.args; + cnum da_nargs = da->fill + c_num(length(da->list)); + args_decl(args_call, max(args->fill + da_nargs, ARGS_MIN)); + args_copy(args_call, da); + args_normalize_exact(args_call, da_nargs); + args_cat_zap_from(args_call, args, 0); + args_add_list(args_call, args->list); + return iapply(fun, args_call); +} + + +static val ipf(val fun, struct args *args) +{ + if (!args || !args_more(args, 0)) + return func_f0v(fun, do_ipf); + else + return func_f0v(dyn_args(args, fun, nil), do_args_ipf); } static val callf(val func, struct args *funlist) { val juxt_fun = juxtv(funlist); - val apf_fun = apf(func); + val apf_fun = apf(func, 0); return chain(juxt_fun, apf_fun, nao); } @@ -6633,8 +6666,8 @@ void eval_init(void) reg_fun(intern(lit("or"), user_package), func_n0v(or_fun)); reg_fun(intern(lit("and"), user_package), func_n0v(and_fun)); reg_fun(intern(lit("retf"), user_package), func_n1(retf)); - reg_fun(intern(lit("apf"), user_package), func_n1(apf)); - reg_fun(intern(lit("ipf"), user_package), func_n1(ipf)); + reg_fun(intern(lit("apf"), user_package), func_n1v(apf)); + reg_fun(intern(lit("ipf"), user_package), func_n1v(ipf)); reg_fun(intern(lit("callf"), user_package), func_n1v(callf)); reg_fun(intern(lit("mapf"), user_package), func_n1v(mapf)); reg_fun(intern(lit("tf"), user_package), func_n0v(tf)); @@ -47974,8 +47974,8 @@ macro. .coNP Functions @ apf and @ ipf .synb -.mets (apf << function ) -.mets (ipf << function ) +.mets (apf < function << arg *) +.mets (ipf < function << arg *) .syne .desc The @@ -47992,6 +47992,18 @@ It then returns whatever .meta function returns. +If one or more additional +.metn arg -s +are passed to +.codn apf , +then these are stored in the function which is returned. +When the function is invoked, it prepends all of these stored +arguments to those that it is being given, and the resulting combined +arguments are applied. Thus the +.metn arg -s +become the leftmost arguments of +.metn function . + The .code ipf function is similar to |