GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
interpreter.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2002-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if ! defined (octave_interpreter_h)
27 #define octave_interpreter_h 1
28 
29 #include "octave-config.h"
30 
31 #include <atomic>
32 #include <map>
33 #include <set>
34 #include <stack>
35 #include <string>
36 
37 #include "child-list.h"
38 #include "oct-time.h"
39 #include "quit.h"
40 #include "str-vec.h"
41 
42 #include "cdef-manager.h"
43 #include "display.h"
44 #include "dynamic-ld.h"
45 #include "environment.h"
46 #include "error.h"
47 #include "event-manager.h"
48 #include "gh-manager.h"
49 #include "graphics.h"
50 #include "gtk-manager.h"
51 #include "help.h"
52 #include "input.h"
53 #include "load-path.h"
54 #include "load-save.h"
55 #include "oct-hist.h"
56 #include "oct-stream.h"
57 #include "ov-typeinfo.h"
58 #include "pager.h"
59 #include "pt-eval.h"
60 #include "settings.h"
61 #include "symtab.h"
62 #include "url-handle-manager.h"
63 
64 extern OCTINTERP_API bool quit_allowed;
65 
66 // TRUE means we are ready to interpret commands, but not everything
67 // is ready for interactive use.
68 extern OCTINTERP_API bool octave_interpreter_ready;
69 
70 // TRUE means we've processed all the init code and we are good to go.
71 extern OCTINTERP_API std::atomic<bool> octave_initialized;
72 
73 #include "oct-time.h"
74 
76 
77 class profiler;
78 class child_list;
79 class push_parser;
80 
81 // The time we last time we changed directories.
82 extern sys::time Vlast_chdir_time;
83 
84 // The application object contains a pointer to the current
85 // interpreter and the interpreter contains a pointer back to the
86 // application context so we need a forward declaration for one (or
87 // both) of them...
88 
89 class application;
90 
92 {
93 public:
94 
95  temporary_file_list () : m_files () { }
96 
97  OCTAVE_DISABLE_COPY_MOVE (temporary_file_list)
98 
100 
101  void insert (const std::string& file);
102 
103  void cleanup ();
104 
105 private:
106 
107  // List of temporary files to delete when we exit.
108  std::set<std::string> m_files;
109 
110 };
111 
112 class OCTINTERP_API interpreter
113 {
114 public:
115 
116  // Create an interpreter object and perform basic initialization.
117 
118  interpreter (application *app_context = nullptr);
119 
120  OCTAVE_DISABLE_COPY_MOVE (interpreter)
121 
122  // Clean up the interpreter object.
123 
124  ~interpreter ();
125 
126  void intern_nargin (octave_idx_type nargs);
127 
128  // If creating an embedded interpreter, you may inhibit reading
129  // the command history file by calling initialize_history with
130  // read_history_file = false prior to calling initialize.
131 
132  void initialize_history (bool read_history_file = false);
133 
134  // If creating an embedded interpreter, you may inhibit setting
135  // the default compiled-in path by calling initialize_load_path
136  // with set_initial_path = false prior calling initialize. After
137  // that, you can add directories to the load path to set up a
138  // custom path.
139 
140  void initialize_load_path (bool set_initial_path = true);
141 
142  // Load command line history, set the load path.
143 
144  void initialize ();
145 
146  // Note: GET_LINE_AND_EVAL is only used by new experimental terminal
147  // widget.
148 
149  void get_line_and_eval ();
150 
151  // Parse a line of input. If input ends at a complete statement
152  // boundary, execute the resulting parse tree. Useful to handle
153  // parsing user input when running in server mode.
154 
155  void parse_and_execute (const std::string& input, bool& incomplete_parse);
156 
157  // Initialize the interpreter (if not already done by an explicit
158  // call to initialize), execute startup files, --eval option code,
159  // script files, and/or interactive commands.
160 
161  int execute ();
162 
163  bool server_mode () const { return m_evaluator.server_mode (); }
164 
165  bool interactive () const
166  {
167  return m_interactive;
168  }
169 
170  void interactive (bool arg)
171  {
172  m_interactive = arg;
173  }
174 
175  void read_site_files (bool flag)
176  {
177  m_read_site_files = flag;
178  }
179 
180  void read_init_files (bool flag)
181  {
182  m_read_init_files = flag;
183  }
184 
185  void verbose (bool flag)
186  {
187  m_verbose = flag;
188  }
189 
190  void traditional (bool flag)
191  {
192  m_traditional = flag;
193  }
194 
195  bool traditional () const
196  {
197  return m_traditional;
198  }
199 
200  void inhibit_startup_message (bool flag)
201  {
202  m_inhibit_startup_message = flag;
203  }
204 
205  bool in_top_level_repl () const
206  {
207  return m_evaluator.in_top_level_repl ();
208  }
209 
210  bool is_initialized () const
211  {
212  return m_initialized;
213  }
214 
215  OCTAVE_DEPRECATED (9, "use octave::is_initialized instead")
216  bool initialized () const
217  {
218  return is_initialized ();
219  }
220 
222  {
223  m_interrupt_all_in_process_group = b;
224  }
225 
227  {
228  return m_interrupt_all_in_process_group;
229  }
230 
232  {
233  return m_app_context;
234  }
235 
237  {
238  return m_display_info;
239  }
240 
242  {
243  return m_environment;
244  }
245 
247  {
248  return m_settings;
249  }
250 
252  {
253  return m_error_system;
254  }
255 
256  tree_evaluator& get_evaluator ();
257 
259  {
260  return m_help_system;
261  }
262 
264  {
265  return m_input_system;
266  }
267 
269  {
270  return m_output_system;
271  }
272 
274  {
275  return m_history_system;
276  }
277 
279  {
280  return m_dynamic_loader;
281  }
282 
284  {
285  return m_load_path;
286  }
287 
289  {
290  return m_load_save_system;
291  }
292 
294  {
295  return m_type_info;
296  }
297 
299  {
300  return m_symbol_table;
301  }
302 
303  symbol_scope get_top_scope () const;
304  symbol_scope get_current_scope () const;
305  symbol_scope require_current_scope (const std::string& who) const;
306 
307  profiler& get_profiler ();
308 
309  stream_list& get_stream_list ();
310 
312  {
313  return m_child_list;
314  }
315 
316  url_handle_manager& get_url_handle_manager ();
317 
319  {
320  return m_cdef_manager;
321  }
322 
324  {
325  return m_gtk_manager;
326  }
327 
329  {
330  return m_event_manager;
331  }
332 
334  {
335  return *m_gh_manager;
336  }
337 
338  // Any Octave code that needs to change the current directory should
339  // call this function instead of calling the system chdir function
340  // directly so that the load-path and GUI may be notified of the
341  // change.
342 
343  int chdir (const std::string& dir);
344 
345  void mlock (bool skip_first = false) const;
346  void munlock (bool skip_first = false) const;
347  bool mislocked (bool skip_first = false) const;
348 
349  // NOTE: since we have a version that accepts a bool argument, we
350  // can't rely on automatic conversion from char* to std::string.
351  void munlock (const char *nm);
352  void munlock (const std::string& nm);
353 
354  bool mislocked (const char *nm);
355  bool mislocked (const std::string& nm);
356 
357  std::string mfilename (const std::string& opt = "") const;
358 
359  octave_value_list eval_string (const std::string& eval_str, bool silent,
360  int& parse_status, int nargout);
361 
362  octave_value eval_string (const std::string& eval_str, bool silent,
363  int& parse_status);
364 
365  octave_value_list eval_string (const octave_value& arg, bool silent,
366  int& parse_status, int nargout);
367 
368  octave_value_list eval (const std::string& try_code, int nargout);
369 
370  octave_value_list eval (const std::string& try_code,
371  const std::string& catch_code, int nargout);
372 
373  octave_value_list evalin (const std::string& context,
374  const std::string& try_code, int nargout);
375 
376  octave_value_list evalin (const std::string& context,
377  const std::string& try_code,
378  const std::string& catch_code, int nargout);
379 
381  feval (const char *name,
382  const octave_value_list& args = octave_value_list (),
383  int nargout = 0);
384 
386  feval (const std::string& name,
387  const octave_value_list& args = octave_value_list (),
388  int nargout = 0);
389 
391  feval (octave_function *fcn,
392  const octave_value_list& args = octave_value_list (),
393  int nargout = 0);
394 
396  feval (const octave_value& f_arg,
397  const octave_value_list& args = octave_value_list (),
398  int nargout = 0);
399 
400  octave_value_list feval (const octave_value_list& args, int nargout = 0);
401 
402  octave_value make_function_handle (const std::string& name);
403 
404  void install_variable (const std::string& name, const octave_value& value,
405  bool global);
406 
407  void set_global_value (const std::string& name, const octave_value& value);
408 
409  octave_value global_varval (const std::string& name) const;
410 
411  void global_assign (const std::string& name,
412  const octave_value& val = octave_value ());
413 
414  octave_value top_level_varval (const std::string& name) const;
415 
416  void top_level_assign (const std::string& name,
417  const octave_value& val = octave_value ());
418 
419  bool is_variable (const std::string& name) const;
420 
421  bool is_local_variable (const std::string& name) const;
422 
423  octave_value varval (const std::string& name) const;
424 
425  void assign (const std::string& name,
426  const octave_value& val = octave_value ());
427 
428  void assignin (const std::string& context, const std::string& varname,
429  const octave_value& val = octave_value ());
430 
431  void source_file (const std::string& file_name,
432  const std::string& context = "",
433  bool verbose = false, bool require_file = true);
434 
435  bool at_top_level () const;
436 
437  bool isglobal (const std::string& name) const;
438 
439  octave_value find (const std::string& name);
440 
441  void clear_all (bool force = false);
442 
443  void clear_objects ();
444 
445  void clear_variable (const std::string& name);
446 
447  void clear_variable_pattern (const std::string& pattern);
448 
449  void clear_variable_regexp (const std::string& pattern);
450 
451  void clear_variables ();
452 
453  void clear_global_variable (const std::string& name);
454 
455  void clear_global_variable_pattern (const std::string& pattern);
456 
457  void clear_global_variable_regexp (const std::string& pattern);
458 
459  void clear_global_variables ();
460 
461  void clear_functions (bool force = false);
462 
463  void clear_function (const std::string& name);
464 
465  void clear_symbol (const std::string& name);
466 
467  void clear_function_pattern (const std::string& pat);
468 
469  void clear_function_regexp (const std::string& pat);
470 
471  void clear_symbol_pattern (const std::string& pat);
472 
473  void clear_symbol_regexp (const std::string& pat);
474 
475  std::list<std::string> variable_names ();
476 
477  std::list<std::string> top_level_variable_names ();
478 
479  std::list<std::string> global_variable_names ();
480 
481  std::list<std::string> user_function_names ();
482 
483  std::list<std::string> autoloaded_functions () const;
484 
485  void interrupt ();
486 
487  // Pause interpreter execution at the next available statement and
488  // enter the debugger.
489  void pause ();
490 
491  // Exit debugger or stop execution and return to the top-level REPL
492  // or server loop.
493  void stop ();
494 
495  // Add EXPR to the set of expressions that may be evaluated when the
496  // debugger stops at a breakpoint.
497  void add_debug_watch_expression (const std::string& expr);
498 
499  // Remove EXPR from the set of expressions that may be evaluated
500  // when the debugger stops at a breakpoint.
501  void remove_debug_watch_expression (const std::string& expr);
502 
503  // Clear the set of expressions that may be evaluated when the
504  // debugger stops at a breakpoint.
505  void clear_debug_watch_expressions ();
506 
507  // Return the set of expressions that may be evaluated when the
508  // debugger stops at a breakpoint.
509  std::set<std::string> debug_watch_expressions () const;
510 
511  // Resume interpreter execution if paused.
512  void resume ();
513 
514  octave_value PS1 (const octave_value_list& args, int nargout);
515  std::string PS1 () const;
516  std::string PS1 (const std::string& s);
517  void set_PS1 (const std::string& s);
518 
519  octave_value PS2 (const octave_value_list& args, int nargout);
520  std::string PS2 () const;
521  std::string PS2 (const std::string& s);
522  void set_PS2 (const std::string& s);
523 
524  octave_value PS4 (const octave_value_list& args, int nargout);
525  std::string PS4 () const;
526  std::string PS4 (const std::string& s);
527  void set_PS4 (const std::string& s);
528 
529  // Provided for convenience. Will be removed once we eliminate the
530  // old terminal widget.
531  bool experimental_terminal_widget () const;
532 
533  void handle_exception (const execution_exception& ee);
534 
535  void recover_from_exception ();
536 
537  void mark_for_deletion (const std::string& file);
538 
539  void cleanup_tmp_files ();
540 
541  void quit (int exit_status, bool force = false, bool confirm = true);
542 
543  void cancel_quit (bool flag) { m_cancel_quit = flag; }
544 
546  {
547  return m_executing_finish_script;
548  }
549 
550  void add_atexit_fcn (const std::string& fname);
551 
552  bool remove_atexit_fcn (const std::string& fname);
553 
554  static interpreter * the_interpreter () { return s_instance; }
555 
556 private:
557 
558  void display_startup_message () const;
559 
560  int execute_startup_files ();
561 
562  int execute_eval_option_code ();
563 
564  int execute_command_line_file ();
565 
566  int main_loop ();
567 
568  int server_loop ();
569 
570  void shutdown ();
571 
572  void execute_atexit_fcns ();
573 
574  void maximum_braindamage ();
575 
576  void execute_pkg_add (const std::string& dir);
577 
578  int safe_source_file (const std::string& file_name,
579  const std::string& context = "",
580  bool verbose = false, bool require_file = true);
581 
582  //--------
583 
584  // The interpreter instance; Currently it is only possible to
585  // have one, so OCTAVE_THREAD_LOCAL will normally be defined to be
586  // empty. Eventually we would like to allow multiple interpreters
587  // to be active at once, but they will still be limited to one per
588  // thread. When that is possible, OCTAVE_THREAD_LOCAL can be
589  // replaced by the C++ thread_local keyword. For now, use a macro
590  // to allow experimenting with thread_local storage.
591 
592  OCTAVE_THREAD_LOCAL static interpreter *s_instance;
593 
594  application *m_app_context;
595 
596  temporary_file_list m_tmp_files;
597 
598  std::list<std::string> m_atexit_fcns;
599 
600  display_info m_display_info;
601 
602  environment m_environment;
603 
604  settings m_settings;
605 
606  error_system m_error_system;
607 
608  tree_evaluator m_evaluator;
609 
610  help_system m_help_system;
611 
612  input_system m_input_system;
613 
614  output_system m_output_system;
615 
616  history_system m_history_system;
617 
618  dynamic_loader m_dynamic_loader;
619 
620  load_path m_load_path;
621 
622  load_save_system m_load_save_system;
623 
624  type_info m_type_info;
625 
626  symbol_table m_symbol_table;
627 
628  stream_list m_stream_list;
629 
630  child_list m_child_list;
631 
632  url_handle_manager m_url_handle_manager;
633 
634  cdef_manager m_cdef_manager;
635 
636  gtk_manager m_gtk_manager;
637 
638  event_manager m_event_manager;
639 
640  gh_manager *m_gh_manager;
641 
642  // TRUE means this is an interactive interpreter (forced or not).
643  bool m_interactive;
644 
645  bool m_read_site_files;
646 
647  bool m_read_init_files;
648 
649  bool m_verbose;
650 
651  bool m_traditional;
652 
653  bool m_inhibit_startup_message;
654 
655  bool m_load_path_initialized;
656 
657  bool m_history_initialized;
658 
659  bool m_interrupt_all_in_process_group;
660 
661  bool m_cancel_quit;
662 
663  bool m_executing_finish_script;
664 
665  bool m_executing_atexit;
666 
667  bool m_initialized;
668 };
669 
670 OCTAVE_END_NAMESPACE(octave)
671 
672 #endif
Provides threadsafe access to octave.
void interrupt_all_in_process_group(bool b)
Definition: interpreter.h:221
void verbose(bool flag)
Definition: interpreter.h:185
void read_site_files(bool flag)
Definition: interpreter.h:175
gh_manager & get_gh_manager()
Definition: interpreter.h:333
bool in_top_level_repl() const
Definition: interpreter.h:205
cdef_manager & get_cdef_manager()
Definition: interpreter.h:318
bool traditional() const
Definition: interpreter.h:195
environment & get_environment()
Definition: interpreter.h:241
load_save_system & get_load_save_system()
Definition: interpreter.h:288
dynamic_loader & get_dynamic_loader()
Definition: interpreter.h:278
type_info & get_type_info()
Definition: interpreter.h:293
bool executing_finish_script() const
Definition: interpreter.h:545
event_manager & get_event_manager()
Definition: interpreter.h:328
symbol_table & get_symbol_table()
Definition: interpreter.h:298
input_system & get_input_system()
Definition: interpreter.h:263
void cancel_quit(bool flag)
Definition: interpreter.h:543
application * get_app_context()
Definition: interpreter.h:231
output_system & get_output_system()
Definition: interpreter.h:268
settings & get_settings()
Definition: interpreter.h:246
gtk_manager & get_gtk_manager()
Definition: interpreter.h:323
history_system & get_history_system()
Definition: interpreter.h:273
void traditional(bool flag)
Definition: interpreter.h:190
bool interactive() const
Definition: interpreter.h:165
void interactive(bool arg)
Definition: interpreter.h:170
void inhibit_startup_message(bool flag)
Definition: interpreter.h:200
display_info & get_display_info()
Definition: interpreter.h:236
load_path & get_load_path()
Definition: interpreter.h:283
void read_init_files(bool flag)
Definition: interpreter.h:180
bool is_initialized() const
Definition: interpreter.h:210
error_system & get_error_system()
Definition: interpreter.h:251
void set_global_value(const std::string &name, const octave_value &value)
child_list & get_child_list()
Definition: interpreter.h:311
bool server_mode() const
Definition: interpreter.h:163
help_system & get_help_system()
Definition: interpreter.h:258
bool interrupt_all_in_process_group() const
Definition: interpreter.h:226
static interpreter * the_interpreter()
Definition: interpreter.h:554
void insert(const std::string &file)
Definition: interpreter.cc:326
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
bool octave_interpreter_ready
Definition: interpreter.cc:92
sys::time Vlast_chdir_time
std::atomic< bool > octave_initialized
Definition: interpreter.cc:95
bool quit_allowed
Definition: interpreter.cc:88
int chdir(const std::string &path_arg)
Definition: lo-sysdep.cc:107
octave_value_list feval(const char *name, const octave_value_list &args, int nargout)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
Definition: oct-parse.cc:10413
void source_file(const std::string &file_name, const std::string &context="", bool verbose=false, bool require_file=true)