summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-01-10 22:51:14 -0800
committerKaz Kylheku <kaz@kylheku.com>2012-01-10 22:51:14 -0800
commit09c6384d6bb4e3c44bf64299657f492ad4bf756a (patch)
tree46804fac62e964547b877d51f4ad6df2d3217e6e /lib.c
parent9fa74517eb0b8252e88f4c636e6e93bca0c9f0be (diff)
downloadtxr-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.c62
1 files changed, 60 insertions, 2 deletions
diff --git a/lib.c b/lib.c
index c5afc004..12752ef4 100644
--- a/lib.c
+++ b/lib.c
@@ -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);
}