changeset 12055:c663c1a78c4a release-3-2-x

implant tree_index_expression::lvalue from development version
author Jaroslav Hajek <highegg@gmail.com>
date Fri, 07 Aug 2009 08:11:49 +0200
parents e868e6276b5c
children 68a4e6a2dc31
files src/ChangeLog src/pt-idx.cc
diffstat 2 files changed, 98 insertions(+), 159 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+2009-08-07  Jaroslav Hajek  <highegg@gmail.com>
+
+	* pt-idx.cc (tree_index_expression::lvalue): Implant code from
+	development version.
+	(get_numel): New assistant function.
+
 2009-07-29  John W. Eaton  <jwe@octave.org>
 
 	* ov-float.cc, ov-flt-re-mat.cc, ov-re-mat.cc, ov-re-sparse.cc,
--- a/src/pt-idx.cc
+++ b/src/pt-idx.cc
@@ -403,12 +403,39 @@
   return retval;
 }
 
+static octave_idx_type
+get_numel (const octave_value& val,
+           const octave_value_list& idx)
+{
+  octave_idx_type retval;
+
+  octave_idx_type len = idx.length ();
+
+  if (len == 0)
+    retval = val.numel ();
+  else
+    {
+      const dim_vector dv = val.dims ().redim (len);
+      retval = 1;
+      for (octave_idx_type i = 0; i < len; i++)
+        {
+          if (idx(i).is_magic_colon ())
+            retval *= dv(i);
+          else
+            retval *= idx(i).numel ();
+        }
+    }
+
+  return retval;
+}
+
 octave_lvalue
 tree_index_expression::lvalue (void)
 {
   octave_lvalue retval;
 
   std::list<octave_value_list> idx;
+  std::string tmp_type;
 
   int n = args.size ();
 
@@ -420,16 +447,13 @@
 
   if (! error_state)
     {
-      // I think it is OK to have a copy here.
-
       const octave_value *tro = retval.object ();
 
-      octave_value first_retval_object;
+      octave_value tmp;
 
       if (tro)
-	first_retval_object = *tro;
+	tmp = *tro;
 
-      octave_value tmp = first_retval_object;
       octave_idx_type tmpi = 0;
       std::list<octave_value_list> tmpidx;
 
@@ -437,45 +461,14 @@
 	{
           if (retval.numel () != 1)
             gripe_indexed_cs_list ();
-
-          if (i > 0)
+          else if (tmpi < i)
             {
-              tree_argument_list *al = *p_args;
-
-              if (al && al->has_magic_end ())
-                {
-                  // We have an expression like
-                  //
-                  //   x{end}.a(end)
-                  //
-                  // and we are looking at the argument list that
-                  // contains the second (or third, etc.) "end" token,
-                  // so we must evaluate everything up to the point of
-                  // that argument list so we pass the appropriate
-                  // value to the built-in __end__ function.
+              tmp = tmp.subsref (type.substr (tmpi, i - tmpi), tmpidx, true);
+              tmpidx.clear ();
+            }
 
-                  if (tmp.is_defined ())
-                    {
-                      if (tmpi < i)
-                        {
-                          tmp = tmp.subsref (type.substr (tmpi, i - tmpi), tmpidx, true);
-
-                          tmpi = i;
-                          tmpidx.clear ();
-                        }
-                    }
-                  else
-                    gripe_invalid_inquiry_subscript ();
-
-                  if (tmp.is_undefined ())
-                    gripe_invalid_inquiry_subscript ();
-                  else if (tmp.is_cs_list ())
-                    gripe_indexed_cs_list ();
-
-                  if (error_state)
-                    break;
-                }
-            }
+          if (error_state)
+            break;
 
 	  switch (type[i])
 	    {
@@ -483,8 +476,19 @@
               {
                 octave_value_list tidx
                   = make_value_list (*p_args, *p_arg_nm, &tmp);
+
                 idx.push_back (tidx);
-                tmpidx.push_back (tidx);
+
+                if (i < n - 1)
+                  {
+                    if (type[i+1] == '.')
+                      {
+                        tmpidx.push_back (tidx);
+                        tmpi = i+1;
+                      }
+                    else
+                      error ("() must be followed by . or close the index chain");
+                  }
               }
               break;
 
@@ -493,60 +497,27 @@
 		octave_value_list tidx
 		  = make_value_list (*p_args, *p_arg_nm, &tmp);
 
-		if (! tidx.all_scalars ())
-		  {
-                    octave_idx_type nel = 1;
-
-                    octave_idx_type nidx = tidx.length ();
-
-                    // Possible cs-list.
-                    bool has_magic_colon = tidx.has_magic_colon ();
-                    dim_vector dims;
-
-		    if (has_magic_colon)
-		      {
-                        if (tmp.is_defined ())
-                          {
-                            if (tmpi < i)
-                              {
-                                tmp = tmp.subsref (type.substr (tmpi, i - tmpi), tmpidx, true);
-                                tmpi = i;
-                                tmpidx.clear ();
-                              }
+                if (tmp.is_undefined ())
+                  {
+                    if (tidx.has_magic_colon ())
+                      gripe_invalid_inquiry_subscript ();
+                    else
+                      tmp = Cell ();
+                  }
+                else if (tmp.is_zero_by_zero () 
+                         && (tmp.is_matrix_type () || tmp.is_string ()))
+                  {
+                    tmp = Cell ();
+                  }
 
-                            if (tmp.is_undefined ())
-                              gripe_invalid_inquiry_subscript ();
-                            else if (tmp.is_cs_list ())
-                              gripe_indexed_cs_list ();
-
-                            dims = (nidx == 1) ? dim_vector (tmp.numel (), 1) : tmp.dims ();
-                          }
-                        else
-                          gripe_invalid_inquiry_subscript ();
-
-                        if (error_state)
-                          break;
-                      }
-
-                    for (octave_idx_type j = 0; j < nidx; j++)
-                      {
-                        octave_value val = tidx(j);
-
-                        if (val.is_magic_colon ())
-                          nel *= dims (j);
-                        else
-                          nel *= val.numel ();
-                      }
-
-                    retval.numel (nel);
-		  }
+                retval.numel (get_numel (tmp, tidx));
 
                 if (error_state)
                   break;
 
 		idx.push_back (tidx);
                 tmpidx.push_back (tidx);
-
+                tmpi = i;
 	      }
 	      break;
 
@@ -556,90 +527,49 @@
                 if (error_state)
                   break;
 
+                bool autoconv = (tmp.is_zero_by_zero () 
+                                 && (tmp.is_matrix_type () || tmp.is_string ()
+                                     || tmp.is_cell ()));
+
                 if (i > 0 && type [i-1] == '(')
                   {
-                    // Possible cs-list.
-
-                    octave_value_list xidx = idx.back ();
-
-                    if (! xidx.all_scalars ())
-                      {
-                        octave_idx_type nel = 1;
-
-                        octave_idx_type nidx = xidx.length ();
-
-                        // Possible cs-list.
-                        bool has_magic_colon = xidx.has_magic_colon ();
-                        dim_vector dims;
+                    octave_value_list pidx = idx.back ();
 
-                        if (has_magic_colon)
-                          {
-                            // Evaluate everything up to the point preceding the last paren.
-                            if (tmp.is_defined ())
-                              {
-                                if (tmpi < i-1)
-                                  {
-                                    tmpidx.pop_back ();
-                                    tmp = tmp.subsref (type.substr (tmpi, i-1 - tmpi), tmpidx, true);
-                                    tmpi = i - 1;
-                                    tmpidx.clear ();
-                                    tmpidx.push_back (xidx);
-                                  }
-
-                                if (tmp.is_undefined ())
-                                  gripe_invalid_inquiry_subscript ();
-                                else if (tmp.is_cs_list ())
-                                  gripe_indexed_cs_list ();
+                    if (tmp.is_undefined ())
+                      {
+                        if (pidx.has_magic_colon ())
+                          gripe_invalid_inquiry_subscript ();
+                        else
+                          tmp = Octave_map ();
+                      }
+                    else if (autoconv)
+                      tmp = Octave_map ();
 
-                                dims = (nidx == 1) ? dim_vector (tmp.numel (), 1) : tmp.dims ();
-                              }
-                            else
-                              gripe_invalid_inquiry_subscript ();
-
-                            if (error_state)
-                              break;
-                          }
+                    retval.numel (get_numel (tmp, pidx));
 
-                        for (octave_idx_type j = 0; j < nidx; j++)
-                          {
-                            octave_value val = xidx(j);
-
-                            if (val.is_magic_colon ())
-                              nel *= dims (j);
-                            else
-                              nel *= val.numel ();
-                          }
-
-                        retval.numel (nel);
-                      }
+                    tmpi = i-1;
+                    tmpidx.push_back (tidx);
                   }
                 else
                   {
-                    // A plain struct component can also yield a list reference.
-                    if (tmp.is_defined () && tmpi < i)
-                        tmp = tmp.subsref (type.substr (tmpi, i - tmpi), tmpidx, true);
-
-                    tmpi = i;
-                    tmpidx.clear ();
+                    if (tmp.is_undefined () || autoconv)
+                      {
+                        tmpi = i+1;
+                        tmp = octave_value ();
+                      }
+                    else
+                      {
+                        retval.numel (get_numel (tmp, octave_value_list ()));
 
-                    if (tmp.is_cs_list ())
-                      gripe_indexed_cs_list ();
-                    else if (tmp.is_map ())
-                      retval.numel (tmp.numel ());
-                    else
-                      tmp = Octave_map ();
-
-                    if (error_state)
-                      break;
-
+                        tmpi = i;
+                        tmpidx.push_back (tidx);
+                      }
                   }
 
                 if (error_state)
                   break;
 
                 idx.push_back (tidx);
-                tmpidx.push_back (tidx);
-
 	      }
 	      break;
 
@@ -647,6 +577,9 @@
 	      panic_impossible ();
 	    }
 
+          if (idx.back ().empty ())
+            error ("invalid empty index list");
+
 	  if (error_state)
 	    break;