diff src/pt-idx.cc @ 8546:3d8a914c580e

improve parser indexed assigment code
author Jaroslav Hajek <highegg@gmail.com>
date Tue, 20 Jan 2009 21:15:17 +0100
parents 3100283874d7
children 906f976d35a8
line wrap: on
line diff
--- a/src/pt-idx.cc	Tue Jan 20 11:09:22 2009 -0500
+++ b/src/pt-idx.cc	Tue Jan 20 21:15:17 2009 +0100
@@ -391,6 +391,12 @@
   return retval;
 }
 
+static void
+gripe_invalid_inquiry_subscript (void)
+{
+  error ("invalid dimension inquiry of a non-existent value");
+}
+
 octave_lvalue
 tree_index_expression::lvalue (void)
 {
@@ -410,8 +416,6 @@
     {
       bool have_new_struct_field = false;
 
-      octave_idx_type new_struct_field_nel = 0;
-
       // I think it is OK to have a copy here.
 
       const octave_value *tro = retval.object ();
@@ -441,10 +445,15 @@
 		  // that argument list so we pass the appropriate
 		  // value to the built-in __end__ function.
 
-		  octave_value_list tmp_list
-		    = first_retval_object.subsref (type.substr (0, i), idx, 1);
+                  if (first_retval_object.is_defined ())
+                    {
+                      octave_value_list tmp_list
+                        = first_retval_object.subsref (type.substr (0, i), idx, 1);
 
-		  tmp = tmp_list(0);
+                      tmp = tmp_list(0);
+                    }
+                  else
+                    gripe_invalid_inquiry_subscript ();
 
 		  if (error_state)
 		    break;
@@ -464,23 +473,27 @@
 
 		idx.push_back (tidx);
 
-		if (i == n-1)
+		if (! tidx.all_scalars () && retval.numel () == 1)
 		  {
-		    // Last indexing element.  Will this result in a
-		    // comma-separated list?
+                    // Possible cs-list.
 
 		    if (tidx.has_magic_colon ())
 		      {
-			octave_value_list tmp_list
-			  = first_retval_object.subsref (type, idx, 1);
+                        if (first_retval_object.is_defined ())
+                          {
+                            octave_value_list tmp_list
+                              = first_retval_object.subsref (type, idx, 1);
 
-			if (! error_state)
-			  {
-			    octave_value val = tmp_list(0);
+                            if (! error_state)
+                              {
+                                octave_value val = tmp_list(0);
 
-			    if (val.is_cs_list ())
-			      retval.numel (val.numel ());
-			  }
+                                if (val.is_cs_list ())
+                                  retval.numel (val.numel ());
+                              }
+                          }
+                        else
+                          gripe_invalid_inquiry_subscript ();
 		      }
 		    else
 		      {
@@ -504,110 +517,109 @@
 	    case '.':
 	      {
 		octave_value tidx = get_struct_index (p_arg_nm, p_dyn_field);
+                if (error_state)
+                  break;
 
-		if (! error_state)
-		  {
-		    if (i == n-1)
-		      {
-			// Last indexing element.  Will this result in a
-			// comma-separated list?
+                if (i > 0 && type [i-1] == '(' && retval.numel () == 1 
+                    && ! idx.back ().all_scalars ())
+                  {
+                    // Possible cs-list.
+
+                    std::string ttype = type.substr (0, i);
 
-			if (have_new_struct_field)
-			  retval.numel (new_struct_field_nel);
-			else if (i > 0)
-			  {
-			    std::string ttype = type.substr (0, i);
+                    octave_value_list xidx = idx.back ();
 
-			    char c = ttype[ttype.length()-1];
-			    if (c == '(' || c == '{')
-			      {
-				octave_idx_type nel = 1;
+                    if (xidx.has_magic_colon ())
+                      {
+                        if (first_retval_object.is_defined () && ! have_new_struct_field)
+                          {
+                            octave_value_list tmp_list
+                              = first_retval_object.subsref (ttype, idx, 1);
 
-				octave_value_list xidx = idx.back ();
+                            if (! error_state)
+                              {
+                                octave_value val = tmp_list(0);
 
-				octave_idx_type nidx = xidx.length ();
+                                if (val.is_map ())
+                                  retval.numel (val.numel ());
+                              }
+                          }
+                        else
+                          gripe_invalid_inquiry_subscript ();
+                      }
+                    else
+                      {
+                        octave_idx_type nel = 1;
 
-				for (octave_idx_type j = 0; j < nidx; j++)
-				  {
-				    octave_value val = xidx(j);
-
-				    nel *= val.numel ();
-				  }
+                        octave_idx_type nidx = xidx.length ();
 
-				retval.numel (nel);
-			      }
-			    else if (first_retval_object.is_defined ()
-				     && ! (first_retval_object.is_real_matrix ()
-					   && first_retval_object.is_zero_by_zero ()))
-			      {
-				octave_value_list tmp_list
-				  = first_retval_object.subsref (ttype, idx, 1);
+                        for (octave_idx_type j = 0; j < nidx; j++)
+                          {
+                            octave_value val = xidx(j);
+
+                            nel *= val.numel ();
+                          }
 
-				if (! error_state)
-				  {
-				    octave_value val = tmp_list(0);
+                        retval.numel (nel);
+                      }
+                  }
+                else if (retval.numel () == 1 && first_retval_object.is_defined ())
+                  {
+                    octave_value tobj = first_retval_object;
+
+                    std::string ttype = type.substr (0, i);
 
-				    retval.numel (val.numel ());
-				  }
-			      }
-			    else
-			      retval.numel (1);
-			  }
-			else
-			  {
-			    if (first_retval_object.is_defined ()
-				&& ! (first_retval_object.is_real_matrix ()
-				      && first_retval_object.is_zero_by_zero ()))
-			      retval.numel (first_retval_object.numel ());
-			    else
-			      retval.numel (1);
-			  }
-		      }
-		    else
-		      {
-			octave_value tobj = first_retval_object;
+                    if (i > 0)
+                      {
+                        // Here we need to ensure that keys do exist.
+                        
+                        octave_value_list tmp_list
+                          = first_retval_object.subsref (ttype, idx, 1);
 
-			if (! have_new_struct_field)
-			  {
-			    if (i > 0 && first_retval_object.is_defined ()
-				&& ! (first_retval_object.is_real_matrix ()
-				      && first_retval_object.is_zero_by_zero ()))
-			      {
-				std::string ttype = type.substr (0, i);
+                        if (tmp_list.length () > 0) tobj = tmp_list (0);
+                      }
 
-				char c = ttype[ttype.length()-1];
+
+                    std::string key = tidx.string_value ();
 
-				if (! (c == '(' || c == '{'))
-				  {
-				    octave_value_list tmp_list
-				      = first_retval_object.subsref (ttype, idx, 1);
-
-				    if (! error_state)
-				      tobj = tmp_list(0);
-				  }
-			      }
-
-			    if (! error_state && tobj.is_map ())
-			      {
-				if (tidx.is_string ())
-				  {
-				    Octave_map m = tobj.map_value ();
+                    if (! error_state)
+                      {
+                        if (tobj.is_map ())
+                          {
+                            Octave_map map = tobj.map_value ();
+                            if (map.contains (key))
+                              retval.numel (map.contents (key).numel ());
+                            else
+                              {
+                                map.contents (key) = octave_value ();
+                                if (i > 0)
+                                  first_retval_object = 
+                                    first_retval_object.subsasgn (ttype, idx, map);
+                                else
+                                  first_retval_object = map;
 
-				    std::string s = tidx.string_value ();
-
-				    if (! m.contains (s))
-				      {
-					have_new_struct_field = true;
+                                have_new_struct_field = true;
+                              }
+                          }
+                        else 
+                          {
+                            Octave_map map (key, octave_value ());
+                            if (i > 0)
+                              first_retval_object = 
+                                first_retval_object.subsasgn (ttype, idx, map);
+                            else
+                              first_retval_object = map;
 
-					new_struct_field_nel = m.numel ();
-				      }
-				  }
-			      }
-			  }
-		      }
+                            have_new_struct_field = true;
+                          }
+                      }
+                  }
 
-		    idx.push_back (octave_value (tidx));
-		  }
+                if (! error_state)
+                  idx.push_back (tidx);
+                else
+                  break;
+
 	      }
 	      break;
 
@@ -625,6 +637,7 @@
 
       if (! error_state)
 	retval.set_index (type, idx);
+
     }
 
   return retval;