Mercurial > octave
changeset 28317:ac87763b1949 stable
capture dynamic field variable values in anonymous functions (bug #58389)
* pt-walk.cc (tree_walker::visit_index_expression): Also visit dynamic
field name expressions.
* ov-fcn-handle.cc: New test.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Mon, 18 May 2020 12:30:41 -0400 |
parents | 768ae9b1a67c |
children | 08229481b65f |
files | libinterp/octave-value/ov-fcn-handle.cc libinterp/parse-tree/pt-walk.cc |
diffstat | 2 files changed, 49 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/octave-value/ov-fcn-handle.cc Sat May 16 15:53:42 2020 +0200 +++ b/libinterp/octave-value/ov-fcn-handle.cc Mon May 18 12:30:41 2020 -0400 @@ -2136,6 +2136,16 @@ */ /* +%!test <*58389> +%! s = "x"; +%! a.(s) = [e, pi]; +%! f = @(x) a.(s)(x); +%! assert (f(1), e); +%! assert (f(2), pi); +%! assert (f([2,1]), [pi, e]); +*/ + +/* %!function r = __f (g, i) %! r = g(i); %!endfunction
--- a/libinterp/parse-tree/pt-walk.cc Sat May 16 15:53:42 2020 +0200 +++ b/libinterp/parse-tree/pt-walk.cc Mon May 18 12:30:41 2020 -0400 @@ -285,16 +285,49 @@ if (e) e->accept (*this); - std::list<tree_argument_list *> lst = expr.arg_lists (); + std::list<tree_argument_list *> arg_lists = expr.arg_lists (); + std::list<string_vector> arg_names = expr.arg_names (); + std::list<tree_expression *> dyn_fields = expr.dyn_fields (); - auto p = lst.begin (); + auto p_arg_lists = arg_lists.begin (); + auto p_arg_names = arg_names.begin (); + auto p_dyn_fields = dyn_fields.begin (); + + std::string type_tags = expr.type_tags (); + int n = type_tags.length (); - while (p != lst.end ()) + for (int i = 0; i < n; i++) { - tree_argument_list *elt = *p++; + switch (type_tags[i]) + { + case '(': + case '{': + { + tree_argument_list *l = *p_arg_lists; + if (l) + l->accept (*this); + } + break; - if (elt) - elt->accept (*this); + case '.': + { + std::string fn = (*p_arg_names)(0); + if (fn.empty ()) + { + tree_expression *df = *p_dyn_fields; + if (df) + df->accept (*this); + } + } + break; + + default: + panic_impossible (); + } + + p_arg_lists++; + p_arg_names++; + p_dyn_fields++; } }