Mercurial > octave
changeset 24356:8b14ba8296af
refactor symbol_record object
When referencing non-local variables, look in correct parent scope
context. Cache pointer to parent scope for non-local access. Don't
cache pointer to declaration scope.
* symrec.h, symrec.cc (symbol_record::symbol_record_rep::m_fwd_scope):
New data member.
(symbol_record::symbol_record_rep::symbol_record_rep):
Eliminate symbol_scope argument. Change all uses.
(symbol_record::symbol_record_rep::assign,
symbol_record::symbol_record_rep::do_non_const_unary_op):
New argument, context Change all uses. Don't look to forward
reference here.
(symbol_record::symbol_record_rep::varref,
symbol_record::symbol_record_rep::varval): New argument, context.
Change all uses. Use context from forward scope when forwarding to
non-local reference.
(symbol_record::symbol_record_rep::clear,
symbol_record::symbol_record_rep::is_defind,
symbol_record::symbol_record_rep::is_variable,
symbol_record::symbol_record_rep::dump): New argument, context.
Change all uses.
(symbol_record::symbol_record_rep::bind_fwd_rep): New argument,
fwd_scope. Change all uses.
(symbol_record::symbol_record_rep::bind_fwd_rep,
symbol_record::symbol_record_rep::unbind_fwd_rep): Return after forwarding.
(symbol_record::symbol_record_rep::get_fwd_scope_context): New function.
(symbol_record::symbol_record_rep::get_decl_scope_context): Delete.
(symbol_record::symbol_record_rep::m_decl_scope): Delete data
member and all uses.
(symbol_record::symbol_record): Eliminate symbol_scope argument.
Change all uses.
(symbol_record::find, symbol_record::assign,
symbol_record::do_non_const_unary_opt, symbol_record::varval,
symbol_record::clear, symbol_record::is_defined,
symbol_record::is_undefined, symbol_record::is_valid,
symbol_record::is_variable, symbol_record::dump): New arg, context.
Change all uses.
(symbol_record::decl_scope): Delete.
(symbol_record::bind_fwd_rep): New arg, fwd_scope. Change all uses.
* load-save.h, load-save.cc (do_save): New argument, context. Change
all uses.
(save_vars): Work with scope instead of symbol table.
* variables.cc (symbol_info::symbol_info, symbol_info::append): New
arg, context. Change all uses.
* oct-lvalue.h, oct-lvalue.cc (octave_lvalue::m_context):
New data member.
(octave_lvalue::octave_lvalue): New argument, context.
Change all uses.
* pt-decl.h (tree_decl_elt::is_defined, tree_decl_elt::is_variable):
New argument, context. Change all uses.
* pt-id.h, pt-id.cc (tree_identifier::link_to_global):
New argument, global_scope.
(tree_identifier::is_defined, tree_identifier::is_variable,
tree_black_hole::is_variable): New argument, context. Change all
uses.
* pt-misc.h, pt-misc.cc (tree_parameter_list::is_defined): New
argument, context. Change all uses.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Mon, 04 Dec 2017 12:30:40 -0500 |
parents | cc3b3ceb155c |
children | ff4717c3223f |
files | libinterp/corefcn/load-save.cc libinterp/corefcn/symrec.cc libinterp/corefcn/symrec.h libinterp/corefcn/symscope.cc libinterp/corefcn/symscope.h libinterp/corefcn/variables.cc libinterp/octave-value/ov-fcn-handle.cc libinterp/parse-tree/lex.ll libinterp/parse-tree/oct-lvalue.cc libinterp/parse-tree/oct-lvalue.h libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/pt-decl.h libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-id.cc libinterp/parse-tree/pt-id.h libinterp/parse-tree/pt-idx.cc libinterp/parse-tree/pt-jit.cc libinterp/parse-tree/pt-misc.cc libinterp/parse-tree/pt-misc.h |
diffstat | 19 files changed, 276 insertions(+), 225 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/load-save.cc Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/corefcn/load-save.cc Mon Dec 04 12:30:40 2017 -0500 @@ -960,9 +960,10 @@ void do_save (std::ostream& os, const octave::symbol_record& sr, + octave::symbol_record::context_id context, load_save_format fmt, bool save_as_floats) { - octave_value val = sr.varval (); + octave_value val = sr.varval (context); if (val.is_defined ()) { @@ -1009,15 +1010,17 @@ save_vars (std::ostream& os, const std::string& pattern, load_save_format fmt, bool save_as_floats) { - octave::symbol_table& symtab = octave::__get_symbol_table__ ("save_vars"); + octave::symbol_scope *scope = octave::__require_current_scope__ ("save_vars"); - std::list<octave::symbol_record> vars = symtab.glob (pattern); + octave::symbol_record::context_id context = scope->current_context (); + + std::list<octave::symbol_record> vars = scope->glob (pattern); size_t saved = 0; for (const auto& var : vars) { - do_save (os, var, fmt, save_as_floats); + do_save (os, var, context, fmt, save_as_floats); saved++; } @@ -1334,13 +1337,15 @@ octave::symbol_scope *top_scope = symtab.top_scope (); + octave::symbol_record::context_id context = top_scope->current_context (); + std::list<octave::symbol_record> vars = top_scope->all_variables (); double save_mem_size = 0; for (const auto& var : vars) { - octave_value val = var.varval (); + octave_value val = var.varval (context); if (val.is_defined ()) {
--- a/libinterp/corefcn/symrec.cc Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/corefcn/symrec.cc Mon Dec 04 12:30:40 2017 -0500 @@ -42,9 +42,9 @@ namespace octave { symbol_record::context_id - symbol_record::symbol_record_rep::get_decl_scope_context (void) const + symbol_record::symbol_record_rep::get_fwd_scope_context (void) const { - return m_decl_scope ? m_decl_scope->current_context () : 0; + return m_fwd_scope ? m_fwd_scope->current_context () : 0; } void @@ -66,15 +66,17 @@ if (auto t_fwd_rep = m_fwd_rep.lock ()) return t_fwd_rep->dup (new_scope); - return new symbol_record_rep (new_scope, m_name, varval (), + static const context_id FIXME_CONTEXT = 0; + + return new symbol_record_rep (m_name, varval (FIXME_CONTEXT), m_storage_class); } octave_value - symbol_record::symbol_record_rep::dump (void) const + symbol_record::symbol_record_rep::dump (context_id context) const { if (auto t_fwd_rep = m_fwd_rep.lock ()) - return t_fwd_rep->dump (); + return t_fwd_rep->dump (context); std::map<std::string, octave_value> m = {{ "name", m_name }, @@ -86,7 +88,7 @@ { "global", is_global () }, { "persistent", is_persistent () }}; - octave_value val = varval (); + octave_value val = varval (context); if (val.is_defined ()) m["value"] = val; @@ -94,21 +96,16 @@ return octave_value (m); } - symbol_record::symbol_record (void) - : m_rep (new symbol_record_rep (__get_current_scope__ ("symbol_record"), - "", octave_value (), local)) - - { } - octave_value - symbol_record::find (const octave_value_list& args) const + symbol_record::find (context_id context, + const octave_value_list& args) const { octave_value retval; symbol_table& symtab = __get_symbol_table__ ("symbol_record::find"); - retval = varval (); + retval = varval (context); if (retval.is_undefined ()) {
--- a/libinterp/corefcn/symrec.h Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/corefcn/symrec.h Mon Dec 04 12:30:40 2017 -0500 @@ -78,11 +78,10 @@ { public: - symbol_record_rep (symbol_scope *s, const std::string& nm, + symbol_record_rep (const std::string& nm, const octave_value& v, unsigned int sc) - : m_decl_scope (s), m_name (nm), - m_fwd_rep (), m_value_stack (), m_storage_class (sc), - m_valid (true) + : m_storage_class (sc), m_name (nm), m_fwd_scope (nullptr), + m_fwd_rep (), m_value_stack (), m_valid (true) { m_value_stack.push_back (v); } @@ -95,77 +94,48 @@ ~symbol_record_rep (void) = default; - void assign (const octave_value& value) + void assign (const octave_value& value, context_id context) { - if (auto t_fwd_rep = m_fwd_rep.lock ()) - { - t_fwd_rep->assign (value); - return; - } - - varref () = value; + varref(context) = value; } void assign (octave_value::assign_op op, const std::string& type, const std::list<octave_value_list>& idx, - const octave_value& value) + const octave_value& value, context_id context) { - if (auto t_fwd_rep = m_fwd_rep.lock ()) - { - t_fwd_rep->assign (op, type, idx, value); - return; - } - - varref().assign (op, type, idx, value); + varref(context).assign (op, type, idx, value); } - void assign (octave_value::assign_op op, const octave_value& value) + void assign (octave_value::assign_op op, const octave_value& value, + context_id context) { - if (auto t_fwd_rep = m_fwd_rep.lock ()) - { - t_fwd_rep->assign (op, value); - return; - } - - varref().assign (op, value); + varref(context).assign (op, value); } - void do_non_const_unary_op (octave_value::unary_op op) + void do_non_const_unary_op (octave_value::unary_op op, + context_id context) { - if (auto t_fwd_rep = m_fwd_rep.lock ()) - { - t_fwd_rep->do_non_const_unary_op (op); - return; - } - - varref().do_non_const_unary_op (op); + varref(context).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) + const std::list<octave_value_list>& idx, + context_id context) { - if (auto t_fwd_rep = m_fwd_rep.lock ()) - { - t_fwd_rep->do_non_const_unary_op (op, type, idx); - return; - } - - varref().do_non_const_unary_op (op, type, idx); + varref(context).do_non_const_unary_op (op, type, idx); } - context_id get_decl_scope_context (void) const; + context_id get_fwd_scope_context (void) const; - octave_value& varref (void) + octave_value& varref (context_id context) { if (auto t_fwd_rep = m_fwd_rep.lock ()) - return t_fwd_rep->varref (); + return t_fwd_rep->varref (get_fwd_scope_context ()); - context_id context = 0; - - if (m_decl_scope && ! (is_persistent () || is_global ())) - context = get_decl_scope_context (); + if (is_persistent ()) + context = 0; context_id n = m_value_stack.size (); while (n++ <= context) @@ -174,15 +144,13 @@ return m_value_stack[context]; } - octave_value varval (void) const + octave_value varval (context_id context) const { if (auto t_fwd_rep = m_fwd_rep.lock ()) - return t_fwd_rep->varval (); + return t_fwd_rep->varval (get_fwd_scope_context ()); - context_id context = 0; - - if (m_decl_scope && ! (is_persistent () || is_global ())) - context = get_decl_scope_context (); + if (is_persistent ()) + context = 0; if (context < m_value_stack.size ()) return m_value_stack[context]; @@ -229,7 +197,7 @@ return retval; } - void clear (void) + void clear (context_id context) { // There is no need to do anything with a fowarded // symbol_record_rep here. @@ -251,19 +219,16 @@ if (is_global ()) unbind_fwd_rep (); - assign (octave_value ()); + assign (octave_value (), context); if (is_persistent ()) unmark_persistent (); } } - bool is_defined (void) const + bool is_defined (context_id context) const { - if (auto t_fwd_rep = m_fwd_rep.lock ()) - return t_fwd_rep->is_defined (); - - return varval ().is_defined (); + return varval (context).is_defined (); } bool is_valid (void) const @@ -274,12 +239,12 @@ return m_valid; } - bool is_variable (void) const + bool is_variable (context_id context) const { if (auto t_fwd_rep = m_fwd_rep.lock ()) - return t_fwd_rep->is_variable (); + return t_fwd_rep->is_variable (context); - return (! is_local () || is_defined ()); + return (! is_local () || is_defined (context)); } bool is_local (void) const @@ -527,33 +492,34 @@ m_valid = false; } - symbol_scope *decl_scope (void) + void bind_fwd_rep (symbol_scope *fwd_scope, + const std::shared_ptr<symbol_record_rep>& fwd_rep) { if (auto t_fwd_rep = m_fwd_rep.lock ()) - return t_fwd_rep->decl_scope (); - - return m_decl_scope; - } + { + t_fwd_rep->bind_fwd_rep (fwd_scope, fwd_rep); + return; + } - void bind_fwd_rep (const std::shared_ptr<symbol_record_rep>& fwd_rep) - { - if (auto t_fwd_rep = m_fwd_rep.lock ()) - t_fwd_rep->bind_fwd_rep (fwd_rep); - + m_fwd_scope = fwd_scope; m_fwd_rep = fwd_rep; } void unbind_fwd_rep (void) { if (auto t_fwd_rep = m_fwd_rep.lock ()) - t_fwd_rep->unbind_fwd_rep (); + { + t_fwd_rep->unbind_fwd_rep (); + return; + } + m_fwd_scope = nullptr; m_fwd_rep.reset (); } symbol_record_rep * dup (symbol_scope *new_scope) const; - octave_value dump (void) const; + octave_value dump (context_id context) const; std::string name (void) const { return m_name; } @@ -561,27 +527,26 @@ private: - symbol_scope *m_decl_scope; + unsigned int m_storage_class; std::string m_name; + symbol_scope *m_fwd_scope; + std::weak_ptr<symbol_record_rep> m_fwd_rep; std::deque<octave_value> m_value_stack; - unsigned int m_storage_class; - bool m_valid; }; public: - symbol_record (void); - - symbol_record (symbol_scope *s, const std::string& nm = "", + symbol_record (const std::string& nm = "", const octave_value& v = octave_value (), unsigned int sc = local) - : m_rep (new symbol_record_rep (s, nm, v, sc)) { } + : m_rep (new symbol_record_rep (nm, v, sc)) + { } symbol_record (const symbol_record& sr) = default; @@ -599,57 +564,60 @@ void rename (const std::string& new_name) { m_rep->rename (new_name); } octave_value - find (const octave_value_list& args = octave_value_list ()) const; + find (context_id context, + const octave_value_list& args = octave_value_list ()) const; - void assign (const octave_value& value) + void assign (const octave_value& value, context_id context) { - m_rep->assign (value); + m_rep->assign (value, context); } void assign (octave_value::assign_op op, const std::string& type, const std::list<octave_value_list>& idx, - const octave_value& value) + const octave_value& value, context_id context) { - m_rep->assign (op, type, idx, value); + m_rep->assign (op, type, idx, value, context); } - void assign (octave_value::assign_op op, const octave_value& value) + void assign (octave_value::assign_op op, const octave_value& value, + context_id context) { - m_rep->assign (op, value); + m_rep->assign (op, value, context); } - void do_non_const_unary_op (octave_value::unary_op op) + void do_non_const_unary_op (octave_value::unary_op op, context_id context) { - m_rep->do_non_const_unary_op (op); + m_rep->do_non_const_unary_op (op, context); } void do_non_const_unary_op (octave_value::unary_op op, const std::string& type, - const std::list<octave_value_list>& idx) + const std::list<octave_value_list>& idx, + context_id context) { - m_rep->do_non_const_unary_op (op, type, idx); + m_rep->do_non_const_unary_op (op, type, idx, context); } - octave_value varval (void) const + octave_value varval (context_id context) const { - return m_rep->varval (); + return m_rep->varval (context); } void push_context (void) { m_rep->push_context (); } size_t pop_context (void) { return m_rep->pop_context (); } - void clear (void) { m_rep->clear (); } + void clear (context_id context) { m_rep->clear (context); } - bool is_defined (void) const + bool is_defined (context_id context) const { - return m_rep->is_defined (); + return m_rep->is_defined (context); } - bool is_undefined (void) const + bool is_undefined (context_id context) const { - return ! m_rep->is_defined (); + return ! m_rep->is_defined (context); } bool is_valid (void) const @@ -657,9 +625,9 @@ return m_rep->is_valid (); } - bool is_variable (void) const + bool is_variable (context_id context) const { - return m_rep->is_variable (); + return m_rep->is_variable (context); } bool is_local (void) const { return m_rep->is_local (); } @@ -692,18 +660,19 @@ void invalidate (void) { m_rep->invalidate (); } - symbol_scope *decl_scope (void) { return m_rep->decl_scope (); } - unsigned int storage_class (void) const { return m_rep->storage_class (); } - void bind_fwd_rep (const symbol_record& sr) + void bind_fwd_rep (symbol_scope *fwd_scope, const symbol_record& sr) { - m_rep->bind_fwd_rep (sr.m_rep); + m_rep->bind_fwd_rep (fwd_scope, sr.m_rep); } void unbind_fwd_rep (void) { m_rep->unbind_fwd_rep (); } - octave_value dump (void) const { return m_rep->dump (); } + octave_value dump (context_id context) const + { + return m_rep->dump (context); + } private:
--- a/libinterp/corefcn/symscope.cc Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/corefcn/symscope.cc Mon Dec 04 12:30:40 2017 -0500 @@ -60,7 +60,7 @@ return symtab.global_varval (name); else { - octave_value val = sr.varval (); + octave_value val = sr.varval (m_context); if (val.is_defined ()) return val; @@ -90,7 +90,7 @@ if (p == m_symbols.end ()) { - symbol_record ret (this, name); + symbol_record ret (name); if (m_is_nested && m_parent && m_parent->look_nonlocal (name, ret)) return m_symbols[name] = ret; @@ -118,7 +118,7 @@ if (! sr.is_hidden ()) { - octave_value val = sr.varval (); + octave_value val = sr.varval (m_context); if (val.is_defined ()) { @@ -180,7 +180,7 @@ { std::string nm = nm_sr.first; const symbol_record& sr = nm_sr.second; - info_map[nm] = sr.dump (); + info_map[nm] = sr.dump (m_context); } return octave_value (info_map); @@ -301,7 +301,7 @@ } else if (! p->second.is_automatic ()) { - result.bind_fwd_rep (p->second); + result.bind_fwd_rep (this, p->second); return true; } @@ -312,7 +312,8 @@ symbol_scope::bind_script_symbols (symbol_scope *curr_scope) { for (auto& nm_sr : m_symbols) - nm_sr.second.bind_fwd_rep (curr_scope->find_symbol (nm_sr.first)); + nm_sr.second.bind_fwd_rep (curr_scope, + curr_scope->find_symbol (nm_sr.first)); } void
--- a/libinterp/corefcn/symscope.h Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/corefcn/symscope.h Mon Dec 04 12:30:40 2017 -0500 @@ -137,7 +137,7 @@ if (val.is_defined ()) { - sr.assign (val); + sr.assign (val, m_context); sr.mark_inherited (); } @@ -192,10 +192,10 @@ { symbol_record& sr = insert (name, force_add); - sr.assign (value); + sr.assign (value, m_context); } else - p->second.assign (value); + p->second.assign (value, m_context); } void assign (const std::string& name, @@ -212,10 +212,10 @@ { symbol_record& sr = insert (name, true); - sr.assign (value); + sr.assign (value, m_context); } else - p->second.assign (value); + p->second.assign (value, m_context); } octave_value varval (const std::string& name) const @@ -223,7 +223,7 @@ table_const_iterator p = m_symbols.find (name); return (p != m_symbols.end () - ? p->second.varval () : octave_value ()); + ? p->second.varval (m_context) : octave_value ()); } bool is_variable (const std::string& name) const @@ -236,7 +236,7 @@ { const symbol_record& sr = p->second; - retval = sr.is_variable (); + retval = sr.is_variable (m_context); } return retval; @@ -268,14 +268,14 @@ symbol_record& sr = nm_sr.second; if (! sr.is_persistent ()) - sr.clear (); + sr.clear (m_context); } } void clear_variables (void) { for (auto& nm_sr : m_symbols) - nm_sr.second.clear (); + nm_sr.second.clear (m_context); } void clear_objects (void) @@ -283,9 +283,9 @@ for (auto& nm_sr : m_symbols) { symbol_record& sr = nm_sr.second; - octave_value val = sr.varval (); + octave_value val = sr.varval (m_context); if (val.isobject ()) - nm_sr.second.clear (); + nm_sr.second.clear (m_context); } } @@ -294,7 +294,7 @@ table_iterator p = m_symbols.find (name); if (p != m_symbols.end ()) - p->second.clear (); + p->second.clear (m_context); } void clear_variable_pattern (const std::string& pat) @@ -305,10 +305,10 @@ { symbol_record& sr = nm_sr.second; - if (sr.is_defined () || sr.is_global ()) + if (sr.is_defined (m_context) || sr.is_global ()) { if (pattern.match (sr.name ())) - sr.clear (); + sr.clear (m_context); } } } @@ -321,10 +321,10 @@ { symbol_record& sr = nm_sr.second; - if (sr.is_defined () || sr.is_global ()) + if (sr.is_defined (m_context) || sr.is_global ()) { if (pattern.is_match (sr.name ())) - sr.clear (); + sr.clear (m_context); } } } @@ -354,7 +354,7 @@ { const symbol_record& sr = nm_sr.second; - if ((defined_only && ! sr.is_defined ()) + if ((defined_only && ! sr.is_defined (m_context)) || (sr.storage_class () & exclude)) continue; @@ -377,7 +377,7 @@ { const symbol_record& sr = nm_sr.second; - if (vars_only && ! sr.is_variable ()) + if (vars_only && ! sr.is_variable (m_context)) continue; retval.push_back (sr); @@ -400,7 +400,7 @@ { const symbol_record& sr = nm_sr.second; - if (vars_only && ! sr.is_variable ()) + if (vars_only && ! sr.is_variable (m_context)) continue; retval.push_back (sr); @@ -416,7 +416,7 @@ for (const auto& nm_sr : m_symbols) { - if (nm_sr.second.is_variable ()) + if (nm_sr.second.is_variable (m_context)) retval.push_back (nm_sr.first); } @@ -431,7 +431,7 @@ return (p != m_symbols.end () && ! p->second.is_global () - && p->second.is_defined ()); + && p->second.is_defined (m_context)); } bool is_global (const std::string& name) const
--- a/libinterp/corefcn/variables.cc Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/corefcn/variables.cc Mon Dec 04 12:30:40 2017 -0500 @@ -1131,6 +1131,7 @@ struct symbol_info { symbol_info (const octave::symbol_record& sr, + octave::symbol_record::context_id context, const std::string& expr_str = "", const octave_value& expr_val = octave_value ()) : name (expr_str.empty () ? sr.name () : expr_str), @@ -1141,7 +1142,8 @@ is_global (sr.is_global ()), is_persistent (sr.is_persistent ()) { - varval = (expr_val.is_undefined () ? sr.varval () : expr_val); + varval = (expr_val.is_undefined () + ? sr.varval (context) : expr_val); is_complex = varval.iscomplex (); } @@ -1294,16 +1296,18 @@ ~symbol_info_list (void) = default; - void append (const octave::symbol_record& sr) + void append (const octave::symbol_record& sr, + octave::symbol_record::context_id context) { - lst.push_back (symbol_info (sr)); + lst.push_back (symbol_info (sr, context)); } void append (const octave::symbol_record& sr, + octave::symbol_record::context_id context, const std::string& expr_str, const octave_value& expr_val) { - lst.push_back (symbol_info (sr, expr_str, expr_val)); + lst.push_back (symbol_info (sr, context, expr_str, expr_val)); } size_t size (void) const { return lst.size (); } @@ -1695,6 +1699,8 @@ octave::symbol_scope *scope = symtab.current_scope (); + octave::symbol_record::context_id context = scope->current_context (); + for (int j = 0; j < npats; j++) { std::string pat = pats[j]; @@ -1708,10 +1714,10 @@ for (const auto& symrec : tmp) { - if (symrec.is_variable ()) + if (symrec.is_variable (context)) { if (verbose) - symbol_stats.append (symrec); + symbol_stats.append (symrec, context); else symbol_names.push_back (symrec.name ()); } @@ -1746,7 +1752,7 @@ octave_value expr_val = octave::eval_string (pat, true, parse_status); - symbol_stats.append (sr, pat, expr_val); + symbol_stats.append (sr, context, pat, expr_val); } } } @@ -1760,10 +1766,10 @@ for (const auto& symrec : tmp) { - if (symrec.is_variable ()) + if (symrec.is_variable (context)) { if (verbose) - symbol_stats.append (symrec); + symbol_stats.append (symrec, context); else symbol_names.push_back (symrec.name ()); }
--- a/libinterp/octave-value/ov-fcn-handle.cc Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/octave-value/ov-fcn-handle.cc Mon Dec 04 12:30:40 2017 -0500 @@ -61,6 +61,7 @@ #include "pt-misc.h" #include "pt-pr-code.h" #include "pt-stmt.h" +#include "symscope.h" #include "unwind-prot.h" #include "variables.h" @@ -353,8 +354,12 @@ octave_user_function *f = fcn.user_function_value (); octave::symbol_scope *f_scope = f->scope (); + octave::symbol_record::context_id context = 0; if (f_scope) - vars = f_scope->all_variables (); + { + vars = f_scope->all_variables (); + context = f_scope->current_context (); + } size_t varlen = vars.size (); @@ -364,8 +369,8 @@ for (const auto& symrec : vars) { - if (! save_text_data (os, symrec.varval (), symrec.name (), - false, 0)) + if (! save_text_data (os, symrec.varval (context), + symrec.name (), false, 0)) return ! os.fail (); } } @@ -530,8 +535,12 @@ octave_user_function *f = fcn.user_function_value (); octave::symbol_scope *f_scope = f->scope (); + octave::symbol_record::context_id context = 0; if (f_scope) - vars = f_scope->all_variables (); + { + vars = f_scope->all_variables (); + context = f_scope->current_context (); + } size_t varlen = vars.size (); @@ -556,8 +565,8 @@ { for (const auto& symrec : vars) { - if (! save_binary_data (os, symrec.varval (), symrec.name (), - "", 0, save_as_floats)) + if (! save_binary_data (os, symrec.varval (context), + symrec.name (), "", 0, save_as_floats)) return ! os.fail (); } } @@ -786,8 +795,12 @@ octave_user_function *f = fcn.user_function_value (); octave::symbol_scope *f_scope = f->scope (); + octave::symbol_record::context_id context = 0; if (f_scope) - vars = f_scope->all_variables (); + { + vars = f_scope->all_variables (); + context = f_scope->current_context (); + } size_t varlen = vars.size (); @@ -836,8 +849,8 @@ for (const auto& symrec : vars) { - if (! add_hdf5_data (data_hid, symrec.varval (), symrec.name (), - "", false, save_as_floats)) + if (! add_hdf5_data (data_hid, symrec.varval (context), + symrec.name (), "", false, save_as_floats)) break; } H5Gclose (data_hid); @@ -1759,8 +1772,12 @@ octave_user_function *fu = fh->user_function_value (); octave::symbol_scope *fu_scope = fu->scope (); + octave::symbol_record::context_id context = 0; if (fu_scope) - vars = fu_scope->all_variables (); + { + vars = fu_scope->all_variables (); + context = fu_scope->current_context (); + } size_t varlen = vars.size (); @@ -1768,7 +1785,7 @@ { octave_scalar_map ws; for (const auto& symrec : vars) - ws.assign (symrec.name (), symrec.varval ()); + ws.assign (symrec.name (), symrec.varval (context)); m.setfield ("workspace", ws); } @@ -1980,6 +1997,11 @@ if (arg_list && arg_list->length () > 0) { + octave::symbol_scope *scope = tw->get_current_scope (); + + octave::symbol_record::context_id context + = scope->current_context (); + bool bad = false; int nargs = arg_list->length (); octave_value_list arg_template (nargs); @@ -2005,7 +2027,7 @@ { arg_mask[iarg] = arginmap[elt_id->name ()]; } - else if (elt_id->is_defined ()) + else if (elt_id->is_defined (context)) { arg_template(iarg) = tw->evaluate (elt_id); arg_mask[iarg] = -1; @@ -2028,7 +2050,7 @@ if (! bad) { // If the head is a value, use it as root. - if (head_id->is_defined ()) + if (head_id->is_defined (context)) root_val = tw->evaluate (head_id); else {
--- a/libinterp/parse-tree/lex.ll Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/parse-tree/lex.ll Mon Dec 04 12:30:40 2017 -0500 @@ -3158,10 +3158,7 @@ symbol_scope *scope = symtab_context.curr_scope (); - symbol_record sr - = (scope - ? scope->insert (ident) - : symbol_record (scope, ident)); + symbol_record sr = (scope ? scope->insert (ident) : symbol_record (ident)); token *tok = new token (NAME, sr, input_line_number, current_input_column);
--- a/libinterp/parse-tree/oct-lvalue.cc Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/parse-tree/oct-lvalue.cc Mon Dec 04 12:30:40 2017 -0500 @@ -37,9 +37,9 @@ if (! is_black_hole ()) { if (m_idx.empty ()) - m_sym.assign (op, rhs); + m_sym.assign (op, rhs, m_context); else - m_sym.assign (op, m_type, m_idx, rhs); + m_sym.assign (op, m_type, m_idx, rhs, m_context); } } @@ -72,9 +72,9 @@ if (! is_black_hole ()) { if (m_idx.empty ()) - m_sym.do_non_const_unary_op (op); + m_sym.do_non_const_unary_op (op, m_context); else - m_sym.do_non_const_unary_op (op, m_type, m_idx); + m_sym.do_non_const_unary_op (op, m_type, m_idx, m_context); } } @@ -84,7 +84,7 @@ if (! is_black_hole ()) { - octave_value val = m_sym.varval (); + octave_value val = m_sym.varval (m_context); if (m_idx.empty ()) retval = val;
--- a/libinterp/parse-tree/oct-lvalue.h Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/parse-tree/oct-lvalue.h Mon Dec 04 12:30:40 2017 -0500 @@ -36,8 +36,14 @@ { public: - octave_lvalue (const symbol_record& sr = symbol_record ()) - : m_sym (sr), m_black_hole (false), m_type (), m_idx (), m_nel (1) + octave_lvalue (void) + : m_sym (), m_context (0), m_black_hole (false), m_type (), + m_idx (), m_nel (1) + { } + + octave_lvalue (const symbol_record& sr, symbol_record::context_id context) + : m_sym (sr), m_context (context), m_black_hole (false), + m_type (), m_idx (), m_nel (1) { } octave_lvalue (const octave_lvalue& vr) = default; @@ -52,17 +58,17 @@ bool is_defined (void) const { - return ! is_black_hole () && m_sym.is_defined (); + return ! is_black_hole () && m_sym.is_defined (m_context); } bool is_undefined (void) const { - return is_black_hole () || m_sym.is_undefined (); + return is_black_hole () || m_sym.is_undefined (m_context); } bool isstruct (void) const { return value().isstruct (); } - void define (const octave_value& v) { m_sym.assign (v); } + void define (const octave_value& v) { m_sym.assign (v, m_context); } void assign (octave_value::assign_op, const octave_value&); @@ -86,6 +92,8 @@ symbol_record m_sym; + symbol_record::context_id m_context; + bool m_black_hole; std::string m_type;
--- a/libinterp/parse-tree/oct-parse.in.yy Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/parse-tree/oct-parse.in.yy Mon Dec 04 12:30:40 2017 -0500 @@ -5421,10 +5421,15 @@ if (expr->is_identifier ()) { + octave::symbol_scope *scope = tw.get_current_scope (); + + octave::symbol_record::context_id context + = scope->current_context (); + tree_identifier *id = dynamic_cast<tree_identifier *> (expr); - do_bind_ans = (! id->is_variable ()); + do_bind_ans = (! id->is_variable (context)); } else do_bind_ans = (! expr->is_assignment_expression ());
--- a/libinterp/parse-tree/pt-decl.h Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/parse-tree/pt-decl.h Mon Dec 04 12:30:40 2017 -0500 @@ -65,9 +65,15 @@ ~tree_decl_elt (void); - bool is_defined (void) { return id ? id->is_defined () : false; } + bool is_defined (symbol_record::context_id context) + { + return id ? id->is_defined (context) : false; + } - bool is_variable (void) { return id ? id->is_variable () : false; } + bool is_variable (symbol_record::context_id context) + { + return id ? id->is_variable (context) : false; + } void mark_as_formal_parameter (void) {
--- a/libinterp/parse-tree/pt-eval.cc Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/parse-tree/pt-eval.cc Mon Dec 04 12:30:40 2017 -0500 @@ -582,13 +582,17 @@ return varargout; else if (nargout <= len) { + symbol_scope *scope = get_current_scope (); + + symbol_record::context_id context = scope->current_context (); + octave_value_list retval (nargout); int i = 0; for (tree_decl_elt *elt : *ret_list) { - if (elt->is_defined ()) + if (elt->is_defined (context)) { octave_value tmp = evaluate (elt); retval(i) = tmp; @@ -716,7 +720,7 @@ symbol_record global_sym = symtab.find_global_symbol (id->name ()); - id->link_to_global (global_sym); + id->link_to_global (symtab.global_scope (), global_sym); } else if (elt.is_persistent ()) id->mark_persistent (); @@ -1037,9 +1041,13 @@ { octave_value_list retval; + symbol_scope *scope = get_current_scope (); + + symbol_record::context_id context = scope->current_context (); + symbol_record sym = expr.symbol (); - octave_value val = sym.find (); + octave_value val = sym.find (context); if (val.is_defined ()) { @@ -1145,8 +1153,16 @@ { std::string extra_message; + // FIXME: make this a member function for direct access to symbol + // table and scope? + + octave::symbol_scope *scope + = octave::__require_current_scope__ ("final_index_error"); + + octave::symbol_record::context_id context = scope->current_context (); + if (expr->is_identifier () - && dynamic_cast<const octave::tree_identifier *> (expr)->is_variable ()) + && dynamic_cast<const octave::tree_identifier *> (expr)->is_variable (context)) { std::string var = expr->name (); @@ -1272,7 +1288,11 @@ { tree_identifier *id = dynamic_cast<tree_identifier *> (expr); - if (! id->is_variable ()) + symbol_scope *scope = get_current_scope (); + + symbol_record::context_id context = scope->current_context (); + + if (! id->is_variable (context)) { octave_value_list first_args; @@ -1297,7 +1317,7 @@ octave_function *fcn = nullptr; - octave_value val = id->do_lookup (first_args); + octave_value val = id->do_lookup (context, first_args); if (val.is_function ()) fcn = val.function_value (true); @@ -2258,9 +2278,13 @@ if (expr->is_identifier ()) { + symbol_scope *scope = get_current_scope (); + + symbol_record::context_id context = scope->current_context (); + tree_identifier *id = dynamic_cast<tree_identifier *> (expr); - do_bind_ans = (! id->is_variable ()); + do_bind_ans = (! id->is_variable (context)); } else do_bind_ans = (! expr->is_assignment_expression ()); @@ -2447,11 +2471,10 @@ if (catch_code) { tree_identifier *expr_id = cmd.identifier (); - octave_lvalue ult; if (expr_id) { - ult = expr_id->lvalue (this); + octave_lvalue ult = expr_id->lvalue (this); octave_scalar_map err; @@ -2715,8 +2738,7 @@ } else { - symbol_scope *scope - = m_interpreter.require_current_scope ("tree_evaluator::bind_ans"); + symbol_scope *scope = get_current_scope (); scope->force_assign (ans, val);
--- a/libinterp/parse-tree/pt-id.cc Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/parse-tree/pt-id.cc Mon Dec 04 12:30:40 2017 -0500 @@ -40,10 +40,11 @@ class tree_evaluator; - void tree_identifier::link_to_global (const symbol_record& global_sym) + void tree_identifier::link_to_global (symbol_scope *global_scope, + const symbol_record& global_sym) { if (! sym.is_global ()) - sym.bind_fwd_rep (global_sym); + sym.bind_fwd_rep (global_scope, global_sym); } void @@ -64,12 +65,14 @@ } octave_lvalue - tree_identifier::lvalue (tree_evaluator *) + tree_identifier::lvalue (tree_evaluator *tw) { if (sym.is_added_static ()) static_workspace_error (); - return octave_lvalue (sym); + symbol_scope *scope = tw->get_current_scope (); + + return octave_lvalue (sym, scope->current_context ()); } tree_identifier *
--- a/libinterp/parse-tree/pt-id.h Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/parse-tree/pt-id.h Mon Dec 04 12:30:40 2017 -0500 @@ -71,9 +71,15 @@ std::string name (void) const { return sym.name (); } - bool is_defined (void) { return sym.is_defined (); } + bool is_defined (symbol_record::context_id context) + { + return sym.is_defined (context); + } - virtual bool is_variable (void) const { return sym.is_variable (); } + virtual bool is_variable (symbol_record::context_id context) const + { + return sym.is_variable (context); + } virtual bool is_black_hole (void) { return false; } @@ -93,12 +99,14 @@ // then .mex files, then .m files. octave_value - do_lookup (const octave_value_list& args = octave_value_list ()) + do_lookup (symbol_record::context_id context, + const octave_value_list& args = octave_value_list ()) { - return sym.find (args); + return sym.find (context, args); } - void link_to_global (const symbol_record& global_sym); + void link_to_global (symbol_scope *global_scope, + const symbol_record& global_sym); void mark_persistent (void) { sym.init_persistent (); } @@ -146,7 +154,7 @@ std::string name (void) const { return "~"; } - bool is_variable (void) const { return false; } + bool is_variable (symbol_record::context_id) const { return false; } bool is_black_hole (void) { return true; }
--- a/libinterp/parse-tree/pt-idx.cc Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/parse-tree/pt-idx.cc Mon Dec 04 12:30:40 2017 -0500 @@ -206,15 +206,17 @@ { std::string extra_message; + octave::symbol_table& symtab = octave::__get_symbol_table__ ("final_index_error"); + + octave::symbol_record::context_id context = symtab.current_context (); + if (expr->is_identifier () - && dynamic_cast<const octave::tree_identifier *> (expr)->is_variable ()) + && dynamic_cast<const octave::tree_identifier *> (expr)->is_variable (context)) { std::string var = expr->name (); e.set_var (var); - octave::symbol_table& symtab = octave::__get_symbol_table__ ("final_index_error"); - octave_value fcn = symtab.find_function (var); if (fcn.is_function ())
--- a/libinterp/parse-tree/pt-jit.cc Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/parse-tree/pt-jit.cc Mon Dec 04 12:30:40 2017 -0500 @@ -797,7 +797,7 @@ { tree_identifier *id = dynamic_cast<tree_identifier *> (expr); - do_bind_ans = (! id->is_variable ()); + do_bind_ans = (! id->is_variable (scope->current_context ())); } else do_bind_ans = (! expr->is_assignment_expression ()); @@ -1144,7 +1144,7 @@ return create_variable (vname, jit_typeinfo::get_any (), false); else { - octave_value val = record.varval (); + octave_value val = record.varval (scope->current_context ()); if (val.is_undefined ()) val = symtab.find_function (vname);
--- a/libinterp/parse-tree/pt-misc.cc Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/parse-tree/pt-misc.cc Mon Dec 04 12:30:40 2017 -0500 @@ -60,13 +60,13 @@ } bool - tree_parameter_list::is_defined (void) + tree_parameter_list::is_defined (symbol_record::context_id context) { bool status = true; for (tree_decl_elt *elt : *this) { - if (! elt->is_variable ()) + if (! elt->is_variable (context)) { status = false; break;
--- a/libinterp/parse-tree/pt-misc.h Mon Dec 04 01:26:06 2017 -0500 +++ b/libinterp/parse-tree/pt-misc.h Mon Dec 04 12:30:40 2017 -0500 @@ -76,7 +76,7 @@ bool varargs_only (void) { return (marked_for_varargs < 0); } - bool is_defined (void); + bool is_defined (symbol_record::context_id context); std::list<std::string> variable_names (void) const;