Mercurial > octave
view libinterp/corefcn/scope.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 | |
children |
line wrap: on
line source
/* Copyright (C) 1993-2017 John W. Eaton Copyright (C) 2009 VZLU Prague This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see <http://www.gnu.org/licenses/>. */ #if ! defined (octave_scope_h) #define octave_scope_h 1 #include "octave-config.h" #include <deque> #include <limits> #include <list> #include <map> #include <set> #include <string> #include "glob-match.h" #include "lo-regexp.h" #include "oct-refcount.h" class tree_argument_list; class octave_user_function; #include "ov.h" #include "ovl.h" #include "symrec.h" #include "workspace-element.h" namespace octave { class scope { public: typedef symbol_record::context_id context_id; typedef std::map<std::string, symbol_record>::const_iterator table_const_iterator; typedef std::map<std::string, 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_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_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_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); 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_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_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_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_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_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_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_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_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_record> all_variables (bool defined_only = true, unsigned int exclude = symbol_record::hidden) const { std::list<symbol_record> retval; for (const auto& nm_sr : m_symbols) { const 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_record> glob (const std::string& pattern, bool vars_only = false) const { std::list<symbol_record> retval; glob_match pat (pattern); for (const auto& nm_sr : m_symbols) { if (pat.match (nm_sr.first)) { const symbol_record& sr = nm_sr.second; if (vars_only && ! sr.is_variable ()) continue; retval.push_back (sr); } } return retval; } std::list<symbol_record> regexp (const std::string& pattern, bool vars_only = false) const { std::list<symbol_record> retval; octave::regexp pat (pattern); for (const auto& nm_sr : m_symbols) { if (pat.is_match (nm_sr.first)) { const 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_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_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; }; } #endif