26#if defined (HAVE_CONFIG_H)
61static void display_scope (std::ostream& os,
const symbol_scope& scope)
65 os <<
"scope: " << scope.
name () << std::endl;
69 os <<
"name (frame offset, data offset, storage class):"
72 std::list<symbol_record> symbols = scope.
symbol_list ();
74 for (
auto& sym : symbols)
76 os <<
" " << sym.name () <<
" (" << sym.frame_offset ()
77 <<
", " << sym.data_offset () <<
", " << sym.storage_class ()
84class compiled_fcn_stack_frame;
85class script_stack_frame;
86class user_fcn_stack_frame;
87class scope_stack_frame;
89class stack_frame_walker
93 stack_frame_walker () { }
95 virtual ~stack_frame_walker () =
default;
99 OCTAVE_DISABLE_COPY_MOVE (stack_frame_walker)
102 visit_compiled_fcn_stack_frame (compiled_fcn_stack_frame&) = 0;
105 visit_script_stack_frame (script_stack_frame&) = 0;
108 visit_user_fcn_stack_frame (user_fcn_stack_frame&) = 0;
111 visit_scope_stack_frame (scope_stack_frame&) = 0;
118 compiled_fcn_stack_frame () =
delete;
129 compiled_fcn_stack_frame (
const compiled_fcn_stack_frame& elt) =
default;
131 compiled_fcn_stack_frame&
132 operator = (
const compiled_fcn_stack_frame& elt) =
delete;
134 ~compiled_fcn_stack_frame () =
default;
136 bool is_compiled_fcn_frame ()
const {
return true; }
195 std::string inputname (
int n,
bool ids_only)
const
211 void display (
bool follow =
true)
const;
213 void accept (stack_frame_walker& sfw);
247 script_stack_frame () =
delete;
254 script_stack_frame (
const script_stack_frame& elt) =
default;
256 script_stack_frame& operator = (
const script_stack_frame& elt) =
delete;
258 ~script_stack_frame ()
260 delete m_unwind_protect_frame;
263 bool is_user_script_frame ()
const {
return true; }
265 static std::shared_ptr<stack_frame>
266 get_access_link (
const std::shared_ptr<stack_frame>&
static_link);
270 void set_script_offsets ();
272 void set_script_offsets_internal (
const std::map<std::string,
275 void resize_and_update_script_offsets (
const symbol_record& sym);
277 symbol_scope get_scope ()
const {
return m_script->scope (); }
287 std::size_t size ()
const {
return m_lexical_frame_offsets.size (); }
289 void resize (std::size_t size)
291 m_lexical_frame_offsets.resize (size, 0);
292 m_value_offsets.resize (size, 0);
296 std::size_t& frame_offset,
297 std::size_t& data_offset);
300 std::size_t& frame_offset,
301 std::size_t& data_offset)
const;
303 bool get_val_offsets (
const symbol_record& sym, std::size_t& frame_offset,
304 std::size_t& data_offset)
const;
328 std::string inputname (
int n,
bool ids_only)
const
335 void display (
bool follow =
true)
const;
337 void accept (stack_frame_walker& sfw);
354 std::vector<std::size_t> m_lexical_frame_offsets;
355 std::vector<std::size_t> m_value_offsets;
365 base_value_stack_frame () =
delete;
367 base_value_stack_frame (
tree_evaluator& tw, std::size_t num_symbols,
374 m_flags (num_symbols,
LOCAL),
378 base_value_stack_frame (
const base_value_stack_frame& elt) =
default;
380 base_value_stack_frame&
381 operator = (
const base_value_stack_frame& elt) =
delete;
383 ~base_value_stack_frame ()
393 for (
auto auto_vars_iter = m_auto_vars.begin ();
394 auto_vars_iter != m_auto_vars.end ();)
395 auto_vars_iter = m_auto_vars.erase (auto_vars_iter);
397 for (
auto values_iter = m_values.begin ();
398 values_iter != m_values.end ();)
399 values_iter = m_values.erase (values_iter);
402 std::size_t size ()
const
404 return m_values.
size ();
407 void resize (std::size_t size)
410 m_flags.resize (size,
LOCAL);
415 return m_flags.at (data_offset);
418 void set_scope_flag (std::size_t data_offset,
scope_flags flag)
420 m_flags.at (data_offset) = flag;
425 return m_auto_vars.at (avt);
430 m_auto_vars.at (avt) = val;
441 return m_values.at (data_offset);
446 return m_values.at (data_offset);
449 void display (
bool follow =
true)
const;
456 std::vector<octave_value> m_values;
465 std::vector<scope_flags> m_flags;
470 std::vector<octave_value> m_auto_vars;
484class user_fcn_stack_frame :
public base_value_stack_frame
488 user_fcn_stack_frame () =
delete;
494 const std::shared_ptr<stack_frame>&
access_link = std::shared_ptr<stack_frame> ())
495 : base_value_stack_frame (tw, get_num_symbols (fcn),
index,
500 m_fcn (fcn), m_unwind_protect_frame (nullptr)
508 const std::shared_ptr<stack_frame>&
access_link = std::shared_ptr<stack_frame> ())
509 : base_value_stack_frame (tw, get_num_symbols (fcn),
index,
514 m_fcn (fcn), m_unwind_protect_frame (nullptr)
518 for (
const auto& nm_ov : local_vars)
519 assign (nm_ov.first, nm_ov.second);
522 user_fcn_stack_frame (
const user_fcn_stack_frame& elt) =
default;
524 user_fcn_stack_frame&
525 operator = (
const user_fcn_stack_frame& elt) =
delete;
527 ~user_fcn_stack_frame ()
529 delete m_unwind_protect_frame;
532 bool is_user_fcn_frame ()
const {
return true; }
534 static std::shared_ptr<stack_frame>
545 void clear_values ();
547 symbol_scope get_scope ()
const {
return m_fcn->scope (); }
562 using base_value_stack_frame::varval;
563 using base_value_stack_frame::varref;
569 std::string inputname (
int n,
bool ids_only)
const;
573 void display (
bool follow =
true)
const;
575 void accept (stack_frame_walker& sfw);
577 void break_closure_cycles (
const std::shared_ptr<stack_frame>& frame);
597class scope_stack_frame :
public base_value_stack_frame
601 scope_stack_frame () =
delete;
607 : base_value_stack_frame (tw, scope.num_symbols (),
index,
612 scope_stack_frame (
const scope_stack_frame& elt) =
default;
614 scope_stack_frame& operator = (
const scope_stack_frame& elt) =
delete;
616 ~scope_stack_frame () =
default;
618 bool is_scope_frame ()
const {
return true; }
624 return m_scope.lookup_symbol (name);
634 using base_value_stack_frame::varval;
635 using base_value_stack_frame::varref;
641 std::string inputname (
int,
bool)
const
644 error (
"invalid call to inputname outside of a function");
651 void display (
bool follow =
true)
const;
653 void accept (stack_frame_walker& sfw);
661class symbol_cleaner :
public stack_frame_walker
665 symbol_cleaner (
const std::string& pattern,
bool have_regexp =
false)
666 : stack_frame_walker (), m_patterns (pattern),
667 m_clear_all_names (false), m_clear_objects (false),
668 m_have_regexp (have_regexp), m_cleared_names ()
671 symbol_cleaner (
const string_vector& patterns,
bool have_regexp =
false)
672 : stack_frame_walker (), m_patterns (patterns),
673 m_clear_all_names (false), m_clear_objects (false),
674 m_have_regexp (have_regexp), m_cleared_names ()
677 symbol_cleaner (
bool clear_all_names =
true,
bool clear_objects =
false)
678 : stack_frame_walker (), m_patterns (),
679 m_clear_all_names (clear_all_names), m_clear_objects (clear_objects),
680 m_have_regexp (false), m_cleared_names ()
683 OCTAVE_DISABLE_COPY_MOVE (symbol_cleaner)
685 ~symbol_cleaner () =
default;
687 void visit_compiled_fcn_stack_frame (compiled_fcn_stack_frame& frame)
693 std::shared_ptr<stack_frame> slink = frame.static_link ();
696 slink->accept (*
this);
699 void visit_script_stack_frame (script_stack_frame& frame)
701 std::shared_ptr<stack_frame> alink = frame.access_link ();
704 alink->accept (*
this);
707 void visit_user_fcn_stack_frame (user_fcn_stack_frame& frame)
711 std::shared_ptr<stack_frame> alink = frame.access_link ();
714 alink->accept (*
this);
717 void visit_scope_stack_frame (scope_stack_frame& frame)
721 std::shared_ptr<stack_frame> alink = frame.access_link ();
724 alink->accept (*
this);
731 std::string name = sym.
name ();
733 if (m_cleared_names.find (name) == m_cleared_names.end ())
743 if (m_clear_objects && ! frame.
is_object (sym))
746 m_cleared_names.insert (name);
756 const std::list<symbol_record>& symbols)
758 if (m_clear_all_names)
760 for (
const auto& sym : symbols)
761 maybe_clear_symbol (frame, sym);
763 else if (m_have_regexp)
769 std::string pattern = m_patterns[j];
773 for (
const auto& sym : symbols)
775 if (pat.is_match (sym.
name ()))
776 maybe_clear_symbol (frame, sym);
786 std::string pattern = m_patterns[j];
790 for (
const auto& sym : symbols)
792 if (pat.match (sym.
name ()))
793 maybe_clear_symbol (frame, sym);
803 std::list<symbol_record> symbols = scope.
symbol_list ();
805 if (m_clear_all_names || ! m_patterns.empty ())
806 clear_symbols (frame, symbols);
811 bool m_clear_all_names;
812 bool m_clear_objects;
815 std::set<std::string> m_cleared_names;
818class symbol_info_accumulator :
public stack_frame_walker
822 symbol_info_accumulator (
const std::string& pattern,
823 bool have_regexp =
false)
824 : stack_frame_walker (), m_patterns (pattern), m_match_all (false),
825 m_first_only (false), m_have_regexp (have_regexp), m_sym_inf_list (),
830 bool have_regexp =
false)
831 : stack_frame_walker (), m_patterns (patterns), m_match_all (false),
832 m_first_only (false), m_have_regexp (have_regexp), m_sym_inf_list (),
836 symbol_info_accumulator (
bool match_all =
true,
bool first_only =
true)
837 : stack_frame_walker (), m_patterns (), m_match_all (match_all),
838 m_first_only (first_only), m_have_regexp (false),
839 m_sym_inf_list (), m_found_names ()
842 OCTAVE_DISABLE_COPY_MOVE (symbol_info_accumulator)
844 ~symbol_info_accumulator () =
default;
846 bool is_empty ()
const
848 for (
const auto& nm_sil : m_sym_inf_list)
859 std::list<std::string> names ()
const
861 std::list<std::string> retval;
863 for (
const auto& nm_sil : m_sym_inf_list)
867 std::list<std::string> nm_list = lst.
names ();
869 for (
const auto& nm : nm_list)
870 retval.push_back (nm);
880 for (
const auto& nm_sil : m_sym_inf_list)
884 for (
const auto& syminf : lst)
885 retval.push_back (syminf);
897 std::size_t n_frames = m_sym_inf_list.size ();
902 for (
const auto& nm_sil : m_sym_inf_list)
904 std::string scope_name = nm_sil.first;
907 map_list[j] = lst.
map_value (scope_name, n_frames-j);
915 void display (std::ostream& os,
const std::string&
format)
const
917 for (
const auto& nm_sil : m_sym_inf_list)
919 os <<
"\nvariables in scope: " << nm_sil.first <<
"\n\n";
927 void visit_compiled_fcn_stack_frame (compiled_fcn_stack_frame& frame)
933 std::shared_ptr<stack_frame> slink = frame.static_link ();
936 slink->accept (*
this);
939 void visit_script_stack_frame (script_stack_frame& frame)
941 std::shared_ptr<stack_frame> alink = frame.access_link ();
944 alink->accept (*
this);
947 void visit_user_fcn_stack_frame (user_fcn_stack_frame& frame)
951 std::shared_ptr<stack_frame> alink = frame.access_link ();
954 alink->accept (*
this);
957 void visit_scope_stack_frame (scope_stack_frame& frame)
961 std::shared_ptr<stack_frame> alink = frame.access_link ();
964 alink->accept (*
this);
969 typedef std::pair<std::string, symbol_info_list> syminf_list_elt;
975 std::list<symbol_record>
978 std::list<symbol_record> new_symbols;
982 for (
const auto& sym : symbols)
986 std::string name = sym.
name ();
989 && m_found_names.find (name) != m_found_names.end ())
992 m_found_names.insert (name);
994 new_symbols.push_back (sym);
998 else if (m_have_regexp)
1004 std::string pattern = m_patterns[j];
1008 for (
const auto& sym : symbols)
1010 std::string name = sym.
name ();
1012 if (pat.is_match (name) && frame.
is_defined (sym))
1015 && m_found_names.find (name) != m_found_names.end ())
1018 m_found_names.insert (name);
1020 new_symbols.push_back (sym);
1031 std::string pattern = m_patterns[j];
1035 for (
const auto& sym : symbols)
1037 std::string name = sym.
name ();
1039 if (pat.match (name) && frame.
is_defined (sym))
1042 && m_found_names.find (name) == m_found_names.end ())
1045 m_found_names.insert (name);
1047 new_symbols.push_back (sym);
1060 std::list<symbol_record> symbols = scope.
symbol_list ();
1062 if (m_match_all || ! m_patterns.empty ())
1063 symbols =
filter (frame, symbols);
1067 m_sym_inf_list.push_back (syminf_list_elt (scope.
name (), syminf_list));
1076 std::list<std::pair<std::string, symbol_info_list>> m_sym_inf_list;
1078 std::set<std::string> m_found_names;
1084 const std::shared_ptr<stack_frame>& parent_link,
1085 const std::shared_ptr<stack_frame>& static_link)
1087 return new compiled_fcn_stack_frame (tw, fcn,
index,
1095 const std::shared_ptr<stack_frame>& parent_link,
1096 const std::shared_ptr<stack_frame>& static_link)
1104 const std::shared_ptr<stack_frame>& parent_link,
1105 const std::shared_ptr<stack_frame>& static_link,
1106 const std::shared_ptr<stack_frame>& access_link)
1108 return new user_fcn_stack_frame (tw, fcn,
index,
1115 const std::shared_ptr<stack_frame>& parent_link,
1116 const std::shared_ptr<stack_frame>& static_link,
1118 const std::shared_ptr<stack_frame>& access_link)
1120 return new user_fcn_stack_frame (tw, fcn,
index,
1128 const std::shared_ptr<stack_frame>& parent_link,
1129 const std::shared_ptr<stack_frame>& static_link)
1141 warning (
"invalid call to stack_frame::clear_values; please report");
1149 for (
const auto& sym : symrec_list)
1160 symbol_stats.push_back (syminf);
1163 return symbol_stats;
1168 bool have_regexp,
bool return_list,
1169 bool verbose,
const std::string& whos_line_fmt,
1170 const std::string& msg)
1172 symbol_info_accumulator sym_inf_accum (patterns, have_regexp);
1179 return sym_inf_accum.map_value ();
1183 else if (! sym_inf_accum.is_empty ())
1187 octave_stdout <<
"Variables visible from the current scope:\n";
1212 symbol_info_accumulator sia (
true,
true);
1216 return sia.symbol_info ();
1222 std::list<octave_scalar_map> ws_list;
1232 for (
const auto& sym_name : symbols.
names ())
1237 ws.
assign (sym_name, val);
1240 ws_list.push_back (ws);
1242 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
1246 Cell ws_frames (ws_list.size (), 1);
1249 for (
const auto& elt : ws_list)
1250 ws_frames(i++) = elt;
1258std::list<std::string>
1261 std::list<std::string> retval;
1265 const std::map<std::string, symbol_record>& symbols = scope.
symbols ();
1267 for (
const auto& nm_sr : symbols)
1270 retval.push_back (nm_sr.first);
1281 symbol_info_accumulator sia (pattern,
false);
1285 return sia.symbol_info ();
1291 symbol_info_accumulator sia (pattern,
true);
1295 return sia.symbol_info ();
1305 error (
"unexpected call to stack_frame::size () - please report this bug");
1315 error (
"unexpected call to stack_frame::resize () - please report this bug");
1325 error (
"unexpected call to stack_frame::get_scope_flag (std::size_t) - please report this bug");
1335 error (
"unexpected call to stack_frame::get_scope_flag (std::size_t, scope_flags) - please report this bug");
1348 std::string nm = sym.
name ();
1351 "global: '%s' is defined in the current scope.\n",
1354 "global: in a future version, global variables must be declared before use.\n");
1365 "global: global value overrides existing local value");
1372 "global: existing local value used to initialize global variable");
1392 error (
"unexpected call to stack_frame::varval (std::size_t) - please report this bug");
1402 error (
"unexpected call to stack_frame::varref (std::size_t) - please report this bug");
1411 error (
"unexpected call to stack_frame::inputname (int, bool) - please report this bug");
1417 symbol_cleaner sc (
true,
true);
1425 symbol_cleaner sc (name);
1433 symbol_cleaner sc (pattern);
1441 symbol_cleaner sc (patterns);
1449 symbol_cleaner sc (pattern,
true);
1457 symbol_cleaner sc (patterns,
true);
1474 os <<
"at top level" << std::endl;
1477 os <<
"stopped in " <<
fcn_name ();
1481 os <<
" at line " <<
line ();
1492 int target_line =
line ();
1493 int start = std::max (target_line - num_lines/2, 0);
1494 int end = target_line + num_lines/2;
1510 os <<
"-- [stack_frame] (" <<
this <<
") --" << std::endl;
1512 os <<
"parent link: ";
1519 os <<
"static link: ";
1526 os <<
"access link: ";
1533 os <<
"line: " <<
m_line << std::endl;
1534 os <<
"column: " <<
m_column << std::endl;
1535 os <<
"index: " <<
m_index << std::endl;
1542 os <<
"FOLLOWING ACCESS LINKS:" << std::endl;
1543 std::shared_ptr<stack_frame> frm =
access_link ();
1546 frm->display (
false);
1549 frm = frm->access_link ();
1554compiled_fcn_stack_frame::display (
bool follow)
const
1558 os <<
"-- [compiled_fcn_stack_frame] (" <<
this <<
") --" << std::endl;
1561 os <<
"fcn: " << m_fcn->name ()
1562 <<
" (" << m_fcn->type_name () <<
")" << std::endl;
1566compiled_fcn_stack_frame::accept (stack_frame_walker& sfw)
1568 sfw.visit_compiled_fcn_stack_frame (*
this);
1574 const std::shared_ptr<stack_frame>& parent_link,
1575 const std::shared_ptr<stack_frame>& static_link)
1576 :
stack_frame (tw, index, parent_link, static_link,
1577 get_access_link (static_link)),
1578 m_script (script), m_unwind_protect_frame (nullptr),
1579 m_lexical_frame_offsets (get_num_symbols (script), 1),
1580 m_value_offsets (get_num_symbols (script), 0)
1582 set_script_offsets ();
1594script_stack_frame::set_script_offsets ()
1601 std::size_t num_script_symbols = script_scope.
num_symbols ();
1603 resize (num_script_symbols);
1605 const std::map<std::string, symbol_record>& script_symbols
1608 set_script_offsets_internal (script_symbols);
1611void script_stack_frame::set_script_offsets_internal
1612(
const std::map<std::string, symbol_record>& script_symbols)
1623 for (
const auto& nm_sr : script_symbols)
1625 std::string name = nm_sr.first;
1630 std::size_t count = 1;
1632 while (parent_scope)
1634 const std::map<std::string, symbol_record>& parent_scope_symbols
1637 auto p = parent_scope_symbols.find (name);
1639 if (p != parent_scope_symbols.end ())
1644 std::size_t script_sr_data_offset = script_sr.
data_offset ();
1646 m_lexical_frame_offsets.at (script_sr_data_offset)
1649 m_value_offsets.at (script_sr_data_offset)
1662 error (
"symbol '%s' cannot be added to static scope",
1668 const std::map<std::string, symbol_record>& eval_scope_symbols
1671 for (
const auto& nm_sr : script_symbols)
1673 std::string name = nm_sr.first;
1676 auto p = eval_scope_symbols.find (name);
1680 if (p == eval_scope_symbols.end ())
1681 eval_scope_sr = eval_scope.
insert (name);
1683 eval_scope_sr = p->second;
1685 std::size_t script_sr_data_offset = script_sr.
data_offset ();
1690 m_lexical_frame_offsets.at (script_sr_data_offset)
1693 m_value_offsets.at (script_sr_data_offset)
1700script_stack_frame::resize_and_update_script_offsets (
const symbol_record& sym)
1708 if (data_offset < size ())
1709 error (
"unexpected: data_offset < size () in script_stack_frame::resize_and_update_script_offsets - please report this bug");
1711 resize (data_offset+1);
1717 std::map<std::string, symbol_record> tmp_symbols;
1718 tmp_symbols[sym.
name ()] = sym;
1719 set_script_offsets_internal (tmp_symbols);
1725std::shared_ptr<stack_frame>
1726script_stack_frame::get_access_link (
const std::shared_ptr<stack_frame>& static_link)
1731 std::shared_ptr<stack_frame> alink = static_link;
1733 while (alink->is_user_script_frame ())
1735 if (alink->access_link ())
1736 alink = alink->access_link ();
1745script_stack_frame::unwind_protect_frame ()
1747 if (! m_unwind_protect_frame)
1750 return m_unwind_protect_frame;
1754script_stack_frame::lookup_symbol (
const std::string& name)
const
1763 error (
"unexpected: sym.frame_offset () != 0 in script_stack_frame::lookup_symbol - please report this bug");
1768 sym = m_access_link->lookup_symbol (name);
1779script_stack_frame::insert_symbol (
const std::string& name)
1795 error (
"unexpected: sym.frame_offset () != 0 in script_stack_frame::insert_symbol - please report this bug");
1806 error (
"unexpected: sym is not valid in script_stack_frame::insert_symbol - please report this bug");
1808 resize_and_update_script_offsets (sym);
1818script_stack_frame::get_val_offsets_internal (
const symbol_record& script_sr,
1819 std::size_t& frame_offset,
1820 std::size_t& data_offset)
const
1831 std::string name = script_sr.
name ();
1835 std::size_t count = 1;
1837 while (parent_scope)
1839 const std::map<std::string, symbol_record>& parent_scope_symbols
1842 auto p = parent_scope_symbols.find (name);
1844 if (p != parent_scope_symbols.end ())
1849 frame_offset = parent_scope_sr.
frame_offset () + count;
1864 const std::map<std::string, symbol_record>& eval_scope_symbols
1867 std::string name = script_sr.
name ();
1869 auto p = eval_scope_symbols.find (name);
1873 if (p != eval_scope_symbols.end ())
1876 eval_scope_sr = p->second;
1891script_stack_frame::get_val_offsets (
const symbol_record& sym,
1892 std::size_t& frame_offset,
1893 std::size_t& data_offset)
const
1898 if (frame_offset == 0)
1906 if (data_offset >= size ())
1907 return get_val_offsets_internal (sym, frame_offset, data_offset);
1915 frame_offset = m_lexical_frame_offsets.at (data_offset);
1917 if (frame_offset == 0)
1925 return get_val_offsets_internal (sym, frame_offset, data_offset);
1928 data_offset = m_value_offsets.at (data_offset);
1941script_stack_frame::get_val_offsets_with_insert (
const symbol_record& sym,
1942 std::size_t& frame_offset,
1943 std::size_t& data_offset)
1948 if (frame_offset == 0)
1950 if (data_offset >= size ())
1956 resize_and_update_script_offsets (sym);
1965 frame_offset = m_lexical_frame_offsets.at (data_offset);
1967 if (frame_offset == 0)
1982 std::map<std::string, symbol_record> tmp_symbols;
1983 tmp_symbols[sym.
name ()] = sym;
1984 set_script_offsets_internal (tmp_symbols);
1989 frame_offset = m_lexical_frame_offsets.at (data_offset);
1992 data_offset = m_value_offsets.at (data_offset);
2003script_stack_frame::scope_flag (
const symbol_record& sym)
const
2005 std::size_t frame_offset;
2006 std::size_t data_offset;
2008 bool found = get_val_offsets (sym, frame_offset, data_offset);
2019 for (std::size_t i = 0; i < frame_offset; i++)
2021 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
2026 error (
"internal error: invalid access link in function call stack");
2028 if (data_offset >= frame->
size ())
2037 std::size_t frame_offset;
2038 std::size_t data_offset;
2040 bool found = get_val_offsets (sym, frame_offset, data_offset);
2050 for (std::size_t i = 0; i < frame_offset; i++)
2052 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
2057 error (
"internal error: invalid access link in function call stack");
2059 if (data_offset >= frame->
size ())
2065 return frame->
varval (data_offset);
2075 return m_evaluator.global_varval (sym.
name ());
2078 error (
"internal error: invalid switch case");
2084 std::size_t frame_offset;
2085 std::size_t data_offset;
2086 get_val_offsets_with_insert (sym, frame_offset, data_offset);
2093 for (std::size_t i = 0; i < frame_offset; i++)
2095 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
2099 if (data_offset >= frame->
size ())
2100 frame->
resize (data_offset+1);
2105 return frame->
varref (data_offset);
2115 return m_evaluator.global_varref (sym.
name ());
2118 error (
"internal error: invalid switch case");
2127 if (data_offset >= size ())
2128 resize_and_update_script_offsets (sym);
2132 std::size_t frame_offset = m_lexical_frame_offsets.at (data_offset);
2133 data_offset = m_value_offsets.at (data_offset);
2135 if (frame_offset > 1)
2136 error (
"variables must be made PERSISTENT or GLOBAL in the first scope in which they are used");
2138 std::shared_ptr<stack_frame> frame = access_link ();
2140 if (data_offset >= frame->size ())
2141 frame->resize (data_offset+1);
2143 frame->set_scope_flag (data_offset, flag);
2147script_stack_frame::display (
bool follow)
const
2151 os <<
"-- [script_stack_frame] (" <<
this <<
") --" << std::endl;
2154 os <<
"script: " << m_script->name ()
2155 <<
" (" << m_script->type_name () <<
")" << std::endl;
2157 os <<
"lexical_offsets: " << m_lexical_frame_offsets.size ()
2160 for (std::size_t i = 0; i < m_lexical_frame_offsets.size (); i++)
2161 os <<
" " << m_lexical_frame_offsets.at (i);
2164 os <<
"value_offsets: " << m_value_offsets.size () <<
" elements:";
2165 for (std::size_t i = 0; i < m_value_offsets.size (); i++)
2166 os <<
" " << m_value_offsets.at (i);
2169 display_scope (os, get_scope ());
2173script_stack_frame::accept (stack_frame_walker& sfw)
2175 sfw.visit_script_stack_frame (*
this);
2179base_value_stack_frame::display (
bool follow)
const
2183 os <<
"-- [base_value_stack_frame] (" <<
this <<
") --" << std::endl;
2186 os <<
"values: " << m_values.size ()
2187 <<
" elements (idx, scope flag, type):" << std::endl;
2189 for (std::size_t i = 0; i < m_values.size (); i++)
2191 os <<
" (" << i <<
", " << m_flags.at (i) <<
", ";
2203std::shared_ptr<stack_frame>
2205 const std::shared_ptr<stack_frame>& static_link)
2207 std::shared_ptr<stack_frame> alink;
2214 error (
"internal call stack error (invalid static link)");
2221 if (caller_nesting_depth < nesting_depth)
2227 alink = static_link;
2236 int links_to_follow = caller_nesting_depth - nesting_depth + 1;
2238 alink = static_link;
2240 while (alink && --links_to_follow >= 0)
2241 alink = alink->access_link ();
2244 error (
"internal function nesting error (invalid access link)");
2252user_fcn_stack_frame::clear_values ()
2256 const std::list<symbol_record>& symbols = fcn_scope.
symbol_list ();
2261 for (
const auto& sym : symbols)
2265 if (frame_offset > 0)
2270 if (data_offset >= size ())
2273 if (get_scope_flag (data_offset) == LOCAL)
2287user_fcn_stack_frame::unwind_protect_frame ()
2289 if (! m_unwind_protect_frame)
2292 return m_unwind_protect_frame;
2296user_fcn_stack_frame::lookup_symbol (
const std::string& name)
const
2309 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
2317user_fcn_stack_frame::insert_symbol (
const std::string& name)
2351 error (
"unexpected: sym is not valid in user_fcn_stack_frame::insert_symbol - please report this bug");
2357user_fcn_stack_frame::scope_flag (
const symbol_record& sym)
const
2367 for (std::size_t i = 0; i < frame_offset; i++)
2369 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
2374 error (
"internal error: invalid access link in function call stack");
2376 if (data_offset >= frame->
size ())
2383user_fcn_stack_frame::varval (
const symbol_record& sym)
const
2393 for (std::size_t i = 0; i < frame_offset; i++)
2395 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
2400 error (
"internal error: invalid access link in function call stack");
2402 if (data_offset >= frame->
size ())
2408 return frame->
varval (data_offset);
2418 return m_evaluator.global_varval (sym.
name ());
2421 error (
"internal error: invalid switch case");
2435 for (std::size_t i = 0; i < frame_offset; i++)
2437 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
2441 if (data_offset >= frame->
size ())
2442 frame->
resize (data_offset+1);
2447 return frame->
varref (data_offset);
2457 return m_evaluator.global_varref (sym.
name ());
2460 error (
"internal error: invalid switch case");
2464user_fcn_stack_frame::inputname (
int n,
bool ids_only)
const
2471 if (n >= 0 && n < arg_names.
numel ())
2473 name = arg_names(n);
2475 if (ids_only && ! m_static_link->is_variable (name))
2483user_fcn_stack_frame::mark_scope (
const symbol_record& sym, scope_flags flag)
2488 error (
"variables must be made PERSISTENT or GLOBAL in the first scope in which they are used");
2492 if (data_offset >= size ())
2493 resize (data_offset+1);
2495 set_scope_flag (data_offset, flag);
2499user_fcn_stack_frame::display (
bool follow)
const
2503 os <<
"-- [user_fcn_stack_frame] (" <<
this <<
") --" << std::endl;
2504 base_value_stack_frame::display (follow);
2506 os <<
"fcn: " << m_fcn->name ()
2507 <<
" (" << m_fcn->type_name () <<
")" << std::endl;
2509 display_scope (os, get_scope ());
2513user_fcn_stack_frame::accept (stack_frame_walker& sfw)
2515 sfw.visit_user_fcn_stack_frame (*
this);
2519user_fcn_stack_frame::break_closure_cycles (
const std::shared_ptr<stack_frame>& frame)
2521 for (
auto& val : m_values)
2522 val.break_closure_cycles (frame);
2529scope_stack_frame::insert_symbol (
const std::string& name)
2542 sym = m_scope.find_symbol (name);
2545 error (
"unexpected: sym is not valid in scope_stack_frame::insert_symbol - please report this bug");
2551scope_stack_frame::scope_flag (
const symbol_record& sym)
const
2558 if (data_offset >= size ())
2561 return get_scope_flag (data_offset);
2572 if (data_offset >= size ())
2575 switch (get_scope_flag (data_offset))
2578 return m_values.at (data_offset);
2581 return m_scope.persistent_varval (data_offset);
2584 return m_evaluator.global_varval (sym.
name ());
2587 error (
"internal error: invalid switch case");
2598 if (data_offset >= size ())
2599 resize (data_offset+1);
2601 switch (get_scope_flag (data_offset))
2604 return m_values.at (data_offset);
2607 return m_scope.persistent_varref (data_offset);
2610 return m_evaluator.global_varref (sym.
name ());
2613 error (
"internal error: invalid switch case");
2625 if (data_offset >= size ())
2626 resize (data_offset+1);
2628 set_scope_flag (data_offset, flag);
2632scope_stack_frame::display (
bool follow)
const
2636 os <<
"-- [scope_stack_frame] (" <<
this <<
") --" << std::endl;
2637 base_value_stack_frame::display (follow);
2639 display_scope (os, m_scope);
2643scope_stack_frame::accept (stack_frame_walker& sfw)
2645 sfw.visit_scope_stack_frame (*
this);
2648OCTAVE_END_NAMESPACE(octave)
N Dimensional Array with copy-on-write semantics.
octave_idx_type numel() const
Number of elements in the array.
static octave_map cat(int dim, octave_idx_type n, const octave_scalar_map *map_list)
void assign(const std::string &k, const octave_value &val)
octave::symbol_scope scope()
void call_object_destructor()
void break_closure_cycles(const std::shared_ptr< octave::stack_frame > &)
octave_idx_type get_count() const
std::string type_name() const
virtual scope_flags get_scope_flag(std::size_t) const
symbol_info_list glob_symbol_info(const std::string &pattern)
std::string fcn_file_name() const
std::list< std::string > variable_names() const
virtual octave_value varval(const symbol_record &sym) const =0
void clear(const symbol_record &sym)
static stack_frame * create(tree_evaluator &tw, octave_function *fcn, std::size_t index, const std::shared_ptr< stack_frame > &parent_link, const std::shared_ptr< stack_frame > &static_link)
std::shared_ptr< stack_frame > static_link() const
octave_value value(const symbol_record &sym, const std::string &type, const std::list< octave_value_list > &idx) const
bool is_global(const symbol_record &sym) const
void clear_variable_regexp(const std::string &pattern)
void mark_global(const symbol_record &sym)
virtual octave_value & varref(const symbol_record &sym)=0
void clear_variable_pattern(const std::string &pattern)
void debug_type(std::ostream &os, int start_line, int end_line) const
std::size_t index() const
symbol_info_list regexp_symbol_info(const std::string &pattern)
virtual void display(bool follow=true) const
virtual void set_scope_flag(std::size_t, scope_flags)
bool is_defined(const symbol_record &sym) const
std::shared_ptr< stack_frame > access_link() const
virtual void accept(stack_frame_walker &sfw)=0
void display_stopped_in_message(std::ostream &os) const
std::shared_ptr< stack_frame > m_parent_link
std::shared_ptr< stack_frame > parent_link() const
bool is_persistent(const symbol_record &sym) const
std::shared_ptr< stack_frame > m_access_link
virtual bool is_user_fcn_frame() const
std::string fcn_name(bool print_subfn=true) const
void assign(const symbol_record &sym, const octave_value &val)
bool is_object(const symbol_record &sym) const
void install_variable(const symbol_record &sym, const octave_value &value, bool global)
void clear_variable(const std::string &name)
std::shared_ptr< stack_frame > m_static_link
std::map< std::string, octave_value > local_vars_map
octave_value who(const string_vector &patterns, bool have_regexp, bool return_list, bool verbose, const std::string &whos_line_fmt, const std::string &msg)
virtual std::string inputname(int n, bool ids_only) const
tree_evaluator & m_evaluator
virtual std::size_t size() const
symbol_info_list all_variables()
virtual void clear_values()
virtual symbol_scope get_scope() const =0
virtual void resize(std::size_t)
bool is_variable(const symbol_record &sym) const
void debug_list(std::ostream &os, int num_lines) const
symbol_info_list make_symbol_info_list(const std::list< symbol_record > &symrec_list) const
std::ostream & list_in_columns(std::ostream &, int width=0, const std::string &prefix="") const
std::list< std::string > names() const
void display(std::ostream &os, const std::string &format) const
octave_value varval(const std::string &name) const
octave_map map_value(const std::string &caller_function_name, int nesting_level) const
symbol_record dup() const
void set_frame_offset(std::size_t offset)
std::size_t frame_offset() const
std::size_t data_offset() const
const std::map< std::string, symbol_record > & symbols() const
std::list< symbol_record > symbol_list() const
symbol_record find_symbol(const std::string &name)
std::size_t num_symbols() const
octave_value persistent_varval(std::size_t data_offset) const
symbol_record insert(const std::string &name)
octave_value & persistent_varref(std::size_t data_offset)
symbol_record lookup_symbol(const std::string &name) const
std::shared_ptr< symbol_scope_rep > parent_scope() const
std::size_t nesting_depth() const
octave_value & global_varref(const std::string &name)
octave_value global_varval(const std::string &name) const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void warning(const char *fmt,...)
void warning_with_id(const char *id, const char *fmt,...)
void error(const char *fmt,...)
MArray< T > filter(MArray< T > &b, MArray< T > &a, MArray< T > &x, MArray< T > &si, int dim=0)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
std::size_t format(std::ostream &os, const char *fmt,...)
void display_file_lines(std::ostream &os, const std::string &file_name, int start, int end, int target_line, const std::string &marker, const std::string &who)