# HG changeset patch # User jwe # Date 863185866 0 # Node ID 56be458e237f38dca092d91e0d9bac8ae79ced41 # Parent cf676ff8b702d0d6e120f9415e2e2402cd5fd4b8 [project @ 1997-05-09 13:37:35 by jwe] diff -r cf676ff8b702 -r 56be458e237f src/ov-base.cc --- a/src/ov-base.cc Fri May 09 13:32:52 1997 +0000 +++ b/src/ov-base.cc Fri May 09 13:51:06 1997 +0000 @@ -44,6 +44,7 @@ #include "ov-str-mat.h" #include "ov-range.h" #include "ov-list.h" +#include "variables.h" int octave_base_value::t_id = -1; @@ -74,14 +75,13 @@ return octave_value (); } -octave_value& -octave_base_value::struct_elt_ref (const string&) +octave_variable_reference +octave_base_value::struct_elt_ref (octave_value *, const string&) { - static octave_value foo; string nm = type_name (); error ("can't perform structure reference operations for %s type", nm.c_str ()); - return foo; + return octave_variable_reference (); } octave_value diff -r cf676ff8b702 -r 56be458e237f src/ov-base.h --- a/src/ov-base.h Fri May 09 13:32:52 1997 +0000 +++ b/src/ov-base.h Fri May 09 13:51:06 1997 +0000 @@ -76,7 +76,8 @@ octave_value struct_elt_val (const string& nm, bool silent) const; - octave_value& struct_elt_ref (const string& nm); + octave_variable_reference + struct_elt_ref (octave_value *parent, const string& nm); int rows (void) const { return -1; } diff -r cf676ff8b702 -r 56be458e237f src/ov-re-mat.cc --- a/src/ov-re-mat.cc Fri May 09 13:32:52 1997 +0000 +++ b/src/ov-re-mat.cc Fri May 09 13:51:06 1997 +0000 @@ -40,6 +40,7 @@ #include "ov-scalar.h" #include "ov-re-mat.h" #include "pr-output.h" +#include "variables.h" octave_allocator octave_matrix::allocator (sizeof (octave_matrix)); @@ -146,6 +147,105 @@ } } +void +octave_matrix::assign_struct_elt (assign_op, const string& nm, + const octave_value& rhs) +{ + octave_value retval; + + Matrix m = rhs.matrix_value (); + + if (! error_state) + { + int nr = -1; + int nc = -1; + + int dim = -1; + + if (m.rows () == 1 && m.cols () == 2) + { + nr = NINT (m (0, 0)); + nc = NINT (m (0, 1)); + } + else if (m.rows () == 2 && m.cols () == 1) + { + nr = NINT (m (0, 0)); + nc = NINT (m (1, 0)); + } + else if (m.rows () == 1 && m.cols () == 1) + { + dim = NINT (m (0, 0)); + + nr = matrix.rows (); + nc = matrix.cols (); + } + + if (nm == "size") + { + if (nr >= 0 && nc >= 0) + matrix.resize (nr, nc, 0.0); + else + error ("invalid size specification = [%d, %d] specified", + nr, nc); + } + else if (nm == "rows") + { + if (dim >= 0) + matrix.resize (dim, nc, 0.0); + else + error ("invalid row dimension = %d specified", dim); + } + else if (nm == "cols" || nm == "columns") + { + if (dim >= 0) + matrix.resize (nr, dim, 0.0); + else + error ("invalid column dimension = %d specified", dim); + } + } +} + +void +octave_matrix::assign_struct_elt (assign_op, const string&, + const octave_value_list&, + const octave_value&) +{ + error ("indexed assignment for matrix properties is not implemented"); +} + +octave_value +octave_matrix::struct_elt_val (const string& nm, bool silent) const +{ + octave_value retval; + + double nr = static_cast (matrix.rows ()); + double nc = static_cast (matrix.cols ()); + + if (nm == "rows") + retval = nr; + else if (nm == "cols" || nm == "columns") + retval = nc; + else if (nm == "size") + { + Matrix tmp (1, 2); + + tmp.elem (0, 0) = nr; + tmp.elem (0, 1) = nc; + + retval = tmp; + } + else if (! silent) + error ("structure has no member `%s'", nm.c_str ()); + + return retval; +} + +octave_variable_reference +octave_matrix::struct_elt_ref (octave_value *parent, const string& nm) +{ + return octave_variable_reference (parent, nm); +} + bool octave_matrix::valid_as_scalar_index (void) const { diff -r cf676ff8b702 -r 56be458e237f src/ov-re-mat.h --- a/src/ov-re-mat.h Fri May 09 13:32:52 1997 +0000 +++ b/src/ov-re-mat.h Fri May 09 13:51:06 1997 +0000 @@ -85,8 +85,20 @@ void assign (const octave_value_list& idx, const Matrix& rhs); + void assign_struct_elt (assign_op, const string& elt_nm, + const octave_value& rhs); + + void assign_struct_elt (assign_op, const string& elt_nm, + const octave_value_list& idx, + const octave_value& rhs); + idx_vector index_vector (void) const { return idx_vector (matrix); } + octave_value struct_elt_val (const string& nm, bool silent) const; + + octave_variable_reference + struct_elt_ref (octave_value *parent, const string& nm); + int rows (void) const { return matrix.rows (); } int columns (void) const { return matrix.columns (); } diff -r cf676ff8b702 -r 56be458e237f src/ov-struct.cc --- a/src/ov-struct.cc Fri May 09 13:32:52 1997 +0000 +++ b/src/ov-struct.cc Fri May 09 13:51:06 1997 +0000 @@ -33,6 +33,7 @@ #include "error.h" #include "ov-struct.h" #include "unwind-prot.h" +#include "variables.h" octave_allocator octave_struct::allocator (sizeof (octave_struct)); @@ -58,10 +59,10 @@ return retval; } -octave_value& -octave_struct::struct_elt_ref (const string& nm) +octave_variable_reference +octave_struct::struct_elt_ref (octave_value *, const string& nm) { - return map [nm]; + return octave_variable_reference (&map [nm]); } void diff -r cf676ff8b702 -r 56be458e237f src/ov-struct.h --- a/src/ov-struct.h Fri May 09 13:32:52 1997 +0000 +++ b/src/ov-struct.h Fri May 09 13:51:06 1997 +0000 @@ -75,7 +75,8 @@ octave_value struct_elt_val (const string& nm, bool silent) const; - octave_value& struct_elt_ref (const string& nm); + octave_variable_reference + struct_elt_ref (octave_value *parent, const string& nm); bool is_defined (void) const { return true; } diff -r cf676ff8b702 -r 56be458e237f src/ov.cc --- a/src/ov.cc Fri May 09 13:32:52 1997 +0000 +++ b/src/ov.cc Fri May 09 13:51:06 1997 +0000 @@ -102,16 +102,16 @@ // error. int Vpropagate_empty_matrices; -// If TRUE, resize matrices when performing and indexed assignment and -// the indices are outside the current bounds. -bool Vresize_on_range_error; - // How many levels of structure elements should we print? int Vstruct_levels_to_print; // Allow divide by zero errors to be suppressed. bool Vwarn_divide_by_zero; +// If TRUE, resize matrices when performing and indexed assignment and +// the indices are outside the current bounds. +static bool Vresize_on_range_error; + // XXX FIXME XXX // Octave's value type. @@ -498,22 +498,64 @@ const octave_value_list& idx, const octave_value& rhs) { + if (Vresize_on_range_error || is_defined ()) + { + make_unique (); + + bool assignment_ok = try_assignment (op, idx, rhs); + + if (! (error_state || assignment_ok)) + { + assignment_ok = try_assignment_with_conversion (op,idx, rhs); + + if (! (error_state || assignment_ok)) + gripe_no_conversion (type_name (), rhs.type_name ()); + } + + if (! error_state) + maybe_mutate (); + } + else + { + error ("indexed assignment to previously undefined variables"); + error ("is only possible when resize_on_range_error is true"); + } + + return *this; +} + +void +octave_value::assign_struct_elt (assign_op op, const string& elt_nm, + const octave_value& rhs) +{ make_unique (); - bool assignment_ok = try_assignment (op, idx, rhs); + rep->assign_struct_elt (op, elt_nm, rhs); +} + - if (! (error_state || assignment_ok)) - { - assignment_ok = try_assignment_with_conversion (op,idx, rhs); +void +octave_value::assign_struct_elt (assign_op op, const string& elt_nm, + const octave_value_list& idx, + const octave_value& rhs) +{ + make_unique (); - if (! (error_state || assignment_ok)) - gripe_no_conversion (type_name (), rhs.type_name ()); - } + rep->assign_struct_elt (op, elt_nm, idx, rhs); +} - if (! error_state) - maybe_mutate (); +octave_variable_reference +octave_value::struct_elt_ref (const string& nm) +{ + return rep->struct_elt_ref (this, nm); +} - return *this; +octave_variable_reference +octave_value::struct_elt_ref (octave_value *, const string&) +{ + panic_impossible (); + + return octave_variable_reference (); } octave_value_list diff -r cf676ff8b702 -r 56be458e237f src/ov.h --- a/src/ov.h Fri May 09 13:32:52 1997 +0000 +++ b/src/ov.h Fri May 09 13:51:06 1997 +0000 @@ -44,6 +44,7 @@ class Octave_map; class octave_stream; class octave_value_list; +class octave_variable_reference; // Constants. @@ -220,6 +221,14 @@ octave_value& assign (assign_op, const octave_value_list& idx, const octave_value& rhs); + virtual void + assign_struct_elt (assign_op, const string& elt_nm, + const octave_value& rhs); + + virtual void + assign_struct_elt (assign_op, const string& elt_nm, + const octave_value_list& idx, const octave_value& rhs); + virtual idx_vector index_vector (void) const { return rep->index_vector (); } @@ -227,8 +236,10 @@ struct_elt_val (const string& nm, bool silent = false) const { return rep->struct_elt_val (nm, silent); } - virtual octave_value& struct_elt_ref (const string& nm) - { return rep->struct_elt_ref (nm); } + octave_variable_reference struct_elt_ref (const string& nm); + + virtual octave_variable_reference + struct_elt_ref (octave_value *parent, const string& nm); // Size. @@ -524,10 +535,6 @@ // error. extern int Vpropagate_empty_matrices; -// If TRUE, resize matrices when performing and indexed assignment and -// the indices are outside the current bounds. -extern bool Vresize_on_range_error; - // How many levels of structure elements should we print? extern int Vstruct_levels_to_print; diff -r cf676ff8b702 -r 56be458e237f src/pt-cmd.cc --- a/src/pt-cmd.cc Fri May 09 13:32:52 1997 +0000 +++ b/src/pt-cmd.cc Fri May 09 13:51:06 1997 +0000 @@ -307,29 +307,25 @@ { quit = false; - octave_variable_reference tmp (ident); + ident->reference () . assign (octave_value::asn_eq, rhs); - if (error_state) + if (! error_state) { - eval_error (); - return; - } - - tmp.assign (octave_value::asn_eq, rhs); - - if (list) - { - list->eval (); + if (list) + list->eval (); if (error_state) { eval_error (); quit = true; - return; } + else + quit = quit_loop_now (); } + else + eval_error (); - quit = quit_loop_now (); + return; } #define DO_LOOP(val) \ diff -r cf676ff8b702 -r 56be458e237f src/pt-const.h --- a/src/pt-const.h Fri May 09 13:32:52 1997 +0000 +++ b/src/pt-const.h Fri May 09 13:51:06 1997 +0000 @@ -78,23 +78,6 @@ octave_value index (const octave_value_list& idx) const { return val.index (idx); } - octave_value& reference (void) - { - val.make_unique (); - return val; - } - - octave_value value (void) const - { return val; } - - octave_value assign (octave_value::assign_op op, - const octave_value_list& idx, - const octave_value& rhs) - { - val.assign (op, idx, rhs); - return val; - } - // Type. It would be nice to eliminate the need for this. bool is_constant (void) const { return true; } diff -r cf676ff8b702 -r 56be458e237f src/pt-exp.cc --- a/src/pt-exp.cc Fri May 09 13:32:52 1997 +0000 +++ b/src/pt-exp.cc Fri May 09 13:51:06 1997 +0000 @@ -513,8 +513,8 @@ return lhs->ident (); } -// ??? FIXME ??? -- should octave_variable_reference::assign return -// the right thing for us to return? +// ??? FIXME ??? -- should octave_value::assign return the right thing +// for us to return? octave_value tree_simple_assignment_expression::eval (bool print) @@ -541,7 +541,7 @@ } else { - octave_variable_reference ult (lhs); + octave_variable_reference ult = lhs->reference (); if (error_state) eval_error (); diff -r cf676ff8b702 -r 56be458e237f src/pt-id.cc --- a/src/pt-id.cc Fri May 09 13:32:52 1997 +0000 +++ b/src/pt-id.cc Fri May 09 13:51:06 1997 +0000 @@ -78,83 +78,6 @@ sym->document (s); } -octave_value -tree_identifier::assign (octave_value::assign_op op, const octave_value& rhs) -{ - octave_value retval; - - if (rhs.is_defined ()) - { - if (! sym->is_defined ()) - { - if (! (sym->is_formal_parameter () - || sym->is_linked_to_global ())) - { - link_to_builtin_variable (sym); - } - } - else if (sym->is_function ()) - { - sym->clear (); - } - - // XXX FIXME XXX -- make this work for ops other than `='. - - if (sym->define (rhs)) - retval = rhs; - } - - return retval; -} - -octave_value -tree_identifier::assign (octave_value::assign_op op, - const octave_value_list& args, - const octave_value& rhs) -{ - octave_value retval; - - if (rhs.is_defined ()) - { - if (! sym->is_defined ()) - { - if (! (sym->is_formal_parameter () - || sym->is_linked_to_global ())) - { - link_to_builtin_variable (sym); - } - } - else if (sym->is_function ()) - { - sym->clear (); - } - - if (sym->is_variable () && sym->is_defined ()) - { - sym->variable_reference () . assign (op, args, rhs); - } - else - { - assert (! sym->is_defined ()); - - if (! Vresize_on_range_error) - { - ::error ("indexed assignment to previously undefined variables"); - ::error ("is only possible when resize_on_range_error is true"); - } - else - { - retval.assign (op, args, rhs); - - if (retval.is_defined ()) - sym->define (retval); - } - } - } - - return retval; -} - bool tree_identifier::is_defined (void) { @@ -350,7 +273,7 @@ return sym->variable_value (); } -octave_value& +octave_variable_reference tree_identifier::reference (void) { return sym->variable_reference (); diff -r cf676ff8b702 -r 56be458e237f src/pt-id.h --- a/src/pt-id.h Fri May 09 13:32:52 1997 +0000 +++ b/src/pt-id.h Fri May 09 13:51:06 1997 +0000 @@ -71,13 +71,6 @@ void document (const string& s); - octave_value assign (octave_value::assign_op op, - const octave_value& t); - - octave_value assign (octave_value::assign_op op, - const octave_value_list& args, - const octave_value& t); - bool is_defined (void); void increment (void); @@ -107,7 +100,7 @@ octave_value value (void) const; - octave_value& reference (void); + octave_variable_reference reference (void); private: diff -r cf676ff8b702 -r 56be458e237f src/pt-indir.cc --- a/src/pt-indir.cc Fri May 09 13:32:52 1997 +0000 +++ b/src/pt-indir.cc Fri May 09 13:51:06 1997 +0000 @@ -164,33 +164,26 @@ return retval; } -octave_value& +octave_variable_reference tree_indirect_ref::reference (void) { if (is_identifier_only ()) return id->reference (); else { + octave_variable_reference tmp; + if (id) - { - octave_value& tmp = id->reference (); - if (tmp.is_undefined () || ! tmp.is_map ()) - tmp = Octave_map (); - return tmp.struct_elt_ref (nm); - } + tmp = id->reference (); else if (indir) - { - octave_value& tmp = indir->reference (); - if (tmp.is_undefined () || ! tmp.is_map ()) - tmp = Octave_map (); - return tmp.struct_elt_ref (nm); - } + tmp = indir->reference (); else - { - static octave_value foo; - panic_impossible (); - return foo; - } + panic_impossible (); + + if (tmp.is_undefined ()) + tmp.define (Octave_map ()); + + return tmp.struct_elt_ref (nm); } } diff -r cf676ff8b702 -r 56be458e237f src/pt-indir.h --- a/src/pt-indir.h Fri May 09 13:32:52 1997 +0000 +++ b/src/pt-indir.h Fri May 09 13:51:06 1997 +0000 @@ -91,7 +91,8 @@ eval (bool print, int nargout, const octave_value_list& args); octave_value value (void) const; - octave_value& reference (void); + + octave_variable_reference reference (void); string elt_name (void) { return nm; } diff -r cf676ff8b702 -r 56be458e237f src/pt-misc.cc --- a/src/pt-misc.cc Fri May 09 13:32:52 1997 +0000 +++ b/src/pt-misc.cc Fri May 09 13:51:06 1997 +0000 @@ -365,11 +365,9 @@ for (Pix p = first (); p != 0; next (p)) { tree_identifier *elt = this->operator () (p); + if (! elt->is_defined ()) - { - octave_variable_reference tmp (elt); - tmp.assign (octave_value::asn_eq, val); - } + elt->reference () . assign (octave_value::asn_eq, val); } } diff -r cf676ff8b702 -r 56be458e237f src/symtab.h --- a/src/symtab.h Fri May 09 13:32:52 1997 +0000 +++ b/src/symtab.h Fri May 09 13:51:06 1997 +0000 @@ -180,7 +180,7 @@ bool is_static (void) const; octave_value variable_value (void) const; - octave_value& variable_reference (void); + octave_variable_reference variable_reference (void); symbol_record *next (void) const;