diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-10-12 06:39:08 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-10-12 06:39:08 -0700 |
commit | 17cd878844f524ebae0024edb60c2f58ac56285d (patch) | |
tree | bd6d5e1a5ae99300ec186e8915830aca0686a2c3 /eval.c | |
parent | 389df91392be85e2b30150e20c5c2a98ec6fd05b (diff) | |
download | txr-17cd878844f524ebae0024edb60c2f58ac56285d.tar.gz txr-17cd878844f524ebae0024edb60c2f58ac56285d.tar.bz2 txr-17cd878844f524ebae0024edb60c2f58ac56285d.zip |
tprint and -t option: handle infinite list.
Test case: txr -t '(gun "foo")' must run in
constant memory.
* eval.c (tprint): Rewritten to iterate over lists using
open loop rather than mapdo. Classification of the sequence
is done using the new seq_info, as must be for all new
sequence functions.
* txr.c (txr_main): Implementation of -t, -p and -P captures
the result of the expression in a variable whose value is
zapped when it is passed to the function. A gc_hint is added
so that this isn't optimized away. Thus, this code won't hold
on to the original pointer to a lazy, infinite list.
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 43 |
1 files changed, 32 insertions, 11 deletions
@@ -5446,20 +5446,41 @@ val pprinl(val obj, val stream) val tprint(val obj, val out) { - switch (type(obj)) { - case NIL: + val self = lit("tprint"); + seq_info_t si = seq_info(obj); + + switch (si.kind) { + case SEQ_NIL: break; - case CONS: - case LCONS: - case VEC: - mapdo(curry_12_1(func_n2(tprint), out), obj); + case SEQ_LISTLIKE: + { + gc_hint(si.obj); + gc_hint(obj); + for (obj = z(si.obj); !endp(obj); obj = cdr(obj)) + tprint(car(obj), out); + } break; - case LIT: - case STR: - case LSTR: - put_line(obj, out); + case SEQ_VECLIKE: + switch (si.type) { + case LIT: + case STR: + case LSTR: + put_line(obj, out); + break; + default: + { + val vec = si.obj; + cnum i, len = c_fixnum(length(vec), self); + + for (i = 0; i < len; i++) + tprint(ref(vec, num_fast(i)), out); + + } + break; + } break; - default: + case SEQ_NOTSEQ: + case SEQ_HASHLIKE: pprinl(obj, out); break; } |