diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-03-20 06:19:28 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-03-20 06:19:28 -0700 |
commit | 004e19fb9ad4ffdec3cd2389289580c112b715c1 (patch) | |
tree | 7d0877a6a0a083fcf095af0bcf9a92dc1a7f5803 /lib.c | |
parent | 2cec86984b7110a6a464b992edb6160149a0a75f (diff) | |
download | txr-004e19fb9ad4ffdec3cd2389289580c112b715c1.tar.gz txr-004e19fb9ad4ffdec3cd2389289580c112b715c1.tar.bz2 txr-004e19fb9ad4ffdec3cd2389289580c112b715c1.zip |
take-until: rewrite with seq_info; elide cons.
* lib.c (take_until_list_fun): Renamed to
lazy_take_until_list_fun.
(lazy_take_until_list_fun, take_until): take_until upgraded to
use seq_info to classify sequence. In the lazy list case, the
state cons is elided; the predicate function is passed as the
function environment, and the key function and list being
traversed are propagated via the lazy cons car and cdr.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 29 |
1 files changed, 13 insertions, 16 deletions
@@ -9896,43 +9896,40 @@ val take_while(val pred, val seq, val keyfun) } } -static val take_until_list_fun(val env, val lcons) +static val lazy_take_until_list_fun(val pred, val lcons) { - us_cons_bind (list, cell, env); - us_cons_bind (pred, keyfun, cell); + us_cons_bind (keyfun, list, lcons); val item = pop(&list); - us_rplaca(lcons, item); if (!list || funcall1(pred, funcall1(keyfun, item))) 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_until(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); - return make_lazy_cons(func_f1(cons(seq, cons(pred, keyfun)), - take_until_list_fun)); - case LSTR: - case LIT: - case STR: - case VEC: + return make_lazy_cons_car_cdr(func_f1(pred, lazy_take_until_list_fun), + keyfun, si.obj); + case SEQ_VECLIKE: { val pos = pos_if(pred, seq, keyfun); if (!pos) return seq; return sub(seq, zero, succ(pos)); } + case SEQ_HASHLIKE: + type_mismatch(lit("take-until: hashes not supported"), nao); default: type_mismatch(lit("take-until: ~s is not a sequence"), seq, nao); } |