changeset 2948:56be458e237f

[project @ 1997-05-09 13:37:35 by jwe]
author jwe
date Fri, 09 May 1997 13:51:06 +0000
parents cf676ff8b702
children 49b42be38aa1
files src/ov-base.cc src/ov-base.h src/ov-re-mat.cc src/ov-re-mat.h src/ov-struct.cc src/ov-struct.h src/ov.cc src/ov.h src/pt-cmd.cc src/pt-const.h src/pt-exp.cc src/pt-id.cc src/pt-id.h src/pt-indir.cc src/pt-indir.h src/pt-misc.cc src/symtab.h
diffstat 17 files changed, 223 insertions(+), 172 deletions(-) [+]
line wrap: on
line diff
--- a/src/ov-base.cc
+++ b/src/ov-base.cc
@@ -44,6 +44,7 @@
 #include "ov-str-mat.h"
 #include "ov-range.h"
 #include "ov-list.h"
+#include "variables.h"
 
 int octave_base_value::t_id = -1;
 
@@ -74,14 +75,13 @@
   return octave_value ();
 }
 
-octave_value&
-octave_base_value::struct_elt_ref (const string&)
+octave_variable_reference
+octave_base_value::struct_elt_ref (octave_value *, const string&)
 {
-  static octave_value foo;
   string nm = type_name ();
   error ("can't perform structure reference operations for %s type",
 	 nm.c_str ());
-  return foo;
+  return octave_variable_reference ();
 }
 
 octave_value
--- a/src/ov-base.h
+++ b/src/ov-base.h
@@ -76,7 +76,8 @@
 
   octave_value struct_elt_val (const string& nm, bool silent) const;
 
-  octave_value& struct_elt_ref (const string& nm);
+  octave_variable_reference
+  struct_elt_ref (octave_value *parent, const string& nm);
 
   int rows (void) const { return -1; }
 
--- a/src/ov-re-mat.cc
+++ b/src/ov-re-mat.cc
@@ -40,6 +40,7 @@
 #include "ov-scalar.h"
 #include "ov-re-mat.h"
 #include "pr-output.h"
+#include "variables.h"
 
 octave_allocator
 octave_matrix::allocator (sizeof (octave_matrix));
@@ -146,6 +147,105 @@
     }
 }
 
+void
+octave_matrix::assign_struct_elt (assign_op, const string& nm,
+				  const octave_value& rhs)
+{
+  octave_value retval;
+
+  Matrix m = rhs.matrix_value ();
+
+  if (! error_state)
+    {
+      int nr = -1;
+      int nc = -1;
+
+      int dim = -1;
+
+      if (m.rows () == 1 && m.cols () == 2)
+	{
+	  nr = NINT (m (0, 0));
+	  nc = NINT (m (0, 1));
+	}
+      else if (m.rows () == 2 && m.cols () == 1)
+	{
+	  nr = NINT (m (0, 0));
+	  nc = NINT (m (1, 0));
+	}
+      else if (m.rows () == 1 && m.cols () == 1)
+	{
+	  dim = NINT (m (0, 0));
+
+	  nr = matrix.rows ();
+	  nc = matrix.cols ();
+	}
+
+      if (nm == "size")
+	{
+	  if (nr >= 0 && nc >= 0)
+	    matrix.resize (nr, nc, 0.0);
+	  else
+	    error ("invalid size specification = [%d, %d] specified",
+		   nr, nc);
+	}
+      else if (nm == "rows")
+	{
+	  if (dim >= 0)
+	    matrix.resize (dim, nc, 0.0);
+	  else
+	    error ("invalid row dimension = %d specified", dim);
+	}
+      else if (nm == "cols" || nm == "columns")
+	{
+	  if (dim >= 0)
+	    matrix.resize (nr, dim, 0.0);
+	  else
+	    error ("invalid column dimension = %d specified", dim);
+	}
+    }
+}
+
+void
+octave_matrix::assign_struct_elt (assign_op, const string&,
+				  const octave_value_list&,
+				  const octave_value&)
+{
+  error ("indexed assignment for matrix properties is not implemented");
+}
+
+octave_value
+octave_matrix::struct_elt_val (const string& nm, bool silent) const
+{
+  octave_value retval;
+
+  double nr = static_cast<double> (matrix.rows ());
+  double nc = static_cast<double> (matrix.cols ());
+
+  if (nm == "rows")
+    retval = nr;
+  else if (nm == "cols" || nm == "columns")
+    retval = nc;
+  else if (nm == "size")
+    {
+      Matrix tmp (1, 2);
+
+      tmp.elem (0, 0) = nr;
+      tmp.elem (0, 1) = nc;
+
+      retval = tmp;
+    }
+  else if (! silent)
+    error ("structure has no member `%s'", nm.c_str ());
+
+  return retval;
+}
+
+octave_variable_reference
+octave_matrix::struct_elt_ref (octave_value *parent, const string& nm)
+{
+  return octave_variable_reference (parent, nm);
+}
+
 bool
 octave_matrix::valid_as_scalar_index (void) const
 {
--- a/src/ov-re-mat.h
+++ b/src/ov-re-mat.h
@@ -85,8 +85,20 @@
 
   void assign (const octave_value_list& idx, const Matrix& rhs);
 
+  void assign_struct_elt (assign_op, const string& elt_nm,
+			  const octave_value& rhs);
+
+  void assign_struct_elt (assign_op, const string& elt_nm,
+			  const octave_value_list& idx,
+			  const octave_value& rhs);
+
   idx_vector index_vector (void) const { return idx_vector (matrix); }
 
+  octave_value struct_elt_val (const string& nm, bool silent) const;
+
+  octave_variable_reference
+  struct_elt_ref (octave_value *parent, const string& nm);
+
   int rows (void) const { return matrix.rows (); }
   int columns (void) const { return matrix.columns (); }
 
--- a/src/ov-struct.cc
+++ b/src/ov-struct.cc
@@ -33,6 +33,7 @@
 #include "error.h"
 #include "ov-struct.h"
 #include "unwind-prot.h"
+#include "variables.h"
 
 octave_allocator
 octave_struct::allocator (sizeof (octave_struct));
@@ -58,10 +59,10 @@
   return retval;
 }
 
-octave_value&
-octave_struct::struct_elt_ref (const string& nm)
+octave_variable_reference
+octave_struct::struct_elt_ref (octave_value *, const string& nm)
 {
-  return map [nm];
+  return octave_variable_reference (&map [nm]);
 }
 
 void
--- a/src/ov-struct.h
+++ b/src/ov-struct.h
@@ -75,7 +75,8 @@
 
   octave_value struct_elt_val (const string& nm, bool silent) const;
 
-  octave_value& struct_elt_ref (const string& nm);
+  octave_variable_reference
+  struct_elt_ref (octave_value *parent, const string& nm);
 
   bool is_defined (void) const { return true; }
 
--- a/src/ov.cc
+++ b/src/ov.cc
@@ -102,16 +102,16 @@
 // error.
 int Vpropagate_empty_matrices;
 
-// If TRUE, resize matrices when performing and indexed assignment and
-// the indices are outside the current bounds.
-bool Vresize_on_range_error;
-
 // How many levels of structure elements should we print?
 int Vstruct_levels_to_print;
 
 // Allow divide by zero errors to be suppressed.
 bool Vwarn_divide_by_zero;
 
+// If TRUE, resize matrices when performing and indexed assignment and
+// the indices are outside the current bounds.
+static bool Vresize_on_range_error;
+
 // XXX FIXME XXX
 
 // Octave's value type.
@@ -498,22 +498,64 @@
 		      const octave_value_list& idx,
 		      const octave_value& rhs)
 {
+  if (Vresize_on_range_error || is_defined ())
+    {
+      make_unique ();
+
+      bool assignment_ok = try_assignment (op, idx, rhs);
+
+      if (! (error_state || assignment_ok))
+	{
+	  assignment_ok = try_assignment_with_conversion (op,idx, rhs);
+
+	  if (! (error_state || assignment_ok))
+	    gripe_no_conversion (type_name (), rhs.type_name ());
+	}
+
+      if (! error_state)
+	maybe_mutate ();
+    }
+  else
+    {
+      error ("indexed assignment to previously undefined variables");
+      error ("is only possible when resize_on_range_error is true");
+    }
+
+  return *this;
+}
+
+void
+octave_value::assign_struct_elt (assign_op op, const string& elt_nm,
+				 const octave_value& rhs)
+{
   make_unique ();
 
-  bool assignment_ok = try_assignment (op, idx, rhs);
+  rep->assign_struct_elt (op, elt_nm, rhs);
+}
+
 
-  if (! (error_state || assignment_ok))
-    {
-      assignment_ok = try_assignment_with_conversion (op,idx, rhs);
+void
+octave_value::assign_struct_elt (assign_op op, const string& elt_nm,
+				 const octave_value_list& idx,
+				 const octave_value& rhs)
+{
+  make_unique ();
 
-      if (! (error_state || assignment_ok))
-	gripe_no_conversion (type_name (), rhs.type_name ());
-    }
+  rep->assign_struct_elt (op, elt_nm, idx, rhs);
+}
 
-  if (! error_state)
-    maybe_mutate ();
+octave_variable_reference
+octave_value::struct_elt_ref (const string& nm)
+{
+  return rep->struct_elt_ref (this, nm);
+}
 
-  return *this;
+octave_variable_reference
+octave_value::struct_elt_ref (octave_value *, const string&)
+{
+  panic_impossible ();
+
+  return octave_variable_reference ();
 }
 
 octave_value_list
--- a/src/ov.h
+++ b/src/ov.h
@@ -44,6 +44,7 @@
 class Octave_map;
 class octave_stream;
 class octave_value_list;
+class octave_variable_reference;
 
 // Constants.
 
@@ -220,6 +221,14 @@
   octave_value& assign (assign_op, const octave_value_list& idx,
 			const octave_value& rhs);
 
+  virtual void
+  assign_struct_elt (assign_op, const string& elt_nm,
+		     const octave_value& rhs);
+
+  virtual void
+  assign_struct_elt (assign_op, const string& elt_nm,
+		     const octave_value_list& idx, const octave_value& rhs);
+
   virtual idx_vector index_vector (void) const
     { return rep->index_vector (); }
 
@@ -227,8 +236,10 @@
   struct_elt_val (const string& nm, bool silent = false) const
     { return rep->struct_elt_val (nm, silent); }
 
-  virtual octave_value& struct_elt_ref (const string& nm)
-    { return rep->struct_elt_ref (nm); }
+  octave_variable_reference struct_elt_ref (const string& nm);
+
+  virtual octave_variable_reference
+  struct_elt_ref (octave_value *parent, const string& nm);
 
   // Size.
 
@@ -524,10 +535,6 @@
 // error.
 extern int Vpropagate_empty_matrices;
 
-// If TRUE, resize matrices when performing and indexed assignment and
-// the indices are outside the current bounds.
-extern bool Vresize_on_range_error;
-
 // How many levels of structure elements should we print?
 extern int Vstruct_levels_to_print;
 
--- a/src/pt-cmd.cc
+++ b/src/pt-cmd.cc
@@ -307,29 +307,25 @@
 {
   quit = false;
 
-  octave_variable_reference tmp (ident);
+  ident->reference () . assign (octave_value::asn_eq, rhs);
 
-  if (error_state)
+  if (! error_state)
     {
-      eval_error ();
-      return;
-    }
-
-  tmp.assign (octave_value::asn_eq, rhs);
-
-  if (list)
-    {
-      list->eval ();
+      if (list)
+	list->eval ();
 
       if (error_state)
 	{
 	  eval_error ();
 	  quit = true;
-	  return;
 	}
+      else
+	quit = quit_loop_now ();
     }
+  else
+    eval_error ();
 
-  quit = quit_loop_now ();
+  return;
 }
 
 #define DO_LOOP(val) \
--- a/src/pt-const.h
+++ b/src/pt-const.h
@@ -78,23 +78,6 @@
   octave_value index (const octave_value_list& idx) const
     { return val.index (idx); }
 
-  octave_value& reference (void)
-    {
-      val.make_unique ();
-      return val;
-    }
-
-  octave_value value (void) const
-    { return val; }
-
-  octave_value assign (octave_value::assign_op op,
-		       const octave_value_list& idx,
-		       const octave_value& rhs)
-    {
-      val.assign (op, idx, rhs);
-      return val;
-    }
-
   // Type.  It would be nice to eliminate the need for this.
 
   bool is_constant (void) const { return true; }
--- a/src/pt-exp.cc
+++ b/src/pt-exp.cc
@@ -513,8 +513,8 @@
   return lhs->ident ();
 }
 
-// ??? FIXME ??? -- should octave_variable_reference::assign return
-// the right thing for us to return?
+// ??? FIXME ??? -- should octave_value::assign return the right thing
+// for us to return?
 
 octave_value
 tree_simple_assignment_expression::eval (bool print)
@@ -541,7 +541,7 @@
 	}
       else
 	{
-	  octave_variable_reference ult (lhs);
+	  octave_variable_reference ult = lhs->reference ();
 
 	  if (error_state)
 	    eval_error ();
--- a/src/pt-id.cc
+++ b/src/pt-id.cc
@@ -78,83 +78,6 @@
     sym->document (s);
 }
 
-octave_value
-tree_identifier::assign (octave_value::assign_op op, const octave_value& rhs)
-{
-  octave_value retval;
-
-  if (rhs.is_defined ())
-    {
-      if (! sym->is_defined ())
-	{
-	  if (! (sym->is_formal_parameter ()
-		 || sym->is_linked_to_global ()))
-	    {
-	      link_to_builtin_variable (sym);
-	    }
-	}
-      else if (sym->is_function ())
-	{
-	  sym->clear ();
-	}
-
-      // XXX FIXME XXX -- make this work for ops other than `='.
-
-      if (sym->define (rhs))
-	retval = rhs;
-    }
-
-  return retval;
-}
-
-octave_value
-tree_identifier::assign (octave_value::assign_op op,
-			 const octave_value_list& args,
-			 const octave_value& rhs)
-{
-  octave_value retval;
-
-  if (rhs.is_defined ())
-    {
-      if (! sym->is_defined ())
-	{
-	  if (! (sym->is_formal_parameter ()
-		 || sym->is_linked_to_global ()))
-	    {
-	      link_to_builtin_variable (sym);
-	    }
-	}
-      else if (sym->is_function ())
-	{
-	  sym->clear ();
-	}
-
-      if (sym->is_variable () && sym->is_defined ())
-	{
-	  sym->variable_reference () . assign (op, args, rhs);
-	}
-      else
-	{
-	  assert (! sym->is_defined ());
-
-	  if (! Vresize_on_range_error)
-	    {
-	      ::error ("indexed assignment to previously undefined variables");
-	      ::error ("is only possible when resize_on_range_error is true");
-	    }
-	  else
-	    {
-	      retval.assign (op, args, rhs);
-
-	      if (retval.is_defined ())
-		sym->define (retval);
-	    }
-	}
-    }
-
-  return retval;
-}
-
 bool
 tree_identifier::is_defined (void)
 {
@@ -350,7 +273,7 @@
   return sym->variable_value ();
 }
 
-octave_value&
+octave_variable_reference
 tree_identifier::reference (void)
 {
   return sym->variable_reference ();
--- a/src/pt-id.h
+++ b/src/pt-id.h
@@ -71,13 +71,6 @@
 
   void document (const string& s);
 
-  octave_value assign (octave_value::assign_op op,
-		       const octave_value& t);
-
-  octave_value assign (octave_value::assign_op op,
-		       const octave_value_list& args,
-		       const octave_value& t);
-
   bool is_defined (void);
 
   void increment (void);
@@ -107,7 +100,7 @@
 
   octave_value value (void) const;
 
-  octave_value& reference (void);
+  octave_variable_reference reference (void);
 
 private:
 
--- a/src/pt-indir.cc
+++ b/src/pt-indir.cc
@@ -164,33 +164,26 @@
   return retval;
 }
 
-octave_value&
+octave_variable_reference
 tree_indirect_ref::reference (void)
 {
   if (is_identifier_only ())
     return id->reference ();
   else
     {
+      octave_variable_reference tmp;
+
       if (id)
-	{
-	  octave_value& tmp = id->reference ();
-	  if (tmp.is_undefined () || ! tmp.is_map ())
-	    tmp = Octave_map ();
-	  return tmp.struct_elt_ref (nm);
-	}
+	tmp = id->reference ();
       else if (indir)
-	{
-	  octave_value& tmp = indir->reference ();
-	  if (tmp.is_undefined () || ! tmp.is_map ())
-	    tmp = Octave_map ();
-	  return tmp.struct_elt_ref (nm);
-	}
+	tmp = indir->reference ();
       else
-	{
-	  static octave_value foo;
-	  panic_impossible ();
-	  return foo;
-	}
+	panic_impossible ();
+
+      if (tmp.is_undefined ())
+	tmp.define (Octave_map ());
+
+      return tmp.struct_elt_ref (nm);
     }
 }
 
--- a/src/pt-indir.h
+++ b/src/pt-indir.h
@@ -91,7 +91,8 @@
   eval (bool print, int nargout, const octave_value_list& args);
 
   octave_value value (void) const;
-  octave_value& reference (void);
+
+  octave_variable_reference reference (void);
 
   string elt_name (void)
     { return nm; }
--- a/src/pt-misc.cc
+++ b/src/pt-misc.cc
@@ -365,11 +365,9 @@
   for (Pix p = first (); p != 0; next (p))
     {
       tree_identifier *elt = this->operator () (p);
+
       if (! elt->is_defined ())
-	{
-	  octave_variable_reference tmp (elt);
-	  tmp.assign (octave_value::asn_eq, val);
-	}
+	elt->reference () . assign (octave_value::asn_eq, val);
     }
 }
 
--- a/src/symtab.h
+++ b/src/symtab.h
@@ -180,7 +180,7 @@
   bool is_static (void) const;
 
   octave_value variable_value (void) const;
-  octave_value& variable_reference (void);
+  octave_variable_reference variable_reference (void);
 
   symbol_record *next (void) const;