Mercurial > octave-nkf
diff libinterp/octave-value/ov.cc @ 19783:c913247c85a8
make colon function work (bug #44290)
* colon.m: Delete.
* scripts/miscellaneous/module.mk: Update.
* data.cc (Fcolon): New function.
* ov.h, ov.cc (do_colon_op): New functions.
* pt-colon.h, pt-colon.cc (tree_colon_expression::make_range): Delete.
(tree_colon_expression::rvalue1): Use do_colon_op instead of make_range.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 18 Feb 2015 17:02:13 -0500 |
parents | 4197fc428c7d |
children | 19755f4fc851 |
line wrap: on
line diff
--- a/libinterp/octave-value/ov.cc Wed Feb 18 14:29:59 2015 -0500 +++ b/libinterp/octave-value/ov.cc Wed Feb 18 17:02:13 2015 -0500 @@ -2388,6 +2388,101 @@ return retval; } +octave_value +do_colon_op (const octave_value& base, const octave_value& increment, + const octave_value& limit, bool is_for_cmd_expr) +{ + octave_value retval; + + if (base.is_object () || increment.is_object () || limit.is_object ()) + { + std::string dispatch_type; + + if (base.is_object ()) + dispatch_type = base.class_name (); + else if (increment.is_defined () && increment.is_object ()) + dispatch_type = increment.class_name (); + else + dispatch_type = limit.class_name (); + + octave_value meth = symbol_table::find_method ("colon", dispatch_type); + + if (meth.is_defined ()) + { + octave_value_list args; + + if (increment.is_defined ()) + { + args(2) = limit; + args(1) = increment; + } + else + args(1) = limit; + + args(0) = base; + + octave_value_list tmp = feval (meth.function_value (), args, 1); + + if (tmp.length () > 0) + retval = tmp(0); + } + else + error ("colon method not defined for %s class", dispatch_type.c_str ()); + } + else + { + bool result_is_str = (base.is_string () && limit.is_string ()); + bool dq_str = (base.is_dq_string () || limit.is_dq_string ()); + + Matrix m_base = base.matrix_value (true); + + if (error_state) + { + error ("invalid base value in colon expression"); + return retval; + } + + Matrix m_limit = limit.matrix_value (true); + + if (error_state) + { + error ("invalid limit value in colon expression"); + return retval; + } + + Matrix m_increment = (increment.is_defined () + ? increment.matrix_value (true) + : Matrix (1, 1, 1.0)); + + if (error_state) + { + error ("invalid increment value in colon expression"); + return retval; + } + + bool base_empty = m_base.is_empty (); + bool limit_empty = m_limit.is_empty (); + bool increment_empty = m_increment.is_empty (); + + if (base_empty || limit_empty || increment_empty) + retval = Range (); + else + { + Range r (m_base(0), m_limit(0), m_increment(0)); + + // For compatibility with Matlab, don't allow the range used in + // a FOR loop expression to be converted to a Matrix. + + retval = octave_value (r, is_for_cmd_expr); + + if (result_is_str) + retval = retval.convert_to_str (false, true, dq_str ? '"' : '\''); + } + } + + return retval; +} + void octave_value::print_info (std::ostream& os, const std::string& prefix) const {