Mercurial > octave
changeset 23481:73558a835b64
eliminate lvalue list arguments from evaluator functions
* ov.cc, ov.h, ov-base.cc, ov-base.h, ov-builtin.cc, ov-builtin.h,
ov-cell.cc, ov-cell.h, ov-fcn-handle.cc, ov-fcn-handle.h,
ov-usr-fcn.cc, ov-usr-fcn.h: Eliminate lvalue_list arguments from
subsref, next_subsref, and do_multi_index_op methods. Change all
callers.
* pt-eval.cc, pt-eval.h (tree_evaluator::ignored_fcn_outputs):
New function.
* ov-usr-fcn.h, ov-usr-fcn.cc
(octave_user_function::bind_automatic_vars): Get list of ignored
output arguments from evaluator.
* pt-eval.cc, pt-eval.h (tree_evaluator::visit_simple_assignment,
tree_evaluator::visit_multi_assignment): Push lvalue list on stack
here, not in tree_evaluator::evaluate or tree_evaluator::evaluate_n.
Use unwind_protect frame to pop from stack. Don't pass lvalue list to
evaluate or evaluate_n functions.
* pt-arg-list.cc, pt-arg-list.h (tree_argument_list::lvalue_list):
Delete.
* pt-eval.cc, pt-eval.h (tree_evaluator::make_lvalue_list):
New function.
(tree_evaluator::visit_multi_assignment): Use it instead of
tree_argument_list::lvalue_list.
* ov-builtin.cc, ov-builtin.h (octave_builtin::curr_lvalue_list):
Delete data member and all uses.
* defun.cc (defun_isargout): Get current lvalue_list from evaluator.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 10 May 2017 11:09:52 -0400 |
parents | 0670624ea91b |
children | c9937e865768 |
files | libinterp/corefcn/defun.cc libinterp/octave-value/ov-base.cc libinterp/octave-value/ov-base.h libinterp/octave-value/ov-builtin.cc libinterp/octave-value/ov-builtin.h libinterp/octave-value/ov-cell.cc libinterp/octave-value/ov-cell.h libinterp/octave-value/ov-fcn-handle.cc libinterp/octave-value/ov-fcn-handle.h libinterp/octave-value/ov-usr-fcn.cc libinterp/octave-value/ov-usr-fcn.h libinterp/octave-value/ov.cc libinterp/octave-value/ov.h libinterp/parse-tree/pt-arg-list.cc libinterp/parse-tree/pt-arg-list.h libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-eval.h |
diffstat | 17 files changed, 133 insertions(+), 286 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/defun.cc Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/corefcn/defun.cc Wed May 10 11:09:52 2017 -0400 @@ -42,8 +42,10 @@ #include "ovl.h" #include "oct-lvalue.h" #include "pager.h" +#include "pt-eval.h" +#include "interpreter-private.h" +#include "interpreter.h" #include "symtab.h" -#include "interpreter.h" #include "variables.h" #include "parse.h" @@ -158,7 +160,7 @@ bool defun_isargout (int nargout, int iout) { const std::list<octave_lvalue> *lvalue_list - = octave_builtin::curr_lvalue_list; + = octave::current_evaluator->lvalue_list (); if (iout >= std::max (nargout, 1)) return false; @@ -183,7 +185,7 @@ void defun_isargout (int nargout, int nout, bool *isargout) { const std::list<octave_lvalue> *lvalue_list - = octave_builtin::curr_lvalue_list; + = octave::current_evaluator->lvalue_list (); if (lvalue_list) {
--- a/libinterp/octave-value/ov-base.cc Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/octave-value/ov-base.cc Wed May 10 11:09:52 2017 -0400 @@ -238,16 +238,6 @@ return subsref (type, idx); } -octave_value_list -octave_base_value::subsref (const std::string& type, - const std::list<octave_value_list>& idx, - int nargout, - const std::list<octave_lvalue> *) -{ - // Fall back to call without passing lvalue list. - return subsref (type, idx, nargout); -} - octave_value octave_base_value::do_index_op (const octave_value_list&, bool) { @@ -262,14 +252,6 @@ error ("can't perform indexing operations for %s type", nm.c_str ()); } -octave_value_list -octave_base_value::do_multi_index_op (int nargout, const octave_value_list& idx, - const std::list<octave_lvalue> *) -{ - // Fall back. - return do_multi_index_op (nargout, idx); -} - idx_vector octave_base_value::index_vector (bool /* require_integers */) const {
--- a/libinterp/octave-value/ov-base.h Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/octave-value/ov-base.h Wed May 10 11:09:52 2017 -0400 @@ -275,22 +275,12 @@ const std::list<octave_value_list>& idx, bool auto_add); - virtual octave_value_list - subsref (const std::string& type, - const std::list<octave_value_list>& idx, - int nargout, - const std::list<octave_lvalue> *lvalue_list); - virtual octave_value do_index_op (const octave_value_list& idx, bool resize_ok = false); virtual octave_value_list do_multi_index_op (int nargout, const octave_value_list& idx); - virtual octave_value_list - do_multi_index_op (int nargout, const octave_value_list& idx, - const std::list<octave_lvalue> *lvalue_list); - virtual void assign (const std::string&, const octave_value&) { } virtual octave_value
--- a/libinterp/octave-value/ov-builtin.cc Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/octave-value/ov-builtin.cc Wed May 10 11:09:52 2017 -0400 @@ -44,15 +44,6 @@ const std::list<octave_value_list>& idx, int nargout) { - return octave_builtin::subsref (type, idx, nargout, 0); -} - -octave_value_list -octave_builtin::subsref (const std::string& type, - const std::list<octave_value_list>& idx, - int nargout, - const std::list<octave_lvalue>* lvalue_list) -{ octave_value_list retval; switch (type[0]) @@ -61,8 +52,7 @@ { int tmp_nargout = (type.length () > 1 && nargout == 0) ? 1 : nargout; - retval = do_multi_index_op (tmp_nargout, idx.front (), - idx.size () == 1 ? lvalue_list : 0); + retval = do_multi_index_op (tmp_nargout, idx.front ()); } break; @@ -97,13 +87,6 @@ octave_value_list octave_builtin::do_multi_index_op (int nargout, const octave_value_list& args) { - return octave_builtin::do_multi_index_op (nargout, args, 0); -} - -octave_value_list -octave_builtin::do_multi_index_op (int nargout, const octave_value_list& args, - const std::list<octave_lvalue> *lvalue_list) -{ octave_value_list retval; if (args.has_magic_colon ()) @@ -115,12 +98,6 @@ frame.add_fcn (octave::call_stack::pop); - if (lvalue_list || curr_lvalue_list) - { - frame.protect_var (curr_lvalue_list); - curr_lvalue_list = lvalue_list; - } - profile_data_accumulator::enter<octave_builtin> block (profiler, *this); retval = (*f) (args, nargout); @@ -176,5 +153,3 @@ { return dispatch_classes.find (dispatch_type) != dispatch_classes.end (); } - -const std::list<octave_lvalue> *octave_builtin::curr_lvalue_list = nullptr;
--- a/libinterp/octave-value/ov-builtin.h Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/octave-value/ov-builtin.h Wed May 10 11:09:52 2017 -0400 @@ -77,11 +77,6 @@ const std::list<octave_value_list>& idx, int nargout); - octave_value_list subsref (const std::string& type, - const std::list<octave_value_list>& idx, - int nargout, - const std::list<octave_lvalue>* lvalue_list); - octave_function * function_value (bool = false) { return this; } bool is_builtin_function (void) const { return true; } @@ -89,10 +84,6 @@ octave_value_list do_multi_index_op (int nargout, const octave_value_list& args); - octave_value_list - do_multi_index_op (int nargout, const octave_value_list& args, - const std::list<octave_lvalue>* lvalue_list); - jit_type * to_jit (void) const; void stash_jit (jit_type& type); @@ -103,8 +94,6 @@ bool handles_dispatch_class (const std::string& dispatch_type) const; - static const std::list<octave_lvalue> *curr_lvalue_list; - protected: // A pointer to the actual function.
--- a/libinterp/octave-value/ov-cell.cc Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/octave-value/ov-cell.cc Wed May 10 11:09:52 2017 -0400 @@ -131,8 +131,7 @@ octave_value_list octave_cell::subsref (const std::string& type, const std::list<octave_value_list>& idx, - int nargout, - const std::list<octave_lvalue> *lvalue_list) + int nargout) { octave_value_list retval; @@ -174,9 +173,7 @@ // octave_user_function::subsref. if (idx.size () > 1) - retval = (lvalue_list - ? retval(0).next_subsref (nargout, type, idx, lvalue_list) - : retval(0).next_subsref (nargout, type, idx)); + retval = retval(0).next_subsref (nargout, type, idx); return retval; }
--- a/libinterp/octave-value/ov-cell.h Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/octave-value/ov-cell.h Wed May 10 11:09:52 2017 -0400 @@ -80,15 +80,7 @@ octave_value_list subsref (const std::string& type, const std::list<octave_value_list>& idx, - int nargout) - { - return subsref (type, idx, nargout, 0); - } - - octave_value_list subsref (const std::string& type, - const std::list<octave_value_list>& idx, - int nargout, - const std::list<octave_lvalue> *lvalue_list); + int nargout); octave_value subsref (const std::string& type, const std::list<octave_value_list>& idx,
--- a/libinterp/octave-value/ov-fcn-handle.cc Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/octave-value/ov-fcn-handle.cc Wed May 10 11:09:52 2017 -0400 @@ -96,15 +96,6 @@ const std::list<octave_value_list>& idx, int nargout) { - return octave_fcn_handle::subsref (type, idx, nargout, 0); -} - -octave_value_list -octave_fcn_handle::subsref (const std::string& type, - const std::list<octave_value_list>& idx, - int nargout, - const std::list<octave_lvalue>* lvalue_list) -{ octave_value_list retval; switch (type[0]) @@ -113,8 +104,7 @@ { int tmp_nargout = (type.length () > 1 && nargout == 0) ? 1 : nargout; - retval = do_multi_index_op (tmp_nargout, idx.front (), - idx.size () == 1 ? lvalue_list : 0); + retval = do_multi_index_op (tmp_nargout, idx.front ()); } break; @@ -144,14 +134,6 @@ octave_fcn_handle::do_multi_index_op (int nargout, const octave_value_list& args) { - return do_multi_index_op (nargout, args, 0); -} - -octave_value_list -octave_fcn_handle::do_multi_index_op (int nargout, - const octave_value_list& args, - const std::list<octave_lvalue>* lvalue_list) -{ octave_value_list retval; out_of_date_check (fcn, "", false); @@ -213,9 +195,9 @@ } if (ov_fcn.is_defined ()) - retval = ov_fcn.do_multi_index_op (nargout, args, lvalue_list); + retval = ov_fcn.do_multi_index_op (nargout, args); else if (fcn.is_defined ()) - retval = fcn.do_multi_index_op (nargout, args, lvalue_list); + retval = fcn.do_multi_index_op (nargout, args); else error ("%s: no method for class %s", nm.c_str (), dispatch_type.c_str ()); @@ -224,7 +206,7 @@ { // Non-overloaded function (anonymous, subfunction, private function). if (fcn.is_defined ()) - retval = fcn.do_multi_index_op (nargout, args, lvalue_list); + retval = fcn.do_multi_index_op (nargout, args); else error ("%s: no longer valid function handle", nm.c_str ()); } @@ -2089,14 +2071,6 @@ octave_fcn_binder::do_multi_index_op (int nargout, const octave_value_list& args) { - return do_multi_index_op (nargout, args, 0); -} - -octave_value_list -octave_fcn_binder::do_multi_index_op (int nargout, - const octave_value_list& args, - const std::list<octave_lvalue>* lvalue_list) -{ octave_value_list retval; if (args.length () == expected_nargin) @@ -2111,10 +2085,10 @@ // Make a shallow copy of arg_template, to ensure consistency throughout // the following call even if we happen to get back here. octave_value_list tmp (arg_template); - retval = root_handle.do_multi_index_op (nargout, tmp, lvalue_list); + retval = root_handle.do_multi_index_op (nargout, tmp); } else - retval = octave_fcn_handle::do_multi_index_op (nargout, args, lvalue_list); + retval = octave_fcn_handle::do_multi_index_op (nargout, args); return retval; }
--- a/libinterp/octave-value/ov-fcn-handle.h Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/octave-value/ov-fcn-handle.h Wed May 10 11:09:52 2017 -0400 @@ -90,18 +90,9 @@ const std::list<octave_value_list>& idx, int nargout); - octave_value_list subsref (const std::string& type, - const std::list<octave_value_list>& idx, - int nargout, - const std::list<octave_lvalue>* lvalue_list); - octave_value_list do_multi_index_op (int nargout, const octave_value_list& args); - octave_value_list - do_multi_index_op (int nargout, const octave_value_list& args, - const std::list<octave_lvalue>* lvalue_list); - bool is_defined (void) const { return true; } bool is_function_handle (void) const { return true; } @@ -211,10 +202,6 @@ octave_value_list do_multi_index_op (int nargout, const octave_value_list& args); - octave_value_list - do_multi_index_op (int nargout, const octave_value_list& args, - const std::list<octave_lvalue>* lvalue_list); - protected: octave_value root_handle;
--- a/libinterp/octave-value/ov-usr-fcn.cc Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/octave-value/ov-usr-fcn.cc Wed May 10 11:09:52 2017 -0400 @@ -410,15 +410,6 @@ const std::list<octave_value_list>& idx, int nargout) { - return octave_user_function::subsref (type, idx, nargout, 0); -} - -octave_value_list -octave_user_function::subsref (const std::string& type, - const std::list<octave_value_list>& idx, - int nargout, - const std::list<octave_lvalue>* lvalue_list) -{ octave_value_list retval; switch (type[0]) @@ -427,8 +418,7 @@ { int tmp_nargout = (type.length () > 1 && nargout == 0) ? 1 : nargout; - retval = do_multi_index_op (tmp_nargout, idx.front (), - idx.size () == 1 ? lvalue_list : 0); + retval = do_multi_index_op (tmp_nargout, idx.front ()); } break; @@ -456,15 +446,7 @@ octave_value_list octave_user_function::do_multi_index_op (int nargout, - const octave_value_list& args) -{ - return do_multi_index_op (nargout, args, 0); -} - -octave_value_list -octave_user_function::do_multi_index_op (int nargout, - const octave_value_list& _args, - const std::list<octave_lvalue>* lvalue_list) + const octave_value_list& _args) { octave_value_list retval; @@ -570,8 +552,8 @@ frame.add_fcn (symbol_table::clear_variables); } - bind_automatic_vars (arg_names, args.length (), nargout, - all_va_args (args), lvalue_list); + bind_automatic_vars (tw, arg_names, args.length (), nargout, + all_va_args (args)); frame.add_method (this, &octave_user_function::restore_warning_states); @@ -607,7 +589,7 @@ { octave::call_stack::set_location (stmt->line (), stmt->column ()); - retval = tw->evaluate_n (expr, nargout, lvalue_list); + retval = tw->evaluate_n (expr, nargout); } } else @@ -705,9 +687,8 @@ void octave_user_function::bind_automatic_vars - (const string_vector& arg_names, int nargin, int nargout, - const octave_value_list& va_args, - const std::list<octave_lvalue> *lvalue_list) + (octave::tree_evaluator *tw, const string_vector& arg_names, + int nargin, int nargout, const octave_value_list& va_args) { if (! arg_names.empty ()) { @@ -743,31 +724,12 @@ if (takes_varargs ()) symbol_table::assign ("varargin", va_args.cell_value ()); - // Force .ignored. variable to be undefined by default. - symbol_table::assign (".ignored."); - - if (lvalue_list) - { - octave_idx_type nbh = 0; - for (const auto& lval : *lvalue_list) - nbh += lval.is_black_hole (); + Matrix ignored_fcn_outputs = tw ? tw->ignored_fcn_outputs () : Matrix (); - if (nbh > 0) - { - // Only assign the hidden variable if black holes actually present. - Matrix bh (1, nbh); - octave_idx_type k = 0; - octave_idx_type l = 0; - for (const auto& lval : *lvalue_list) - { - if (lval.is_black_hole ()) - bh(l++) = k+1; - k += lval.numel (); - } - - symbol_table::assign (".ignored.", bh); - } - } + if (ignored_fcn_outputs.is_empty ()) + symbol_table::assign (".ignored."); + else + symbol_table::assign (".ignored.", ignored_fcn_outputs); symbol_table::mark_hidden (".ignored."); symbol_table::mark_automatic (".ignored.");
--- a/libinterp/octave-value/ov-usr-fcn.h Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/octave-value/ov-usr-fcn.h Wed May 10 11:09:52 2017 -0400 @@ -45,6 +45,7 @@ { class tree_parameter_list; class tree_statement_list; + class tree_evaluator; class tree_expression; class tree_walker; } @@ -370,18 +371,9 @@ const std::list<octave_value_list>& idx, int nargout); - octave_value_list subsref (const std::string& type, - const std::list<octave_value_list>& idx, - int nargout, - const std::list<octave_lvalue>* lvalue_list); - octave_value_list do_multi_index_op (int nargout, const octave_value_list& args); - octave_value_list - do_multi_index_op (int nargout, const octave_value_list& args, - const std::list<octave_lvalue>* lvalue_list); - octave::tree_parameter_list * parameter_list (void) { return param_list; } octave::tree_parameter_list * return_list (void) { return ret_list; } @@ -517,9 +509,10 @@ void print_code_function_trailer (void); - void bind_automatic_vars (const string_vector& arg_names, int nargin, - int nargout, const octave_value_list& va_args, - const std::list<octave_lvalue> *lvalue_list); + void bind_automatic_vars (octave::tree_evaluator *tw, + const string_vector& arg_names, + int nargin, int nargout, + const octave_value_list& va_args); void restore_warning_states (void);
--- a/libinterp/octave-value/ov.cc Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/octave-value/ov.cc Wed May 10 11:09:52 2017 -0400 @@ -1451,17 +1451,6 @@ return rep->subsref (type, idx, nargout); } -octave_value_list -octave_value::subsref (const std::string& type, - const std::list<octave_value_list>& idx, int nargout, - const std::list<octave_lvalue> *lvalue_list) -{ - if (lvalue_list) - return rep->subsref (type, idx, nargout, lvalue_list); - else - return subsref (type, idx, nargout); -} - octave_value octave_value::next_subsref (const std::string& type, const std::list<octave_value_list>& idx, @@ -1494,23 +1483,6 @@ return *this; } -octave_value_list -octave_value::next_subsref (int nargout, const std::string& type, - const std::list<octave_value_list>& idx, - const std::list<octave_lvalue> *lvalue_list, - size_t skip) -{ - if (idx.size () > skip) - { - std::list<octave_value_list> new_idx (idx); - for (size_t i = 0; i < skip; i++) - new_idx.erase (new_idx.begin ()); - return subsref (type.substr (skip), new_idx, nargout, lvalue_list); - } - else - return *this; -} - octave_value octave_value::next_subsref (bool auto_add, const std::string& type, const std::list<octave_value_list>& idx, @@ -1533,13 +1505,6 @@ return rep->do_multi_index_op (nargout, idx); } -octave_value_list -octave_value::do_multi_index_op (int nargout, const octave_value_list& idx, - const std::list<octave_lvalue> *lvalue_list) -{ - return rep->do_multi_index_op (nargout, idx, lvalue_list); -} - octave_value octave_value::subsasgn (const std::string& type, const std::list<octave_value_list>& idx,
--- a/libinterp/octave-value/ov.h Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/octave-value/ov.h Wed May 10 11:09:52 2017 -0400 @@ -431,11 +431,6 @@ const std::list<octave_value_list>& idx, int nargout); - octave_value_list subsref (const std::string& type, - const std::list<octave_value_list>& idx, - int nargout, - const std::list<octave_lvalue> *lvalue_list); - octave_value next_subsref (const std::string& type, const std::list<octave_value_list>& idx, size_t skip = 1); @@ -445,12 +440,6 @@ std::list<octave_value_list>& idx, size_t skip = 1); - octave_value_list next_subsref (int nargout, - const std::string& type, const - std::list<octave_value_list>& idx, - const std::list<octave_lvalue> *lvalue_list, - size_t skip = 1); - octave_value next_subsref (bool auto_add, const std::string& type, const std::list<octave_value_list>& idx, size_t skip = 1); @@ -462,10 +451,6 @@ octave_value_list do_multi_index_op (int nargout, const octave_value_list& idx); - octave_value_list - do_multi_index_op (int nargout, const octave_value_list& idx, - const std::list<octave_lvalue> *lvalue_list); - octave_value subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs);
--- a/libinterp/parse-tree/pt-arg-list.cc Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/parse-tree/pt-arg-list.cc Wed May 10 11:09:52 2017 -0400 @@ -31,7 +31,6 @@ #include "defun.h" #include "error.h" -#include "oct-lvalue.h" #include "ovl.h" #include "ov.h" #include "ov-usr-fcn.h" @@ -262,17 +261,6 @@ return args; } - std::list<octave_lvalue> - tree_argument_list::lvalue_list (tree_evaluator *tw) - { - std::list<octave_lvalue> retval; - - for (tree_expression *elt : *this) - retval.push_back (elt->lvalue (tw)); - - return retval; - } - string_vector tree_argument_list::get_arg_names (void) const {
--- a/libinterp/parse-tree/pt-arg-list.h Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/parse-tree/pt-arg-list.h Wed May 10 11:09:52 2017 -0400 @@ -28,7 +28,6 @@ #include <list> class octave_value_list; -class octave_lvalue; #include "str-vec.h" @@ -93,8 +92,6 @@ octave_value_list convert_to_const_vector (tree_evaluator *tw, const octave_value *object = nullptr); - std::list<octave_lvalue> lvalue_list (tree_evaluator *tw); - string_vector get_arg_names (void) const; std::list<std::string> variable_names (void) const;
--- a/libinterp/parse-tree/pt-eval.cc Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/parse-tree/pt-eval.cc Wed May 10 11:09:52 2017 -0400 @@ -82,8 +82,8 @@ tree_evaluator::reset (void) { m_value_stack.clear (); - m_lvalue_list_stack.pop (); - m_nargout_stack.pop (); + m_lvalue_list_stack.clear (); + m_nargout_stack.clear (); } void @@ -408,6 +408,43 @@ || statement_context == script)); } + Matrix + tree_evaluator::ignored_fcn_outputs (void) const + { + Matrix retval; + + 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 (); + + octave_idx_type nbh = 0; + + for (const auto& lval : *lvalue_list) + nbh += lval.is_black_hole (); + + if (nbh > 0) + { + retval.resize (1, nbh); + + octave_idx_type k = 0; + octave_idx_type l = 0; + + for (const auto& lval : *lvalue_list) + { + if (lval.is_black_hole ()) + retval(l++) = k+1; + + k += lval.numel (); + } + } + + return retval; + } + octave_value tree_evaluator::evaluate (tree_decl_elt *elt) { @@ -942,14 +979,7 @@ if (fcn && ! (expr.is_postfix_indexed () && fcn->is_postfix_index_handled (expr.postfix_index ()))) { - octave_value_list tmp_args; - - const std::list<octave_lvalue> *lvalue_list - = m_lvalue_list_stack.top (); - - retval = (lvalue_list - ? val.do_multi_index_op (nargout, tmp_args, lvalue_list) - : val.do_multi_index_op (nargout, tmp_args)); + retval = val.do_multi_index_op (nargout, octave_value_list ()); } else { @@ -1230,12 +1260,9 @@ p_dyn_field++; } - const std::list<octave_lvalue> *lvalue_list = m_lvalue_list_stack.top (); - try { - retval = tmp.subsref (type.substr (tmpi, n - tmpi), idx, nargout, - lvalue_list); + retval = tmp.subsref (type.substr (tmpi, n - tmpi), idx, nargout); } catch (octave::index_exception& e) // range problems, bad index type, etc. { @@ -1252,10 +1279,7 @@ { octave_value_list empty_args; - retval = (lvalue_list - ? val.do_multi_index_op (nargout, empty_args, - lvalue_list) - : val.do_multi_index_op (nargout, empty_args)); + retval = val.do_multi_index_op (nargout, empty_args); } } @@ -1520,9 +1544,16 @@ if (rhs) { + unwind_protect frame; + tree_argument_list *lhs = expr.left_hand_side (); - std::list<octave_lvalue> lvalue_list = lhs->lvalue_list (this); + std::list<octave_lvalue> lvalue_list = make_lvalue_list (lhs); + + m_lvalue_list_stack.push (&lvalue_list); + + frame.add_method (m_lvalue_list_stack, + &value_stack<const std::list<octave_lvalue>*>::pop); octave_idx_type n_out = 0; @@ -1530,7 +1561,7 @@ n_out += lval.numel (); // The following trick is used to keep rhs_val constant. - const octave_value_list rhs_val1 = evaluate_n (rhs, n_out, &lvalue_list); + const octave_value_list rhs_val1 = evaluate_n (rhs, n_out); const octave_value_list rhs_val = (rhs_val1.length () == 1 && rhs_val1(0).is_cs_list () ? rhs_val1(0).list_value () @@ -1869,8 +1900,18 @@ try { + octave::unwind_protect frame; + octave_lvalue ult = lhs->lvalue (this); + std::list<octave_lvalue> lvalue_list; + lvalue_list.push_back (ult); + + m_lvalue_list_stack.push (&lvalue_list); + + frame.add_method (m_lvalue_list_stack, + &value_stack<const std::list<octave_lvalue>*>::pop); + if (ult.numel () != 1) err_nonbraced_cs_list_assignment (); @@ -2467,6 +2508,17 @@ return expr_value; } + + std::list<octave_lvalue> + tree_evaluator::make_lvalue_list (tree_argument_list *lhs) + { + std::list<octave_lvalue> retval; + + for (tree_expression *elt : *lhs) + retval.push_back (elt->lvalue (this)); + + return retval; + } } DEFUN (max_recursion_depth, args, nargout,
--- a/libinterp/parse-tree/pt-eval.h Wed May 10 15:04:28 2017 +0200 +++ b/libinterp/parse-tree/pt-eval.h Wed May 10 11:09:52 2017 -0400 @@ -62,7 +62,12 @@ void push (const T& val) { m_stack.push (val); } - T pop (void) + void pop (void) + { + m_stack.pop (); + } + + T val_pop (void) { T retval = m_stack.top (); m_stack.pop (); @@ -74,6 +79,16 @@ return m_stack.top (); } + size_t size (void) const + { + return m_stack.size (); + } + + bool empty (void) const + { + return m_stack.empty (); + } + void clear (void) { while (! m_stack.empty ()) @@ -225,35 +240,35 @@ // TRUE means we are evaluating some kind of looping construct. static bool in_loop_command; - octave_value evaluate (tree_expression *expr, int nargout = 1, - const std::list<octave_lvalue> *lvalue_list = nullptr) + Matrix ignored_fcn_outputs (void) const; + + const std::list<octave_lvalue> * lvalue_list (void) + { + return m_lvalue_list_stack.empty () ? 0 : m_lvalue_list_stack.top (); + } + + octave_value evaluate (tree_expression *expr, int nargout = 1) { m_nargout_stack.push (nargout); - m_lvalue_list_stack.push (lvalue_list); expr->accept (*this); m_nargout_stack.pop (); - m_lvalue_list_stack.pop (); - octave_value_list tmp = m_value_stack.pop (); + octave_value_list tmp = m_value_stack.val_pop (); return tmp.empty () ? octave_value () : tmp(0); } - octave_value_list - evaluate_n (tree_expression *expr, int nargout = 1, - const std::list<octave_lvalue> *lvalue_list = nullptr) + octave_value_list evaluate_n (tree_expression *expr, int nargout = 1) { m_nargout_stack.push (nargout); - m_lvalue_list_stack.push (lvalue_list); expr->accept (*this); m_nargout_stack.pop (); - m_lvalue_list_stack.pop (); - return m_value_stack.pop (); + return m_value_stack.val_pop (); } octave_value evaluate (tree_decl_elt *); @@ -289,6 +304,8 @@ bool is_logically_true (tree_expression *expr, const char *warn_for); + std::list<octave_lvalue> make_lvalue_list (tree_argument_list *); + value_stack<octave_value_list> m_value_stack; value_stack<const std::list<octave_lvalue>*> m_lvalue_list_stack;