Mercurial > octave
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;