Mercurial > octave-nkf
changeset 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 | 3fc946d5e91f |
children | 2111917d34c4 |
files | libinterp/corefcn/data.cc libinterp/octave-value/ov.cc libinterp/octave-value/ov.h libinterp/parse-tree/pt-colon.cc libinterp/parse-tree/pt-colon.h scripts/miscellaneous/colon.m scripts/miscellaneous/module.mk |
diffstat | 7 files changed, 140 insertions(+), 145 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/data.cc Wed Feb 18 14:29:59 2015 -0500 +++ b/libinterp/corefcn/data.cc Wed Feb 18 17:02:13 2015 -0500 @@ -6262,6 +6262,37 @@ octave_value::op_el_or_eq, args); } +DEFUN (colon, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {@var{r} =} colon (@var{base}, @var{limit})\n\ +@deftypefnx {Built-in Function} {@var{r} =} colon (@var{base}, @var{increment}, @var{limit})\n\ +Return the result of the colon expression corresponding to @var{base}, @var{limit}, and optionally, @var{increment}.\n\ +\n\ +This function is equivalent to the operator syntax @w{@code{base : limit}}\n\ +or @w{@code{base : increment : limit}}.\n\ +@end deftypefn") +{ + octave_value retval; + int nargin = args.length (); + + switch (nargin) + { + case 2: + retval = do_colon_op (args(0), args(1)); + break; + + case 3: + retval = do_colon_op (args(0), args(1), args (2)); + break; + + default: + print_usage (); + break; + } + + return retval; +} + static double tic_toc_timestamp = -1.0; DEFUN (tic, args, nargout,
--- 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 {
--- a/libinterp/octave-value/ov.h Wed Feb 18 14:29:59 2015 -0500 +++ b/libinterp/octave-value/ov.h Wed Feb 18 17:02:13 2015 -0500 @@ -1064,6 +1064,18 @@ const octave_value& b, const Array<octave_idx_type>& ra_idx); + friend OCTINTERP_API octave_value do_colon_op (const octave_value& base, + const octave_value& limit, + bool is_for_cmd_expr = false) + { + return do_colon_op (base, octave_value (), limit, is_for_cmd_expr); + } + + friend OCTINTERP_API octave_value do_colon_op (const octave_value& base, + const octave_value& increment, + const octave_value& limit, + bool is_for_cmd_expr = false); + const octave_base_value& get_rep (void) const { return *rep; } bool is_copy_of (const octave_value &val) const { return rep == val.rep; }
--- a/libinterp/parse-tree/pt-colon.cc Wed Feb 18 14:29:59 2015 -0500 +++ b/libinterp/parse-tree/pt-colon.cc Wed Feb 18 17:02:13 2015 -0500 @@ -81,94 +81,6 @@ } octave_value -tree_colon_expression::make_range (const Matrix& m_base, - const Matrix& m_limit, - const Matrix& m_increment, - bool result_is_str, bool dq_str) const -{ - octave_value 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; -} - -octave_value -tree_colon_expression::make_range (const octave_value& ov_base, - const octave_value& ov_limit, - const octave_value& ov_increment) const -{ - octave_value retval; - - if (ov_base.is_object () || ov_limit.is_object () || - ov_increment.is_object ()) - { - octave_value_list tmp1; - tmp1(2) = ov_limit; - tmp1(1) = ov_increment; - tmp1(0) = ov_base; - - octave_value fcn = symbol_table::find_function ("colon", tmp1); - - if (fcn.is_defined ()) - { - octave_value_list tmp2 = fcn.do_multi_index_op (1, tmp1); - - if (! error_state) - retval = tmp2 (0); - } - else - ::error ("can not find overloaded colon function"); - } - else - { - bool result_is_str = (ov_base.is_string () && ov_limit.is_string ()); - bool dq_str = (ov_base.is_dq_string () || ov_limit.is_dq_string ()); - - Matrix m_base = ov_base.matrix_value (true); - - if (error_state) - eval_error ("invalid base value in colon expression"); - else - { - Matrix m_limit = ov_limit.matrix_value (true); - - if (error_state) - eval_error ("invalid limit value in colon expression"); - else - { - Matrix m_increment = ov_increment.matrix_value (true); - - if (error_state) - eval_error ("invalid increment value in colon expression"); - else - retval = make_range (m_base, m_limit, m_increment, - result_is_str, dq_str); - } - } - } - - return retval; -} - -octave_value tree_colon_expression::rvalue1 (int) { octave_value retval; @@ -237,7 +149,8 @@ } if (! error_state) - retval = make_range (ov_base, ov_limit, ov_increment); + retval = do_colon_op (ov_base, ov_increment, ov_limit, + is_for_cmd_expr ()); } }
--- a/libinterp/parse-tree/pt-colon.h Wed Feb 18 14:29:59 2015 -0500 +++ b/libinterp/parse-tree/pt-colon.h Wed Feb 18 17:02:13 2015 -0500 @@ -105,15 +105,6 @@ bool save_base; - octave_value - make_range (const Matrix& m_base, const Matrix& m_limit, - const Matrix& m_increment, bool result_is_str, - bool dq_str) const; - - octave_value - make_range (const octave_value& ov_base, const octave_value& ov_limit, - const octave_value& ov_increment) const; - // No copying! tree_colon_expression (const tree_colon_expression&);
--- a/scripts/miscellaneous/colon.m Wed Feb 18 14:29:59 2015 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -## Copyright (C) 2008-2015 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {@var{r} =} colon (@var{a}, @var{b}) -## @deftypefnx {Function File} {@var{r} =} colon (@var{a}, @var{b}, @var{c}) -## Method of a class to construct a range with the @code{:} operator. For -## example: -## -## @example -## @group -## a = myclass (@dots{}); -## b = myclass (@dots{}); -## c = a : b -## @end group -## @end example -## -## @seealso{class, subsref, subsasgn} -## @end deftypefn - -function colon (varargin) - - if (nargin != 0) - error ('colon: not defined for class "%s"', class (varargin{1})); - endif - -endfunction - - -%!error <colon: not defined for class "double"> colon (1) -
--- a/scripts/miscellaneous/module.mk Wed Feb 18 14:29:59 2015 -0500 +++ b/scripts/miscellaneous/module.mk Wed Feb 18 17:02:13 2015 -0500 @@ -10,7 +10,6 @@ miscellaneous/bunzip2.m \ miscellaneous/bzip2.m \ miscellaneous/cast.m \ - miscellaneous/colon.m \ miscellaneous/citation.m \ miscellaneous/comma.m \ miscellaneous/compare_versions.m \