changeset 27519:804e5d42b728

move reader and parser from evaluator repl to interpreter main_loop * interpreter.h, interpreter.cc (interpreter::m_in_top_level_repl, interpreter::in_top_level_repl): Move data member and function here from tree_evaluator. (interpreter::main_loop): Move reader, parser, and most exception handling here from tree_evaluator::repl function. Eliminate non-working code for debugging nan or inf exceptions. * pt-eval.h, pt-eval.cc (tree_evaluator::eval): Rename from repl. Perform statement list evaluation here.
author John W. Eaton <jwe@octave.org>
date Wed, 16 Oct 2019 23:26:33 -0400
parents 25479159213b
children 7a871724d4b0
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, 163 insertions(+), 171 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/interpreter.cc	Wed Oct 16 14:35:03 2019 -0700
+++ b/libinterp/corefcn/interpreter.cc	Wed Oct 16 23:26:33 2019 -0400
@@ -390,6 +390,7 @@
       m_inhibit_startup_message (false),
       m_load_path_initialized (false),
       m_history_initialized (false),
+      m_in_top_level_repl (false),
       m_initialized (false)
   {
     // FIXME: When thread_local storage is used by default, this message
@@ -972,8 +973,10 @@
 
   int interpreter::main_loop (void)
   {
+    int retval = 0;
+
     if (! m_app_context)
-      return 0;
+      return retval;
 
     octave_save_signal_mask ();
 
@@ -988,7 +991,128 @@
 
     // The big loop.
 
-    return m_evaluator.repl (m_interactive);
+#if defined (OCTAVE_ENABLE_COMMAND_LINE_PUSH_PARSER)
+
+    input_reader reader (*this);
+
+    // Attach input_reader object to parser so that the promptflag can
+    // be adjusted automatically when we are parsing multi-line
+    // commands.
+
+    push_parser repl_parser (*this, &reader);
+
+#else
+
+    // The pull parser takes ownership of the lexer and will delete it
+    // when the parser goes out of scope.
+
+    parser repl_parser (m_interactive
+                        ? new lexer (*this) : new lexer (stdin, *this));
+
+#endif
+
+    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 ();
+              }
+
+#if defined (OCTAVE_ENABLE_COMMAND_LINE_PUSH_PARSER)
+
+            do
+              {
+                bool eof;
+
+                std::string input_line = reader.get_input (eof);
+
+                if (eof)
+                  {
+                    retval = EOF;
+                    break;
+                  }
+
+                retval = repl_parser.run (input_line, false);
+              }
+            while (retval < 0);
+
+#else
+
+            retval = repl_parser.run ();
+
+#endif
+            if (retval == 0)
+              {
+                std::shared_ptr<tree_statement_list>
+                  stmt_list = repl_parser.statement_list ();
+
+                if (stmt_list)
+                  {
+                    m_evaluator.eval (stmt_list, m_interactive);
+                  }
+                else if (repl_parser.at_end_of_input ())
+                  {
+                    retval = 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.
+                retval = 1;
+                break;
+              }
+          }
+        catch (const std::bad_alloc&)
+          {
+            recover_from_exception ();
+
+            std::cerr << "error: out of memory -- trying to return to prompt"
+                      << std::endl;
+          }
+      }
+    while (retval == 0);
+
+    if (retval == EOF)
+      {
+        if (m_interactive)
+          octave_stdout << "\n";
+
+        return 0;
+      }
+
+    return retval;
   }
 
   // Call a function with exceptions handled to avoid problems with
--- a/libinterp/corefcn/interpreter.h	Wed Oct 16 14:35:03 2019 -0700
+++ b/libinterp/corefcn/interpreter.h	Wed Oct 16 23:26:33 2019 -0400
@@ -154,6 +154,11 @@
       m_inhibit_startup_message = flag;
     }
 
+    bool in_top_level_repl (void) const
+    {
+      return m_in_top_level_repl;
+    }
+
     bool initialized (void) const
     {
       return m_initialized;
@@ -493,6 +498,9 @@
 
     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_initialized;
 
     void maximum_braindamage (void);
--- a/libinterp/parse-tree/pt-eval.cc	Wed Oct 16 14:35:03 2019 -0700
+++ b/libinterp/parse-tree/pt-eval.cc	Wed Oct 16 23:26:33 2019 -0400
@@ -330,9 +330,7 @@
         // If there is no enclosing debug level or the top-level
         // repl is not active, handle dbquit the same as dbcont.
 
-        tree_evaluator& tw = m_interpreter.get_evaluator ();
-
-        if (m_level > 0 || tw.in_top_level_repl ())
+        if (m_level > 0 || m_interpreter.in_top_level_repl ())
           throw quit_debug_exception ();
         else
           return true;
@@ -343,9 +341,7 @@
         // If the top-level repl is not active, handle "dbquit all"
         // the same as dbcont.
 
-        tree_evaluator& tw = m_interpreter.get_evaluator ();
-
-        if (tw.in_top_level_repl ())
+        if (m_interpreter.in_top_level_repl ())
           throw quit_debug_exception (true);
         else
           return true;
@@ -359,169 +355,36 @@
     return m_call_stack.at_top_level ();
   }
 
-  int tree_evaluator::repl (bool interactive)
+  void tree_evaluator::eval (std::shared_ptr<tree_statement_list>& stmt_list,
+                             bool interactive)
   {
-    int retval = 0;
-
-#if defined (OCTAVE_ENABLE_COMMAND_LINE_PUSH_PARSER)
-
-    input_reader reader (m_interpreter);
-
-    // Attach input_reader object to parser so that the promptflag can
-    // be adjusted automatically when we are parsing multi-line
-    // commands.
-
-    push_parser repl_parser (m_interpreter, &reader);
-
-#else
-
-    // The pull parser takes ownership of the lexer and will delete it
-    // when the parser goes out of scope.
-
-    parser repl_parser (interactive
-                        ? new lexer (m_interpreter)
-                        : new lexer (stdin, m_interpreter));
-
-#endif
-
-    error_system& es = m_interpreter.get_error_system ();
-
-    do
+    try
       {
-        try
+        stmt_list->accept (*this);
+
+        octave_quit ();
+
+        if (! interactive)
           {
-            unwind_protect_var<bool> upv (m_in_top_level_repl, true);
-
-            repl_parser.reset ();
-
-            if (at_top_level ())
-              {
-                m_dbstep_flag = 0;
-                reset_debug_state ();
-              }
-
-#if defined (OCTAVE_ENABLE_COMMAND_LINE_PUSH_PARSER)
-
-            do
-              {
-                bool eof;
-
-                std::string input_line = reader.get_input (eof);
-
-                if (eof)
-                  {
-                    retval = EOF;
-                    break;
-                  }
-
-                retval = repl_parser.run (input_line, false);
-              }
-            while (retval < 0);
-
-#else
-
-            retval = repl_parser.run ();
-
-#endif
-
-            if (retval == 0)
-              {
-                std::shared_ptr<tree_statement_list> stmt_list
-                  = repl_parser.statement_list ();
-
-                if (stmt_list)
-                  {
-                    stmt_list->accept (*this);
-
-                    octave_quit ();
-
-                    if (! interactive)
-                      {
-                        bool quit = (m_returning || m_breaking);
-
-                        if (m_returning)
-                          m_returning = 0;
-
-                        if (m_breaking)
-                          m_breaking--;
-
-                        if (quit)
-                          break;
-                      }
-
-                    if (octave_completion_matches_called)
-                      octave_completion_matches_called = false;
-                  }
-                else if (repl_parser.at_end_of_input ())
-                  {
-                    retval = EOF;
-                    break;
-                  }
-              }
+            bool quit = (m_returning || m_breaking);
+
+            if (m_returning)
+              m_returning = 0;
+
+            if (m_breaking)
+              m_breaking--;
+
+            if (quit)
+              return;
           }
-        catch (const interrupt_exception&)
-          {
-            m_interpreter.recover_from_exception ();
-
-            // Required newline when the user does Ctrl+C at the prompt.
-            if (interactive)
-              octave_stdout << "\n";
-          }
-        catch (const quit_debug_exception&)
-          {
-            m_interpreter.recover_from_exception ();
-          }
-        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)
-          {
-            es.save_exception (ee);
-            es.display_exception (ee, std::cerr);
-
-            if (interactive)
-              m_interpreter.recover_from_exception ();
-            else
-              {
-                // We should exit with a nonzero status.
-                retval = 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;
-          }
-
-#if defined (DBSTOP_NANINF)
-        error_system& es = m_interpreter.get_error_system ();
-
-        if (es.debug_on_naninf ())
-          {
-            if (setjump (naninf_jump) != 0)
-              debug_or_throw_exception (true);  // true = stack trace
-          }
-#endif
+
+        if (octave_completion_matches_called)
+          octave_completion_matches_called = false;
       }
-    while (retval == 0);
-
-    if (retval == EOF)
+    catch (const quit_debug_exception&)
       {
-        if (interactive)
-          octave_stdout << "\n";
-
-        retval = 0;
+        m_interpreter.recover_from_exception ();
       }
-
-    return retval;
   }
 
   std::string
--- a/libinterp/parse-tree/pt-eval.h	Wed Oct 16 14:35:03 2019 -0700
+++ b/libinterp/parse-tree/pt-eval.h	Wed Oct 16 23:26:33 2019 -0400
@@ -27,6 +27,7 @@
 
 #include <iosfwd>
 #include <list>
+#include <memory>
 #include <set>
 #include <stack>
 #include <string>
@@ -134,7 +135,7 @@
         m_echo_files (), m_in_loop_command (false),
         m_breaking (0), m_continuing (0), m_returning (0),
         m_indexed_object (nullptr), m_index_position (0),
-        m_num_indices (0), m_in_top_level_repl (false)
+        m_num_indices (0)
       { }
 
     // No copying!
@@ -147,7 +148,8 @@
 
     bool at_top_level (void) const;
 
-    int repl (bool interactive);
+    void eval (std::shared_ptr<tree_statement_list>& stmt_list,
+               bool interactive);
 
     std::string mfilename (const std::string& opt = "") const;
 
@@ -630,8 +632,6 @@
 
     int num_indices (void) const { return m_num_indices; }
 
-    bool in_top_level_repl (void) const { return m_in_top_level_repl; }
-
     const std::list<octave_lvalue> * lvalue_list (void) const
     {
       return m_lvalue_list;
@@ -832,9 +832,6 @@
     const octave_value *m_indexed_object;
     int m_index_position;
     int m_num_indices;
-
-    // TRUE if we are in the top level interactive read eval print loop.
-    bool m_in_top_level_repl;
   };
 }