From d01e894af245c7f8df9b193b482150a1b9725f1c Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 4 Apr 2024 07:33:54 -0700 Subject: New function: lcons-force. * lib.[ch] (lcons_force): New function. * eval.c (eval_init): Register lcons-force intrinsic. * txr.1: Documented. --- eval.c | 1 + lib.c | 12 ++++++++++++ lib.h | 1 + txr.1 | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/eval.c b/eval.c index 095313ac..4125d33a 100644 --- a/eval.c +++ b/eval.c @@ -7294,6 +7294,7 @@ void eval_init(void) reg_fun(intern(lit("lcons-fun"), user_package), func_n1(lcons_fun)); reg_fun(intern(lit("lcons-car"), user_package), func_n1(lcons_car)); reg_fun(intern(lit("lcons-cdr"), user_package), func_n1(lcons_cdr)); + reg_fun(intern(lit("lcons-force"), user_package), func_n1(lcons_force)); reg_fun(car_s, car_f); reg_fun(cdr_s, cdr_f); reg_fun(rplaca_s, func_n2(rplaca)); diff --git a/lib.c b/lib.c index 12f024cc..4ee9cd59 100644 --- a/lib.c +++ b/lib.c @@ -4863,6 +4863,18 @@ val lcons_fun(val lcons) return lcons->lc.func; } +val lcons_force(val lcons) +{ + val iter = lcons; + + while (type(iter) == LCONS && iter->lc.func) { + lcons_force(car(iter)); + iter = us_cdr(iter); + } + + return lcons; +} + val list(val first, ...) { va_list vl; diff --git a/lib.h b/lib.h index b4b1df87..9378ce02 100644 --- a/lib.h +++ b/lib.h @@ -933,6 +933,7 @@ void rcyc_cons(val cons); void rcyc_empty(void); val lcons_fun(val lcons); INLINE val us_lcons_fun(val lcons) { return lcons->lc.func; } +val lcons_force(val lcons); val list(val first, ...); /* terminated by nao */ val listv(varg ); val consp(val obj); diff --git a/txr.1 b/txr.1 index 278279cb..d236688c 100644 --- a/txr.1 +++ b/txr.1 @@ -24373,6 +24373,32 @@ cons to store state information necessary for the propagation of a lazy list. If that state information consists of no more than two values, then no additional context object need be allocated. +.coNP Function @ lcons-force +.synb +.mets (lcons-force << object ) +.syne +.desc +The +.code lcons-function +recursively forces a lazy cons. + +If the argument +.meta object +is of +.code lcons +type, and has not been previously forced, then it is forced. The +associated lazy function is invoked. Then, +.code lcons-force +is recursively invoked on the +.code car +and +.code cdr +fields of the lazy cons. + +The +.code lcons-force +function returns its argument. + .coNP Macro @ lcons .synb .mets (lcons < car-expression << cdr-expression ) @@ -24524,6 +24550,12 @@ is true, then .meta throw-on-error-p shall be false, and vice versa. +Note: the +.code lcons-force +function may be used on the return value of +.code get-lines +to force the lazy list. + .coNP Macro @ close-lazy-streams .synb .mets (close-lazy-streams << body-form *) -- cgit v1.2.3