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__ ();
110 warning (
"function file '%s' changed since it was parsed",
123std::deque<std::string>
134 const octave::sys::time& timestamp)
139 warning (
"help text for function is newer than function");
141 m_file_info =
new octave::file_info (text, timestamp);
144std::map<std::string, octave_value>
147 return std::map<std::string, octave_value> ();
153 std::map<std::string, octave_value> m
167 "user-defined script",
168 "user-defined script");
175(
const std::string& fnm,
const std::string& nm,
176 const octave::symbol_scope& scope, octave::tree_statement_list *cmds,
177 const std::string& ds)
185(
const std::string& fnm,
const std::string& nm,
186 const octave::symbol_scope& scope,
const std::string& ds)
199 tw.push_stack_frame (
this);
201 octave::unwind_action act ([&tw] () { tw.pop_stack_frame (); });
203 return execute (tw, nargout, args);
210 return tw.execute_user_script (*
this, nargout, args);
216 tw.visit_octave_user_script (*
this);
222 "user-defined function",
223 "user-defined function");
229 :
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)
245 std::ostringstream buf;
247 octave::tree_print_code tpc (buf);
251 m_ret_list->accept (tpc);
258 m_param_list->accept (tpc);
278 octave::tree_statement *last_stmt =
m_cmd_list->back ();
280 octave::tree_command *cmd = last_stmt->command ();
282 octave::tree_no_op_command *no_op_cmd =
dynamic_cast <octave::tree_no_op_command *
> (cmd);
284 if (no_op_cmd && (no_op_cmd->is_end_of_fcn_or_script () || no_op_cmd->is_end_of_file ()))
285 no_op_cmd->attach_trailing_comments (lst);
293 octave::tree_statement *last_stmt =
m_cmd_list->back ();
295 octave::tree_command *cmd = last_stmt->command ();
297 octave::tree_no_op_command *no_op_cmd =
dynamic_cast <octave::tree_no_op_command *
> (cmd);
299 if (no_op_cmd && (no_op_cmd->is_end_of_fcn_or_script () || no_op_cmd->is_end_of_file ()))
300 return no_op_cmd->trailing_comments ();
303 return octave::comment_list ();
312octave_user_function::maybe_relocate_end_internal ()
315 if (m_anonymous_function)
320 octave::tree_statement *last_stmt =
m_cmd_list->back ();
322 if (last_stmt && last_stmt->is_end_of_fcn_or_script ()
323 && last_stmt->is_end_of_file ())
325 octave::tree_statement_list::reverse_iterator next_to_last_elt =
m_cmd_list->rbegin ();
328 octave::filepos new_eof_pos;
342 new_eof_pos = m_param_list->end_pos ();
344 new_eof_pos = m_id->end_pos ();
350 octave::tree_statement *next_to_last_stmt = *next_to_last_elt;
352 new_eof_pos = next_to_last_stmt->end_pos ();
355 last_stmt->update_end_pos (new_eof_pos);
363 std::map<std::string, octave_value> fcns =
subfunctions ();
367 for (
auto& nm_fnval : fcns)
372 f->maybe_relocate_end_internal ();
376 maybe_relocate_end_internal ();
388 std::ostringstream result;
390 octave::filepos bp =
beg_pos ();
392 int bp_line = bp.line ();
393 int bp_column = bp.column ();
397 <<
':' << bp_line <<
':' << bp_column;
403 result <<
'@' <<
name ();
406 <<
':' << bp_line <<
':' << bp_column;
410 return result.str ();
427 std::string ff_name = octave::fcn_file_in_path (
m_file_name);
429 static const std::string canonical_fcn_file_dir
430 = octave::sys::canonicalize_file_name
431 (octave::config::fcn_file_dir ());
433 = canonical_fcn_file_dir.empty () ? octave::config::fcn_file_dir ()
434 : canonical_fcn_file_dir;
437 m_system_fcn_file =
true;
440 m_system_fcn_file =
false;
452 return (m_param_list && m_param_list->takes_varargs ());
458 return (m_ret_list && m_ret_list->takes_varargs ());
464 m_scope.mark_subfunctions_in_scope_as_private (cname);
478 m_scope.unlock_subfunctions ();
481std::map<std::string, octave_value>
484 return m_scope.subfunctions ();
494 std::string subfcns = subfcns_arg;
496 std::string first_fcn = subfcns;
498 std::size_t pos = subfcns.find (
'>');
500 if (pos == std::string::npos)
504 first_fcn = subfcns.substr (0, pos-1);
505 subfcns = subfcns.substr (pos+1);
510 if (subfcns.empty ())
521 return m_scope.has_subfunctions ();
527 m_scope.stash_subfunction_names (names);
530std::list<std::string>
533 return m_scope.subfunction_names ();
544 retval = args.
slice (m_num_named_args, n);
558 tw.push_stack_frame (
this);
560 octave::unwind_action act ([&tw] () { tw.pop_stack_frame (); });
562 return execute (tw, nargout, args);
569 return tw.execute_user_function (*
this, nargout, args);
575 tw.visit_octave_user_function (*
this);
578octave::tree_expression *
584 octave::tree_statement *stmt =
m_cmd_list->front ();
585 return stmt->expression ();
592 if (Voptimize_subsasgn_calls
593 && m_param_list && m_ret_list
594 && m_param_list->size () > 0 && ! m_param_list->varargs_only ()
595 && m_ret_list->size () == 1 && ! m_ret_list->takes_varargs ())
597 octave::tree_identifier *par1 = m_param_list->front ()->ident ();
598 octave::tree_identifier *ret1 = m_ret_list->front ()->ident ();
599 retval = par1->name () == ret1->name ();
606octave_user_function::ctor_type_str ()
const
610 switch (m_class_constructor)
625 retval =
"unrecognized enum value";
633octave_user_function::method_type_str ()
const
637 switch (m_class_method)
652 retval =
"unrecognized enum value";
662 octave::filepos bp =
beg_pos ();
663 octave::filepos ep =
end_pos ();
665 std::map<std::string, octave_value> m
667 {
"line", bp.line () },
668 {
"col", bp.column () },
669 {
"end_line", ep.line () },
670 {
"end_col", ep.column () },
671 {
"system_fcn_file", m_system_fcn_file },
672 {
"num_named_args", m_num_named_args },
673 {
"subfunction", m_subfunction },
674 {
"inline_function", m_inline_function },
675 {
"anonymous_function", m_anonymous_function },
676 {
"nested_function", m_nested_function },
677 {
"ctor_type", ctor_type_str () },
678 {
"class_method", m_class_method }
685octave_user_function::print_code_function_header (
const std::string& prefix)
689 tpc.visit_octave_user_function_header (*
this);
693octave_user_function::print_code_function_trailer (
const std::string& prefix)
697 tpc.visit_octave_user_function_trailer (*
this);
703 octave::interpreter& interp = octave::__get_interpreter__ ();
705 octave::tree_evaluator& tw = interp.get_evaluator ();
708 = tw.get_auto_fcn_var (octave::stack_frame::SAVED_WARNING_STATES);
716 error (
"unexpected: SAVED_WARNING_STATES is not a struct in octave_user_function::restore_warning_states - please report this bug");
763 int nargin = args.
length ();
781 error (
"nargin: invalid function name: %s", name.c_str ());
786 error (
"nargin: FCN must be a string or function handle");
795 std::string type = fcn_val->
type_name ();
796 error (
"nargin: number of input arguments unavailable for %s objects",
802 retval = (m_param_list ? m_param_list->size () : 0);
804 retval = -1 - retval;
874 int nargin = args.
length ();
892 error (
"nargout: invalid function name: %s", name.c_str ());
908 error (
"nargout: FCN must be a string or function handle");
917 std::string type = fcn_val->
type_name ();
918 error (
"nargout: number of output arguments unavailable for %s objects",
924 retval = (m_ret_list ? m_ret_list->size () : 0);
927 retval = -1 - retval;
931 if (interp.at_top_level ())
932 error (
"nargout: invalid call at top level");
945DEFUN (optimize_subsasgn_calls, args, nargout,
963 "optimize_subsasgn_calls");
967val_in_table (
const Matrix& table,
double val)
973 return (i > 0 && table(i-1) == val);
977isargout1 (
int nargout,
const Matrix& ignored,
double k)
979 if (k != math::fix (k) || k <= 0)
980 error (
"isargout: K must be a positive integer");
982 return (k == 1 || k <= nargout) && ! val_in_table (ignored, k);
1003 if (args.length () != 1)
1006 if (interp.at_top_level ())
1007 error (
"isargout: invalid call at top level");
1023 if (args(0).is_scalar_type ())
1025 double k = args(0).double_value ();
1027 return ovl (isargout1 (nargout1, ignored, k));
1029 else if (args(0).isnumeric ())
1031 const NDArray ka = args(0).array_value ();
1035 r(i) = isargout1 (nargout1, ignored, ka(i));
1126OCTAVE_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::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
octave::tree_parameter_list * parameter_list()
octave::comment_list trailing_comments() 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()
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)
F77_RET_T const F77_DBLE const F77_DBLE * f
#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)
octave_value set_internal_variable(bool &var, const octave_value_list &args, int nargout, const char *nm)