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 | |
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.
-rw-r--r-- | eval.c | 43 | ||||
-rw-r--r-- | txr.c | 12 |
2 files changed, 41 insertions, 14 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; } @@ -858,13 +858,19 @@ int txr_main(int argc, char **argv) tprint)); val args_saved = or2(orig_args, arg_list); val args_new; + val obj; reg_varl(self_path_s, lit("cmdline-expr")); reg_var(args_s, or2(orig_args, arg_list)); - pf(eval_intrinsic(lisp_parse(arg, std_error, colon_k, - lit("cmdline-expr"), colon_k), - make_env(bindings, nil, nil)), std_output); + + obj = eval_intrinsic(lisp_parse(arg, std_error, colon_k, + lit("cmdline-expr"), colon_k), + make_env(bindings, nil, nil)); + gc_hint(obj); + pf(z(obj), std_output); + evaled = t; + args_new = cdr(lookup_global_var(args_s)); if (args_new != args_saved) { arg_list = args_new; |