summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-09-19 11:23:31 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-09-19 11:23:31 -0700
commit4c066cf5782381ca49de86af2ea07e2a259a8b64 (patch)
treea84311f76d803841f44b99714401c419e50906da /lib.c
parent4be9838bd95543911ab72cb68baf8fc85d63b586 (diff)
downloadtxr-4c066cf5782381ca49de86af2ea07e2a259a8b64.tar.gz
txr-4c066cf5782381ca49de86af2ea07e2a259a8b64.tar.bz2
txr-4c066cf5782381ca49de86af2ea07e2a259a8b64.zip
Adding flatcar* function.
* eval.c (eval_init): Registered flatcar* intrinsic. * lib.c (lazy_flatcar_scan, lazy_flatcar_func): New static functions. (lazy_flatcar): New function. * lib.h (lazy_flatcar): Declared. * txr.1: Documented, also touching flatten documentation.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/lib.c b/lib.c
index 6de77669..4d0537b6 100644
--- a/lib.c
+++ b/lib.c
@@ -1521,6 +1521,53 @@ val flatcar(val tree)
return flatcar(car(tree));
}
+static val lazy_flatcar_scan(val tree, val *cont)
+{
+ for (;;) {
+ val a = car(tree);
+ val d = cdr(tree);
+
+ if (d != nil)
+ *cont = cons(d, *cont);
+
+ if (atom(a))
+ return a;
+
+ tree = a;
+ }
+}
+
+static val lazy_flatcar_func(val env, val lcons)
+{
+ val tree = car(env);
+ val cont = nil;
+ val atom = lazy_flatcar_scan(tree, &cont);
+
+ rplaca(lcons, atom);
+ rplaca(env, cont);
+
+ if (cont)
+ rplacd(lcons, make_lazy_cons(lcons_fun(lcons)));
+
+ return nil;
+}
+
+val lazy_flatcar(val tree)
+{
+ if (atom(tree)) {
+ return cons(tree, nil);
+ } else {
+ val cont = nil;
+ val nextatom = lazy_flatcar_scan(tree, &cont);
+
+ if (!cont)
+ return cons(nextatom, nil);
+
+ return make_lazy_cons(func_f1(cons(tree, nil), lazy_flatcar_func));
+ }
+}
+
+
static val tuples_func(val env, val lcons)
{
list_collect_decl (out, ptail);