GNU Octave  3.8.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-2013 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 
114  void stash_fcn_file_time (const octave_time& t)
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 
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 
187  symbol_table::context_id active_context () const
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_time& t) { t_checked = t; }
234 
235  void stash_fcn_file_time (const octave_time& t)
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_time time_parsed (void) const { return t_parsed; }
252 
253  octave_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 = std::string ())
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 = std::string ()) 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 = true; }
331 
332  bool is_class_constructor (const std::string& cname = std::string ()) const
333  {
334  return class_constructor
335  ? (cname.empty () ? true : cname == dispatch_class ()) : false;
336  }
337 
338  void mark_as_class_method (void) { class_method = true; }
339 
340  bool is_class_method (const std::string& cname = std::string ()) const
341  {
342  return class_method
343  ? (cname.empty () ? true : cname == dispatch_class ()) : false;
344  }
345 
346  octave_value subsref (const std::string& type,
347  const std::list<octave_value_list>& idx)
348  {
349  octave_value_list tmp = subsref (type, idx, 1);
350  return tmp.length () > 0 ? tmp(0) : octave_value ();
351  }
352 
353  octave_value_list subsref (const std::string& type,
354  const std::list<octave_value_list>& idx,
355  int nargout);
356 
357  octave_value_list subsref (const std::string& type,
358  const std::list<octave_value_list>& idx,
359  int nargout,
360  const std::list<octave_lvalue>* lvalue_list);
361 
363  do_multi_index_op (int nargout, const octave_value_list& args);
364 
366  do_multi_index_op (int nargout, const octave_value_list& args,
367  const std::list<octave_lvalue>* lvalue_list);
368 
369  tree_parameter_list *parameter_list (void) { return param_list; }
370 
371  tree_parameter_list *return_list (void) { return ret_list; }
372 
373  tree_statement_list *body (void) { return cmd_list; }
374 
375  octave_comment_list *leading_comment (void) { return lead_comm; }
376 
377  octave_comment_list *trailing_comment (void) { return trail_comm; }
378 
379  // If is_special_expr is true, retrieve the sigular expression that forms the
380  // body. May be null (even if is_special_expr is true).
381  tree_expression *special_expr (void);
382 
383  bool subsasgn_optimization_ok (void);
384 
385  void accept (tree_walker& tw);
386 
387  template <class T>
388  bool local_protect (T& variable)
389  {
390  if (curr_unwind_protect_frame)
391  {
392  curr_unwind_protect_frame->protect_var (variable);
393  return true;
394  }
395  else
396  return false;
397  }
398 
399 #ifdef HAVE_LLVM
400  jit_function_info *get_info (void) { return jit_info; }
401 
402  void stash_info (jit_function_info *info) { jit_info = info; }
403 #endif
404 
405 #if 0
406  void print_symtab_info (std::ostream& os) const;
407 #endif
408 
409 private:
410 
411  // List of arguments for this function. These are local variables.
413 
414  // List of parameters we return. These are also local variables in
415  // this function.
417 
418  // The list of commands that make up the body of this function.
420 
421  // The comments preceding the FUNCTION token.
423 
424  // The comments preceding the ENDFUNCTION token.
426 
427  // The name of the file we parsed.
428  std::string file_name;
429 
430  // Location where this function was defined.
435 
436  // The name of the parent function, if any.
437  std::string parent_name;
438 
439  // The list of subfunctions (if any) in the order they appear in the
440  // file.
441  std::list<std::string> subfcn_names;
442 
443  // The time the file was parsed.
445 
446  // The time the file was last checked to see if it needs to be
447  // parsed again.
449 
450  // True if this function came from a file that is considered to be a
451  // system function. This affects whether we check the time stamp
452  // on the file to see if it has changed.
454 
455  // Used to keep track of recursion depth.
457 
458  // The number of arguments that have names.
460 
461  // TRUE means this subfunction of a primary function.
463 
464  // TRUE means this is an inline function.
466 
467  // TRUE means this is an anonymous function.
469 
470  // TRUE means this is a nested function. (either a child or parent)
472 
473  // TRUE means this function is the constructor for class object.
475 
476  // TRUE means this function is a method for a class.
478 
479  // The scope of the parent function, if any.
481 
483 
484  // pointer to the current unwind_protect frame of this function.
486 
487 #ifdef HAVE_LLVM
489 #endif
490 
491  void maybe_relocate_end_internal (void);
492 
493  void print_code_function_header (void);
494 
495  void print_code_function_trailer (void);
496 
497  void bind_automatic_vars (const string_vector& arg_names, int nargin,
498  int nargout, const octave_value_list& va_args,
499  const std::list<octave_lvalue> *lvalue_list);
500 
501  void restore_warning_states (void);
502 
503  // No copying!
504 
506 
507  octave_user_function& operator = (const octave_user_function& fn);
508 
510 
512 };
513 
514 #endif