diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-10-18 06:08:35 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-10-18 06:08:35 -0700 |
commit | a7ab51c02e36aa9e2a6a6faa2b59c965bf82d309 (patch) | |
tree | b190b4f8e173ac01d55bb9f64fb000c76dae110e /lib.c | |
parent | 45fa8653f7a3ece2eb0c3e92057fdfa9bc5b3780 (diff) | |
download | txr-a7ab51c02e36aa9e2a6a6faa2b59c965bf82d309.tar.gz txr-a7ab51c02e36aa9e2a6a6faa2b59c965bf82d309.tar.bz2 txr-a7ab51c02e36aa9e2a6a6faa2b59c965bf82d309.zip |
functions: provide accessors for basic properties.
* eval.c (eval_init): Register intrinsic functions
fun-fixparam-count, fun-optparam-count, fun-variadic.
* lib.c (get_param_counts): New static function.
(fun_fixparam_count, fun_optparam_count, fun_variadic): New
functions.
* lib.h (fun_fixparam_count, fun_optparam_count,
fun_variadic): Declared.
* txr.1: Documented.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 63 |
1 files changed, 63 insertions, 0 deletions
@@ -6206,6 +6206,69 @@ val vm_fun_p(val obj) return (functionp(obj) && obj->f.functype == FVM) ? t : nil; } +static val get_param_counts(val params, cnum *fixparam, cnum *optparam) +{ + cnum fx = 0, oa = -1; + + for (; consp(params); params = us_cdr(params)) { + val param = us_car(params); + if (param == colon_k && oa < 0) { + oa = 0; + } else { + fx++; + oa += (oa >= 0); + } + } + + *fixparam = fx; + *optparam = oa; + return params; +} + +val fun_fixparam_count(val fun) +{ + type_check(lit("func-fixparam-count"), fun, FUN); + + if (fun->f.functype != FINTERP) { + return num(fun->f.fixparam); + } else { + val form = fun->f.f.interp_fun; + cnum fixparam, optparam; + val params = cadr(form); + (void) get_param_counts(params, &fixparam, &optparam); + return num(fixparam); + } +} + +val fun_optparam_count(val fun) +{ + type_check(lit("func-optparam-count"), fun, FUN); + + if (fun->f.functype != FINTERP) { + return num(fun->f.optargs); + } else { + val form = fun->f.f.interp_fun; + cnum fixparam, optparam; + val params = cadr(form); + (void) get_param_counts(params, &fixparam, &optparam); + return num(optparam); + } +} + +val fun_variadic(val fun) +{ + type_check(lit("func-variadic"), fun, FUN); + + if (fun->f.functype != FINTERP) { + return tnil(fun->f.variadic); + } else { + val form = fun->f.f.interp_fun; + cnum fixparam, optparam; + val params = cadr(form); + return tnil(get_param_counts(params, &fixparam, &optparam)); + } +} + static noreturn void callerror(val fun, val msg) { uses_or2; |