diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-09-19 11:23:31 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-09-19 11:23:31 -0700 |
commit | 4c066cf5782381ca49de86af2ea07e2a259a8b64 (patch) | |
tree | a84311f76d803841f44b99714401c419e50906da /lib.c | |
parent | 4be9838bd95543911ab72cb68baf8fc85d63b586 (diff) | |
download | txr-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.c | 47 |
1 files changed, 47 insertions, 0 deletions
@@ -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); |