changeset 16320:09f0cb9cac7d

don't modify symbol table scope in the parser * symtab.h (symbol_table::insert): Accept scope as argument. * lex.h (symbol_table_context): New class. (octave_lexer::symtab_context: New data member. * parse-private.h: Delete. * parse.h, oct-parse.in.yy (parser_symtab_context): Delete global variable and all uses. * lex.ll (octave_lexer::reset): Clear symtab_context. (octave_base_lexer::handle_superclass_identifier, octave_base_lexer::handle_meta_identifier, octave_base_lexer::handle_identifier): Get current symbol table scope for parsing from symtab_context. Use it to insert new variables in the symbol table. * oct-parse.in.yy (ABORT_PARSE): Don't pop symtab_context. (push_fcn_symtab, param_list_beg): Push newly allocated scope on the symtab_context stack. Don't modify symbol table scope. (make_anon_fcn_handle): Get function scope from symtab_context instead of the symbol table. Pop symtab_context. (start_function): Get function scope from symtab_context instead of the symbol table. (octave_base_parser::recover_from_parsing_function): Pop symtab_context.
author John W. Eaton <jwe@octave.org>
date Sat, 16 Mar 2013 02:02:43 -0400
parents 54c4b4b58a24
children 7612d75a559b
files libinterp/interpfcn/symtab.h libinterp/parse-tree/lex.h libinterp/parse-tree/lex.ll libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/parse-private.h
diffstat 5 files changed, 90 insertions(+), 133 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/interpfcn/symtab.h	Fri Mar 15 14:52:02 2013 -0400
+++ b/libinterp/interpfcn/symtab.h	Sat Mar 16 02:02:43 2013 -0400
@@ -1171,11 +1171,12 @@
   static octave_value builtin_find (const std::string& name);
 
   // Insert a new name in the table.
-  static symbol_record& insert (const std::string& name)
+  static symbol_record& insert (const std::string& name,
+                                scope_id scope = xcurrent_scope)
   {
     static symbol_record foobar;
 
-    symbol_table *inst = get_instance (xcurrent_scope);
+    symbol_table *inst = get_instance (scope);
 
     return inst ? inst->do_insert (name) : foobar;
   }
--- a/libinterp/parse-tree/lex.h	Fri Mar 15 14:52:02 2013 -0400
+++ b/libinterp/parse-tree/lex.h	Sat Mar 16 02:02:43 2013 -0400
@@ -43,6 +43,55 @@
 {
 public:
 
+  // Track symbol table information when parsing functions.
+
+  class symbol_table_context
+  {
+  public:
+
+    symbol_table_context (void)
+      : frame_stack (), init_scope (symbol_table::current_scope ())
+    {
+      push (init_scope);
+    }
+
+    void clear (void)
+    {
+      while (! frame_stack.empty ())
+        frame_stack.pop ();
+
+      push (init_scope);
+    }
+
+    bool empty (void) const { return frame_stack.empty (); }
+
+    void pop (void)
+    {
+      frame_stack.pop ();
+    }
+
+    void push (symbol_table::scope_id scope)
+    {
+      frame_stack.push (scope);
+    }
+
+    void push (void)
+    {
+      push (symbol_table::current_scope ());
+    }
+
+    symbol_table::scope_id curr_scope (void) const
+    {
+      return frame_stack.top ();
+    }
+
+  private:
+
+    std::stack<symbol_table::scope_id> frame_stack;
+
+    symbol_table::scope_id init_scope;
+  };
+
   // Track nesting of square brackets, curly braces, and parentheses.
 
   class bbp_nesting_level
@@ -233,7 +282,7 @@
       current_input_line (), comment_text (), help_text (),
       fcn_file_name (), fcn_file_full_name (), looking_at_object_index (),
       parsed_function_name (), pending_local_variables (),
-      nesting_level (), tokens ()
+      symtab_context (), nesting_level (), tokens ()
   {
     init ();
   }
@@ -375,6 +424,9 @@
   // set of identifiers that might be local variable names.
   std::set<std::string> pending_local_variables;
 
+  // Track current symbol table scope and context.
+  symbol_table_context symtab_context;
+
   // is the closest nesting level a square bracket, squiggly brace,
   // a paren, or an anonymous function body?
   bbp_nesting_level nesting_level;
--- a/libinterp/parse-tree/lex.ll	Fri Mar 15 14:52:02 2013 -0400
+++ b/libinterp/parse-tree/lex.ll	Sat Mar 16 02:02:43 2013 -0400
@@ -84,7 +84,6 @@
 #include "lex.h"
 #include "ov.h"
 #include "parse.h"
-#include "parse-private.h"
 #include "pt-all.h"
 #include "symtab.h"
 #include "token.h"
@@ -1622,7 +1621,7 @@
   // Start off on the right foot.
   clear_start_state ();
 
-  parser_symtab_context.clear ();
+  symtab_context.clear ();
 
   // We do want a prompt by default.
   promptflag (1);
@@ -2403,11 +2402,14 @@
       return LEXICAL_ERROR;
     }
 
-  push_token (new token (SUPERCLASSREF,
-                         meth.empty () ? 0 : &(symbol_table::insert (meth)),
-                         cls.empty () ? 0 : &(symbol_table::insert (cls)),
-                         pkg.empty () ? 0 : &(symbol_table::insert (pkg)),
-                         input_line_number, current_input_column));
+  symbol_table::scope_id sid = symtab_context.curr_scope ();
+
+  push_token (new token
+              (SUPERCLASSREF,
+               meth.empty () ? 0 : &(symbol_table::insert (meth, sid)),
+               cls.empty () ? 0 : &(symbol_table::insert (cls, sid)),
+               pkg.empty () ? 0 : &(symbol_table::insert (pkg, sid)),
+               input_line_number, current_input_column));
 
   current_input_column += flex_yyleng ();
 
@@ -2435,10 +2437,13 @@
       return LEXICAL_ERROR;
     }
 
-  push_token (new token (METAQUERY,
-                         cls.empty () ? 0 : &(symbol_table::insert (cls)),
-                         pkg.empty () ? 0 : &(symbol_table::insert (pkg)),
-                         input_line_number, current_input_column));
+  symbol_table::scope_id sid = symtab_context.curr_scope ();
+
+  push_token (new token
+              (METAQUERY,
+               cls.empty () ? 0 : &(symbol_table::insert (cls, sid)),
+               pkg.empty () ? 0 : &(symbol_table::insert (pkg, sid)),
+               input_line_number, current_input_column));
 
   current_input_column += flex_yyleng ();
 
@@ -2527,7 +2532,9 @@
   if (tok == "end")
     tok = "__end__";
 
-  token *tok_val = new token (NAME, &(symbol_table::insert (tok)),
+  symbol_table::scope_id sid = symtab_context.curr_scope ();
+
+  token *tok_val = new token (NAME, &(symbol_table::insert (tok, sid)),
                               input_line_number, current_input_column);
 
   if (at_beginning_of_statement
--- a/libinterp/parse-tree/oct-parse.in.yy	Fri Mar 15 14:52:02 2013 -0400
+++ b/libinterp/parse-tree/oct-parse.in.yy	Sat Mar 16 02:02:43 2013 -0400
@@ -68,7 +68,6 @@
 #include "toplev.h"
 #include "pager.h"
 #include "parse.h"
-#include "parse-private.h"
 #include "pt-all.h"
 #include "pt-eval.h"
 #include "symtab.h"
@@ -98,9 +97,6 @@
 // TRUE means we printed messages about reading startup files.
 bool reading_startup_message_printed = false;
 
-// Keep track of symbol table information when parsing functions.
-symtab_context parser_symtab_context;
-
 // List of autoloads (function -> file mapping).
 static std::map<std::string, std::string> autoload_map;
 
@@ -123,9 +119,7 @@
   do \
     { \
       yyerrok; \
-      if (! parser_symtab_context.empty ()) \
-        parser_symtab_context.pop (); \
-      if ((interactive || forced_interactive)   \
+      if ((interactive || forced_interactive) \
           && ! lexer.input_from_eval_string ()) \
         YYACCEPT; \
       else \
@@ -1000,16 +994,16 @@
                     if (parser.max_fcn_depth < parser.curr_fcn_depth)
                       parser.max_fcn_depth = parser.curr_fcn_depth;
 
-                    parser_symtab_context.push ();
-
-                    symbol_table::set_scope (symbol_table::alloc_scope ());
-
-                    parser.function_scopes.push_back (symbol_table::current_scope ());
+                    lexer.symtab_context.push (symbol_table::alloc_scope ());
+
+                    parser.function_scopes.push_back
+                     (lexer.symtab_context.curr_scope ());
 
                     if (! lexer.reading_script_file
                         && parser.curr_fcn_depth == 1
                         && ! parser.parsing_subfunctions)
-                      parser.primary_fcn_scope = symbol_table::current_scope ();
+                      parser.primary_fcn_scope
+                        = lexer.symtab_context.curr_scope ();
 
                     if (lexer.reading_script_file
                         && parser.curr_fcn_depth > 1)
@@ -1027,8 +1021,7 @@
 
                     if (lexer.looking_at_function_handle)
                       {
-                        parser_symtab_context.push ();
-                        symbol_table::set_scope (symbol_table::alloc_scope ());
+                        lexer.symtab_context.push (symbol_table::alloc_scope ());
                         lexer.looking_at_function_handle--;
                         lexer.looking_at_anon_fcn_args = true;
                       }
@@ -1892,12 +1885,12 @@
 
   tree_parameter_list *ret_list = 0;
 
-  symbol_table::scope_id fcn_scope = symbol_table::current_scope ();
-
-  if (parser_symtab_context.empty ())
+  symbol_table::scope_id fcn_scope = lexer.symtab_context.curr_scope ();
+
+  if (lexer.symtab_context.empty ())
     panic_impossible ();
 
-  parser_symtab_context.pop ();
+  lexer.symtab_context.pop ();
 
   stmt->set_print_flag (false);
 
@@ -2579,7 +2572,7 @@
   body->append (end_fcn_stmt);
 
   octave_user_function *fcn
-    = new octave_user_function (symbol_table::current_scope (),
+    = new octave_user_function (lexer.symtab_context.curr_scope (),
                                 param_list, 0, body);
 
   if (fcn)
@@ -2770,10 +2763,10 @@
 void
 octave_base_parser::recover_from_parsing_function (void)
 {
-  if (parser_symtab_context.empty ())
+  if (lexer.symtab_context.empty ())
     panic_impossible ();
 
-  parser_symtab_context.pop ();
+  lexer.symtab_context.pop ();
 
   if (lexer.reading_fcn_file && curr_fcn_depth == 1
       && ! parsing_subfunctions)
--- a/libinterp/parse-tree/parse-private.h	Fri Mar 15 14:52:02 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
-
-Copyright (C) 2012 John W. Eaton
-
-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_parse_private_h)
-#define octave_parse_private_h 1
-
-#include <stack>
-
-#include "symtab.h"
-
-// Keep track of symbol table information when parsing functions.
-class symtab_context
-{
-private:
-
-  class frame
-  {
-  public:
-    frame (symbol_table::scope_id s, symbol_table::scope_id c)
-      : m_scope (s), m_context (c) { }
-
-    frame (const frame& f) : m_scope (f.m_scope), m_context (f.m_context) { }
-
-    frame& operator = (const frame& f)
-    {
-      if (&f != this)
-        {
-          m_scope = f.m_scope;
-          m_context = f.m_context;
-        }
-
-      return *this;
-    }
-
-    ~frame (void) { }
-
-    symbol_table::scope_id scope (void) const { return m_scope; }
-    symbol_table::scope_id context (void) const { return m_context; }
-
-  private:
-
-    symbol_table::scope_id m_scope;
-    symbol_table::scope_id m_context;
-  };
-
-  std::stack<frame> frame_stack;
-
-public:
-  symtab_context (void) : frame_stack () { }
-
-  void clear (void)
-  {
-    while (! frame_stack.empty ())
-      frame_stack.pop ();
-  }
-
-  bool empty (void) const { return frame_stack.empty (); }
-
-  void pop (void)
-  {
-    frame tmp = frame_stack.top ();
-
-    symbol_table::set_scope_and_context (tmp.scope (), tmp.context ());
-
-    frame_stack.pop ();
-  }
-
-  void push (void)
-  {
-    frame_stack.push (frame (symbol_table::current_scope (),
-                             symbol_table::current_context ()));
-  }
-};
-
-extern symtab_context parser_symtab_context;
-
-#endif