changeset 27020:30e9204de313

move feval functions to interpreter class * interpreter.h, interpreter.cc (interpreter::feval): New functions created from global feval functions in oct-parse.yy. Change all uses. * oct-parse.yy (feval): Forward to interpreter::feval functions.
author John W. Eaton <jwe@octave.org>
date Mon, 01 Apr 2019 13:57:10 +0000
parents 6cb675912f2b
children 2e4e42ba7016
files libgui/graphics/Canvas.cc libinterp/corefcn/interpreter.cc libinterp/corefcn/interpreter.h libinterp/parse-tree/oct-parse.yy
diffstat 4 files changed, 155 insertions(+), 102 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/graphics/Canvas.cc	Mon Apr 01 13:11:14 2019 +0000
+++ b/libgui/graphics/Canvas.cc	Mon Apr 01 13:57:10 2019 +0000
@@ -41,6 +41,8 @@
 
 #include "annotation-dialog.h"
 
+#include "interpreter-private.h"
+#include "interpreter.h"
 #include "oct-opengl.h"
 #include "octave-qt-link.h"
 #include "resource-manager.h"
@@ -202,7 +204,10 @@
   void
   Canvas::annotation_callback (const octave_value_list& args)
   {
-    Ffeval (ovl ("annotation").append (args));
+    octave::interpreter& interp
+      = octave::__get_interpreter__ ("Canvas::annotation_callback");
+
+    interp.feval ("annotation", args);
 
     redraw ();
   }
--- a/libinterp/corefcn/interpreter.cc	Mon Apr 01 13:11:14 2019 +0000
+++ b/libinterp/corefcn/interpreter.cc	Mon Apr 01 13:57:10 2019 +0000
@@ -1219,6 +1219,114 @@
     return m_evaluator.evalin (context, try_code, catch_code, nargout);
   }
 
+  //! Evaluate an Octave function (built-in or interpreted) and return
+  //! the list of result values.
+  //!
+  //! @param name The name of the function to call.
+  //! @param args The arguments to the function.
+  //! @param nargout The number of output arguments expected.
+  //! @return A list of output values.  The length of the list is not
+  //!         necessarily the same as @c nargout.
+
+  octave_value_list interpreter::feval (const char *name,
+                                        const octave_value_list& args,
+                                        int nargout)
+  {
+    return feval (std::string (name), args, nargout);
+  }
+
+  octave_value_list interpreter::feval (const std::string& name,
+                                        const octave_value_list& args,
+                                        int nargout)
+  {
+    octave_value fcn = m_symbol_table.find_function (name, args);
+
+    if (fcn.is_undefined ())
+      error ("feval: function '%s' not found", name.c_str ());
+
+    octave_function *of = fcn.function_value ();
+
+    return of->call (m_evaluator, nargout, args);
+  }
+
+  octave_value_list interpreter::feval (octave_function *fcn,
+                                        const octave_value_list& args,
+                                        int nargout)
+  {
+    if (fcn)
+      return fcn->call (m_evaluator, nargout, args);
+
+    return octave_value_list ();
+  }
+
+  octave_value_list interpreter::feval (const octave_value& val,
+                                        const octave_value_list& args,
+                                        int nargout)
+  {
+    // FIXME: do we really want to silently return an empty ovl if
+    // the function object is undefined?  It's essentially what the
+    // version above that accepts a pointer to an octave_function
+    // object does and some code was apparently written to rely on it
+    // (for example, __ode15__).
+
+    if (val.is_undefined ())
+      return ovl ();
+
+    if (val.is_function ())
+      {
+        return feval (val.function_value (), args, nargout);
+      }
+    else if (val.is_function_handle ())
+      {
+        // This covers function handles, inline functions, and anonymous
+        //  functions.
+
+        std::list<octave_value_list> arg_list;
+        arg_list.push_back (args);
+
+        // FIXME: could we make octave_value::subsref a const method?
+        // It would be difficult because there are instances of
+        // incrementing the reference count inside subsref methods,
+        // which means they can't be const with the current way of
+        // handling reference counting.
+
+        octave_value xval = val;
+        return xval.subsref ("(", arg_list, nargout);
+      }
+    else if (val.is_string ())
+      {
+        return feval (val.string_value (), args, nargout);
+      }
+    else
+      error ("feval: first argument must be a string, inline function, or a function handle");
+
+    return ovl ();
+  }
+
+  //! Evaluate an Octave function (built-in or interpreted) and return
+  //! the list of result values.
+  //!
+  //! @param args The first element of @c args is the function to call.
+  //!             It may be the name of the function as a string, a function
+  //!             handle, or an inline function.  The remaining arguments are
+  //!             passed to the function.
+  //! @param nargout The number of output arguments expected.
+  //! @return A list of output values.  The length of the list is not
+  //!         necessarily the same as @c nargout.
+
+  octave_value_list interpreter::feval (const octave_value_list& args,
+                                        int nargout)
+  {
+    if (args.length () == 0)
+      error ("feval: first argument must be a string, inline function, or a function handle");
+
+    octave_value f_arg = args(0);
+
+    octave_value_list tmp_args = args.slice (1, args.length () - 1, true);
+
+    return feval (f_arg, tmp_args, nargout);
+  }
+
   void interpreter::install_variable (const std::string& name,
                                       const octave_value& value, bool global)
   {
--- a/libinterp/corefcn/interpreter.h	Mon Apr 01 13:11:14 2019 +0000
+++ b/libinterp/corefcn/interpreter.h	Mon Apr 01 13:57:10 2019 +0000
@@ -263,6 +263,28 @@
                               const std::string& try_code,
                               const std::string& catch_code, int nargout);
 
+    octave_value_list
+    feval (const char *name,
+           const octave_value_list& args = octave_value_list (),
+           int nargout = 0);
+
+    octave_value_list
+    feval (const std::string& name,
+           const octave_value_list& args = octave_value_list (),
+           int nargout = 0);
+
+    octave_value_list
+    feval (octave_function *fcn,
+           const octave_value_list& args = octave_value_list (),
+           int nargout = 0);
+
+    octave_value_list
+    feval (const octave_value& f_arg,
+           const octave_value_list& args = octave_value_list (),
+           int nargout = 0);
+
+    octave_value_list feval (const octave_value_list& args, int nargout = 0);
+
     void install_variable (const std::string& name, const octave_value& value,
                            bool global);
 
--- a/libinterp/parse-tree/oct-parse.yy	Mon Apr 01 13:11:14 2019 +0000
+++ b/libinterp/parse-tree/oct-parse.yy	Mon Apr 01 13:57:10 2019 +0000
@@ -54,7 +54,6 @@
 
 #include "Cell.h"
 #include "builtin-defun-decls.h"
-#include "call-stack.h"
 #include "defun.h"
 #include "dirfns.h"
 #include "dynamic-ld.h"
@@ -4781,127 +4780,46 @@
   octave_value_list
   feval (const char *name, const octave_value_list& args, int nargout)
   {
-    return feval (std::string (name), args, nargout);
+    interpreter& interp = __get_interpreter__ ("feval");
+
+    return interp.feval (name, args, nargout);
   }
 
   octave_value_list
   feval (const std::string& name, const octave_value_list& args, int nargout)
   {
-    octave_value_list retval;
-
-    symbol_table& symtab = __get_symbol_table__ ("feval");
-
-    octave_value fcn = symtab.find_function (name, args);
-
-    if (fcn.is_defined ())
-      {
-        tree_evaluator& tw = __get_evaluator__ ("feval");
-
-        octave_function *of = fcn.function_value ();
-
-        retval = of->call (tw, nargout, args);
-      }
-    else
-      error ("feval: function '%s' not found", name.c_str ());
-
-    return retval;
+    interpreter& interp = __get_interpreter__ ("feval");
+
+    return interp.feval (name, args, nargout);
   }
 
   octave_value_list
   feval (octave_function *fcn, const octave_value_list& args, int nargout)
   {
-    octave_value_list retval;
-
-    if (fcn)
-      {
-        tree_evaluator& tw = __get_evaluator__ ("feval");
-
-        retval = fcn->call (tw, nargout, args);
-      }
-
-    return retval;
+    interpreter& interp = __get_interpreter__ ("feval");
+
+    return interp.feval (fcn, args, nargout);
   }
 
   octave_value_list
   feval (const octave_value& val, const octave_value_list& args, int nargout)
   {
-    // FIXME: do we really want to silently return an empty ovl if
-    // the function object is undefined?  It's essentially what the
-    // version above that accepts a pointer to an octave_function
-    // object does and some code was apparently written to rely on it
-    // (for example, __ode15__).
-
-    if (val.is_undefined ())
-      return ovl ();
-
-    if (val.is_function ())
-      {
-        return feval (val.function_value (), args, nargout);
-      }
-    else if (val.is_function_handle ())
-      {
-        // This covers function handles, inline functions, and anonymous
-        //  functions.
-
-        std::list<octave_value_list> arg_list;
-        arg_list.push_back (args);
-
-        // FIXME: could we make octave_value::subsref a const method?
-        // It would be difficult because there are instances of
-        // incrementing the reference count inside subsref methods,
-        // which means they can't be const with the current way of
-        // handling reference counting.
-
-        octave_value xval = val;
-        return xval.subsref ("(", arg_list, nargout);
-      }
-    else if (val.is_string ())
-      {
-        return feval (val.string_value (), args, nargout);
-      }
-    else
-      error ("feval: first argument must be a string, inline function, or a function handle");
-
-    return ovl ();
+    interpreter& interp = __get_interpreter__ ("feval");
+
+    return interp.feval (val, args, nargout);
   }
 
-  static octave_value_list
-  get_feval_args (const octave_value_list& args)
-  {
-    return args.slice (1, args.length () - 1, true);
-  }
-
-  //! Evaluate an Octave function (built-in or interpreted) and return
-  //! the list of result values.
-  //!
-  //! @param args The first element of @c args is the function to call.
-  //!             It may be the name of the function as a string, a function
-  //!             handle, or an inline function.  The remaining arguments are
-  //!             passed to the function.
-  //! @param nargout The number of output arguments expected.
-  //! @return A list of output values.  The length of the list is not
-  //!         necessarily the same as @c nargout.
-
   octave_value_list
   feval (const octave_value_list& args, int nargout)
   {
-    if (args.length () > 0)
-      {
-        octave_value f_arg = args(0);
-
-        octave_value_list tmp_args = get_feval_args (args);
-
-        return feval (f_arg, tmp_args, nargout);
-      }
-    else
-      error ("feval: first argument must be a string, inline function, or a function handle");
-
-    return ovl ();
+    interpreter& interp = __get_interpreter__ ("feval");
+
+    return interp.feval (args, nargout);
   }
 }
 
-DEFUN (feval, args, nargout,
-       doc: /* -*- texinfo -*-
+DEFMETHOD (feval, interp, args, nargout,
+           doc: /* -*- texinfo -*-
 @deftypefn {} {} feval (@var{name}, @dots{})
 Evaluate the function named @var{name}.
 
@@ -4943,7 +4861,7 @@
   if (args.length () == 0)
     print_usage ();
 
-  return octave::feval (args, nargout);
+  return interp.feval (args, nargout);
 }
 
 DEFMETHOD (builtin, interp, args, nargout,
@@ -4984,7 +4902,7 @@
   octave_value fcn = symtab.builtin_find (name);
 
   if (fcn.is_defined ())
-    retval = octave::feval (fcn.function_value (), args.splice (0, 1), nargout);
+    retval = interp.feval (fcn.function_value (), args.splice (0, 1), nargout);
   else
     error ("builtin: lookup for symbol '%s' failed", name.c_str ());