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 \