Mercurial > octave
diff src/ov.cc @ 3933:f9ea3dcf58ee
[project @ 2002-05-15 03:21:00 by jwe]
author | jwe |
---|---|
date | Wed, 15 May 2002 03:21:01 +0000 |
parents | e8627dc4bdf2 |
children | 635209a37bf4 |
line wrap: on
line diff
--- a/src/ov.cc Tue May 07 18:10:44 2002 +0000 +++ b/src/ov.cc Wed May 15 03:21:01 2002 +0000 @@ -32,7 +32,6 @@ #include "str-vec.h" #include "oct-obj.h" -#include "oct-lvalue.h" #include "ov.h" #include "ov-base.h" #include "ov-bool.h" @@ -508,10 +507,10 @@ rep->count = 1; } -octave_value::octave_value (octave_value *new_rep) +octave_value::octave_value (octave_value *new_rep, int count) : rep (new_rep) { - rep->count = 1; + rep->count = count; } octave_value::~octave_value (void) @@ -529,7 +528,7 @@ } octave_value * -octave_value::clone (void) +octave_value::clone (void) const { panic_impossible (); return 0; @@ -551,34 +550,121 @@ } octave_value_list +octave_value::subsref (const std::string type, + const SLList<octave_value_list>& idx, int nargout) +{ + if (is_constant ()) + return rep->subsref (type, idx); + else + return rep->subsref (type, idx, nargout); +} + +octave_value +octave_value::next_subsref (const std::string type, + const SLList<octave_value_list>& idx, + int skip) +{ + assert (skip > 0); + + if (idx.length () > skip) + { + SLList<octave_value_list> new_idx (idx); + for (int i = 0; i < skip; i++) + new_idx.remove_front (); + return subsref (type.substr (skip), new_idx); + } + else + return *this; +} + +octave_value_list octave_value::do_multi_index_op (int nargout, const octave_value_list& idx) { return rep->do_multi_index_op (nargout, idx); } static void -gripe_no_conversion (const std::string& on, const std::string& tn1, const std::string& tn2) +gripe_no_conversion (const std::string& on, const std::string& tn1, + const std::string& tn2) { error ("operator %s: no conversion for assignment of `%s' to indexed `%s'", on.c_str (), tn2.c_str (), tn1.c_str ()); } +#if 0 static void -gripe_assign_failed (const std::string& on, const std::string& tn1, const std::string& tn2) +gripe_assign_failed (const std::string& on, const std::string& tn1, + const std::string& tn2) { error ("assignment failed for `%s %s %s'", tn1.c_str (), on.c_str (), tn2.c_str ()); } +#endif static void -gripe_assign_failed_or_no_method (const std::string& on, const std::string& tn1, +gripe_assign_failed_or_no_method (const std::string& on, + const std::string& tn1, const std::string& tn2) { error ("assignment failed, or no method for `%s %s %s'", tn1.c_str (), on.c_str (), tn2.c_str ()); } -void +octave_value +octave_value::subsasgn (const std::string type, + const SLList<octave_value_list>& idx, + const octave_value& rhs) +{ + return rep->subsasgn (type, idx, rhs); +} + +octave_value +octave_value::assign (assign_op op, const std::string type, + const SLList<octave_value_list>& idx, + const octave_value& rhs) +{ + octave_value retval; + + make_unique (); + + octave_value t_rhs = rhs; + + if (op != op_asn_eq) + { + // XXX FIXME XXX -- only do the following stuff if we can't find + // a specific function to call to handle the op= operation for + // the types we have. + + octave_value t = subsref (type, idx); + + if (! error_state) + { + binary_op binop = op_eq_to_binary_op (op); + + if (! error_state) + t_rhs = do_binary_op (binop, t, rhs); + } + } + + if (! error_state) + { + if (type[0] == '.' && ! is_map ()) + { + octave_value tmp = Octave_map (); + retval = tmp.subsasgn (type, idx, t_rhs); + } + else + retval = subsasgn (type, idx, t_rhs); + } + + if (error_state) + gripe_assign_failed_or_no_method (assign_op_as_string (op), + type_name (), rhs.type_name ()); + + return retval; +} + +const octave_value& octave_value::assign (assign_op op, const octave_value& rhs) { if (op == op_asn_eq) @@ -603,119 +689,8 @@ gripe_assign_failed_or_no_method (assign_op_as_string (op), type_name (), rhs.type_name ()); } -} -void -octave_value::simple_assign (octave_value::assign_op orig_op, - const octave_value_list& idx, - const octave_value& rhs) -{ - make_unique (); - - bool assignment_ok = try_assignment (op_asn_eq, idx, rhs); - - if (! (error_state || assignment_ok)) - { - assignment_ok = try_assignment_with_conversion (op_asn_eq, idx, rhs); - - if (! (error_state || assignment_ok)) - gripe_no_conversion (assign_op_as_string (orig_op), - type_name (), rhs.type_name ()); - } -} - -void -octave_value::assign (octave_value::assign_op op, - const octave_value_list& idx, - const octave_value& rhs) -{ - if (Vresize_on_range_error || is_defined ()) - { - if (op == op_asn_eq) - simple_assign (op, idx, rhs); - else - { - // XXX FIXME XXX -- only do the following stuff if we can't - // find a specific function to call to handle the op= - // operation for the types we have. - - octave_value t1 = *this; - - t1 = t1.do_index_op (idx); - - if (! error_state) - { - binary_op binop = op_eq_to_binary_op (op); - - if (! error_state) - { - octave_value t2 = do_binary_op (binop, t1, rhs); - - if (! error_state) - { - simple_assign (op, idx, t2); - - if (error_state) - gripe_assign_failed (assign_op_as_string (op), - type_name (), rhs.type_name ()); - } - else - gripe_assign_failed_or_no_method (assign_op_as_string (op), - type_name (), - rhs.type_name ()); - } - else - gripe_assign_failed_or_no_method (assign_op_as_string (op), - type_name (), - rhs.type_name ()); - } - else - gripe_assign_failed (assign_op_as_string (op), - 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"); - } -} - -void -octave_value::assign_struct_elt (assign_op op, const std::string& elt_nm, - const octave_value& rhs) -{ - make_unique (); - - rep->assign_struct_elt (op, elt_nm, rhs); -} - - -void -octave_value::assign_struct_elt (assign_op op, const std::string& elt_nm, - const octave_value_list& idx, - const octave_value& rhs) -{ - make_unique (); - - rep->assign_struct_elt (op, elt_nm, idx, rhs); -} - -octave_lvalue -octave_value::struct_elt_ref (const std::string& nm) -{ - return rep->struct_elt_ref (this, nm); -} - -octave_lvalue -octave_value::struct_elt_ref (octave_value *, const std::string&) -{ - panic_impossible (); - - return octave_lvalue (); + return *this; } Cell @@ -980,164 +955,113 @@ } static void -gripe_assign_conversion_failed (const std::string& tn1, const std::string& tn2) +gripe_assign_conversion_failed (const std::string& tn1, + const std::string& tn2) { error ("type conversion for assignment of `%s' to indexed `%s' failed", tn2.c_str (), tn1.c_str ()); } -bool -octave_value::convert_and_assign (octave_value::assign_op op, - const octave_value_list& idx, - const octave_value& rhs) -{ - bool assignment_ok = false; - - int t_lhs = type_id (); - int t_rhs = rhs.type_id (); - - int t_result - = octave_value_typeinfo::lookup_pref_assign_conv (t_lhs, t_rhs); - - if (t_result >= 0) - { - type_conv_fcn cf - = octave_value_typeinfo::lookup_widening_op (t_lhs, t_result); - - if (cf) - { - octave_value *tmp = cf (*rep); - - if (tmp) - { - octave_value *old_rep = rep; - rep = tmp; - rep->count = 1; - - assignment_ok = try_assignment (op, idx, rhs); - - if (! assignment_ok && old_rep) - { - if (--rep->count == 0) - delete rep; - - rep = old_rep; - old_rep = 0; - } - - if (old_rep && --old_rep->count == 0) - delete old_rep; - } - else - gripe_assign_conversion_failed (type_name (), rhs.type_name ()); - } - else - gripe_indexed_assignment (type_name (), rhs.type_name ()); - } - - return (assignment_ok && ! error_state); -} - -bool -octave_value::try_assignment_with_conversion (octave_value::assign_op op, - const octave_value_list& idx, - const octave_value& rhs) -{ - bool assignment_ok = convert_and_assign (op, idx, rhs); - - if (! (error_state || assignment_ok)) - { - octave_value tmp_rhs; - type_conv_fcn cf_rhs = rhs.numeric_conversion_function (); - - if (cf_rhs) - { - octave_value *tmp = cf_rhs (*rhs.rep); - - if (tmp) - tmp_rhs = octave_value (tmp); - else - { - gripe_assign_conversion_failed (type_name (), rhs.type_name ()); - return false; - } - } - else - tmp_rhs = rhs; - - octave_value *old_rep = 0; - type_conv_fcn cf_this = numeric_conversion_function (); - - if (cf_this) - { - old_rep = rep; - - octave_value *tmp = cf_this (*rep); - - if (tmp) - { - rep = tmp; - rep->count = 1; - } - else - { - gripe_assign_conversion_failed (type_name (), rhs.type_name ()); - return false; - } - } - - if (cf_this || cf_rhs) - { - assignment_ok = try_assignment (op, idx, tmp_rhs); - - if (! (error_state || assignment_ok)) - assignment_ok = convert_and_assign (op, idx, tmp_rhs); - } - - if (! assignment_ok && old_rep) - { - if (--rep->count == 0) - delete rep; - - rep = old_rep; - old_rep = 0; - } - - if (old_rep && --old_rep->count == 0) - delete old_rep; - } - - return (assignment_ok && ! error_state); -} - -bool -octave_value::try_assignment (octave_value::assign_op op, - const octave_value_list& idx, +octave_value +octave_value::numeric_assign (const std::string type, + const SLList<octave_value_list>& idx, const octave_value& rhs) { - bool retval = false; + octave_value retval; int t_lhs = type_id (); int t_rhs = rhs.type_id (); assign_op_fcn f - = octave_value_typeinfo::lookup_assign_op (op, t_lhs, t_rhs); + = octave_value_typeinfo::lookup_assign_op (op_asn_eq, t_lhs, t_rhs); + + bool done = false; if (f) { - f (*rep, idx, *(rhs.rep)); + f (*this, idx.front (), rhs.get_rep ()); - retval = (! error_state); + done = (! error_state); } + + if (done) + retval = octave_value (this, count + 1); else { - f = octave_value_typeinfo::lookup_assignany_op (op, t_lhs); + int t_result + = octave_value_typeinfo::lookup_pref_assign_conv (t_lhs, t_rhs); + + if (t_result >= 0) + { + type_conv_fcn cf + = octave_value_typeinfo::lookup_widening_op (t_lhs, t_result); + + if (cf) + { + octave_value *tmp (cf (*this)); - if (f) + if (tmp) + { + retval = tmp->subsasgn (type, idx, rhs); + + done = (! error_state); + } + else + gripe_assign_conversion_failed (type_name (), + rhs.type_name ()); + } + else + gripe_indexed_assignment (type_name (), rhs.type_name ()); + } + + if (! (done || error_state)) { - f (*rep, idx, rhs); + octave_value tmp_rhs; + type_conv_fcn cf_rhs = rhs.numeric_conversion_function (); + + if (cf_rhs) + { + octave_value *tmp = cf_rhs (rhs.get_rep ()); + + if (tmp) + tmp_rhs = octave_value (tmp); + else + { + gripe_assign_conversion_failed (type_name (), + rhs.type_name ()); + return octave_value (); + } + } + else + tmp_rhs = rhs; + + type_conv_fcn cf_this = numeric_conversion_function (); + + octave_value *tmp_lhs = this; - retval = (! error_state); + if (cf_this) + { + octave_value *tmp = cf_this (*this); + + if (tmp) + tmp_lhs = tmp; + else + { + gripe_assign_conversion_failed (type_name (), + rhs.type_name ()); + return octave_value (); + } + } + + if (cf_this || cf_rhs) + { + retval = tmp_lhs->subsasgn (type, idx, tmp_rhs); + + done = (! error_state); + } + else + gripe_no_conversion (assign_op_as_string (op_asn_eq), + type_name (), rhs.type_name ()); } } @@ -1145,7 +1069,8 @@ } static void -gripe_binary_op (const std::string& on, const std::string& tn1, const std::string& tn2) +gripe_binary_op (const std::string& on, const std::string& tn1, + const std::string& tn2) { error ("binary operator `%s' not implemented for `%s' by `%s' operations", on.c_str (), tn1.c_str (), tn2.c_str ()); @@ -1158,8 +1083,8 @@ } octave_value -do_binary_op (octave_value::binary_op op, const octave_value& v1, - const octave_value& v2) +do_binary_op (octave_value::binary_op op, + const octave_value& v1, const octave_value& v2) { octave_value retval; @@ -1233,6 +1158,16 @@ return retval; } +void +octave_value::print_info (std::ostream& os, const std::string& prefix) const +{ + os << prefix << "type_name: " << type_name () << "\n" + << prefix << "count: " << get_count () << "\n" + << prefix << "rep info: "; + + rep->print_info (os, prefix + " "); +} + static void gripe_unary_op (const std::string& on, const std::string& tn) { @@ -1291,14 +1226,15 @@ } static void -gripe_unary_op_conversion_failed (const std::string& op, const std::string& tn) +gripe_unary_op_conversion_failed (const std::string& op, + const std::string& tn) { error ("operator %s: type conversion for `%s' failed", op.c_str (), tn.c_str ()); } -void -octave_value::do_non_const_unary_op (octave_value::unary_op op) +const octave_value& +octave_value::do_non_const_unary_op (unary_op op) { octave_value retval; @@ -1359,30 +1295,50 @@ else gripe_unary_op (octave_value::unary_op_as_string (op), type_name ()); } + + return *this; } +#if 0 static void -gripe_unary_op_failed_or_no_method (const std::string& on, const std::string& tn) +gripe_unary_op_failed_or_no_method (const std::string& on, + const std::string& tn) { error ("operator %s: no method, or unable to evaluate for %s operand", on.c_str (), tn.c_str ()); } +#endif void -octave_value::do_non_const_unary_op (octave_value::unary_op op, - const octave_value_list& idx) +octave_value::do_non_const_unary_op (unary_op op, const octave_value_list& idx) { - // XXX FIXME XXX -- only do the following stuff if we can't find a - // specific function to call to handle the op= operation for the - // types we have. + abort (); +} + +octave_value +octave_value::do_non_const_unary_op (unary_op op, const std::string type, + const SLList<octave_value_list>& idx) +{ + octave_value retval; + + if (idx.empty ()) + { + do_non_const_unary_op (op); - assign_op assop = unary_op_to_assign_op (op); + retval = *this; + } + else + { + // XXX FIXME XXX -- only do the following stuff if we can't find a + // specific function to call to handle the op= operation for the + // types we have. - if (! error_state) - assign (assop, idx, 1.0); - else - gripe_unary_op_failed_or_no_method (unary_op_as_string (op), - type_name ()); + assign_op assop = unary_op_to_assign_op (op); + + retval = assign (assop, type, idx, 1.0); + } + + return retval; } // Current indentation. @@ -1521,6 +1477,42 @@ return binop; } +octave_value +octave_value::empty_conv (const std::string& type, const octave_value& rhs) +{ + octave_value retval; + + if (type.length () > 0) + { + switch (type[0]) + { + case '(': + { + if (type.length () > 1 && type[1] == '.') + retval = Octave_map (); + else + retval = octave_value (rhs.empty_clone ()); + } + break; + + case '{': + retval = Cell (); + break; + + case '.': + retval = Octave_map (); + break; + + default: + panic_impossible (); + } + } + else + retval = octave_value (rhs.empty_clone ()); + + return retval; +} + void install_types (void) {