26#if defined (HAVE_CONFIG_H)
39#include "builtin-defun-decls.h"
70static bool Voptimize_subsasgn_calls =
true;
78 m_scope.set_user_code (
nullptr);
83 octave::event_manager& evmgr = octave::__get_event_manager__ ();
111 octave::tree_statement *last_stmt =
m_cmd_list->back ();
113 octave::tree_command *cmd = last_stmt->command ();
115 octave::tree_no_op_command *no_op_cmd =
dynamic_cast<octave::tree_no_op_command *
> (cmd);
117 if (no_op_cmd && (no_op_cmd->is_end_of_fcn_or_script () || no_op_cmd->is_end_of_file ()))
118 return no_op_cmd->trailing_comments ();
121 return octave::comment_list ();
132 warning (
"function file '%s' changed since it was parsed",
145std::deque<std::string>
156 const octave::sys::time& timestamp)
161 warning (
"help text for function is newer than function");
163 m_file_info =
new octave::file_info (text, timestamp);
166std::map<std::string, octave_value>
169 return std::map<std::string, octave_value> ();
175 std::map<std::string, octave_value> m
189 "user-defined script",
190 "user-defined script");
197(
const std::string& fnm,
const std::string& nm,
198 const octave::symbol_scope& scope, octave::tree_statement_list *cmds,
199 const std::string& ds)
207(
const std::string& fnm,
const std::string& nm,
208 const octave::symbol_scope& scope,
const std::string& ds)
221 tw.push_stack_frame (
this);
223 octave::unwind_action act ([&tw] () { tw.pop_stack_frame (); });
225 return execute (tw, nargout, args);
232 return tw.execute_user_script (*
this, nargout, args);
238 tw.visit_octave_user_script (*
this);
244 "user-defined function",
245 "user-defined function");
251 :
octave_user_code (
"",
"", scope, cl,
""), m_id (id), m_param_list (pl), m_ret_list (rl), m_num_named_args (m_param_list ? m_param_list->size () : 0)
267 std::ostringstream buf;
269 octave::tree_print_code tpc (buf);
273 m_ret_list->accept (tpc);
280 m_param_list->accept (tpc);
300 octave::tree_statement *last_stmt =
m_cmd_list->back ();
302 octave::tree_command *cmd = last_stmt->command ();
304 octave::tree_no_op_command *no_op_cmd =
dynamic_cast<octave::tree_no_op_command *
> (cmd);
306 if (no_op_cmd && (no_op_cmd->is_end_of_fcn_or_script () || no_op_cmd->is_end_of_file ()))
307 no_op_cmd->attach_trailing_comments (lst);
317octave_user_function::maybe_relocate_end_internal ()
320 if (m_anonymous_function)
325 octave::tree_statement *last_stmt =
m_cmd_list->back ();
327 if (last_stmt && last_stmt->is_end_of_fcn_or_script ()
328 && last_stmt->is_end_of_file ())
330 octave::tree_statement_list::reverse_iterator next_to_last_elt =
m_cmd_list->rbegin ();
333 octave::filepos new_eof_pos;
347 new_eof_pos = m_param_list->end_pos ();
349 new_eof_pos = m_id->end_pos ();
355 octave::tree_statement *next_to_last_stmt = *next_to_last_elt;
357 new_eof_pos = next_to_last_stmt->end_pos ();
360 last_stmt->update_end_pos (new_eof_pos);
368 std::map<std::string, octave_value> fcns =
subfunctions ();
372 for (
auto& nm_fnval : fcns)
377 f->maybe_relocate_end_internal ();
381 maybe_relocate_end_internal ();
393 std::ostringstream result;
395 octave::filepos bp =
beg_pos ();
397 int bp_line = bp.line ();
398 int bp_column = bp.column ();
402 <<
':' << bp_line <<
':' << bp_column;
408 result <<
'@' <<
name ();
411 <<
':' << bp_line <<
':' << bp_column;
415 return result.str ();
432 std::string ff_name = octave::fcn_file_in_path (
m_file_name);
434 static const std::string canonical_fcn_file_dir
435 = octave::sys::canonicalize_file_name
436 (octave::config::fcn_file_dir ());
438 = canonical_fcn_file_dir.empty () ? octave::config::fcn_file_dir ()
439 : canonical_fcn_file_dir;
442 m_system_fcn_file =
true;
445 m_system_fcn_file =
false;
457 return (m_param_list && m_param_list->takes_varargs ());
463 return (m_ret_list && m_ret_list->takes_varargs ());
469 m_scope.mark_subfunctions_in_scope_as_private (cname);
483 m_scope.unlock_subfunctions ();
486std::map<std::string, octave_value>
489 return m_scope.subfunctions ();
499 std::string subfcns = subfcns_arg;
501 std::string first_fcn = subfcns;
503 std::size_t pos = subfcns.find (
'>');
505 if (pos == std::string::npos)
509 first_fcn = subfcns.substr (0, pos-1);
510 subfcns = subfcns.substr (pos+1);
515 if (subfcns.empty ())
526 return m_scope.has_subfunctions ();
532 m_scope.stash_subfunction_names (names);
535std::list<std::string>
538 return m_scope.subfunction_names ();
549 retval = args.
slice (m_num_named_args, n);
563 tw.push_stack_frame (
this);
565 octave::unwind_action act ([&tw] () { tw.pop_stack_frame (); });
567 return execute (tw, nargout, args);
574 return tw.execute_user_function (*
this, nargout, args);
580 tw.visit_octave_user_function (*
this);
583octave::tree_expression *
589 octave::tree_statement *stmt =
m_cmd_list->front ();
590 return stmt->expression ();
597 if (Voptimize_subsasgn_calls
598 && m_param_list && m_ret_list
599 && m_param_list->size () > 0 && ! m_param_list->varargs_only ()
600 && m_ret_list->size () == 1 && ! m_ret_list->takes_varargs ())
602 octave::tree_identifier *par1 = m_param_list->front ()->ident ();
603 octave::tree_identifier *ret1 = m_ret_list->front ()->ident ();
604 retval = par1->name () == ret1->name ();
611octave_user_function::ctor_type_str ()
const
615 switch (m_class_constructor)
630 retval =
"unrecognized enum value";
638octave_user_function::method_type_str ()
const
642 switch (m_class_method)
657 retval =
"unrecognized enum value";
667 octave::filepos bp =
beg_pos ();
668 octave::filepos ep =
end_pos ();
670 std::map<std::string, octave_value> m
672 {
"line", bp.line () },
673 {
"col", bp.column () },
674 {
"end_line", ep.line () },
675 {
"end_col", ep.column () },
676 {
"system_fcn_file", m_system_fcn_file },
677 {
"num_named_args", m_num_named_args },
678 {
"subfunction", m_subfunction },
679 {
"inline_function", m_inline_function },
680 {
"anonymous_function", m_anonymous_function },
681 {
"nested_function", m_nested_function },
682 {
"ctor_type", ctor_type_str () },
683 {
"class_method", m_class_method }
690octave_user_function::print_code_function_header (
const std::string& prefix)
694 tpc.visit_octave_user_function_header (*
this);
698octave_user_function::print_code_function_trailer (
const std::string& prefix)
702 tpc.visit_octave_user_function_trailer (*
this);
708 octave::interpreter& interp = octave::__get_interpreter__ ();
710 octave::tree_evaluator& tw = interp.get_evaluator ();
713 = tw.get_auto_fcn_var (octave::stack_frame::SAVED_WARNING_STATES);
721 error (
"unexpected: SAVED_WARNING_STATES is not a struct in octave_user_function::restore_warning_states - please report this bug");
768 int nargin = args.
length ();
786 error (
"nargin: invalid function name: %s", name.c_str ());
791 error (
"nargin: FCN must be a string or function handle");
800 std::string type = fcn_val->
type_name ();
801 error (
"nargin: number of input arguments unavailable for %s objects",
807 retval = (m_param_list ? m_param_list->size () : 0);
809 retval = -1 - retval;
879 int nargin = args.
length ();
897 error (
"nargout: invalid function name: %s", name.c_str ());
913 error (
"nargout: FCN must be a string or function handle");
922 std::string type = fcn_val->
type_name ();
923 error (
"nargout: number of output arguments unavailable for %s objects",
929 retval = (m_ret_list ? m_ret_list->size () : 0);
932 retval = -1 - retval;
936 if (interp.at_top_level ())
937 error (
"nargout: invalid call at top level");
950DEFUN (optimize_subsasgn_calls, args, nargout,
968 "optimize_subsasgn_calls");
972val_in_table (
const Matrix& table,
double val)
978 return (i > 0 && table(i-1) == val);
982isargout1 (
int nargout,
const Matrix& ignored,
double k)
984 if (k != math::fix (k) || k <= 0)
985 error (
"isargout: K must be a positive integer");
987 return (k == 1 || k <= nargout) && ! val_in_table (ignored, k);
1008 if (args.length () != 1)
1011 if (interp.at_top_level ())
1012 error (
"isargout: invalid call at top level");
1028 if (args(0).is_scalar_type ())
1030 double k = args(0).double_value ();
1032 return ovl (isargout1 (nargout1, ignored, k));
1034 else if (args(0).isnumeric ())
1036 const NDArray ka = args(0).array_value ();
1040 r(i) = isargout1 (nargout1, ignored, ka(i));
1131OCTAVE_END_NAMESPACE(octave)
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
bool isempty() const
Size of the specified dimension.
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.
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="")
const Cell & contents(const_iterator p) const
octave_idx_type numel() const
octave::filepos end_pos() const
octave::filepos beg_pos() const
std::string get_code_line(std::size_t line)
octave::comment_list leading_comments() const
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::comment_list trailing_comments() const
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
octave::tree_parameter_list * parameter_list()
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()
bool subsasgn_optimization_ok()
void mark_as_private_function(const std::string &cname="")
octave::tree_parameter_list * return_list()
std::string parent_fcn_name() const
octave_user_function * user_function_value(bool=false)
bool is_anonymous_function() const
void unlock_subfunctions()
void erase_subfunctions()
void accept(octave::tree_walker &tw)
std::string signature() const
void restore_warning_states()
void maybe_relocate_end()
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_user_function(const octave::symbol_scope &scope=octave::symbol_scope::anonymous(), octave::tree_identifier *id=nullptr, octave::tree_parameter_list *pl=nullptr, octave::tree_parameter_list *rl=nullptr, octave::tree_statement_list *cl=nullptr)
bool takes_var_return() const
void attach_trailing_comments(const octave::comment_list &lst)
octave::filepos beg_pos() const
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_function * function_value(bool silent=false) const
int int_value(bool req_int=false, bool frc_str_conv=false) const
octave_value dump() const
octave_map map_value() const
std::string string_value(bool force=false) const
octave_fcn_handle * fcn_handle_value(bool silent=false) const
octave_idx_type length() const
octave_user_function * user_function_value(bool silent=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,...)
octave_value_list Fwarning(octave::interpreter &interp, const octave_value_list &args, int nargout)
void error(const char *fmt,...)
void err_wrong_type_arg(const char *name, const char *s)
#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.
#define panic_unless(cond)
F77_RET_T const F77_DBLE const F77_DBLE * f
octave_value set_internal_variable(bool &var, const octave_value_list &args, int nargout, const char *nm)