26 #if defined (HAVE_CONFIG_H)
65 static bool Voptimize_subsasgn_calls =
true;
73 m_scope.set_user_code (
nullptr);
95 warning (
"function file '%s' changed since it was parsed",
108 std::deque<std::string>
119 const octave::sys::time& timestamp)
124 warning (
"help text for function is newer than function");
129 std::map<std::string, octave_value>
132 return std::map<std::string, octave_value> ();
138 std::map<std::string, octave_value>
m
152 "user-defined script",
153 "user-defined script");
160 (
const std::string& fnm,
const std::string& nm,
161 const octave::symbol_scope& scope, octave::tree_statement_list *cmds,
162 const std::string& ds)
170 (
const std::string& fnm,
const std::string& nm,
171 const octave::symbol_scope& scope,
const std::string& ds)
184 tw.push_stack_frame (
this);
186 octave::unwind_action act ([&tw] () { tw.pop_stack_frame (); });
188 return execute (tw, nargout, args);
195 return tw.execute_user_script (*
this, nargout, args);
201 tw.visit_octave_user_script (*
this);
207 "user-defined function",
208 "user-defined function");
214 (
const octave::symbol_scope& scope, octave::tree_parameter_list *pl,
215 octave::tree_parameter_list *rl, octave::tree_statement_list *cl)
217 m_param_list (pl), m_ret_list (rl),
218 m_lead_comm (), m_trail_comm (),
219 m_location_line (0), m_location_column (0),
220 m_system_fcn_file (false),
221 m_num_named_args (m_param_list ? m_param_list->length () : 0),
222 m_subfunction (false), m_inline_function (false),
223 m_anonymous_function (false), m_nested_function (false),
224 m_class_constructor (none), m_class_method (none)
255 octave_user_function::maybe_relocate_end_internal ()
259 octave::tree_statement *last_stmt =
m_cmd_list->back ();
261 if (last_stmt && last_stmt->is_end_of_fcn_or_script ()
262 && last_stmt->is_end_of_file ())
264 octave::tree_statement_list::reverse_iterator
279 octave::tree_statement *next_to_last_stmt = *next_to_last_elt;
281 new_eof_line = next_to_last_stmt->line ();
282 new_eof_col = next_to_last_stmt->column ();
285 last_stmt->set_location (new_eof_line + 1, new_eof_col);
293 std::map<std::string, octave_value> fcns =
subfunctions ();
297 for (
auto& nm_fnval : fcns)
302 f->maybe_relocate_end_internal ();
306 maybe_relocate_end_internal ();
318 std::ostringstream result;
322 <<
':' << m_location_line <<
':' << m_location_column;
328 result <<
'@' <<
name ();
331 <<
':' << m_location_line <<
':' << m_location_column;
335 return result.str ();
354 static const std::string canonical_fcn_file_dir
359 : canonical_fcn_file_dir;
362 m_system_fcn_file =
true;
365 m_system_fcn_file =
false;
377 return (m_param_list && m_param_list->takes_varargs ());
383 return (m_ret_list && m_ret_list->takes_varargs ());
389 m_scope.mark_subfunctions_in_scope_as_private (cname);
403 m_scope.unlock_subfunctions ();
406 std::map<std::string, octave_value>
409 return m_scope.subfunctions ();
419 std::string subfcns = subfcns_arg;
421 std::string first_fcn = subfcns;
423 std::size_t pos = subfcns.find (
'>');
425 if (pos == std::string::npos)
429 first_fcn = subfcns.substr (0, pos-1);
430 subfcns = subfcns.substr (pos+1);
435 if (subfcns.empty ())
446 return m_scope.has_subfunctions ();
452 m_scope.stash_subfunction_names (names);
455 std::list<std::string>
458 return m_scope.subfunction_names ();
469 retval = args.
slice (m_num_named_args,
n);
483 tw.push_stack_frame (
this);
485 octave::unwind_action act ([&tw] () { tw.pop_stack_frame (); });
487 return execute (tw, nargout, args);
494 return tw.execute_user_function (*
this, nargout, args);
500 tw.visit_octave_user_function (*
this);
503 octave::tree_expression *
509 octave::tree_statement *stmt =
m_cmd_list->front ();
510 return stmt->expression ();
517 if (Voptimize_subsasgn_calls
518 && m_param_list && m_ret_list
519 && m_param_list->length () > 0 && ! m_param_list->varargs_only ()
520 && m_ret_list->length () == 1 && ! m_ret_list->takes_varargs ())
522 octave::tree_identifier *par1 = m_param_list->front ()->ident ();
523 octave::tree_identifier *ret1 = m_ret_list->front ()->ident ();
524 retval = par1->name () == ret1->name ();
531 octave_user_function::ctor_type_str ()
const
535 switch (m_class_constructor)
550 retval =
"unrecognized enum value";
558 octave_user_function::method_type_str ()
const
562 switch (m_class_method)
577 retval =
"unrecognized enum value";
587 std::map<std::string, octave_value>
m
589 {
"line", m_location_line },
590 {
"col", m_location_column },
591 {
"end_line", m_end_location_line },
592 {
"end_col", m_end_location_column },
593 {
"system_fcn_file", m_system_fcn_file },
594 {
"num_named_args", m_num_named_args },
595 {
"subfunction", m_subfunction },
596 {
"inline_function", m_inline_function },
597 {
"anonymous_function", m_anonymous_function },
598 {
"nested_function", m_nested_function },
599 {
"ctor_type", ctor_type_str () },
600 {
"class_method", m_class_method }
607 octave_user_function::print_code_function_header (
const std::string& prefix)
611 tpc.visit_octave_user_function_header (*
this);
615 octave_user_function::print_code_function_trailer (
const std::string& prefix)
619 tpc.visit_octave_user_function_trailer (*
this);
627 octave::tree_evaluator& tw = interp.get_evaluator ();
630 = tw.get_auto_fcn_var (octave::stack_frame::SAVED_WARNING_STATES);
642 Cell ids =
m.contents (
"identifier");
643 Cell states =
m.contents (
"state");
685 int nargin = args.length ();
703 error (
"nargin: invalid function name: %s", name.c_str ());
708 error (
"nargin: FCN must be a string or function handle");
717 std::string type = fcn_val->
type_name ();
718 error (
"nargin: number of input arguments unavailable for %s objects",
724 retval = (m_param_list ? m_param_list->
length () : 0);
726 retval = -1 - retval;
796 int nargin = args.length ();
814 error (
"nargout: invalid function name: %s", name.c_str ());
830 error (
"nargout: FCN must be a string or function handle");
839 std::string type = fcn_val->
type_name ();
840 error (
"nargout: number of output arguments unavailable for %s objects",
846 retval = (m_ret_list ? m_ret_list->
length () : 0);
849 retval = -1 - retval;
853 if (interp.at_top_level ())
854 error (
"nargout: invalid call at top level");
867 DEFUN (optimize_subsasgn_calls, args, nargout,
885 "optimize_subsasgn_calls");
889 val_in_table (
const Matrix& table,
double val)
895 return (i > 0 && table(i-1) == val);
899 isargout1 (
int nargout,
const Matrix& ignored,
double k)
902 error (
"isargout: K must be a positive integer");
904 return (k == 1 || k <= nargout) && ! val_in_table (ignored, k);
925 if (args.length () != 1)
928 if (interp.at_top_level ())
929 error (
"isargout: invalid call at top level");
945 if (args(0).is_scalar_type ())
947 double k = args(0).double_value ();
949 return ovl (isargout1 (nargout1, ignored, k));
951 else if (args(0).isnumeric ())
953 const NDArray ka = args(0).array_value ();
957 r(i) = isargout1 (nargout1, ignored, ka(i));
1048 OCTAVE_END_NAMESPACE(
octave)
octave_value_list Fwarning(octave::interpreter &, const octave_value_list &=octave_value_list(), int=0)
bool isempty() const
Size of the specified dimension.
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
octave_idx_type lookup(const T &value, sortmode mode=UNSORTED) const
Do a binary lookup in a sorted array.
octave_idx_type numel() const
Number of elements in the array.
std::size_t length() const
virtual octave_user_function * user_function_value(bool silent=false)
virtual std::string type_name() const
friend class octave_value
bool is_anonymous() const
std::string dispatch_class() const
bool is_class_method(const std::string &cname="") const
bool is_class_constructor(const std::string &cname="") const
virtual void mark_as_private_function(const std::string &cname="")
std::string get_code_line(std::size_t line)
octave::sys::time m_t_checked
std::string fcn_file_name() const
octave_value dump() const
std::deque< std::string > get_code_lines(std::size_t line, std::size_t num_lines)
virtual std::map< std::string, octave_value > subfunctions() const
octave::tree_statement_list * m_cmd_list
octave::sys::time m_t_parsed
octave::file_info * m_file_info
void cache_function_text(const std::string &text, const octave::sys::time ×tamp)
octave::symbol_scope m_scope
octave::sys::time time_parsed() const
std::list< std::string > subfunction_names() const
octave_value_list call(octave::tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())
bool is_inline_function() const
bool takes_varargs() const
bool is_special_expr() const
void stash_parent_fcn_scope(const octave::symbol_scope &ps)
void mark_as_system_fcn_file()
octave_user_function * define_ret_list(octave::tree_parameter_list *t)
std::string profiler_name() const
octave_value_list all_va_args(const octave_value_list &args)
void stash_subfunction_names(const std::list< std::string > &names)
bool is_classdef_constructor(const std::string &cname="") const
octave_value_list execute(octave::tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())
octave::tree_expression * special_expr()
octave::tree_parameter_list * parameter_list()
bool subsasgn_optimization_ok()
void mark_as_private_function(const std::string &cname="")
int beginning_column() const
std::string parent_fcn_name() const
bool is_anonymous_function() const
void unlock_subfunctions()
void erase_subfunctions()
void accept(octave::tree_walker &tw)
void restore_warning_states()
void maybe_relocate_end()
int beginning_line() const
octave_value find_subfunction(const std::string &subfuns) const
bool is_subfunction() const
bool has_subfunctions() const
std::map< std::string, octave_value > subfunctions() const
octave::tree_parameter_list * return_list()
bool takes_var_return() const
octave_user_function(const octave::symbol_scope &scope=octave::symbol_scope::anonymous(), octave::tree_parameter_list *pl=nullptr, octave::tree_parameter_list *rl=nullptr, octave::tree_statement_list *cl=nullptr)
octave_value dump() const
void accept(octave::tree_walker &tw)
octave_value_list call(octave::tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())
octave_value_list execute(octave::tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())
octave_value_list slice(octave_idx_type offset, octave_idx_type len, bool tags=false) const
octave_idx_type length() const
bool is_function_handle() const
bool is_undefined() const
bool is_inline_function() const
octave_user_function * user_function_value(bool silent=false) const
int int_value(bool req_int=false, bool frc_str_conv=false) const
octave_function * function_value(bool silent=false) const
octave_map map_value() const
octave_fcn_handle * fcn_handle_value(bool silent=false) const
std::string string_value(bool force=false) const
Matrix matrix_value(bool frc_str_conv=false) const
octave_value find_function(const std::string &name, const symbol_scope &search_scope=symbol_scope::invalid())
octave_value get_auto_fcn_var(stack_frame::auto_var_type avt) const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
std::string fcn_file_dir()
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void warning(const char *fmt,...)
void() error(const char *fmt,...)
#define panic_impossible()
#define panic_unless(cond)
void err_wrong_type_arg(const char *name, const char *s)
event_manager & __get_event_manager__()
interpreter & __get_interpreter__()
F77_RET_T const F77_DBLE const F77_DBLE * f
std::string fcn_file_dir()
std::string canonicalize_file_name(const std::string &name)
std::string fcn_file_in_path(const std::string &name)
octave_value set_internal_variable(bool &var, const octave_value_list &args, int nargout, const char *nm)
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.