changeset 8051:36a485f7f335

symtab.h (symbol_table::do_inherit): copy alll symbols from donor scope
author John W. Eaton <jwe@octave.org>
date Fri, 22 Aug 2008 16:29:17 -0400
parents dac919d9c418
children 961d4c52ffae
files src/ChangeLog src/symtab.h
diffstat 2 files changed, 41 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Fri Aug 22 14:42:12 2008 -0400
+++ b/src/ChangeLog	Fri Aug 22 16:29:17 2008 -0400
@@ -1,3 +1,10 @@
+2008-08-22  John W. Eaton  <jwe@octave.org>
+
+	* symtab.h (symbol_table::inherit): Pass reference to symbol table
+	to do_inherit instead of scope.
+	(symbol_table::do_inherit): First arg is now reference to
+	symbol_table, not scope id.  Insert all variables from donor scope.
+
 2008-08-21  Thomas Treichl  <Thomas.Treichl@gmx.net>
 	
 	* mappers.cc: Increase test script tolerance.
--- a/src/symtab.h	Fri Aug 22 14:42:12 2008 -0400
+++ b/src/symtab.h	Fri Aug 22 16:29:17 2008 -0400
@@ -1020,7 +1020,12 @@
     symbol_table *inst = get_instance (scope);
 
     if (inst)
-      inst->do_inherit (donor_scope, donor_context);
+      {
+	symbol_table *donor_symbol_table = get_instance (donor_scope);
+
+	if (donor_symbol_table)
+	  inst->do_inherit (*donor_symbol_table, donor_context);
+      }
   }
 
   static bool at_top_level (void) { return xcurrent_scope == xtop_scope; }
@@ -1923,18 +1928,39 @@
       return p->second;
   }
 
-  void do_inherit (scope_id donor_scope, context_id donor_context)
+  void do_inherit (symbol_table& donor_symbol_table, context_id donor_context)
   {
-    for (table_iterator p = table.begin (); p != table.end (); p++)
+    // Copy all variables from the donor scope in case they are needed
+    // in a subsequent anonymous function.  For example, to allow
+    //
+    //   function r = f2 (f, x)
+    //     r = f (x);
+    //   end
+    //
+    //   function f = f1 (k)
+    //     f = @(x) f2 (@(y) y-k, x);
+    //   end
+    //
+    //   f = f1 (3)  ==>  @(x) fcn2 (@(y) y - k, x)
+    //   f (10)      ==>  7
+    //
+    // to work as expected.
+    //
+    // FIXME -- is there a better way to accomplish this?
+
+    std::map<std::string, symbol_record> donor_table = donor_symbol_table.table;
+
+    for (table_iterator p = donor_table.begin (); p != donor_table.end (); p++)
       {
-	symbol_record& sr = p->second;
-
-	std::string nm = sr.name ();
+	symbol_record& donor_sr = p->second;
+
+	std::string nm = donor_sr.name ();
+
+	symbol_record& sr = do_insert (nm);
 
 	if (! (sr.is_automatic () || sr.is_formal () || nm == "__retval__"))
 	  {
-	    octave_value val
-	      = symbol_table::varval (nm, donor_scope, donor_context);
+	    octave_value val = donor_sr.varval (donor_context);
 
 	    if (val.is_defined ())
 	      {