From 6a9a84f20e925f76f58d935d9844215af4bf0363 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 5 Apr 2019 19:40:15 -0700 Subject: @(output): bugfix: lazy evaluation doesn't work. In an @(output), if we reference a variable bound to a lazy list, and the generation of that logic references TXR pattern variables, things break: the lazy list's code doesn't see the binding. This is because the lazy list is forced by some logic that doesn't establish the proper environment for that evaluation. Inside a @(repeat), the do_output function measures the lengths of lists emanating from variables, and that has the effect of forcing the lazy lists. * match.c (v_output): Just set up the dynamic environment around the entire function, so that any Lisp evaluation that occurs is happening as if it were via tleval. --- match.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/match.c b/match.c index b2f38d19..30b89041 100644 --- a/match.c +++ b/match.c @@ -3734,6 +3734,13 @@ static val v_output(match_files_ctx *c) val named_var = nil, continue_expr = nil, finish_expr = nil; val alist; val stream = nil; + val ret = next_spec_k; + + uw_env_begin; + + val saved_de = set_dyn_env(make_env(c->bindings, nil, nil)); + + uw_set_match_context(cons(c->spec, c->spec)); if (first(dest_spec) == nothrow_k) { if (rest(dest_spec)) @@ -3812,7 +3819,7 @@ static val v_output(match_files_ctx *c) c->bindings = acons(into_var, list_out, c->bindings); } } - return next_spec_k; + goto out; } } @@ -3831,7 +3838,7 @@ static val v_output(match_files_ctx *c) if (finish_expr) close_stream(stream, t); - return next_spec_k; + goto out; } stream = complex_open(dest, t, append, nothrow, nil); @@ -3841,7 +3848,8 @@ static val v_output(match_files_ctx *c) if (!stream) { debuglf(specline, lit("could not open ~a: " "treating as failed match due to nothrow"), dest, nao); - return nil; + ret = nil; + goto out; } else { do_output(c->bindings, specs, filter, stream); flush_stream(stream); @@ -3852,7 +3860,10 @@ static val v_output(match_files_ctx *c) close_stream(stream, t); } - return next_spec_k; +out: + set_dyn_env(saved_de); + uw_env_end; + return ret; } static val v_try(match_files_ctx *c) -- cgit v1.2.3