diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2012-01-10 22:51:14 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2012-01-10 22:51:14 -0800 |
commit | 09c6384d6bb4e3c44bf64299657f492ad4bf756a (patch) | |
tree | 46804fac62e964547b877d51f4ad6df2d3217e6e /lib.c | |
parent | 9fa74517eb0b8252e88f4c636e6e93bca0c9f0be (diff) | |
download | txr-09c6384d6bb4e3c44bf64299657f492ad4bf756a.tar.gz txr-09c6384d6bb4e3c44bf64299657f492ad4bf756a.tar.bz2 txr-09c6384d6bb4e3c44bf64299657f492ad4bf756a.zip |
Spat of new features having to do with lazy processing.
* eval.c (prog1_s, gen_s, generate_s, delay_s, promise_s): New symbol
variables.
(eval_prog1, op_prog1, expand_gen, expand_delay): New static functions.
(expand): Handle gen and delay.
(lazy_mapcar_func, lazy_mapcar, lazy_mapcarv_func, lazy_mapcarv,
lazy_mappendv): New static functions.
(rangev_func, rangev, generate_func, generate, repeat_infinite_func,
repeat_times_func, repeatv, force): New static functions.
(eval_init): New operators and functions interned.
lazy-flatten renamed to flatten*.
* lib.c (null_f): New global variable.
(ltail, lazy_appendv): New functions.
(lazy_appendv_func): New static function.
(obj_init): null_f protected and initialized.
* lib.h (null_f, ltail, lazy_appendv): Declared.
* txr.1: Documented.
* txr.vim: Updated.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 62 |
1 files changed, 60 insertions, 2 deletions
@@ -82,7 +82,7 @@ val null_string; val nil_string; val null_list; -val identity_f, equal_f, eql_f, eq_f, car_f, cdr_f; +val identity_f, equal_f, eql_f, eq_f, car_f, cdr_f, null_f; val gensym_counter; @@ -308,6 +308,13 @@ val *tail(val cons) return cdr_l(cons); } +val *ltail(val *cons) +{ + while (cdr(*cons)) + cons = cdr_l(*cons); + return cons; +} + val pop(val *plist) { val ret = car(*plist); @@ -394,6 +401,56 @@ val nappend2(val list1, val list2) return out; } +static val lazy_appendv_func(val env, val lcons) +{ + cons_bind (last, lists, env); + val nonempty = nil; + + while (lists) { + nonempty = pop(&lists); + if (nonempty) + break; + } + + rplaca(lcons, last); + + if (atom(nonempty)) { + rplacd(lcons, nonempty); + return nil; + } + + rplacd(env, lists); + + { + val *ptail = ltail(&nonempty); + rplaca(env, car(*ptail)); + *ptail = make_lazy_cons(lcons_fun(lcons)); + rplacd(lcons, nonempty); + } + return nil; +} + +val lazy_appendv(val lists) +{ + val nonempty = nil; + + while (lists) { + nonempty = pop(&lists); + if (nonempty) + break; + } + + if (atom(nonempty)) + return nonempty; + + { + val *ptail = ltail(&nonempty); + *ptail = make_lazy_cons(func_f1(cons(car(*ptail), lists), + lazy_appendv_func)); + return nonempty; + } +} + val ldiff(val list1, val list2) { list_collect_decl (out, ptail); @@ -3166,7 +3223,7 @@ static void obj_init(void) protect(&packages, &system_package, &keyword_package, &user_package, &null_string, &nil_string, - &null_list, &equal_f, &eq_f, &eql_f, &car_f, &cdr_f, + &null_list, &equal_f, &eq_f, &eql_f, &car_f, &cdr_f, &null_f, &identity_f, &prog_string, &env_list, (val *) 0); @@ -3284,6 +3341,7 @@ static void obj_init(void) identity_f = func_n1(identity); car_f = func_n1(car); cdr_f = func_n1(cdr); + null_f = func_n1(nullp); gensym_counter = zero; prog_string = string(progname); } |