diff --git a/libinterp/parse-tree/pt-eval.cc b/libinterp/parse-tree/pt-eval.cc --- a/libinterp/parse-tree/pt-eval.cc +++ b/libinterp/parse-tree/pt-eval.cc @@ -78,7 +78,9 @@ namespace octave void tree_evaluator::reset (void) { - m_value_stack.clear (); + m_result_type_stack.clear (); + m_single_value_stack.clear (); + m_multi_value_stack.clear (); m_lvalue_list_stack.clear (); m_nargout_stack.clear (); } @@ -151,7 +153,7 @@ namespace octave octave_value fh (octave_fcn_binder::maybe_binder (ov_fcn, this)); - m_value_stack.push (ovl (fh)); + push_result (fh); } void @@ -186,7 +188,7 @@ namespace octave if (etype == octave_value::op_el_or) { expr.matlab_style_short_circuit_warning ("|"); - m_value_stack.push (ovl (octave_value (true))); + push_result (octave_value (true)); return; } } @@ -195,7 +197,7 @@ namespace octave if (etype == octave_value::op_el_and) { expr.matlab_style_short_circuit_warning ("&"); - m_value_stack.push (ovl (octave_value (false))); + push_result (octave_value (false)); return; } } @@ -207,7 +209,7 @@ namespace octave result = b.is_true (); } - m_value_stack.push (ovl (octave_value (result))); + push_result (octave_value (result)); return; } } @@ -237,7 +239,7 @@ namespace octave } } - m_value_stack.push (ovl (val)); + push_result (val); } void @@ -266,7 +268,7 @@ namespace octave { if (etype == tree_boolean_expression::bool_or) { - m_value_stack.push (ovl (octave_value (true))); + push_result (octave_value (true)); return; } } @@ -274,7 +276,7 @@ namespace octave { if (etype == tree_boolean_expression::bool_and) { - m_value_stack.push (ovl (octave_value (false))); + push_result (octave_value (false)); return; } } @@ -291,7 +293,7 @@ namespace octave val = octave_value (result); } - m_value_stack.push (ovl (val)); + push_result (val); } void @@ -320,7 +322,7 @@ namespace octave } } - m_value_stack.push (ovl (val)); + push_result (val); } void @@ -352,7 +354,7 @@ namespace octave if (! op_base || ! op_limit) { - m_value_stack.push (ovl (octave_value (val))); + push_result (octave_value (val)); return; } @@ -402,7 +404,7 @@ namespace octave expr.is_for_cmd_expr ()); } - m_value_stack.push (ovl (val)); + push_result (val); } void @@ -1087,7 +1089,8 @@ namespace octave feval ("display", args); } - retval = val; + push_result (val); + return; } } else if (sym.is_added_static ()) @@ -1095,7 +1098,7 @@ namespace octave else expr.eval_undefined_error (); - m_value_stack.push (retval); + push_result (retval); } void @@ -1355,7 +1358,7 @@ namespace octave { // No more indices, so we are done. - m_value_stack.push (retval); + push_result (retval); return; } } @@ -1542,7 +1545,7 @@ namespace octave } } - m_value_stack.push (retval); + push_result (retval); } void @@ -1739,7 +1742,7 @@ namespace octave } } - m_value_stack.push (retval); + push_result (retval); } void @@ -1801,7 +1804,7 @@ namespace octave retval = val; - m_value_stack.push (retval); + push_result (retval); } void @@ -1966,7 +1969,7 @@ namespace octave val = retval_list; } - m_value_stack.push (val); + push_result (val); } void @@ -1991,7 +1994,7 @@ namespace octave if (nargout > 1) error ("invalid number of output arguments for constant expression"); - m_value_stack.push (ovl (expr.value ())); + push_result (expr.value ()); } void @@ -2001,7 +2004,7 @@ namespace octave octave_value fh = make_fcn_handle (nm); - m_value_stack.push (ovl (fh)); + push_result (fh); } void @@ -2033,7 +2036,7 @@ namespace octave } } - m_value_stack.push (retval); + push_result (retval); } void @@ -2077,7 +2080,7 @@ namespace octave } } - m_value_stack.push (ovl (val)); + push_result (val); } void @@ -2120,7 +2123,7 @@ namespace octave } } - m_value_stack.push (ovl (val)); + push_result (val); } void @@ -2232,7 +2235,7 @@ namespace octave } } - m_value_stack.push (ovl (val)); + push_result (val); } void @@ -2277,29 +2280,29 @@ namespace octave // evaluate the expression and that should take care of // everything, binding ans as necessary? - bool do_bind_ans = false; - - if (expr->is_identifier ()) + octave_value tmp_result = evaluate (expr, 0); + + if (tmp_result.is_defined ()) { - symbol_scope scope = get_current_scope (); - - symbol_record::context_id context = scope.current_context (); - - tree_identifier *id = dynamic_cast (expr); - - do_bind_ans = (! id->is_variable (context)); + bool do_bind_ans = false; + + if (expr->is_identifier ()) + { + symbol_scope scope = get_current_scope (); + + symbol_record::context_id context = scope.current_context (); + + tree_identifier *id = dynamic_cast (expr); + + do_bind_ans = (! id->is_variable (context)); + } + else + do_bind_ans = (! expr->is_assignment_expression ()); + + if (do_bind_ans) + bind_ans (tmp_result, expr->print_result () + && statement_printing_enabled ()); } - else - do_bind_ans = (! expr->is_assignment_expression ()); - - octave_value tmp_result = evaluate (expr, 0); - - if (do_bind_ans && tmp_result.is_defined ()) - bind_ans (tmp_result, expr->print_result () - && statement_printing_enabled ()); - - // if (tmp_result.is_defined ()) - // result_values(0) = tmp_result; } } catch (const std::bad_alloc&) diff --git a/libinterp/parse-tree/pt-eval.h b/libinterp/parse-tree/pt-eval.h --- a/libinterp/parse-tree/pt-eval.h +++ b/libinterp/parse-tree/pt-eval.h @@ -31,6 +31,7 @@ along with Octave; see the file COPYING. #include #include "call-stack.h" +#include "ov.h" #include "ovl.h" #include "profiler.h" #include "pt-exp.h" @@ -45,6 +46,12 @@ namespace octave class interpreter; class unwind_protect; + enum result_type + { + single = 1, + multi = 2 + }; + // How to evaluate the code that the parse trees represent. class OCTINTERP_API tree_evaluator : public tree_walker @@ -115,8 +122,10 @@ namespace octave typedef void (*decl_elt_init_fcn) (tree_decl_elt&); tree_evaluator (interpreter& interp) - : m_interpreter (interp), m_value_stack (), m_lvalue_list_stack (), - m_nargout_stack (), m_call_stack (interp), m_profiler (), + : m_interpreter (interp), m_result_type_stack (), + m_single_value_stack (), m_multi_value_stack (), + m_lvalue_list_stack (), m_nargout_stack (), + m_call_stack (interp), m_profiler (), m_max_recursion_depth (256), m_silent_functions (false), m_string_fill_char (' '), m_PS4 ("+ "), m_echo (ECHO_OFF), m_echo_state (false), m_echo_file_name (), m_echo_file_pos (1), @@ -269,28 +278,67 @@ namespace octave ? nullptr : m_lvalue_list_stack.top ()); } + void push_result (const octave_value& val) + { + m_result_type_stack.push (single); + m_single_value_stack.push (val); + } + + void push_result (const octave_value_list& vals) + { + m_result_type_stack.push (multi); + m_multi_value_stack.push (vals); + } + octave_value evaluate (tree_expression *expr, int nargout = 1) { + octave_value retval; + m_nargout_stack.push (nargout); expr->accept (*this); m_nargout_stack.pop (); - octave_value_list tmp = m_value_stack.val_pop (); + switch (m_result_type_stack.val_pop ()) + { + case single: + retval = m_single_value_stack.val_pop (); + break; - return tmp.empty () ? octave_value () : tmp(0); + case multi: + { + octave_value_list tmp = m_multi_value_stack.val_pop (); + retval = tmp(0); + } + break; + } + + return retval; } octave_value_list evaluate_n (tree_expression *expr, int nargout = 1) { + octave_value_list retval; + m_nargout_stack.push (nargout); expr->accept (*this); m_nargout_stack.pop (); - return m_value_stack.val_pop (); + switch (m_result_type_stack.val_pop ()) + { + case single: + retval = ovl (m_single_value_stack.val_pop ()); + break; + + case multi: + retval = m_multi_value_stack.val_pop (); + break; + } + + return retval; } octave_value evaluate (tree_decl_elt *); @@ -424,7 +472,9 @@ namespace octave interpreter& m_interpreter; - value_stack m_value_stack; + value_stack m_result_type_stack; + value_stack m_single_value_stack; + value_stack m_multi_value_stack; value_stack*> m_lvalue_list_stack;