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