changeset 14912:3d3c002ccc60

Add symbol_table::symbol_record_ref * src/symbtab.h (symbol_table::symbol_record_ref): New function. * src/pt-id.h (tree_identifier): Use symbol_record_ref instead of symbol_record. * src/pt-id.cc (tree_identifier): Use symbol_record_ref instead of symbol_record.
author Max Brister <max@2bass.com>
date Fri, 18 May 2012 08:53:26 -0600
parents 1e2196d0bea4
children c7071907a641
files src/pt-id.cc src/pt-id.h src/symtab.h
diffstat 3 files changed, 65 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/src/pt-id.cc	Fri May 18 08:11:00 2012 -0600
+++ b/src/pt-id.cc	Fri May 18 08:53:26 2012 -0600
@@ -63,7 +63,7 @@
   if (error_state)
     return retval;
 
-  octave_value val = xsym ().find ();
+  octave_value val = sym->find ();
 
   if (val.is_defined ())
     {
@@ -114,7 +114,7 @@
 octave_lvalue
 tree_identifier::lvalue (void)
 {
-  return octave_lvalue (&(xsym().varref ()));
+  return octave_lvalue (&(sym->varref ()));
 }
 
 tree_identifier *
--- a/src/pt-id.h	Fri May 18 08:11:00 2012 -0600
+++ b/src/pt-id.h	Fri May 18 08:53:26 2012 -0600
@@ -46,12 +46,12 @@
 public:
 
   tree_identifier (int l = -1, int c = -1)
-    : tree_expression (l, c), sym (), scope (-1) { }
+    : tree_expression (l, c) { }
 
   tree_identifier (const symbol_table::symbol_record& s,
                    int l = -1, int c = -1,
                    symbol_table::scope_id sc = symbol_table::current_scope ())
-    : tree_expression (l, c), sym (s), scope (sc) { }
+    : tree_expression (l, c), sym (s, sc) { }
 
   ~tree_identifier (void) { }
 
@@ -63,9 +63,9 @@
   // accessing it through sym so that this function may remain const.
   std::string name (void) const { return sym.name (); }
 
-  bool is_defined (void) { return xsym().is_defined (); }
+  bool is_defined (void) { return sym->is_defined (); }
 
-  virtual bool is_variable (void) { return xsym().is_variable (); }
+  virtual bool is_variable (void) { return sym->is_variable (); }
 
   virtual bool is_black_hole (void) { return false; }
 
@@ -87,14 +87,14 @@
   octave_value
   do_lookup (const octave_value_list& args = octave_value_list ())
   {
-    return xsym().find (args);
+    return sym->find (args);
   }
 
-  void mark_global (void) { xsym().mark_global (); }
+  void mark_global (void) { sym->mark_global (); }
 
-  void mark_as_static (void) { xsym().init_persistent (); }
+  void mark_as_static (void) { sym->init_persistent (); }
 
-  void mark_as_formal_parameter (void) { xsym().mark_formal (); }
+  void mark_as_formal_parameter (void) { sym->mark_formal (); }
 
   // We really need to know whether this symbol referst to a variable
   // or a function, but we may not know that yet.
@@ -117,25 +117,7 @@
 private:
 
   // The symbol record that this identifier references.
-  symbol_table::symbol_record sym;
-
-  symbol_table::scope_id scope;
-
-  // A script may be executed in multiple scopes.  If the last one was
-  // different from the one we are in now, update sym to be from the
-  // new scope.
-  symbol_table::symbol_record& xsym (void)
-  {
-    symbol_table::scope_id curr_scope = symbol_table::current_scope ();
-
-    if (scope != curr_scope || ! sym.is_valid ())
-      {
-        scope = curr_scope;
-        sym = symbol_table::insert (sym.name ());
-      }
-
-    return sym;
-  }
+  symbol_table::symbol_record_ref sym;
 
   // No copying!
 
--- a/src/symtab.h	Fri May 18 08:11:00 2012 -0600
+++ b/src/symtab.h	Fri May 18 08:53:26 2012 -0600
@@ -581,6 +581,60 @@
     symbol_record (symbol_record_rep *new_rep) : rep (new_rep) { }
   };
 
+  // Always access a symbol from the current scope.
+  // Useful for scripts, as they may be executed in more than one scope.
+  class
+  symbol_record_ref
+  {
+  public:
+    symbol_record_ref (void) : scope (-1) {}
+
+    symbol_record_ref (symbol_record record,
+                       scope_id curr_scope = symbol_table::current_scope ())
+      : scope (curr_scope), sym (record)
+    {}
+
+    symbol_record_ref& operator = (const symbol_record_ref& ref)
+    {
+      scope = ref.scope;
+      sym = ref.sym;
+      return *this;
+    }
+
+    // The name is the same regardless of scope.
+    const std::string& name (void) const { return sym.name (); }
+
+    symbol_record *operator-> (void)
+    {
+      update ();
+      return &sym;
+    }
+
+    // can be used to place symbol_record_ref in maps, we don't overload < as
+    // it doesn't make any sense for symbol_record_ref
+    struct comparator
+    {
+      bool operator ()(const symbol_record_ref& lhs,
+                       const symbol_record_ref& rhs) const
+      {
+        return lhs.name () < rhs.name ();
+      }
+    };
+  private:
+    void update (void)
+    {
+      scope_id curr_scope = symbol_table::current_scope ();
+      if (scope != curr_scope || ! sym.is_valid ())
+        {
+          scope = curr_scope;
+          sym = symbol_table::insert (sym.name ());
+        }
+    }
+
+    scope_id scope;
+    symbol_record sym;
+  };
+
   class
   fcn_info
   {