changeset 7767:71f068b22fcc

scope and context fixes for function handles
author John W. Eaton <jwe@octave.org>
date Wed, 07 May 2008 13:45:30 -0400
parents fc81e027c53c
children a2d9f325b65a
files src/ChangeLog src/load-save.cc src/ov-fcn-handle.cc src/pt-arg-list.cc src/pt-arg-list.h src/pt-assign.cc src/pt-assign.h src/pt-binop.cc src/pt-binop.h src/pt-cell.cc src/pt-cell.h src/pt-cmd.cc src/pt-cmd.h src/pt-colon.cc src/pt-colon.h src/pt-const.cc src/pt-const.h src/pt-decl.cc src/pt-decl.h src/pt-except.cc src/pt-except.h src/pt-exp.h src/pt-fcn-handle.cc src/pt-fcn-handle.h src/pt-id.cc src/pt-id.h src/pt-idx.cc src/pt-idx.h src/pt-jump.cc src/pt-jump.h src/pt-loop.cc src/pt-loop.h src/pt-mat.cc src/pt-mat.h src/pt-misc.cc src/pt-misc.h src/pt-select.cc src/pt-select.h src/pt-stmt.cc src/pt-stmt.h src/pt-unop.cc src/pt-unop.h src/symtab.cc src/symtab.h
diffstat 44 files changed, 417 insertions(+), 225 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Tue May 06 13:39:55 2008 -0400
+++ b/src/ChangeLog	Wed May 07 13:45:30 2008 -0400
@@ -1,3 +1,67 @@
+2008-05-07  John W. Eaton  <jwe@octave.org>
+
+	* pt-arg-list.cc, pt-arg-list.h (tree_argument_list::dup):
+	New arg, context.
+	* pt-assign.cc, pt-assign.h (tree_simple_assignment::dup,
+	tree_multi_assignment::dup): Likewise.
+	* pt-binop.cc, pt-binop.h (tree_binary_expression::dup,
+	tree_boolean_expression::dup): Likewise.
+	* pt-cell.cc, pt-cell.h (tree_cell::dup): Likewise.
+	* pt-cmd.cc, pt-cmd.h (tree_no_op_command::dup,
+	tree_function_def::dup): Likewise.
+	* pt-colon.cc, pt-colon.h (tree_colon_expression::dup): Likewise.
+	* pt-const.cc, pt-const.h (tree_constant::dup): Likewise.
+	* pt-decl.cc, pt-decl.h (tree_decl_elt::dup, tree_decl_init_list::dup,
+	tree_global_command::dup, tree_static_command::dup): Likewise.
+	* pt-except.cc, pt-except.h (tree_try_catch_command::dup,
+	tree_unwind_protect_command::dup): Likewise.
+	* pt-exp.h (tree_expression:dup): Likewise.
+	* pt-fcn-handle.cc, pt-exp.h (tree_expression:dup): Likewise.
+	* pt-fcn-handle.h (tree_fcn_handle::dup,
+	tree_anon_fcn_handle::dup): Likewise.
+	* pt-id.cc, pt-id.h (tree_identifier::dup): Likewise.
+	* pt-idx.cc, pt-idx.h (tree_index_expression::dup): Likewise.
+	* pt-jump.cc, pt-jump.h (tree_break_command::dup,
+	tree_continue_command::dup, tree_return_command::dup): Likewise.
+	* pt-loop.cc, pt-loop.h (tree_while_command::dup,
+	tree_do_until_command::dup, tree_simple_for_command::dup,
+	tree_complex_for_command::dup): Likewise.
+	* pt-mat.cc, pt-mat.h (tree_matrix::dup): Likewise.
+	* pt-misc.cc, pt-misc.h (tree_parameter_list::dup,
+	tree_return_list::dup): Likewise.
+	* pt-select.cc, pt-select.h (tree_if_clause::dup,
+	tree_if_command_list::dup, tree_if_command::dup,
+	tree_switch_case::dup, tree_switch_case_list::dup,
+	tree_switch_command::dup, tree_statement::dup,
+	tree_statement_list::dup, tree_prefix_expression::dup,
+	tree_postfix_expression::dup): Likewise.
+
+	* ov-fcn-handle.cc (octave_fcn_handle::save_ascii,
+	octave_fcn_handle::save_binary, octave_fcn_handle::save_hdf5):
+ 	Pass context to symbol_table::all_variables.
+	* load-save.cc (dump_octave_core): Likewise.
+	* ov-fcn-handle.cc (Ffunctions): Don't skip anonymous functions
+	with the name set to the text of the function body.
+ 	Pass context to symbol_table::all_variables and
+	symbol_table::symbol_record::varval.
+
+	* symtab.h (symbol_table::varref, symbol_table::do_varref,
+	symbol_table::varval, symbol_table::do_varval,
+	symbol_table::all_variables, symbol_table::do_all_variables, 
+	symbol_table::symbol_record::varref,
+	symbol_table::symbol_record::varval,
+	symbol_table::symbol_record::is_defined,
+	symbol_table::symbol_record::is_variable,
+	symbol_table::symbol_record::symbol_record_rep::varref,
+	symbol_table::symbol_record::symbol_record_rep::varval,
+	symbol_table::symbol_record::symbol_record_rep::is_defined,
+	symbol_table::symbol_record::symbol_record_rep::is_variable,
+	):
+	* symtab.h (symbol_table::do_inherit): New arg, donor_context.
+	Look for value in donor_contxt.  Set value in base context.
+	* symtab.cc (symbol_table::symbol_record::symbol_record_rep::dump):
+	Pass xcurrent_context to varval.
+
 2008-05-06  David Bateman  <dbateman@free.fr>
 
 	* ov-fcn-inline.cc (Finline): Also ignore NaN, Inf, pi, NA and eps.
--- a/src/load-save.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/load-save.cc	Wed May 07 13:45:30 2008 -0400
@@ -1270,7 +1270,8 @@
 {
   write_header (os, fmt);
 
-  std::list<symbol_table::symbol_record> vars = symbol_table::all_variables ();
+  std::list<symbol_table::symbol_record> vars
+    = symbol_table::all_variables (symbol_table::top_scope (), 0);
 
   double save_mem_size = 0;
 
--- a/src/ov-fcn-handle.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/ov-fcn-handle.cc	Wed May 07 13:45:30 2008 -0400
@@ -242,7 +242,7 @@
       octave_user_function *f = fcn.user_function_value ();
 
       std::list<symbol_table::symbol_record> vars
-	= symbol_table::all_variables (f->scope ());
+	= symbol_table::all_variables (f->scope (), 0);
 
       size_t varlen = vars.size ();
 
@@ -410,7 +410,7 @@
       octave_user_function *f = fcn.user_function_value ();
 
       std::list<symbol_table::symbol_record> vars
-	= symbol_table::all_variables (f->scope ());
+	= symbol_table::all_variables (f->scope (), 0);
 
       size_t varlen = vars.size ();
 
@@ -654,7 +654,7 @@
       octave_user_function *f = fcn.user_function_value ();
 
       std::list<symbol_table::symbol_record> vars
-	= symbol_table::all_variables (f->scope ());
+	= symbol_table::all_variables (f->scope (), 0);
 
       size_t varlen = vars.size ();
 
@@ -1276,41 +1276,36 @@
 
 	      std::string nm = fcn->fcn_file_name ();
 
-	      if (nm.empty ())
+	      if (fh_nm == "@<anonymous>")
 		{
-		  if (fh_nm == "@<anonymous>")
-		    {
-		      m.assign ("file", "");
+		  m.assign ("file", nm);
+
+		  octave_user_function *fu = fh->user_function_value ();
 
-		      octave_user_function *fu = fh->user_function_value ();
+		  std::list<symbol_table::symbol_record> vars
+		    = symbol_table::all_variables (fu->scope (), 0);
+
+		  size_t varlen = vars.size ();
 
-		      std::list<symbol_table::symbol_record> vars
-			= symbol_table::all_variables (fu->scope ());
-
-		      size_t varlen = vars.size ();
-
-		      if (varlen > 0)
+		  if (varlen > 0)
+		    {
+		      Octave_map ws;
+		      for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin ();
+			   p != vars.end (); p++)
 			{
-			  Octave_map ws;
-			  for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin ();
-			       p != vars.end (); p++)
-			    {
-			      ws.assign (p->name (), p->varval ());
-			    }
-
-			  m.assign ("workspace", ws);
+			  ws.assign (p->name (), p->varval (0));
 			}
+
+		      m.assign ("workspace", ws);
 		    }
-		  else if (fcn->is_user_function () || fcn->is_user_script ())
-		    {
-		      octave_function *fu = fh->function_value ();
-		      m.assign ("file", fu->fcn_file_name ());
-		    }
-		  else
-		    m.assign ("file", "");
+		}
+	      else if (fcn->is_user_function () || fcn->is_user_script ())
+		{
+		  octave_function *fu = fh->function_value ();
+		  m.assign ("file", fu->fcn_file_name ());
 		}
 	      else
-		m.assign ("file", nm);
+		m.assign ("file", "");
 
 	      retval = m;
 	    }
@@ -1387,6 +1382,21 @@
 }
 
 /*
+%!function y = testrecursionfunc (f, x, n)
+%!  if (nargin < 3)
+%!    n = 0;
+%!  endif
+%!  if (n > 2)
+%!    y = f (x);
+%!  else
+%!    n++;
+%!    y = testrecursionfunc (@(x) f(2*x), x, n);
+%!  endif
+%!test
+%! assert (testrecursionfunc (@(x) x, 1), 8);
+*/
+
+/*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
 ;;; End: ***
--- a/src/pt-arg-list.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-arg-list.cc	Wed May 07 13:45:30 2008 -0400
@@ -253,7 +253,8 @@
 }
 
 tree_argument_list *
-tree_argument_list::dup (symbol_table::scope_id scope)
+tree_argument_list::dup (symbol_table::scope_id scope,
+			 symbol_table::context_id context)
 {
   tree_argument_list *new_list = new tree_argument_list ();
 
@@ -264,7 +265,7 @@
     {
       tree_expression *elt = *p;
 
-      new_list->append (elt ? elt->dup (scope) : 0);
+      new_list->append (elt ? elt->dup (scope, context) : 0);
     }
 
   return new_list;
--- a/src/pt-arg-list.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-arg-list.h	Wed May 07 13:45:30 2008 -0400
@@ -78,7 +78,8 @@
 
   string_vector get_arg_names (void) const;
 
-  tree_argument_list *dup (symbol_table::scope_id scope);
+  tree_argument_list *dup (symbol_table::scope_id scope,
+			   symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-assign.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-assign.cc	Wed May 07 13:45:30 2008 -0400
@@ -289,11 +289,12 @@
 }
 
 tree_expression *
-tree_simple_assignment::dup (symbol_table::scope_id scope)
+tree_simple_assignment::dup (symbol_table::scope_id scope,
+			     symbol_table::context_id context)
 {
   tree_simple_assignment *new_sa
-    = new tree_simple_assignment (lhs ? lhs->dup (scope) : 0,
-				  rhs ? rhs->dup (scope) : 0,
+    = new tree_simple_assignment (lhs ? lhs->dup (scope, context) : 0,
+				  rhs ? rhs->dup (scope, context) : 0,
 				  preserve, etype);
 
   new_sa->copy_base (*this);
@@ -516,11 +517,12 @@
 }
 
 tree_expression *
-tree_multi_assignment::dup (symbol_table::scope_id scope)
+tree_multi_assignment::dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context)
 {
   tree_multi_assignment *new_ma
-    = new tree_multi_assignment (lhs ? lhs->dup (scope) : 0,
-				 rhs ? rhs->dup (scope) : 0,
+    = new tree_multi_assignment (lhs ? lhs->dup (scope, context) : 0,
+				 rhs ? rhs->dup (scope, context) : 0,
 				 preserve, etype);
 
   new_ma->copy_base (*this);
--- a/src/pt-assign.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-assign.h	Wed May 07 13:45:30 2008 -0400
@@ -73,7 +73,8 @@
 
   tree_expression *right_hand_side (void) { return rhs; }
 
-  tree_expression *dup (symbol_table::scope_id scope);
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -143,7 +144,8 @@
 
   tree_expression *right_hand_side (void) { return rhs; }
 
-  tree_expression *dup (symbol_table::scope_id scope);
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context);
 
   void accept (tree_walker& tw);
   
--- a/src/pt-binop.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-binop.cc	Wed May 07 13:45:30 2008 -0400
@@ -106,11 +106,12 @@
 }
 
 tree_expression *
-tree_binary_expression::dup (symbol_table::scope_id scope)
+tree_binary_expression::dup (symbol_table::scope_id scope,
+			     symbol_table::context_id context)
 {
   tree_binary_expression *new_be
-    = new tree_binary_expression (op_lhs ? op_lhs->dup (scope) : 0,
-				  op_rhs ? op_rhs->dup (scope) : 0,
+    = new tree_binary_expression (op_lhs ? op_lhs->dup (scope, context) : 0,
+				  op_rhs ? op_rhs->dup (scope, context) : 0,
 				  line (), column (), etype);
 
   new_be->copy_base (*this);
@@ -233,11 +234,12 @@
 }
 
 tree_expression *
-tree_boolean_expression::dup (symbol_table::scope_id scope)
+tree_boolean_expression::dup (symbol_table::scope_id scope,
+			      symbol_table::context_id context)
 {
   tree_boolean_expression *new_be
-    = new tree_boolean_expression (op_lhs ? op_lhs->dup (scope) : 0,
-				   op_rhs ? op_rhs->dup (scope) : 0,
+    = new tree_boolean_expression (op_lhs ? op_lhs->dup (scope, context) : 0,
+				   op_rhs ? op_rhs->dup (scope, context) : 0,
 				   line (), column (), etype);
 
   new_be->copy_base (*this);
--- a/src/pt-binop.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-binop.h	Wed May 07 13:45:30 2008 -0400
@@ -83,7 +83,8 @@
   tree_expression *lhs (void) { return op_lhs; }
   tree_expression *rhs (void) { return op_rhs; }
 
-  tree_expression *dup (symbol_table::scope_id scope);
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -140,7 +141,8 @@
 
   type op_type (void) const { return etype; }
 
-  tree_expression *dup (symbol_table::scope_id scope);
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context);
 
 private:
 
--- a/src/pt-cell.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-cell.cc	Wed May 07 13:45:30 2008 -0400
@@ -102,7 +102,8 @@
 }
 
 tree_expression *
-tree_cell::dup (symbol_table::scope_id scope)
+tree_cell::dup (symbol_table::scope_id scope,
+		symbol_table::context_id context)
 {
   tree_cell *new_cell = new tree_cell (0, line (), column ());
 
@@ -110,7 +111,7 @@
     {
       tree_argument_list *elt = *p;
 
-      new_cell->append (elt ? elt->dup (scope) : 0);
+      new_cell->append (elt ? elt->dup (scope, context) : 0);
     }
 
   new_cell->copy_base (*this);
--- a/src/pt-cell.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-cell.h	Wed May 07 13:45:30 2008 -0400
@@ -53,7 +53,8 @@
 
   octave_value_list rvalue (int);
 
-  tree_expression *dup (symbol_table::scope_id scope);
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-cmd.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-cmd.cc	Wed May 07 13:45:30 2008 -0400
@@ -31,7 +31,8 @@
 // No-op.
 
 tree_command *
-tree_no_op_command::dup (symbol_table::scope_id)
+tree_no_op_command::dup (symbol_table::scope_id,
+			 symbol_table::context_id context)
 {
   return new tree_no_op_command (orig_cmd, line (), column ());
 }
@@ -63,7 +64,8 @@
 }
 
 tree_command *
-tree_function_def::dup (symbol_table::scope_id)
+tree_function_def::dup (symbol_table::scope_id,
+			symbol_table::context_id context)
 {
   return new tree_function_def (fcn, line (), column ());
 }
--- a/src/pt-cmd.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-cmd.h	Wed May 07 13:45:30 2008 -0400
@@ -47,7 +47,8 @@
 
   virtual void eval (void) = 0;
 
-  virtual tree_command *dup (symbol_table::scope_id) = 0;
+  virtual tree_command *dup (symbol_table::scope_id,
+			     symbol_table::context_id context) = 0;
 
 private:
 
@@ -72,7 +73,8 @@
 
   void eval (void) { MAYBE_DO_BREAKPOINT; }
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -103,7 +105,8 @@
 
   void eval (void);
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-colon.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-colon.cc	Wed May 07 13:45:30 2008 -0400
@@ -210,13 +210,14 @@
 }
 
 tree_expression *
-tree_colon_expression::dup (symbol_table::scope_id scope)
+tree_colon_expression::dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context)
 {
-  tree_colon_expression *new_ce
-    = new tree_colon_expression (op_base ? op_base->dup (scope) : 0,
-				 op_limit ? op_limit->dup (scope) : 0,
-				 op_increment ? op_increment->dup (scope) : 0,
-				 line (), column ());
+  tree_colon_expression *new_ce = new
+    tree_colon_expression (op_base ? op_base->dup (scope, context) : 0,
+			   op_limit ? op_limit->dup (scope, context) : 0,
+			   op_increment ? op_increment->dup (scope, context) : 0,
+			   line (), column ());
 
   new_ce->copy_base (*new_ce);
 
--- a/src/pt-colon.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-colon.h	Wed May 07 13:45:30 2008 -0400
@@ -92,7 +92,8 @@
   int line (void) const;
   int column (void) const;
 
-  tree_expression *dup (symbol_table::scope_id scope);
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-const.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-const.cc	Wed May 07 13:45:30 2008 -0400
@@ -71,7 +71,8 @@
 }
 
 tree_expression *
-tree_constant::dup (symbol_table::scope_id)
+tree_constant::dup (symbol_table::scope_id,
+		    symbol_table::context_id context)
 {
   tree_constant *new_tc
     = new tree_constant (val, orig_text, line (), column ());
--- a/src/pt-const.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-const.h	Wed May 07 13:45:30 2008 -0400
@@ -82,7 +82,8 @@
 
   octave_value_list rvalue (int nargout);
 
-  tree_expression *dup (symbol_table::scope_id scope);
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-decl.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-decl.cc	Wed May 07 13:45:30 2008 -0400
@@ -69,10 +69,11 @@
 }
 
 tree_decl_elt *
-tree_decl_elt::dup (symbol_table::scope_id scope)
+tree_decl_elt::dup (symbol_table::scope_id scope,
+		    symbol_table::context_id context)
 {
-  return new tree_decl_elt (id ? id->dup (scope) : 0,
-			    expr ? expr->dup (scope) : 0);
+  return new tree_decl_elt (id ? id->dup (scope, context) : 0,
+			    expr ? expr->dup (scope, context) : 0);
 }
 
 void
@@ -98,7 +99,8 @@
 }
 
 tree_decl_init_list *
-tree_decl_init_list::dup (symbol_table::scope_id scope)
+tree_decl_init_list::dup (symbol_table::scope_id scope,
+			  symbol_table::context_id context)
 {
   tree_decl_init_list *new_dil = new tree_decl_init_list ();
 
@@ -106,7 +108,7 @@
     {
       tree_decl_elt *elt = *p;
 
-      new_dil->append (elt ? elt->dup (scope) : 0);
+      new_dil->append (elt ? elt->dup (scope, context) : 0);
     }
   
   return new_dil;
@@ -177,10 +179,12 @@
 }
 
 tree_command *
-tree_global_command::dup (symbol_table::scope_id scope)
+tree_global_command::dup (symbol_table::scope_id scope,
+			  symbol_table::context_id context)
 {
-  return new tree_global_command (init_list ? init_list->dup (scope) : 0,
-				  line (), column ());
+  return
+    new tree_global_command (init_list ? init_list->dup (scope, context) : 0,
+			     line (), column ());
 }
 
 // Static.
@@ -228,10 +232,12 @@
 }
 
 tree_command *
-tree_static_command::dup (symbol_table::scope_id scope)
+tree_static_command::dup (symbol_table::scope_id scope,
+			  symbol_table::context_id context)
 {
-  return new tree_static_command (init_list ? init_list->dup (scope) : 0,
-				  line (), column ());
+  return
+    new tree_static_command (init_list ? init_list->dup (scope, context) : 0,
+			     line (), column ());
 }
 
 /*
--- a/src/pt-decl.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-decl.h	Wed May 07 13:45:30 2008 -0400
@@ -78,7 +78,8 @@
 
   tree_expression *expression (void) { return expr; }
 
-  tree_decl_elt *dup (symbol_table::scope_id scope);
+  tree_decl_elt *dup (symbol_table::scope_id scope,
+		      symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -118,7 +119,8 @@
 
   void eval (tree_decl_elt::eval_fcn);
 
-  tree_decl_init_list *dup (symbol_table::scope_id scope);
+  tree_decl_init_list *dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -187,7 +189,8 @@
 
   void eval (void);
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
 private:
 
@@ -217,7 +220,8 @@
 
   void eval (void);
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
 private:
 
--- a/src/pt-except.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-except.cc	Wed May 07 13:45:30 2008 -0400
@@ -135,14 +135,16 @@
 }
 
 tree_command *
-tree_try_catch_command::dup (symbol_table::scope_id scope)
+tree_try_catch_command::dup (symbol_table::scope_id scope,
+			     symbol_table::context_id context)
 {
-  return new tree_try_catch_command (try_code ? try_code->dup (scope) : 0,
-				     catch_code ? catch_code->dup (scope) : 0,
-				     lead_comm ? lead_comm->dup () : 0,
-				     mid_comm ? mid_comm->dup () : 0,
-				     trail_comm ? trail_comm->dup () : 0,
-				     line (), column ());
+  return new
+    tree_try_catch_command (try_code ? try_code->dup (scope, context) : 0,
+			    catch_code ? catch_code->dup (scope, context) : 0,
+			    lead_comm ? lead_comm->dup () : 0,
+			    mid_comm ? mid_comm->dup () : 0,
+			    trail_comm ? trail_comm->dup () : 0,
+			    line (), column ());
 }
 
 void
@@ -251,11 +253,12 @@
 }
 
 tree_command *
-tree_unwind_protect_command::dup (symbol_table::scope_id scope)
+tree_unwind_protect_command::dup (symbol_table::scope_id scope,
+				  symbol_table::context_id context)
 {
   return new tree_unwind_protect_command
-    (unwind_protect_code ? unwind_protect_code->dup (scope) : 0,
-     cleanup_code ? cleanup_code->dup (scope) : 0,
+    (unwind_protect_code ? unwind_protect_code->dup (scope, context) : 0,
+     cleanup_code ? cleanup_code->dup (scope, context) : 0,
      lead_comm ? lead_comm->dup () : 0,
      mid_comm ? mid_comm->dup () : 0,
      trail_comm ? trail_comm->dup () : 0,
--- a/src/pt-except.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-except.h	Wed May 07 13:45:30 2008 -0400
@@ -65,7 +65,8 @@
 
   octave_comment_list *trailing_comment (void) { return trail_comm; }
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -127,7 +128,8 @@
 
   octave_comment_list *trailing_comment (void) { return trail_comm; }
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-exp.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-exp.h	Wed May 07 13:45:30 2008 -0400
@@ -47,7 +47,8 @@
 
   virtual bool has_magic_end (void) const = 0;
 
-  virtual tree_expression *dup (symbol_table::scope_id) = 0;
+  virtual tree_expression *dup (symbol_table::scope_id,
+				symbol_table::context_id context) = 0;
 
   virtual bool is_constant (void) const { return false; }
 
--- a/src/pt-fcn-handle.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-fcn-handle.cc	Wed May 07 13:45:30 2008 -0400
@@ -71,7 +71,8 @@
 }
 
 tree_expression *
-tree_fcn_handle::dup (symbol_table::scope_id)
+tree_fcn_handle::dup (symbol_table::scope_id,
+		      symbol_table::context_id)
 {
   tree_fcn_handle *new_fh = new tree_fcn_handle (nm, line (), column ());
 
@@ -99,13 +100,14 @@
   symbol_table::scope_id new_scope = symbol_table::dup_scope (this_scope);
 
   if (new_scope > 0)
-    symbol_table::inherit (new_scope, symbol_table::current_scope ());
+    symbol_table::inherit (new_scope, symbol_table::current_scope (),
+			   symbol_table::current_context ());
 
   octave_user_function *uf
     = new octave_user_function (new_scope,
-				param_list ? param_list->dup (new_scope) : 0,
-				ret_list ? ret_list->dup (new_scope) : 0,
-				cmd_list ? cmd_list->dup (new_scope) : 0);
+				param_list ? param_list->dup (new_scope, 0) : 0,
+				ret_list ? ret_list->dup (new_scope, 0) : 0,
+				cmd_list ? cmd_list->dup (new_scope, 0) : 0);
 
   octave_function *curr_fcn = octave_call_stack::current ();
 
@@ -135,7 +137,8 @@
 }
 
 tree_expression *
-tree_anon_fcn_handle::dup (symbol_table::scope_id parent_scope)
+tree_anon_fcn_handle::dup (symbol_table::scope_id parent_scope,
+			   symbol_table::context_id parent_context)
 {
   tree_parameter_list *param_list = parameter_list ();
   tree_parameter_list *ret_list = return_list ();
@@ -145,13 +148,13 @@
   symbol_table::scope_id new_scope = symbol_table::dup_scope (this_scope);
 
   if (new_scope > 0)
-    symbol_table::inherit (new_scope, parent_scope);
+    symbol_table::inherit (new_scope, parent_scope, parent_context);
 
-  tree_anon_fcn_handle *new_afh
-    = new tree_anon_fcn_handle (param_list ? param_list->dup (new_scope) : 0,
-				ret_list ? ret_list->dup (new_scope) : 0,
-				cmd_list ? cmd_list->dup (new_scope) : 0,
-				new_scope, line (), column ());
+  tree_anon_fcn_handle *new_afh = new
+    tree_anon_fcn_handle (param_list ? param_list->dup (new_scope, 0) : 0,
+			  ret_list ? ret_list->dup (new_scope, 0) : 0,
+			  cmd_list ? cmd_list->dup (new_scope, 0) : 0,
+			  new_scope, line (), column ());
 
   new_afh->copy_base (*this);
 
--- a/src/pt-fcn-handle.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-fcn-handle.h	Wed May 07 13:45:30 2008 -0400
@@ -69,7 +69,8 @@
 
   octave_value_list rvalue (int nargout);
 
-  tree_expression *dup (symbol_table::scope_id scope);
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -123,7 +124,8 @@
 
   symbol_table::scope_id scope (void) { return fcn ? fcn->scope () : -1; }
 
-  tree_expression *dup (symbol_table::scope_id scope);
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-id.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-id.cc	Wed May 07 13:45:30 2008 -0400
@@ -123,7 +123,8 @@
 }
 
 tree_identifier *
-tree_identifier::dup (symbol_table::scope_id sc)
+tree_identifier::dup (symbol_table::scope_id sc,
+		      symbol_table::context_id context)
 {
   // The new tree_identifier object contains a symbol_record
   // entry from the duplicated scope.
--- a/src/pt-id.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-id.h	Wed May 07 13:45:30 2008 -0400
@@ -111,7 +111,8 @@
 
   void eval_undefined_error (void);
 
-  tree_identifier *dup (symbol_table::scope_id scope);
+  tree_identifier *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-idx.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-idx.cc	Wed May 07 13:45:30 2008 -0400
@@ -689,12 +689,13 @@
 }
 
 tree_index_expression *
-tree_index_expression::dup (symbol_table::scope_id scope)
+tree_index_expression::dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context)
 {
   tree_index_expression *new_idx_expr
     = new tree_index_expression (line (), column ());
 
-  new_idx_expr->expr = expr ? expr->dup (scope) : 0;
+  new_idx_expr->expr = expr ? expr->dup (scope, context) : 0;
 
   std::list<tree_argument_list *> new_args;
 
@@ -704,7 +705,7 @@
     {
       tree_argument_list *elt = *p;
 
-      new_args.push_back (elt ? elt->dup (scope) : 0);
+      new_args.push_back (elt ? elt->dup (scope, context) : 0);
     }
 
   new_idx_expr->args = new_args;
@@ -721,7 +722,7 @@
     {
       tree_expression *elt = *p;
 
-      new_dyn_field.push_back (elt ? elt->dup (scope) : 0);
+      new_dyn_field.push_back (elt ? elt->dup (scope, context) : 0);
     }
 
   new_idx_expr->dyn_field = new_dyn_field;
--- a/src/pt-idx.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-idx.h	Wed May 07 13:45:30 2008 -0400
@@ -90,7 +90,8 @@
 
   void eval_error (void) const;
 
-  tree_index_expression *dup (symbol_table::scope_id scope);
+  tree_index_expression *dup (symbol_table::scope_id scope,
+			      symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-jump.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-jump.cc	Wed May 07 13:45:30 2008 -0400
@@ -49,7 +49,8 @@
 }
 
 tree_command *
-tree_break_command::dup (symbol_table::scope_id)
+tree_break_command::dup (symbol_table::scope_id,
+			 symbol_table::context_id context)
 {
   return new tree_break_command (line (), column ());
 }
@@ -75,7 +76,8 @@
 }
 
 tree_command *
-tree_continue_command::dup (symbol_table::scope_id)
+tree_continue_command::dup (symbol_table::scope_id,
+			    symbol_table::context_id context)
 {
   return new tree_continue_command (line (), column ());
 }
@@ -101,7 +103,8 @@
 }
 
 tree_command *
-tree_return_command::dup (symbol_table::scope_id)
+tree_return_command::dup (symbol_table::scope_id,
+			  symbol_table::context_id context)
 {
   return new tree_return_command (line (), column ());
 }
--- a/src/pt-jump.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-jump.h	Wed May 07 13:45:30 2008 -0400
@@ -42,7 +42,8 @@
 
   void eval (void);
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -71,7 +72,8 @@
 
   void eval (void);
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -100,7 +102,8 @@
 
   void eval (void);
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-loop.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-loop.cc	Wed May 07 13:45:30 2008 -0400
@@ -126,10 +126,11 @@
 }
 
 tree_command *
-tree_while_command::dup (symbol_table::scope_id scope)
+tree_while_command::dup (symbol_table::scope_id scope,
+			 symbol_table::context_id context)
 {
-  return new tree_while_command (expr ? expr->dup (scope) : 0,
-				 list ? list->dup (scope) : 0,
+  return new tree_while_command (expr ? expr->dup (scope, context) : 0,
+				 list ? list->dup (scope, context) : 0,
 				 lead_comm ? lead_comm->dup () : 0,
 				 trail_comm ? trail_comm->dup (): 0,
 				 line (), column ());
@@ -189,10 +190,11 @@
 }
 
 tree_command *
-tree_do_until_command::dup (symbol_table::scope_id scope)
+tree_do_until_command::dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context)
 {
-  return new tree_do_until_command (expr ? expr->dup (scope) : 0,
-				    list ? list->dup (scope) : 0,
+  return new tree_do_until_command (expr ? expr->dup (scope, context) : 0,
+				    list ? list->dup (scope, context) : 0,
 				    lead_comm ? lead_comm->dup () : 0,
 				    trail_comm ? trail_comm->dup (): 0,
 				    line (), column ());
@@ -495,11 +497,12 @@
 }
 
 tree_command *
-tree_simple_for_command::dup (symbol_table::scope_id scope)
+tree_simple_for_command::dup (symbol_table::scope_id scope,
+			      symbol_table::context_id context)
 {
-  return new tree_simple_for_command (lhs ? lhs->dup (scope) : 0,
-				      expr ? expr->dup (scope) : 0,
-				      list ? list->dup (scope) : 0,
+  return new tree_simple_for_command (lhs ? lhs->dup (scope, context) : 0,
+				      expr ? expr->dup (scope, context) : 0,
+				      list ? list->dup (scope, context) : 0,
 				      lead_comm ? lead_comm->dup () : 0,
 				      trail_comm ? trail_comm->dup () : 0,
 				      line (), column ());
@@ -616,14 +619,15 @@
 }
 
 tree_command *
-tree_complex_for_command::dup (symbol_table::scope_id scope)
+tree_complex_for_command::dup (symbol_table::scope_id scope,
+			       symbol_table::context_id context)
 {
-  return new tree_complex_for_command (lhs ? lhs->dup (scope) : 0,
-				      expr ? expr->dup (scope) : 0,
-				      list ? list->dup (scope) : 0,
-				      lead_comm ? lead_comm->dup () : 0,
-				      trail_comm ? trail_comm->dup () : 0,
-				      line (), column ());
+  return new tree_complex_for_command (lhs ? lhs->dup (scope, context) : 0,
+				       expr ? expr->dup (scope, context) : 0,
+				       list ? list->dup (scope, context) : 0,
+				       lead_comm ? lead_comm->dup () : 0,
+				       trail_comm ? trail_comm->dup () : 0,
+				       line (), column ());
 }
 
 void
--- a/src/pt-loop.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-loop.h	Wed May 07 13:45:30 2008 -0400
@@ -79,7 +79,8 @@
 
   octave_comment_list *trailing_comment (void) { return trail_comm; }
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -134,7 +135,8 @@
 
   void eval_error (void);
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -182,7 +184,8 @@
 
   octave_comment_list *trailing_comment (void) { return trail_comm; }
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -246,7 +249,8 @@
 
   octave_comment_list *trailing_comment (void) { return trail_comm; }
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-mat.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-mat.cc	Wed May 07 13:45:30 2008 -0400
@@ -951,7 +951,8 @@
 }
 
 tree_expression *
-tree_matrix::dup (symbol_table::scope_id scope)
+tree_matrix::dup (symbol_table::scope_id scope,
+		  symbol_table::context_id context)
 {
   tree_matrix *new_matrix = new tree_matrix (0, line (), column ());
 
@@ -959,7 +960,7 @@
     {
       tree_argument_list *elt = *p;
 
-      new_matrix->append (elt ? elt->dup (scope) : 0);
+      new_matrix->append (elt ? elt->dup (scope, context) : 0);
     }
 
   new_matrix->copy_base (*this);
--- a/src/pt-mat.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-mat.h	Wed May 07 13:45:30 2008 -0400
@@ -64,7 +64,8 @@
 
   octave_value_list rvalue (int nargout);
 
-  tree_expression *dup (symbol_table::scope_id scope);
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-misc.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-misc.cc	Wed May 07 13:45:30 2008 -0400
@@ -247,7 +247,8 @@
 }
 
 tree_parameter_list *
-tree_parameter_list::dup (symbol_table::scope_id scope)
+tree_parameter_list::dup (symbol_table::scope_id scope,
+			  symbol_table::context_id context)
 {
   tree_parameter_list *new_list = new tree_parameter_list ();
 
@@ -258,7 +259,7 @@
     {
       tree_decl_elt *elt = *p;
 
-      new_list->append (elt->dup (scope));
+      new_list->append (elt->dup (scope, context));
     }
 
   return new_list;
@@ -283,7 +284,8 @@
 }
 
 tree_return_list *
-tree_return_list::dup (symbol_table::scope_id scope)
+tree_return_list::dup (symbol_table::scope_id scope,
+		       symbol_table::context_id context)
 {
   tree_return_list *new_list = new tree_return_list ();
 
@@ -291,7 +293,7 @@
     {
       tree_index_expression *elt = *p;
 
-      new_list->append (elt->dup (scope));
+      new_list->append (elt->dup (scope, context));
     }
 
   return new_list;
--- a/src/pt-misc.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-misc.h	Wed May 07 13:45:30 2008 -0400
@@ -81,7 +81,8 @@
 
   octave_value_list convert_to_const_vector (const Cell& varargout);
 
-  tree_parameter_list *dup (symbol_table::scope_id scope);
+  tree_parameter_list *dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -114,7 +115,8 @@
 
   ~tree_return_list (void);
 
-  tree_return_list *dup (symbol_table::scope_id scope);
+  tree_return_list *dup (symbol_table::scope_id scope,
+			 symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-select.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-select.cc	Wed May 07 13:45:30 2008 -0400
@@ -60,10 +60,11 @@
 }
 
 tree_if_clause *
-tree_if_clause::dup (symbol_table::scope_id scope)
+tree_if_clause::dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context)
 {
-  return new tree_if_clause (expr ? expr->dup (scope) : 0,
-			     list ? list->dup (scope) : 0,
+  return new tree_if_clause (expr ? expr->dup (scope, context) : 0,
+			     list ? list->dup (scope, context) : 0,
 			     lead_comm ? lead_comm->dup () : 0);
 }
 
@@ -88,7 +89,8 @@
 }
 
 tree_if_command_list *
-tree_if_command_list::dup (symbol_table::scope_id scope)
+tree_if_command_list::dup (symbol_table::scope_id scope,
+			   symbol_table::context_id context)
 {
   tree_if_command_list *new_icl = new tree_if_command_list ();
 
@@ -96,7 +98,7 @@
     {
       tree_if_clause *elt = *p;
 
-      new_icl->append (elt ? elt->dup (scope) : 0);
+      new_icl->append (elt ? elt->dup (scope, context) : 0);
     }
 
   return new_icl;
@@ -129,9 +131,10 @@
 }
 
 tree_command *
-tree_if_command::dup (symbol_table::scope_id scope)
+tree_if_command::dup (symbol_table::scope_id scope,
+		      symbol_table::context_id context)
 {
-  return new tree_if_command (list ? list->dup (scope) : 0,
+  return new tree_if_command (list ? list->dup (scope, context) : 0,
 			      lead_comm ? lead_comm->dup () : 0,
 			      trail_comm ? trail_comm->dup () : 0,
 			      line (), column ());
@@ -243,10 +246,11 @@
 }
 
 tree_switch_case *
-tree_switch_case::dup (symbol_table::scope_id scope)
+tree_switch_case::dup (symbol_table::scope_id scope,
+		       symbol_table::context_id context)
 {
-  return new tree_switch_case (label ? label->dup (scope) : 0,
-			       list ? list->dup (scope) : 0,
+  return new tree_switch_case (label ? label->dup (scope, context) : 0,
+			       list ? list->dup (scope, context) : 0,
 			       lead_comm ? lead_comm->dup () : 0);
 }
 
@@ -271,7 +275,8 @@
 }
 
 tree_switch_case_list *
-tree_switch_case_list::dup (symbol_table::scope_id scope)
+tree_switch_case_list::dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context)
 {
   tree_switch_case_list *new_scl = new tree_switch_case_list ();
 
@@ -279,7 +284,7 @@
     {
       tree_switch_case *elt = *p;
 
-      new_scl->append (elt ? elt->dup (scope) : 0);
+      new_scl->append (elt ? elt->dup (scope, context) : 0);
     }
   
   return new_scl;
@@ -332,10 +337,11 @@
 }
 
 tree_command *
-tree_switch_command::dup (symbol_table::scope_id scope)
+tree_switch_command::dup (symbol_table::scope_id scope,
+			  symbol_table::context_id context)
 {
-  return new tree_switch_command (expr ? expr->dup (scope) : 0,
-				  list ? list->dup (scope) : 0,
+  return new tree_switch_command (expr ? expr->dup (scope, context) : 0,
+				  list ? list->dup (scope, context) : 0,
 				  lead_comm ? lead_comm->dup () : 0,
 				  trail_comm ? trail_comm->dup () : 0,
 				  line (), column ());
--- a/src/pt-select.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-select.h	Wed May 07 13:45:30 2008 -0400
@@ -64,7 +64,8 @@
 
   octave_comment_list *leading_comment (void) { return lead_comm; }
 
-  tree_if_clause *dup (symbol_table::scope_id scope);
+  tree_if_clause *dup (symbol_table::scope_id scope,
+		       symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -107,7 +108,8 @@
 
   void eval (void);
 
-  tree_if_command_list *dup (symbol_table::scope_id scope);
+  tree_if_command_list *dup (symbol_table::scope_id scope,
+			     symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -142,7 +144,8 @@
 
   octave_comment_list *trailing_comment (void) { return trail_comm; }
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -197,7 +200,8 @@
 
   octave_comment_list *leading_comment (void) { return lead_comm; }
 
-  tree_switch_case *dup (symbol_table::scope_id scope);
+  tree_switch_case *dup (symbol_table::scope_id scope,
+			 symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -240,7 +244,8 @@
 
   void eval (const octave_value& val);
 
-  tree_switch_case_list *dup (symbol_table::scope_id scope);
+  tree_switch_case_list *dup (symbol_table::scope_id scope,
+			      symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -282,7 +287,8 @@
 
   octave_comment_list *trailing_comment (void) { return trail_comm; }
 
-  tree_command *dup (symbol_table::scope_id scope);
+  tree_command *dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-stmt.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-stmt.cc	Wed May 07 13:45:30 2008 -0400
@@ -138,13 +138,14 @@
 }
 
 tree_statement *
-tree_statement::dup (symbol_table::scope_id scope)
+tree_statement::dup (symbol_table::scope_id scope,
+		     symbol_table::context_id context)
 {
   tree_statement *new_stmt = new tree_statement ();
 
-  new_stmt->cmd = cmd ? cmd->dup (scope) : 0;
+  new_stmt->cmd = cmd ? cmd->dup (scope, context) : 0;
 
-  new_stmt->expr = expr ? expr->dup (scope) : 0;
+  new_stmt->expr = expr ? expr->dup (scope, context) : 0;
 
   new_stmt->comm = comm ? comm->dup () : 0;
 
@@ -263,7 +264,8 @@
 }
 
 tree_statement_list *
-tree_statement_list::dup (symbol_table::scope_id scope)
+tree_statement_list::dup (symbol_table::scope_id scope,
+			  symbol_table::context_id context)
 {
   tree_statement_list *new_list = new tree_statement_list ();
 
@@ -273,7 +275,7 @@
     {
       tree_statement *elt = *p;
 
-      new_list->append (elt ? elt->dup (scope) : 0);
+      new_list->append (elt ? elt->dup (scope, context) : 0);
     }
 
   return new_list;
--- a/src/pt-stmt.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-stmt.h	Wed May 07 13:45:30 2008 -0400
@@ -86,7 +86,8 @@
 
   void set_expression (tree_expression *e) { expr = e; }
 
-  tree_statement *dup (symbol_table::scope_id scope);
+  tree_statement *dup (symbol_table::scope_id scope,
+		       symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -147,7 +148,8 @@
 
   octave_value_list list_breakpoints (void);
 
-  tree_statement_list *dup (symbol_table::scope_id scope);
+  tree_statement_list *dup (symbol_table::scope_id scope,
+			    symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/pt-unop.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-unop.cc	Wed May 07 13:45:30 2008 -0400
@@ -121,10 +121,11 @@
 }
 
 tree_expression *
-tree_prefix_expression::dup (symbol_table::scope_id scope)
+tree_prefix_expression::dup (symbol_table::scope_id scope,
+			     symbol_table::context_id context)
 {
   tree_prefix_expression *new_pe
-    = new tree_prefix_expression (op ? op->dup (scope) : 0,
+    = new tree_prefix_expression (op ? op->dup (scope, context) : 0,
 				  line (), column (), etype);
 
   new_pe->copy_base (*this);
@@ -218,10 +219,11 @@
 }
 
 tree_expression *
-tree_postfix_expression::dup (symbol_table::scope_id scope)
+tree_postfix_expression::dup (symbol_table::scope_id scope,
+			      symbol_table::context_id context)
 {
   tree_postfix_expression *new_pe
-    = new tree_postfix_expression (op ? op->dup (scope) : 0,
+    = new tree_postfix_expression (op ? op->dup (scope, context) : 0,
 				   line (), column (), etype);
 
   new_pe->copy_base (*this);
--- a/src/pt-unop.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/pt-unop.h	Wed May 07 13:45:30 2008 -0400
@@ -104,7 +104,8 @@
 
   void eval_error (void);
 
-  tree_expression *dup (symbol_table::scope_id scope);
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
@@ -142,7 +143,8 @@
 
   void eval_error (void);
 
-  tree_expression *dup (symbol_table::scope_id scope);
+  tree_expression *dup (symbol_table::scope_id scope,
+			symbol_table::context_id context);
 
   void accept (tree_walker& tw);
 
--- a/src/symtab.cc	Tue May 06 13:39:55 2008 -0400
+++ b/src/symtab.cc	Wed May 07 13:45:30 2008 -0400
@@ -73,7 +73,7 @@
 symbol_table::symbol_record::symbol_record_rep::dump
   (std::ostream& os, const std::string& prefix) const
 {
-  octave_value val = varval ();
+  octave_value val = varval (xcurrent_context);
 
   os << prefix << name;
 
--- a/src/symtab.h	Tue May 06 13:39:55 2008 -0400
+++ b/src/symtab.h	Wed May 07 13:45:30 2008 -0400
@@ -195,7 +195,7 @@
 	value_stack.push_back (v);
       }
 
-      octave_value& varref (void)
+      octave_value& varref (context_id context)
       {
 	if (is_global ())
 	  return symbol_table::global_varref (name);
@@ -204,14 +204,14 @@
 	else
 	  {
 	    context_id n = value_stack.size ();
-	    while (n++ <= symbol_table::xcurrent_context)
+	    while (n++ <= context)
 	      value_stack.push_back (octave_value ());
 
-	    return value_stack[symbol_table::xcurrent_context];
+	    return value_stack[context];
 	  }
       }
 
-      octave_value varval (void) const
+      octave_value varval (context_id context) const
       {
 	if (is_global ())
 	  return symbol_table::global_varval (name);
@@ -219,8 +219,8 @@
 	  return symbol_table::persistent_varval (name);
 	else
 	  {
-	    if (symbol_table::xcurrent_context < value_stack.size ())
-	      return value_stack[symbol_table::xcurrent_context];
+	    if (context < value_stack.size ())
+	      return value_stack[context];
 	    else
 	      return octave_value ();
 	  }
@@ -268,19 +268,24 @@
 
 	    if (is_persistent ())
 	      {
-		symbol_table::persistent_varref (name) = varval ();
+		symbol_table::persistent_varref (name)
+		  = varval (xcurrent_context);
+
 		unmark_persistent ();
 	      }
 
-	    varref () = octave_value ();
+	    varref (xcurrent_context) = octave_value ();
 	  }
       }
 
-      bool is_defined (void) const { return varval ().is_defined (); }
-
-      bool is_variable (void) const
+      bool is_defined (context_id context) const
       {
-	return (storage_class != local || is_defined ());
+	return varval (context).is_defined ();
+      }
+
+      bool is_variable (context_id context) const
+      {
+	return (storage_class != local || is_defined (context));
       }
 
       bool is_local (void) const { return storage_class & local; }
@@ -321,11 +326,11 @@
 
       void init_persistent (void)
       {
-	if (! is_defined ())
+	if (! is_defined (xcurrent_context))
 	  {
 	    mark_persistent ();
 
-	    varref () = symbol_table::persistent_varval (name);
+	    varref (xcurrent_context) = symbol_table::persistent_varval (name);
 	  }
 	// FIXME -- this causes trouble with recursive calls.
 	// else
@@ -340,7 +345,8 @@
 
       symbol_record_rep *dup (void)
       {
-	return new symbol_record_rep (name, varval (), storage_class);
+	return new symbol_record_rep (name, varval (xcurrent_context),
+				      storage_class);
       }
 
       void dump (std::ostream& os, const std::string& prefix) const;
@@ -400,9 +406,15 @@
     find (tree_argument_list *args, const string_vector& arg_names,
 	  octave_value_list& evaluated_args, bool& args_evaluated) const;
 
-    octave_value& varref (void) { return rep->varref (); }
-
-    octave_value varval (void) const { return rep->varval (); }
+    octave_value& varref (context_id context = xcurrent_context)
+    {
+      return rep->varref (context);
+    }
+
+    octave_value varval (context_id context = xcurrent_context) const
+    {
+      return rep->varval (context);
+    }
 
     void push_context (void) { rep->push_context (); }
 
@@ -410,8 +422,15 @@
 
     void clear (void) { rep->clear (); }
 
-    bool is_defined (void) const { return rep->is_defined (); }
-    bool is_variable (void) const { return rep->is_variable (); }
+    bool is_defined (context_id context = xcurrent_context) const
+    {
+      return rep->is_defined (context);
+    }
+
+    bool is_variable (context_id context = xcurrent_context) const
+    {
+      return rep->is_variable (context);
+    }
 
     bool is_local (void) const { return rep->is_local (); }
     bool is_automatic (void) const { return rep->is_automatic (); }
@@ -977,12 +996,13 @@
     return inst ? inst->do_find_symbol (name) : symbol_record ();
   }
 
-  static void inherit (scope_id scope, scope_id donor_scope)
+  static void
+  inherit (scope_id scope, scope_id donor_scope, context_id donor_context)
   {
     symbol_table *inst = get_instance (scope);
 
     if (inst)
-      inst->do_inherit (donor_scope);
+      inst->do_inherit (donor_scope, donor_context);
   }
 
   static bool at_top_level (void) { return xcurrent_scope == xtop_scope; }
@@ -1005,21 +1025,23 @@
   }
 
   static octave_value& varref (const std::string& name,
-			       scope_id scope = xcurrent_scope)
+			       scope_id scope = xcurrent_scope,
+			       context_id context = xcurrent_context)
   {
     static octave_value foobar;
 
     symbol_table *inst = get_instance (scope);
 
-    return inst ? inst->do_varref (name) : foobar;
+    return inst ? inst->do_varref (name, context) : foobar;
   }
 
   static octave_value varval (const std::string& name,
-			      scope_id scope = xcurrent_scope)
+			      scope_id scope = xcurrent_scope,
+			      context_id context = xcurrent_context)
   {
     symbol_table *inst = get_instance (scope);
 
-    return inst ? inst->do_varval (name) : octave_value ();
+    return inst ? inst->do_varval (name, context) : octave_value ();
   }
 
   static octave_value&
@@ -1488,12 +1510,14 @@
   }
 
   static std::list<symbol_record>
-  all_variables (scope_id scope = xcurrent_scope, bool defined_only = true)
+  all_variables (scope_id scope = xcurrent_scope,
+		 context_id context = xcurrent_context,
+		 bool defined_only = true)
   {
     symbol_table *inst = get_instance (scope);
 
     return inst
-      ? inst->do_all_variables (defined_only) : std::list<symbol_record> ();
+      ? inst->do_all_variables (context, defined_only) : std::list<symbol_record> ();
   }
 
   static std::list<symbol_record> glob (const std::string& pattern)
@@ -1811,7 +1835,7 @@
       return p->second;
   }
 
-  void do_inherit (scope_id donor_scope)
+  void do_inherit (scope_id donor_scope, context_id donor_context)
   {
     for (table_iterator p = table.begin (); p != table.end (); p++)
       {
@@ -1821,11 +1845,17 @@
 
 	if (! (sr.is_automatic () || sr.is_formal () || nm == "__retval__"))
 	  {
-	    octave_value val = symbol_table::varval (nm, donor_scope);
+	    octave_value val
+	      = symbol_table::varval (nm, donor_scope, donor_context);
 
 	    if (val.is_defined ())
 	      {
-		sr.varref () = val;
+		// Currently, inherit is always called when creating a
+		// new table, so it only makes sense to copy values into
+		// the base context (== 0), but maybe the context
+		// should be passed in as a parameter instead?
+
+		sr.varref (0) = val;
 
 		sr.mark_inherited ();
 	      }
@@ -1847,7 +1877,7 @@
       ? (table[name] = symbol_record (name)) : p->second;
   }
 
-  octave_value& do_varref (const std::string& name)
+  octave_value& do_varref (const std::string& name, context_id context)
   {
     table_iterator p = table.find (name);
 
@@ -1855,17 +1885,17 @@
       {
 	symbol_record& sr = do_insert (name);
 
-	return sr.varref ();
+	return sr.varref (context);
       }
     else
-      return p->second.varref ();
+      return p->second.varref (context);
   }
 
-  octave_value do_varval (const std::string& name) const
+  octave_value do_varval (const std::string& name, context_id context) const
   {
     table_const_iterator p = table.find (name);
 
-    return (p != table.end ()) ? p->second.varval () : octave_value ();
+    return (p != table.end ()) ? p->second.varval (context) : octave_value ();
   }
 
   octave_value& do_persistent_varref (const std::string& name)
@@ -2017,7 +2047,8 @@
       p->second.mark_global ();
   }
 
-  std::list<symbol_record> do_all_variables (bool defined_only) const
+  std::list<symbol_record>
+  do_all_variables (context_id context, bool defined_only) const
   {
     std::list<symbol_record> retval;
 
@@ -2025,7 +2056,7 @@
       {
 	const symbol_record& sr = p->second;
 
-	if (defined_only && ! sr.is_defined ())
+	if (defined_only && ! sr.is_defined (context))
 	  continue;
 
 	retval.push_back (sr);