# HG changeset patch # User John W. Eaton # Date 1234924886 18000 # Node ID 70f5a0375afdbe4a7e33380ec81da5e737d12446 # Parent 374cb30311a8bd932fe6ece5b6231caf9776ff9c oct-map.h: fix think-o in previous change diff -r 374cb30311a8 -r 70f5a0375afd src/ChangeLog --- a/src/ChangeLog Tue Feb 17 21:47:10 2009 +0100 +++ b/src/ChangeLog Tue Feb 17 21:41:26 2009 -0500 @@ -1,5 +1,36 @@ 2009-02-17 John W. Eaton + * ov-fcn.h (octave_function::octave_function): Initialize data members. + (octave_function::dispatch_class): No longer virtual. + Replace with version from ov-usr-fcn.h. + (octave_function::xdispatch_class, + octave_function::stash_dispatch_class): Move here from ov-usr-fcn.h. + (octave_function::mark_as_private_function, + octave_function::is_private_function, + octave_function::is_private_function_of_class): New functions. + (octave_function::private_function): New data member. + * ov-usr-fcn.h (octave_user_function::xdispatch_class, + octave_user_function::stash_dispatch_class, + octave_user_function::dispatch_class): Delete. + * ov-usr-fcn.cc (octave_user_function::octave_user_function): + Don't initialize xdispatch_type. + + * symtab.cc + (symbol_table::fcn_info::fcn_info_rep::load_private_function): + If private directory is subdirectory of class directory, qmark + function as a private directory of the class. + + * ov-class.cc (octave_class::in_class_method): Also return true + for functions that are private to a class. + (octave_class::subsasgn): If not in class method, look for + subsasgn method. If not found, or if not in a class method, + perform default struct-style subscripted indexing. + + * ov-class.h (octave_class::empty_clone): + Preserve fields and class name. + * oct-map.h (Octave_map::Octave_map (const string_vector&): + New constructor. + * ov-class.cc (octave_class::subsref): If indexing directly and result is map, return class object, not simple struct. diff -r 374cb30311a8 -r 70f5a0375afd src/oct-map.h --- a/src/oct-map.h Tue Feb 17 21:47:10 2009 +0100 +++ b/src/oct-map.h Tue Feb 17 21:41:26 2009 -0500 @@ -56,6 +56,17 @@ key_list.push_back (k); } + Octave_map (const string_vector& sv) + : map (), key_list (), dimensions (0, 0) + { + for (octave_idx_type i = 0; i < sv.length (); i++) + { + std::string k = sv[i]; + map[k] = Cell (); + key_list.push_back (k); + } + } + Octave_map (const std::string& k, const Cell& vals) : map (), key_list (), dimensions (vals.dims ()) { diff -r 374cb30311a8 -r 70f5a0375afd src/ov-class.cc --- a/src/ov-class.cc Tue Feb 17 21:47:10 2009 +0100 +++ b/src/ov-class.cc Tue Feb 17 21:41:26 2009 -0500 @@ -321,211 +321,7 @@ { octave_value retval; - if (in_class_method () && ! rhs.is_object ()) - { - // FIXME -- this block of code is the same as the body of - // octave_struct::subsasgn. Maybe it could be shared instead of - // duplicated. - - int n = type.length (); - - octave_value t_rhs = rhs; - - if (n > 1 && ! (type.length () == 2 && type[0] == '(' && type[1] == '.')) - { - switch (type[0]) - { - case '(': - { - if (type.length () > 1 && type[1] == '.') - { - std::list::const_iterator p = idx.begin (); - octave_value_list t_idx = *p; - - octave_value_list key_idx = *++p; - - assert (key_idx.length () == 1); - - std::string key = key_idx(0).string_value (); - - octave_value u; - - if (! map.contains (key)) - u = octave_value::empty_conv (type.substr (2), rhs); - else - { - Cell map_val = map.contents (key); - - Cell map_elt = map_val.index (idx.front (), true); - - u = numeric_conv (map_elt, type.substr (2)); - } - - if (! error_state) - { - std::list next_idx (idx); - - // We handled two index elements, so subsasgn to - // needs to skip both of them. - - next_idx.erase (next_idx.begin ()); - next_idx.erase (next_idx.begin ()); - - u.make_unique (); - - t_rhs = u.subsasgn (type.substr (2), next_idx, rhs); - } - } - else - gripe_invalid_index_for_assignment (); - } - break; - - case '.': - { - octave_value_list key_idx = idx.front (); - - assert (key_idx.length () == 1); - - std::string key = key_idx(0).string_value (); - - octave_value u; - - if (! map.contains (key)) - u = octave_value::empty_conv (type.substr (1), rhs); - else - { - Cell map_val = map.contents (key); - - u = numeric_conv (map_val, type.substr (1)); - } - - if (! error_state) - { - std::list next_idx (idx); - - next_idx.erase (next_idx.begin ()); - - u.make_unique (); - - t_rhs = u.subsasgn (type.substr (1), next_idx, rhs); - } - } - break; - - case '{': - gripe_invalid_index_type (type_name (), type[0]); - break; - - default: - panic_impossible (); - } - } - - if (! error_state) - { - switch (type[0]) - { - case '(': - { - if (n > 1 && type[1] == '.') - { - std::list::const_iterator p = idx.begin (); - octave_value_list key_idx = *++p; - - assert (key_idx.length () == 1); - - std::string key = key_idx(0).string_value (); - - if (! error_state) - { - map.assign (idx.front (), key, t_rhs); - - if (! error_state) - { - count++; - retval = octave_value (this); - } - else - gripe_failed_assignment (); - } - else - gripe_failed_assignment (); - } - else - { - if (t_rhs.is_map()) - { - Octave_map rhs_map = t_rhs.map_value (); - - if (! error_state) - { - map.assign (idx.front (), rhs_map); - - if (! error_state) - { - count++; - retval = octave_value (this); - } - else - gripe_failed_assignment (); - } - else - error ("invalid class assignment"); - } - else - { - if (t_rhs.is_empty()) - { - map.maybe_delete_elements (idx.front()); - - if (! error_state) - { - count++; - retval = octave_value (this); - } - else - gripe_failed_assignment (); - } - else - error ("invalid class assignment"); - } - } - } - break; - - case '.': - { - octave_value_list key_idx = idx.front (); - - assert (key_idx.length () == 1); - - std::string key = key_idx(0).string_value (); - - map.assign (key, t_rhs); - - if (! error_state) - { - count++; - retval = octave_value (this); - } - else - gripe_failed_assignment (); - } - break; - - case '{': - gripe_invalid_index_type (type_name (), type[0]); - break; - - default: - panic_impossible (); - } - } - else - gripe_failed_assignment (); - } - else + if (! in_class_method ()) { octave_value meth = symbol_table::find_method ("subsasgn", class_name ()); @@ -551,15 +347,216 @@ if (tmp.length () > 1) error ("expecting single return value from @%s/subsasgn", class_name().c_str ()); + else retval = tmp(0); + return retval; } - else - error ("no subsasgn method defined for class %s", - class_name().c_str ()); + } + + // FIXME -- this block of code is the same as the body of + // octave_struct::subsasgn. Maybe it could be shared instead of + // duplicated. + + int n = type.length (); + + octave_value t_rhs = rhs; + + if (n > 1 && ! (type.length () == 2 && type[0] == '(' && type[1] == '.')) + { + switch (type[0]) + { + case '(': + { + if (type.length () > 1 && type[1] == '.') + { + std::list::const_iterator p = idx.begin (); + octave_value_list t_idx = *p; + + octave_value_list key_idx = *++p; + + assert (key_idx.length () == 1); + + std::string key = key_idx(0).string_value (); + + octave_value u; + + if (! map.contains (key)) + u = octave_value::empty_conv (type.substr (2), rhs); + else + { + Cell map_val = map.contents (key); + + Cell map_elt = map_val.index (idx.front (), true); + + u = numeric_conv (map_elt, type.substr (2)); + } + + if (! error_state) + { + std::list next_idx (idx); + + // We handled two index elements, so subsasgn to + // needs to skip both of them. + + next_idx.erase (next_idx.begin ()); + next_idx.erase (next_idx.begin ()); + + u.make_unique (); + + t_rhs = u.subsasgn (type.substr (2), next_idx, rhs); + } + } + else + gripe_invalid_index_for_assignment (); + } + break; + + case '.': + { + octave_value_list key_idx = idx.front (); + + assert (key_idx.length () == 1); + + std::string key = key_idx(0).string_value (); + + octave_value u; + + if (! map.contains (key)) + u = octave_value::empty_conv (type.substr (1), rhs); + else + { + Cell map_val = map.contents (key); + + u = numeric_conv (map_val, type.substr (1)); + } + + if (! error_state) + { + std::list next_idx (idx); + + next_idx.erase (next_idx.begin ()); + + u.make_unique (); + + t_rhs = u.subsasgn (type.substr (1), next_idx, rhs); + } + } + break; + + case '{': + gripe_invalid_index_type (type_name (), type[0]); + break; + + default: + panic_impossible (); + } } + if (! error_state) + { + switch (type[0]) + { + case '(': + { + if (n > 1 && type[1] == '.') + { + std::list::const_iterator p = idx.begin (); + octave_value_list key_idx = *++p; + + assert (key_idx.length () == 1); + + std::string key = key_idx(0).string_value (); + + if (! error_state) + { + map.assign (idx.front (), key, t_rhs); + + if (! error_state) + { + count++; + retval = octave_value (this); + } + else + gripe_failed_assignment (); + } + else + gripe_failed_assignment (); + } + else + { + if (t_rhs.is_object () || t_rhs.is_map ()) + { + Octave_map rhs_map = t_rhs.map_value (); + + if (! error_state) + { + map.assign (idx.front (), rhs_map); + + if (! error_state) + { + count++; + retval = octave_value (this); + } + else + gripe_failed_assignment (); + } + else + error ("invalid class assignment"); + } + else + { + if (t_rhs.is_empty ()) + { + map.maybe_delete_elements (idx.front()); + + if (! error_state) + { + count++; + retval = octave_value (this); + } + else + gripe_failed_assignment (); + } + else + error ("invalid class assignment"); + } + } + } + break; + + case '.': + { + octave_value_list key_idx = idx.front (); + + assert (key_idx.length () == 1); + + std::string key = key_idx(0).string_value (); + + map.assign (key, t_rhs); + + if (! error_state) + { + count++; + retval = octave_value (this); + } + else + gripe_failed_assignment (); + } + break; + + case '{': + gripe_invalid_index_type (type_name (), type[0]); + break; + + default: + panic_impossible (); + } + } + else + gripe_failed_assignment (); + return retval; } @@ -1161,7 +1158,9 @@ octave_function *fcn = octave_call_stack::current (); return (fcn - && (fcn->is_class_method () || fcn->is_class_constructor ()) + && (fcn->is_class_method () + || fcn->is_class_constructor () + || fcn->is_private_function_of_class (class_name ())) && fcn->dispatch_class () == class_name ()); } diff -r 374cb30311a8 -r 70f5a0375afd src/ov-class.h --- a/src/ov-class.h Tue Feb 17 21:47:10 2009 +0100 +++ b/src/ov-class.h Tue Feb 17 21:41:26 2009 -0500 @@ -60,7 +60,11 @@ ~octave_class (void) { } octave_base_value *clone (void) const { return new octave_class (*this); } - octave_base_value *empty_clone (void) const { return new octave_class (); } + + octave_base_value *empty_clone (void) const + { + return new octave_class (Octave_map (map.keys ()), class_name ()); + } Cell dotref (const octave_value_list& idx); diff -r 374cb30311a8 -r 70f5a0375afd src/ov-fcn.h --- a/src/ov-fcn.h Tue Feb 17 21:47:10 2009 +0100 +++ b/src/ov-fcn.h Tue Feb 17 21:41:26 2009 -0500 @@ -45,7 +45,9 @@ { public: - octave_function (void) { } + octave_function (void) + : relative (false), locked (false), private_function (false), + xdispatch_class (), my_name (), my_dir_name (), doc () { } ~octave_function (void) { } @@ -80,12 +82,25 @@ virtual bool is_class_method (void) const { return false; } - virtual std::string dispatch_class (void) const { return std::string (); } - virtual bool takes_varargs (void) const { return false; } virtual bool takes_var_return (void) const { return false; } + void stash_dispatch_class (const std::string& nm) { xdispatch_class = nm; } + + std::string dispatch_class (void) const { return xdispatch_class; } + + void mark_as_private_function (const std::string& cname = std::string ()) + { + private_function = true; + xdispatch_class = cname; + } + + bool is_private_function (void) const { return private_function; } + + bool is_private_function_of_class (const std::string& nm) + { return private_function && xdispatch_class == nm; } + std::string dir_name (void) const { return my_dir_name; } void stash_dir_name (const std::string& dir) { my_dir_name = dir; } @@ -134,6 +149,14 @@ // TRUE if this function is tagged so that it can't be cleared. bool locked; + // TRUE means this is a private function. + bool private_function; + + // If this object is a class method or constructor, or a private + // function inside a class directory, this is the name of the class + // to which the method belongs. + std::string xdispatch_class; + // The name of this function. std::string my_name; diff -r 374cb30311a8 -r 70f5a0375afd src/ov-usr-fcn.cc --- a/src/ov-usr-fcn.cc Tue Feb 17 21:47:10 2009 +0100 +++ b/src/ov-usr-fcn.cc Tue Feb 17 21:41:26 2009 -0500 @@ -183,8 +183,8 @@ system_fcn_file (false), call_depth (-1), num_named_args (param_list ? param_list->length () : 0), nested_function (false), inline_function (false), - class_constructor (false), class_method (false), xdispatch_class (), - args_passed (), num_args_passed (0), parent_scope (-1), local_scope (sid) + class_constructor (false), class_method (false), args_passed (), + num_args_passed (0), parent_scope (-1), local_scope (sid) { if (cmd_list) cmd_list->mark_as_function_body (); diff -r 374cb30311a8 -r 70f5a0375afd src/ov-usr-fcn.h --- a/src/ov-usr-fcn.h Tue Feb 17 21:47:10 2009 +0100 +++ b/src/ov-usr-fcn.h Tue Feb 17 21:41:26 2009 -0500 @@ -260,10 +260,6 @@ bool is_class_method (void) const { return class_method; } - void stash_dispatch_class (const std::string& nm) { xdispatch_class = nm; } - - std::string dispatch_class (void) const { return xdispatch_class; } - void save_args_passed (const octave_value_list& args) { if (call_depth > 0) @@ -367,10 +363,6 @@ // TRUE means this function is a method for a class. bool class_method; - // If this object is a class method or constructor, this is the name - // of the class to which the method belongs. - std::string xdispatch_class; - // The values that were passed as arguments. octave_value_list args_passed; diff -r 374cb30311a8 -r 70f5a0375afd src/symtab.cc --- a/src/symtab.cc Tue Feb 17 21:47:10 2009 +0100 +++ b/src/symtab.cc Tue Feb 17 21:41:26 2009 -0500 @@ -300,6 +300,20 @@ if (fcn) { + std::string class_name; + + size_t pos = dir_name.find_last_of (file_ops::dir_sep_chars ()); + + if (pos != std::string::npos) + { + std::string tmp = dir_name.substr (pos+1); + + if (tmp[0] == '@') + class_name = tmp.substr (1); + } + + fcn->mark_as_private_function (class_name); + retval = octave_value (fcn); private_functions[dir_name] = retval;