changeset 10544:9961fc022d9d

fix assignment to non-existing variables and octave_value::assign
author Jaroslav Hajek <highegg@gmail.com>
date Fri, 23 Apr 2010 11:23:43 +0200
parents f41c6634d5af
children ffe28cdc6fe2
files src/ChangeLog src/oct-lvalue.cc src/ov-base-mat.h src/ov-base-scalar.h src/ov-base-sparse.h src/ov-base.cc src/ov-base.h src/ov-bool.h src/ov-float.h src/ov.cc src/ov.h
diffstat 11 files changed, 54 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Fri Apr 23 09:48:57 2010 +0200
+++ b/src/ChangeLog	Fri Apr 23 11:23:43 2010 +0200
@@ -1,3 +1,23 @@
+2010-04-23  Jaroslav Hajek  <highegg@gmail.com>
+
+	* ov-bool.h (octave_bool::empty_clone): Correctly return an empty
+	matrix.
+	* ov-float.h (octave_float::empty_clone): Ditto.
+	* ov-base-mat.h (octave_base_matrix::clone,
+	octave_base_matrix::empty_clone): Remove.
+	* ov-base-scalar.h (octave_base_scalar::clone,
+	octave_base_scalar::empty_clone): Remove.
+	* ov-base-sparse.h (octave_base_sparse::clone,
+	octave_base_sparse::empty_clone): Remove.
+	* ov-base.h (octave_base_value::empty_clone): Remove implementation.
+	* ov-base.cc (octave_base_value::empty_clone): Implement here.
+	Fall back to resize() for empty_clone().
+	* ov.cc (octave_value::assign): Correct behavior in the indexed OP= case.
+	Use better error messages. Always return non-const reference, like any
+	assignment.
+	* ov.h: Update decls.
+	* oct-lvalue.cc (octave_lvalue::assign): Simplify.
+
 2010-04-22  Rik <octave@nomad.inbox5.com>
 
 	* DLD-FUNCTIONS/hess.cc.: return correct Hessenberg matrix when called 
--- a/src/oct-lvalue.cc	Fri Apr 23 09:48:57 2010 +0200
+++ b/src/oct-lvalue.cc	Fri Apr 23 11:23:43 2010 +0200
@@ -35,12 +35,10 @@
 {
   if (val)
     {
-      octave_value tmp (idx.empty ()
-                        ? val->assign (op, rhs)
-                        : val->assign (op, type, idx, rhs));
-
-      if (! error_state)
-        *val = tmp;
+      if (idx.empty ())
+        val->assign (op, rhs);
+      else
+        val->assign (op, type, idx, rhs);
     }
 }
 
--- a/src/ov-base-mat.h	Fri Apr 23 09:48:57 2010 +0200
+++ b/src/ov-base-mat.h	Fri Apr 23 11:23:43 2010 +0200
@@ -70,9 +70,6 @@
 
   ~octave_base_matrix (void) { clear_cached_info (); }
 
-  octave_base_value *clone (void) const { return new octave_base_matrix (*this); }
-  octave_base_value *empty_clone (void) const { return new octave_base_matrix (); }
-
   size_t byte_size (void) const { return matrix.byte_size (); }
 
   octave_value squeeze (void) const { return MT (matrix.squeeze ()); }
--- a/src/ov-base-scalar.h	Fri Apr 23 09:48:57 2010 +0200
+++ b/src/ov-base-scalar.h	Fri Apr 23 11:23:43 2010 +0200
@@ -57,9 +57,6 @@
 
   ~octave_base_scalar (void) { }
 
-  octave_base_value *clone (void) const { return new octave_base_scalar (*this); }
-  octave_base_value *empty_clone (void) const { return new octave_base_scalar (); }
-
   octave_value squeeze (void) const { return scalar; }
 
   octave_value full_value (void) const { return scalar; }
--- a/src/ov-base-sparse.h	Fri Apr 23 09:48:57 2010 +0200
+++ b/src/ov-base-sparse.h	Fri Apr 23 11:23:43 2010 +0200
@@ -72,10 +72,6 @@
 
   ~octave_base_sparse (void) { }
 
-  octave_base_value *clone (void) const { return new octave_base_sparse (*this); }
-  octave_base_value *empty_clone (void) const 
-    { return new octave_base_sparse (); }
-
   octave_idx_type nnz (void) const { return matrix.nnz (); }
 
   octave_idx_type nzmax (void) const { return matrix.nzmax (); }
--- a/src/ov-base.cc	Fri Apr 23 09:48:57 2010 +0200
+++ b/src/ov-base.cc	Fri Apr 23 11:23:43 2010 +0200
@@ -115,6 +115,12 @@
 // is memory to be saved
 bool Vsparse_auto_mutate = false;
 
+octave_base_value *
+octave_base_value::empty_clone (void) const
+{
+  return resize (dim_vector ()).clone ();
+}
+
 octave_value
 octave_base_value::squeeze (void) const
 {
--- a/src/ov-base.h	Fri Apr 23 09:48:57 2010 +0200
+++ b/src/ov-base.h	Fri Apr 23 11:23:43 2010 +0200
@@ -216,7 +216,7 @@
 
   // Empty clone.
   virtual octave_base_value *
-  empty_clone (void) const { return new octave_base_value (); }
+  empty_clone (void) const;
 
   // Unique clone. Usually clones, but may be overriden to fake the
   // cloning when sharing copies is to be controlled from within an
--- a/src/ov-bool.h	Fri Apr 23 09:48:57 2010 +0200
+++ b/src/ov-bool.h	Fri Apr 23 11:23:43 2010 +0200
@@ -37,6 +37,7 @@
 #include "oct-stream.h"
 #include "ov-base.h"
 #include "ov-base-scalar.h"
+#include "ov-bool-mat.h"
 #include "ov-scalar.h"
 #include "ov-typeinfo.h"
 
@@ -65,7 +66,7 @@
   ~octave_bool (void) { }
 
   octave_base_value *clone (void) const { return new octave_bool (*this); }
-  octave_base_value *empty_clone (void) const { return new octave_bool (); }
+  octave_base_value *empty_clone (void) const { return new octave_bool_matrix (); }
 
   type_conv_info numeric_conversion_function (void) const;
 
--- a/src/ov-float.h	Fri Apr 23 09:48:57 2010 +0200
+++ b/src/ov-float.h	Fri Apr 23 11:23:43 2010 +0200
@@ -72,7 +72,7 @@
   // We return an octave_matrix here instead of an octave_float_scalar so
   // that in expressions like A(2,2,2) = 2 (for A previously
   // undefined), A will be empty instead of a 1x1 object.
-  octave_base_value *empty_clone (void) const { return new octave_matrix (); }
+  octave_base_value *empty_clone (void) const { return new octave_float_matrix (); }
 
   octave_value do_index_op (const octave_value_list& idx,
                             bool resize_ok = false);
--- a/src/ov.cc	Fri Apr 23 09:48:57 2010 +0200
+++ b/src/ov.cc	Fri Apr 23 11:23:43 2010 +0200
@@ -1271,7 +1271,7 @@
   return rep->subsasgn (type, idx, rhs);
 }
 
-octave_value
+octave_value&
 octave_value::assign (assign_op op, const std::string& type,
                       const std::list<octave_value_list>& idx,
                       const octave_value& rhs)
@@ -1284,15 +1284,20 @@
 
   if (op != op_asn_eq)
     {
-      octave_value t = subsref (type, idx);
-
-      if (! error_state)
+      if (is_defined ())
         {
-          binary_op binop = op_eq_to_binary_op (op);
+          octave_value t = subsref (type, idx);
 
           if (! error_state)
-            t_rhs = do_binary_op (binop, t, rhs);
+            {
+              binary_op binop = op_eq_to_binary_op (op);
+
+              if (! error_state)
+                t_rhs = do_binary_op (binop, t, rhs);
+            }
         }
+      else
+        error ("in computed assignment A(index) OP= X, A must be defined first");
     }
 
   if (! error_state)
@@ -1300,26 +1305,26 @@
       if (type[0] == '.' && ! (is_map () || is_object ()))
         {
           octave_value tmp = Octave_map ();
-          retval = tmp.subsasgn (type, idx, t_rhs);
+          *this = tmp.subsasgn (type, idx, t_rhs);
         }
       else
-        retval = subsasgn (type, idx, t_rhs);
+        *this = subsasgn (type, idx, t_rhs);
 
       if (error_state)
         gripe_assign_failed_or_no_method (assign_op_as_string (op_asn_eq),
                                           type_name (), rhs.type_name ());
     }
 
-  return retval;
+  return *this;
 }
 
-const octave_value&
+octave_value&
 octave_value::assign (assign_op op, const octave_value& rhs)
 {
   if (op == op_asn_eq)
     // Regularize a null matrix if stored into a variable.
     operator = (rhs.storable_value ());
-  else
+  else if (is_defined ())
     {
       octave_value_typeinfo::assign_op_fcn f = 0;
       
@@ -1358,6 +1363,8 @@
             }
         }
     }
+  else
+    error ("in computed assignment A OP= X, A must be defined first");
 
   return *this;
 }
--- a/src/ov.h	Fri Apr 23 09:48:57 2010 +0200
+++ b/src/ov.h	Fri Apr 23 11:23:43 2010 +0200
@@ -411,11 +411,11 @@
                                  const std::list<octave_value_list>& idx,
                                  const octave_value& rhs);
 
-  octave_value assign (assign_op op, const std::string& type,
+  octave_value& assign (assign_op op, const std::string& type,
                        const std::list<octave_value_list>& idx,
                        const octave_value& rhs);
 
-  const octave_value& assign (assign_op, const octave_value& rhs);
+  octave_value& assign (assign_op, const octave_value& rhs);
 
   idx_vector index_vector (void) const
     { return rep->index_vector (); }