GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
pt-eval.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2009-2018 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software: you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <https://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if ! defined (octave_pt_eval_h)
24 #define octave_pt_eval_h 1
25 
26 #include "octave-config.h"
27 
28 #include <list>
29 #include <set>
30 #include <stack>
31 #include <string>
32 
33 #include "call-stack.h"
34 #include "ov.h"
35 #include "ovl.h"
36 #include "profiler.h"
37 #include "pt-exp.h"
38 #include "pt-walk.h"
39 
40 namespace octave
41 {
42  class symbol_scope;
43  class tree_decl_elt;
44  class tree_expression;
45 
46  class interpreter;
47  class unwind_protect;
48 
50  {
52  RT_VALUE = 1,
54  };
55 
56  // How to evaluate the code that the parse trees represent.
57 
58  class OCTINTERP_API tree_evaluator : public tree_walker
59  {
60  public:
61 
63  {
64  ECHO_OFF = 0,
65  ECHO_SCRIPTS = 1,
66  ECHO_FUNCTIONS = 2,
67  ECHO_ALL = 4
68  };
69 
70  template <typename T>
72  {
73  public:
74 
75  value_stack (void) = default;
76 
77  value_stack (const value_stack&) = default;
78 
79  value_stack& operator = (const value_stack&) = default;
80 
81  ~value_stack (void) = default;
82 
83  void push (const T& val) { m_stack.push (val); }
84 
85  void pop (void)
86  {
87  m_stack.pop ();
88  }
89 
90  T val_pop (void)
91  {
92  T retval = m_stack.top ();
93  m_stack.pop ();
94  return retval;
95  }
96 
97  T top (void) const
98  {
99  return m_stack.top ();
100  }
101 
102  size_t size (void) const
103  {
104  return m_stack.size ();
105  }
106 
107  bool empty (void) const
108  {
109  return m_stack.empty ();
110  }
111 
112  void clear (void)
113  {
114  while (! m_stack.empty ())
115  m_stack.pop ();
116  }
117 
118  private:
119 
120  std::stack<T> m_stack;
121  };
122 
123  typedef void (*decl_elt_init_fcn) (tree_decl_elt&);
124 
126  : m_interpreter (interp), m_result_type (RT_UNDEFINED),
127  m_expr_result_value (), m_expr_result_value_list (),
128  m_lvalue_list_stack (), m_nargout_stack (),
129  m_call_stack (interp), m_profiler (),
130  m_max_recursion_depth (256), m_silent_functions (false),
131  m_string_fill_char (' '), m_PS4 ("+ "), m_echo (ECHO_OFF),
132  m_echo_state (false), m_echo_file_name (), m_echo_file_pos (1),
133  m_echo_files ()
134  { }
135 
136  // No copying!
137 
138  tree_evaluator (const tree_evaluator&) = delete;
139 
140  tree_evaluator& operator = (const tree_evaluator&) = delete;
141 
142  ~tree_evaluator (void) = default;
143 
144  void reset (void);
145 
146  void visit_anon_fcn_handle (tree_anon_fcn_handle&);
147 
148  void visit_argument_list (tree_argument_list&);
149 
150  void visit_binary_expression (tree_binary_expression&);
151 
152  void visit_boolean_expression (tree_boolean_expression&);
153 
154  void visit_compound_binary_expression (tree_compound_binary_expression&);
155 
156  void visit_break_command (tree_break_command&);
157 
158  void visit_colon_expression (tree_colon_expression&);
159 
160  void visit_continue_command (tree_continue_command&);
161 
162  void visit_decl_command (tree_decl_command&);
163 
164  void visit_decl_init_list (tree_decl_init_list&);
165 
166  void visit_decl_elt (tree_decl_elt&);
167 
168  void visit_simple_for_command (tree_simple_for_command&);
169 
170  void visit_complex_for_command (tree_complex_for_command&);
171 
172  void visit_octave_user_script (octave_user_script&);
173 
174  void visit_octave_user_function (octave_user_function&);
175 
176  void visit_octave_user_function_header (octave_user_function&);
177 
178  void visit_octave_user_function_trailer (octave_user_function&);
179 
180  void visit_function_def (tree_function_def&);
181 
182  void visit_identifier (tree_identifier&);
183 
184  void visit_if_clause (tree_if_clause&);
185 
186  void visit_if_command (tree_if_command&);
187 
188  void visit_if_command_list (tree_if_command_list&);
189 
190  void visit_index_expression (tree_index_expression&);
191 
192  void visit_matrix (tree_matrix&);
193 
194  void visit_cell (tree_cell&);
195 
196  void visit_multi_assignment (tree_multi_assignment&);
197 
198  void visit_no_op_command (tree_no_op_command&);
199 
200  void visit_constant (tree_constant&);
201 
202  void visit_fcn_handle (tree_fcn_handle&);
203 
204  void visit_funcall (tree_funcall&);
205 
206  void visit_parameter_list (tree_parameter_list&);
207 
208  void visit_postfix_expression (tree_postfix_expression&);
209 
210  void visit_prefix_expression (tree_prefix_expression&);
211 
212  void visit_return_command (tree_return_command&);
213 
214  void visit_return_list (tree_return_list&);
215 
216  void visit_simple_assignment (tree_simple_assignment&);
217 
218  void visit_statement (tree_statement&);
219 
220  void visit_statement_list (tree_statement_list&);
221 
222  void visit_switch_case (tree_switch_case&);
223 
224  void visit_switch_case_list (tree_switch_case_list&);
225 
226  void visit_switch_command (tree_switch_command&);
227 
228  void visit_try_catch_command (tree_try_catch_command&);
229 
230  void do_unwind_protect_cleanup_code (tree_statement_list *list);
231 
232  void visit_unwind_protect_command (tree_unwind_protect_command&);
233 
234  void visit_while_command (tree_while_command&);
235  void visit_do_until_command (tree_do_until_command&);
236 
237  void bind_ans (const octave_value& val, bool print);
238 
239  bool statement_printing_enabled (void);
240 
241  static void reset_debug_state (void);
242 
243  // If > 0, stop executing at the (N-1)th stopping point, counting
244  // from the the current execution point in the current frame.
245  //
246  // If < 0, stop executing at the next possible stopping point.
247  static int dbstep_flag;
248 
249  // The number of the stack frame we are currently debugging.
250  static size_t current_frame;
251 
252  static bool debug_mode;
253 
255 
256  // Possible types of evaluation contexts.
258  {
259  function, // function body
260  script, // script file
261  other // command-line input or eval string
262  };
263 
264  // The context for the current evaluation.
266 
267  // TRUE means we are evaluating some kind of looping construct.
268  static bool in_loop_command;
269 
270  Matrix ignored_fcn_outputs (void) const;
271 
272  bool isargout (int nargout, int iout) const;
273 
274  void isargout (int nargout, int nout, bool *isargout) const;
275 
276  const std::list<octave_lvalue> * lvalue_list (void) const
277  {
278  return (m_lvalue_list_stack.empty ()
279  ? nullptr : m_lvalue_list_stack.top ());
280  }
281 
283  {
284  m_result_type = RT_VALUE;
285  m_expr_result_value = val;
286  }
287 
288  void push_result (const octave_value_list& vals)
289  {
290  m_result_type = RT_VALUE_LIST;
291  m_expr_result_value_list = vals;
292  }
293 
295  {
297 
298  m_nargout_stack.push (nargout);
299 
300  expr->accept (*this);
301 
302  m_nargout_stack.pop ();
303 
304  switch (m_result_type)
305  {
306  case RT_UNDEFINED:
307  panic_impossible ();
308  break;
309 
310  case RT_VALUE:
311  retval = m_expr_result_value;
312  m_expr_result_value = octave_value ();
313  break;
314 
315  case RT_VALUE_LIST:
316  retval = (m_expr_result_value_list.empty ()
317  ? octave_value () : m_expr_result_value_list(0));
318  m_expr_result_value_list = octave_value_list ();
319  break;
320  }
321 
322  return retval;
323  }
324 
326  {
328 
329  m_nargout_stack.push (nargout);
330 
331  expr->accept (*this);
332 
333  m_nargout_stack.pop ();
334 
335  switch (m_result_type)
336  {
337  case RT_UNDEFINED:
338  panic_impossible ();
339  break;
340 
341  case RT_VALUE:
342  retval = ovl (m_expr_result_value);
343  m_expr_result_value = octave_value ();
344  break;
345 
346  case RT_VALUE_LIST:
347  retval = m_expr_result_value_list;
348  m_expr_result_value_list = octave_value_list ();
349  break;
350  }
351 
352  return retval;
353  }
354 
355  octave_value evaluate (tree_decl_elt *);
356 
357  void define_parameter_list_from_arg_vector
358  (tree_parameter_list *param_list, const octave_value_list& args);
359 
360  void undefine_parameter_list (tree_parameter_list *param_list);
361 
363  convert_return_list_to_const_vector
364  (tree_parameter_list *ret_list, int nargout, const Cell& varargout);
365 
366  bool eval_decl_elt (tree_decl_elt *elt);
367 
368  bool switch_case_label_matches (tree_switch_case *expr,
369  const octave_value& val);
370 
371  call_stack& get_call_stack (void) { return m_call_stack; }
372 
373  profiler& get_profiler (void) { return m_profiler; }
374 
375  symbol_scope get_current_scope (void);
376 
377  int max_recursion_depth (void) const { return m_max_recursion_depth; }
378 
380  {
381  int val = m_max_recursion_depth;
382  m_max_recursion_depth = n;
383  return val;
384  }
385 
387  max_recursion_depth (const octave_value_list& args, int nargout);
388 
389  bool silent_functions (void) const { return m_silent_functions; }
390 
391  bool silent_functions (bool b)
392  {
393  int val = m_silent_functions;
394  m_silent_functions = b;
395  return val;
396  }
397 
399  silent_functions (const octave_value_list& args, int nargout);
400 
401  char string_fill_char (void) const { return m_string_fill_char; }
402 
403  char string_fill_char (char c)
404  {
405  int val = m_string_fill_char;
406  m_string_fill_char = c;
407  return val;
408  }
409 
410  octave_value PS4 (const octave_value_list& args, int nargout);
411 
412  std::string PS4 (void) const { return m_PS4; }
413 
415  {
416  std::string val = m_PS4;
417  m_PS4 = s;
418  return val;
419  }
420 
421  octave_value echo (const octave_value_list& args, int nargout);
422 
423  int echo (void) const { return m_echo; }
424 
425  int echo (int val)
426  {
427  int old_val = m_echo;
428  m_echo = val;
429  return old_val;
430  }
431 
433  string_fill_char (const octave_value_list& args, int nargout);
434 
435  void push_echo_state (unwind_protect& frame, int type,
436  const std::string& file_name, size_t pos = 1);
437 
438  private:
439 
440  void set_echo_state (int type, const std::string& file_name, size_t pos);
441 
442  void maybe_set_echo_state (void);
443 
444  void push_echo_state_cleanup (unwind_protect& frame);
445 
446  bool maybe_push_echo_state_cleanup (void);
447 
448  void do_breakpoint (tree_statement& stmt) const;
449 
450  void do_breakpoint (bool is_breakpoint,
451  bool is_end_of_fcn_or_script = false) const;
452 
453  virtual octave_value
454  do_keyboard (const octave_value_list& args = octave_value_list ()) const;
455 
456  bool is_logically_true (tree_expression *expr, const char *warn_for);
457 
460  const string_vector& arg_nm,
461  const octave_value *object, bool rvalue = true);
462 
463  std::list<octave_lvalue> make_lvalue_list (tree_argument_list *);
464 
465  // For unwind-protect.
466  void set_echo_state (bool val) { m_echo_state = val; }
467 
468  // For unwind-protect.
469  void set_echo_file_name (const std::string& file_name)
470  {
471  m_echo_file_name = file_name;
472  }
473 
474  // For unwind-protect.
475  void set_echo_file_pos (const size_t& file_pos)
476  {
477  m_echo_file_pos = file_pos;
478  }
479 
480  bool echo_this_file (const std::string& file, int type) const;
481 
482  void echo_code (size_t line);
483 
485 
489 
491 
493 
495 
497 
498  // Maximum nesting level for functions, scripts, or sourced files
499  // called recursively.
501 
502  // If TRUE, turn off printing of results in functions (as if a
503  // semicolon has been appended to each statement).
505 
506  // The character to fill with when creating string arrays.
508 
509  // String printed before echoed commands (enabled by --echo-commands).
511 
512  // Echo commands as they are executed?
513  //
514  // 1 ==> echo commands read from script files
515  // 2 ==> echo commands from functions
516  //
517  // more than one state can be active at once.
518  int m_echo;
519 
520  // Are we currently echoing commands? This state is set by the
521  // functions that execute fucntions and scripts.
523 
525 
526  // Next line to echo, counting from 1.
528 
529  std::map<std::string, bool> m_echo_files;
530  };
531 }
532 
533 #if defined (OCTAVE_USE_DEPRECATED_FUNCTIONS)
534 
535 OCTAVE_DEPRECATED (4.4, "use 'octave::tree_evaluator' instead")
536 typedef octave::tree_evaluator tree_evaluator;
537 
538 #endif
539 
540 #endif
void push_result(const octave_value_list &vals)
Definition: pt-eval.h:288
std::string PS4(void) const
Definition: pt-eval.h:412
Definition: Cell.h:37
For example cd octave end example noindent changes the current working directory to file
Definition: dirfns.cc:124
The value of lines which begin with a space character are not saved in the history list A value of all commands are saved on the history list
Definition: oct-hist.cc:734
tree_evaluator(interpreter &interp)
Definition: pt-eval.h:125
static int dbstep_flag
Definition: pt-eval.h:247
void set_echo_file_pos(const size_t &file_pos)
Definition: pt-eval.h:475
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:4986
static bool in_loop_command
Definition: pt-eval.h:268
interpreter & m_interpreter
Definition: pt-eval.h:484
value_stack< const std::list< octave_lvalue > * > m_lvalue_list_stack
Definition: pt-eval.h:490
void push_result(const octave_value &val)
Definition: pt-eval.h:282
std::string PS4(const std::string &s)
Definition: pt-eval.h:414
virtual void accept(tree_walker &tw)=0
call_stack m_call_stack
Definition: pt-eval.h:494
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit and then converted to the native representation Opening a file that is already open simply opens it again and returns a separate file id It is not an error to open a file several though writing to the same file through several different file ids may produce unexpected results The possible values of text mode reading and writing automatically converts linefeeds to the appropriate line end character for the you may append a you must also open the file in binary mode The parameter conversions are currently only supported for and permissions will be set to and then everything is written in a single operation This is very efficient and improves performance c
Definition: file-io.cc:587
s
Definition: file-io.cc:2729
octave_value_list evaluate_n(tree_expression *expr, int nargout=1)
Definition: pt-eval.h:325
static bool quiet_breakpoint_flag
Definition: pt-eval.h:254
bool silent_functions(bool b)
Definition: pt-eval.h:391
std::string m_echo_file_name
Definition: pt-eval.h:524
int echo(void) const
Definition: pt-eval.h:423
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
Definition: ov-usr-fcn.cc:997
static size_t current_frame
Definition: pt-eval.h:250
call_stack & get_call_stack(void)
Definition: pt-eval.h:371
std::map< std::string, bool > m_echo_files
Definition: pt-eval.h:529
is false
Definition: cellfun.cc:400
octave_value retval
Definition: data.cc:6246
#define panic_impossible()
Definition: error.h:40
void set_echo_file_name(const std::string &file_name)
Definition: pt-eval.h:469
octave_value m_expr_result_value
Definition: pt-eval.h:487
OCTINTERP_API void bind_ans(const octave_value &val, bool print)
idx type
Definition: ov.cc:3114
Definition: dMatrix.h:36
result_type
Definition: pt-eval.h:49
static bool debug_mode
Definition: pt-eval.h:252
const std::list< octave_lvalue > * lvalue_list(void) const
Definition: pt-eval.h:276
int max_recursion_depth(void) const
Definition: pt-eval.h:377
octave::unwind_protect frame
Definition: graphics.cc:12190
std::string m_PS4
Definition: pt-eval.h:510
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
int echo(int val)
Definition: pt-eval.h:425
octave_value do_keyboard(const octave_value_list &args=octave_value_list())
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).isinteger())
result_type m_result_type
Definition: pt-eval.h:486
static octave_value_list make_value_list(octave::tree_evaluator *tw, octave::tree_argument_list *m_args, const string_vector &m_arg_nm, const octave_value *object, bool rvalue=true)
Definition: pt-idx.cc:148
b
Definition: cellfun.cc:400
octave_value_list m_expr_result_value_list
Definition: pt-eval.h:488
char string_fill_char(void) const
Definition: pt-eval.h:401
octave_value evaluate(tree_expression *expr, int nargout=1)
Definition: pt-eval.h:294
value_stack< int > m_nargout_stack
Definition: pt-eval.h:492
static stmt_list_type statement_context
Definition: pt-eval.h:265
int max_recursion_depth(int n)
Definition: pt-eval.h:379
char string_fill_char(char c)
Definition: pt-eval.h:403
bool silent_functions(void) const
Definition: pt-eval.h:389
profiler & get_profiler(void)
Definition: pt-eval.h:373
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:888
void set_echo_state(bool val)
Definition: pt-eval.h:466