GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ov-usr-fcn.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2017 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 the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 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 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if ! defined (octave_ov_usr_fcn_h)
24 #define octave_ov_usr_fcn_h 1
25 
26 #include "octave-config.h"
27 
28 #include <ctime>
29 
30 #include <string>
31 #include <stack>
32 
33 #include "comment-list.h"
34 #include "ovl.h"
35 #include "ov-fcn.h"
36 #include "ov-typeinfo.h"
37 #include "symtab.h"
38 #include "unwind-prot.h"
39 
40 class string_vector;
41 
42 class octave_value;
46 class tree_expression;
47 class tree_walker;
48 
49 #if defined (HAVE_LLVM)
50 class jit_function_info;
51 #endif
52 
53 class
55 {
56 public:
58  : octave_function () { }
59 
60  ~octave_user_code (void) { }
61 
62  bool is_user_code (void) const { return true; }
63 
64  virtual std::map<std::string, octave_value> subfunctions (void) const;
65 
66  virtual tree_statement_list *body (void) = 0;
67 
68 protected:
69 
71  const std::string& ds = "")
72  : octave_function (nm, ds) { }
73 
74 private:
75 
76  // No copying!
77 
79 
80  octave_user_code& operator = (const octave_user_code& f);
81 };
82 
83 // Scripts.
84 
85 class
87 {
88 public:
89 
90  octave_user_script (void);
91 
92  octave_user_script (const std::string& fnm, const std::string& nm,
93  tree_statement_list *cmds,
94  const std::string& ds = "");
95 
96  octave_user_script (const std::string& fnm, const std::string& nm,
97  const std::string& ds = "");
98 
99  ~octave_user_script (void);
100 
101  octave_function *function_value (bool = false) { return this; }
102 
103  octave_user_script *user_script_value (bool = false) { return this; }
104 
105  octave_user_code *user_code_value (bool = false) { return this; }
106 
107  // Scripts and user functions are both considered "scripts" because
108  // they are written in Octave's scripting language.
109 
110  bool is_user_script (void) const { return true; }
111 
112  void stash_fcn_file_name (const std::string& nm) { file_name = nm; }
113 
114  void mark_fcn_file_up_to_date (const octave::sys::time& t) { t_checked = t; }
115 
117  {
118  t_parsed = t;
119  mark_fcn_file_up_to_date (t);
120  }
121 
122  std::string fcn_file_name (void) const { return file_name; }
123 
124  octave::sys::time time_parsed (void) const { return t_parsed; }
125 
126  octave::sys::time time_checked (void) const { return t_checked; }
127 
129  const std::list<octave_value_list>& idx)
130  {
131  octave_value_list tmp = subsref (type, idx, 1);
132  return tmp.length () > 0 ? tmp(0) : octave_value ();
133  }
134 
136  const std::list<octave_value_list>& idx,
137  int nargout);
138 
140  do_multi_index_op (int nargout, const octave_value_list& args);
141 
142  tree_statement_list *body (void) { return cmd_list; }
143 
144  void accept (tree_walker& tw);
145 
146 private:
147 
148  // The list of commands that make up the body of this function.
150 
151  // The name of the file we parsed.
153 
154  // The time the file was parsed.
156 
157  // The time the file was last checked to see if it needs to be
158  // parsed again.
160 
161  // Used to keep track of recursion depth.
163 
164  // No copying!
165 
167 
168  octave_user_script& operator = (const octave_user_script& f);
169 
171 };
172 
173 // User-defined functions.
174 
175 class
177 {
178 public:
179 
181  tree_parameter_list *pl = 0,
182  tree_parameter_list *rl = 0,
183  tree_statement_list *cl = 0);
184 
185  ~octave_user_function (void);
186 
188  {
189  return is_anonymous_function ()
190  ? 0 : static_cast<symbol_table::context_id>(call_depth);
191  }
192 
193  octave_function *function_value (bool = false) { return this; }
194 
195  octave_user_function *user_function_value (bool = false) { return this; }
196 
197  octave_user_code *user_code_value (bool = false) { return this; }
198 
199  octave_user_function *define_param_list (tree_parameter_list *t);
200 
201  octave_user_function *define_ret_list (tree_parameter_list *t);
202 
203  void stash_fcn_file_name (const std::string& nm);
204 
205  void stash_fcn_location (int line, int col)
206  {
207  location_line = line;
208  location_column = col;
209  }
210 
211  int beginning_line (void) const { return location_line; }
212  int beginning_column (void) const { return location_column; }
213 
214  void stash_fcn_end_location (int line, int col)
215  {
216  end_location_line = line;
217  end_location_column = col;
218  }
219 
220  int ending_line (void) const { return end_location_line; }
221  int ending_column (void) const { return end_location_column; }
222 
223  void maybe_relocate_end (void);
224 
225  void stash_parent_fcn_name (const std::string& p) { parent_name = p; }
226 
227  void stash_parent_fcn_scope (symbol_table::scope_id ps) { parent_scope = ps; }
228 
229  void stash_leading_comment (octave_comment_list *lc) { lead_comm = lc; }
230 
231  void stash_trailing_comment (octave_comment_list *tc) { trail_comm = tc; }
232 
233  void mark_fcn_file_up_to_date (const octave::sys::time& t) { t_checked = t; }
234 
236  {
237  t_parsed = t;
238  mark_fcn_file_up_to_date (t);
239  }
240 
241  std::string fcn_file_name (void) const { return file_name; }
242 
243  std::string profiler_name (void) const;
244 
245  std::string parent_fcn_name (void) const { return parent_name; }
246 
247  symbol_table::scope_id parent_fcn_scope (void) const { return parent_scope; }
248 
249  symbol_table::scope_id scope (void) { return local_scope; }
250 
251  octave::sys::time time_parsed (void) const { return t_parsed; }
252 
253  octave::sys::time time_checked (void) const { return t_checked; }
254 
255  void mark_as_system_fcn_file (void);
256 
257  bool is_system_fcn_file (void) const { return system_fcn_file; }
258 
259  bool is_user_function (void) const { return true; }
260 
261  void erase_subfunctions (void)
262  {
264  }
265 
266  bool takes_varargs (void) const;
267 
268  bool takes_var_return (void) const;
269 
270  void mark_as_private_function (const std::string& cname = "")
271  {
273 
275  }
276 
277  void lock_subfunctions (void);
278 
279  void unlock_subfunctions (void);
280 
281  std::map<std::string, octave_value> subfunctions (void) const;
282 
283  bool has_subfunctions (void) const;
284 
285  void stash_subfunction_names (const std::list<std::string>& names);
286 
287  std::list<std::string> subfunction_names (void) const
288  {
289  return subfcn_names;
290  }
291 
292  octave_value_list all_va_args (const octave_value_list& args);
293 
294  void stash_function_name (const std::string& s) { my_name = s; }
295 
296  void mark_as_subfunction (void) { subfunction = true; }
297 
298  bool is_subfunction (void) const { return subfunction; }
299 
300  void mark_as_inline_function (void) { inline_function = true; }
301 
302  bool is_inline_function (void) const { return inline_function; }
303 
304  void mark_as_anonymous_function (void) { anonymous_function = true; }
305 
306  bool is_anonymous_function (void) const { return anonymous_function; }
307 
308  bool is_anonymous_function_of_class
309  (const std::string& cname = "") const
310  {
311  return anonymous_function
312  ? (cname.empty ()
313  ? (! dispatch_class ().empty ())
314  : cname == dispatch_class ())
315  : false;
316  }
317 
318  // If we are a special expression, then the function body consists of exactly
319  // one expression. The expression's result is the return value of the
320  // function.
321  bool is_special_expr (void) const
322  {
323  return is_inline_function () || is_anonymous_function ();
324  }
325 
326  bool is_nested_function (void) const { return nested_function; }
327 
328  void mark_as_nested_function (void) { nested_function = true; }
329 
330  void mark_as_class_constructor (void) { class_constructor = legacy; }
331 
332  void mark_as_classdef_constructor (void) { class_constructor = classdef; }
333 
334  bool is_class_constructor (const std::string& cname = "") const
335  {
336  return class_constructor == legacy
337  ? (cname.empty () ? true : cname == dispatch_class ()) : false;
338  }
339 
340  bool is_classdef_constructor (const std::string& cname = "") const
341  {
342  return class_constructor == classdef
343  ? (cname.empty () ? true : cname == dispatch_class ()) : false;
344  }
345 
346  void mark_as_class_method (void) { class_method = true; }
347 
348  bool is_class_method (const std::string& cname = "") const
349  {
350  return class_method
351  ? (cname.empty () ? true : cname == dispatch_class ()) : false;
352  }
353 
355  const std::list<octave_value_list>& idx)
356  {
357  octave_value_list tmp = subsref (type, idx, 1);
358  return tmp.length () > 0 ? tmp(0) : octave_value ();
359  }
360 
362  const std::list<octave_value_list>& idx,
363  int nargout);
364 
366  const std::list<octave_value_list>& idx,
367  int nargout,
368  const std::list<octave_lvalue>* lvalue_list);
369 
371  do_multi_index_op (int nargout, const octave_value_list& args);
372 
374  do_multi_index_op (int nargout, const octave_value_list& args,
375  const std::list<octave_lvalue>* lvalue_list);
376 
377  tree_parameter_list *parameter_list (void) { return param_list; }
378 
379  tree_parameter_list *return_list (void) { return ret_list; }
380 
381  tree_statement_list *body (void) { return cmd_list; }
382 
383  octave_comment_list *leading_comment (void) { return lead_comm; }
384 
385  octave_comment_list *trailing_comment (void) { return trail_comm; }
386 
387  // If is_special_expr is true, retrieve the sigular expression that forms the
388  // body. May be null (even if is_special_expr is true).
389  tree_expression *special_expr (void);
390 
391  bool subsasgn_optimization_ok (void);
392 
393  void accept (tree_walker& tw);
394 
395  template <typename T>
397  {
398  if (curr_unwind_protect_frame)
399  {
400  curr_unwind_protect_frame->protect_var (variable);
401  return true;
402  }
403  else
404  return false;
405  }
406 
407 #if defined (HAVE_LLVM)
408  jit_function_info *get_info (void) { return jit_info; }
409 
410  void stash_info (jit_function_info *info) { jit_info = info; }
411 #endif
412 
413 #if 0
414  void print_symtab_info (std::ostream& os) const;
415 #endif
416 
417 private:
418 
419  enum class_ctor_type
420  {
423  classdef
424  };
425 
426  // List of arguments for this function. These are local variables.
428 
429  // List of parameters we return. These are also local variables in
430  // this function.
432 
433  // The list of commands that make up the body of this function.
435 
436  // The comments preceding the FUNCTION token.
438 
439  // The comments preceding the ENDFUNCTION token.
441 
442  // The name of the file we parsed.
444 
445  // Location where this function was defined.
450 
451  // The name of the parent function, if any.
453 
454  // The list of subfunctions (if any) in the order they appear in the
455  // file.
456  std::list<std::string> subfcn_names;
457 
458  // The time the file was parsed.
460 
461  // The time the file was last checked to see if it needs to be
462  // parsed again.
464 
465  // True if this function came from a file that is considered to be a
466  // system function. This affects whether we check the time stamp
467  // on the file to see if it has changed.
469 
470  // Used to keep track of recursion depth.
472 
473  // The number of arguments that have names.
475 
476  // TRUE means this subfunction of a primary function.
478 
479  // TRUE means this is an inline function.
481 
482  // TRUE means this is an anonymous function.
484 
485  // TRUE means this is a nested function. (either a child or parent)
487 
488  // Enum describing whether this function is the constructor for class object.
490 
491  // TRUE means this function is a method for a class.
493 
494  // The scope of the parent function, if any.
496 
498 
499  // pointer to the current unwind_protect frame of this function.
501 
502 #if defined (HAVE_LLVM)
504 #endif
505 
506  void maybe_relocate_end_internal (void);
507 
508  void print_code_function_header (void);
509 
510  void print_code_function_trailer (void);
511 
512  void bind_automatic_vars (const string_vector& arg_names, int nargin,
513  int nargout, const octave_value_list& va_args,
514  const std::list<octave_lvalue> *lvalue_list);
515 
516  void restore_warning_states (void);
517 
518  // No copying!
519 
521 
522  octave_user_function& operator = (const octave_user_function& fn);
523 
525 };
526 
527 #endif
void stash_trailing_comment(octave_comment_list *tc)
Definition: ov-usr-fcn.h:231
void mark_fcn_file_up_to_date(const octave::sys::time &t)
Definition: ov-usr-fcn.h:114
std::list< std::string > subfunction_names(void) const
Definition: ov-usr-fcn.h:287
int beginning_line(void) const
Definition: ov-usr-fcn.h:211
octave::unwind_protect * curr_unwind_protect_frame
Definition: ov-usr-fcn.h:500
void mark_as_inline_function(void)
Definition: ov-usr-fcn.h:300
symbol_table::scope_id local_scope
Definition: ov-usr-fcn.h:497
octave_user_function * user_function_value(bool=false)
Definition: ov-usr-fcn.h:195
~octave_user_code(void)
Definition: ov-usr-fcn.h:60
std::list< std::string > subfcn_names
Definition: ov-usr-fcn.h:456
void stash_fcn_file_time(const octave::sys::time &t)
Definition: ov-usr-fcn.h:116
octave_comment_list * trail_comm
Definition: ov-usr-fcn.h:440
tree_parameter_list * parameter_list(void)
Definition: ov-usr-fcn.h:377
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE * f
octave::sys::time t_parsed
Definition: ov-usr-fcn.h:459
octave_idx_type length(void) const
Definition: ovl.h:96
octave_user_code(void)
Definition: ov-usr-fcn.h:57
idx subsref(val, idx) esult
Definition: ov.cc:3080
bool is_classdef_constructor(const std::string &cname="") const
Definition: ov-usr-fcn.h:340
bool local_protect(T &variable)
Definition: ov-usr-fcn.h:396
bool is_user_script(void) const
Definition: ov-usr-fcn.h:110
octave::sys::time t_checked
Definition: ov-usr-fcn.h:463
bool is_inline_function(void) const
Definition: ov-usr-fcn.h:302
symbol_table::scope_id scope(void)
Definition: ov-usr-fcn.h:249
bool is_user_code(void) const
Definition: ov-usr-fcn.h:62
void stash_fcn_end_location(int line, int col)
Definition: ov-usr-fcn.h:214
bool is_special_expr(void) const
Definition: ov-usr-fcn.h:321
octave_comment_list * trailing_comment(void)
Definition: ov-usr-fcn.h:385
bool is_user_function(void) const
Definition: ov-usr-fcn.h:259
octave_comment_list * lead_comm
Definition: ov-usr-fcn.h:437
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
Definition: ov-usr-fcn.h:128
void stash_info(jit_function_info *info)
Definition: ov-usr-fcn.h:410
octave_user_code * user_code_value(bool=false)
Definition: ov-usr-fcn.h:105
symbol_table::scope_id parent_scope
Definition: ov-usr-fcn.h:495
bool is_class_method(const std::string &cname="") const
Definition: ov-usr-fcn.h:348
octave_comment_list * leading_comment(void)
Definition: ov-usr-fcn.h:383
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function t
Definition: ov-usr-fcn.cc:935
octave_user_code(const std::string &nm, const std::string &ds="")
Definition: ov-usr-fcn.h:70
void stash_leading_comment(octave_comment_list *lc)
Definition: ov-usr-fcn.h:229
s
Definition: file-io.cc:2682
octave_function * function_value(bool=false)
Definition: ov-usr-fcn.h:101
octave::sys::time t_parsed
Definition: ov-usr-fcn.h:155
void mark_fcn_file_up_to_date(const octave::sys::time &t)
Definition: ov-usr-fcn.h:233
symbol_table::context_id active_context() const
Definition: ov-usr-fcn.h:187
symbol_table::scope_id parent_fcn_scope(void) const
Definition: ov-usr-fcn.h:247
void stash_fcn_location(int line, int col)
Definition: ov-usr-fcn.h:205
bool is_system_fcn_file(void) const
Definition: ov-usr-fcn.h:257
is any Octave expression that can be evaluated in the code context that exists at the breakpoint When the breakpoint is and execution will stop if for example because it refers to an undefined variable
Definition: debug.cc:1099
bool is_subfunction(void) const
Definition: ov-usr-fcn.h:298
bool is_class_constructor(const std::string &cname="") const
Definition: ov-usr-fcn.h:334
JNIEnv void * args
Definition: ov-java.cc:67
static void mark_subfunctions_in_scope_as_private(scope_id scope, const std::string &class_name)
Definition: symtab.h:1240
#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
Definition: ov-base.h:148
bool is_anonymous_function(void) const
Definition: ov-usr-fcn.h:306
OCTAVE_EXPORT octave_value_list isdir nd deftypefn *std::string nm
Definition: utils.cc:941
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:935
void stash_function_name(const std::string &s)
Definition: ov-usr-fcn.h:294
tree_parameter_list * return_list(void)
Definition: ov-usr-fcn.h:379
int nargin
Definition: graphics.cc:10115
void mark_as_nested_function(void)
Definition: ov-usr-fcn.h:328
static void erase_subfunctions_in_scope(scope_id scope)
Definition: symtab.h:1233
void stash_parent_fcn_scope(symbol_table::scope_id ps)
Definition: ov-usr-fcn.h:227
void mark_as_class_method(void)
Definition: ov-usr-fcn.h:346
double tmp
Definition: data.cc:6300
virtual void mark_as_private_function(const std::string &cname="")
Definition: ov-fcn.h:110
octave::sys::time t_checked
Definition: ov-usr-fcn.h:159
idx type
Definition: ov.cc:3129
void stash_fcn_file_time(const octave::sys::time &t)
Definition: ov-usr-fcn.h:235
tree_statement_list * cmd_list
Definition: ov-usr-fcn.h:149
jit_function_info * get_info(void)
Definition: ov-usr-fcn.h:408
std::string fcn_file_name(void) const
Definition: ov-usr-fcn.h:241
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
Definition: ov-usr-fcn.h:354
std::string file_name
Definition: ov-usr-fcn.h:152
std::string file_name
Definition: ov-usr-fcn.h:443
void mark_as_classdef_constructor(void)
Definition: ov-usr-fcn.h:332
octave_user_code * user_code_value(bool=false)
Definition: ov-usr-fcn.h:197
octave_user_script * user_script_value(bool=false)
Definition: ov-usr-fcn.h:103
tree_statement_list * body(void)
Definition: ov-usr-fcn.h:142
void erase_subfunctions(void)
Definition: ov-usr-fcn.h:261
octave::sys::time time_parsed(void) const
Definition: ov-usr-fcn.h:124
jit_function_info * jit_info
Definition: ov-usr-fcn.h:503
octave::sys::time time_checked(void) const
Definition: ov-usr-fcn.h:253
p
Definition: lu.cc:138
void stash_fcn_file_name(const std::string &nm)
Definition: ov-usr-fcn.h:112
std::string parent_name
Definition: ov-usr-fcn.h:452
tree_statement_list * cmd_list
Definition: ov-usr-fcn.h:434
class_ctor_type class_constructor
Definition: ov-usr-fcn.h:489
octave_function * function_value(bool=false)
Definition: ov-usr-fcn.h:193
tree_parameter_list * param_list
Definition: ov-usr-fcn.h:427
void mark_as_anonymous_function(void)
Definition: ov-usr-fcn.h:304
octave::sys::time time_parsed(void) const
Definition: ov-usr-fcn.h:251
octave::sys::time time_checked(void) const
Definition: ov-usr-fcn.h:126
void mark_as_subfunction(void)
Definition: ov-usr-fcn.h:296
int ending_line(void) const
Definition: ov-usr-fcn.h:220
int beginning_column(void) const
Definition: ov-usr-fcn.h:212
std::string fcn_file_name(void) const
Definition: ov-usr-fcn.h:122
tree_statement_list * body(void)
Definition: ov-usr-fcn.h:381
void stash_parent_fcn_name(const std::string &p)
Definition: ov-usr-fcn.h:225
std::string parent_fcn_name(void) const
Definition: ov-usr-fcn.h:245
tree_parameter_list * ret_list
Definition: ov-usr-fcn.h:431
static int call_depth
Definition: daspk.cc:58
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:854
void mark_as_class_constructor(void)
Definition: ov-usr-fcn.h:330
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))
void mark_as_private_function(const std::string &cname="")
Definition: ov-usr-fcn.h:270
bool is_nested_function(void) const
Definition: ov-usr-fcn.h:326
int ending_column(void) const
Definition: ov-usr-fcn.h:221