changeset 29846:78cb255c78a4 stable

move top-level REPL from interpreter to evaluator * pt-eval.h, pt-eval.cc (tree_evaluator::m_in_top_level_repl): New member variable. (tree_evaluator::in_top_level_repl): New function. (tree_evaluator::repl): New function, adapted from interepreter::main_loop. * interpreter.h interpreter.cc (interpreter::m_in_top_level_repl): Delete. (interpreter::in_top_level_repl): Forward to tree_evaluator::in_top_level_repl. (interpreter::main_loop): Forward to tree_evaluator::repl.
author John W. Eaton <jwe@octave.org>
date Fri, 02 Jul 2021 09:38:48 -0400
parents c4f9513b09f1
children c517a55a14ad
files libinterp/corefcn/interpreter.cc libinterp/corefcn/interpreter.h libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-eval.h
diffstat 4 files changed, 146 insertions(+), 135 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/interpreter.cc	Thu Jul 01 13:24:03 2021 +0200
+++ b/libinterp/corefcn/interpreter.cc	Fri Jul 02 09:38:48 2021 -0400
@@ -466,7 +466,6 @@
       m_inhibit_startup_message (false),
       m_load_path_initialized (false),
       m_history_initialized (false),
-      m_in_top_level_repl (false),
       m_cancel_quit (false),
       m_executing_finish_script (false),
       m_executing_atexit (false),
@@ -1207,132 +1206,7 @@
 
   int interpreter::main_loop (void)
   {
-    // The big loop.  Read, Eval, Print, Loop.  Normally user
-    // interaction at the command line in a terminal session, but we may
-    // also end up here when reading from a pipe or when stdin is
-    // connected to a file by the magic of input redirection.
-
-    int exit_status = 0;
-
-    // FIXME: should this choice be a command-line option?  Note that we
-    // intend that the push parser interface only be used for
-    // interactive sessions.
-
-#if defined (OCTAVE_ENABLE_COMMAND_LINE_PUSH_PARSER)
-    static bool use_command_line_push_parser = true;
-#else
-    static bool use_command_line_push_parser = false;
-#endif
-
-    // The following logic is written as it is to allow easy transition
-    // to setting USE_COMMAND_LINE_PUSH_PARSER at run time and to
-    // simplify the logic of the main loop below by using the same
-    // base_parser::run interface for both push and pull parsers.
-
-    std::shared_ptr<base_parser> repl_parser;
-
-    if (m_interactive)
-      {
-        if (use_command_line_push_parser)
-          {
-            push_parser *pp = new push_parser (*this, new input_reader (*this));
-            repl_parser = std::shared_ptr<base_parser> (pp);
-          }
-        else
-          {
-            parser *pp = new parser (new lexer (*this));
-            repl_parser = std::shared_ptr<base_parser> (pp);
-          }
-      }
-    else
-      {
-        parser *pp = new parser (new lexer (stdin, *this));
-        repl_parser = std::shared_ptr<base_parser> (pp);
-      }
-
-    do
-      {
-        try
-          {
-            unwind_protect_var<bool> upv (m_in_top_level_repl, true);
-
-            repl_parser->reset ();
-
-            if (m_evaluator.at_top_level ())
-              {
-                m_evaluator.dbstep_flag (0);
-                m_evaluator.reset_debug_state ();
-              }
-
-            exit_status = repl_parser->run ();
-
-            if (exit_status == 0)
-              {
-                std::shared_ptr<tree_statement_list>
-                  stmt_list = repl_parser->statement_list ();
-
-                if (stmt_list)
-                  {
-                    command_editor::increment_current_command_number ();
-
-                    m_evaluator.eval (stmt_list, m_interactive);
-                  }
-                else if (repl_parser->at_end_of_input ())
-                  {
-                    exit_status = EOF;
-                    break;
-                  }
-              }
-          }
-        catch (const interrupt_exception&)
-          {
-            recover_from_exception ();
-
-            // Required newline when the user does Ctrl+C at the prompt.
-            if (m_interactive)
-              octave_stdout << "\n";
-          }
-        catch (const index_exception& e)
-          {
-            recover_from_exception ();
-
-            std::cerr << "error: unhandled index exception: "
-                      << e.message () << " -- trying to return to prompt"
-                      << std::endl;
-          }
-        catch (const execution_exception& ee)
-          {
-            m_error_system.save_exception (ee);
-            m_error_system.display_exception (ee, std::cerr);
-
-            if (m_interactive)
-              recover_from_exception ();
-            else
-              {
-                // We should exit with a nonzero status.
-                exit_status = 1;
-                break;
-              }
-          }
-        catch (const std::bad_alloc&)
-          {
-            recover_from_exception ();
-
-            std::cerr << "error: out of memory -- trying to return to prompt"
-                      << std::endl;
-          }
-      }
-    while (exit_status == 0);
-
-    if (exit_status == EOF)
-      {
-        if (m_interactive)
-          octave_stdout << "\n";
-
-        exit_status = 0;
-      }
-
-    return exit_status;
+    return m_evaluator.repl ();
   }
 
   tree_evaluator& interpreter::get_evaluator (void)
--- a/libinterp/corefcn/interpreter.h	Thu Jul 01 13:24:03 2021 +0200
+++ b/libinterp/corefcn/interpreter.h	Fri Jul 02 09:38:48 2021 -0400
@@ -187,7 +187,7 @@
 
     bool in_top_level_repl (void) const
     {
-      return m_in_top_level_repl;
+      return m_evaluator.in_top_level_repl ();
     }
 
     bool initialized (void) const
@@ -560,9 +560,6 @@
 
     bool m_history_initialized;
 
-    // TRUE if we are in the top level interactive read eval print loop.
-    bool m_in_top_level_repl;
-
     bool m_cancel_quit;
 
     bool m_executing_finish_script;
--- a/libinterp/parse-tree/pt-eval.cc	Thu Jul 01 13:24:03 2021 +0200
+++ b/libinterp/parse-tree/pt-eval.cc	Fri Jul 02 09:38:48 2021 -0400
@@ -464,6 +464,139 @@
     return fname;
   }
 
+  int tree_evaluator::repl (void)
+  {
+    // The big loop.  Read, Eval, Print, Loop.  Normally user
+    // interaction at the command line in a terminal session, but we may
+    // also end up here when reading from a pipe or when stdin is
+    // connected to a file by the magic of input redirection.
+
+    int exit_status = 0;
+
+    // FIXME: should this choice be a command-line option?  Note that we
+    // intend that the push parser interface only be used for
+    // interactive sessions.
+
+#if defined (OCTAVE_ENABLE_COMMAND_LINE_PUSH_PARSER)
+    static bool use_command_line_push_parser = true;
+#else
+    static bool use_command_line_push_parser = false;
+#endif
+
+    // The following logic is written as it is to allow easy transition
+    // to setting USE_COMMAND_LINE_PUSH_PARSER at run time and to
+    // simplify the logic of the main loop below by using the same
+    // base_parser::run interface for both push and pull parsers.
+
+    std::shared_ptr<base_parser> repl_parser;
+
+    if (m_interpreter.interactive ())
+      {
+        if (use_command_line_push_parser)
+          {
+            push_parser *pp = new push_parser (m_interpreter,
+                                               new input_reader (m_interpreter));
+            repl_parser = std::shared_ptr<base_parser> (pp);
+          }
+        else
+          {
+            parser *pp = new parser (new lexer (m_interpreter));
+            repl_parser = std::shared_ptr<base_parser> (pp);
+          }
+      }
+    else
+      {
+        parser *pp = new parser (new lexer (stdin, m_interpreter));
+        repl_parser = std::shared_ptr<base_parser> (pp);
+      }
+
+    do
+      {
+        try
+          {
+            unwind_protect_var<bool> upv (m_in_top_level_repl, true);
+
+            repl_parser->reset ();
+
+            if (at_top_level ())
+              {
+                dbstep_flag (0);
+                reset_debug_state ();
+              }
+
+            exit_status = repl_parser->run ();
+
+            if (exit_status == 0)
+              {
+                std::shared_ptr<tree_statement_list>
+                  stmt_list = repl_parser->statement_list ();
+
+                if (stmt_list)
+                  {
+                    command_editor::increment_current_command_number ();
+
+                    eval (stmt_list, m_interpreter.interactive ());
+                  }
+                else if (repl_parser->at_end_of_input ())
+                  {
+                    exit_status = EOF;
+                    break;
+                  }
+              }
+          }
+        catch (const interrupt_exception&)
+          {
+            m_interpreter.recover_from_exception ();
+
+            // Required newline when the user does Ctrl+C at the prompt.
+            if (m_interpreter.interactive ())
+              octave_stdout << "\n";
+          }
+        catch (const index_exception& e)
+          {
+            m_interpreter.recover_from_exception ();
+
+            std::cerr << "error: unhandled index exception: "
+                      << e.message () << " -- trying to return to prompt"
+                      << std::endl;
+          }
+        catch (const execution_exception& ee)
+          {
+            error_system& es = m_interpreter.get_error_system ();
+
+            es.save_exception (ee);
+            es.display_exception (ee, std::cerr);
+
+            if (m_interpreter.interactive ())
+              m_interpreter.recover_from_exception ();
+            else
+              {
+                // We should exit with a nonzero status.
+                exit_status = 1;
+                break;
+              }
+          }
+        catch (const std::bad_alloc&)
+          {
+            m_interpreter.recover_from_exception ();
+
+            std::cerr << "error: out of memory -- trying to return to prompt"
+                      << std::endl;
+          }
+      }
+    while (exit_status == 0);
+
+    if (exit_status == EOF)
+      {
+        if (m_interpreter.interactive ())
+          octave_stdout << "\n";
+
+        exit_status = 0;
+      }
+
+    return exit_status;
+  }
+
   octave_value_list
   tree_evaluator::eval_string (const std::string& eval_str, bool silent,
                                int& parse_status, int nargout)
--- a/libinterp/parse-tree/pt-eval.h	Thu Jul 01 13:24:03 2021 +0200
+++ b/libinterp/parse-tree/pt-eval.h	Fri Jul 02 09:38:48 2021 -0400
@@ -136,10 +136,10 @@
         m_silent_functions (false), m_string_fill_char (' '),
         m_PS4 ("+ "), m_dbstep_flag (0), m_echo (ECHO_OFF),
         m_echo_state (false), m_echo_file_name (), m_echo_file_pos (1),
-        m_echo_files (), m_in_loop_command (false),
-        m_breaking (0), m_continuing (0), m_returning (0),
-        m_indexed_object (), m_index_list (), m_index_type (),
-        m_index_position (0), m_num_indices (0)
+        m_echo_files (), m_in_top_level_repl (false),
+        m_in_loop_command (false), m_breaking (0), m_continuing (0),
+        m_returning (0), m_indexed_object (), m_index_list (),
+        m_index_type (), m_index_position (0), m_num_indices (0)
     { }
 
     // No copying!
@@ -152,6 +152,10 @@
 
     bool at_top_level (void) const;
 
+    int repl (void);
+
+    bool in_top_level_repl (void) const { return m_in_top_level_repl; }
+
     void eval (std::shared_ptr<tree_statement_list>& stmt_list,
                bool interactive);
 
@@ -852,6 +856,9 @@
 
     std::map<std::string, bool> m_echo_files;
 
+    // TRUE if we are in the top level interactive read eval print loop.
+    bool m_in_top_level_repl;
+
     // TRUE means we are evaluating some kind of looping construct.
     bool m_in_loop_command;