Mercurial > octave
changeset 23482:c9937e865768
make isargout work again for nested function calls
* pt-eval.cc, pt-eval.h (tree_evaluator::ignored_fcn_outputs):
Return if lvalue_list is null.
(tree_evaluator::make_value_list): Now a member function instead of
static file-scope function. Change all callers.
(tree_evaluator::visit_index_expression, tree_evaluator::visit_cell):
Push null lvalue_list on m_lvalue_list_stack.
* ov-usr-fcn.cc (octave_user_function::bind_automatic_var):
Always define .ignored. symbol. New tests.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 10 May 2017 13:37:43 -0400 |
parents | 73558a835b64 |
children | 6d5a646ede0c |
files | libinterp/octave-value/ov-usr-fcn.cc libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-eval.h |
diffstat | 3 files changed, 78 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/octave-value/ov-usr-fcn.cc Wed May 10 11:09:52 2017 -0400 +++ b/libinterp/octave-value/ov-usr-fcn.cc Wed May 10 13:37:43 2017 -0400 @@ -726,10 +726,7 @@ Matrix ignored_fcn_outputs = tw ? tw->ignored_fcn_outputs () : Matrix (); - if (ignored_fcn_outputs.is_empty ()) - symbol_table::assign (".ignored."); - else - symbol_table::assign (".ignored.", ignored_fcn_outputs); + symbol_table::assign (".ignored.", ignored_fcn_outputs); symbol_table::mark_hidden (".ignored."); symbol_table::mark_automatic (".ignored."); @@ -1073,6 +1070,11 @@ %! endif %!endfunction %! +%!function [a, b] = try_isargout2 (x, y) +%! a = y; +%! b = {isargout(1), isargout(2), x}; +%!endfunction +%! %!test %! [x, y] = try_isargout (); %! assert ([x, y], [1, 2]); @@ -1111,4 +1113,12 @@ %! assert (y, -2); %! [~, y] = c{2}(); %! assert (y, -2); +%! +## Nesting, anyone? +%!test +%! [~, b] = try_isargout2 (try_isargout, rand); +%! assert (b, {0, 1, -1}); +%!test +%! [~, b] = try_isargout2 ({try_isargout, try_isargout}, rand); +%! assert (b, {0, 1, {-1, -1}}); */
--- a/libinterp/parse-tree/pt-eval.cc Wed May 10 11:09:52 2017 -0400 +++ b/libinterp/parse-tree/pt-eval.cc Wed May 10 13:37:43 2017 -0400 @@ -416,11 +416,11 @@ if (m_lvalue_list_stack.empty ()) return retval; - // std::cerr << "lvalue_list_stack size: " - // << m_lvalue_list_stack.size () << std::endl; - const std::list<octave_lvalue> *lvalue_list = m_lvalue_list_stack.top (); + if (! lvalue_list) + return retval; + octave_idx_type nbh = 0; for (const auto& lval : *lvalue_list) @@ -1043,29 +1043,6 @@ } } -static inline octave_value_list -make_value_list (octave::tree_evaluator *tw, octave::tree_argument_list *args, - const string_vector& arg_nm, - const octave_value *object, bool rvalue = true) -{ - octave_value_list retval; - - if (args) - { - if (rvalue && object && args->has_magic_end () && object->is_undefined ()) - err_invalid_inquiry_subscript (); - - retval = args->convert_to_const_vector (tw, object); - } - - octave_idx_type n = retval.length (); - - if (n > 0) - retval.stash_name_tags (arg_nm); - - return retval; -} - // Final step of processing an indexing error. Add the name of the // variable being indexed, if any, then issue an error. (Will this also // be needed by pt-lvalue, which calls subsref?) @@ -1132,6 +1109,16 @@ if (n > 0) { + // Function calls inside an argument list can't have ignored + // output arguments. + + unwind_protect frame; + + m_lvalue_list_stack.push (0); + + frame.add_method (m_lvalue_list_stack, + &value_stack<const std::list<octave_lvalue>*>::pop); + string_vector anm = *(arg_nm.begin ()); have_args = true; first_args = al -> convert_to_const_vector (this); @@ -1239,11 +1226,11 @@ have_args = false; } else - idx.push_back (make_value_list (this, *p_args, *p_arg_nm, &tmp)); + idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp)); break; case '{': - idx.push_back (make_value_list (this, *p_args, *p_arg_nm, &tmp)); + idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp)); break; case '.': @@ -1488,6 +1475,16 @@ { octave_value retval; + // Function calls inside an argument list can't have ignored + // output arguments. + + unwind_protect frame; + + m_lvalue_list_stack.push (0); + + frame.add_method (m_lvalue_list_stack, + &value_stack<const std::list<octave_lvalue>*>::pop); + octave_idx_type nr = expr.length (); octave_idx_type nc = -1; @@ -2509,6 +2506,40 @@ return expr_value; } + octave_value_list + tree_evaluator::make_value_list (octave::tree_argument_list *args, + const string_vector& arg_nm, + const octave_value *object, bool rvalue) + { + octave_value_list retval; + + if (args) + { + // Function calls inside an argument list can't have ignored + // output arguments. + + unwind_protect frame; + + m_lvalue_list_stack.push (0); + + frame.add_method (m_lvalue_list_stack, + &value_stack<const std::list<octave_lvalue>*>::pop); + + if (rvalue && object && args->has_magic_end () + && object->is_undefined ()) + err_invalid_inquiry_subscript (); + + retval = args->convert_to_const_vector (this, object); + } + + octave_idx_type n = retval.length (); + + if (n > 0) + retval.stash_name_tags (arg_nm); + + return retval; + } + std::list<octave_lvalue> tree_evaluator::make_lvalue_list (tree_argument_list *lhs) {
--- a/libinterp/parse-tree/pt-eval.h Wed May 10 11:09:52 2017 -0400 +++ b/libinterp/parse-tree/pt-eval.h Wed May 10 13:37:43 2017 -0400 @@ -304,6 +304,11 @@ bool is_logically_true (tree_expression *expr, const char *warn_for); + octave_value_list + make_value_list (octave::tree_argument_list *args, + const string_vector& arg_nm, + const octave_value *object, bool rvalue = true); + std::list<octave_lvalue> make_lvalue_list (tree_argument_list *); value_stack<octave_value_list> m_value_stack;