GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
ov-usr-fcn.h
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1996-2022 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if ! defined (octave_ov_usr_fcn_h)
27#define octave_ov_usr_fcn_h 1
28
29#include "octave-config.h"
30
31#include <string>
32
33#include "comment-list.h"
34#include "ovl.h"
35#include "ov-fcn.h"
36#include "ov-typeinfo.h"
37#include "symscope.h"
38#include "unwind-prot.h"
39
40class string_vector;
41
42class octave_value;
43
44namespace octave
45{
46 class file_info;
47 class stack_frame;
48 class tree_parameter_list;
49 class tree_statement_list;
50 class tree_evaluator;
51 class tree_expression;
52 class tree_walker;
53}
54
55class
57{
58protected:
59
60 octave_user_code (const std::string& fnm = "", const std::string& nm = "",
62 octave::tree_statement_list *cmds = nullptr,
63 const std::string& ds = "")
64 : octave_function (nm, ds), m_scope (scope), m_file_name (fnm),
65 m_t_parsed (static_cast<OCTAVE_TIME_T> (0)),
66 m_t_checked (static_cast<OCTAVE_TIME_T> (0)),
67 m_file_info (nullptr), m_cmd_list (cmds)
68 {
69 if (m_scope)
70 m_scope.set_user_code (this);
71 }
72
73public:
74
75 // No copying!
76
78
79 octave_user_code& operator = (const octave_user_code& f) = delete;
80
81 ~octave_user_code (void);
82
83 bool is_user_code (void) const { return true; }
84
85 std::string get_code_line (std::size_t line);
86
87 std::deque<std::string> get_code_lines (std::size_t line,
88 std::size_t num_lines);
89
90 void cache_function_text (const std::string& text,
91 const octave::sys::time& timestamp);
92
93 octave::symbol_scope scope (void) { return m_scope; }
94
95 void stash_fcn_file_name (const std::string& nm) { m_file_name = nm; }
96
98 { m_t_checked = t; }
99
101 {
102 m_t_parsed = t;
103 mark_fcn_file_up_to_date (t);
104 }
105
106 std::string fcn_file_name (void) const { return m_file_name; }
107
108 octave::sys::time time_parsed (void) const { return m_t_parsed; }
109
110 octave::sys::time time_checked (void) const { return m_t_checked; }
111
112 virtual octave_value find_subfunction (const std::string&) const
113 {
114 return octave_value ();
115 }
116
117 virtual std::map<std::string, octave_value> subfunctions (void) const;
118
119 octave::tree_statement_list * body (void) { return m_cmd_list; }
120
121 octave_value dump (void) const;
122
123protected:
124
125 void get_file_info (void);
126
127 // Our symbol table scope.
129
130 // The name of the file we parsed.
131 std::string m_file_name;
132
133 // The time the file was parsed.
135
136 // The time the file was last checked to see if it needs to be
137 // parsed again.
139
140 // Cached text of function or script code with line offsets
141 // calculated.
143
144 // The list of commands that make up the body of this function.
146};
147
148// Scripts.
149
150class
152{
153public:
154
155 octave_user_script (void);
156
157 octave_user_script (const std::string& fnm, const std::string& nm,
159 octave::tree_statement_list *cmds = nullptr,
160 const std::string& ds = "");
161
162 octave_user_script (const std::string& fnm, const std::string& nm,
164 const std::string& ds = "");
165
166 // No copying!
167
169
170 octave_user_script& operator = (const octave_user_script& f) = delete;
171
172 ~octave_user_script (void) = default;
173
174 octave_function * function_value (bool = false) { return this; }
175
176 octave_user_script * user_script_value (bool = false) { return this; }
177
178 octave_user_code * user_code_value (bool = false) { return this; }
179
180 // Scripts and user functions are both considered "scripts" because
181 // they are written in Octave's scripting language.
182
183 bool is_user_script (void) const { return true; }
184
185 // We must overload the call method so that we call the proper
186 // push_stack_frame method, which is overloaded for pointers to
187 // octave_function, octave_user_function, and octave_user_script
188 // objects.
189
191 call (octave::tree_evaluator& tw, int nargout = 0,
192 const octave_value_list& args = octave_value_list ());
193
195 execute (octave::tree_evaluator& tw, int nargout = 0,
196 const octave_value_list& args = octave_value_list ());
197
198 void accept (octave::tree_walker& tw);
199
200private:
201
203};
204
205// User-defined functions.
206
207class
209{
210public:
211
213 octave::tree_parameter_list *pl = nullptr,
214 octave::tree_parameter_list *rl = nullptr,
215 octave::tree_statement_list *cl = nullptr);
216
217 // No copying!
218
220
221 octave_user_function& operator = (const octave_user_function& fn) = delete;
222
224
225 octave_function * function_value (bool = false) { return this; }
226
227 octave_user_function * user_function_value (bool = false) { return this; }
228
229 octave_user_code * user_code_value (bool = false) { return this; }
230
232
234
235 void stash_fcn_location (int line, int col)
236 {
237 m_location_line = line;
238 m_location_column = col;
239 }
240
241 int beginning_line (void) const { return m_location_line; }
242 int beginning_column (void) const { return m_location_column; }
243
244 void stash_fcn_end_location (int line, int col)
245 {
246 m_end_location_line = line;
247 m_end_location_column = col;
248 }
249
250 int ending_line (void) const { return m_end_location_line; }
251 int ending_column (void) const { return m_end_location_column; }
252
253 void maybe_relocate_end (void);
254
255 void stash_parent_fcn_scope (const octave::symbol_scope& ps);
256
257 void stash_leading_comment (octave::comment_list *lc) { m_lead_comm = lc; }
258
259 void stash_trailing_comment (octave::comment_list *tc) { m_trail_comm = tc; }
260
261 std::string profiler_name (void) const;
262
263 std::string parent_fcn_name (void) const
264 {
265 octave::symbol_scope pscope = parent_fcn_scope ();
266
267 return pscope.fcn_name ();
268 }
269
271 {
272 return m_scope.parent_scope ();
273 }
274
275 std::list<std::string> parent_fcn_names (void) const
276 {
277 return m_scope.parent_fcn_names ();
278 }
279
280 void mark_as_system_fcn_file (void);
281
282 bool is_system_fcn_file (void) const { return m_system_fcn_file; }
283
284 bool is_user_function (void) const { return true; }
285
286 void erase_subfunctions (void);
287
288 bool takes_varargs (void) const;
289
290 bool takes_var_return (void) const;
291
292 void mark_as_private_function (const std::string& cname = "");
293
294 void lock_subfunctions (void);
295
296 void unlock_subfunctions (void);
297
298 std::map<std::string, octave_value> subfunctions (void) const;
299
300 octave_value find_subfunction (const std::string& subfuns) const;
301
302 bool has_subfunctions (void) const;
303
304 void stash_subfunction_names (const std::list<std::string>& names);
305
306 std::list<std::string> subfunction_names (void) const;
307
308 octave_value_list all_va_args (const octave_value_list& args);
309
310 void stash_function_name (const std::string& s) { m_name = s; }
311
312 void mark_as_subfunction (void) { m_subfunction = true; }
313
314 bool is_subfunction (void) const { return m_subfunction; }
315
316 void mark_as_inline_function (void) { m_inline_function = true; }
317
318 bool is_inline_function (void) const { return m_inline_function; }
319
320 void mark_as_anonymous_function (void) { m_anonymous_function = true; }
321
322 bool is_anonymous_function (void) const { return m_anonymous_function; }
323
325 (const std::string& cname = "") const
326 {
327 return m_anonymous_function
328 ? (cname.empty ()
329 ? (! dispatch_class ().empty ())
330 : cname == dispatch_class ())
331 : false;
332 }
333
334 // If we are a special expression, then the function body consists of exactly
335 // one expression. The expression's result is the return value of the
336 // function.
337 bool is_special_expr (void) const
338 {
339 return is_inline_function () || is_anonymous_function ();
340 }
341
342 void mark_as_nested_function (void) { m_nested_function = true; }
343
344 bool is_nested_function (void) const { return m_nested_function; }
345
346 bool is_parent_function (void) const { return m_scope.is_parent (); }
347
348 void mark_as_legacy_constructor (void) { m_class_constructor = legacy; }
349
350 bool is_legacy_constructor (const std::string& cname = "") const
351 {
352 return (m_class_constructor == legacy
353 ? (cname.empty () ? true : cname == dispatch_class ()) : false);
354 }
355
356 void mark_as_classdef_constructor (void) { m_class_constructor = classdef; }
357
358 bool is_classdef_constructor (const std::string& cname = "") const
359 {
360 return (m_class_constructor == classdef
361 ? (cname.empty () ? true : cname == dispatch_class ()) : false);
362 }
363
364 void mark_as_legacy_method (void) { m_class_method = legacy; }
365
366 bool is_legacy_method (const std::string& cname = "") const
367 {
368 return (m_class_method == legacy
369 ? (cname.empty () ? true : cname == dispatch_class ()) : false);
370 }
371
372 void mark_as_classdef_method (void) { m_class_method = classdef; }
373
374 bool is_classdef_method (const std::string& cname = "") const
375 {
376 return (m_class_method == classdef
377 ? (cname.empty () ? true : cname == dispatch_class ()) : false);
378 }
379
380 // We must overload the call method so that we call the proper
381 // push_stack_frame method, which is overloaded for pointers to
382 // octave_function, octave_user_function, and octave_user_script
383 // objects.
384
386 call (octave::tree_evaluator& tw, int nargout = 0,
387 const octave_value_list& args = octave_value_list ());
388
390 execute (octave::tree_evaluator& tw, int nargout = 0,
391 const octave_value_list& args = octave_value_list ());
392
393 octave::tree_parameter_list * parameter_list (void) { return m_param_list; }
394
395 octave::tree_parameter_list * return_list (void) { return m_ret_list; }
396
397 octave::comment_list * leading_comment (void) { return m_lead_comm; }
398
399 octave::comment_list * trailing_comment (void) { return m_trail_comm; }
400
401 // If is_special_expr is true, retrieve the sigular expression that forms the
402 // body. May be null (even if is_special_expr is true).
403 octave::tree_expression * special_expr (void);
404
405 bool subsasgn_optimization_ok (void);
406
407 void accept (octave::tree_walker& tw);
408
409 octave_value dump (void) const;
410
411private:
412
413 enum class_method_type
414 {
417 classdef
418 };
419
420 std::string ctor_type_str (void) const;
421 std::string method_type_str (void) const;
422
423 // List of arguments for this function. These are local variables.
425
426 // List of parameters we return. These are also local variables in
427 // this function.
429
430 // The comments preceding the FUNCTION token.
432
433 // The comments preceding the ENDFUNCTION token.
435
436 // Location where this function was defined.
441
442 // True if this function came from a file that is considered to be a
443 // system function. This affects whether we check the time stamp
444 // on the file to see if it has changed.
446
447 // The number of arguments that have names.
449
450 // TRUE means this is a m_subfunction of a primary function.
452
453 // TRUE means this is an inline function.
455
456 // TRUE means this is an anonymous function.
458
459 // TRUE means this is a nested function.
461
462 // Enum describing whether this function is the constructor for class object.
464
465 // Enum describing whether this function is a method for a class.
467
468 void maybe_relocate_end_internal (void);
469
470 void print_code_function_header (const std::string& prefix);
471
472 void print_code_function_trailer (const std::string& prefix);
473
474 // XXX FIXME (public)
475public:
476
477 void restore_warning_states (void);
478
480};
481
482#endif
std::shared_ptr< symbol_scope_rep > parent_scope(void) const
Definition: symscope.h:447
std::string fcn_name(void) const
Definition: symscope.h:582
void stash_fcn_file_name(const std::string &nm)
Definition: ov-usr-fcn.h:95
std::string fcn_file_name(void) const
Definition: ov-usr-fcn.h:106
octave_user_code(const octave_user_code &f)=delete
std::string m_file_name
Definition: ov-usr-fcn.h:131
void mark_fcn_file_up_to_date(const octave::sys::time &t)
Definition: ov-usr-fcn.h:97
octave::sys::time m_t_checked
Definition: ov-usr-fcn.h:138
octave::tree_statement_list * body(void)
Definition: ov-usr-fcn.h:119
octave::sys::time time_checked(void) const
Definition: ov-usr-fcn.h:110
octave::tree_statement_list * m_cmd_list
Definition: ov-usr-fcn.h:145
virtual octave_value find_subfunction(const std::string &) const
Definition: ov-usr-fcn.h:112
octave::sys::time m_t_parsed
Definition: ov-usr-fcn.h:134
octave::file_info * m_file_info
Definition: ov-usr-fcn.h:142
octave::sys::time time_parsed(void) const
Definition: ov-usr-fcn.h:108
void stash_fcn_file_time(const octave::sys::time &t)
Definition: ov-usr-fcn.h:100
octave::symbol_scope scope(void)
Definition: ov-usr-fcn.h:93
bool is_user_code(void) const
Definition: ov-usr-fcn.h:83
octave::symbol_scope m_scope
Definition: ov-usr-fcn.h:128
octave_user_code(const std::string &fnm="", const std::string &nm="", const octave::symbol_scope &scope=octave::symbol_scope(), octave::tree_statement_list *cmds=nullptr, const std::string &ds="")
Definition: ov-usr-fcn.h:60
octave::symbol_scope parent_fcn_scope(void) const
Definition: ov-usr-fcn.h:270
std::string parent_fcn_name(void) const
Definition: ov-usr-fcn.h:263
bool is_legacy_method(const std::string &cname="") const
Definition: ov-usr-fcn.h:366
void stash_trailing_comment(octave::comment_list *tc)
Definition: ov-usr-fcn.h:259
void stash_function_name(const std::string &s)
Definition: ov-usr-fcn.h:310
octave_user_code * user_code_value(bool=false)
Definition: ov-usr-fcn.h:229
bool is_nested_function(void) const
Definition: ov-usr-fcn.h:344
bool is_special_expr(void) const
Definition: ov-usr-fcn.h:337
void mark_as_anonymous_function(void)
Definition: ov-usr-fcn.h:320
octave::comment_list * m_trail_comm
Definition: ov-usr-fcn.h:434
octave::comment_list * leading_comment(void)
Definition: ov-usr-fcn.h:397
octave::tree_parameter_list * m_param_list
Definition: ov-usr-fcn.h:424
int ending_line(void) const
Definition: ov-usr-fcn.h:250
bool is_classdef_constructor(const std::string &cname="") const
Definition: ov-usr-fcn.h:358
bool is_user_function(void) const
Definition: ov-usr-fcn.h:284
void mark_as_classdef_method(void)
Definition: ov-usr-fcn.h:372
bool is_system_fcn_file(void) const
Definition: ov-usr-fcn.h:282
bool is_legacy_constructor(const std::string &cname="") const
Definition: ov-usr-fcn.h:350
bool is_classdef_method(const std::string &cname="") const
Definition: ov-usr-fcn.h:374
int ending_column(void) const
Definition: ov-usr-fcn.h:251
octave_user_function * user_function_value(bool=false)
Definition: ov-usr-fcn.h:227
int beginning_column(void) const
Definition: ov-usr-fcn.h:242
void mark_as_classdef_constructor(void)
Definition: ov-usr-fcn.h:356
class_method_type m_class_method
Definition: ov-usr-fcn.h:466
octave_function * function_value(bool=false)
Definition: ov-usr-fcn.h:225
std::list< std::string > parent_fcn_names(void) const
Definition: ov-usr-fcn.h:275
octave::tree_parameter_list * m_ret_list
Definition: ov-usr-fcn.h:428
octave::tree_parameter_list * parameter_list(void)
Definition: ov-usr-fcn.h:393
void mark_as_legacy_constructor(void)
Definition: ov-usr-fcn.h:348
bool is_anonymous_function_of_class(const std::string &cname="") const
Definition: ov-usr-fcn.h:325
bool is_inline_function(void) const
Definition: ov-usr-fcn.h:318
class_method_type m_class_constructor
Definition: ov-usr-fcn.h:463
void stash_leading_comment(octave::comment_list *lc)
Definition: ov-usr-fcn.h:257
bool is_subfunction(void) const
Definition: ov-usr-fcn.h:314
bool is_parent_function(void) const
Definition: ov-usr-fcn.h:346
int beginning_line(void) const
Definition: ov-usr-fcn.h:241
void stash_fcn_location(int line, int col)
Definition: ov-usr-fcn.h:235
void stash_fcn_end_location(int line, int col)
Definition: ov-usr-fcn.h:244
octave_user_function(const octave_user_function &fn)=delete
octave::tree_parameter_list * return_list(void)
Definition: ov-usr-fcn.h:395
void mark_as_legacy_method(void)
Definition: ov-usr-fcn.h:364
octave::comment_list * trailing_comment(void)
Definition: ov-usr-fcn.h:399
void mark_as_subfunction(void)
Definition: ov-usr-fcn.h:312
void mark_as_inline_function(void)
Definition: ov-usr-fcn.h:316
octave_user_function * define_param_list(octave::tree_parameter_list *t)
octave::comment_list * m_lead_comm
Definition: ov-usr-fcn.h:431
bool is_anonymous_function(void) const
Definition: ov-usr-fcn.h:322
void mark_as_nested_function(void)
Definition: ov-usr-fcn.h:342
~octave_user_script(void)=default
octave_user_code * user_code_value(bool=false)
Definition: ov-usr-fcn.h:178
bool is_user_script(void) const
Definition: ov-usr-fcn.h:183
octave_user_script(const octave_user_script &f)=delete
octave_user_script * user_script_value(bool=false)
Definition: ov-usr-fcn.h:176
octave_function * function_value(bool=false)
Definition: ov-usr-fcn.h:174
F77_RET_T const F77_DBLE const F77_DBLE * f
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
Definition: ov-base.h:173