summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eval.c4
-rw-r--r--lib.c44
-rw-r--r--lib.h2
-rw-r--r--match.c11
-rw-r--r--txr.139
-rw-r--r--txr.c2
6 files changed, 82 insertions, 20 deletions
diff --git a/eval.c b/eval.c
index 6b2ac391..fcd802d9 100644
--- a/eval.c
+++ b/eval.c
@@ -7123,8 +7123,8 @@ void eval_init(void)
reg_fun(intern(lit("compl-span-str"), user_package), func_n2(compl_span_str));
reg_fun(intern(lit("break-str"), user_package), func_n2(break_str));
- reg_fun(intern(lit("lazy-stream-cons"), user_package), func_n1(lazy_stream_cons));
- reg_fun(intern(lit("get-lines"), user_package), func_n1o(lazy_stream_cons, 0));
+ reg_fun(intern(lit("lazy-stream-cons"), user_package), func_n2o(lazy_stream_cons, 1));
+ reg_fun(intern(lit("get-lines"), user_package), func_n2o(lazy_stream_cons, 0));
reg_fun(intern(lit("lazy-str"), user_package), func_n3o(lazy_str, 1));
reg_fun(intern(lit("lazy-stringp"), user_package), func_n1(lazy_stringp));
reg_fun(intern(lit("lazy-str-force-upto"), user_package), func_n2(lazy_str_force_upto));
diff --git a/lib.c b/lib.c
index 5de9f170..79b3c1e4 100644
--- a/lib.c
+++ b/lib.c
@@ -8995,12 +8995,24 @@ static val simple_lazy_stream_func(val stream, val lcons)
return nil;
}
-static val lazy_stream_cont(val stream, val func, val env)
+static val simple_lazy_stream_func_nt(val stream, val lcons)
+{
+ if (set(mkloc(lcons->lc.car, lcons), get_line(stream)) != nil) {
+ set(mkloc(lcons->lc.cdr, lcons), make_lazy_cons(us_lcons_fun(lcons)));
+ } else {
+ close_stream(stream, nil);
+ lcons->lc.cdr = nil;
+ }
+
+ return nil;
+}
+
+static val lazy_stream_cont(val stream, val func, val env, val throw_p)
{
val next = get_line(stream);
if (!next) {
- close_stream(stream, t);
+ close_stream(stream, throw_p);
return nil;
}
@@ -9015,27 +9027,45 @@ static val lazy_stream_func(val env, val lcons)
set(mkloc(lcons->lc.car, lcons), prefetched_line);
set(mkloc(lcons->lc.cdr, lcons), lazy_stream_cont(stream,
- us_lcons_fun(lcons), env));
+ us_lcons_fun(lcons), env, t));
return prefetched_line;
}
-val lazy_stream_cons(val stream)
+static val lazy_stream_func_nt(val env, val lcons)
+{
+ val stream = car(env);
+ val prefetched_line = cdr(env);
+
+ set(mkloc(lcons->lc.car, lcons), prefetched_line);
+ set(mkloc(lcons->lc.cdr, lcons), lazy_stream_cont(stream,
+ us_lcons_fun(lcons), env, nil));
+
+ return prefetched_line;
+}
+
+
+val lazy_stream_cons(val stream, val no_throw_close)
{
stream = default_arg_strict(stream, std_input);
+ no_throw_close = default_null_arg(no_throw_close);
if (real_time_stream_p(stream)) {
- return make_lazy_cons(func_f1(stream, simple_lazy_stream_func));
+ return make_lazy_cons(func_f1(stream, if3(no_throw_close,
+ simple_lazy_stream_func_nt,
+ simple_lazy_stream_func)));
} else {
val first = get_line(stream);
if (!first) {
- close_stream(stream, t);
+ close_stream(stream, null(no_throw_close));
return nil;
}
return make_lazy_cons(func_f1(cons(stream, first),
- lazy_stream_func));
+ if3(no_throw_close,
+ lazy_stream_func_nt,
+ lazy_stream_func)));
}
}
diff --git a/lib.h b/lib.h
index e3b89087..5fdf9bde 100644
--- a/lib.h
+++ b/lib.h
@@ -1089,7 +1089,7 @@ val replace_vec(val vec_in, val items, val from, val to);
val replace_obj(val obj, val items, val from, val to);
val fill_vec(val vec, val item, val from_in, val to_in);
val cat_vec(val list);
-val lazy_stream_cons(val stream);
+val lazy_stream_cons(val stream, val no_throw_close);
val lazy_str(val list, val term, val limit);
val lazy_str_force_upto(val lstr, val index);
val lazy_str_force(val lstr);
diff --git a/match.c b/match.c
index f0ed32f4..d2bcf41a 100644
--- a/match.c
+++ b/match.c
@@ -2843,7 +2843,8 @@ static val v_next_impl(match_files_ctx *c)
if (stream) {
cons_bind (new_bindings, success,
match_files(mf_file_data(*c, str, stream,
- lazy_stream_cons(stream), one)));
+ lazy_stream_cons(stream, nothrow),
+ one)));
if (success)
return cons(new_bindings,
@@ -4604,7 +4605,7 @@ static void open_data_source(match_files_ctx *c)
} else {
debuglf(first_spec, lit("opening standard input as data source"), nao);
c->curfile = lit("-");
- c->data = lazy_stream_cons(std_input);
+ c->data = lazy_stream_cons(std_input, nil);
c->data_lineno = one;
}
} else if (non_matching_dir) {
@@ -4628,10 +4629,10 @@ static void open_data_source(match_files_ctx *c)
c->curfile = source_spec;
c->stream = stream;
- if ((c->data = lazy_stream_cons(stream)) != nil)
+ if ((c->data = lazy_stream_cons(stream, nothrow)) != nil)
c->data_lineno = one;
} else if (streamp(name)) {
- if ((c->data = lazy_stream_cons(name)))
+ if ((c->data = lazy_stream_cons(name, nil)))
c->data_lineno = one;
} else {
sem_error(specline, lit("~s doesn't denote a valid data source"), name, nao);
@@ -4773,7 +4774,7 @@ val match_fun(val name, val args, val input_in, val files_in)
val files = cons(curfile, default_null_arg(files_in));
val in_bindings = cdr(uw_get_match_context());
val data = if3(streamp(input),
- lazy_stream_cons(input),
+ lazy_stream_cons(input, nil),
input);
/* TODO: pass through source location context */
match_files_ctx c = mf_all(spec, files, in_bindings, data,
diff --git a/txr.1 b/txr.1
index 7586af51..557422c2 100644
--- a/txr.1
+++ b/txr.1
@@ -4045,7 +4045,21 @@ is invoked with the
.code :nothrow
keyword, then if the input
source cannot be opened, the situation is treated as a simple
-match failure.
+match failure. The
+.code :nothrow
+keyword also ensures that when the stream is later closed,
+which occurs when the lazy list reads all of the available data,
+the implicit call to the
+.code close-stream
+function specifies
+.code nil
+as the argument value to that function's
+.meta throw-on-error-p
+parameter. This
+.code :nothrow
+mechanism does not suppress all exceptions related to the processing
+of that stream; unusual conditions encountered during the reading of
+data from the stream may throw exceptions.
The variant
.code "@(next :args)"
@@ -22855,8 +22869,8 @@ function:
.coNP Functions @ lazy-stream-cons and @ get-lines
.synb
-.mets (lazy-stream-cons << stream )
-.mets (get-lines <> [ stream ])
+.mets (lazy-stream-cons << stream <> [ no-throw-close-p ])
+.mets (get-lines >> [ stream <> [ no-throw-close-p ]])
.syne
.desc
The
@@ -22903,7 +22917,8 @@ by making another call to
.codn lazy-stream-cons ,
installing the result into the
.code cdr
-field.
+field. When this lazy list obtains an end-of-file indication from the stream,
+it closes the stream.
.code lazy-stream-cons
inspects the real-time property of a stream
@@ -22928,6 +22943,22 @@ a one-line stream translates to
.onom
and so forth.
+If and when
+.meta stream
+is closed by the function directly, or else by the returned lazy list, the
+.meta no-throw-close-p
+Boolean argument, defaulting to
+.codn nil ,
+controls the
+.meta throw-on-error-p
+argument of the call to the
+.code close-stream
+function. These arguments have opposite polarity: if
+.meta no-throw-close-p
+is true, then
+.meta throw-on-error-p
+shall be false, and vice versa.
+
.coNP Macro @ delay
.synb
.mets (delay << expression )
diff --git a/txr.c b/txr.c
index 159218a9..341b242a 100644
--- a/txr.c
+++ b/txr.c
@@ -381,7 +381,7 @@ static int license(void)
for (iter = path_list; iter; iter = cdr(iter)) {
val lic = open_file(car(iter), lit("r"));
- put_lines(lazy_stream_cons(lic), std_output);
+ put_lines(lazy_stream_cons(lic, nil), std_output);
put_char(chr('\n'), std_output);
}
}