26 #if defined (HAVE_CONFIG_H)
59 static void display_scope (std::ostream& os,
const symbol_scope& scope)
63 os <<
"scope: " << scope.
name () << std::endl;
67 os <<
"name (frame offset, data offset, storage class):"
70 std::list<symbol_record> symbols = scope.
symbol_list ();
72 for (
auto& sym : symbols)
74 os <<
" " << sym.name () <<
" (" << sym.frame_offset ()
75 <<
", " << sym.data_offset () <<
", " << sym.storage_class ()
82 class compiled_fcn_stack_frame;
83 class script_stack_frame;
84 class user_fcn_stack_frame;
85 class scope_stack_frame;
87 class stack_frame_walker
91 stack_frame_walker () { }
93 virtual ~stack_frame_walker () =
default;
97 OCTAVE_DISABLE_COPY_MOVE (stack_frame_walker)
100 visit_compiled_fcn_stack_frame (compiled_fcn_stack_frame&) = 0;
103 visit_script_stack_frame (script_stack_frame&) = 0;
106 visit_user_fcn_stack_frame (user_fcn_stack_frame&) = 0;
109 visit_scope_stack_frame (scope_stack_frame&) = 0;
112 class compiled_fcn_stack_frame :
public stack_frame
116 compiled_fcn_stack_frame () =
delete;
120 const std::shared_ptr<stack_frame>& parent_link,
121 const std::shared_ptr<stack_frame>& static_link)
122 :
stack_frame (tw, index, parent_link, static_link,
127 compiled_fcn_stack_frame (
const compiled_fcn_stack_frame& elt) =
default;
129 compiled_fcn_stack_frame&
130 operator = (
const compiled_fcn_stack_frame& elt) =
delete;
132 ~compiled_fcn_stack_frame () =
default;
134 bool is_compiled_fcn_frame ()
const {
return true; }
161 void set_auto_fcn_var (auto_var_type avt,
const octave_value& val)
201 void display (
bool follow =
true)
const;
203 void accept (stack_frame_walker& sfw);
237 script_stack_frame () =
delete;
241 const std::shared_ptr<stack_frame>& parent_link,
242 const std::shared_ptr<stack_frame>& static_link);
244 script_stack_frame (
const script_stack_frame& elt) =
default;
246 script_stack_frame& operator = (
const script_stack_frame& elt) =
delete;
248 ~script_stack_frame ()
250 delete m_unwind_protect_frame;
253 bool is_user_script_frame ()
const {
return true; }
255 static std::shared_ptr<stack_frame>
256 get_access_link (
const std::shared_ptr<stack_frame>& static_link);
260 void set_script_offsets ();
262 void set_script_offsets_internal (
const std::map<std::string,
265 void resize_and_update_script_offsets (
const symbol_record& sym);
267 symbol_scope get_scope ()
const {
return m_script->scope (); }
277 std::size_t size ()
const {
return m_lexical_frame_offsets.size (); }
279 void resize (std::size_t size)
281 m_lexical_frame_offsets.resize (size, 0);
282 m_value_offsets.resize (size, 0);
286 std::size_t& frame_offset,
287 std::size_t& data_offset);
290 std::size_t& frame_offset,
291 std::size_t& data_offset)
const;
293 bool get_val_offsets (
const symbol_record& sym, std::size_t& frame_offset,
294 std::size_t& data_offset)
const;
298 void set_auto_fcn_var (auto_var_type avt,
const octave_value& val)
318 void mark_scope (
const symbol_record& sym, scope_flags flag);
320 void display (
bool follow =
true)
const;
322 void accept (stack_frame_walker& sfw);
339 std::vector<std::size_t> m_lexical_frame_offsets;
340 std::vector<std::size_t> m_value_offsets;
350 base_value_stack_frame () =
delete;
352 base_value_stack_frame (
tree_evaluator& tw, std::size_t num_symbols,
354 const std::shared_ptr<stack_frame>& parent_link,
355 const std::shared_ptr<stack_frame>& static_link,
356 const std::shared_ptr<stack_frame>& access_link)
357 :
stack_frame (tw, index, parent_link, static_link, access_link),
359 m_flags (num_symbols,
LOCAL),
363 base_value_stack_frame (
const base_value_stack_frame& elt) =
default;
365 base_value_stack_frame&
366 operator = (
const base_value_stack_frame& elt) =
delete;
368 ~base_value_stack_frame ()
378 for (
auto auto_vars_iter = m_auto_vars.begin ();
379 auto_vars_iter != m_auto_vars.end ();)
380 auto_vars_iter = m_auto_vars.erase (auto_vars_iter);
382 for (
auto values_iter = m_values.begin ();
383 values_iter != m_values.end ();)
384 values_iter = m_values.erase (values_iter);
387 std::size_t size ()
const
389 return m_values.
size ();
392 void resize (std::size_t size)
395 m_flags.resize (size, LOCAL);
400 return m_flags.at (data_offset);
403 void set_scope_flag (std::size_t data_offset, scope_flags flag)
405 m_flags.at (data_offset) = flag;
410 return m_auto_vars.at (avt);
413 void set_auto_fcn_var (auto_var_type avt,
const octave_value& val)
415 m_auto_vars.at (avt) = val;
426 return m_values.at (data_offset);
431 return m_values.at (data_offset);
434 void display (
bool follow =
true)
const;
441 std::vector<octave_value> m_values;
450 std::vector<scope_flags> m_flags;
455 std::vector<octave_value> m_auto_vars;
469 class user_fcn_stack_frame :
public base_value_stack_frame
473 user_fcn_stack_frame () =
delete;
477 const std::shared_ptr<stack_frame>& parent_link,
478 const std::shared_ptr<stack_frame>& static_link,
479 const std::shared_ptr<stack_frame>& access_link = std::shared_ptr<stack_frame> ())
480 : base_value_stack_frame (tw, get_num_symbols (fcn), index,
481 parent_link, static_link,
484 : get_access_link (fcn, static_link))),
485 m_fcn (fcn), m_unwind_protect_frame (nullptr)
490 const std::shared_ptr<stack_frame>& parent_link,
491 const std::shared_ptr<stack_frame>& static_link,
492 const local_vars_map& local_vars,
493 const std::shared_ptr<stack_frame>& access_link = std::shared_ptr<stack_frame> ())
494 : base_value_stack_frame (tw, get_num_symbols (fcn), index,
495 parent_link, static_link,
498 : get_access_link (fcn, static_link))),
499 m_fcn (fcn), m_unwind_protect_frame (nullptr)
503 for (
const auto& nm_ov : local_vars)
504 assign (nm_ov.first, nm_ov.second);
507 user_fcn_stack_frame (
const user_fcn_stack_frame& elt) =
default;
509 user_fcn_stack_frame&
510 operator = (
const user_fcn_stack_frame& elt) =
delete;
512 ~user_fcn_stack_frame ()
514 delete m_unwind_protect_frame;
517 bool is_user_fcn_frame ()
const {
return true; }
519 static std::shared_ptr<stack_frame>
521 const std::shared_ptr<stack_frame>& static_link);
530 void clear_values ();
532 symbol_scope get_scope ()
const {
return m_fcn->scope (); }
554 void mark_scope (
const symbol_record& sym, scope_flags flag);
556 void display (
bool follow =
true)
const;
558 void accept (stack_frame_walker& sfw);
560 void break_closure_cycles (
const std::shared_ptr<stack_frame>& frame);
580 class scope_stack_frame :
public base_value_stack_frame
584 scope_stack_frame () =
delete;
588 const std::shared_ptr<stack_frame>& parent_link,
589 const std::shared_ptr<stack_frame>& static_link)
590 : base_value_stack_frame (tw, scope.num_symbols (), index,
591 parent_link, static_link, nullptr),
595 scope_stack_frame (
const scope_stack_frame& elt) =
default;
597 scope_stack_frame& operator = (
const scope_stack_frame& elt) =
delete;
599 ~scope_stack_frame () =
default;
601 bool is_scope_frame ()
const {
return true; }
607 return m_scope.lookup_symbol (name);
624 void mark_scope (
const symbol_record& sym, scope_flags flag);
626 void display (
bool follow =
true)
const;
628 void accept (stack_frame_walker& sfw);
636 class symbol_cleaner :
public stack_frame_walker
640 symbol_cleaner (
const std::string& pattern,
bool have_regexp =
false)
641 : stack_frame_walker (), m_patterns (pattern),
642 m_clear_all_names (false), m_clear_objects (false),
643 m_have_regexp (have_regexp), m_cleared_names ()
646 symbol_cleaner (
const string_vector& patterns,
bool have_regexp =
false)
647 : stack_frame_walker (), m_patterns (patterns),
648 m_clear_all_names (false), m_clear_objects (false),
649 m_have_regexp (have_regexp), m_cleared_names ()
652 symbol_cleaner (
bool clear_all_names =
true,
bool clear_objects =
false)
653 : stack_frame_walker (), m_patterns (),
654 m_clear_all_names (clear_all_names), m_clear_objects (clear_objects),
655 m_have_regexp (false), m_cleared_names ()
658 OCTAVE_DISABLE_COPY_MOVE (symbol_cleaner)
660 ~symbol_cleaner () =
default;
662 void visit_compiled_fcn_stack_frame (compiled_fcn_stack_frame& frame)
668 std::shared_ptr<stack_frame> slink = frame.static_link ();
671 slink->accept (*
this);
674 void visit_script_stack_frame (script_stack_frame& frame)
676 std::shared_ptr<stack_frame> alink = frame.access_link ();
679 alink->accept (*
this);
682 void visit_user_fcn_stack_frame (user_fcn_stack_frame& frame)
686 std::shared_ptr<stack_frame> alink = frame.access_link ();
689 alink->accept (*
this);
692 void visit_scope_stack_frame (scope_stack_frame& frame)
696 std::shared_ptr<stack_frame> alink = frame.access_link ();
699 alink->accept (*
this);
706 std::string name = sym.
name ();
708 if (m_cleared_names.find (name) == m_cleared_names.end ())
718 if (m_clear_objects && ! frame.
is_object (sym))
721 m_cleared_names.insert (name);
731 const std::list<symbol_record>& symbols)
733 if (m_clear_all_names)
735 for (
const auto& sym : symbols)
736 maybe_clear_symbol (frame, sym);
738 else if (m_have_regexp)
744 std::string pattern = m_patterns[j];
748 for (
const auto& sym : symbols)
750 if (pat.is_match (sym.
name ()))
751 maybe_clear_symbol (frame, sym);
761 std::string pattern = m_patterns[j];
765 for (
const auto& sym : symbols)
767 if (pat.match (sym.
name ()))
768 maybe_clear_symbol (frame, sym);
778 std::list<symbol_record> symbols = scope.
symbol_list ();
780 if (m_clear_all_names || ! m_patterns.empty ())
781 clear_symbols (frame, symbols);
786 bool m_clear_all_names;
787 bool m_clear_objects;
790 std::set<std::string> m_cleared_names;
793 class symbol_info_accumulator :
public stack_frame_walker
797 symbol_info_accumulator (
const std::string& pattern,
798 bool have_regexp =
false)
799 : stack_frame_walker (), m_patterns (pattern), m_match_all (false),
800 m_first_only (false), m_have_regexp (have_regexp), m_sym_inf_list (),
805 bool have_regexp =
false)
806 : stack_frame_walker (), m_patterns (patterns), m_match_all (false),
807 m_first_only (false), m_have_regexp (have_regexp), m_sym_inf_list (),
811 symbol_info_accumulator (
bool match_all =
true,
bool first_only =
true)
812 : stack_frame_walker (), m_patterns (), m_match_all (match_all),
813 m_first_only (first_only), m_have_regexp (false),
814 m_sym_inf_list (), m_found_names ()
817 OCTAVE_DISABLE_COPY_MOVE (symbol_info_accumulator)
819 ~symbol_info_accumulator () =
default;
821 bool is_empty ()
const
823 for (
const auto& nm_sil : m_sym_inf_list)
834 std::list<std::string> names ()
const
836 std::list<std::string> retval;
838 for (
const auto& nm_sil : m_sym_inf_list)
842 std::list<std::string> nm_list = lst.
names ();
844 for (
const auto& nm : nm_list)
845 retval.push_back (nm);
855 for (
const auto& nm_sil : m_sym_inf_list)
859 for (
const auto& syminf : lst)
872 std::size_t n_frames = m_sym_inf_list.
size ();
877 for (
const auto& nm_sil : m_sym_inf_list)
879 std::string scope_name = nm_sil.first;
882 map_list[j] = lst.
map_value (scope_name, n_frames-j);
890 void display (std::ostream& os,
const std::string&
format)
const
892 for (
const auto& nm_sil : m_sym_inf_list)
894 os <<
"\nvariables in scope: " << nm_sil.first <<
"\n\n";
902 void visit_compiled_fcn_stack_frame (compiled_fcn_stack_frame& frame)
908 std::shared_ptr<stack_frame> slink = frame.static_link ();
911 slink->accept (*
this);
914 void visit_script_stack_frame (script_stack_frame& frame)
916 std::shared_ptr<stack_frame> alink = frame.access_link ();
919 alink->accept (*
this);
922 void visit_user_fcn_stack_frame (user_fcn_stack_frame& frame)
926 std::shared_ptr<stack_frame> alink = frame.access_link ();
929 alink->accept (*
this);
932 void visit_scope_stack_frame (scope_stack_frame& frame)
936 std::shared_ptr<stack_frame> alink = frame.access_link ();
939 alink->accept (*
this);
944 typedef std::pair<std::string, symbol_info_list> syminf_list_elt;
950 std::list<symbol_record>
953 std::list<symbol_record> new_symbols;
957 for (
const auto& sym : symbols)
961 std::string name = sym.
name ();
964 && m_found_names.find (name) != m_found_names.end ())
967 m_found_names.insert (name);
969 new_symbols.push_back (sym);
973 else if (m_have_regexp)
979 std::string pattern = m_patterns[j];
983 for (
const auto& sym : symbols)
985 std::string name = sym.
name ();
987 if (pat.is_match (name) && frame.
is_defined (sym))
990 && m_found_names.find (name) != m_found_names.end ())
993 m_found_names.insert (name);
995 new_symbols.push_back (sym);
1006 std::string pattern = m_patterns[j];
1010 for (
const auto& sym : symbols)
1012 std::string name = sym.
name ();
1014 if (pat.match (name) && frame.
is_defined (sym))
1017 && m_found_names.find (name) == m_found_names.end ())
1020 m_found_names.insert (name);
1022 new_symbols.push_back (sym);
1035 std::list<symbol_record> symbols = scope.
symbol_list ();
1037 if (m_match_all || ! m_patterns.empty ())
1038 symbols =
filter (frame, symbols);
1042 m_sym_inf_list.
push_back (syminf_list_elt (scope.
name (), syminf_list));
1051 std::list<std::pair<std::string, symbol_info_list>> m_sym_inf_list;
1053 std::set<std::string> m_found_names;
1059 const std::shared_ptr<stack_frame>& parent_link,
1060 const std::shared_ptr<stack_frame>& static_link)
1062 return new compiled_fcn_stack_frame (tw, fcn,
index,
1070 const std::shared_ptr<stack_frame>& parent_link,
1071 const std::shared_ptr<stack_frame>& static_link)
1079 const std::shared_ptr<stack_frame>& parent_link,
1080 const std::shared_ptr<stack_frame>& static_link,
1081 const std::shared_ptr<stack_frame>& access_link)
1083 return new user_fcn_stack_frame (tw, fcn,
index,
1090 const std::shared_ptr<stack_frame>& parent_link,
1091 const std::shared_ptr<stack_frame>& static_link,
1093 const std::shared_ptr<stack_frame>& access_link)
1095 return new user_fcn_stack_frame (tw, fcn,
index,
1103 const std::shared_ptr<stack_frame>& parent_link,
1104 const std::shared_ptr<stack_frame>& static_link)
1116 warning (
"invalid call to stack_frame::clear_values; please report");
1124 for (
const auto& sym : symrec_list)
1135 symbol_stats.
append (syminf);
1138 return symbol_stats;
1143 bool have_regexp,
bool return_list,
1144 bool verbose,
const std::string& whos_line_fmt,
1145 const std::string& msg)
1147 symbol_info_accumulator sym_inf_accum (patterns, have_regexp);
1154 return sym_inf_accum.map_value ();
1158 else if (! sym_inf_accum.is_empty ())
1162 octave_stdout <<
"Variables visible from the current scope:\n";
1187 symbol_info_accumulator sia (
true,
true);
1191 return sia.symbol_info ();
1197 std::list<octave_scalar_map> ws_list;
1207 for (
const auto& sym_name : symbols.
names ())
1212 ws.
assign (sym_name, val);
1215 ws_list.push_back (ws);
1217 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
1221 Cell ws_frames (ws_list.size (), 1);
1224 for (
const auto& elt : ws_list)
1225 ws_frames(i++) = elt;
1233 std::list<std::string>
1236 std::list<std::string> retval;
1240 const std::map<std::string, symbol_record>& symbols = scope.
symbols ();
1242 for (
const auto& nm_sr : symbols)
1245 retval.push_back (nm_sr.first);
1256 symbol_info_accumulator sia (pattern,
false);
1260 return sia.symbol_info ();
1266 symbol_info_accumulator sia (pattern,
true);
1270 return sia.symbol_info ();
1323 std::string nm = sym.
name ();
1326 "global: '%s' is defined in the current scope.\n",
1329 "global: in a future version, global variables must be declared before use.\n");
1340 "global: global value overrides existing local value");
1347 "global: existing local value used to initialize global variable");
1383 symbol_cleaner sc (
true,
true);
1391 symbol_cleaner sc (name);
1399 symbol_cleaner sc (pattern);
1407 symbol_cleaner sc (patterns);
1415 symbol_cleaner sc (pattern,
true);
1423 symbol_cleaner sc (patterns,
true);
1440 os <<
"at top level" << std::endl;
1443 os <<
"stopped in " <<
fcn_name ();
1447 os <<
" at line " <<
line ();
1458 os <<
"-- [stack_frame] (" <<
this <<
") --" << std::endl;
1460 os <<
"parent link: ";
1467 os <<
"static link: ";
1474 os <<
"access link: ";
1481 os <<
"line: " <<
m_line << std::endl;
1482 os <<
"column: " <<
m_column << std::endl;
1483 os <<
"index: " <<
m_index << std::endl;
1490 os <<
"FOLLOWING ACCESS LINKS:" << std::endl;
1491 std::shared_ptr<stack_frame> frm =
access_link ();
1494 frm->display (
false);
1497 frm = frm->access_link ();
1502 compiled_fcn_stack_frame::display (
bool follow)
const
1506 os <<
"-- [compiled_fcn_stack_frame] (" <<
this <<
") --" << std::endl;
1509 os <<
"fcn: " << m_fcn->name ()
1510 <<
" (" << m_fcn->type_name () <<
")" << std::endl;
1514 compiled_fcn_stack_frame::accept (stack_frame_walker& sfw)
1516 sfw.visit_compiled_fcn_stack_frame (*
this);
1522 const std::shared_ptr<stack_frame>& parent_link,
1523 const std::shared_ptr<stack_frame>& static_link)
1524 :
stack_frame (tw, index, parent_link, static_link,
1525 get_access_link (static_link)),
1526 m_script (script), m_unwind_protect_frame (nullptr),
1527 m_lexical_frame_offsets (get_num_symbols (script), 1),
1528 m_value_offsets (get_num_symbols (script), 0)
1530 set_script_offsets ();
1542 script_stack_frame::set_script_offsets ()
1549 std::size_t num_script_symbols = script_scope.
num_symbols ();
1551 resize (num_script_symbols);
1553 const std::map<std::string, symbol_record>& script_symbols
1556 set_script_offsets_internal (script_symbols);
1559 void script_stack_frame::set_script_offsets_internal
1560 (
const std::map<std::string, symbol_record>& script_symbols)
1571 for (
const auto& nm_sr : script_symbols)
1573 std::string name = nm_sr.first;
1578 std::size_t count = 1;
1580 while (parent_scope)
1582 const std::map<std::string, symbol_record>& parent_scope_symbols
1585 auto p = parent_scope_symbols.find (name);
1587 if (p != parent_scope_symbols.end ())
1592 std::size_t script_sr_data_offset = script_sr.
data_offset ();
1594 m_lexical_frame_offsets.at (script_sr_data_offset)
1597 m_value_offsets.at (script_sr_data_offset)
1610 error (
"symbol '%s' cannot be added to static scope",
1616 const std::map<std::string, symbol_record>& eval_scope_symbols
1619 for (
const auto& nm_sr : script_symbols)
1621 std::string name = nm_sr.first;
1624 auto p = eval_scope_symbols.find (name);
1628 if (p == eval_scope_symbols.end ())
1629 eval_scope_sr = eval_scope.
insert (name);
1631 eval_scope_sr = p->second;
1633 std::size_t script_sr_data_offset = script_sr.
data_offset ();
1638 m_lexical_frame_offsets.at (script_sr_data_offset)
1641 m_value_offsets.at (script_sr_data_offset)
1648 script_stack_frame::resize_and_update_script_offsets (
const symbol_record& sym)
1658 resize (data_offset+1);
1664 std::map<std::string, symbol_record> tmp_symbols;
1665 tmp_symbols[sym.
name ()] = sym;
1666 set_script_offsets_internal (tmp_symbols);
1672 std::shared_ptr<stack_frame>
1673 script_stack_frame::get_access_link (
const std::shared_ptr<stack_frame>& static_link)
1678 std::shared_ptr<stack_frame> alink = static_link;
1680 while (alink->is_user_script_frame ())
1682 if (alink->access_link ())
1683 alink = alink->access_link ();
1692 script_stack_frame::unwind_protect_frame ()
1694 if (! m_unwind_protect_frame)
1697 return m_unwind_protect_frame;
1701 script_stack_frame::lookup_symbol (
const std::string& name)
const
1714 sym = m_access_link->lookup_symbol (name);
1725 script_stack_frame::insert_symbol (
const std::string& name)
1751 resize_and_update_script_offsets (sym);
1761 script_stack_frame::get_val_offsets_internal (
const symbol_record& script_sr,
1762 std::size_t& frame_offset,
1763 std::size_t& data_offset)
const
1774 std::string name = script_sr.
name ();
1778 std::size_t count = 1;
1780 while (parent_scope)
1782 const std::map<std::string, symbol_record>& parent_scope_symbols
1785 auto p = parent_scope_symbols.find (name);
1787 if (p != parent_scope_symbols.end ())
1792 frame_offset = parent_scope_sr.
frame_offset () + count;
1807 const std::map<std::string, symbol_record>& eval_scope_symbols
1810 std::string name = script_sr.
name ();
1812 auto p = eval_scope_symbols.find (name);
1816 if (p != eval_scope_symbols.end ())
1819 eval_scope_sr = p->second;
1834 script_stack_frame::get_val_offsets (
const symbol_record& sym,
1835 std::size_t& frame_offset,
1836 std::size_t& data_offset)
const
1841 if (frame_offset == 0)
1849 if (data_offset >= size ())
1850 return get_val_offsets_internal (sym, frame_offset, data_offset);
1858 frame_offset = m_lexical_frame_offsets.at (data_offset);
1860 if (frame_offset == 0)
1868 return get_val_offsets_internal (sym, frame_offset, data_offset);
1871 data_offset = m_value_offsets.at (data_offset);
1884 script_stack_frame::get_val_offsets_with_insert (
const symbol_record& sym,
1885 std::size_t& frame_offset,
1886 std::size_t& data_offset)
1891 if (frame_offset == 0)
1893 if (data_offset >= size ())
1899 resize_and_update_script_offsets (sym);
1908 frame_offset = m_lexical_frame_offsets.at (data_offset);
1910 if (frame_offset == 0)
1925 std::map<std::string, symbol_record> tmp_symbols;
1926 tmp_symbols[sym.
name ()] = sym;
1927 set_script_offsets_internal (tmp_symbols);
1932 frame_offset = m_lexical_frame_offsets.at (data_offset);
1935 data_offset = m_value_offsets.at (data_offset);
1946 script_stack_frame::scope_flag (
const symbol_record& sym)
const
1948 std::size_t frame_offset;
1949 std::size_t data_offset;
1951 bool found = get_val_offsets (sym, frame_offset, data_offset);
1962 for (std::size_t i = 0; i < frame_offset; i++)
1964 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
1969 error (
"internal error: invalid access link in function call stack");
1971 if (data_offset >= frame->
size ())
1980 std::size_t frame_offset;
1981 std::size_t data_offset;
1983 bool found = get_val_offsets (sym, frame_offset, data_offset);
1993 for (std::size_t i = 0; i < frame_offset; i++)
1995 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
2000 error (
"internal error: invalid access link in function call stack");
2002 if (data_offset >= frame->
size ())
2008 return frame->
varval (data_offset);
2018 return m_evaluator.global_varval (sym.
name ());
2021 error (
"internal error: invalid switch case");
2027 std::size_t frame_offset;
2028 std::size_t data_offset;
2029 get_val_offsets_with_insert (sym, frame_offset, data_offset);
2036 for (std::size_t i = 0; i < frame_offset; i++)
2038 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
2042 if (data_offset >= frame->
size ())
2043 frame->
resize (data_offset+1);
2048 return frame->
varref (data_offset);
2058 return m_evaluator.global_varref (sym.
name ());
2061 error (
"internal error: invalid switch case");
2070 if (data_offset >= size ())
2071 resize_and_update_script_offsets (sym);
2075 std::size_t frame_offset = m_lexical_frame_offsets.at (data_offset);
2076 data_offset = m_value_offsets.at (data_offset);
2078 if (frame_offset > 1)
2079 error (
"variables must be made PERSISTENT or GLOBAL in the first scope in which they are used");
2081 std::shared_ptr<stack_frame> frame = access_link ();
2083 if (data_offset >= frame->size ())
2084 frame->resize (data_offset+1);
2086 frame->set_scope_flag (data_offset, flag);
2090 script_stack_frame::display (
bool follow)
const
2094 os <<
"-- [script_stack_frame] (" <<
this <<
") --" << std::endl;
2097 os <<
"script: " << m_script->name ()
2098 <<
" (" << m_script->type_name () <<
")" << std::endl;
2100 os <<
"lexical_offsets: " << m_lexical_frame_offsets.size ()
2103 for (std::size_t i = 0; i < m_lexical_frame_offsets.size (); i++)
2104 os <<
" " << m_lexical_frame_offsets.at (i);
2107 os <<
"value_offsets: " << m_value_offsets.size () <<
" elements:";
2108 for (std::size_t i = 0; i < m_value_offsets.size (); i++)
2109 os <<
" " << m_value_offsets.at (i);
2112 display_scope (os, get_scope ());
2116 script_stack_frame::accept (stack_frame_walker& sfw)
2118 sfw.visit_script_stack_frame (*
this);
2122 base_value_stack_frame::display (
bool follow)
const
2126 os <<
"-- [base_value_stack_frame] (" <<
this <<
") --" << std::endl;
2129 os <<
"values: " << m_values.size ()
2130 <<
" elements (idx, scope flag, type):" << std::endl;
2132 for (std::size_t i = 0; i < m_values.size (); i++)
2134 os <<
" (" << i <<
", " << m_flags.at (i) <<
", ";
2146 std::shared_ptr<stack_frame>
2148 const std::shared_ptr<stack_frame>& static_link)
2150 std::shared_ptr<stack_frame> alink;
2157 error (
"internal call stack error (invalid static link)");
2164 if (caller_nesting_depth < nesting_depth)
2170 alink = static_link;
2179 int links_to_follow = caller_nesting_depth - nesting_depth + 1;
2181 alink = static_link;
2183 while (alink && --links_to_follow >= 0)
2184 alink = alink->access_link ();
2187 error (
"internal function nesting error (invalid access link)");
2195 user_fcn_stack_frame::clear_values ()
2199 const std::list<symbol_record>& symbols = fcn_scope.
symbol_list ();
2204 for (
const auto& sym : symbols)
2208 if (frame_offset > 0)
2213 if (data_offset >= size ())
2216 if (get_scope_flag (data_offset) == LOCAL)
2230 user_fcn_stack_frame::unwind_protect_frame ()
2232 if (! m_unwind_protect_frame)
2235 return m_unwind_protect_frame;
2239 user_fcn_stack_frame::lookup_symbol (
const std::string& name)
const
2252 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
2260 user_fcn_stack_frame::insert_symbol (
const std::string& name)
2299 user_fcn_stack_frame::scope_flag (
const symbol_record& sym)
const
2309 for (std::size_t i = 0; i < frame_offset; i++)
2311 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
2316 error (
"internal error: invalid access link in function call stack");
2318 if (data_offset >= frame->
size ())
2335 for (std::size_t i = 0; i < frame_offset; i++)
2337 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
2342 error (
"internal error: invalid access link in function call stack");
2344 if (data_offset >= frame->
size ())
2350 return frame->
varval (data_offset);
2360 return m_evaluator.global_varval (sym.
name ());
2363 error (
"internal error: invalid switch case");
2377 for (std::size_t i = 0; i < frame_offset; i++)
2379 std::shared_ptr<stack_frame> nxt = frame->
access_link ();
2383 if (data_offset >= frame->
size ())
2384 frame->
resize (data_offset+1);
2389 return frame->
varref (data_offset);
2399 return m_evaluator.global_varref (sym.
name ());
2402 error (
"internal error: invalid switch case");
2406 user_fcn_stack_frame::mark_scope (
const symbol_record& sym, scope_flags flag)
2411 error (
"variables must be made PERSISTENT or GLOBAL in the first scope in which they are used");
2415 if (data_offset >= size ())
2416 resize (data_offset+1);
2418 set_scope_flag (data_offset, flag);
2422 user_fcn_stack_frame::display (
bool follow)
const
2426 os <<
"-- [user_fcn_stack_frame] (" <<
this <<
") --" << std::endl;
2427 base_value_stack_frame::display (follow);
2429 os <<
"fcn: " << m_fcn->name ()
2430 <<
" (" << m_fcn->type_name () <<
")" << std::endl;
2432 display_scope (os, get_scope ());
2436 user_fcn_stack_frame::accept (stack_frame_walker& sfw)
2438 sfw.visit_user_fcn_stack_frame (*
this);
2442 user_fcn_stack_frame::break_closure_cycles (
const std::shared_ptr<stack_frame>& frame)
2444 for (
auto& val : m_values)
2448 m_access_link->break_closure_cycles (frame);
2452 scope_stack_frame::insert_symbol (
const std::string& name)
2465 sym = m_scope.find_symbol (name);
2473 scope_stack_frame::scope_flag (
const symbol_record& sym)
const
2480 if (data_offset >= size ())
2483 return get_scope_flag (data_offset);
2494 if (data_offset >= size ())
2497 switch (get_scope_flag (data_offset))
2500 return m_values.at (data_offset);
2503 return m_scope.persistent_varval (data_offset);
2506 return m_evaluator.global_varval (sym.
name ());
2509 error (
"internal error: invalid switch case");
2520 if (data_offset >= size ())
2521 resize (data_offset+1);
2523 switch (get_scope_flag (data_offset))
2526 return m_values.at (data_offset);
2529 return m_scope.persistent_varref (data_offset);
2532 return m_evaluator.global_varref (sym.
name ());
2535 error (
"internal error: invalid switch case");
2547 if (data_offset >= size ())
2548 resize (data_offset+1);
2550 set_scope_flag (data_offset, flag);
2554 scope_stack_frame::display (
bool follow)
const
2558 os <<
"-- [scope_stack_frame] (" <<
this <<
") --" << std::endl;
2559 base_value_stack_frame::display (follow);
2561 display_scope (os, m_scope);
2565 scope_stack_frame::accept (stack_frame_walker& sfw)
2567 sfw.visit_scope_stack_frame (*
this);
2570 OCTAVE_END_NAMESPACE(
octave)
void push_back(const elt_type &s)
void append(const elt_type &s)
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::shared_ptr< stack_frame > parent_link() 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)
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(std::size_t data_offset)
void clear_variable_pattern(const std::string &pattern)
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
virtual void accept(stack_frame_walker &sfw)=0
void display_stopped_in_message(std::ostream &os) const
octave_value varval(const std::string &name) const
std::shared_ptr< stack_frame > m_parent_link
bool is_persistent(const symbol_record &sym) const
std::shared_ptr< stack_frame > m_access_link
virtual bool is_user_fcn_frame() const
virtual octave_value & varref(const symbol_record &sym)=0
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
std::shared_ptr< stack_frame > static_link() const
virtual octave_value varval(std::size_t data_offset) 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)
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
std::shared_ptr< stack_frame > access_link() 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
symbol_record find_symbol(const std::string &name)
std::size_t num_symbols() const
std::list< symbol_record > symbol_list() const
std::shared_ptr< symbol_scope_rep > parent_scope() 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)
const std::map< std::string, symbol_record > & symbols() const
symbol_record lookup_symbol(const std::string &name) 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,...)
#define panic_impossible()
#define panic_unless(cond)
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)
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
std::size_t format(std::ostream &os, const char *fmt,...)