changeset 8881:8ed42c679af5

after defining a script or function, clear local variables created for parsing
author John W. Eaton <jwe@octave.org>
date Thu, 26 Feb 2009 13:58:47 -0500
parents 078ca05e4ef8
children 8633ae24a892
files src/ChangeLog src/lex.h src/lex.l src/parse.y src/symtab.h
diffstat 5 files changed, 100 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Thu Feb 26 12:25:22 2009 -0500
+++ b/src/ChangeLog	Thu Feb 26 13:58:47 2009 -0500
@@ -1,5 +1,25 @@
 2009-02-26  John W. Eaton  <jwe@octave.org>
 
+	* symtab.h (symbol_table::symbol_record::symbol_record_rep::forced):
+	New static constant.
+	(symbol_table::symbol_record::symbol_record_rep::force_variable,
+	symbol_table::symbol_record::force_variable): New functions.
+	(symbol_table::symbol_record::symbol_record_rep::is_forced,
+	symbol_table::symbol_record::symbol_record_rep::mark_forced,
+	symbol_table::symbol_record::symbol_record_rep::unmark_forced,
+	symbol_table::symbol_record::symbol_record_rep::clear_forced,
+	symbol_table::symbol_record::is_forced,
+	symbol_table::symbol_record::mark_forced,
+	symbol_table::symbol_record::clear_forced,
+	symbol_table::symbol_record::unmark_forced): New fucntions.
+	* lex.h, lex.l (force_local_variable): Delete.
+	(handle_identifier): Call symbol_table::force_variable instead of
+	force_local_variable.
+	* parse.y (make_script): Call symbol_table:clear_forced_variables
+	after defining script.
+	(finish_function): Call symbol_table::clear_forced_variables
+	instead of symbol_table::clear_variables.
+	
 	* DLD-FUNCTIONS/chol.cc: Correct spelling of CHOLMOD in tests.
 
 	* version.h (OCTAVE_VERSION): Now 3.1.53+.
--- a/src/lex.h	Thu Feb 26 12:25:22 2009 -0500
+++ b/src/lex.h	Thu Feb 26 13:58:47 2009 -0500
@@ -54,8 +54,6 @@
 
 extern void prep_lexer_for_script (void);
 
-extern void force_local_variable (const std::string& name);
-
 // For communication between the lexer and parser.
 
 class
--- a/src/lex.l	Thu Feb 26 12:25:22 2009 -0500
+++ b/src/lex.l	Thu Feb 26 13:58:47 2009 -0500
@@ -1636,15 +1636,6 @@
 	      != lexer_flags.pending_local_variables.end ()));
 }
 
-void
-force_local_variable (const std::string& name)
-{
-  octave_value& val = symbol_table::varref (name);
-
-  if (! val.is_defined ())
-    val = Matrix ();
-}
-
 static std::string
 grab_block_comment (stream_reader& reader, bool& eof)
 {
@@ -3206,7 +3197,7 @@
 	       || (lexer_flags.looking_at_parameter_list
 		   && ! lexer_flags.looking_at_initializer_expression))
 	{
-	  force_local_variable (tok);
+	  symbol_table::force_variable (tok);
 	}
       else if (lexer_flags.looking_at_matrix_or_assign_lhs)
 	{
--- a/src/parse.y	Thu Feb 26 12:25:22 2009 -0500
+++ b/src/parse.y	Thu Feb 26 13:58:47 2009 -0500
@@ -840,7 +840,7 @@
 			 p != lexer_flags.pending_local_variables.end ();
 			 p++)
 		      {
-			force_local_variable (*p);
+			symbol_table::force_variable (*p);
 		      }
 		    lexer_flags.pending_local_variables.clear ();
 		  }
@@ -2495,6 +2495,8 @@
   script->stash_fcn_file_time (now);
 
   curr_fcn_ptr = script;
+
+  symbol_table::clear_forced_variables ();
 }
 
 // Begin defining a function.
@@ -2677,7 +2679,7 @@
       // Clear any local variables that may have been added while
       // parsing (for example, by force_local_variable in lex.l). 
 
-      symbol_table::clear_variables (fcn->scope ());
+      symbol_table::clear_forced_variables (fcn->scope ());
     }
 
   return retval;
--- a/src/symtab.h	Thu Feb 26 12:25:22 2009 -0500
+++ b/src/symtab.h	Thu Feb 26 13:58:47 2009 -0500
@@ -182,6 +182,9 @@
     // not cleared at function exit
     static const unsigned int persistent = 64;
 
+    // temporary variables forced into symbol table for parsing
+    static const unsigned int forced = 128;
+
   private:
 
     class
@@ -196,6 +199,17 @@
 	value_stack.push_back (v);
       }
 
+      void force_variable (context_id context)
+      {
+	octave_value& val = varref (context);
+
+	if (! val.is_defined ())
+	  {
+	    val = Matrix ();
+	    mark_forced ();
+	  }
+      }
+
       octave_value& varref (context_id context)
       {
 	if (is_global ())
@@ -279,6 +293,15 @@
 	  }
       }
 
+      void clear_forced (void)
+      {
+	if (is_forced ())
+	  {
+	    varref (xcurrent_context) = octave_value ();
+	    unmark_forced ();
+	  }
+      }
+
       bool is_defined (context_id context) const
       {
 	return varval (context).is_defined ();
@@ -296,6 +319,7 @@
       bool is_inherited (void) const { return storage_class & inherited; }
       bool is_global (void) const { return storage_class & global; }
       bool is_persistent (void) const { return storage_class & persistent; }
+      bool is_forced (void) const { return storage_class & forced; }
 
       void mark_local (void) { storage_class |= local; }
       void mark_automatic (void) { storage_class |= automatic; }
@@ -316,6 +340,7 @@
 	else
 	  storage_class |= persistent;
       }
+      void mark_forced (void) { storage_class |= forced; }
 
       void unmark_local (void) { storage_class &= ~local; }
       void unmark_automatic (void) { storage_class &= ~automatic; }
@@ -324,6 +349,7 @@
       void unmark_inherited (void) { storage_class &= ~inherited; }
       void unmark_global (void) { storage_class &= ~global; }
       void unmark_persistent (void) { storage_class &= ~persistent; }
+      void unmark_forced (void) { storage_class &= ~forced; }
 
       void init_persistent (void)
       {
@@ -407,6 +433,11 @@
     find (tree_argument_list *args, const string_vector& arg_names,
 	  octave_value_list& evaluated_args, bool& args_evaluated) const;
 
+    void force_variable (context_id context = xcurrent_context)
+    {
+      rep->force_variable (context);
+    }
+
     octave_value& varref (context_id context = xcurrent_context)
     {
       return rep->varref (context);
@@ -423,6 +454,8 @@
 
     void clear (void) { rep->clear (); }
 
+    void clear_forced (void) { rep->clear_forced (); }
+    
     bool is_defined (context_id context = xcurrent_context) const
     {
       return rep->is_defined (context);
@@ -440,6 +473,7 @@
     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_forced (void) const { return rep->is_forced (); }
 
     void mark_local (void) { rep->mark_local (); }
     void mark_automatic (void) { rep->mark_automatic (); }
@@ -448,6 +482,7 @@
     void mark_inherited (void) { rep->mark_inherited (); }
     void mark_global (void) { rep->mark_global (); }
     void mark_persistent (void) { rep->mark_persistent (); }
+    void mark_forced (void) { rep->mark_forced (); }
 
     void unmark_local (void) { rep->unmark_local (); }
     void unmark_automatic (void) { rep->unmark_automatic (); }
@@ -456,6 +491,7 @@
     void unmark_inherited (void) { rep->unmark_inherited (); }
     void unmark_global (void) { rep->unmark_global (); }
     void unmark_persistent (void) { rep->unmark_persistent (); }
+    void unmark_forced (void) { rep->unmark_forced (); }
 
     void init_persistent (void) { rep->init_persistent (); }
 
@@ -821,7 +857,7 @@
     }
 
     void clear (void) { rep->clear (); }
-    
+
     void clear_user_function (void) { rep->clear_user_function (); }
     
     void clear_mex_function (void) { rep->clear_mex_function (); }
@@ -1051,6 +1087,18 @@
     return inst ? inst->do_insert (name) : foobar;
   }
 
+  static void force_variable (const std::string& name,
+			      scope_id scope = xcurrent_scope,
+			      context_id context = xcurrent_context)
+  {
+    assert (xcurrent_context == 0);
+
+    symbol_table *inst = get_instance (scope);
+
+    if (inst)
+      inst->do_force_variable (name, context);
+  }
+
   static octave_value& varref (const std::string& name,
 			       scope_id scope = xcurrent_scope,
 			       context_id context = xcurrent_context)
@@ -1299,6 +1347,14 @@
       inst->do_clear_variables ();
   }
 
+  static void clear_forced_variables (scope_id scope = xcurrent_scope)
+  {
+    symbol_table *inst = get_instance (scope);
+
+    if (inst)
+      inst->do_clear_forced_variables ();
+  }
+
   // For unwind_protect.
   static void clear_variables (void *) { clear_variables (); }
 
@@ -1998,6 +2054,18 @@
       ? (table[name] = symbol_record (name)) : p->second;
   }
 
+  void do_force_variable (const std::string& name, context_id context)
+  {
+    table_iterator p = table.find (name);
+
+    if (p == table.end ())
+      {
+	symbol_record& sr = do_insert (name);
+
+	sr.force_variable (context);
+      }
+  }
+
   octave_value& do_varref (const std::string& name, context_id context)
   {
     table_iterator p = table.find (name);
@@ -2081,6 +2149,12 @@
       p->second.clear ();
   }
 
+  void do_clear_forced_variables (void)
+  {
+    for (table_iterator p = table.begin (); p != table.end (); p++)
+      p->second.clear_forced ();
+  }
+
   void do_clear_global (const std::string& name)
   {
     table_iterator p = table.find (name);