# HG changeset patch # User Jaroslav Hajek # Date 1249625509 -7200 # Node ID c663c1a78c4af0059e0e35b60b3a55c762f507c8 # Parent e868e6276b5ca2b5ddaf8dd50f60b56bc07ce78f implant tree_index_expression::lvalue from development version diff -r e868e6276b5c -r c663c1a78c4a src/ChangeLog --- a/src/ChangeLog Thu Aug 06 07:32:53 2009 +0200 +++ b/src/ChangeLog Fri Aug 07 08:11:49 2009 +0200 @@ -1,3 +1,9 @@ +2009-08-07 Jaroslav Hajek + + * pt-idx.cc (tree_index_expression::lvalue): Implant code from + development version. + (get_numel): New assistant function. + 2009-07-29 John W. Eaton * ov-float.cc, ov-flt-re-mat.cc, ov-re-mat.cc, ov-re-sparse.cc, diff -r e868e6276b5c -r c663c1a78c4a src/pt-idx.cc --- a/src/pt-idx.cc Thu Aug 06 07:32:53 2009 +0200 +++ b/src/pt-idx.cc Fri Aug 07 08:11:49 2009 +0200 @@ -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 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 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;