Mercurial > hg > octave-lyh
changeset 9147:5579998f8acf
Update to OOP facilities.
* scripts/general/isa.m: Fixed isa so that multiple layers of
class hierarchy are reported correctly.
* src/variables.cc: Make exist('obj') for objects report correctly.
* src/ov-base.h: Added an assign method so ov-class is able to
assign structure elements properly.
* src/ov-class.h: Assign map elements.
* src/ov-class.cc:
- Made sure that there are no duplicate classes in parent tree.
- Simplified search algorithm for parent classes.
- Fixed subsasgn so cls = method(cls,value) works when properly
when method is a parent-class method.
- Added __isa_parent__ so isa works correctly.
author | rtshort@bristlecone.phaselocked.com |
---|---|
date | Wed, 22 Apr 2009 14:33:26 -0400 |
parents | a48c500e48e1 |
children | 69e6bbfef8c2 |
files | scripts/ChangeLog scripts/general/isa.m src/ChangeLog src/ov-base.h src/ov-class.cc src/ov-class.h src/variables.cc |
diffstat | 7 files changed, 104 insertions(+), 52 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,7 @@ +2009-04-22 Robert T. Short <octave@phaselockedsystems.com> + + * general/isa.m: Correctly report multiple layers of class hierarchy. + 2009-04-20 John W. Eaton <jwe@octave.org> * special-matrix/vander.m: Update tests.
--- a/scripts/general/isa.m +++ b/scripts/general/isa.m @@ -44,10 +44,7 @@ class_of_x = class (x); retval = strcmp (class_of_x, cname); if (! retval && isobject (x)) - parent_classes_of_x = __parent_classes__ (x); - if (! isempty (parent_classes_of_x)) - retval = any (strcmp (parent_classes_of_x, cname)); - endif + retval = __isa_parent__ (x, cname); endif endif
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2009-04-22 Robert T. Short <octave@phaselockedsystems.com> + + * variables.cc (symbol_exist): Also return 1 for objects. + * ov-base.h (octave_base_value::assign): New virtual function. + * ov-class.h (octave_class::assign): New function. + * ov-class.cc (octave_class::find_parent_class): Simplify. + (octave_class::octave_class): Don't allow duplicate parent classes. + (octave_class::subsasgn): Allow cls = method (cls, value) to work + properly when method is a parent-class method. + (get_method_class): New static function. + (octave_class:subsasgn, octave_class::dotref): Use it. + (F__isa_parent__): New function. + 2009-04-22 Jaroslav Hajek <highegg@gmail.com> * ov-range.cc (octave_range::char_array_value): New virtual function
--- a/src/ov-base.h +++ b/src/ov-base.h @@ -171,6 +171,8 @@ virtual octave_value_list do_multi_index_op (int nargout, const octave_value_list& idx); + virtual void assign (const std::string&, const octave_value&) { } + virtual octave_value subsasgn (const std::string& type, const std::list<octave_value_list>& idx,
--- a/src/ov-class.cc +++ b/src/ov-class.cc @@ -78,69 +78,67 @@ { std::string cnm = parent.class_name (); - parent_list.push_back (cnm); + if (find_parent_class (cnm)) + error ("duplicate class in parent tree"); + else + { + parent_list.push_back (cnm); - map.assign (cnm, parent); + map.assign (cnm, parent); + } } } - load_path::add_to_parent_map (id, parent_list); + if (! error_state) + load_path::add_to_parent_map (id, parent_list); } octave_base_value * octave_class::find_parent_class (const std::string& parent_class_name) { octave_base_value* retval = 0; - std::string dbg_clsnm = class_name (); if (parent_class_name == class_name ()) retval = this; else { - // Search in the list of immediate parents first, then in the - // ancestor tree. - - std::list<std::string>::iterator - p = find (parent_list.begin (), parent_list.end (), parent_class_name); - - if (p != parent_list.end ()) + for (std::list<std::string>::iterator pit = parent_list.begin (); + pit != parent_list.end (); + pit++) { - Octave_map::const_iterator pmap = map.seek (parent_class_name); + Octave_map::const_iterator smap = map.seek (*pit); - if (pmap != map.end ()) - { - const Cell& tmp = pmap->second; - - octave_value vtmp = tmp(0); + const Cell& tmp = smap->second; - retval = vtmp.internal_rep (); - } - } - else - { - for (std::list<std::string>::iterator pit = parent_list.begin (); - pit != parent_list.end (); - pit++) - { - Octave_map::const_iterator smap = map.seek (*pit); + octave_value vtmp = tmp(0); + + octave_base_value *obvp = vtmp.internal_rep (); - const Cell& tmp = smap->second; - - octave_value vtmp = tmp(0); - - octave_base_value *obvp = vtmp.internal_rep (); + retval = obvp->find_parent_class (parent_class_name); - retval = obvp->find_parent_class (parent_class_name); - - if (retval) - break; - } + if (retval) + break; } } return retval; } +static std::string +get_current_method_class (void) +{ + // FIXME -- is there a better way to do this? + octave_function *fcn = octave_call_stack::current (); + + std::string my_dir = fcn->dir_name (); + + size_t ipos = my_dir.find_last_of ("@"); + + assert (ipos != std::string::npos); + + return my_dir.substr (ipos+1); +} + Cell octave_class::dotref (const octave_value_list& idx) { @@ -148,11 +146,7 @@ assert (idx.length () == 1); - // FIXME -- Is there a "proper" way to do this? - octave_function* fcn = octave_call_stack::current (); - std::string my_dir = fcn->dir_name (); - int ipos = my_dir.find_last_of ("@"); - std::string method_class = my_dir.substr (ipos+1); + std::string method_class = get_current_method_class (); // Find the class in which this method resides before attempting to access // the requested field. @@ -628,15 +622,27 @@ std::string key = key_idx(0).string_value (); - map.assign (key, t_rhs); + // Find the class in which this method resides before + // attempting to access the requested field. + + std::string method_class = get_current_method_class (); + + octave_base_value *obvp = find_parent_class (method_class); - if (! error_state) + if (obvp) { - count++; - retval = octave_value (this); + obvp->assign (key, t_rhs); + + if (! error_state) + { + count++; + retval = octave_value (this); + } + else + gripe_failed_assignment (); } else - gripe_failed_assignment (); + error ("malformed class"); } break; @@ -1313,6 +1319,33 @@ return retval; } +DEFUN (__isa_parent__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} __isa_parent__ (@var{class}, @var{name})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval = false; + + if (args.length () == 2) + { + octave_value cls = args(0); + octave_value nm = args(1); + + if (! error_state) + { + if (cls.find_parent_class (nm.string_value ())) + retval = true; + } + else + error ("__isa_parent__: expecting arguments to be character strings"); + } + else + print_usage (); + + return retval; +} + DEFUN (__parent_classes__, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __parent_classes__ (@var{x})\n\
--- a/src/ov-class.h +++ b/src/ov-class.h @@ -86,6 +86,9 @@ static octave_value numeric_conv (const Cell& val, const std::string& type); + void assign(const std::string& k, const octave_value& rhs) + { map.assign (k, rhs); }; + octave_value subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs);