summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-04-05 19:40:15 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-04-05 19:40:15 -0700
commit6a9a84f20e925f76f58d935d9844215af4bf0363 (patch)
treed63553113db4a5c015cddecf25ee85eaf2f83a01 /match.c
parent5ca3693a7b5d65fd5aa67c737e7a60b457db2281 (diff)
downloadtxr-6a9a84f20e925f76f58d935d9844215af4bf0363.tar.gz
txr-6a9a84f20e925f76f58d935d9844215af4bf0363.tar.bz2
txr-6a9a84f20e925f76f58d935d9844215af4bf0363.zip
@(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.
Diffstat (limited to 'match.c')
-rw-r--r--match.c19
1 files 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)