Mercurial > octave
diff libinterp/corefcn/symtab.h @ 24263:3b302b2890d7
disentangle symbol_record, scope, and fcn_info from symbol_table class
* fcn-info.cc, fcn-info.h, scope.cc, scope.h, symrec.cc, symrec.h:
New files extracted from symtab.h and symtab.cc.
* libinterp/corefcn/module.mk: Update.
* symrec.cc (symbol_record::symbol_record_rep::xglobal_varref):
Don't access private symbol_table internals directly.
* scope.h, scope.cc (scope::find, scope::builtin_find,
scope::clear_global, scope::clear_global_pattern):
Don't access private symbol_table internals directly.
* symtab.h, symtab.cc (symbol_table::builtin_find): Don't forward to
current scope. Look directly in fcn_info table.
(symbol_table::global_varref, symbol_table::fcn_table_find,
symbol_table::erase_global, symbol_table::erase_global_pattern):
New functions.
* scope.h (scope::context_id): New typedef.
* symrec.h (symbol_record::context_id): New typedef.
* symtab.h (symbol_table::context_id): Update.
* symtab.h, symtab.cc (symbol_table::dummy_octave_value):
Delete static data member.
* symtab.h (symbol_table::context_id): Delete typedef.
(symbol_table::symbol_record, symbol_table::scope,
symbol_table::fcn_info): New typedefs.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 16 Nov 2017 16:06:31 -0500 |
parents | e15ad9af158f |
children | f494b87d2a93 |
line wrap: on
line diff
--- a/libinterp/corefcn/symtab.h Thu Nov 16 16:12:12 2017 -0500 +++ b/libinterp/corefcn/symtab.h Thu Nov 16 16:06:31 2017 -0500 @@ -40,8 +40,11 @@ class tree_argument_list; class octave_user_function; +#include "fcn-info.h" #include "ov.h" #include "ovl.h" +#include "scope.h" +#include "symrec.h" #include "workspace-element.h" namespace octave @@ -50,1064 +53,11 @@ { public: - static octave_value dummy_octave_value; - - typedef size_t context_id; - - class scope; - - class fcn_info; - - class symbol_record - { - public: - - // generic variable - static const unsigned int local = 1; - - // varargin, argn, .nargin., .nargout. - // (FIXME: is this really used now?) - static const unsigned int automatic = 2; - - // formal parameter - static const unsigned int formal = 4; - - // not listed or cleared (.nargin., .nargout.) - static const unsigned int hidden = 8; - - // inherited from parent scope; not cleared at function exit - static const unsigned int inherited = 16; - - // global (redirects to global scope) - static const unsigned int global = 32; - - // not cleared at function exit - static const unsigned int persistent = 64; - - // this symbol may NOT become a variable. - // (symbol added to a static workspace) - static const unsigned int added_static = 128; - - private: - - class symbol_record_rep - { - public: - - symbol_record_rep (scope *s, const std::string& nm, - const octave_value& v, unsigned int sc) - : m_decl_scope (s), curr_fcn (nullptr), name (nm), - m_fwd_rep (nullptr), value_stack (), - storage_class (sc), /* finfo (), */ valid (true), count (1) - { - value_stack.push_back (v); - } - - // No copying! - - symbol_record_rep (const symbol_record_rep& ov) = delete; - - symbol_record_rep& operator = (const symbol_record_rep&) = delete; - - ~symbol_record_rep (void) = default; - - void assign (const octave_value& value) - { - if (m_fwd_rep) - { - m_fwd_rep->assign (value); - return; - } - - varref () = value; - } - - void assign (octave_value::assign_op op, - const std::string& type, - const std::list<octave_value_list>& idx, - const octave_value& value) - { - if (m_fwd_rep) - { - m_fwd_rep->assign (op, type, idx, value); - return; - } - - varref().assign (op, type, idx, value); - } - - void assign (octave_value::assign_op op, const octave_value& value) - { - if (m_fwd_rep) - { - m_fwd_rep->assign (op, value); - return; - } - - varref().assign (op, value); - } - - void do_non_const_unary_op (octave_value::unary_op op) - { - if (m_fwd_rep) - { - m_fwd_rep->do_non_const_unary_op (op); - return; - } - - varref().do_non_const_unary_op (op); - } - - void do_non_const_unary_op (octave_value::unary_op op, - const std::string& type, - const std::list<octave_value_list>& idx) - { - if (m_fwd_rep) - { - m_fwd_rep->do_non_const_unary_op (op, type, idx); - return; - } - - varref().do_non_const_unary_op (op, type, idx); - } - - octave_value& varref (void) - { - if (m_fwd_rep) - return m_fwd_rep->varref (); - - context_id context - = m_decl_scope ? m_decl_scope->current_context () : 0; - - if (is_global ()) - return xglobal_varref (); - else if (is_persistent ()) - return xpersistent_varref (); - else - { - context_id n = value_stack.size (); - while (n++ <= context) - value_stack.push_back (octave_value ()); - - return value_stack[context]; - } - } - - octave_value varval (void) const - { - if (m_fwd_rep) - return m_fwd_rep->varval (); - - context_id context - = m_decl_scope ? m_decl_scope->current_context () : 0; - - if (is_global ()) - return xglobal_varval (); - else if (is_persistent ()) - return xpersistent_varval (); - else - { - if (context < value_stack.size ()) - return value_stack[context]; - else - return octave_value (); - } - } - - void push_context (scope *sid) - { - if (m_fwd_rep) - { - m_fwd_rep->push_context (sid); - return; - } - - if (! (is_persistent () || is_global ()) - && sid == decl_scope ()) - value_stack.push_back (octave_value ()); - } - - // If pop_context returns 0, we are out of values and this element - // of the symbol table should be deleted. This can happen for - // functions like - // - // function foo (n) - // if (n > 0) - // foo (n-1); - // else - // eval ("x = 1"); - // endif - // endfunction - // - // Here, X should only exist in the final stack frame. - - size_t pop_context (scope *sid) - { - if (m_fwd_rep) - return m_fwd_rep->pop_context (sid); - - size_t retval = 1; - - if (! (is_persistent () || is_global ()) - && sid == decl_scope ()) - { - value_stack.pop_back (); - retval = value_stack.size (); - } - - return retval; - } - - void clear (void) - { - if (m_fwd_rep) - { - m_fwd_rep->clear (); - return; - } - - clear (decl_scope ()); - } - - void clear (scope *sid); - - bool is_defined (void) const - { - if (m_fwd_rep) - return m_fwd_rep->is_defined (); - - return varval ().is_defined (); - } - - bool is_valid (void) const - { - if (m_fwd_rep) - return m_fwd_rep->is_valid (); - - return valid; - } - - bool is_variable (void) const - { - if (m_fwd_rep) - return m_fwd_rep->is_variable (); - - return (! is_local () || is_defined ()); - } - - bool is_local (void) const - { - if (m_fwd_rep) - return m_fwd_rep->is_local (); - - return storage_class & local; - } - - bool is_automatic (void) const - { - if (m_fwd_rep) - return m_fwd_rep->is_automatic (); - - return storage_class & automatic; - } - - bool is_formal (void) const - { - if (m_fwd_rep) - return m_fwd_rep->is_formal (); - - return storage_class & formal; - } - - bool is_hidden (void) const - { - if (m_fwd_rep) - return m_fwd_rep->is_hidden (); - - return storage_class & hidden; - } - - bool is_inherited (void) const - { - if (m_fwd_rep) - return m_fwd_rep->is_inherited (); - - return storage_class & inherited; - } - - bool is_global (void) const - { - if (m_fwd_rep) - return m_fwd_rep->is_global (); - - return storage_class & global; - } - - bool is_persistent (void) const - { - if (m_fwd_rep) - return m_fwd_rep->is_persistent (); - - return storage_class & persistent; - } - - bool is_added_static (void) const - { - if (m_fwd_rep) - return m_fwd_rep->is_added_static (); - - return storage_class & added_static; - } - - void mark_local (void) - { - if (m_fwd_rep) - { - m_fwd_rep->mark_local (); - return; - } - - storage_class |= local; - } - - void mark_automatic (void) - { - if (m_fwd_rep) - { - m_fwd_rep->mark_automatic (); - return; - } - - storage_class |= automatic; - } - - void mark_formal (void) - { - if (m_fwd_rep) - { - m_fwd_rep->mark_formal (); - return; - } - - storage_class |= formal; - } - - void mark_hidden (void) - { - if (m_fwd_rep) - { - m_fwd_rep->mark_hidden (); - return; - } - - storage_class |= hidden; - } - - void mark_inherited (void) - { - if (m_fwd_rep) - { - m_fwd_rep->mark_inherited (); - return; - } - - storage_class |= inherited; - } - - void mark_global (void) - { - if (m_fwd_rep) - { - m_fwd_rep->mark_global (); - return; - } - - if (is_persistent ()) - error ("can't make persistent variable %s global", name.c_str ()); - - storage_class |= global; - } - - void mark_persistent (void) - { - if (m_fwd_rep) - { - m_fwd_rep->mark_persistent (); - return; - } - - if (is_global ()) - error ("can't make global variable %s persistent", name.c_str ()); - - storage_class |= persistent; - } - - void mark_added_static (void) - { - if (m_fwd_rep) - { - m_fwd_rep->mark_added_static (); - return; - } - - storage_class |= added_static; - } - - void unmark_local (void) - { - if (m_fwd_rep) - { - m_fwd_rep->unmark_local (); - return; - } - - storage_class &= ~local; - } - - void unmark_automatic (void) - { - if (m_fwd_rep) - { - m_fwd_rep->unmark_automatic (); - return; - } - - storage_class &= ~automatic; - } - - void unmark_formal (void) - { - if (m_fwd_rep) - { - m_fwd_rep->unmark_formal (); - return; - } - - storage_class &= ~formal; - } - - void unmark_hidden (void) - { - if (m_fwd_rep) - { - m_fwd_rep->unmark_hidden (); - return; - } - - storage_class &= ~hidden; - } - - void unmark_inherited (void) - { - if (m_fwd_rep) - { - m_fwd_rep->unmark_inherited (); - return; - } - - storage_class &= ~inherited; - } - - void unmark_global (void) - { - if (m_fwd_rep) - { - m_fwd_rep->unmark_global (); - return; - } - - storage_class &= ~global; - } - - void unmark_persistent (void) - { - if (m_fwd_rep) - { - m_fwd_rep->unmark_persistent (); - return; - } - - storage_class &= ~persistent; - } - - void unmark_added_static (void) - { - if (m_fwd_rep) - { - m_fwd_rep->unmark_added_static (); - return; - } - - storage_class &= ~added_static; - } - - void init_persistent (void); - - void invalidate (void) - { - if (m_fwd_rep) - { - m_fwd_rep->invalidate (); - return; - } - - valid = false; - } - - void erase_persistent (void); - - scope *decl_scope (void) - { - if (m_fwd_rep) - return m_fwd_rep->decl_scope (); - - return m_decl_scope; - } - - void set_curr_fcn (octave_user_function *fcn) - { - if (m_fwd_rep) - { - m_fwd_rep->set_curr_fcn (fcn); - return; - } - - curr_fcn = fcn; - } - - // We don't forward more than once, so no need to forward the - // next two. + typedef octave::symbol_record symbol_record; + typedef octave::scope scope; + typedef octave::fcn_info fcn_info; - void bind_fwd_rep (symbol_record_rep *fwd_rep) { m_fwd_rep = fwd_rep; } - - void unbind_fwd_rep (void) { m_fwd_rep = nullptr; } - - symbol_record_rep * dup (scope *new_scope) const; - - octave_value dump (void) const; - - scope *m_decl_scope; - - octave_user_function *curr_fcn; - - std::string name; - - symbol_record_rep *m_fwd_rep; - - std::deque<octave_value> value_stack; - - unsigned int storage_class; - - // fcn_info *finfo; - - bool valid; - - refcount<size_t> count; - - private: - - octave_value& xglobal_varref (void); - - octave_value& xpersistent_varref (void); - - octave_value xglobal_varval (void) const; - - octave_value xpersistent_varval (void) const; - }; - - public: - - symbol_record (void); - - symbol_record (scope *s, const std::string& nm = "", - const octave_value& v = octave_value (), - unsigned int sc = local) - : rep (new symbol_record_rep (s, nm, v, sc)) { } - - symbol_record (const symbol_record& sr) - : rep (sr.rep) - { - rep->count++; - } - - symbol_record& operator = (const symbol_record& sr) - { - if (this != &sr) - { - if (--rep->count == 0) - delete rep; - - rep = sr.rep; - rep->count++; - } - - return *this; - } - - ~symbol_record (void) - { - if (--rep->count == 0) - delete rep; - } - - symbol_record dup (scope *sid) const - { - return symbol_record (rep->dup (sid)); - } - - const std::string& name (void) const { return rep->name; } - - void rename (const std::string& new_name) { rep->name = new_name; } - - octave_value - find (const octave_value_list& args = octave_value_list ()) const; - - void assign (const octave_value& value) - { - rep->assign (value); - } - - void assign (octave_value::assign_op op, - const std::string& type, - const std::list<octave_value_list>& idx, - const octave_value& value) - { - rep->assign (op, type, idx, value); - } - - void assign (octave_value::assign_op op, const octave_value& value) - { - rep->assign (op, value); - } - - void do_non_const_unary_op (octave_value::unary_op op) - { - rep->do_non_const_unary_op (op); - } - - void do_non_const_unary_op (octave_value::unary_op op, - const std::string& type, - const std::list<octave_value_list>& idx) - { - rep->do_non_const_unary_op (op, type, idx); - } - - // Delete when deprecated varref functions are removed. - octave_value& varref (void) - { - return rep->varref (); - } - - octave_value varval (void) const - { - return rep->varval (); - } - - void push_context (scope *sid) { rep->push_context (sid); } - - size_t pop_context (scope *sid) { return rep->pop_context (sid); } - - void clear (void) { rep->clear (); } - - void clear (scope *sid) { rep->clear (sid); } - - bool is_defined (void) const - { - return rep->is_defined (); - } - - bool is_undefined (void) const - { - return ! rep->is_defined (); - } - - bool is_valid (void) const - { - return rep->is_valid (); - } - - bool is_variable (void) const - { - return rep->is_variable (); - } - - bool is_local (void) const { return rep->is_local (); } - bool is_automatic (void) const { return rep->is_automatic (); } - bool is_formal (void) const { return rep->is_formal (); } - bool is_global (void) const { return rep->is_global (); } - bool is_hidden (void) const { return rep->is_hidden (); } - bool is_inherited (void) const { return rep->is_inherited (); } - bool is_persistent (void) const { return rep->is_persistent (); } - bool is_added_static (void) const { return rep->is_added_static (); } - - void mark_local (void) { rep->mark_local (); } - void mark_automatic (void) { rep->mark_automatic (); } - void mark_formal (void) { rep->mark_formal (); } - void mark_hidden (void) { rep->mark_hidden (); } - void mark_inherited (void) { rep->mark_inherited (); } - void mark_global (void) { rep->mark_global (); } - void mark_persistent (void) { rep->mark_persistent (); } - void mark_added_static (void) { rep->mark_added_static (); } - - void unmark_local (void) { rep->unmark_local (); } - void unmark_automatic (void) { rep->unmark_automatic (); } - void unmark_formal (void) { rep->unmark_formal (); } - void unmark_hidden (void) { rep->unmark_hidden (); } - void unmark_inherited (void) { rep->unmark_inherited (); } - void unmark_global (void) { rep->unmark_global (); } - void unmark_persistent (void) { rep->unmark_persistent (); } - void unmark_added_static (void) { rep->unmark_added_static (); } - - void init_persistent (void) { rep->init_persistent (); } - - void erase_persistent (void) { rep->erase_persistent (); } - - void invalidate (void) { rep->invalidate (); } - - scope *decl_scope (void) { return rep->decl_scope (); } - - unsigned int xstorage_class (void) const { return rep->storage_class; } - - void set_curr_fcn (octave_user_function *fcn) - { - rep->set_curr_fcn (fcn); - } - - void bind_fwd_rep (const symbol_record& sr) - { - rep->bind_fwd_rep (sr.rep); - } - - void unbind_fwd_rep (void) { rep->unbind_fwd_rep (); } - - octave_value dump (void) const { return rep->dump (); } - - const symbol_record_rep *xrep (void) const { return rep; } - - private: - - symbol_record_rep *rep; - - symbol_record (symbol_record_rep *new_rep) : rep (new_rep) { } - }; - - class fcn_info - { - public: - - typedef std::map<std::string, octave_value>::const_iterator - str_val_const_iterator; - typedef std::map<std::string, octave_value>::iterator str_val_iterator; - - private: - - class fcn_info_rep - { - public: - - fcn_info_rep (const std::string& nm) - : name (nm), package_name (), local_functions (), - private_functions (), class_constructors (), class_methods (), - cmdline_function (), autoload_function (), function_on_path (), - built_in_function (), count (1) - { - size_t pos = name.rfind ('.'); - - if (pos != std::string::npos) - { - package_name = name.substr (0, pos); - name = name.substr (pos+1); - } - } - - // No copying! - - fcn_info_rep (const fcn_info_rep&) = delete; - - fcn_info_rep& operator = (const fcn_info_rep&) = delete; - - ~fcn_info_rep (void) = default; - - octave_value install_local_function (const std::string& file_name); - - octave_value load_private_function (const std::string& dir_name); - - octave_value load_class_constructor (void); - - octave_value load_class_method (const std::string& dispatch_type); - - octave_value find (const octave_value_list& args, bool local_funcs); - - octave_value builtin_find (void); - - octave_value find_method (const std::string& dispatch_type); - - octave_value find_autoload (void); - - octave_value find_package (void); - - octave_value find_user_function (void); - - bool is_user_function_defined (void) const - { - return function_on_path.is_defined (); - } - - octave_value find_function (const octave_value_list& args, - bool local_funcs) - { - return find (args, local_funcs); - } - - void install_cmdline_function (const octave_value& f) - { - cmdline_function = f; - } - - void install_local_function (const octave_value& f, - const std::string& file_name) - { - local_functions[file_name] = f; - } - - void install_user_function (const octave_value& f) - { - function_on_path = f; - } - - void install_built_in_function (const octave_value& f) - { - built_in_function = f; - } - - void install_built_in_dispatch (const std::string& klass); - - template <typename T> - void - clear_map (std::map<T, octave_value>& map, bool force = false) - { - typename std::map<T, octave_value>::iterator p = map.begin (); - - while (p != map.end ()) - { - if (force || ! p->second.islocked ()) - map.erase (p++); - else - p++; - } - } - - void clear_autoload_function (bool force = false) - { - if (force || ! autoload_function.islocked ()) - autoload_function = octave_value (); - } - - // We also clear command line functions here, as these are both - // "user defined" - void clear_user_function (bool force = false) - { - clear_autoload_function (force); - - if (force || ! function_on_path.islocked ()) - function_on_path = octave_value (); - - if (force || ! cmdline_function.islocked ()) - cmdline_function = octave_value (); - } - - void clear_mex_function (void) - { - if (function_on_path.is_mex_function ()) - clear_user_function (); - } - - void clear_package (void) - { - package = octave_value (); - } - - void clear (bool force = false) - { - clear_map (local_functions, force); - clear_map (private_functions, force); - clear_map (class_constructors, force); - clear_map (class_methods, force); - - clear_autoload_function (force); - clear_user_function (force); - clear_package (); - } - - octave_value dump (void) const; - - std::string full_name (void) const - { - if (package_name.empty ()) - return name; - else - return package_name + '.' + name; - } - - std::string name; - - std::string package_name; - - // File name to function object. - std::map<std::string, octave_value> local_functions; - - // Directory name to function object. - std::map<std::string, octave_value> private_functions; - - // Class name to function object. - std::map<std::string, octave_value> class_constructors; - - // Dispatch type to function object. - std::map<std::string, octave_value> class_methods; - - octave_value cmdline_function; - - octave_value autoload_function; - - octave_value function_on_path; - - octave_value package; - - octave_value built_in_function; - - refcount<size_t> count; - - private: - - octave_value xfind (const octave_value_list& args, bool local_funcs); - - octave_value x_builtin_find (void); - }; - - public: - - fcn_info (const std::string& nm = "") - : rep (new fcn_info_rep (nm)) { } - - fcn_info (const fcn_info& fi) : rep (fi.rep) - { - rep->count++; - } - - fcn_info& operator = (const fcn_info& fi) - { - if (this != &fi) - { - if (--rep->count == 0) - delete rep; - - rep = fi.rep; - rep->count++; - } - - return *this; - } - - ~fcn_info (void) - { - if (--rep->count == 0) - delete rep; - } - - octave_value find (const octave_value_list& args = octave_value_list (), - bool local_funcs = true) - { - return rep->find (args, local_funcs); - } - - octave_value builtin_find (void) - { - return rep->builtin_find (); - } - - octave_value find_method (const std::string& dispatch_type) const - { - return rep->find_method (dispatch_type); - } - - octave_value find_built_in_function (void) const - { - return rep->built_in_function; - } - - octave_value find_cmdline_function (void) const - { - return rep->cmdline_function; - } - - octave_value find_autoload (void) - { - return rep->find_autoload (); - } - - octave_value find_user_function (void) - { - return rep->find_user_function (); - } - - bool is_user_function_defined (void) const - { - return rep->is_user_function_defined (); - } - - octave_value find_function (const octave_value_list& args - = octave_value_list (), - bool local_funcs = true) - { - return rep->find_function (args, local_funcs); - } - - void install_cmdline_function (const octave_value& f) - { - rep->install_cmdline_function (f); - } - - void install_local_function (const octave_value& f, - const std::string& file_name) - { - rep->install_local_function (f, file_name); - } - - void install_user_function (const octave_value& f) - { - rep->install_user_function (f); - } - - void install_built_in_function (const octave_value& f) - { - rep->install_built_in_function (f); - } - - void install_built_in_dispatch (const std::string& klass) - { - rep->install_built_in_dispatch (klass); - } - - void clear (bool force = false) { rep->clear (force); } - - void clear_user_function (bool force = false) - { - rep->clear_user_function (force); - } - - void clear_autoload_function (bool force = false) - { - rep->clear_autoload_function (force); - } - - void clear_mex_function (void) { rep->clear_mex_function (); } - - octave_value dump (void) const { return rep->dump (); } - - private: - - fcn_info_rep *rep; - }; + typedef scope::context_id context_id; symbol_table (void) : m_global_symbols (), m_fcn_table (), m_class_precedence_table (), @@ -1192,8 +142,6 @@ bool skip_variables = false, bool local_funcs = true); - octave_value builtin_find (const std::string& name); - void assign (const std::string& name, const octave_value& value, bool force_add) { if (m_current_scope) @@ -1225,6 +173,14 @@ p->second = value; } + octave_value& global_varref (const std::string& name) + { + global_symbols_iterator p = m_global_symbols.find (name); + + return (p == m_global_symbols.end () + ? m_global_symbols[name] : p->second); + } + octave_value global_varval (const std::string& name) const { global_symbols_const_iterator p = m_global_symbols.find (name); @@ -1303,6 +259,13 @@ ? p->second.find_autoload () : octave_value ()); } + octave_value builtin_find (const std::string& name); + + octave_value + fcn_table_find (const std::string& name, + const octave_value_list& args = octave_value_list (), + bool local_funcs = true); + octave_value find_function (const std::string& name, const octave_value_list& args = octave_value_list (), @@ -1512,6 +475,10 @@ (p++)->second.clear_mex_function (); } + void erase_global (const std::string& name); + + void erase_global_pattern (const glob_match& pattern); + bool set_class_relationship (const std::string& sup_class, const std::string& inf_class); @@ -1783,542 +750,6 @@ return p != m_fcn_table.end () ? &p->second : nullptr; } - class scope - { - public: - - typedef std::map<std::string, symbol_table::symbol_record>::const_iterator - table_const_iterator; - typedef std::map<std::string, symbol_table::symbol_record>::iterator - table_iterator; - - typedef std::map<std::string, octave_value>::const_iterator - m_persistent_symbols_const_iterator; - typedef std::map<std::string, octave_value>::iterator - m_persistent_symbols_iterator; - - typedef std::map<std::string, octave_value>::const_iterator - subfunctions_const_iterator; - typedef std::map<std::string, octave_value>::iterator subfunctions_iterator; - - scope (const std::string& name = "") - : m_name (name), m_symbols (), m_persistent_symbols (), m_subfunctions (), - m_fcn (nullptr), m_parent (nullptr), m_parent_fcn (), m_children (), m_is_nested (false), - m_is_static (false), m_context (0) - { } - - // No copying! - - scope (const scope&) = delete; - - scope& operator = (const scope&) = delete; - - ~scope (void) = default; - - void insert_symbol_record (const symbol_table::symbol_record& sr) - { - m_symbols[sr.name ()] = sr; - } - - bool is_nested (void) const { return m_is_nested; } - - void mark_nested (void) { m_is_nested = true; } - - bool is_static (void) const { return m_is_static; } - - void mark_static (void) { m_is_static = true; } - - scope * parent_scope (void) const { return m_parent; } - octave_value parent_fcn (void) const { return m_parent_fcn; } - - scope * dup (void) const - { - scope *new_sid = new scope (); - - for (const auto& nm_sr : m_symbols) - new_sid->insert_symbol_record (nm_sr.second.dup (new_sid)); - - new_sid->m_parent = m_parent; - new_sid->m_parent_fcn = m_parent_fcn; - - return new_sid; - } - - void set_context (context_id context) { m_context = context; } - - context_id current_context (void) const { return m_context; } - - symbol_table::symbol_record find_symbol (const std::string& name) - { - table_iterator p = m_symbols.find (name); - - if (p == m_symbols.end ()) - return insert (name); - else - return p->second; - } - - void inherit_internal (scope& donor_scope) - { - for (auto& nm_sr : m_symbols) - { - symbol_table::symbol_record& sr = nm_sr.second; - - if (! (sr.is_automatic () || sr.is_formal ())) - { - std::string nm = sr.name (); - - if (nm != "__retval__") - { - octave_value val = donor_scope.varval (nm); - - if (val.is_defined ()) - { - sr.assign (val); - - sr.mark_inherited (); - } - } - } - } - } - - 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); - - octave_value builtin_find (const std::string& name); - - symbol_table::symbol_record& - insert (const std::string& name, bool force_add = false); - - void rename (const std::string& old_name, const std::string& new_name) - { - table_iterator p = m_symbols.find (old_name); - - if (p != m_symbols.end ()) - { - symbol_table::symbol_record sr = p->second; - - sr.rename (new_name); - - m_symbols.erase (p); - - m_symbols[new_name] = sr; - } - } - - void assign (const std::string& name, const octave_value& value, - bool force_add) - { - table_iterator p = m_symbols.find (name); - - if (p == m_symbols.end ()) - { - symbol_table::symbol_record& sr = insert (name, force_add); - - sr.assign (value); - } - else - p->second.assign (value); - } - - void assign (const std::string& name, - const octave_value& value = octave_value ()) - { - assign (name, value, false); - } - - void force_assign (const std::string& name, const octave_value& value) - { - table_iterator p = m_symbols.find (name); - - if (p == m_symbols.end ()) - { - symbol_table::symbol_record& sr = insert (name, true); - - sr.assign (value); - } - else - p->second.assign (value); - } - - // Use assign (name, value, force_add) instead. - // Delete when deprecated varref functions are removed. - octave_value& varref (const std::string& name, bool force_add) - { - table_iterator p = m_symbols.find (name); - - if (p == m_symbols.end ()) - { - symbol_table::symbol_record& sr = insert (name, force_add); - - return sr.varref (); - } - else - return p->second.varref (); - } - - octave_value varval (const std::string& name) const - { - table_const_iterator p = m_symbols.find (name); - - return (p != m_symbols.end () - ? p->second.varval () : octave_value ()); - } - - void persistent_assign (const std::string& name, const octave_value& value) - { - m_persistent_symbols_iterator p = m_persistent_symbols.find (name); - - if (p == m_persistent_symbols.end ()) - m_persistent_symbols[name] = value; - else - p->second = value; - } - - // Use persistent_assign (name, value) instead. - // Delete when deprecated varref functions are removed. - octave_value& persistent_varref (const std::string& name) - { - m_persistent_symbols_iterator p = m_persistent_symbols.find (name); - - return (p == m_persistent_symbols.end () - ? m_persistent_symbols[name] : p->second); - } - - octave_value persistent_varval (const std::string& name) const - { - m_persistent_symbols_const_iterator p = m_persistent_symbols.find (name); - - return (p != m_persistent_symbols.end ()) ? p->second : octave_value (); - } - - void erase_persistent (const std::string& name) - { - m_persistent_symbols_iterator p = m_persistent_symbols.find (name); - - if (p != m_persistent_symbols.end ()) - m_persistent_symbols.erase (p); - } - - bool is_variable (const std::string& name) const - { - bool retval = false; - - table_const_iterator p = m_symbols.find (name); - - if (p != m_symbols.end ()) - { - const symbol_table::symbol_record& sr = p->second; - - retval = sr.is_variable (); - } - - return retval; - } - - void push_context (void) - { - for (auto& nm_sr : m_symbols) - nm_sr.second.push_context (this); - } - - void pop_context (void) - { - table_iterator tbl_it = m_symbols.begin (); - - while (tbl_it != m_symbols.end ()) - { - if (tbl_it->second.pop_context (this) == 0) - m_symbols.erase (tbl_it++); - else - tbl_it++; - } - } - - void clear_variables (void) - { - for (auto& nm_sr : m_symbols) - nm_sr.second.clear (this); - } - - void clear_objects (void) - { - for (auto& nm_sr : m_symbols) - { - symbol_table::symbol_record& sr = nm_sr.second; - octave_value val = sr.varval (); - if (val.isobject ()) - nm_sr.second.clear (this); - } - } - - void clear_global (const std::string& name); - - void clear_variable (const std::string& name) - { - table_iterator p = m_symbols.find (name); - - if (p != m_symbols.end ()) - p->second.clear (this); - } - - void clear_global_pattern (const std::string& pat); - - void clear_variable_pattern (const std::string& pat) - { - glob_match pattern (pat); - - for (auto& nm_sr : m_symbols) - { - symbol_table::symbol_record& sr = nm_sr.second; - - if (sr.is_defined () || sr.is_global ()) - { - if (pattern.match (sr.name ())) - sr.clear (this); - } - } - } - - void clear_variable_regexp (const std::string& pat) - { - octave::regexp pattern (pat); - - for (auto& nm_sr : m_symbols) - { - symbol_table::symbol_record& sr = nm_sr.second; - - if (sr.is_defined () || sr.is_global ()) - { - if (pattern.is_match (sr.name ())) - sr.clear (this); - } - } - } - - void mark_automatic (const std::string& name) - { - insert (name).mark_automatic (); - } - - void mark_hidden (const std::string& name) - { - insert (name).mark_hidden (); - } - - void mark_global (const std::string& name) - { - insert (name).mark_global (); - } - - std::list<symbol_table::symbol_record> - all_variables (bool defined_only = true, - unsigned int exclude = symbol_table::symbol_record::hidden) const - { - std::list<symbol_table::symbol_record> retval; - - for (const auto& nm_sr : m_symbols) - { - const symbol_table::symbol_record& sr = nm_sr.second; - - if ((defined_only && ! sr.is_defined ()) - || (sr.xstorage_class () & exclude)) - continue; - - retval.push_back (sr); - } - - return retval; - } - - std::list<symbol_table::symbol_record> - glob (const std::string& pattern, bool vars_only = false) const - { - std::list<symbol_table::symbol_record> retval; - - glob_match pat (pattern); - - for (const auto& nm_sr : m_symbols) - { - if (pat.match (nm_sr.first)) - { - const symbol_table::symbol_record& sr = nm_sr.second; - - if (vars_only && ! sr.is_variable ()) - continue; - - retval.push_back (sr); - } - } - - return retval; - } - - std::list<symbol_table::symbol_record> - regexp (const std::string& pattern, bool vars_only = false) const - { - std::list<symbol_table::symbol_record> retval; - - octave::regexp pat (pattern); - - for (const auto& nm_sr : m_symbols) - { - if (pat.is_match (nm_sr.first)) - { - const symbol_table::symbol_record& sr = nm_sr.second; - - if (vars_only && ! sr.is_variable ()) - continue; - - retval.push_back (sr); - } - } - - return retval; - } - - std::list<std::string> variable_names (void) - { - std::list<std::string> retval; - - for (const auto& nm_sr : m_symbols) - { - if (nm_sr.second.is_variable ()) - retval.push_back (nm_sr.first); - } - - retval.sort (); - - return retval; - } - - bool is_local_variable (const std::string& name) const - { - table_const_iterator p = m_symbols.find (name); - - return (p != m_symbols.end () - && ! p->second.is_global () - && p->second.is_defined ()); - } - - bool is_global (const std::string& name) const - { - table_const_iterator p = m_symbols.find (name); - - return p != m_symbols.end () && p->second.is_global (); - } - - void install_subfunction (const std::string& name, - 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) - { - for (auto& nm_sf : m_subfunctions) - nm_sf.second.lock (); - } - - void unlock_subfunctions (void) - { - for (auto& nm_sf : m_subfunctions) - nm_sf.second.unlock (); - } - - std::map<std::string, octave_value> subfunctions (void) - { - return m_subfunctions; - } - - void erase_subfunctions (void) - { - m_subfunctions.clear (); - } - - void mark_subfunctions_in_scope_as_private (const std::string& class_name); - - std::list<workspace_element> workspace_info (void) const; - - octave_value dump (void) const; - - std::string name (void) const { return m_name; } - - void cache_name (const std::string& name) { m_name = name; } - - octave_user_function *function (void) { return m_fcn; } - - void set_function (octave_user_function *fcn) { m_fcn = fcn; } - - void set_parent (scope *p); - - void update_nest (void); - - bool look_nonlocal (const std::string& name, - symbol_table::symbol_record& result); - - void bind_script_symbols (scope *curr_scope); - - void unbind_script_symbols (void); - - private: - - // Name for this scope (usually the corresponding filename of the - // function corresponding to the scope). - std::string m_name; - - // Map from symbol names to symbol info. - std::map<std::string, symbol_table::symbol_record> m_symbols; - - // Map from names of persistent variables to values. - std::map<std::string, octave_value> m_persistent_symbols; - - // Map from symbol names to subfunctions. - std::map<std::string, octave_value> m_subfunctions; - - // The associated user code (may be null). - octave_user_function *m_fcn; - - // Parent of nested function (may be null). - scope *m_parent; - octave_value m_parent_fcn; - - // Child nested functions. - std::vector<scope*> m_children; - - // If true, then this scope belongs to a nested function. - bool m_is_nested; - - // If true then no variables can be added. - bool m_is_static; - - context_id m_context; - - octave_value dump_symbols_map (void) const; - }; - private: typedef std::map<std::string, octave_value>::const_iterator