summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2024-04-04 07:33:54 -0700
committerKaz Kylheku <kaz@kylheku.com>2024-04-04 07:33:54 -0700
commitd01e894af245c7f8df9b193b482150a1b9725f1c (patch)
treeef4ba9ec874f641421acd7e20a5a88976d507334
parentf7acc9f8daf14a4171e86fe5fd9dd1c32f6b3948 (diff)
downloadtxr-d01e894af245c7f8df9b193b482150a1b9725f1c.tar.gz
txr-d01e894af245c7f8df9b193b482150a1b9725f1c.tar.bz2
txr-d01e894af245c7f8df9b193b482150a1b9725f1c.zip
New function: lcons-force.
* lib.[ch] (lcons_force): New function. * eval.c (eval_init): Register lcons-force intrinsic. * txr.1: Documented.
-rw-r--r--eval.c1
-rw-r--r--lib.c12
-rw-r--r--lib.h1
-rw-r--r--txr.132
4 files changed, 46 insertions, 0 deletions
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 *)