ov-usr-fcn.h

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #if !defined (octave_user_function_h)
00024 #define octave_user_function_h 1
00025 
00026 #include <ctime>
00027 
00028 #include <string>
00029 #include <stack>
00030 
00031 #include "comment-list.h"
00032 #include "oct-obj.h"
00033 #include "ov-fcn.h"
00034 #include "ov-typeinfo.h"
00035 #include "symtab.h"
00036 #include "unwind-prot.h"
00037 
00038 class string_vector;
00039 
00040 class octave_value;
00041 class tree_parameter_list;
00042 class tree_statement_list;
00043 class tree_va_return_list;
00044 class tree_walker;
00045 
00046 class
00047 octave_user_code : public octave_function
00048 {
00049 public:
00050   octave_user_code (void)
00051     : octave_function () { }
00052 
00053   ~octave_user_code (void) { }
00054 
00055   bool is_user_code (void) const { return true; }
00056 
00057   virtual tree_statement_list *body (void) = 0;
00058 
00059 protected:
00060 
00061   octave_user_code (const std::string& nm,
00062                     const std::string& ds = std::string ())
00063     : octave_function (nm, ds) { }
00064 
00065 private:
00066 
00067   // No copying!
00068 
00069   octave_user_code (const octave_user_code& f);
00070 
00071   octave_user_code& operator = (const octave_user_code& f);
00072 };
00073 
00074 // Scripts.
00075 
00076 class
00077 octave_user_script : public octave_user_code
00078 {
00079 public:
00080 
00081   octave_user_script (void);
00082 
00083   octave_user_script (const std::string& fnm, const std::string& nm,
00084                       tree_statement_list *cmds,
00085                       const std::string& ds = std::string ());
00086 
00087   octave_user_script (const std::string& fnm, const std::string& nm,
00088                       const std::string& ds = std::string ());
00089 
00090   ~octave_user_script (void);
00091 
00092   octave_function *function_value (bool = false) { return this; }
00093 
00094   octave_user_script *user_script_value (bool = false) { return this; }
00095 
00096   octave_user_code *user_code_value (bool = false) { return this; }
00097 
00098   // Scripts and user functions are both considered "scripts" because
00099   // they are written in Octave's scripting language.
00100 
00101   bool is_user_script (void) const { return true; }
00102 
00103   void stash_fcn_file_name (const std::string& nm) { file_name = nm; }
00104 
00105   void mark_fcn_file_up_to_date (const octave_time& t) { t_checked = t; }
00106 
00107   void stash_fcn_file_time (const octave_time& t)
00108     {
00109       t_parsed = t;
00110       mark_fcn_file_up_to_date (t);
00111     }
00112 
00113   std::string fcn_file_name (void) const { return file_name; }
00114 
00115   octave_time time_parsed (void) const { return t_parsed; }
00116 
00117   octave_time time_checked (void) const { return t_checked; }
00118 
00119   octave_value subsref (const std::string& type,
00120                         const std::list<octave_value_list>& idx)
00121     {
00122       octave_value_list tmp = subsref (type, idx, 1);
00123       return tmp.length () > 0 ? tmp(0) : octave_value ();
00124     }
00125 
00126   octave_value_list subsref (const std::string& type,
00127                              const std::list<octave_value_list>& idx,
00128                              int nargout);
00129 
00130   octave_value_list
00131   do_multi_index_op (int nargout, const octave_value_list& args);
00132 
00133   tree_statement_list *body (void) { return cmd_list; }
00134 
00135   void accept (tree_walker& tw);
00136 
00137 private:
00138 
00139   // The list of commands that make up the body of this function.
00140   tree_statement_list *cmd_list;
00141 
00142   // The name of the file we parsed.
00143   std::string file_name;
00144 
00145   // The time the file was parsed.
00146   octave_time t_parsed;
00147 
00148   // The time the file was last checked to see if it needs to be
00149   // parsed again.
00150   octave_time t_checked;
00151 
00152   // Used to keep track of recursion depth.
00153   int call_depth;
00154 
00155   // No copying!
00156 
00157   octave_user_script (const octave_user_script& f);
00158 
00159   octave_user_script& operator = (const octave_user_script& f);
00160 
00161   DECLARE_OCTAVE_ALLOCATOR
00162 
00163   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
00164 };
00165 
00166 // User-defined functions.
00167 
00168 class
00169 octave_user_function : public octave_user_code
00170 {
00171 public:
00172 
00173   octave_user_function (symbol_table::scope_id sid = -1,
00174                         tree_parameter_list *pl = 0,
00175                         tree_parameter_list *rl = 0,
00176                         tree_statement_list *cl = 0);
00177 
00178   ~octave_user_function (void);
00179 
00180   octave_function *function_value (bool = false) { return this; }
00181 
00182   octave_user_function *user_function_value (bool = false) { return this; }
00183 
00184   octave_user_code *user_code_value (bool = false) { return this; }
00185 
00186   octave_user_function *define_param_list (tree_parameter_list *t);
00187 
00188   octave_user_function *define_ret_list (tree_parameter_list *t);
00189 
00190   void stash_fcn_file_name (const std::string& nm);
00191 
00192   void stash_fcn_location (int line, int col)
00193     {
00194       location_line = line;
00195       location_column = col;
00196     }
00197 
00198   void stash_parent_fcn_name (const std::string& p) { parent_name = p; }
00199 
00200   void stash_parent_fcn_scope (symbol_table::scope_id ps) { parent_scope = ps; }
00201 
00202   void stash_leading_comment (octave_comment_list *lc) { lead_comm = lc; }
00203 
00204   void stash_trailing_comment (octave_comment_list *tc) { trail_comm = tc; }
00205 
00206   void mark_fcn_file_up_to_date (const octave_time& t) { t_checked = t; }
00207 
00208   void stash_fcn_file_time (const octave_time& t)
00209     {
00210       t_parsed = t;
00211       mark_fcn_file_up_to_date (t);
00212     }
00213 
00214   std::string fcn_file_name (void) const { return file_name; }
00215 
00216   std::string profiler_name (void) const;
00217 
00218   std::string parent_fcn_name (void) const { return parent_name; }
00219 
00220   symbol_table::scope_id parent_fcn_scope (void) const { return parent_scope; }
00221 
00222   symbol_table::scope_id scope (void) { return local_scope; }
00223 
00224   octave_time time_parsed (void) const { return t_parsed; }
00225 
00226   octave_time time_checked (void) const { return t_checked; }
00227 
00228   void mark_as_system_fcn_file (void);
00229 
00230   bool is_system_fcn_file (void) const { return system_fcn_file; }
00231 
00232   bool is_user_function (void) const { return true; }
00233 
00234   void erase_subfunctions (void)
00235     {
00236       symbol_table::erase_subfunctions_in_scope (local_scope);
00237     }
00238 
00239   bool takes_varargs (void) const;
00240 
00241   bool takes_var_return (void) const;
00242 
00243   void mark_as_private_function (const std::string& cname = std::string ())
00244     {
00245       symbol_table::mark_subfunctions_in_scope_as_private (local_scope, cname);
00246 
00247       octave_function::mark_as_private_function (cname);
00248     }
00249 
00250   void lock_subfunctions (void);
00251 
00252   void unlock_subfunctions (void);
00253 
00254   octave_value_list all_va_args (const octave_value_list& args);
00255 
00256   void stash_function_name (const std::string& s) { my_name = s; }
00257 
00258   void mark_as_subfunction (void) { subfunction = true; }
00259 
00260   bool is_subfunction (void) const { return subfunction; }
00261 
00262   void mark_as_inline_function (void) { inline_function = true; }
00263 
00264   bool is_inline_function (void) const { return inline_function; }
00265 
00266   void mark_as_anonymous_function (void) { anonymous_function = true; }
00267 
00268   bool is_anonymous_function (void) const { return anonymous_function; }
00269 
00270   bool is_anonymous_function_of_class
00271     (const std::string& cname = std::string ()) const
00272   {
00273     return anonymous_function
00274       ? (cname.empty ()
00275          ? (! dispatch_class().empty ())
00276          : cname == dispatch_class ())
00277       : false;
00278   }
00279 
00280   void mark_as_class_constructor (void) { class_constructor = true; }
00281 
00282   bool is_class_constructor (const std::string& cname = std::string ()) const
00283     {
00284       return class_constructor
00285         ? (cname.empty () ? true : cname == dispatch_class ()) : false;
00286     }
00287 
00288   void mark_as_class_method (void) { class_method = true; }
00289 
00290   bool is_class_method (const std::string& cname = std::string ()) const
00291     {
00292       return class_method
00293         ? (cname.empty () ? true : cname == dispatch_class ()) : false;
00294     }
00295 
00296   octave_value subsref (const std::string& type,
00297                         const std::list<octave_value_list>& idx)
00298     {
00299       octave_value_list tmp = subsref (type, idx, 1);
00300       return tmp.length () > 0 ? tmp(0) : octave_value ();
00301     }
00302 
00303   octave_value_list subsref (const std::string& type,
00304                              const std::list<octave_value_list>& idx,
00305                              int nargout);
00306 
00307   octave_value_list subsref (const std::string& type,
00308                              const std::list<octave_value_list>& idx,
00309                              int nargout, const std::list<octave_lvalue>* lvalue_list);
00310 
00311   octave_value_list
00312   do_multi_index_op (int nargout, const octave_value_list& args);
00313 
00314   octave_value_list
00315   do_multi_index_op (int nargout, const octave_value_list& args,
00316                      const std::list<octave_lvalue>* lvalue_list);
00317 
00318   tree_parameter_list *parameter_list (void) { return param_list; }
00319 
00320   tree_parameter_list *return_list (void) { return ret_list; }
00321 
00322   tree_statement_list *body (void) { return cmd_list; }
00323 
00324   octave_comment_list *leading_comment (void) { return lead_comm; }
00325 
00326   octave_comment_list *trailing_comment (void) { return trail_comm; }
00327 
00328   bool subsasgn_optimization_ok (void);
00329 
00330   void accept (tree_walker& tw);
00331 
00332   template <class T>
00333   bool local_protect (T& variable)
00334     {
00335       if (curr_unwind_protect_frame)
00336         {
00337           curr_unwind_protect_frame->protect_var (variable);
00338           return true;
00339         }
00340       else
00341         return false;
00342     }
00343 
00344 #if 0
00345   void print_symtab_info (std::ostream& os) const;
00346 #endif
00347 
00348 private:
00349 
00350   // List of arguments for this function.  These are local variables.
00351   tree_parameter_list *param_list;
00352 
00353   // List of parameters we return.  These are also local variables in
00354   // this function.
00355   tree_parameter_list *ret_list;
00356 
00357   // The list of commands that make up the body of this function.
00358   tree_statement_list *cmd_list;
00359 
00360   // The comments preceding the FUNCTION token.
00361   octave_comment_list *lead_comm;
00362 
00363   // The comments preceding the ENDFUNCTION token.
00364   octave_comment_list *trail_comm;
00365 
00366   // The name of the file we parsed.
00367   std::string file_name;
00368 
00369   // Location where this function was defined.
00370   int location_line;
00371   int location_column;
00372 
00373   // The name of the parent function, if any.
00374   std::string parent_name;
00375 
00376   // The time the file was parsed.
00377   octave_time t_parsed;
00378 
00379   // The time the file was last checked to see if it needs to be
00380   // parsed again.
00381   octave_time t_checked;
00382 
00383   // True if this function came from a file that is considered to be a
00384   // system function.  This affects whether we check the time stamp
00385   // on the file to see if it has changed.
00386   bool system_fcn_file;
00387 
00388   // Used to keep track of recursion depth.
00389   int call_depth;
00390 
00391   // The number of arguments that have names.
00392   int num_named_args;
00393 
00394   // TRUE means this subfunction of a primary function.
00395   bool subfunction;
00396 
00397   // TRUE means this is an inline function.
00398   bool inline_function;
00399 
00400   // TRUE means this is an anonymous function.
00401   bool anonymous_function;
00402 
00403   // TRUE means this function is the constructor for class object.
00404   bool class_constructor;
00405 
00406   // TRUE means this function is a method for a class.
00407   bool class_method;
00408 
00409   // The scope of the parent function, if any.
00410   symbol_table::scope_id parent_scope;
00411 
00412   symbol_table::scope_id local_scope;
00413 
00414   // pointer to the current unwind_protect frame of this function.
00415   unwind_protect *curr_unwind_protect_frame;
00416 
00417 #if 0
00418   // The symbol record for argn in the local symbol table.
00419   octave_value& argn_varref;
00420 
00421   // The symbol record for nargin in the local symbol table.
00422   octave_value& nargin_varref;
00423 
00424   // The symbol record for nargout in the local symbol table.
00425   octave_value& nargout_varref;
00426 
00427   // The symbol record for varargin in the local symbol table.
00428   octave_value& varargin_varref;
00429 #endif
00430 
00431   void print_code_function_header (void);
00432 
00433   void print_code_function_trailer (void);
00434 
00435   void bind_automatic_vars (const string_vector& arg_names, int nargin,
00436                             int nargout, const octave_value_list& va_args,
00437                             const std::list<octave_lvalue> *lvalue_list);
00438 
00439   // No copying!
00440 
00441   octave_user_function (const octave_user_function& fn);
00442 
00443   octave_user_function& operator = (const octave_user_function& fn);
00444 
00445   DECLARE_OCTAVE_ALLOCATOR
00446 
00447   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
00448 };
00449 
00450 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines