diff libinterp/octave-value/ov.cc @ 28519:d4563c5d4060

handle all dispatching for colon operator in do_colon_op function * ov.cc (do_colon_op): Handle all dispatching here, but using lookup based on argument vector passed to feval instead of determining dispatch type separately. * pt-colon.cc (tree_colon_expression::evaluate): Simply evaluate arguments and pass them to do_colon_op. * test/colon-op: New test directory. * test/module.mk: Update.
author John W. Eaton <jwe@octave.org>
date Mon, 29 Jun 2020 23:45:19 -0400
parents b743a63e2dab
children ee9b1081471f
line wrap: on
line diff
--- a/libinterp/octave-value/ov.cc	Tue Jun 30 15:52:25 2020 -0400
+++ b/libinterp/octave-value/ov.cc	Mon Jun 29 23:45:19 2020 -0400
@@ -2506,103 +2506,95 @@
 
   if (base.isobject () || increment.isobject () || limit.isobject ())
     {
-      std::string dispatch_type;
-
-      if (base.isobject ())
-        dispatch_type = base.class_name ();
-      else if (increment.is_defined () && increment.isobject ())
-        dispatch_type = increment.class_name ();
-      else
-        dispatch_type = limit.class_name ();
-
-      octave::symbol_table& symtab = octave::__get_symbol_table__ ("do_colon_op");
-
-      octave_value meth = symtab.find_method ("colon", dispatch_type);
-
-      if (! meth.is_defined ())
-        error ("colon method not defined for %s class", dispatch_type.c_str ());
-
-      octave_value_list args;
+      octave_value_list tmp1;
 
       if (increment.is_defined ())
         {
-          args(2) = limit;
-          args(1) = increment;
+          tmp1(2) = limit;
+          tmp1(1) = increment;
+          tmp1(0) = base;
         }
       else
-        args(1) = limit;
-
-      args(0) = base;
-
-      octave_value_list tmp = octave::feval (meth.function_value (), args, 1);
-
-      if (tmp.length () > 0)
-        retval = tmp(0);
+        {
+          tmp1(1) = limit;
+          tmp1(0) = base;
+        }
+
+      octave::interpreter& interp = octave::__get_interpreter__ ("do_colon_op");
+
+      octave::symbol_table& symtab = interp.get_symbol_table ();
+
+      octave_value fcn = symtab.find_function ("colon", tmp1);
+
+      if (fcn.is_defined ())
+        {
+          octave_value_list tmp2 = interp.feval (fcn, tmp1, 1);
+
+          return tmp2 (0);
+        }
     }
+
+  bool result_is_str = (base.is_string () && limit.is_string ());
+  bool dq_str = (base.is_dq_string () || limit.is_dq_string ());
+
+  if (base.numel () > 1 || limit.numel () > 1
+      || (increment.is_defined () && increment.numel () > 1))
+    warning_with_id ("Octave:colon-nonscalar-argument",
+                     "colon arguments should be scalars");
+
+  if (base.iscomplex () || limit.iscomplex ()
+      || (increment.is_defined () && increment.iscomplex ()))
+    warning_with_id ("Octave:colon-complex-argument",
+                     "imaginary part of complex colon arguments is ignored");
+
+  Matrix m_base, m_limit, m_increment;
+
+  try
+    {
+      m_base = base.matrix_value (true);
+    }
+  catch (octave::execution_exception& e)
+    {
+      error (e, "invalid base value in colon expression");
+    }
+
+  try
+    {
+      m_limit = limit.matrix_value (true);
+    }
+  catch (octave::execution_exception& e)
+    {
+      error (e, "invalid limit value in colon expression");
+    }
+
+  try
+    {
+      m_increment = (increment.is_defined ()
+                     ? increment.matrix_value (true)
+                     : Matrix (1, 1, 1.0));
+    }
+  catch (octave::execution_exception& e)
+    {
+      error (e, "invalid increment value in colon expression");
+    }
+
+  bool base_empty = m_base.isempty ();
+  bool limit_empty = m_limit.isempty ();
+  bool increment_empty = m_increment.isempty ();
+
+  if (base_empty || limit_empty || increment_empty)
+    retval = Range ();
   else
     {
-      bool result_is_str = (base.is_string () && limit.is_string ());
-      bool dq_str = (base.is_dq_string () || limit.is_dq_string ());
-
-      if (base.numel () > 1 || limit.numel () > 1
-          || (increment.is_defined () && increment.numel () > 1))
-        warning_with_id ("Octave:colon-nonscalar-argument",
-                         "colon arguments should be scalars");
-
-      if (base.iscomplex () || limit.iscomplex ()
-          || (increment.is_defined () && increment.iscomplex ()))
-        warning_with_id ("Octave:colon-complex-argument",
-                         "imaginary part of complex colon arguments is ignored");
-
-      Matrix m_base, m_limit, m_increment;
-
-      try
-        {
-          m_base = base.matrix_value (true);
-        }
-      catch (octave::execution_exception& e)
-        {
-          error (e, "invalid base value in colon expression");
-        }
-
-      try
-        {
-          m_limit = limit.matrix_value (true);
-        }
-      catch (octave::execution_exception& e)
-        {
-          error (e, "invalid limit value in colon expression");
-        }
-
-      try
-        {
-          m_increment = (increment.is_defined ()
-                         ? increment.matrix_value (true)
-                         : Matrix (1, 1, 1.0));
-        }
-      catch (octave::execution_exception& e)
-        {
-          error (e, "invalid increment value in colon expression");
-        }
-
-      bool base_empty = m_base.isempty ();
-      bool limit_empty = m_limit.isempty ();
-      bool increment_empty = m_increment.isempty ();
-
-      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 ? '"' : '\''));
-        }
+      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;