# HG changeset patch # User John W. Eaton # Date 1497568506 14400 # Node ID 91c8f006ed8b1111dcbf4d0ae2374ba2f9a397a6 # Parent 2fe11412e785a87e085b16565fc732991327f204 remove additional functions from symbol_table class Remove functions from symbol_table class that simply forward to the corresponding function in the symbol_table::scope class. Change all uses to access these functions using a scope object. diff -r 2fe11412e785 -r 91c8f006ed8b examples/code/make_int.cc --- a/examples/code/make_int.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/examples/code/make_int.cc Thu Jun 15 19:15:06 2017 -0400 @@ -22,7 +22,6 @@ #include #include #include -#include #include class octave_value_list; diff -r 2fe11412e785 -r 91c8f006ed8b libgui/src/main-window.cc --- a/libgui/src/main-window.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libgui/src/main-window.cc Thu Jun 15 19:15:06 2017 -0400 @@ -2420,10 +2420,11 @@ { Fload (ovl (file)); - symbol_table& symtab - = octave::__get_symbol_table__ ("main_window::load_workspace_callback"); - - octave_link::set_workspace (true, symtab.workspace_info ()); + symbol_table::scope *scope + = octave::__get_current_scope__ ("main_window::load_workspace_callback"); + + if (scope) + octave_link::set_workspace (true, scope->workspace_info ()); } void @@ -2438,16 +2439,18 @@ void main_window::rename_variable_callback (const main_window::name_pair& names) { - symbol_table& symtab - = octave::__get_symbol_table__ ("main_window::rename_variable_callback"); - - /* bool status = */ symtab.rename (names.first, names.second); - - // if (status) - octave_link::set_workspace (true, symtab.workspace_info ()); - - // else - // ; // we need an octave_link action that runs a GUI error option. + symbol_table::scope *scope + = octave::__get_current_scope__ ("main_window::rename_variable_callback"); + + if (scope) + { + scope->rename (names.first, names.second); + + octave_link::set_workspace (true, scope->workspace_info ()); + } + + // FIXME: if this action fails, do we need a way to display that info + // in the GUI? } void diff -r 2fe11412e785 -r 91c8f006ed8b libgui/src/workspace-view.cc --- a/libgui/src/workspace-view.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libgui/src/workspace-view.cc Thu Jun 15 19:15:06 2017 -0400 @@ -373,10 +373,10 @@ { QString var_name = get_var_name (index); - symbol_table& symtab - = octave::__get_symbol_table__ ("workspace_view::handle_contextmenu_copy_value"); + symbol_table::scope *scope + = octave::__get_current_scope__ ("workspace_view::handle_contextmenu_copy_value"); - octave_value val = symtab.varval (var_name.toStdString ()); + octave_value val = scope ? scope->varval (var_name.toStdString ()) : 0; std::ostringstream buf; val.print_raw (buf, true); diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/corefcn/defun.cc --- a/libinterp/corefcn/defun.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/corefcn/defun.cc Thu Jun 15 19:15:06 2017 -0400 @@ -91,7 +91,8 @@ { octave_value fcn (new octave_builtin (f, name, file, doc)); - symbol_table& symtab = octave::__get_symbol_table__ ("install_builtin_function"); + symbol_table& symtab + = octave::__get_symbol_table__ ("install_builtin_function"); symtab.install_built_in_function (name, fcn); } @@ -103,7 +104,8 @@ { octave_value fcn (new octave_builtin (m, name, file, doc)); - symbol_table& symtab = octave::__get_symbol_table__ ("install_builtin_function"); + symbol_table& symtab + = octave::__get_symbol_table__ ("install_builtin_function"); symtab.install_built_in_function (name, fcn); } @@ -120,7 +122,8 @@ octave_value fval (fcn); - symbol_table& symtab = octave::__get_symbol_table__ ("install_dld_function"); + symbol_table& symtab + = octave::__get_symbol_table__ ("install_dld_function"); symtab.install_built_in_function (name, fval); } @@ -137,7 +140,8 @@ octave_value fval (fcn); - symbol_table& symtab = octave::__get_symbol_table__ ("install_dld_function"); + symbol_table& symtab + = octave::__get_symbol_table__ ("install_dld_function"); symtab.install_built_in_function (name, fval); } @@ -153,7 +157,8 @@ octave_value fval (fcn); - symbol_table& symtab = octave::__get_symbol_table__ ("install_mex_function"); + symbol_table& symtab + = octave::__get_symbol_table__ ("install_mex_function"); symtab.install_built_in_function (name, fval); } @@ -169,7 +174,8 @@ void install_builtin_dispatch (const std::string& name, const std::string& klass) { - symbol_table& symtab = octave::__get_symbol_table__ ("install_builtin_dispatch"); + symbol_table& symtab + = octave::__get_symbol_table__ ("install_builtin_dispatch"); symtab.install_built_in_dispatch (name, klass); } diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/corefcn/error.cc --- a/libinterp/corefcn/error.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/corefcn/error.cc Thu Jun 15 19:15:06 2017 -0400 @@ -1513,6 +1513,9 @@ if (nargin == 3 && argv[3] == "local" && ! symtab.at_top_level ()) { + symbol_table::scope *scope + = symtab.require_current_scope ("warning"); + octave_scalar_map val = warning_query (arg2); octave_value curr_state = val.contents ("state"); @@ -1520,7 +1523,7 @@ // FIXME: this might be better with a dictionary object. octave_value curr_warning_states - = symtab.varval (".saved_warning_states."); + = scope->varval (".saved_warning_states."); octave_map m; @@ -1568,7 +1571,7 @@ m.contents ("identifier") = ids; m.contents ("state") = states; - symtab.assign (".saved_warning_states.", m); + scope->assign (".saved_warning_states.", m); // Now ignore the "local" argument and continue to // handle the current setting. diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/corefcn/interpreter.cc --- a/libinterp/corefcn/interpreter.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/corefcn/interpreter.cc Thu Jun 15 19:15:06 2017 -0400 @@ -519,8 +519,14 @@ void interpreter::intern_nargin (octave_idx_type nargs) { - m_symbol_table.assign (".nargin.", nargs); - m_symbol_table.mark_hidden (".nargin."); + // FIXME: should this explicitly be top_scope? + symbol_table::scope *scope = m_symbol_table.current_scope (); + + if (scope) + { + scope->assign (".nargin.", nargs); + scope->mark_hidden (".nargin."); + } } // Read the history file unless a command-line option inhibits that. diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/corefcn/load-path.cc --- a/libinterp/corefcn/load-path.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/corefcn/load-path.cc Thu Jun 15 19:15:06 2017 -0400 @@ -121,9 +121,9 @@ // Look in private directory corresponding to current function (if // any). - symbol_table& symtab = octave::__get_symbol_table__ ("find_private_file"); - - octave_user_function *curr_fcn = symtab.get_curr_fcn (); + symbol_table::scope *scope = octave::__get_current_scope__ ("find_private_file"); + + octave_user_function *curr_fcn = scope ? scope->function () : 0; if (curr_fcn) { diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/corefcn/load-save.cc --- a/libinterp/corefcn/load-save.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/corefcn/load-save.cc Thu Jun 15 19:15:06 2017 -0400 @@ -145,16 +145,20 @@ const octave_value& val, bool global, const std::string& /*doc*/) { - symbol_table& symtab = octave::__get_symbol_table__ ("install_loaded_variable"); + symbol_table& symtab + = octave::__get_symbol_table__ ("install_loaded_varaible"); + + symbol_table::scope *scope + = symtab.require_current_scope ("install_loaded_variable"); if (global) { - symtab.clear (name); - symtab.mark_global (name); + scope->clear_variable (name); + scope->mark_global (name); symtab.global_assign (name, val); } else - symtab.assign (name, val); + scope->assign (name, val); } // Return TRUE if NAME matches one of the given globbing PATTERNS. @@ -1272,12 +1276,17 @@ std::string struct_name = argv[argv_idx]; - symbol_table& symtab = octave::__get_symbol_table__ ("save_vars"); + symbol_table::scope *scope = octave::__get_current_scope__ ("save_vars"); + + octave_value struct_var; - if (! symtab.is_variable (struct_name)) - error ("save: no such variable: '%s'", struct_name.c_str ()); + if (scope) + { + if (! scope->is_variable (struct_name)) + error ("save: no such variable: '%s'", struct_name.c_str ()); - octave_value struct_var = symtab.varval (struct_name); + struct_var = scope->varval (struct_name); + } if (! struct_var.isstruct () || struct_var.numel () != 1) error ("save: '%s' is not a scalar structure", struct_name.c_str ()); @@ -1321,8 +1330,9 @@ symbol_table& symtab = octave::__get_symbol_table__ ("dump_octave_core"); - std::list vars - = symtab.all_variables (symtab.top_scope ()); + symbol_table::scope *top_scope = symtab.top_scope (); + + std::list vars = top_scope->all_variables (); double save_mem_size = 0; diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/corefcn/mex.cc --- a/libinterp/corefcn/mex.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/corefcn/mex.cc Thu Jun 15 19:15:06 2017 -0400 @@ -3425,9 +3425,10 @@ frame.add_method (cs, &octave::call_stack::pop); } - symbol_table& symtab = octave::__get_symbol_table__ ("mexGetVariable"); - - val = symtab.varval (name); + symbol_table::scope *scope + = octave::__require_current_scope__ ("mexGetVariable"); + + val = scope->varval (name); } else mexErrMsgTxt ("mexGetVariable: symbol table does not exist"); @@ -3490,9 +3491,10 @@ frame.add_method (cs, &octave::call_stack::pop); } - symbol_table& symtab = octave::__get_symbol_table__ ("mexPutVariable"); - - symtab.assign (name, mxArray::as_octave_value (ptr)); + symbol_table::scope *scope + = octave::__require_current_scope__ ("mexPutVariable"); + + scope->assign (name, mxArray::as_octave_value (ptr)); } else mexErrMsgTxt ("mexPutVariable: symbol table does not exist"); diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/corefcn/octave-link.cc --- a/libinterp/corefcn/octave-link.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/corefcn/octave-link.cc Thu Jun 15 19:15:06 2017 -0400 @@ -69,10 +69,13 @@ symbol_table& symtab = octave::__get_symbol_table__ ("octave_link::set_workspace"); + std::list workspace_info; + symbol_table::scope *scope = symtab.current_scope (); + if (scope) + workspace_info = scope->workspace_info (); instance->do_set_workspace (symtab.at_top_level (), - instance->debugging, - symtab.workspace_info ()); + instance->debugging, workspace_info); } } diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/corefcn/symtab.cc --- a/libinterp/corefcn/symtab.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/corefcn/symtab.cc Thu Jun 15 19:15:06 2017 -0400 @@ -57,7 +57,7 @@ static int Vignore_function_time_stamp = 1; void -symbol_table::symbol_record::symbol_record_rep::clear (const scope *sid) +symbol_table::symbol_record::symbol_record_rep::clear (scope *sid) { if (! (is_hidden () || is_inherited ()) && sid == decl_scope ()) @@ -65,12 +65,9 @@ if (is_global ()) unmark_global (); - symbol_table& symtab - = octave::__get_symbol_table__ ("symbol_table::symbol_record::symbol_record_rep::clear"); - if (is_persistent ()) { - symtab.persistent_assign (name, varval ()); + sid->persistent_assign (name, varval ()); unmark_persistent (); } @@ -82,14 +79,14 @@ void symbol_table::symbol_record::symbol_record_rep::init_persistent (void) { - symbol_table& symtab - = octave::__get_symbol_table__ ("symbol_table::symbol_record::symbol_record_rep::init_persistent"); + symbol_table::scope *scope + = octave::__require_current_scope__ ("symbol_table::symbol_record::symbol_record_rep::init_persistent"); if (! is_defined ()) { mark_persistent (); - assign (symtab.persistent_varval (name)); + assign (scope->persistent_varval (name)); } // FIXME: this causes trouble with recursive calls. // else @@ -101,11 +98,10 @@ { unmark_persistent (); - symbol_table& symtab - = octave::__get_symbol_table__ ("symbol_table::symbol_record::symbol_record_rep::erase_persistent"); + symbol_table::scope *scope + = octave::__require_current_scope__ ("symbol_table::symbol_record::symbol_record_rep::erase_persistent"); - - symtab.erase_persistent (name); + scope->erase_persistent (name); } symbol_table::symbol_record::symbol_record_rep * @@ -155,12 +151,10 @@ octave_value& symbol_table::symbol_record::symbol_record_rep::xpersistent_varref (void) { - symbol_table& symtab - = octave::__get_symbol_table__ ("symbol_table::symbol_record::symbol_record_rep::xpersistent_varref"); + symbol_table::scope *scope + = octave::__get_current_scope__ ("symbol_table::symbol_record::symbol_record_rep::xpersistent_varref"); - scope *s = symtab.current_scope (); - - return s ? s->persistent_varref (name) : dummy_octave_value; + return scope ? scope->persistent_varref (name) : dummy_octave_value; } octave_value @@ -175,10 +169,10 @@ octave_value symbol_table::symbol_record::symbol_record_rep::xpersistent_varval (void) const { - symbol_table& symtab - = octave::__get_symbol_table__ ("symbol_table::symbol_record::symbol_record_rep::xpersistent_varval"); + symbol_table::scope *scope + = octave::__get_current_scope__ ("symbol_table::symbol_record::symbol_record_rep::xpersistent_varval"); - return symtab.persistent_varval (name); + return scope ? scope->persistent_varval (name) : octave_value (); } symbol_table::symbol_record::symbol_record (void) @@ -232,9 +226,7 @@ symbol_table::symbol_reference::symbol_reference (const symbol_record& record) : m_scope (0), m_context (0),m_sym (record) { - symbol_table& symtab = octave::__get_symbol_table__ ("symbol_reference"); - - m_scope = symtab.current_scope (); + m_scope = octave::__get_current_scope__ ("symbol_reference"); } void @@ -806,10 +798,10 @@ { if (local_funcs) { - symbol_table& symtab - = octave::__get_symbol_table__ ("symbol_table::fcn_info::fcn_info_rep::xfind"); + symbol_table::scope *scope + = octave::__get_current_scope__ ("symbol_table::fcn_info::fcn_info_rep::xfind"); - octave_user_function *current_fcn = symtab.get_curr_fcn (); + octave_user_function *current_fcn = scope ? scope->function () : 0; // Local function. @@ -1010,10 +1002,10 @@ // Private function. - symbol_table& symtab - = octave::__get_symbol_table__ ("symbol_table::fcn_info::fcn_info_rep::x_builtin_find"); + symbol_table::scope *scope + = octave::__get_current_scope__ ("symbol_table::fcn_info::fcn_info_rep::x_builtin_find"); - octave_user_function *current_fcn = symtab.get_curr_fcn (); + octave_user_function *current_fcn = scope ? scope->function () : 0; if (current_fcn) { diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/corefcn/symtab.h --- a/libinterp/corefcn/symtab.h Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/corefcn/symtab.h Thu Jun 15 19:15:06 2017 -0400 @@ -214,7 +214,7 @@ void clear (void) { clear (decl_scope ()); } - void clear (const scope *sid); + void clear (scope *sid); bool is_defined (void) const { @@ -279,7 +279,7 @@ void erase_persistent (void); - const scope *decl_scope (void) const { return m_decl_scope; } + scope *decl_scope (void) { return m_decl_scope; } void set_curr_fcn (octave_user_function *fcn) { @@ -411,7 +411,7 @@ void clear (void) { rep->clear (); } - void clear (const scope *sid) { rep->clear (sid); } + void clear (scope *sid) { rep->clear (sid); } bool is_defined (void) const { @@ -466,7 +466,7 @@ void invalidate (void) { rep->invalidate (); } - const scope *decl_scope (void) const { return rep->decl_scope (); } + scope *decl_scope (void) { return rep->decl_scope (); } unsigned int xstorage_class (void) const { return rep->storage_class; } @@ -905,6 +905,14 @@ scope *current_scope (void) { return m_current_scope; } + scope *require_current_scope (const std::string& who) + { + if (! m_current_scope) + error ("%s: missing scope", who.c_str ()); + + return m_current_scope; + } + context_id current_context (void) const { return m_current_scope ? m_current_scope->current_context () : 0; @@ -939,22 +947,12 @@ void inherit (scope *recipient_scope, scope *donor_scope) { if (recipient_scope) - { - while (donor_scope) - { - recipient_scope->inherit (*donor_scope); - - if (donor_scope->is_nested ()) - donor_scope = donor_scope->parent_scope (); - else - break; - } - } + recipient_scope->inherit (donor_scope); } - void inherit (scope *sid) + void inherit (scope *recipient_scope) { - inherit (sid, m_current_scope); + inherit (recipient_scope, m_current_scope); } bool at_top_level (void) { return m_current_scope == m_top_scope; } @@ -968,39 +966,6 @@ octave_value builtin_find (const std::string& name); - void rename (const std::string& old_name, const std::string& new_name) - { - if (m_current_scope) - m_current_scope->rename (old_name, new_name); - } - - void assign (const std::string& name, - const octave_value& value = octave_value ()) - { - m_current_scope->assign (name, value); - } - - // Convenience function to simplify - // octave_user_function::bind_automatic_vars - - void force_assign (const std::string& name, const octave_value& value, - scope *sid) - { - if (sid) - sid->assign (name, value, true); - } - - void force_assign (const std::string& name, - const octave_value& value = octave_value ()) - { - m_current_scope->assign (name, value); - } - - octave_value varval (const std::string& name) - { - return m_current_scope->varval (name); - } - void global_assign (const std::string& name, const octave_value& value = octave_value ()) @@ -1035,31 +1000,6 @@ return m_top_scope->varval (name); } - void - persistent_assign (const std::string& name, - const octave_value& value = octave_value ()) - { - if (m_current_scope) - m_current_scope->persistent_assign (name, value); - } - - octave_value persistent_varval (const std::string& name) - { - return (m_current_scope - ? m_current_scope->persistent_varval (name) : octave_value ()); - } - - void erase_persistent (const std::string& name) - { - if (m_current_scope) - m_current_scope->erase_persistent (name); - } - - bool is_variable (const std::string& name) - { - return m_current_scope ? m_current_scope->is_variable (name) : false; - } - bool is_built_in_function_name (const std::string& name) { @@ -1161,29 +1101,6 @@ } } - // Install subfunction FCN named NAME. SCOPE is the scope of the - // primary function corresponding to this subfunction. - - void install_subfunction (const std::string& name, const octave_value& fcn, - scope *parent_scope) - { - if (parent_scope) - parent_scope->install_subfunction (name, fcn); - } - - void install_nestfunction (const std::string& name, const octave_value& fcn, - scope *parent_scope) - { - if (parent_scope) - parent_scope->install_subfunction (name, fcn, true); - } - - void update_nest (scope *sid) - { - if (sid) - sid->update_nest (); - } - // Install local function FCN named NAME. FILE_NAME is the name of // the file containing the local function. @@ -1251,16 +1168,13 @@ } } - void clear (const std::string& name) - { - clear_variable (name); - } - void clear_all (bool force = false) { - clear_variables (); - - clear_global_pattern ("*"); + if (m_current_scope) + { + m_current_scope->clear_variables (); + m_current_scope->clear_global_pattern ("*"); + } clear_functions (force); } @@ -1269,23 +1183,6 @@ // function with default values so that it will work properly with // unwind_protect. - void clear_variables (scope *sid) - { - if (sid) - sid->clear_variables (); - } - - void clear_variables (void) - { - clear_variables (m_current_scope); - } - - void clear_objects (void) - { - if (m_current_scope) - m_current_scope->clear_objects (); - } - void clear_functions (bool force = false) { fcn_table_iterator p = m_fcn_table.begin (); @@ -1299,23 +1196,13 @@ clear_user_function (name); } - void clear_global (const std::string& name) - { - if (m_current_scope) - m_current_scope->clear_global (name); - } - - void clear_variable (const std::string& name) - { - if (m_current_scope) - m_current_scope->clear_variable (name); - } - void clear_symbol (const std::string& name) { // FIXME: are we supposed to do both here? - clear_variable (name); + if (m_current_scope) + m_current_scope->clear_variable (name); + clear_function (name); } @@ -1334,29 +1221,13 @@ } } - void clear_global_pattern (const std::string& pat) - { - if (m_current_scope) - m_current_scope->clear_global_pattern (pat); - } - - void clear_variable_pattern (const std::string& pat) - { - if (m_current_scope) - m_current_scope->clear_variable_pattern (pat); - } - - void clear_variable_regexp (const std::string& pat) - { - if (m_current_scope) - m_current_scope->clear_variable_regexp (pat); - } - void clear_symbol_pattern (const std::string& pat) { // FIXME: are we supposed to do both here? - clear_variable_pattern (pat); + if (m_current_scope) + m_current_scope->clear_variable_pattern (pat); + clear_function_pattern (pat); } @@ -1460,45 +1331,6 @@ void pop_context (void *) { pop_context (); } - void mark_hidden (const std::string& name) - { - if (m_current_scope) - m_current_scope->mark_hidden (name); - } - - void mark_global (const std::string& name) - { - if (m_current_scope) - m_current_scope->mark_global (name); - } - - // exclude: Storage classes to exclude, you can OR them together - std::list - all_variables (scope *sid, bool defined_only, unsigned int exclude) - { - return (sid - ? sid->all_variables (defined_only, exclude) - : std::list ()); - } - - std::list - all_variables (scope *sid, bool defined_only) - { - return all_variables (sid, defined_only, symbol_record::hidden); - } - - std::list - all_variables (scope *sid) - { - return all_variables (sid, true); - } - - std::list - all_variables (void) - { - return all_variables (m_current_scope); - } - std::list glob (const std::string& pattern) { return (m_current_scope @@ -1655,47 +1487,12 @@ return retval; } - bool is_local_variable (const std::string& name) - { - return m_current_scope ? m_current_scope->is_local_variable (name) : false; - } - - bool is_global (const std::string& name) - { - return m_current_scope ? m_current_scope->is_global (name) : false; - } - - std::list workspace_info (void) - { - return (m_current_scope - ? m_current_scope->workspace_info () - : std::list ()); - } - void dump (std::ostream& os, scope *sid); void dump_global (std::ostream& os); void dump_functions (std::ostream& os); - void cache_name (scope *sid, const std::string& name) - { - if (sid) - sid->cache_name (name); - } - void stash_dir_name_for_subfunctions (scope *sid, - const std::string& dir_name) - { - if (sid) - sid->stash_dir_name_for_subfunctions (dir_name); - } - - void set_parent (scope *child_scope, scope *parent_scope) - { - if (child_scope) - child_scope->set_parent (parent_scope); - } - void add_to_parent_map (const std::string& classname, const std::list& parent_list) { @@ -1803,7 +1600,7 @@ return p->second; } - void inherit (scope& donor_scope) + void inherit_internal (scope& donor_scope) { for (auto& nm_sr : m_symbols) { @@ -1828,6 +1625,20 @@ } } + void inherit (scope *donor_scope) + { + while (donor_scope) + { + inherit_internal (*donor_scope); + + if (donor_scope->is_nested ()) + donor_scope = donor_scope->parent_scope (); + else + break; + } + } + + octave_value find (const std::string& name, const octave_value_list& args, bool skip_variables, bool local_funcs); @@ -2059,7 +1870,8 @@ } std::list - all_variables (bool defined_only, unsigned int exclude) const + all_variables (bool defined_only = true, + unsigned int exclude = symbol_table::symbol_record::hidden) const { std::list retval; @@ -2158,6 +1970,12 @@ const octave_value& fval, bool is_nested = false); + void install_nestfunction (const std::string& name, + const octave_value& fval) + { + install_subfunction (name, fval, true); + } + octave_value find_subfunction (const std::string& name) const; void lock_subfunctions (void) diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/corefcn/variables.cc --- a/libinterp/corefcn/variables.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/corefcn/variables.cc Thu Jun 15 19:15:06 2017 -0400 @@ -89,9 +89,11 @@ void clear_variable (const std::string& nm) { - symbol_table& symtab = octave::__get_symbol_table__ ("clear_variable"); - - symtab.clear_variable (nm); + symbol_table::scope *scope + = octave::__get_current_scope__ ("clear_variable"); + + if (scope) + scope->clear_variable (nm); } void @@ -235,9 +237,10 @@ if (! name.empty ()) { - symbol_table& symtab = octave::__get_symbol_table__ ("is_variable"); - - octave_value val = symtab.varval (name); + symbol_table::scope *scope + = octave::__get_current_scope__ ("is_variable"); + + octave_value val = scope ? scope->varval (name) : octave_value (); retval = val.is_defined (); } @@ -356,11 +359,11 @@ if (! args(0).is_string ()) error ("isglobal: NAME must be a string"); - symbol_table& symtab = octave::__get_symbol_table__ ("do_isglobal"); + symbol_table::scope *scope = octave::__get_current_scope__ ("do_isglobal"); std::string name = args(0).string_value (); - return symtab.is_global (name); + return scope && scope->is_global (name); } DEFUN (isglobal, args, , @@ -414,7 +417,9 @@ if (search_any || search_var) { - octave_value val = symtab.varval (name); + symbol_table::scope *scope = symtab.current_scope (); + + octave_value val = scope ? scope->varval (name) : octave_value (); if (val.is_constant () || val.isobject () || val.is_function_handle () @@ -695,9 +700,10 @@ octave_value lookup_function_handle (const std::string& nm) { - symbol_table& symtab = octave::__get_symbol_table__ ("lookup_function_handle"); - - octave_value val = symtab.varval (nm); + symbol_table::scope *scope + = octave::__get_current_scope__ ("lookup_function_handle"); + + octave_value val = scope ? scope->varval (nm) : octave_value (); return val.is_function_handle () ? val : octave_value (); } @@ -1706,7 +1712,7 @@ cs.push (&tmp_scope, 0); frame.add_method (cs, &octave::call_stack::pop); - frame.add_method (symtab, &symbol_table::clear_variables); + frame.add_method (tmp_scope, &symbol_table::scope::clear_variables); octave::feval ("load", octave_value (nm), 0); @@ -1745,15 +1751,18 @@ symbol_info_list symbol_stats; std::list symbol_names; + symbol_table::scope *scope = symtab.current_scope (); + for (int j = 0; j < npats; j++) { std::string pat = pats[j]; if (have_regexp) { - std::list tmp = global_only - ? symtab.regexp_global_variables (pat) - : symtab.regexp_variables (pat); + std::list tmp + = (global_only + ? symtab.regexp_global_variables (pat) + : symtab.regexp_variables (pat)); for (const auto& symrec : tmp) { @@ -1783,7 +1792,7 @@ std::string base_name = pat.substr (0, pos); - if (symtab.is_variable (base_name)) + if (scope && scope->is_variable (base_name)) { symbol_table::symbol_record sr = symtab.find_symbol (base_name); @@ -1802,9 +1811,10 @@ } else { - std::list tmp = global_only - ? symtab.glob_global_variables (pat) - : symtab.glob_variables (pat); + std::list tmp + = (global_only + ? symtab.glob_global_variables (pat) + : symtab.glob_variables (pat)); for (const auto& symrec : tmp) { @@ -1990,9 +2000,11 @@ } else { - symbol_table& symtab = octave::__get_symbol_table__ ("bind_ans"); - - symtab.force_assign (ans, val); + symbol_table::scope *scope + = octave::__get_current_scope__ ("bind_ans"); + + if (scope) + scope->force_assign (ans, val); if (print) { @@ -2241,6 +2253,11 @@ { symbol_table& symtab = octave::__get_symbol_table__ ("do_clear_globals"); + symbol_table::scope *scope = symtab.current_scope (); + + if (! scope) + return; + if (idx == argc) { string_vector gvars = symtab.global_variable_names (); @@ -2248,7 +2265,7 @@ int gcount = gvars.numel (); for (int i = 0; i < gcount; i++) - symtab.clear_global (gvars[i]); + scope->clear_global (gvars[i]); } else { @@ -2263,13 +2280,13 @@ std::string nm = gvars[i]; if (! name_matches_any_pattern (nm, argv, argc, idx)) - symtab.clear_global (nm); + scope->clear_global (nm); } } else { while (idx < argc) - symtab.clear_global_pattern (argv[idx++]); + scope->clear_global_pattern (argv[idx++]); } } } @@ -2278,15 +2295,19 @@ do_clear_variables (const string_vector& argv, int argc, int idx, bool exclusive = false, bool have_regexp = false) { - symbol_table& symtab = octave::__get_symbol_table__ ("do_clear_variables"); + symbol_table::scope *scope + = octave::__get_current_scope__ ("do_clear_variables"); + + if (! scope) + return; if (idx == argc) - symtab.clear_variables (); + scope->clear_variables (); else { if (exclusive) { - string_vector lvars = symtab.variable_names (); + string_vector lvars = scope->variable_names (); int lcount = lvars.numel (); @@ -2295,17 +2316,17 @@ std::string nm = lvars[i]; if (! name_matches_any_pattern (nm, argv, argc, idx, have_regexp)) - symtab.clear_variable (nm); + scope->clear_variable (nm); } } else { if (have_regexp) while (idx < argc) - symtab.clear_variable_regexp (argv[idx++]); + scope->clear_variable_regexp (argv[idx++]); else while (idx < argc) - symtab.clear_variable_pattern (argv[idx++]); + scope->clear_variable_pattern (argv[idx++]); } } } @@ -2317,7 +2338,12 @@ symbol_table& symtab = octave::__get_symbol_table__ ("do_clear_symbols"); if (idx == argc) - symtab.clear_variables (); + { + symbol_table::scope *scope = symtab.current_scope (); + + if (scope) + scope->clear_variables (); + } else { if (exclusive) @@ -2343,34 +2369,40 @@ { // This is supposed to be mostly Matlab compatible. - symbol_table& symtab = octave::__get_symbol_table__ ("do_matlab_compatible_clear"); + symbol_table& symtab + = octave::__get_symbol_table__ ("do_matlab_compatible_clear"); + + symbol_table::scope *scope = symtab.current_scope (); + + if (! scope) + return; for (; idx < argc; idx++) { if (argv[idx] == "all" - && ! symtab.is_local_variable ("all")) + && ! scope->is_local_variable ("all")) { symtab.clear_all (); } else if (argv[idx] == "functions" - && ! symtab.is_local_variable ("functions")) + && ! scope->is_local_variable ("functions")) { do_clear_functions (argv, argc, ++idx); } else if (argv[idx] == "global" - && ! symtab.is_local_variable ("global")) + && ! scope->is_local_variable ("global")) { do_clear_globals (argv, argc, ++idx); } else if (argv[idx] == "variables" - && ! symtab.is_local_variable ("variables")) + && ! scope->is_local_variable ("variables")) { - symtab.clear_variables (); + scope->clear_variables (); } else if (argv[idx] == "classes" - && ! symtab.is_local_variable ("classes")) + && ! scope->is_local_variable ("classes")) { - symtab.clear_objects (); + scope->clear_objects (); octave_class::clear_exemplar_map (); symtab.clear_all (); } @@ -2488,6 +2520,7 @@ bool have_dash_option = false; symbol_table& symtab = interp.get_symbol_table (); + symbol_table::scope *scope = symtab.current_scope (); while (++idx < argc) { @@ -2575,7 +2608,8 @@ } else if (clear_objects) { - symtab.clear_objects (); + if (scope) + scope->clear_objects (); octave_class::clear_exemplar_map (); symtab.clear_all (); } @@ -2726,9 +2760,9 @@ std::string name = args(0).xstring_value ("__varval__: first argument must be a variable name"); - symbol_table& symtab = interp.get_symbol_table (); - - return symtab.varval (args(0).string_value ()); + symbol_table::scope *scope = interp.get_current_scope (); + + return scope ? scope->varval (args(0).string_value ()) : octave_value (); } static std::string Vmissing_component_hook; diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/octave-value/ov-classdef.cc --- a/libinterp/octave-value/ov-classdef.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/octave-value/ov-classdef.cc Thu Jun 15 19:15:06 2017 -0400 @@ -1095,10 +1095,10 @@ error ("cannot call superclass constructor with variable `%s'", mname.c_str ()); - symbol_table& symtab - = octave::__get_symbol_table__ ("octave_classdef_superclass_ref::call"); - - octave_value sym = symtab.varval (mname); + symbol_table::scope *scope + = octave::__require_current_scope__ ("octave_classdef_superclass_ref::call"); + + octave_value sym = scope->varval (mname); cls.run_constructor (to_cdef_ref (sym), idx); diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/octave-value/ov-fcn-handle.cc --- a/libinterp/octave-value/ov-fcn-handle.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/octave-value/ov-fcn-handle.cc Thu Jun 15 19:15:06 2017 -0400 @@ -86,9 +86,10 @@ if (uf && nm != anonymous) { - symbol_table& symtab = octave::__get_symbol_table__ ("octave_fcn_handle"); + symbol_table::scope *uf_scope = uf->scope (); - symtab.cache_name (uf->scope (), nm); + if (uf_scope) + uf_scope->cache_name (nm); } if (uf && uf->is_nested_function () && ! uf->is_subfunction ()) @@ -351,13 +352,12 @@ if (fcn.is_undefined ()) return false; - octave_user_function *f = fcn.user_function_value (); + std::list vars; - symbol_table& symtab - = octave::__get_symbol_table__ ("octave_fcn_handle::save_ascii"); - - std::list vars - = symtab.all_variables (f->scope ()); + octave_user_function *f = fcn.user_function_value (); + symbol_table::scope *f_scope = f->scope (); + if (f_scope) + vars = f_scope->all_variables (); size_t varlen = vars.size (); @@ -489,7 +489,12 @@ octave_user_function *uf = fcn.user_function_value (true); if (uf) - symtab.cache_name (uf->scope (), nm); + { + symbol_table::scope *uf_scope = uf->scope (); + + if (uf_scope) + uf_scope->cache_name (nm); + } } else success = false; @@ -516,13 +521,12 @@ if (fcn.is_undefined ()) return false; - octave_user_function *f = fcn.user_function_value (); + std::list vars; - symbol_table& symtab - = octave::__get_symbol_table__ ("octave_fcn_handle::save_binary"); - - std::list vars - = symtab.all_variables (f->scope ()); + octave_user_function *f = fcn.user_function_value (); + symbol_table::scope *f_scope = f->scope (); + if (f_scope) + vars = f_scope->all_variables (); size_t varlen = vars.size (); @@ -671,7 +675,12 @@ octave_user_function *uf = fcn.user_function_value (true); if (uf) - symtab.cache_name (uf->scope (), nm); + { + symbol_table::scope *uf_scope = uf->scope (); + + if (uf_scope) + uf_scope->cache_name (nm); + } } else success = false; @@ -794,13 +803,12 @@ H5Dclose (data_hid); - octave_user_function *f = fcn.user_function_value (); + std::list vars; - symbol_table& symtab - = octave::__get_symbol_table__ ("octave_fcn_handle::load_hdf5"); - - std::list vars - = symtab.all_variables (f->scope ()); + octave_user_function *f = fcn.user_function_value (); + symbol_table::scope *f_scope = f->scope (); + if (f_scope) + vars = f_scope->all_variables (); size_t varlen = vars.size (); @@ -1202,7 +1210,12 @@ octave_user_function *uf = fcn.user_function_value (true); if (uf) - symtab.cache_name (uf->scope (), nm); + { + symbol_table::scope *uf_scope = uf->scope (); + + if (uf_scope) + uf_scope->cache_name (nm); + } } else success = false; @@ -1695,8 +1708,8 @@ %! endfor */ -DEFMETHOD (functions, interp, args, , - doc: /* -*- texinfo -*- +DEFUN (functions, args, , + doc: /* -*- texinfo -*- @deftypefn {} {@var{s} =} functions (@var{fcn_handle}) Return a structure containing information about the function handle @var{fcn_handle}. @@ -1791,12 +1804,12 @@ { m.setfield ("file", nm); - octave_user_function *fu = fh->user_function_value (); + std::list vars; - symbol_table& symtab = interp.get_symbol_table (); - - std::list vars - = symtab.all_variables (fu->scope ()); + octave_user_function *fu = fh->user_function_value (); + symbol_table::scope *fu_scope = fu->scope (); + if (fu_scope) + vars = fu_scope->all_variables (); size_t varlen = vars.size (); diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/octave-value/ov-usr-fcn.cc --- a/libinterp/octave-value/ov-usr-fcn.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/octave-value/ov-usr-fcn.cc Thu Jun 15 19:15:06 2017 -0400 @@ -825,7 +825,8 @@ } else { - retval = symtab.varval (".nargin."); + symbol_table::scope *scope = symtab.require_current_scope ("nargin"); + retval = scope->varval (".nargin."); if (retval.is_undefined ()) retval = 0; @@ -950,7 +951,8 @@ if (symtab.at_top_level ()) error ("nargout: invalid call at top level"); - retval = symtab.varval (".nargout."); + symbol_table::scope *scope = symtab.require_current_scope ("nargout"); + retval = scope->varval (".nargout."); if (retval.is_undefined ()) retval = 0; @@ -1022,10 +1024,12 @@ if (symtab.at_top_level ()) error ("isargout: invalid call at top level"); - int nargout1 = symtab.varval (".nargout.").int_value (); + symbol_table::scope *scope = symtab.require_current_scope ("isargout"); + + int nargout1 = scope->varval (".nargout.").int_value (); Matrix ignored; - octave_value tmp = symtab.varval (".ignored."); + octave_value tmp = scope->varval (".ignored."); if (tmp.is_defined ()) ignored = tmp.matrix_value (); diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/parse-tree/lex.ll --- a/libinterp/parse-tree/lex.ll Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/parse-tree/lex.ll Thu Jun 15 19:15:06 2017 -0400 @@ -2108,10 +2108,10 @@ { if (empty ()) { - symbol_table& symtab - = octave::__get_symbol_table__ ("lexical_feedback::symbol_table_context::curr_scope"); - - return symtab.current_scope (); + symbol_table::scope *scope + = octave::__get_current_scope__ ("lexical_feedback::symbol_table_context::curr_scope"); + + return scope; } else return frame_stack.front (); diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/parse-tree/oct-parse.in.yy --- a/libinterp/parse-tree/oct-parse.in.yy Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/parse-tree/oct-parse.in.yy Thu Jun 15 19:15:06 2017 -0400 @@ -3396,7 +3396,9 @@ symbol_table& symtab = octave::__get_symbol_table__ ("base_parser::finish_function"); - symtab.cache_name (fcn->scope (), tmp); + + symbol_table::scope *fcn_scope = fcn->scope (); + fcn_scope->cache_name (tmp); if (lc) fcn->stash_leading_comment (lc); @@ -3407,29 +3409,27 @@ { fcn->stash_fcn_location (l, c); + octave_value ov_fcn (fcn); + if (endfunction_found && function_scopes.size () > 1) { symbol_table::scope *pscope = function_scopes.parent_scope (); - symtab.install_nestfunction (nm, octave_value (fcn), pscope); + pscope->install_nestfunction (nm, ov_fcn); } else { fcn->mark_as_subfunction (); subfunction_names.push_back (nm); - symtab.install_subfunction (nm, octave_value (fcn), - primary_fcn_scope); + primary_fcn_scope->install_subfunction (nm, ov_fcn); } } - if (fcn) - { - if (parsing_local_functions ) - symtab.install_local_function (nm, octave_value (fcn), file); - else if (curr_fcn_depth == 1) - symtab.update_nest (fcn->scope ()); - } + if (parsing_local_functions ) + symtab.install_local_function (nm, octave_value (fcn), file); + else if (curr_fcn_depth == 1) + fcn_scope->update_nest (); if (! lexer.reading_fcn_file && curr_fcn_depth == 1) { @@ -4572,11 +4572,9 @@ if (retval->is_user_function ()) { - symbol_table::scope *id = retval->scope (); - - symbol_table& symtab = octave::__get_symbol_table__ ("load_fcn_from_file"); - - symtab.stash_dir_name_for_subfunctions (id, dir_name); + symbol_table::scope *scope = retval->scope (); + + scope->stash_dir_name_for_subfunctions (dir_name); } } @@ -5443,9 +5441,10 @@ if (octave::is_keyword (nm)) error ("assignin: invalid assignment to keyword '%s'", nm.c_str ()); - symbol_table& symtab = interp.get_symbol_table (); - - symtab.assign (nm, args(2)); + symbol_table::scope *scope = interp.get_current_scope (); + + if (scope) + scope->assign (nm, args(2)); } else error ("assignin: invalid variable name in argument VARNAME"); diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/parse-tree/pt-eval.cc --- a/libinterp/parse-tree/pt-eval.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/parse-tree/pt-eval.cc Thu Jun 15 19:15:06 2017 -0400 @@ -106,7 +106,7 @@ symbol_table::scope *new_scope = af_scope ? af_scope->dup () : 0; if (new_scope && af_parent_scope) - symtab.inherit (new_scope, af_parent_scope); + new_scope->inherit (af_parent_scope); tree_parameter_list *param_list_dup = param_list ? param_list->dup (*new_scope) : 0; @@ -126,8 +126,7 @@ = new octave_user_function (new_scope, param_list_dup, ret_list, stmt_list); - if (af_parent_scope) - symtab.set_parent (new_scope, af_parent_scope); + new_scope->set_parent (af_parent_scope); octave_function *curr_fcn = m_call_stack.current (); @@ -481,9 +480,10 @@ int count = 0; - symbol_table& symtab = m_interpreter.get_symbol_table (); - - octave_value tmp = symtab.varval (".ignored."); + symbol_table::scope *scope + = m_interpreter.require_current_scope ("tree_evaluator::initialize_undefined_parameter_list_elements"); + + octave_value tmp = scope->varval (".ignored."); const Matrix ignored = (tmp.is_defined () ? tmp.matrix_value () : Matrix ()); octave_idx_type k = 0; @@ -973,7 +973,10 @@ // Make sure that any variable with the same name as the new // function is cleared. - symtab.assign (nm); + symbol_table::scope *scope = symtab.current_scope (); + + if (scope) + scope->assign (nm); } } diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/parse-tree/pt-fcn-handle.cc --- a/libinterp/parse-tree/pt-fcn-handle.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/parse-tree/pt-fcn-handle.cc Thu Jun 15 19:15:06 2017 -0400 @@ -83,6 +83,10 @@ symbol_table::scope *new_scope = af_scope ? af_scope->dup () : 0; + // FIXME: why should we inherit from the current scope here? That + // doesn't seem right, but with the way things work now it appears + // to be required for bug-31371.tst to pass. + if (new_scope) symtab.inherit (new_scope); diff -r 2fe11412e785 -r 91c8f006ed8b libinterp/parse-tree/pt-jit.cc --- a/libinterp/parse-tree/pt-jit.cc Thu Jun 15 10:47:50 2017 -0400 +++ b/libinterp/parse-tree/pt-jit.cc Thu Jun 15 19:15:06 2017 -0400 @@ -118,9 +118,9 @@ jit_convert::jit_convert (tree& tee, jit_type *for_bounds) : converting_function (false) { - symbol_table& symtab = octave::__get_symbol_table__ ("jit_convert::jit_convert"); - - initialize (symtab.current_scope ()); + symbol_table::scope *scope = octave::__get_current_scope__ ("jit_convert::jit_convert"); + + initialize (scope); if (for_bounds) create_variable (next_for_bounds (false), for_bounds); @@ -2510,9 +2510,9 @@ if (iter == extra_vars.end ()) { - symbol_table& symtab = octave::__get_symbol_table__ ("jit_convert::find"); - - return symtab.varval (vname); + symbol_table::scope *scope = octave::__require_current_scope__ ("jit_convert::find"); + + return scope->varval (vname); } else return *iter->second;