changeset 23532:084245f9bd03

pass reference to evaluator to octave_function call methods * interpreter-private.h, interpreter-private.cc: (__get_evaluator__): New function. * interpreter.h, interpreter.cc (interpreter::m_evaluator): Now a reference instead of a pointer. Change all uses. (interpreter::get_evaluator): New function. (intrepreter::current_evaluator): Delete. Replace all uses with __get_evaluator__. * ov-fcn.h, ov-fcn.cc (octave_function::call): Pass reference to tree_evaluator. Change all functions in derived classes and all uses. (octave_function::subsref): Delete. * ov-usr-fcn.h, ov-usr-fcn.cc (octave_user_script::subsref): Delete. * pt-eval.h, pt-eval.cc (tree_evaluator::m_interpreter): Now a reference instead of a pointer. Change all uses. * ov-classdef.h, ov-classdef.cc (execute_ov): Delete. Replaces uses with calls to feval. (octave_classdef_superclass_ref::subsref): Delete.
author John W. Eaton <jwe@octave.org>
date Thu, 25 May 2017 13:13:17 -0400
parents 60695e6ef416
children 8edbc923a7dc
files libinterp/corefcn/defun.cc libinterp/corefcn/input.cc libinterp/corefcn/interpreter-private.cc libinterp/corefcn/interpreter-private.h libinterp/corefcn/interpreter.cc libinterp/corefcn/interpreter.h libinterp/octave-value/ov-builtin.cc libinterp/octave-value/ov-builtin.h libinterp/octave-value/ov-classdef.cc libinterp/octave-value/ov-fcn.cc libinterp/octave-value/ov-fcn.h libinterp/octave-value/ov-mex-fcn.cc libinterp/octave-value/ov-mex-fcn.h libinterp/octave-value/ov-usr-fcn.cc libinterp/octave-value/ov-usr-fcn.h libinterp/parse-tree/lex.h libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-eval.h
diffstat 19 files changed, 136 insertions(+), 213 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/defun.cc	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/corefcn/defun.cc	Thu May 25 13:13:17 2017 -0400
@@ -182,10 +182,12 @@
   return retval;
 }
 
-bool defun_isargout (int nargout, int iout)
+bool
+defun_isargout (int nargout, int iout)
 {
-  const std::list<octave_lvalue> *lvalue_list
-    = octave::current_evaluator->lvalue_list ();
+  octave::tree_evaluator& tw = octave::__get_evaluator__ ("defun_isargout");
+
+  const std::list<octave_lvalue> *lvalue_list = tw.lvalue_list ();
 
   if (iout >= std::max (nargout, 1))
     return false;
@@ -207,10 +209,12 @@
     return true;
 }
 
-void defun_isargout (int nargout, int nout, bool *isargout)
+void
+defun_isargout (int nargout, int nout, bool *isargout)
 {
-  const std::list<octave_lvalue> *lvalue_list
-    = octave::current_evaluator->lvalue_list ();
+  octave::tree_evaluator& tw = octave::__get_evaluator__ ("defun_isargout");
+
+  const std::list<octave_lvalue> *lvalue_list = tw.lvalue_list ();
 
   if (lvalue_list)
     {
--- a/libinterp/corefcn/input.cc	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/corefcn/input.cc	Thu May 25 13:13:17 2017 -0400
@@ -694,6 +694,8 @@
 
   octave::parser curr_parser;
 
+  octave::tree_evaluator& tw = octave::__get_evaluator__ ("get_debug_input");
+
   while (Vdebugging)
     {
       try
@@ -712,7 +714,7 @@
             {
               if (retval == 0 && curr_parser.stmt_list)
                 {
-                  curr_parser.stmt_list->accept (*octave::current_evaluator);
+                  curr_parser.stmt_list->accept (tw);
 
                   if (octave_completion_matches_called)
                     octave_completion_matches_called = false;
--- a/libinterp/corefcn/interpreter-private.cc	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/corefcn/interpreter-private.cc	Thu May 25 13:13:17 2017 -0400
@@ -49,4 +49,11 @@
 
     return interp.get_load_path ();
   }
+
+  tree_evaluator& __get_evaluator__ (const std::string& who)
+  {
+    interpreter& interp = __get_interpreter__ (who);
+
+    return interp.get_evaluator ();
+  }
 }
--- a/libinterp/corefcn/interpreter-private.h	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/corefcn/interpreter-private.h	Thu May 25 13:13:17 2017 -0400
@@ -31,10 +31,13 @@
 {
   class interpreter;
   class load_path;
+  class tree_evaluator;
 
   extern interpreter& __get_interpreter__ (const std::string& who);
 
   extern load_path& __get_load_path__ (const std::string& who);
+
+  extern tree_evaluator& __get_evaluator__ (const std::string& who);
 }
 
 #endif
--- a/libinterp/corefcn/interpreter.cc	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/corefcn/interpreter.cc	Thu May 25 13:13:17 2017 -0400
@@ -361,14 +361,12 @@
 
 namespace octave
 {
-  tree_evaluator *current_evaluator = nullptr;
-
   // Create an interpreter object and perform initialization up to the
   // point of setting reading command history and setting the load
   // path.
 
   interpreter::interpreter (application *app_context)
-    : m_app_context (app_context), m_evaluator (new tree_evaluator (this)),
+    : m_app_context (app_context), m_evaluator (new tree_evaluator (*this)),
       m_load_path (), m_interactive (false), m_read_site_files (true),
       m_read_init_files (m_app_context != 0), m_verbose (false),
       m_inhibit_startup_message (false), m_load_path_initialized (false),
@@ -380,8 +378,6 @@
 
     instance = this;
 
-    current_evaluator = m_evaluator;
-
     // Matlab uses "C" locale for LC_NUMERIC class regardless of local setting
     setlocale (LC_NUMERIC, "C");
     setlocale (LC_TIME, "C");
@@ -511,9 +507,6 @@
     cleanup ();
 
     instance = 0;
-    current_evaluator = 0;
-
-    delete m_evaluator;
   }
 
   // Read the history file unless a command-line option inhibits that.
@@ -1135,6 +1128,11 @@
     OCTAVE_SAFE_CALL (octave::chunk_buffer::clear, ());
   }
 
+  tree_evaluator& interpreter::get_evaluator (void)
+  {
+    return *m_evaluator;
+  }
+
   void interpreter::recover_from_exception (void)
   {
     octave::can_interrupt = true;
--- a/libinterp/corefcn/interpreter.h	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/corefcn/interpreter.h	Thu May 25 13:13:17 2017 -0400
@@ -45,8 +45,6 @@
 {
   class tree_evaluator;
 
-  extern tree_evaluator *current_evaluator;
-
   // The application object contains a pointer to the current
   // interpreter and the interpreter contains a pointer back to the
   // application context so we need a forward declaration for one (or
@@ -137,6 +135,8 @@
       return m_load_path;
     }
 
+    tree_evaluator& get_evaluator (void);
+
     static void recover_from_exception (void);
 
     static void add_atexit_function (const std::string& fname);
--- a/libinterp/octave-value/ov-builtin.cc	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/octave-value/ov-builtin.cc	Thu May 25 13:13:17 2017 -0400
@@ -41,7 +41,8 @@
                                      "built-in function");
 
 octave_value_list
-octave_builtin::call (int nargout, const octave_value_list& args)
+octave_builtin::call (octave::tree_evaluator&, int nargout,
+                      const octave_value_list& args)
 {
   octave_value_list retval;
 
--- a/libinterp/octave-value/ov-builtin.h	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/octave-value/ov-builtin.h	Thu May 25 13:13:17 2017 -0400
@@ -38,6 +38,7 @@
 
 namespace octave
 {
+  class tree_evaluator;
   class interpreter;
 }
 
@@ -86,7 +87,8 @@
 
   bool is_builtin_function (void) const { return true; }
 
-  octave_value_list call (int nargout, const octave_value_list& args);
+  octave_value_list call (octave::tree_evaluator& tw, int nargout,
+                          const octave_value_list& args);
 
   jit_type * to_jit (void) const;
 
--- a/libinterp/octave-value/ov-classdef.cc	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/octave-value/ov-classdef.cc	Thu May 25 13:13:17 2017 -0400
@@ -147,16 +147,6 @@
   return retval;
 }
 
-inline octave_value_list
-execute_ov (octave_value val, const octave_value_list& args, int nargout)
-{
-  std::list<octave_value_list> idx (1, args);
-
-  std::string type ("(");
-
-  return val.subsref (type, idx, nargout);
-}
-
 static cdef_class
 lookup_class (const std::string& name, bool error_if_not_found = true,
               bool load_if_not_found = true)
@@ -425,7 +415,8 @@
 static bool
 is_method_executing (const octave_value& ov, const cdef_object& obj)
 {
-  octave::tree_evaluator *tw = octave::current_evaluator;
+  octave::tree_evaluator& tw
+    = octave::__get_evaluator__ ("is_method_executing");
 
   octave_function *stack_fcn = octave::call_stack::current ();
 
@@ -456,7 +447,7 @@
             {
               octave::tree_decl_elt *elt = pl->front ();
 
-              octave_value arg0 = tw->evaluate (elt);
+              octave_value arg0 = tw.evaluate (elt);
 
               if (arg0.is_defined () && arg0.type_name () == "object")
                 {
@@ -1008,27 +999,19 @@
   subsref (const std::string& type,
            const std::list<octave_value_list>& idx,
            int nargout)
-  { return object.meta_subsref (type, idx, nargout); }
-
-  octave_value
-  subsref (const std::string& type,
-           const std::list<octave_value_list>& idx)
   {
-    octave_value_list retval;
-
-    retval = subsref (type, idx, 1);
-
-    return (retval.length () > 0 ? retval(0) : octave_value ());
+    return object.meta_subsref (type, idx, nargout);
   }
 
-  octave_value_list call (int nargout, const octave_value_list& idx)
+  octave_value_list call (octave::tree_evaluator&, int nargout,
+                          const octave_value_list& args)
   {
     // Emulate ()-type meta subsref
 
-    std::list<octave_value_list> l (1, idx);
+    std::list<octave_value_list> idx (1, args);
     std::string type ("(");
 
-    return subsref (type, l, nargout);
+    return subsref (type, idx, nargout);
   }
 
   bool accepts_postfix_index (char type) const
@@ -1072,44 +1055,7 @@
   octave_function * function_value (bool = false) { return this; }
 
   octave_value_list
-  subsref (const std::string& type,
-           const std::list<octave_value_list>& idx,
-           int nargout)
-  {
-    size_t skip = 0;
-    octave_value_list retval;
-
-    switch (type[0])
-      {
-      case '(':
-        skip = 1;
-        retval = call (type.length () > 1 ? 1 : nargout, idx.front ());
-        break;
-      default:
-        retval = call (1, octave_value_list ());
-        break;
-      }
-
-    if (type.length () > skip && idx.size () > skip
-        && retval.length () > 0)
-      retval = retval(0).next_subsref (nargout, type, idx, skip);
-
-    return retval;
-  }
-
-  octave_value
-  subsref (const std::string& type,
-           const std::list<octave_value_list>& idx)
-  {
-    octave_value_list retval;
-
-    retval = subsref (type, idx, 1);
-
-    return (retval.length () > 0 ? retval(0) : octave_value ());
-  }
-
-  octave_value_list
-  call (int nargout, const octave_value_list& idx)
+  call (octave::tree_evaluator&, int nargout, const octave_value_list& idx)
   {
     octave_value_list retval;
 
@@ -2878,7 +2824,7 @@
 
       args(0) = to_ov (obj);
 
-      args = execute_ov (get_fcn, args, 1);
+      args = octave::feval (get_fcn, args, 1);
 
       retval = args(0);
     }
@@ -2932,7 +2878,7 @@
       args(0) = to_ov (obj);
       args(1) = val;
 
-      args = execute_ov (set_fcn, args, 1);
+      args = octave::feval (set_fcn, args, 1);
 
       if (args.length () > 0 && args(0).is_defined ())
         {
@@ -3039,7 +2985,7 @@
   check_method ();
 
   if (function.is_defined ())
-    retval = execute_ov (function, args, nargout);
+    retval = octave::feval (function, args, nargout);
 
   return retval;
 }
@@ -3071,7 +3017,7 @@
       for (int i = 0; i < args.length (); i++)
         new_args(i+1) = args(i);
 
-      retval = execute_ov (function, new_args, nargout);
+      retval = octave::feval (function, new_args, nargout);
     }
 
   return retval;
--- a/libinterp/octave-value/ov-fcn.cc	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/octave-value/ov-fcn.cc	Thu May 25 13:13:17 2017 -0400
@@ -42,48 +42,3 @@
   panic_impossible ();
   return 0;
 }
-
-octave_value_list
-octave_function::subsref (const std::string& type,
-                          const std::list<octave_value_list>& idx,
-                          int nargout)
-{
-  octave_value_list retval;
-
-  switch (type[0])
-    {
-    case '(':
-      {
-        int tmp_nargout = (type.length () > 1 && nargout == 0) ? 1 : nargout;
-
-        retval = call (tmp_nargout, idx.front ());
-      }
-      break;
-
-    case '{':
-    case '.':
-      {
-        std::string nm = type_name ();
-        error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
-      }
-      break;
-
-    default:
-      panic_impossible ();
-    }
-
-  // FIXME: perhaps there should be an
-  // octave_value_list::next_subsref member function?  See also
-  // octave_user_function::subsref.
-  //
-  // FIXME: Note that if a function call returns multiple
-  // values, and there is further indexing to perform, then we are
-  // ignoring all but the first value.  Is this really what we want to
-  // do?  If it is not, then what should happen for stat("file").size,
-  // for exmaple?
-
-  if (idx.size () > 1)
-    retval = retval(0).next_subsref (nargout, type, idx);
-
-  return retval;
-}
--- a/libinterp/octave-value/ov-fcn.h	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/octave-value/ov-fcn.h	Thu May 25 13:13:17 2017 -0400
@@ -37,6 +37,7 @@
 
 namespace octave
 {
+  class tree_evaluator;
   class tree_walker;
 }
 
@@ -199,21 +200,9 @@
   { return (type == '('); }
 
   virtual octave_value_list
-  call (int nargout = 0,
+  call (octave::tree_evaluator& tw, int nargout = 0,
         const octave_value_list& args = octave_value_list ()) = 0;
 
-  octave_value subsref (const std::string& type,
-                        const std::list<octave_value_list>& idx)
-  {
-    octave_value_list tmp = subsref (type, idx, 1);
-    return tmp.length () > 0 ? tmp(0) : octave_value ();
-  }
-
-  octave_value_list
-  subsref (const std::string& type,
-           const std::list<octave_value_list>& idx,
-           int nargout);
-
 protected:
 
   octave_function (const std::string& nm,
--- a/libinterp/octave-value/ov-mex-fcn.cc	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/octave-value/ov-mex-fcn.cc	Thu May 25 13:13:17 2017 -0400
@@ -83,7 +83,8 @@
           int nargout);
 
 octave_value_list
-octave_mex_function::call (int nargout, const octave_value_list& args)
+octave_mex_function::call (octave::tree_evaluator&, int nargout,
+                           const octave_value_list& args)
 {
   octave_value_list retval;
 
--- a/libinterp/octave-value/ov-mex-fcn.h	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/octave-value/ov-mex-fcn.h	Thu May 25 13:13:17 2017 -0400
@@ -36,6 +36,11 @@
 class octave_value;
 class octave_value_list;
 
+namespace octave
+{
+  class tree_evaluator;
+}
+
 // Dynamically-linked functions.
 
 class
@@ -80,7 +85,8 @@
 
   bool is_mex_function (void) const { return true; }
 
-  octave_value_list call (int nargout, const octave_value_list& args);
+  octave_value_list call (octave::tree_evaluator& tw, int nargout,
+                          const octave_value_list& args);
 
   void atexit (void (*fcn) (void)) { m_exit_fcn_ptr = fcn; }
 
--- a/libinterp/octave-value/ov-usr-fcn.cc	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/octave-value/ov-usr-fcn.cc	Thu May 25 13:13:17 2017 -0400
@@ -112,14 +112,8 @@
 }
 
 octave_value_list
-octave_user_script::subsref (const std::string&,
-                             const std::list<octave_value_list>&, int)
-{
-  error ("invalid use of script %s in index expression", file_name.c_str ());
-}
-
-octave_value_list
-octave_user_script::call (int nargout, const octave_value_list& args)
+octave_user_script::call (octave::tree_evaluator& tw, int nargout,
+                          const octave_value_list& args)
 {
   octave_value_list retval;
 
@@ -150,9 +144,7 @@
       profile_data_accumulator::enter<octave_user_script>
         block (profiler, *this);
 
-      octave::tree_evaluator *tw = octave::current_evaluator;
-
-      cmd_list->accept (*tw);
+      cmd_list->accept (tw);
 
       if (octave::tree_return_command::returning)
         octave::tree_return_command::returning = 0;
@@ -405,7 +397,8 @@
 }
 
 octave_value_list
-octave_user_function::call (int nargout, const octave_value_list& _args)
+octave_user_function::call (octave::tree_evaluator& tw, int nargout,
+                            const octave_value_list& _args)
 {
   octave_value_list retval;
 
@@ -463,10 +456,8 @@
 
   string_vector arg_names = args.name_tags ();
 
-  octave::tree_evaluator *tw = octave::current_evaluator;
-
   if (param_list && ! param_list->varargs_only ())
-    tw->define_parameter_list_from_arg_vector (param_list, args);
+    tw.define_parameter_list_from_arg_vector (param_list, args);
 
   // For classdef constructor, pre-populate the output arguments
   // with the pre-initialized object instance, extracted above.
@@ -477,7 +468,7 @@
         error ("%s: invalid classdef constructor, no output argument defined",
                dispatch_class ().c_str ());
 
-      tw->define_parameter_list_from_arg_vector (ret_list, ret_args);
+      tw.define_parameter_list_from_arg_vector (ret_list, ret_args);
     }
 
   // Force parameter list to be undefined when this function exits.
@@ -485,7 +476,7 @@
   // variables that are also named function parameters.
 
   if (param_list)
-    frame.add_method (tw, &octave::tree_evaluator::undefine_parameter_list,
+    frame.add_method (&tw, &octave::tree_evaluator::undefine_parameter_list,
                       param_list);
 
   // Force return list to be undefined when this function exits.
@@ -493,7 +484,7 @@
   // variables that are also named values returned by this function.
 
   if (ret_list)
-    frame.add_method (tw, &octave::tree_evaluator::undefine_parameter_list,
+    frame.add_method (&tw, &octave::tree_evaluator::undefine_parameter_list,
                       ret_list);
 
   if (call_depth == 0)
@@ -548,11 +539,11 @@
           {
             octave::call_stack::set_location (stmt->line (), stmt->column ());
 
-            retval = tw->evaluate_n (expr, nargout);
+            retval = tw.evaluate_n (expr, nargout);
           }
       }
     else
-      cmd_list->accept (*tw);
+      cmd_list->accept (tw);
   }
 
   if (echo_commands)
@@ -568,8 +559,8 @@
 
   if (ret_list && ! is_special_expr ())
     {
-      tw->initialize_undefined_parameter_list_elements (ret_list, my_name,
-                                                        nargout, Matrix ());
+      tw.initialize_undefined_parameter_list_elements (ret_list, my_name,
+                                                       nargout, Matrix ());
 
       Cell varargout;
 
@@ -581,7 +572,7 @@
             varargout = varargout_varval.xcell_value ("varargout must be a cell array object");
         }
 
-      retval = tw->convert_parameter_list_to_const_vector (ret_list, nargout, varargout);
+      retval = tw.convert_parameter_list_to_const_vector (ret_list, nargout, varargout);
     }
 
   return retval;
@@ -646,7 +637,7 @@
 
 void
 octave_user_function::bind_automatic_vars
-  (octave::tree_evaluator *tw, const string_vector& arg_names,
+  (octave::tree_evaluator& tw, const string_vector& arg_names,
    int nargin, int nargout, const octave_value_list& va_args)
 {
   if (! arg_names.empty ())
@@ -683,7 +674,7 @@
   if (takes_varargs ())
     symbol_table::assign ("varargin", va_args.cell_value ());
 
-  Matrix ignored_fcn_outputs = tw ? tw->ignored_fcn_outputs () : Matrix ();
+  Matrix ignored_fcn_outputs = tw.ignored_fcn_outputs ();
 
   symbol_table::assign (".ignored.", ignored_fcn_outputs);
 
--- a/libinterp/octave-value/ov-usr-fcn.h	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/octave-value/ov-usr-fcn.h	Thu May 25 13:13:17 2017 -0400
@@ -134,11 +134,8 @@
 
   octave::sys::time time_checked (void) const { return t_checked; }
 
-  octave_value_list subsref (const std::string& type,
-                             const std::list<octave_value_list>& idx,
-                             int nargout);
-
-  octave_value_list call (int nargout, const octave_value_list& args);
+  octave_value_list call (octave::tree_evaluator& tw, int nargout,
+                          const octave_value_list& args);
 
   octave::tree_statement_list * body (void) { return cmd_list; }
 
@@ -352,7 +349,8 @@
            ? (cname.empty () ? true : cname == dispatch_class ()) : false;
   }
 
-  octave_value_list call (int nargout, const octave_value_list& args);
+  octave_value_list call (octave::tree_evaluator& tw, int nargout,
+                          const octave_value_list& args);
 
   octave::tree_parameter_list * parameter_list (void) { return param_list; }
 
@@ -489,7 +487,7 @@
 
   void print_code_function_trailer (void);
 
-  void bind_automatic_vars (octave::tree_evaluator *tw,
+  void bind_automatic_vars (octave::tree_evaluator& tw,
                             const string_vector& arg_names,
                             int nargin, int nargout,
                             const octave_value_list& va_args);
--- a/libinterp/parse-tree/lex.h	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/parse-tree/lex.h	Thu May 25 13:13:17 2017 -0400
@@ -546,9 +546,9 @@
       octave_comment_list *comment_list;
     };
 
-    base_lexer (interpreter *interp_context = nullptr)
+    base_lexer (interpreter *interp = nullptr)
       : lexical_feedback (), scanner (0), input_buf (), comment_buf (),
-        m_interp_context (interp_context)
+        m_interpreter (interp)
     {
       init ();
     }
@@ -653,7 +653,7 @@
     comment_buffer comment_buf;
 
     // Interpreter that contains us, if any.
-    interpreter *m_interp_context;
+    interpreter *m_interpreter;
 
     virtual void increment_promptflag (void) = 0;
 
@@ -720,17 +720,16 @@
   {
   public:
 
-    lexer (interpreter *interp_context = nullptr)
-      : base_lexer (interp_context), reader (this)
+    lexer (interpreter *interp = nullptr)
+      : base_lexer (interp), reader (this)
     { }
 
-    lexer (FILE *file, interpreter *interp_context = nullptr)
-      : base_lexer (interp_context), reader (file, this)
+    lexer (FILE *file, interpreter *interp = nullptr)
+      : base_lexer (interp), reader (file, this)
     { }
 
-    lexer (const std::string& eval_string,
-           interpreter *interp_context = nullptr)
-      : base_lexer (interp_context), reader (eval_string, this)
+    lexer (const std::string& eval_string, interpreter *interp = nullptr)
+      : base_lexer (interp), reader (eval_string, this)
     { }
 
     // No copying!
@@ -784,28 +783,27 @@
   {
   public:
 
-    push_lexer (interpreter *interp_context = nullptr)
-      : base_lexer (interp_context), pflag (1)
+    push_lexer (interpreter *interp = nullptr)
+      : base_lexer (interp), pflag (1)
     {
       append_input ("", false);
     }
 
-    push_lexer (const std::string& input,
-                interpreter *interp_context = nullptr)
-      : base_lexer (interp_context), pflag (1)
+    push_lexer (const std::string& input, interpreter *interp = nullptr)
+      : base_lexer (interp), pflag (1)
     {
       append_input (input, false);
     }
 
-    push_lexer (bool eof, interpreter *interp_context = nullptr)
-      : base_lexer (interp_context), pflag (1)
+    push_lexer (bool eof, interpreter *interp = nullptr)
+      : base_lexer (interp), pflag (1)
     {
       append_input ("", eof);
     }
 
     push_lexer (const std::string& input, bool eof,
-                interpreter *interp_context = nullptr)
-      : base_lexer (interp_context), pflag (1)
+                interpreter *interp = nullptr)
+      : base_lexer (interp), pflag (1)
     {
       append_input (input, eof);
     }
--- a/libinterp/parse-tree/oct-parse.in.yy	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/parse-tree/oct-parse.in.yy	Thu May 25 13:13:17 2017 -0400
@@ -2358,7 +2358,10 @@
               {
                 try
                   {
-                    octave_value tmp = octave::current_evaluator->evaluate (e);
+                    octave::tree_evaluator& tw
+                      = __get_evaluator__ ("finish_colon_expression");
+
+                    octave_value tmp = tw.evaluate (e);
 
                     tree_constant *tc_retval
                       = new tree_constant (tmp, base->line (), base->column ());
@@ -3921,7 +3924,10 @@
 
     if (e->is_constant ())
       {
-        octave_value ov = octave::current_evaluator->evaluate (e);
+        octave::tree_evaluator& tw
+          = __get_evaluator__ ("validate_matrix_for_assignment");
+
+        octave_value ov = tw.evaluate (e);
 
         delete e;
 
@@ -3989,7 +3995,10 @@
       {
         try
           {
-            octave_value tmp = octave::current_evaluator->evaluate (array_list);
+            octave::tree_evaluator& tw
+              = __get_evaluator__ ("finish_array_list");
+
+            octave_value tmp = tw.evaluate (array_list);
 
             tree_constant *tc_retval
               = new tree_constant (tmp, array_list->line (),
@@ -4344,8 +4353,11 @@
 
               bool is_at_folder = ! dispatch_type.empty ();
 
-              fcn_ptr =
-                parser.classdef_object->make_meta_class (octave::current_evaluator, is_at_folder);
+              octave::tree_evaluator& tw
+                = octave::__get_evaluator__ ("parse_fcn_file");
+
+              fcn_ptr
+                = parser.classdef_object->make_meta_class (&tw, is_at_folder);
 
               delete (parser.classdef_object);
 
@@ -4808,7 +4820,9 @@
         std::cout.flush ();
       }
 
-    fcn->call ();
+    tree_evaluator& tw = __get_evaluator__ ("source");
+
+    fcn->call (tw, 0);
 
     if (verbose)
       std::cout << "done." << std::endl;
@@ -4937,9 +4951,11 @@
 
     if (fcn.is_defined ())
       {
+        tree_evaluator& tw = __get_evaluator__ ("feval");
+
         octave_function *of = fcn.function_value ();
 
-        retval = of->call (nargout, args);
+        retval = of->call (tw, nargout, args);
       }
     else
       error ("feval: function '%s' not found", name.c_str ());
@@ -4953,7 +4969,11 @@
     octave_value_list retval;
 
     if (fcn)
-      retval = fcn->call (nargout, args);
+      {
+        tree_evaluator& tw = __get_evaluator__ ("feval");
+
+        retval = fcn->call (tw, nargout, args);
+      }
 
     return retval;
   }
@@ -5135,6 +5155,8 @@
               {
                 tree_statement *stmt = 0;
 
+                octave::tree_evaluator& tw = __get_evaluator__ ("eval_string");
+
                 if (parser.stmt_list->length () == 1
                     && (stmt = parser.stmt_list->front ())
                     && stmt->is_expression ())
@@ -5156,7 +5178,7 @@
                     else
                       do_bind_ans = (! expr->is_assignment_expression ());
 
-                    retval = octave::current_evaluator->evaluate_n (expr, nargout);
+                    retval = tw.evaluate_n (expr, nargout);
 
                     if (do_bind_ans && ! retval.empty ())
                       bind_ans (retval(0), expr->print_result ());
@@ -5165,7 +5187,7 @@
                       retval = octave_value_list ();
                   }
                 else if (nargout == 0)
-                  parser.stmt_list->accept (*octave::current_evaluator);
+                  parser.stmt_list->accept (tw);
                 else
                   error ("eval: invalid use of statement list");
 
--- a/libinterp/parse-tree/pt-eval.cc	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/parse-tree/pt-eval.cc	Thu May 25 13:13:17 2017 -0400
@@ -985,7 +985,7 @@
         if (fcn && ! (expr.is_postfix_indexed ()
                       && fcn->accepts_postfix_index (expr.postfix_index ())))
           {
-            retval = fcn->call (nargout);
+            retval = fcn->call (*this, nargout);
           }
         else
           {
@@ -1218,7 +1218,7 @@
               {
                 try
                   {
-                    retval = fcn->call (nargout, first_args);
+                    retval = fcn->call (*this, nargout, first_args);
                   }
                 catch (octave::index_exception& e)
                   {
@@ -1820,7 +1820,7 @@
         if (f && ! (expr.is_postfix_indexed ()
                     && f->accepts_postfix_index (expr.postfix_index ())))
           {
-            retval = f->call (nargout);
+            retval = f->call (*this, nargout);
           }
       }
 
--- a/libinterp/parse-tree/pt-eval.h	Thu May 25 08:10:34 2017 -0700
+++ b/libinterp/parse-tree/pt-eval.h	Thu May 25 13:13:17 2017 -0400
@@ -102,9 +102,9 @@
 
     typedef void (*decl_elt_init_fcn) (tree_decl_elt&);
 
-    tree_evaluator (interpreter *interp_context)
+    tree_evaluator (interpreter& interp)
       : m_value_stack (), m_lvalue_list_stack (), m_nargout_stack (),
-        m_interp_context (interp_context)
+        m_interpreter (interp)
     { }
 
     // No copying!
@@ -317,7 +317,7 @@
 
     value_stack<int> m_nargout_stack;
 
-    interpreter *m_interp_context;
+    interpreter& m_interpreter;
   };
 }