Mercurial > hg > octave-nkf
changeset 5846:db0598f94c0f
[project @ 2006-06-07 18:16:16 by jwe]
author | jwe |
---|---|
date | Wed, 07 Jun 2006 18:16:16 +0000 |
parents | 8b4a99ae3b5e |
children | 62e7b9307d00 |
files | src/ChangeLog src/oct-lvalue.h src/oct-obj.cc src/oct-obj.h src/ov-cell.cc src/pt-arg-list.cc src/pt-arg-list.h src/pt-assign.cc src/pt-idx.cc |
diffstat | 9 files changed, 194 insertions(+), 65 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,21 @@ +2006-06-07 John W. Eaton <jwe@octave.org> + + * ov-cell.cc (octave_cell::subsasgn): Handle c-s list object on + RHS if last index is '{'. + * pt-assign.cc (tree_multi_assignment::rvalue): Compute all LHS + lvalues before evaluating RHS. If LHS lvalue expects more than + one output, pass octave_cs_list object to assign method. + * pt-idx.cc (tree_index_expression::lvalue): Compute expected + number of values if '{' index appears last. + * pt-arg-list.cc (tree_argument_list::lvalue_list): New function. + * pt-arg-list.h (tree_argument_list::lvalue_list): Provide decl. + * oct-lvalue.h (octave_lvalue::nel): New data member. + (octave_lvalue::numel): New functions + * oct-obj.cc (octave_value_list::has_magic_colon): New function. + * oct-obj.h (octave_value_list::has_magic_colon): Provide decl. + * pt-arg-list.cc (tree_argument_list::nargout_count): Delete function. + * pt-arg-list.h (tree_argument_list::nargout_count): Delete decl. + 2006-06-06 John W. Eaton <jwe@octave.org> * sighandlers.cc (generic_sig_handler, sigint_handler):
--- a/src/oct-lvalue.h +++ b/src/oct-lvalue.h @@ -45,11 +45,11 @@ octave_lvalue (octave_value *v = &dummy_val, symbol_record::change_function f = 0) - : val (v), type (), idx (), chg_fcn (f), index_set (false) { } + : val (v), type (), idx (), chg_fcn (f), nel (1), index_set (false) { } octave_lvalue (const octave_lvalue& vr) : val (vr.val), type (vr.type), idx (vr.idx), chg_fcn (vr.chg_fcn), - index_set (vr.index_set) { } + nel (vr.nel), index_set (vr.index_set) { } octave_lvalue& operator = (const octave_lvalue& vr) { @@ -59,6 +59,7 @@ type = vr.type; idx = vr.idx; chg_fcn = vr.chg_fcn; + nel = vr.nel; index_set = vr.index_set; } @@ -77,6 +78,10 @@ void assign (octave_value::assign_op, const octave_value&); + void numel (octave_idx_type n) { nel = n; } + + octave_idx_type numel (void) const { return nel; } + void set_index (const std::string& t, const std::list<octave_value_list>& i); void clear_index (void) { type = std::string (); idx.clear (); } @@ -97,6 +102,8 @@ symbol_record::change_function chg_fcn; + octave_idx_type nel; + bool index_set; };
--- a/src/oct-obj.cc +++ b/src/oct-obj.cc @@ -168,9 +168,21 @@ for (octave_idx_type i = 0; i < n; i++) if (! elem(i).is_string ()) - return 0; + return false; + + return true; +} - return 1; +bool +octave_value_list::has_magic_colon (void) const +{ + octave_idx_type n = length (); + + for (octave_idx_type i = 0; i < n; i++) + if (elem(i).is_magic_colon ()) + return true; + + return false; } string_vector
--- a/src/oct-obj.h +++ b/src/oct-obj.h @@ -111,6 +111,8 @@ bool all_strings_p (void) const; + bool has_magic_colon (void) const; + string_vector make_argv (const std::string&) const; void stash_name_tags (const string_vector& nm) { names = nm; }
--- a/src/ov-cell.cc +++ b/src/ov-cell.cc @@ -222,7 +222,18 @@ { octave_value_list i = idx.front (); - octave_base_matrix<Cell>::assign (i, Cell (t_rhs)); + if (t_rhs.is_cs_list ()) + { + Cell tmp_cell = Cell (t_rhs.list_value ()); + + // FIXME -- shouldn't care if the dimensions of the + // RHS don't match the dimensions of the subscripted + // LHS. + + octave_base_matrix<Cell>::assign (i, tmp_cell); + } + else + octave_base_matrix<Cell>::assign (i, Cell (t_rhs)); count++; retval = octave_value (this);
--- a/src/pt-arg-list.cc +++ b/src/pt-arg-list.cc @@ -32,6 +32,7 @@ #include "defun.h" #include "error.h" +#include "oct-lvalue.h" #include "oct-obj.h" #include "ov.h" #include "ov-usr-fcn.h" @@ -77,25 +78,6 @@ list_includes_magic_end = true; } -int -tree_argument_list::nargout_count (void) const -{ - int retval = 0; - - for (const_iterator p = begin (); p != end (); p++) - { - tree_expression *elt = *p; - - // FIXME -- need to be able to determine whether elt is - // an expression that could evaluate to a cs-list object, and if - // so, how many elements are in that list. Ugly! - - retval++; - } - - return retval; -} - bool tree_argument_list::all_elements_are_constant (void) const { @@ -260,6 +242,23 @@ return args; } +std::list<octave_lvalue> +tree_argument_list::lvalue_list (void) +{ + std::list<octave_lvalue> retval; + + for (tree_argument_list::iterator p = begin (); + p != end (); + p++) + { + tree_expression *elt = *p; + + retval.push_back (elt->lvalue ()); + } + + return retval; +} + string_vector tree_argument_list::get_arg_names (void) const {
--- a/src/pt-arg-list.h +++ b/src/pt-arg-list.h @@ -24,10 +24,11 @@ #if !defined (octave_tree_arg_list_h) #define octave_tree_arg_list_h 1 -class octave_value_list; +#include <list> +class octave_value_list; +class octave_lvalue; class tree_expression; - class tree_walker; #include "str-vec.h" @@ -65,8 +66,6 @@ void append (const element_type& s); - int nargout_count (void) const; - void mark_as_simple_assign_lhs (void) { simple_assign_lhs = true; } bool is_simple_assign_lhs (void) { return simple_assign_lhs; } @@ -75,6 +74,8 @@ octave_value_list convert_to_const_vector (const octave_value *object = 0); + std::list<octave_lvalue> lvalue_list (void); + string_vector get_arg_names (void) const; void accept (tree_walker& tw);
--- a/src/pt-assign.cc +++ b/src/pt-assign.cc @@ -200,11 +200,18 @@ if (rhs) { - int n_out = lhs->nargout_count (); + std::list<octave_lvalue> lvalue_list = lhs->lvalue_list (); if (error_state) return retval; + int n_out = 0; + + for (std::list<octave_lvalue>::const_iterator p = lvalue_list.begin (); + p != lvalue_list.end (); + p++) + n_out += p->numel (); + octave_value_list rhs_val = rhs->rvalue (n_out); if (error_state) @@ -212,15 +219,18 @@ if (rhs_val.empty ()) { - error ("value on right hand side of assignment is undefined"); - eval_error (); - return retval; + if (n_out > 0) + { + error ("value on right hand side of assignment is undefined"); + eval_error (); + return retval; + } } else { - int k = 0; + octave_idx_type k = 0; - int n = rhs_val.length (); + octave_idx_type n = rhs_val.length (); if (n == 1) { @@ -236,22 +246,52 @@ retval.resize (n, octave_value ()); - for (tree_argument_list::iterator p = lhs->begin (); - p != lhs->end (); + tree_argument_list::iterator q = lhs->begin (); + + for (std::list<octave_lvalue>::iterator p = lvalue_list.begin (); + p != lvalue_list.end (); p++) { - tree_expression *lhs_elt = *p; + tree_expression *lhs_elt = *q++; + + octave_lvalue ult = *p; + + octave_idx_type nel = ult.numel (); - if (lhs_elt) + if (nel > 1) { - octave_lvalue ult = lhs_elt->lvalue (); + if (k + nel <= n) + { + if (etype == octave_value::op_asn_eq) + { + octave_value_list ovl (nel, octave_value ()); + + for (octave_idx_type j = 0; j < nel; j++) + ovl(j) = rhs_val(k+j); + + ult.assign (etype, octave_value (ovl, true)); - if (error_state) - { - eval_error (); - break; + if (! error_state) + { + for (octave_idx_type j = 0; j < nel; j++) + retval(k+j) = rhs_val(k+j); + + k += nel; + } + } + else + { + std::string op = octave_value::assign_op_as_string (etype); + error ("operator %s unsupported for comma-separated list assignment", + op.c_str ()); + } } - else if (k < n) + else + error ("some elements undefined in return list"); + } + else + { + if (k < n) { ult.assign (etype, rhs_val(k)); @@ -261,39 +301,38 @@ retval(k) = rhs_val(k); else retval(k) = ult.value (); + + k++; } } else error ("element number %d undefined in return list", k+1); + } - if (error_state) - { - eval_error (); - break; - } - else if (print_result ()) - { - // We clear any index here so that we can get - // the new value of the referenced object below, - // instead of the indexed value (which should be - // the same as the right hand side value). + if (error_state) + { + eval_error (); + break; + } + else if (print_result ()) + { + // We clear any index here so that we can get + // the new value of the referenced object below, + // instead of the indexed value (which should be + // the same as the right hand side value). - ult.clear_index (); + ult.clear_index (); - octave_value lhs_val = ult.value (); + octave_value lhs_val = ult.value (); - if (! error_state) - lhs_val.print_with_name (octave_stdout, - lhs_elt->name ()); - } + if (! error_state) + lhs_val.print_with_name (octave_stdout, + lhs_elt->name ()); } - else - eval_error (); if (error_state) break; - k++; } } }
--- a/src/pt-idx.cc +++ b/src/pt-idx.cc @@ -427,7 +427,47 @@ break; case '{': - idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp)); + { + octave_value_list tidx + = make_value_list (*p_args, *p_arg_nm, &tmp); + + idx.push_back (tidx); + + if (i == n-1) + { + // Last indexing element. Will this result in a + // comma-separated list? + + if (tidx.has_magic_colon ()) + { + octave_value_list tmp_list + = first_retval_object.subsref (type, idx, 1); + + if (! error_state) + { + octave_value val = tmp_list(0); + + if (val.is_cs_list ()) + retval.numel (val.numel ()); + } + } + else + { + octave_idx_type nel = 1; + + octave_idx_type nidx = tidx.length (); + + for (octave_idx_type j = 0; j < nidx; j++) + { + octave_value val = tidx(j); + + nel *= val.numel (); + } + + retval.numel (nel); + } + } + } break; case '.':