summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib.c62
-rw-r--r--txr.12
2 files changed, 32 insertions, 32 deletions
diff --git a/lib.c b/lib.c
index cbf5c948..03f22587 100644
--- a/lib.c
+++ b/lib.c
@@ -9818,79 +9818,79 @@ val ends_with(val little, val big, val testfun, val keyfun)
return tnil(!mm || eql(pred(neg(mm)), length(little)));
}
-static val take_list_fun(val env, val lcons)
+static val lazy_take_list_fun(val list, val lcons)
{
- us_cons_bind (list, count, env);
+ val count = us_car(lcons);
us_rplaca(lcons, pop(&list));
- if3(le((count = pred(count)), zero) || list == nil,
- us_rplacd(lcons, nil),
- us_rplacd(lcons, make_lazy_cons(us_lcons_fun(lcons))));
+ if (list == nil || le((count = pred(count)), zero)) {
+ us_rplacd(lcons, nil);
+ } else {
+ val fun = us_lcons_fun(lcons);
+ us_rplacd(lcons, make_lazy_cons_car(fun, count));
+ us_func_set_env(fun, list);
+ }
- us_rplaca(env, list);
- us_rplacd(env, count);
return nil;
}
val take(val count, val seq)
{
- switch (type(seq)) {
- case NIL:
+ seq_info_t si = seq_info(seq);
+
+ switch (si.kind) {
+ case SEQ_NIL:
return nil;
- case CONS:
- case LCONS:
+ case SEQ_LISTLIKE:
if (le(count, zero))
return nil;
- return make_lazy_cons(func_f1(cons(seq, count), take_list_fun));
- case LSTR:
- case LIT:
- case STR:
- case VEC:
+ return make_lazy_cons_car(func_f1(si.obj, lazy_take_list_fun), count);
+ case SEQ_VECLIKE:
return sub(seq, zero, count);
+ case SEQ_HASHLIKE:
+ type_mismatch(lit("take: hashes not supported"), nao);
default:
type_mismatch(lit("take: ~s is not a sequence"), seq, nao);
}
}
-static val take_while_list_fun(val env, val lcons)
+static val lazy_take_while_list_fun(val pred, val lcons)
{
- us_cons_bind (list, cell, env);
- us_cons_bind (pred, keyfun, cell);
+ us_cons_bind (keyfun, list, lcons);
us_rplaca(lcons, pop(&list));
if (!list || !funcall1(pred, funcall1(keyfun, car(list))))
us_rplacd(lcons, nil);
else
- us_rplacd(lcons, make_lazy_cons(us_lcons_fun(lcons)));
+ us_rplacd(lcons, make_lazy_cons_car_cdr(us_lcons_fun(lcons), keyfun, list));
- us_rplaca(env, list);
return nil;
}
val take_while(val pred, val seq, val keyfun)
{
- switch (type(seq)) {
- case NIL:
+ seq_info_t si = seq_info(seq);
+
+ switch (si.kind) {
+ case SEQ_NIL:
return nil;
- case CONS:
- case LCONS:
+ case SEQ_LISTLIKE:
keyfun = default_arg(keyfun, identity_f);
if (!funcall1(pred, funcall1(keyfun, (car(seq)))))
return nil;
- return make_lazy_cons(func_f1(cons(seq, cons(pred, keyfun)),
- take_while_list_fun));
- case LSTR:
- case LIT:
- case STR:
- case VEC:
+ return make_lazy_cons_car_cdr(func_f1(pred, lazy_take_while_list_fun),
+ keyfun, si.obj);
+ case SEQ_VECLIKE:
{
val pos = pos_if(notf(pred), seq, keyfun);
if (!pos)
return seq;
return sub(seq, zero, pos);
}
+ case SEQ_HASHLIKE:
+ type_mismatch(lit("take-while: hashes not supported"), nao);
default:
type_mismatch(lit("take-while: ~s is not a sequence"), seq, nao);
}
diff --git a/txr.1 b/txr.1
index 358ccb8f..4f87a33f 100644
--- a/txr.1
+++ b/txr.1
@@ -26823,7 +26823,7 @@ returns a lazy list which produces the first
items of sequence.
For other kinds of sequences, including lazy strings,
-.code drop
+.code take
works eagerly.
If