# HG changeset patch # User jwe # Date 1021432861 0 # Node ID f9ea3dcf58ee016c06040d361d2c9a54bffbd921 # Parent 2e2e32198722822c3e34c1780e12a8a2f59d54e8 [project @ 2002-05-15 03:21:00 by jwe] diff --git a/liboctave/Array-idx.h b/liboctave/Array-idx.h --- a/liboctave/Array-idx.h +++ b/liboctave/Array-idx.h @@ -69,13 +69,14 @@ template Array -Array::index (idx_vector& idx_arg) const +Array::index (idx_vector& idx_arg, int resize_ok, + const T& resize_fill_value) const { Array retval; int len = length (); - int n = idx_arg.freeze (len, "vector"); + int n = idx_arg.freeze (len, "vector", resize_ok); if (idx_arg) { @@ -100,7 +101,10 @@ for (int i = 0; i < n; i++) { int ii = idx_arg.elem (i); - retval.elem (i) = elem (ii); + if (ii > len) + retval.elem (i) = resize_fill_value; + else + retval.elem (i) = elem (ii); } } } diff --git a/liboctave/Array.cc b/liboctave/Array.cc --- a/liboctave/Array.cc +++ b/liboctave/Array.cc @@ -185,6 +185,16 @@ return foo; } +template +void +Array::print_info (std::ostream& os, const std::string& prefix) const +{ + os << prefix << "rep address: " << rep << "\n" + << prefix << "rep->len: " << rep->len << "\n" + << prefix << "rep->data: " << static_cast (rep->data) << "\n" + << prefix << "rep->count: " << rep->count << "\n"; +} + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/liboctave/Array.h b/liboctave/Array.h --- a/liboctave/Array.h +++ b/liboctave/Array.h @@ -30,6 +30,8 @@ #include +#include + #include "lo-utils.h" class idx_vector; @@ -232,6 +234,7 @@ } #ifdef HEAVYWEIGHT_INDEXING + void set_max_indices (int mi) { max_indices = mi; } void clear_index (void); @@ -246,10 +249,14 @@ Array value (void); - Array index (idx_vector& i) const; + Array index (idx_vector& i, int resize_ok = 0, + const T& rfv = Array::resize_fill_value ()) const; + #endif static T resize_fill_value (void) { return static_cast (0); } + + void print_info (std::ostream& os, const std::string& prefix) const; }; template diff --git a/liboctave/Array2-idx.h b/liboctave/Array2-idx.h --- a/liboctave/Array2-idx.h +++ b/liboctave/Array2-idx.h @@ -56,13 +56,16 @@ template Array2 -Array2::index (idx_vector& idx_arg) const +Array2::index (idx_vector& idx_arg, int resize_ok, + const T& resize_fill_value) const { Array2 retval; int nr = d1; int nc = d2; + int orig_len = nr * nc; + int idx_orig_rows = idx_arg.orig_rows (); int idx_orig_columns = idx_arg.orig_columns (); @@ -77,7 +80,7 @@ } else if (nr == 1 && nc == 1) { - Array tmp = Array::index (idx_arg); + Array tmp = Array::index (idx_arg, resize_ok); if (tmp.length () != 0) retval = Array2 (tmp, idx_orig_rows, idx_orig_columns); @@ -88,7 +91,7 @@ { int result_is_column_vector = (nc == 1); - Array tmp = Array::index (idx_arg); + Array tmp = Array::index (idx_arg, resize_ok); int len = tmp.length (); @@ -110,7 +113,7 @@ // This code is only for indexing matrices. The vector // cases are handled above. - idx_arg.freeze (nr * nc, "matrix"); + idx_arg.freeze (nr * nc, "matrix", resize_ok); if (idx_arg) { @@ -125,15 +128,22 @@ retval.resize (result_nr, result_nc); + + int k = 0; for (int j = 0; j < result_nc; j++) { for (int i = 0; i < result_nr; i++) { int ii = idx_arg.elem (k++); - int fr = ii % nr; - int fc = (ii - fr) / nr; - retval.elem (i, j) = elem (fr, fc); + if (ii > orig_len) + retval.elem (i, j) = resize_fill_value; + else + { + int fr = ii % nr; + int fc = (ii - fr) / nr; + retval.elem (i, j) = elem (fr, fc); + } } } } @@ -148,15 +158,16 @@ template Array2 -Array2::index (idx_vector& idx_i, idx_vector& idx_j) const +Array2::index (idx_vector& idx_i, idx_vector& idx_j, int resize_ok, + const T& resize_fill_value) const { Array2 retval; int nr = d1; int nc = d2; - int n = idx_i.freeze (nr, "row"); - int m = idx_j.freeze (nc, "column"); + int n = idx_i.freeze (nr, "row", resize_ok); + int m = idx_j.freeze (nc, "column", resize_ok); if (idx_i && idx_j) { @@ -178,7 +189,10 @@ for (int i = 0; i < n; i++) { int ii = idx_i.elem (i); - retval.elem (i, j) = elem (ii, jj); + if (ii > nr || jj > nc) + retval.elem (i, j) = resize_fill_value; + else + retval.elem (i, j) = elem (ii, jj); } } } diff --git a/liboctave/Array2.cc b/liboctave/Array2.cc --- a/liboctave/Array2.cc +++ b/liboctave/Array2.cc @@ -237,6 +237,17 @@ } } +template +void +Array2::print_info (std::ostream& os, const std::string& prefix) const +{ + os << "\n" + << prefix << "rows: " << rows () << "\n" + << prefix << "cols: " << cols () << "\n"; + + Array::print_info (os, prefix + " "); +} + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/liboctave/Array2.h b/liboctave/Array2.h --- a/liboctave/Array2.h +++ b/liboctave/Array2.h @@ -174,16 +174,22 @@ Array2 transpose (void) const; #ifdef HEAVYWEIGHT_INDEXING + void maybe_delete_elements (idx_vector& i); void maybe_delete_elements (idx_vector& i, idx_vector& j); Array2 value (void); - Array2 index (idx_vector& i) const; + Array2 index (idx_vector& i, int resize_ok = 0, + const T& rfv = Array::resize_fill_value ()) const; - Array2 index (idx_vector& i, idx_vector& j) const; + Array2 index (idx_vector& i, idx_vector& j, int resize_ok = 0, + const T& rfv = Array::resize_fill_value ()) const; + #endif + + void print_info (std::ostream& os, const std::string& prefix) const; }; template diff --git a/liboctave/ArrayN-idx.h b/liboctave/ArrayN-idx.h --- a/liboctave/ArrayN-idx.h +++ b/liboctave/ArrayN-idx.h @@ -70,7 +70,8 @@ template ArrayN -ArrayN::index (idx_vector& idx) const +ArrayN::index (idx_vector& idx, int resize_ok, + const T& resize_fill_value) const { ArrayN retval; assert (0); @@ -78,7 +79,7 @@ } static inline Array -freeze (Array& idx, const Array& dimensions) +freeze (Array& idx, const Array& dimensions, int resize_ok) { Array retval; @@ -89,7 +90,7 @@ retval.resize (n); for (int i = 0; i < n; i++) - retval(i) = idx(i).freeze (dimensions(i), "XXX FIXME XXX"); + retval(i) = idx(i).freeze (dimensions(i), "XXX FIXME XXX", resize_ok); return retval; } @@ -199,13 +200,14 @@ template ArrayN -ArrayN::index (Array& arr_idx) const +ArrayN::index (Array& arr_idx, int resize_ok, + const T& resize_fill_value) const { ArrayN retval; int n_dims = dimensions.length (); - Array frozen_lengths = freeze (arr_idx, dimensions); + Array frozen_lengths = freeze (arr_idx, dimensions, resize_ok); if (frozen_lengths.length () == n_dims) { @@ -239,7 +241,10 @@ { Array elt_idx = get_elt_idx (result_idx); - retval.elem (result_idx) = elem (elt_idx); + if (elt_idx > orig_len) + retval.elem (result_idx) = resize_fill_value; + else + retval.elem (result_idx) = elem (elt_idx); increment_index (result_idx, frozen_lengths); } diff --git a/liboctave/ArrayN.h b/liboctave/ArrayN.h --- a/liboctave/ArrayN.h +++ b/liboctave/ArrayN.h @@ -179,9 +179,12 @@ ArrayN value (void); - ArrayN index (idx_vector& idx) const; + ArrayN index (idx_vector& idx, int resize_ok = 0, + const T& rfv = Array::resize_fill_value ()) const; - ArrayN index (Array& idx) const; + ArrayN index (Array& idx, int resize_ok = 0, + const T& rfv = Array::resize_fill_value ()) const; + #endif }; diff --git a/liboctave/CMatrix.h b/liboctave/CMatrix.h --- a/liboctave/CMatrix.h +++ b/liboctave/CMatrix.h @@ -273,6 +273,8 @@ friend std::ostream& operator << (std::ostream& os, const ComplexMatrix& a); friend std::istream& operator >> (std::istream& is, ComplexMatrix& a); + static Complex resize_fill_value (void) { return Complex (0.0, 0.0); } + private: ComplexMatrix (Complex *d, int r, int c) : MArray2 (d, r, c) { } diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog --- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,33 @@ +2002-05-14 John W. Eaton + + * oct-rl-edit.c (OCTAVE_RL_SAVE_STRING): New macro. + (octave_rl_set_name, octave_rl_set_basic_quote_characters): Use it. + (octave_rl_set_basic_word_break_characters, + octave_rl_set_completer_word_break_characters): New functions. + * oct-rl-edit.h: Provide decls. + * cmd-edit.cc (gnu_readline::do_set_basic_word_break_characters, + gnu_readline::do_set_completer_word_break_characters): New functions. + (command_editor::set_basic_quote_characters, + command_editor::set_completion_append_character): New static functions. + * cmd-edit.h: Provide decls. + (command_editor::do_set_basic_word_break_characters, + command_editor::do_set_completer_word_break_characters): + New virtual functions. + + * CMatrix.h, boolMatrix.h, chMatrix.h, dMatrix.h + (resize_fill_value): New static function. + + * Array-idx.h (Array::index): New args, resize_ok and + resize_fill_value. + * Array2-idx.h (Array2::index): Likewise. + * ArrayN-idx.h (ArrayN::index): Likewise. + + * Array2.cc (Array::print_info): New function. + * Array2.h: Provide decl. + + * Array.cc (Array::print_info): New function. + * Array.h: Provide decl. + 2002-05-03 John W. Eaton * idx-vector.h (idx_vector::idx_vector (int)): New function. diff --git a/liboctave/boolMatrix.h b/liboctave/boolMatrix.h --- a/liboctave/boolMatrix.h +++ b/liboctave/boolMatrix.h @@ -74,6 +74,8 @@ friend std::istream& operator >> (std::istream& is, Matrix& a); #endif + static bool resize_fill_value (void) { return false; } + private: boolMatrix (bool *b, int r, int c) : Array2 (b, r, c) { } diff --git a/liboctave/chMatrix.h b/liboctave/chMatrix.h --- a/liboctave/chMatrix.h +++ b/liboctave/chMatrix.h @@ -81,6 +81,8 @@ friend std::istream& operator >> (std::istream& is, Matrix& a); #endif + static char resize_fill_value (void) { return '\0'; } + private: charMatrix (char *ch, int r, int c) : MArray2 (ch, r, c) { } diff --git a/liboctave/cmd-edit.cc b/liboctave/cmd-edit.cc --- a/liboctave/cmd-edit.cc +++ b/liboctave/cmd-edit.cc @@ -93,6 +93,10 @@ void do_blink_matching_paren (bool flag); + void do_set_basic_word_break_characters (const std::string& s); + + void do_set_completer_word_break_characters (const std::string& s); + void do_set_basic_quote_characters (const std::string& s); void do_set_completion_append_character (char c); @@ -270,6 +274,18 @@ } void +gnu_readline::do_set_basic_word_break_characters (const std::string& s) +{ + ::octave_rl_set_basic_word_break_characters (s.c_str ()); +} + +void +gnu_readline::do_set_completer_word_break_characters (const std::string& s) +{ + ::octave_rl_set_completer_word_break_characters (s.c_str ()); +} + +void gnu_readline::do_set_basic_quote_characters (const std::string& s) { ::octave_rl_set_basic_quote_characters (s.c_str ()); @@ -635,6 +651,20 @@ } void +command_editor::set_basic_word_break_characters (const std::string& s) +{ + if (instance_ok ()) + instance->do_set_basic_word_break_characters (s); +} + +void +command_editor::set_completer_word_break_characters (const std::string& s) +{ + if (instance_ok ()) + instance->do_set_completer_word_break_characters (s); +} + +void command_editor::set_basic_quote_characters (const std::string& s) { if (instance_ok ()) diff --git a/liboctave/cmd-edit.h b/liboctave/cmd-edit.h --- a/liboctave/cmd-edit.h +++ b/liboctave/cmd-edit.h @@ -73,6 +73,12 @@ static void blink_matching_paren (bool flag); + static void command_editor::set_basic_word_break_characters + (const std::string& s); + + static void command_editor::set_completer_word_break_characters + (const std::string& s); + static void set_basic_quote_characters (const std::string& s); static void set_completion_append_character (char c); @@ -159,6 +165,10 @@ virtual void do_blink_matching_paren (bool) { } + virtual void do_set_basic_word_break_characters (const std::string&) { } + + virtual void do_set_completer_word_break_characters (const std::string&) { } + virtual void do_set_basic_quote_characters (const std::string&) { } virtual void do_set_completion_append_character (char) { } diff --git a/liboctave/dMatrix.h b/liboctave/dMatrix.h --- a/liboctave/dMatrix.h +++ b/liboctave/dMatrix.h @@ -233,6 +233,8 @@ int write (std::ostream& os, oct_data_conv::data_type dt, int skip, oct_mach_info::float_format flt_fmt); + static double resize_fill_value (void) { return 0; } + private: Matrix (double *d, int r, int c) : MArray2 (d, r, c) { } diff --git a/liboctave/oct-rl-edit.c b/liboctave/oct-rl-edit.c --- a/liboctave/oct-rl-edit.c +++ b/liboctave/oct-rl-edit.c @@ -33,6 +33,19 @@ #include "oct-rl-edit.h" +#define OCTAVE_RL_SAVE_STRING(ss, s) \ + static char *ss = 0; \ + \ + if (ss) \ + { \ + free (ss); \ + ss = 0; \ + } \ + \ + ss = malloc (strlen (s) + 1); \ + \ + strcpy (ss, s) + int octave_rl_screen_height (void) { @@ -123,17 +136,7 @@ void octave_rl_set_name (const char *n) { - static char *nm = 0; - - if (nm) - { - free (nm); - nm = 0; - } - - nm = malloc (strlen (n + 1)); - - strcpy (nm, n); + OCTAVE_RL_SAVE_STRING (nm, n); rl_readline_name = nm; @@ -184,19 +187,25 @@ } void +octave_rl_set_basic_word_break_characters (const char *s) +{ + OCTAVE_RL_SAVE_STRING (ss, s); + + rl_basic_word_break_characters = ss; +} + +void +octave_rl_set_completer_word_break_characters (const char *s) +{ + OCTAVE_RL_SAVE_STRING (ss, s); + + rl_completer_word_break_characters = ss; +} + +void octave_rl_set_basic_quote_characters (const char *s) { - static char *ss = 0; - - if (ss) - { - free (ss); - ss = 0; - } - - ss = malloc (strlen (s) + 1); - - strcpy (ss, s); + OCTAVE_RL_SAVE_STRING (ss, s); rl_basic_quote_characters = ss; } diff --git a/liboctave/oct-rl-edit.h b/liboctave/oct-rl-edit.h --- a/liboctave/oct-rl-edit.h +++ b/liboctave/oct-rl-edit.h @@ -72,6 +72,10 @@ extern void octave_rl_read_init_file (const char *); +extern void octave_rl_set_basic_word_break_characters (const char *); + +extern void octave_rl_set_completer_word_break_characters (const char *); + extern void octave_rl_set_basic_quote_characters (const char *); extern void octave_rl_set_completion_append_character (char); diff --git a/src/Cell.h b/src/Cell.h --- a/src/Cell.h +++ b/src/Cell.h @@ -52,12 +52,22 @@ Cell (const Array2& c) : Array2 (c) { } + Cell (const Array& c, int nr, int nc) + : Array2 (c, nr, nc) { } + Cell (const Cell& c) : Array2 (c) { } - boolMatrix all(void) const { return boolMatrix();} //FIXME - boolMatrix any(void) const {return boolMatrix();} //FIXME - bool is_true(void) const {return false;} //FIXME + // XXX FIXME XXX + boolMatrix all (void) const { return boolMatrix (); } + + // XXX FIXME XXX + boolMatrix any (void) const { return boolMatrix (); } + + // XXX FIXME XXX + bool is_true (void) const { return false; } + + static octave_value resize_fill_value (void) { return octave_value (); } }; #endif diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,210 @@ +2002-05-14 John W. Eaton + + * ov.h (octave_value::get_count): Now const. + + * ov.h, ov.cc (octave_value::do_non_const_unary_op, + octave_value::assign): Idx is now a list of octave_value_list + objects. + + * ov-base.cc, ov-base.h (octave_base_value::do_struct_elt_index_op, + octave_base_value::struct_elt_ref): Delete. + * ov-struct.cc, ov-struct.h (octave_sruct::do_struct_elt_index_op, + octave_struct::struct_elt_ref): Delete. + * ov.cc, ov.h (octave_value::do_struct_elt_index_op, + octave_value::struct_elt_ref, octave_value::assign_struct_elt, + octave_value::convert_and_assign, octave_value::try_assignment, + octave_value::try_assignment_with_conversion, + octave_value::simple_assign): Delete. + + * parse.y (make_index_expression): Type is now a single + character. Change all callers. If expr is already an index + expression, append index to it. + (make_indirect_ref): Likewise. + + * pt-pr-code.cc (octave_print_internal (std::ostream&, const + Cell&, bool, int)): Now just a dummy function, panic if called. + + * pt-idx.cc (tree_index_expression::make_arg_struct): New function. + (tree_index_expression::type): Delete enum, rename from itype, now + a string. + (tree_index_expression::arg_nm): Now a list of string_vector objects. + (tree_index_expression::idx): Now a list of tree_argument_list* + objects. + (tree_index_expression::is_index_expression): Always return true. + (tree_index_expression::apend, make_value_list, make_subs_cell): + New functions. + + * pt-pr-code.cc (visit_index_expression): Handle new definition of + tree_index_expression object. + * pt-check.cc (visit_index_expression): Likewise. + * pt-bp.cc (visit_index_expression): Likewise. + + * ov-usr-fcn.h (octave_user_function::restore_args_passed): + Clear args_passed even if nothing was saved. + + * ov-base.cc (octave_base_value::subsasgn, + octave_base_value::map_keys, octave_base_value::print_info): + New functions. + + * ov.h, ov.cc (octave_value::map_keys, octave_value::print_info, + octave_value::subsref, octave_value::subsasgn, + octave_value::numeric_assign, octave_value::next_subsref): + New functions. + (octave_value::empty_conv): New static function. + (octave_value (octave_value *, int)): New arg, count. + + * ov-base-mat.cc (octave_base_matrix::subsref, + octave_base_matrix::subsasgn): New functions. + * ov-base-mat.h: Provide decls. + + * ov-builtin.cc (octave_builtin::subsref): New function. + * ov-builtin.h: Provide decl. + + * ov-range.cc (octave_range::subsref): New function. + * ov-range.h: Provide decl. + + * ov-cell.cc (octave_cell::subsref, octave_cell::subsasgn, + octave_cell::list_value, octave_cell::print, + octave_cell::print_raw, octave_cell::print_name_tag): New functions. + * ov-cell.h: Provide decls. + + * ov-struct.cc (octave_struct::dotref, octave_struct::subsref, + octave_struct::subsasgn, gripe_invalid_index, + gripe_invalid_index_for_assignment, grip_invalid_index_type, + gripe_failed_assignment): New functions. + (octave_struct::numeric_conv): New static function. + * ov-struct.h: Provide decls. + (octave_struct::is_constant): Return true. + (octave_struct::map_keys): New function. + + * ov-list.cc (octave_list::subsref, octave_list::subsasgn): + New functions. + * ov-list.h: Provide decls. + + * ov-usr-fcn.cc (octave_user_function::subsref, + octave_user_function::print_symtab_info): New functions. + * ov-usr-fcn.h: Provide decl. + + * ov-mapper.cc (octave_mapper::subsref): New function. + * ov-mapper.h: Provide decl. + + * ov-base.cc (octave_base_value::subsref, + octave_base_value::subsasgn): New functions. + * ov-base.h: Provide decls. + + * ov-base.cc (octave_base_value::do_index_op): New arg, resize_ok. + * ov-base-mat.cc (octave_base_matrix::do_index_op): Likewise. + * ov-base-nd-array.cc (octave_base_nd_array::do_index_op): Ditto. + * ov-bool-mat.cc (octave_bool::do_index_op): Ditto. + * ov-str-mat.cc (octave_char_matrix_str::do_index_op): Ditto. + * ov-range.cc (octave_range::do_index_op): Ditto. + * ov-list.cc (octave_list::do_index_op): Ditto. + * ov.cc (octave_value::do_index_op): Ditto. + + * ov-base-mat.cc (octave_base_matrix::print_info): New function. + + * ov-base-mat.h (octave_base_matrix::empty_clone): New function. + * ov-base-nd-array.h (octave_base_nd_array::empty_clone): Ditto. + * ov-base.h (octave_base_value::empty_clone): Ditto. + * ov-bool-mat.h (octave_bool::empty_clone): Ditto. + * ov-ch-mat.h (octave_char_matrix::empty_clone): Likewise. + * ov-colon.h (octave_magic_colon::empty_clone): Likewise. + * ov-complex.h (octave_complex::empty_clone): Likewise. + * ov-cx-mat.h (octave_complex_matrix::empty_clone): Likewise. + * ov-fcn.cc (octave_function::empty_clone): Likewise. + * ov-file.h (octave_file::empty_clone): Likewise. + * ov-range.h (octave_range::empty_clone): Likewise. + * ov-list.h (octave_list::empty_clone): Likewise. + * ov-re-mat.h (octave_matrix::empty_clone): Likewise. + * ov-re-nd-array.h (octave_double_nd_array::empty_clone): Likewise. + * ov-str-mat.h (octave_char_matrix_str::empty_clone): Likewise. + * ov-struct.h (octave_struct::empty_clone): Likewise. + * ov-va_args.h (octave_all_va_args::empty_clone): Likewise. + * ov.h (octave_value::empty_clone): Likewise. + + * ov-base-mat.h (octave_base_matrix::clone): Now const. + * ov-base-nd-array.h (octave_base_nd_array::clone): Likewise. + * ov-base.h (octave_base_value::clone): Likewise. + * ov-bool-mat.h (octave_bool::clone): Likewise. + * ov-ch-mat.h (octave_char_matrix::clone): Likewise. + * ov-colon.h (octave_magic_colon::clone): Likewise. + * ov-complex.h (octave_complex::clone): Likewise. + * ov-cx-mat.h (octave_complex_matrix::clone): Likewise. + * ov-fcn.h (octave_function::clone): Likewise. + * ov-file.h (octave_file::clone): Likewise. + * ov-range.h (octave_range::clone): Likewise. + * ov-list.h (octave_list::clone): Likewise. + * ov-re-mat.h (octave_matrix::clone): Likewise. + * ov-re-nd-array.h (octave_double_nd_array::clone): Likewise. + * ov-str-mat.h (octave_char_matrix_str::clone): Likewise. + * ov-struct.h (octave_struct::clone): Likewise. + * ov-va_args.h (octave_all_va_args::clone): Likewise. + * ov.h (octave_value::clone): Likewise. + + * oct-lvalue.cc (octave_lvalue::assign, octave_lvalue::set_index, + octave_lvalue::do_unary_op): Idx is now a list of indices. Simplify. + * oct-lvalue.h (octave_lvalue::value): Simplify. + (octave_lvalue::struct_elt_names): Delete data member. + (octave_lvalue::type): Now string + Update decls. + + * pt-exp.h (tree_expression::is_indirect_ref): + Delete virtual function. + + * pt-plot.cc (subplot::extract_plot_data): Use subsref, instead of + do_index_op. + + * pt-stmt.cc (tree_statement::eval): Don't try to avoid binding + ans for structure references. + + * symtab.cc (symbol_record::symbol_def::print_info): Rename from + symbol_record::symbol_def::dump_symbol_info. + (symbol_record::print_info): Rename from + symbol_record::dump_symbol_info. Now const.. + (symbol_record::print_symbol_info_line): Now const. + (symbol_table::print_info): Rename from print_stats. Accept + ostream arg. Now const. Print more info. + * symtab.h: Update decls. + + * toplev.cc (octave_config_info): Indexing a map now returns a + list, but we only want to return the first element. + + * variables.cc (generate_struct_completions, looks_like_struct): + Simplify using eval_string. + (F__print_symtab_info__): Rename from F__dump_symtab_info__. + Handle "top-level" and individual function names in addition to + "global". + (F__print_symbol_info__): Rename from F___dump_symbol_info__. + + * octave.cc (intern_argv): Built-in variable argv is now a cell array. + + * ov-complex.cc (valid_scalar_indices): Delete. + * ov-scalar.cc (valid_scalar_indices): Delete. + + * oct-obj.cc (octave_value_list::valid_scalar_indices): New function. + (octave_value_list::index): New arg, resize_ok. + * oct-obj.h: Provide decls. + + * oct-map.cc (Octave_map::keys): Rename from make_name_list. + Change all uses. + (Octave_map::assign, Octave_map::index): New functions. + * oct-map.h: Provide decls. + + * data.cc (Fstruct_contains): Use map_value instead of + do_struct_elt_index_op. + + * Cell.h (Cell (const Array2&, int, int)): + New constructor. + (Cell::resize_fill_value): New static function. + + * input.cc (initialize_command_input): Set basic and completer + word break characters. + 2002-05-07 John W. Eaton + * ov.h (octave_value::subsref): New function. + * ov-base.cc (octave_base_value::subsref): Likewise. + * ov-struct.cc (octave_struct::print_raw): Print scalar struct arrays more compactly. @@ -12,7 +217,6 @@ (Octave_map::array_length): New fucntion. * oct-obj.cc (octave_value_list::assign): New function. - 2002-05-06 John W. Eaton * TEMPLATE-INST/Map-oct-obj.cc: New file. diff --git a/src/Map.h b/src/Map.h --- a/src/Map.h +++ b/src/Map.h @@ -75,7 +75,7 @@ virtual void clear (void); // delete all items virtual C& operator [] (const std::string& key) = 0; // access contents by key - + virtual void del (const std::string& key) = 0; // delete entry virtual Pix first (void) const = 0; // Pix of first item or 0 diff --git a/src/data.cc b/src/data.cc --- a/src/data.cc +++ b/src/data.cc @@ -849,7 +849,7 @@ if (args (0).is_map ()) { Octave_map m = args(0).map_value (); - retval(0) = m.make_name_list (); + retval(0) = m.keys (); } else gripe_wrong_type_arg ("struct_elements", args (0)); @@ -881,9 +881,11 @@ if (args(0).is_map () && args(1).is_string ()) { - std::string s = args(1).string_value (); - octave_value tmp = args(0).do_struct_elt_index_op (s, true); - retval = static_cast (tmp.is_defined ()); + std::string key = args(1).string_value (); + + Octave_map m = args(0).map_value (); + + retval = static_cast (m.contains (key)); } else print_usage ("struct_contains"); diff --git a/src/input.cc b/src/input.cc --- a/src/input.cc +++ b/src/input.cc @@ -476,6 +476,15 @@ command_editor::set_name ("Octave"); + // XX FIXME XXX -- this needs to include a comma too, but that + // causes trouble for the new struct element completion code. + + static char *s = "\t\n !\"\'*+-/:;<=>[\\]^`~"; + + command_editor::set_basic_word_break_characters (s); + + command_editor::set_completer_word_break_characters (s); + command_editor::set_basic_quote_characters ("\""); command_editor::set_completion_function (generate_completion); diff --git a/src/oct-lvalue.cc b/src/oct-lvalue.cc --- a/src/oct-lvalue.cc +++ b/src/oct-lvalue.cc @@ -32,38 +32,22 @@ void octave_lvalue::assign (octave_value::assign_op op, const octave_value& rhs) { - octave_value saved_val; - - if (chg_fcn) - saved_val = *val; + octave_value tmp (idx.empty () + ? val->assign (op, rhs) + : val->assign (op, type, idx, rhs)); - if (idx.empty ()) - { - if (struct_elt_name.empty ()) - val->assign (op, rhs); - else - val->assign_struct_elt (op, struct_elt_name, rhs); - } - else - { - if (struct_elt_name.empty ()) - val->assign (op, idx, rhs); - else - val->assign_struct_elt (op, struct_elt_name, idx, rhs); - } - - if (chg_fcn && ! error_state && chg_fcn () < 0) - *val = saved_val; + if (! (error_state || chg_fcn && chg_fcn () < 0)) + *val = tmp; } void -octave_lvalue::set_index (const octave_value_list& i, - tree_index_expression::type t) +octave_lvalue::set_index (const std::string& t, + const SLList& i) { if (! index_set) { + type = t; idx = i; - itype = t; index_set = true; } else @@ -73,18 +57,12 @@ void octave_lvalue::do_unary_op (octave_value::unary_op op) { - octave_value saved_val; - - if (chg_fcn) - saved_val = *val; + octave_value tmp (idx.empty () + ? val->do_non_const_unary_op (op) + : val->do_non_const_unary_op (op, type, idx)); - if (idx.empty ()) - val->do_non_const_unary_op (op); - else - val->do_non_const_unary_op (op, idx); - - if (chg_fcn && ! error_state && chg_fcn () < 0) - *val = saved_val; + if (! (error_state || chg_fcn && chg_fcn () < 0)) + *val = tmp; } /* diff --git a/src/oct-lvalue.h b/src/oct-lvalue.h --- a/src/oct-lvalue.h +++ b/src/oct-lvalue.h @@ -28,6 +28,8 @@ #include +#include "SLList.h" + #include "oct-obj.h" #include "pt-idx.h" #include "symtab.h" @@ -44,25 +46,20 @@ octave_lvalue (octave_value *v = &dummy_val, symbol_record::change_function f = 0) - : val (v), idx (), chg_fcn (f), struct_elt_name (), index_set (false) { } - - octave_lvalue (octave_value *v, const std::string& nm, - symbol_record::change_function f = 0) - : val (v), idx (), chg_fcn (f), struct_elt_name (nm), index_set (false) { } + : val (v), type (), idx (), chg_fcn (f), index_set (false) { } octave_lvalue (const octave_lvalue& vr) - : val (vr.val), idx (vr.idx), itype (vr.itype), chg_fcn (vr.chg_fcn), - struct_elt_name (vr.struct_elt_name), index_set (vr.index_set) { } + : val (vr.val), type (vr.type), idx (vr.idx), chg_fcn (vr.chg_fcn), + index_set (vr.index_set) { } octave_lvalue& operator = (const octave_lvalue& vr) { if (this != &vr) { val = vr.val; + type = vr.type; idx = vr.idx; - itype = vr.itype; chg_fcn = vr.chg_fcn; - struct_elt_name = vr.struct_elt_name; index_set = vr.index_set; } @@ -81,43 +78,25 @@ void assign (octave_value::assign_op, const octave_value&); - octave_lvalue struct_elt_ref (const std::string& nm) - { - val->make_unique (); - return val->struct_elt_ref (nm); - } + void set_index (const std::string& t, const SLList& i); - void set_index (const octave_value_list& i, - tree_index_expression::type t - = tree_index_expression::unknown); - - void clear_index (void) { idx = octave_value_list (); } + void clear_index (void) { type = std::string (); idx.clear (); } void do_unary_op (octave_value::unary_op op); octave_value value (void) - { - return struct_elt_name.empty () - ? (idx.empty () - ? *val - : val->do_index_op (idx)) - : (idx.empty () - ? val->do_struct_elt_index_op (struct_elt_name) - : val->do_struct_elt_index_op (struct_elt_name, idx)); - } + { return idx.empty () ? *val : val->subsref (type, idx); } private: octave_value *val; - octave_value_list idx; + std::string type; - tree_index_expression::type itype; + SLList idx; symbol_record::change_function chg_fcn; - std::string struct_elt_name; - bool index_set; }; diff --git a/src/oct-map.cc b/src/oct-map.cc --- a/src/oct-map.cc +++ b/src/oct-map.cc @@ -35,7 +35,7 @@ #include "utils.h" string_vector -Octave_map::make_name_list (void) +Octave_map::keys (void) const { int len = length (); @@ -87,6 +87,42 @@ return *this; } +Octave_map& +Octave_map::assign (const std::string& key, const octave_value_list& rhs) +{ + if (map.empty ()) + map[key] = rhs; + else + { + octave_value_list tmp = map.contents (map.first ()); + + if (tmp.length () == rhs.length ()) + map[key] = rhs; + else + error ("invalid structure assignment"); + } + + return *this; +} + +Octave_map +Octave_map::index (idx_vector& idx) +{ + Octave_map retval; + + for (Pix p = first (); p != 0; next (p)) + { + octave_value_list tmp = contents(p).index (idx); + + if (error_state) + break; + + retval[key(p)] = tmp; + } + + return error_state ? Octave_map () : retval; +} + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/src/oct-map.h b/src/oct-map.h --- a/src/oct-map.h +++ b/src/oct-map.h @@ -82,13 +82,17 @@ void clear (void) { map.clear (); } - string_vector make_name_list (void); + string_vector keys (void) const; int array_length () const; Octave_map& assign (const idx_vector& idx, const std::string& key, const octave_value_list& rhs); + Octave_map& assign (const std::string& key, const octave_value_list& rhs); + + Octave_map index (idx_vector& idx); + private: // The map of names to values. diff --git a/src/oct-obj.cc b/src/oct-obj.cc --- a/src/oct-obj.cc +++ b/src/oct-obj.cc @@ -34,6 +34,18 @@ octave_allocator octave_value_list::allocator (sizeof (octave_value_list)); +bool +octave_value_list::valid_scalar_indices (void) const +{ + int n = data.length (); + + for (int i = 0; i < n; i++) + if (! data(i).valid_as_scalar_index ()) + return false; + + return true; +} + octave_value_list& octave_value_list::prepend (const octave_value& val) { @@ -137,9 +149,9 @@ } octave_value_list -octave_value_list::index (idx_vector& i) const +octave_value_list::index (idx_vector& i, int resize_ok) const { - return octave_value_list (data.index (i)); + return octave_value_list (data.index (i, resize_ok, octave_value ())); } octave_value_list& diff --git a/src/oct-obj.h b/src/oct-obj.h --- a/src/oct-obj.h +++ b/src/oct-obj.h @@ -111,6 +111,8 @@ return *this; } + bool valid_scalar_indices (void) const; + // Assignment will resize on range errors. octave_value& operator () (int n) { return elem (n); } @@ -136,7 +138,7 @@ octave_value_list splice (int offset, int length, const octave_value_list& lst) const; - octave_value_list index (idx_vector& i) const; + octave_value_list index (idx_vector& i, int resize_ok = 0) const; octave_value_list& assign (const idx_vector& i, const octave_value_list& rhs); diff --git a/src/octave.cc b/src/octave.cc --- a/src/octave.cc +++ b/src/octave.cc @@ -51,6 +51,7 @@ #include "str-vec.h" #include +#include "Cell.h" #include "defun.h" #include "error.h" #include "file-io.h" @@ -159,14 +160,18 @@ bind_builtin_variable ("nargin", static_cast (argc-1), true, true, 0); - octave_value_list octave_argv; + Cell octave_argv; if (argc > 1) { + Array tmp (argc-1); + // Skip program name in argv. - while (--argc > 0) - octave_argv(argc-1) = octave_value (*(argv+argc)); + int i = argc; + while (--i > 0) + tmp(i-1) = octave_value (*(argv+i)); + octave_argv = Cell (tmp, argc-1, 1); } bind_builtin_constant ("argv", octave_argv, true, true); diff --git a/src/ov-base-mat.cc b/src/ov-base-mat.cc --- a/src/ov-base-mat.cc +++ b/src/ov-base-mat.cc @@ -30,14 +30,83 @@ #include +#include "Cell.h" #include "oct-obj.h" +#include "oct-map.h" #include "ov-base.h" #include "ov-base-mat.h" #include "pr-output.h" template octave_value -octave_base_matrix::do_index_op (const octave_value_list& idx) +octave_base_matrix::subsref (const std::string type, + const SLList& idx) +{ + octave_value retval; + + switch (type[0]) + { + case '(': + retval = do_index_op (idx.front ()); + break; + + case '{': + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + + return retval.next_subsref (type, idx); +} + +template +octave_value +octave_base_matrix::subsasgn (const std::string type, + const SLList& idx, + const octave_value& rhs) +{ + octave_value retval; + + switch (type[0]) + { + case '(': + { + if (type.length () == 1) + retval = numeric_assign (type, idx, rhs); + else + { + std::string nm = type_name (); + error ("in indexed assignment of %s, last rhs index must be ()", + nm.c_str ()); + } + } + break; + + case '{': + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + + return retval; +} + +template +octave_value +octave_base_matrix::do_index_op (const octave_value_list& idx, + int resize_ok) { octave_value retval; @@ -50,7 +119,7 @@ idx_vector i = idx (0).index_vector (); idx_vector j = idx (1).index_vector (); - retval = MT (matrix.index (i, j)); + retval = MT (matrix.index (i, j, resize_ok, MT::resize_fill_value ())); } break; @@ -58,7 +127,7 @@ { idx_vector i = idx (0).index_vector (); - retval = MT (matrix.index (i)); + retval = MT (matrix.index (i, resize_ok, MT::resize_fill_value ())); } break; @@ -162,7 +231,8 @@ template void -octave_base_matrix::print_raw (std::ostream& os, bool pr_as_read_syntax) const +octave_base_matrix::print_raw (std::ostream& os, + bool pr_as_read_syntax) const { octave_print_internal (os, matrix, pr_as_read_syntax, current_print_indent_level ()); @@ -170,7 +240,8 @@ template bool -octave_base_matrix::print_name_tag (std::ostream& os, const std::string& name) const +octave_base_matrix::print_name_tag (std::ostream& os, + const std::string& name) const { bool retval = false; @@ -189,6 +260,14 @@ return retval; } +template +void +octave_base_matrix::print_info (std::ostream& os, + const std::string& prefix) const +{ + matrix.print_info (os, prefix); +} + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/src/ov-base-mat.h b/src/ov-base-mat.h --- a/src/ov-base-mat.h +++ b/src/ov-base-mat.h @@ -63,9 +63,20 @@ ~octave_base_matrix (void) { } - octave_value *clone (void) { return new octave_base_matrix (*this); } + octave_value *clone (void) const { return new octave_base_matrix (*this); } + octave_value *empty_clone (void) const { return new octave_base_matrix (); } + + octave_value subsref (const std::string type, + const SLList& idx); - octave_value do_index_op (const octave_value_list& idx); + octave_value subsasgn (const std::string type, + const SLList& idx, + const octave_value& rhs); + + octave_value do_index_op (const octave_value_list& idx, int resize_ok); + + octave_value do_index_op (const octave_value_list& idx) + { return do_index_op (idx, 0); } void assign (const octave_value_list& idx, const MT& rhs); @@ -101,6 +112,8 @@ bool print_name_tag (std::ostream& os, const std::string& name) const; + void print_info (std::ostream& os, const std::string& prefix) const; + protected: MT matrix; diff --git a/src/ov-base-nd-array.cc b/src/ov-base-nd-array.cc --- a/src/ov-base-nd-array.cc +++ b/src/ov-base-nd-array.cc @@ -50,7 +50,8 @@ template octave_value -octave_base_nd_array::do_index_op (const octave_value_list& idx) +octave_base_nd_array::do_index_op (const octave_value_list& idx, + int resize_ok) { octave_value retval; @@ -61,14 +62,14 @@ Array i = idx_list_to_idx_array (idx); retval - = octave_value (new octave_base_nd_array (AT (array.index (i)))); + = octave_value (new octave_base_nd_array (AT (array.index (i, resize_ok)))); } else if (len == 1) { idx_vector i = idx(0).index_vector (); retval - = octave_value (new octave_base_nd_array (AT (array.index (i)))); + = octave_value (new octave_base_nd_array (AT (array.index (i, resize_ok)))); } else { diff --git a/src/ov-base-nd-array.h b/src/ov-base-nd-array.h --- a/src/ov-base-nd-array.h +++ b/src/ov-base-nd-array.h @@ -63,9 +63,10 @@ ~octave_base_nd_array (void) { } - octave_value *clone (void) { return new octave_base_nd_array (*this); } + octave_value *clone (void) const { return new octave_base_nd_array (*this); } + octave_value *empty_clone (void) const { return new octave_base_nd_array (); } - octave_value do_index_op (const octave_value_list& idx); + octave_value do_index_op (const octave_value_list& idx, int resize_ok); bool is_matrix_type (void) const { return false; } diff --git a/src/ov-base-scalar.cc b/src/ov-base-scalar.cc --- a/src/ov-base-scalar.cc +++ b/src/ov-base-scalar.cc @@ -31,10 +31,85 @@ #include #include "ov-base.h" +#include "ov-cx-mat.h" +#include "ov-re-mat.h" #include "ov-base-scalar.h" #include "pr-output.h" template +octave_value +octave_base_scalar::subsref (const std::string type, + const SLList& idx) +{ + octave_value retval; + + switch (type[0]) + { + case '(': + retval = do_index_op (idx.front ()); + break; + + case '{': + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + + return retval.next_subsref (type, idx); +} + +template +octave_value +octave_base_scalar::subsasgn (const std::string type, + const SLList& idx, + const octave_value& rhs) +{ + octave_value retval; + + switch (type[0]) + { + case '(': + { + if (type.length () == 1) + { + if (idx.front().valid_scalar_indices () + && rhs.is_scalar_type () + && rhs.is_numeric_type ()) + retval = rhs; + else + retval = numeric_assign (type, idx, rhs); + } + else + { + std::string nm = type_name (); + error ("in indexed assignment of %s, last rhs index must be ()", + nm.c_str ()); + } + } + break; + + case '{': + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + + return retval; +} + +template void octave_base_scalar::print (std::ostream& os, bool pr_as_read_syntax) const { @@ -44,7 +119,8 @@ template void -octave_base_scalar::print_raw (std::ostream& os, bool pr_as_read_syntax) const +octave_base_scalar::print_raw (std::ostream& os, + bool pr_as_read_syntax) const { indent (os); octave_print_internal (os, scalar, pr_as_read_syntax); @@ -52,7 +128,8 @@ template bool -octave_base_scalar::print_name_tag (std::ostream& os, const std::string& name) const +octave_base_scalar::print_name_tag (std::ostream& os, + const std::string& name) const { indent (os); os << name << " = "; diff --git a/src/ov-base-scalar.h b/src/ov-base-scalar.h --- a/src/ov-base-scalar.h +++ b/src/ov-base-scalar.h @@ -59,6 +59,13 @@ ~octave_base_scalar (void) { } + octave_value subsref (const std::string type, + const SLList& idx); + + octave_value subsasgn (const std::string type, + const SLList& idx, + const octave_value& rhs); + int rows (void) const { return 1; } int columns (void) const { return 1; } diff --git a/src/ov-base.cc b/src/ov-base.cc --- a/src/ov-base.cc +++ b/src/ov-base.cc @@ -53,7 +53,25 @@ DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_base_value, ""); octave_value -octave_base_value::do_index_op (const octave_value_list&) +octave_base_value::subsref (const std::string, + const SLList&) +{ + std::string nm = type_name (); + error ("can't perform indexing operations for %s type", nm.c_str ()); + return octave_value (); +} + +octave_value_list +octave_base_value::subsref (const std::string, + const SLList&, int) +{ + std::string nm = type_name (); + error ("can't perform indexing operations for %s type", nm.c_str ()); + return octave_value (); +} + +octave_value +octave_base_value::do_index_op (const octave_value_list&, int) { std::string nm = type_name (); error ("can't perform indexing operations for %s type", nm.c_str ()); @@ -77,32 +95,28 @@ } octave_value -octave_base_value::do_struct_elt_index_op (const std::string&, - const octave_value_list&, - bool) -{ - std::string nm = type_name (); - error ("can't perform indexed structure reference operations for %s type", - nm.c_str ()); - return octave_value (); -} - -octave_value -octave_base_value::do_struct_elt_index_op (const std::string&, bool) +octave_base_value::subsasgn (const std::string type, + const SLList& idx, + const octave_value& rhs) { - std::string nm = type_name (); - error ("can't perform structure reference operations for %s type", - nm.c_str ()); - return octave_value (); -} + octave_value retval; -octave_lvalue -octave_base_value::struct_elt_ref (octave_value *, const std::string&) -{ - std::string nm = type_name (); - error ("can't perform structure reference operations for %s type", - nm.c_str ()); - return octave_lvalue (); + if (is_defined ()) + { + std::string nm = type_name (); + error ("can't perform indexed assignment for %s type", nm.c_str ()); + } + else + { + // Create new object of appropriate type for given index and rhs + // types and then call subsasgn again for that object. + + octave_value tmp = octave_value::empty_conv (type, rhs); + + retval = tmp.subsasgn (type, idx, rhs); + } + + return retval; } octave_value @@ -143,6 +157,13 @@ return true; } +void +octave_base_value::print_info (std::ostream& os, + const std::string& prefix) const +{ + os << "no info for type: " << type_name () << "\n"; +} + int octave_base_value::int_value (bool require_int, bool frc_str_conv) const { @@ -271,6 +292,14 @@ return retval; } +string_vector +octave_base_value::map_keys (void) const +{ + string_vector retval; + gripe_wrong_type_arg ("octave_base_value::map_keys()", type_name ()); + return retval; +} + octave_stream octave_base_value::stream_value (void) const { diff --git a/src/ov-base.h b/src/ov-base.h --- a/src/ov-base.h +++ b/src/ov-base.h @@ -62,7 +62,8 @@ ~octave_base_value (void) { } - octave_value *clone (void) { return new octave_base_value (*this); } + octave_value *clone (void) const { return new octave_base_value (*this); } + octave_value *empty_clone (void) const { return new octave_base_value (); } type_conv_fcn numeric_conversion_function (void) const { return static_cast (0); } @@ -70,20 +71,26 @@ octave_value *try_narrowing_conversion (void) { return static_cast (0); } - octave_value do_index_op (const octave_value_list& idx); + octave_value subsref (const std::string type, + const SLList& idx); + + octave_value_list subsref (const std::string type, + const SLList& idx, + int nargout); + + octave_value do_index_op (const octave_value_list& idx, int resize_ok); + + octave_value do_index_op (const octave_value_list& idx) + { return do_index_op (idx, 0); } octave_value_list do_multi_index_op (int nargout, const octave_value_list& idx); idx_vector index_vector (void) const; - octave_value - do_struct_elt_index_op (const std::string& nm, const octave_value_list& idx, - bool silent); - - octave_value do_struct_elt_index_op (const std::string& nm, bool silent); - - octave_lvalue struct_elt_ref (octave_value *parent, const std::string& nm); + octave_value subsasgn (const std::string type, + const SLList& idx, + const octave_value& rhs); int rows (void) const { return -1; } @@ -184,6 +191,8 @@ Octave_map map_value (void) const; + string_vector map_keys (void) const; + octave_stream stream_value (void) const; int stream_number (void) const; @@ -206,6 +215,8 @@ bool print_name_tag (std::ostream& os, const std::string& name) const; + void print_info (std::ostream& os, const std::string& prefix) const; + private: DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA diff --git a/src/ov-bool-mat.h b/src/ov-bool-mat.h --- a/src/ov-bool-mat.h +++ b/src/ov-bool-mat.h @@ -66,7 +66,8 @@ ~octave_bool_matrix (void) { } - octave_value *clone (void) { return new octave_bool_matrix (*this); } + octave_value *clone (void) const { return new octave_bool_matrix (*this); } + octave_value *empty_clone (void) const { return new octave_bool_matrix (); } type_conv_fcn numeric_conversion_function (void) const; diff --git a/src/ov-bool.cc b/src/ov-bool.cc --- a/src/ov-bool.cc +++ b/src/ov-bool.cc @@ -76,7 +76,7 @@ } octave_value -octave_bool::do_index_op (const octave_value_list& idx) +octave_bool::do_index_op (const octave_value_list& idx, int resize_ok) { octave_value retval; @@ -96,7 +96,7 @@ octave_value tmp (new octave_matrix (matrix_value ())); - retval = tmp.do_index_op (idx); + retval = tmp.do_index_op (idx, resize_ok); } return retval; diff --git a/src/ov-bool.h b/src/ov-bool.h --- a/src/ov-bool.h +++ b/src/ov-bool.h @@ -64,11 +64,12 @@ ~octave_bool (void) { } - octave_value *clone (void) { return new octave_bool (*this); } + octave_value *clone (void) const { return new octave_bool (*this); } + octave_value *empty_clone (void) const { return new octave_bool (); } type_conv_fcn numeric_conversion_function (void) const; - octave_value do_index_op (const octave_value_list& idx); + octave_value do_index_op (const octave_value_list& idx, int resize_ok); idx_vector index_vector (void) const { return idx_vector (scalar); } diff --git a/src/ov-builtin.cc b/src/ov-builtin.cc --- a/src/ov-builtin.cc +++ b/src/ov-builtin.cc @@ -52,6 +52,37 @@ } octave_value_list +octave_builtin::subsref (const std::string type, + const SLList& idx, + int nargout) +{ + octave_value_list retval; + + switch (type[0]) + { + case '(': + retval = do_multi_index_op (nargout, idx.front ()); + break; + + case '{': + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + + return retval; + + // XXX FIXME XXX + // return retval.next_subsref (type, idx); +} + +octave_value_list octave_builtin::do_multi_index_op (int nargout, const octave_value_list& args) { octave_value_list retval; diff --git a/src/ov-builtin.h b/src/ov-builtin.h --- a/src/ov-builtin.h +++ b/src/ov-builtin.h @@ -50,6 +50,10 @@ ~octave_builtin (void) { } + octave_value_list subsref (const std::string type, + const SLList& idx, + int nargout); + octave_function *function_value (bool) { return this; } bool is_builtin_function (void) const { return true; } diff --git a/src/ov-cell.cc b/src/ov-cell.cc --- a/src/ov-cell.cc +++ b/src/ov-cell.cc @@ -50,6 +50,160 @@ DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_cell, "cell"); +octave_value +octave_cell::subsref (const std::string type, + const SLList& idx) +{ + octave_value retval; + + switch (type[0]) + { + case '(': + retval = do_index_op (idx.front ()); + break; + + case '{': + { + octave_value tmp = do_index_op (idx.front ()); + + Cell tcell = tmp.cell_value (); + + if (tcell.length () == 1) + retval = tcell(0,0); + else + { + int nr = tcell.rows (); + int nc = tcell.columns (); + octave_value_list lst (nr * nc, octave_value ()); + int k = 0; + for (int j = 0; j < nc; j++) + for (int i = 0; i < nr; i++) + lst(k++) = tcell(i,j); + retval = lst; + } + } + break; + + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + + return retval.next_subsref (type, idx); +} + +octave_value +octave_cell::subsasgn (const std::string type, + const SLList& idx, + const octave_value& rhs) +{ + octave_value retval; + + int n = type.length (); + + octave_value t_rhs = rhs; + + if (n > 1) + { + switch (type[0]) + { + case '(': + { + octave_value tmp = do_index_op (idx.front (), true); + + if (! tmp.is_defined ()) + tmp = octave_value::empty_conv (type.substr (1), rhs); + + if (! error_state) + { + SLList next_idx (idx); + + next_idx.remove_front (); + + t_rhs = tmp.subsasgn (type.substr (1), next_idx, rhs); + } + } + break; + + case '{': + { + octave_value tmp = do_index_op (idx.front (), true); + + if (! tmp.is_defined ()) + tmp = octave_value::empty_conv (type.substr (1), rhs); + + Cell tcell = tmp.cell_value (); + + if (! error_state && tcell.length () == 1) + { + tmp = tcell(0,0); + + SLList next_idx (idx); + + next_idx.remove_front (); + + t_rhs = tmp.subsasgn (type.substr (1), next_idx, rhs); + } + } + break; + + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + } + + switch (type[0]) + { + case '(': + { + octave_value_list i = idx.front (); + + if (t_rhs.is_cell ()) + octave_base_matrix::assign (i, t_rhs.cell_value ()); + else + octave_base_matrix::assign (i, Cell (t_rhs)); + + retval = octave_value (this, count + 1); + } + break; + + case '{': + { + octave_value_list i = idx.front (); + + octave_base_matrix::assign (i, Cell (t_rhs)); + + retval = octave_value (this, count + 1); + } + break; + + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + + return retval; +} + void octave_cell::assign (const octave_value_list& idx, const octave_value& rhs) { @@ -59,6 +213,89 @@ octave_base_matrix::assign (idx, Cell (rhs)); } +octave_value_list +octave_cell::list_value (void) const +{ + octave_value_list retval; + + int nr = rows (); + int nc = columns (); + + if (nr == 1 && nc > 0) + { + retval.resize (nc); + + for (int i = 0; i < nc; i++) + retval(i) = matrix(0,i); + } + else if (nc == 1 && nr > 0) + { + retval.resize (nr); + + for (int i = 0; i < nr; i++) + retval(i) = matrix(i,0); + } + else + error ("invalid conversion from cell array to list"); + + return retval; +} + +void +octave_cell::print (std::ostream& os, bool) const +{ + print_raw (os); +} + +void +octave_cell::print_raw (std::ostream& os, bool) const +{ + int nr = rows (); + int nc = columns (); + + if (nr > 0 && nc > 0) + { + indent (os); + os << "{"; + newline (os); + + increment_indent_level (); + + for (int j = 0; j < nc; j++) + { + for (int i = 0; i < nr; i++) + { + std::ostrstream buf; + buf << "[" << i+1 << "," << j+1 << "]" << std::ends; + const char *nm = buf.str (); + + octave_value val = matrix(i,j); + + val.print_with_name (os, nm); + + delete [] nm; + } + } + + decrement_indent_level (); + + indent (os); + os << "}"; + newline (os); + } + else + os << "{}"; +} + +bool +octave_cell::print_name_tag (std::ostream& os, const std::string& name) const +{ + indent (os); + os << name << " ="; + newline (os); + return false; +} + DEFUN (iscell, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} iscell (@var{x})\n\ diff --git a/src/ov-cell.h b/src/ov-cell.h --- a/src/ov-cell.h +++ b/src/ov-cell.h @@ -66,18 +66,34 @@ void assign (const octave_value_list& idx, const octave_value& rhs); - octave_value *clone (void) { return new octave_cell (*this); } + octave_value *clone (void) const { return new octave_cell (*this); } + octave_value *empty_clone (void) const { return new octave_cell (); } #if 0 octave_value *try_narrowing_conversion (void); #endif + octave_value subsref (const std::string type, + const SLList& idx); + + octave_value subsasgn (const std::string type, + const SLList& idx, + const octave_value& rhs); + bool is_defined (void) const { return true; } bool is_cell (void) const { return true; } Cell cell_value (void) const { return matrix; } + octave_value_list list_value (void) const; + + void print (std::ostream& os, bool pr_as_read_syntax = false) const; + + void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const; + + bool print_name_tag (std::ostream& os, const std::string& name) const; + private: DECLARE_OCTAVE_ALLOCATOR diff --git a/src/ov-ch-mat.h b/src/ov-ch-mat.h --- a/src/ov-ch-mat.h +++ b/src/ov-ch-mat.h @@ -76,7 +76,8 @@ ~octave_char_matrix (void) { } - octave_value *clone (void) { return new octave_char_matrix (*this); } + octave_value *clone (void) const { return new octave_char_matrix (*this); } + octave_value *empty_clone (void) const { return new octave_char_matrix (); } bool is_char_matrix (void) const { return true; } bool is_real_matrix (void) const { return true; } diff --git a/src/ov-colon.h b/src/ov-colon.h --- a/src/ov-colon.h +++ b/src/ov-colon.h @@ -55,7 +55,8 @@ ~octave_magic_colon (void) { } - octave_value *clone (void) { return new octave_magic_colon (*this); } + octave_value *clone (void) const { return new octave_magic_colon (*this); } + octave_value *empty_clone (void) const { return new octave_magic_colon (); } idx_vector index_vector (void) const { return idx_vector (':'); } diff --git a/src/ov-complex.cc b/src/ov-complex.cc --- a/src/ov-complex.cc +++ b/src/ov-complex.cc @@ -60,24 +60,12 @@ return retval; } -static inline bool -valid_scalar_indices (const octave_value_list& args) -{ - int nargin = args.length (); - - for (int i = 0; i < nargin; i++) - if (! args(i).valid_as_scalar_index ()) - return false; - - return true; -} - octave_value -octave_complex::do_index_op (const octave_value_list& idx) +octave_complex::do_index_op (const octave_value_list& idx, int resize_ok) { octave_value retval; - if (valid_scalar_indices (idx)) + if (idx.valid_scalar_indices ()) retval = scalar; else { @@ -93,7 +81,7 @@ octave_value tmp (new octave_complex_matrix (complex_matrix_value ())); - retval = tmp.do_index_op (idx); + retval = tmp.do_index_op (idx, resize_ok); } return retval; diff --git a/src/ov-complex.h b/src/ov-complex.h --- a/src/ov-complex.h +++ b/src/ov-complex.h @@ -64,11 +64,12 @@ ~octave_complex (void) { } - octave_value *clone (void) { return new octave_complex (*this); } + octave_value *clone (void) const { return new octave_complex (*this); } + octave_value *empty_clone (void) const { return new octave_complex (); } octave_value *try_narrowing_conversion (void); - octave_value do_index_op (const octave_value_list& idx); + octave_value do_index_op (const octave_value_list& idx, int resize_ok); bool is_complex_scalar (void) const { return true; } diff --git a/src/ov-cx-mat.h b/src/ov-cx-mat.h --- a/src/ov-cx-mat.h +++ b/src/ov-cx-mat.h @@ -73,7 +73,8 @@ ~octave_complex_matrix (void) { } - octave_value *clone (void) { return new octave_complex_matrix (*this); } + octave_value *clone (void) const { return new octave_complex_matrix (*this); } + octave_value *empty_clone (void) const { return new octave_complex_matrix (); } octave_value *try_narrowing_conversion (void); diff --git a/src/ov-fcn.cc b/src/ov-fcn.cc --- a/src/ov-fcn.cc +++ b/src/ov-fcn.cc @@ -34,7 +34,14 @@ DEFINE_OCTAVE_ALLOCATOR (octave_function); octave_function * -octave_function::clone (void) +octave_function::clone (void) const +{ + panic_impossible (); + return 0; +} + +octave_function * +octave_function::empty_clone (void) const { panic_impossible (); return 0; diff --git a/src/ov-fcn.h b/src/ov-fcn.h --- a/src/ov-fcn.h +++ b/src/ov-fcn.h @@ -50,9 +50,8 @@ ~octave_function (void) { } - // This should only be called for derived types. - - octave_function *clone (void); + octave_function *clone (void) const; + octave_function *empty_clone (void) const; bool is_defined (void) const { return true; } diff --git a/src/ov-file.h b/src/ov-file.h --- a/src/ov-file.h +++ b/src/ov-file.h @@ -60,7 +60,8 @@ ~octave_file (void) { } - octave_value *clone (void) { return new octave_file (*this); } + octave_value *clone (void) const { return new octave_file (*this); } + octave_value *empty_clone (void) const { return new octave_file (); } type_conv_fcn numeric_conversion_function (void) const; diff --git a/src/ov-list.cc b/src/ov-list.cc --- a/src/ov-list.cc +++ b/src/ov-list.cc @@ -43,7 +43,62 @@ DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_list, "list"); octave_value -octave_list::do_index_op (const octave_value_list& idx) +octave_list::subsref (const std::string type, + const SLList& idx) +{ + octave_value retval; + + switch (type[0]) + { + case '(': + { + octave_value_list tmp_idx = idx.front (); + + if (tmp_idx.length () == 1) + { + idx_vector i = tmp_idx (0).index_vector (); + + retval = octave_value_list (lst.index (i)); + } + else + error ("only one index allowed for lists"); + } + break; + + case '{': + { + octave_value_list tmp_idx = idx.front (); + + if (tmp_idx.length () == 1) + { + idx_vector i = tmp_idx (0).index_vector (); + + octave_value_list tmp = lst.index (i); + + if (tmp.length () == 1) + retval = tmp(0); + } + else + error ("only one index allowed for lists"); + } + break; + + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + + return retval.next_subsref (type, idx); +} + +octave_value +octave_list::do_index_op (const octave_value_list& idx, int resize_ok) { octave_value retval; @@ -51,7 +106,7 @@ { idx_vector i = idx (0).index_vector (); - retval = octave_value_list (lst.index (i)); + retval = octave_value_list (lst.index (i, resize_ok)); } else error ("lists may only be indexed by a single scalar"); @@ -59,6 +114,79 @@ return retval; } +octave_value +octave_list::subsasgn (const std::string type, + const SLList& idx, + const octave_value& rhs) +{ + octave_value retval; + + int n = type.length (); + + octave_value t_rhs = rhs; + + if (n > 1) + { + switch (type[0]) + { + case '(': + { + octave_value tmp = do_index_op (idx.front (), true); + + if (! tmp.is_defined ()) + tmp = octave_value::empty_conv (type.substr (1), rhs); + + if (! error_state) + { + SLList next_idx (idx); + + next_idx.remove_front (); + + t_rhs = tmp.subsasgn (type.substr (1), next_idx, rhs); + } + } + break; + + case '{': + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + } + + switch (type[0]) + { + case '(': + { + octave_value_list i = idx.front (); + + assign (i, t_rhs); + + retval = octave_value (this, count + 1); + } + break; + + case '{': + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + + return retval; +} + void octave_list::assign (const octave_value_list& idx, const octave_value& rhs) { diff --git a/src/ov-list.h b/src/ov-list.h --- a/src/ov-list.h +++ b/src/ov-list.h @@ -61,9 +61,17 @@ ~octave_list (void) { } - octave_value *clone (void) { return new octave_list (*this); } + octave_value *clone (void) const { return new octave_list (*this); } + octave_value *empty_clone (void) const { return new octave_list (); } + + octave_value subsref (const std::string type, + const SLList& idx); - octave_value do_index_op (const octave_value_list& idx); + octave_value do_index_op (const octave_value_list& idx, int resize_ok); + + octave_value subsasgn (const std::string type, + const SLList& idx, + const octave_value& rhs); void assign (const octave_value_list& idx, const octave_value& rhs); diff --git a/src/ov-mapper.cc b/src/ov-mapper.cc --- a/src/ov-mapper.cc +++ b/src/ov-mapper.cc @@ -231,6 +231,37 @@ } octave_value_list +octave_mapper::subsref (const std::string type, + const SLList& idx, + int nargout) +{ + octave_value_list retval; + + switch (type[0]) + { + case '(': + retval = do_multi_index_op (nargout, idx.front ()); + break; + + case '{': + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + + return retval; + + // XXX FIXME XXX + // return retval.next_subsref (type, idx); +} + +octave_value_list octave_mapper::do_multi_index_op (int, const octave_value_list& args) { octave_value retval; diff --git a/src/ov-mapper.h b/src/ov-mapper.h --- a/src/ov-mapper.h +++ b/src/ov-mapper.h @@ -63,6 +63,10 @@ octave_function *function_value (bool) { return this; } + octave_value_list subsref (const std::string type, + const SLList& idx, + int nargout); + octave_value_list do_multi_index_op (int nargout, const octave_value_list& args); diff --git a/src/ov-range.cc b/src/ov-range.cc --- a/src/ov-range.cc +++ b/src/ov-range.cc @@ -35,6 +35,7 @@ #include "gripes.h" #include "ops.h" +#include "oct-obj.h" #include "ov-range.h" #include "ov-re-mat.h" #include "ov-scalar.h" @@ -81,7 +82,34 @@ } octave_value -octave_range::do_index_op (const octave_value_list& idx) +octave_range::subsref (const std::string type, + const SLList& idx) +{ + octave_value retval; + + switch (type[0]) + { + case '(': + retval = do_index_op (idx.front ()); + break; + + case '{': + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + + return retval.next_subsref (type, idx); +} + +octave_value +octave_range::do_index_op (const octave_value_list& idx, int resize_ok) { // XXX FIXME XXX -- this doesn't solve the problem of // @@ -95,7 +123,7 @@ octave_value tmp (new octave_matrix (range.matrix_value ())); - return tmp.do_index_op (idx); + return tmp.do_index_op (idx, resize_ok); } double diff --git a/src/ov-range.h b/src/ov-range.h --- a/src/ov-range.h +++ b/src/ov-range.h @@ -40,6 +40,7 @@ #include "oct-alloc.h" #include "str-vec.h" +#include "SLList.h" #include "error.h" #include "ov-base.h" #include "ov-typeinfo.h" @@ -78,13 +79,20 @@ ~octave_range (void) { } - octave_value *clone (void) { return new octave_range (*this); } + octave_value *clone (void) const { return new octave_range (*this); } + octave_value *empty_clone (void) const { return new octave_range (); } type_conv_fcn numeric_conversion_function (void) const; octave_value *try_narrowing_conversion (void); - octave_value do_index_op (const octave_value_list& idx); + octave_value subsref (const std::string type, + const SLList& idx); + + octave_value do_index_op (const octave_value_list& idx, int resize_ok); + + octave_value do_index_op (const octave_value_list& idx) + { return do_index_op (idx, 0); } idx_vector index_vector (void) const { return idx_vector (range); } diff --git a/src/ov-re-mat.h b/src/ov-re-mat.h --- a/src/ov-re-mat.h +++ b/src/ov-re-mat.h @@ -73,7 +73,8 @@ ~octave_matrix (void) { } - octave_value *clone (void) { return new octave_matrix (*this); } + octave_value *clone (void) const { return new octave_matrix (*this); } + octave_value *empty_clone (void) const { return new octave_matrix (); } octave_value *try_narrowing_conversion (void); diff --git a/src/ov-re-nd-array.h b/src/ov-re-nd-array.h --- a/src/ov-re-nd-array.h +++ b/src/ov-re-nd-array.h @@ -60,7 +60,8 @@ ~octave_double_nd_array (void) { } - octave_value *clone (void) { return new octave_double_nd_array (*this); } + octave_value *clone (void) const { return new octave_double_nd_array (*this); } + octave_value *empty_clone (void) const { return new octave_double_nd_array (); } #if 0 octave_value *try_narrowing_conversion (void); diff --git a/src/ov-scalar.cc b/src/ov-scalar.cc --- a/src/ov-scalar.cc +++ b/src/ov-scalar.cc @@ -49,24 +49,12 @@ DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_scalar, "scalar"); -static inline bool -valid_scalar_indices (const octave_value_list& args) -{ - int nargin = args.length (); - - for (int i = 0; i < nargin; i++) - if (! args(i).valid_as_scalar_index ()) - return false; - - return true; -} - octave_value -octave_scalar::do_index_op (const octave_value_list& idx) +octave_scalar::do_index_op (const octave_value_list& idx, int resize_ok) { octave_value retval; - if (valid_scalar_indices (idx)) + if (idx.valid_scalar_indices ()) retval = scalar; else { @@ -82,7 +70,7 @@ octave_value tmp (new octave_matrix (matrix_value ())); - retval = tmp.do_index_op (idx); + retval = tmp.do_index_op (idx, resize_ok); } return retval; diff --git a/src/ov-scalar.h b/src/ov-scalar.h --- a/src/ov-scalar.h +++ b/src/ov-scalar.h @@ -65,9 +65,10 @@ ~octave_scalar (void) { } - octave_value *clone (void) { return new octave_scalar (*this); } + octave_value *clone (void) const { return new octave_scalar (*this); } + octave_value *empty_clone (void) const { return new octave_scalar (); } - octave_value do_index_op (const octave_value_list& idx); + octave_value do_index_op (const octave_value_list& idx, int resize_ok); idx_vector index_vector (void) const { return idx_vector (scalar); } diff --git a/src/ov-str-mat.cc b/src/ov-str-mat.cc --- a/src/ov-str-mat.cc +++ b/src/ov-str-mat.cc @@ -62,7 +62,8 @@ } octave_value -octave_char_matrix_str::do_index_op (const octave_value_list& idx) +octave_char_matrix_str::do_index_op (const octave_value_list& idx, + int resize_ok) { octave_value retval; @@ -75,7 +76,8 @@ idx_vector i = idx (0).index_vector (); idx_vector j = idx (1).index_vector (); - retval = octave_value (charMatrix (matrix.index (i, j)), true); + retval = octave_value (charMatrix (matrix.index (i, j, resize_ok)), + true); } break; @@ -83,7 +85,7 @@ { idx_vector i = idx (0).index_vector (); - retval = octave_value (charMatrix (matrix.index (i)), true); + retval = octave_value (charMatrix (matrix.index (i, resize_ok)), true); } break; diff --git a/src/ov-str-mat.h b/src/ov-str-mat.h --- a/src/ov-str-mat.h +++ b/src/ov-str-mat.h @@ -79,11 +79,12 @@ ~octave_char_matrix_str (void) { } - octave_value *clone (void) { return new octave_char_matrix_str (*this); } + octave_value *clone (void) const { return new octave_char_matrix_str (*this); } + octave_value *empty_clone (void) const { return new octave_char_matrix_str (); } type_conv_fcn numeric_conversion_function (void) const; - octave_value do_index_op (const octave_value_list& idx); + octave_value do_index_op (const octave_value_list& idx, int resize_ok); void assign (const octave_value_list& idx, const charMatrix& rhs); diff --git a/src/ov-struct.cc b/src/ov-struct.cc --- a/src/ov-struct.cc +++ b/src/ov-struct.cc @@ -30,6 +30,7 @@ #include +#include "Cell.h" #include "error.h" #include "oct-lvalue.h" #include "ov-list.h" @@ -41,35 +42,324 @@ DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_struct, "struct"); -octave_value -octave_struct::do_struct_elt_index_op (const std::string& nm, - const octave_value_list& idx, - bool silent) +octave_value_list +octave_struct::dotref (const octave_value_list& idx) { - // XXX DO_ME XXX - return octave_value (); -} + octave_value_list retval; + + assert (idx.length () == 1); -octave_value -octave_struct::do_struct_elt_index_op (const std::string& nm, bool silent) -{ - octave_value retval; + std::string nm = idx(0).string_value (); + + Pix p = map.seek (nm); - Pix idx = map.seek (nm); - - if (idx) - retval = map.contents (idx); - else if (! silent) + if (p) + retval = map.contents (p); + else error ("structure has no member `%s'", nm.c_str ()); return retval; } -octave_lvalue -octave_struct::struct_elt_ref (octave_value *, const std::string& nm) +static void +gripe_invalid_index (void) +{ + error ("invalid index for structure array"); +} + +static void +gripe_invalid_index_for_assignment (void) +{ + error ("invalid index for structure array assignment"); +} + +static void +gripe_invalid_index_type (const std::string& nm, char t) +{ + error ("%s cannot be indexed with %c", nm.c_str (), t); +} + +static void +gripe_failed_assignment (void) +{ + error ("assignment to structure element failed"); +} + +octave_value +octave_struct::subsref (const std::string type, + const SLList& idx) +{ + octave_value retval; + + int skip = 1; + + switch (type[0]) + { + case '(': + { + if (type.length () > 1 && type[1] == '.') + { + Pix p = idx.first (); + idx.next (p); + octave_value_list key_idx = idx(p); + + octave_value_list tmp = dotref (key_idx); + + if (! error_state) + { + octave_value_list t_idx = idx.front (); + + if (t_idx.length () == 1) + { + idx_vector i = t_idx(0).index_vector (); + octave_value_list t = tmp.index (i); + + retval = (t.length () == 1) ? t(0) : octave_value (t); + + // We handled two index elements, so tell + // next_subsref to skip both of them. + + skip++; + } + else + gripe_invalid_index (); + } + } + else + { + octave_value_list t_idx = idx.front (); + + if (t_idx.length () == 1) + { + idx_vector i = t_idx(0).index_vector (); + retval = map.index (i); + } + else + gripe_invalid_index (); + } + } + break; + + case '.': + { + octave_value_list t = dotref (idx.front ()); + + retval = (t.length () == 1) ? t(0) : octave_value (t); + } + break; + + case '{': + gripe_invalid_index_type (type_name (), type[0]); + break; + + default: + panic_impossible (); + } + + if (! error_state) + retval = retval.next_subsref (type, idx, skip); + + return retval; +} + +octave_value +octave_struct::numeric_conv (const octave_value_list& val, + const std::string& type) +{ + octave_value retval; + + if (val.length () == 1) + { + retval = val(0); + + if (type.length () > 0 && type[0] == '.' && ! retval.is_map ()) + retval = Octave_map (); + } + else + gripe_invalid_index_for_assignment (); + + return retval; +} + +octave_value +octave_struct::subsasgn (const std::string type, + const SLList& idx, + const octave_value& rhs) { - // XXX FIXME XXX -- struct array - return octave_lvalue (&map[nm](0)); + octave_value retval; + + 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] == '.') + { + Pix p = idx.first (); + octave_value_list t_idx = idx(p); + + if (t_idx.length () == 1) + { + idx.next (p); + octave_value_list key_idx = 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 + { + octave_value_list map_val = map[key]; + + octave_value_list t_idx = idx.front (); + + idx_vector i = t_idx(0).index_vector (); + + octave_value_list map_elt = map_val.index (i, true); + + u = numeric_conv (map_elt, type.substr (2)); + } + + if (! error_state) + { + SLList next_idx (idx); + + // We handled two index elements, so subsasgn to + // needs to skip both of them. + + next_idx.remove_front (); + next_idx.remove_front (); + + t_rhs = u.subsasgn (type.substr (2), next_idx, rhs); + } + } + else + gripe_invalid_index_for_assignment (); + } + 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 + { + octave_value_list map_val = map[key]; + + u = numeric_conv (map_val, type.substr (1)); + } + + if (! error_state) + { + SLList next_idx (idx); + + next_idx.remove_front (); + + 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] == '.') + { + Pix p = idx.first (); + idx.next (p); + octave_value_list key_idx = idx(p); + + assert (key_idx.length () == 1); + + std::string key = key_idx(0).string_value (); + + if (! error_state) + { + octave_value_list t_idx = idx.front (); + + if (t_idx.length () == 1) + { + idx_vector i = t_idx(0).index_vector (); + + map.assign (i, key, t_rhs); + + if (! error_state) + retval = octave_value (this, count + 1); + else + gripe_failed_assignment (); + } + else + gripe_invalid_index_for_assignment (); + } + else + gripe_failed_assignment (); + } + 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 (); + + map.assign (key, t_rhs); + + if (! error_state) + retval = octave_value (this, count + 1); + else + gripe_failed_assignment (); + } + break; + + case '{': + gripe_invalid_index_type (type_name (), type[0]); + break; + + default: + panic_impossible (); + } + } + else + gripe_failed_assignment (); + + return retval; } void diff --git a/src/ov-struct.h b/src/ov-struct.h --- a/src/ov-struct.h +++ b/src/ov-struct.h @@ -64,24 +64,31 @@ ~octave_struct (void) { } - octave_value *clone (void) { return new octave_struct (*this); } + octave_value *clone (void) const { return new octave_struct (*this); } + octave_value *empty_clone (void) const { return new octave_struct (); } + + octave_value_list dotref (const octave_value_list& idx); - octave_value - do_struct_elt_index_op (const std::string& nm, const octave_value_list& idx, - bool silent); + octave_value subsref (const std::string type, + const SLList& idx); - octave_value do_struct_elt_index_op (const std::string& nm, bool silent); + static octave_value numeric_conv (const octave_value_list& val, + const std::string& type); - octave_lvalue struct_elt_ref (octave_value *parent, const std::string& nm); + octave_value subsasgn (const std::string type, + const SLList& idx, + const octave_value& rhs); bool is_defined (void) const { return true; } - bool is_constant (void) const { return false; } + bool is_constant (void) const { return true; } bool is_map (void) const { return true; } Octave_map map_value (void) const { return map; } + string_vector map_keys (void) const { return map.keys (); } + void print (std::ostream& os, bool pr_as_read_syntax = false) const; void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const; diff --git a/src/ov-usr-fcn.cc b/src/ov-usr-fcn.cc --- a/src/ov-usr-fcn.cc +++ b/src/ov-usr-fcn.cc @@ -257,6 +257,37 @@ } octave_value_list +octave_user_function::subsref (const std::string type, + const SLList& idx, + int nargout) +{ + octave_value_list retval; + + switch (type[0]) + { + case '(': + retval = do_multi_index_op (nargout, idx.front ()); + break; + + case '{': + case '.': + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + break; + + default: + panic_impossible (); + } + + return retval; + + // XXX FIXME XXX + // return retval.next_subsref (type, idx); +} + +octave_value_list octave_user_function::do_multi_index_op (int nargout, const octave_value_list& args) { @@ -450,6 +481,15 @@ } void +octave_user_function::print_symtab_info (std::ostream& os) const +{ + if (sym_tab) + sym_tab->print_info (os); + else + warning ("%s: no symbol table info!", fcn_name.c_str ()); +} + +void octave_user_function::print_code_function_header (void) { tree_print_code tpc (octave_stdout, Vps4); diff --git a/src/ov-usr-fcn.h b/src/ov-usr-fcn.h --- a/src/ov-usr-fcn.h +++ b/src/ov-usr-fcn.h @@ -127,10 +127,16 @@ void restore_args_passed (void) { - if (! saved_args.empty ()) + if (saved_args.empty ()) + args_passed = octave_value_list (); + else args_passed = saved_args.pop (); } + octave_value_list subsref (const std::string type, + const SLList& idx, + int nargout); + octave_value_list do_multi_index_op (int nargout, const octave_value_list& args); @@ -148,6 +154,8 @@ void accept (tree_walker& tw); + void print_symtab_info (std::ostream& os) const; + private: octave_user_function (void); diff --git a/src/ov-va-args.h b/src/ov-va-args.h --- a/src/ov-va-args.h +++ b/src/ov-va-args.h @@ -55,7 +55,8 @@ ~octave_all_va_args (void) { } - octave_value *clone (void) { return new octave_all_va_args (*this); } + octave_value *clone (void) const { return new octave_all_va_args (*this); } + octave_value *empty_clone (void) const { return new octave_all_va_args (); } bool is_defined (void) const { return true; } diff --git a/src/ov.cc b/src/ov.cc --- a/src/ov.cc +++ b/src/ov.cc @@ -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& 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& idx, + int skip) +{ + assert (skip > 0); + + if (idx.length () > skip) + { + SLList 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& 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& 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& 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& 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) { diff --git a/src/ov.h b/src/ov.h --- a/src/ov.h +++ b/src/ov.h @@ -38,6 +38,8 @@ #include "oct-alloc.h" #include "str-vec.h" +#include "SLList.h" + class Cell; class Octave_map; class octave_stream; @@ -147,6 +149,9 @@ static std::string assign_op_as_string (assign_op); + static octave_value empty_conv (const std::string& type, + const octave_value& rhs = octave_value ()); + enum magic_colon { magic_colon_t }; enum all_va_args { all_va_args_t }; @@ -178,7 +183,7 @@ octave_value (octave_value::magic_colon); octave_value (octave_value::all_va_args); - octave_value (octave_value *new_rep); + octave_value (octave_value *new_rep, int count = 1); // Copy constructor. @@ -188,15 +193,18 @@ rep->count++; } + // This should only be called for derived types. + + virtual octave_value *clone (void) const; + + virtual octave_value *empty_clone (void) const + { return rep->empty_clone (); } + // Delete the representation of this constant if the count drops to // zero. virtual ~octave_value (void); - // This should only be called for derived types. - - virtual octave_value *clone (void); - void make_unique (void) { if (rep->count > 1) @@ -223,7 +231,7 @@ return *this; } - int get_count (void) { return rep->count; } + int get_count (void) const { return rep->count; } virtual type_conv_fcn numeric_conversion_function (void) const { return rep->numeric_conversion_function (); } @@ -233,44 +241,50 @@ virtual octave_value *try_narrowing_conversion (void) { return rep->try_narrowing_conversion (); } - virtual octave_value do_index_op (const octave_value_list& idx) - { return rep->do_index_op (idx); } + virtual octave_value subsref (const std::string type, + const SLList& idx) + { return rep->subsref (type, idx); } + + octave_value subsref (const std::string type, const octave_value_list& idx) + { + SLList i; + + i.append (idx); + + return rep->subsref (type, i); + } + + virtual octave_value_list subsref (const std::string type, + const SLList& idx, + int nargout); + + octave_value next_subsref (const std::string type, const + SLList& idx, + int skip = 1); + + virtual octave_value do_index_op (const octave_value_list& idx, + int resize_ok) + { return rep->do_index_op (idx, resize_ok); } + + octave_value do_index_op (const octave_value_list& idx) + { return do_index_op (idx, 0); } virtual octave_value_list do_multi_index_op (int nargout, const octave_value_list& idx); - void assign (assign_op, const octave_value& rhs); - - void assign (assign_op, const octave_value_list& idx, - const octave_value& rhs); + virtual octave_value subsasgn (const std::string type, + const SLList& idx, + const octave_value& rhs); - virtual void - assign_struct_elt (assign_op, const std::string& elt_nm, - const octave_value& rhs); + octave_value assign (assign_op op, const std::string type, + const SLList& idx, + const octave_value& rhs); - virtual void - assign_struct_elt (assign_op, const std::string& elt_nm, - const octave_value_list& idx, - const octave_value& rhs); + const octave_value& assign (assign_op, const octave_value& rhs); virtual idx_vector index_vector (void) const { return rep->index_vector (); } - virtual octave_value - do_struct_elt_index_op (const std::string& nm, bool silent = false) - { return rep->do_struct_elt_index_op (nm, silent); } - - virtual octave_value - do_struct_elt_index_op (const std::string& nm, - const octave_value_list& idx, - bool silent = false) - { return rep->do_struct_elt_index_op (nm, idx, silent); } - - octave_lvalue struct_elt_ref (const std::string& nm); - - virtual octave_lvalue - struct_elt_ref (octave_value *parent, const std::string& nm); - // Size. virtual int rows (void) const @@ -433,6 +447,9 @@ virtual Octave_map map_value (void) const; + virtual string_vector map_keys (void) const + { return rep->map_keys (); } + virtual octave_stream stream_value (void) const; virtual int stream_number (void) const; @@ -495,24 +512,35 @@ // Unary and binary operations. - friend octave_value do_unary_op (octave_value::unary_op, - const octave_value&); + friend octave_value do_unary_op (unary_op op, + const octave_value& a); - void do_non_const_unary_op (octave_value::unary_op); + const octave_value& do_non_const_unary_op (unary_op op); + + void do_non_const_unary_op (unary_op op, const octave_value_list& idx); - void do_non_const_unary_op (octave_value::unary_op, - const octave_value_list& idx); + octave_value do_non_const_unary_op (unary_op op, const std::string type, + const SLList& idx); - friend octave_value do_binary_op (octave_value::binary_op, - const octave_value&, - const octave_value&); + friend octave_value do_binary_op (binary_op op, + const octave_value& a, + const octave_value& b); const octave_value& get_rep (void) const { return *rep; } + virtual void print_info (std::ostream& os, + const std::string& prefix = std::string ()) const; + protected: octave_value (const octave_xvalue&) : rep (0) { } + // This should only be called for derived types. + + octave_value numeric_assign (const std::string type, + const SLList& idx, + const octave_value& rhs); + void reset_indent_level (void) const { curr_print_indent_level = 0; } @@ -531,23 +559,13 @@ void reset (void) const; -private: - union { octave_value *rep; // The real representation. int count; // A reference count. }; - bool convert_and_assign (assign_op, const octave_value_list& idx, - const octave_value& rhs); - - bool try_assignment_with_conversion (assign_op, - const octave_value_list& idx, - const octave_value& rhs); - - bool try_assignment (assign_op, const octave_value_list& idx, - const octave_value& rhs); +private: static int curr_print_indent_level; static bool beginning_of_line; @@ -556,9 +574,6 @@ binary_op op_eq_to_binary_op (assign_op op); - void simple_assign (assign_op orig_op, const octave_value_list& idx, - const octave_value& rhs); - DECLARE_OCTAVE_ALLOCATOR }; diff --git a/src/parse.y b/src/parse.y --- a/src/parse.y +++ b/src/parse.y @@ -280,8 +280,8 @@ // Make an index expression. static tree_index_expression * -make_index_expression (tree_expression *expr, tree_argument_list *args, - tree_index_expression::type); +make_index_expression (tree_expression *expr, + tree_argument_list *args, char type); // Make an indirect reference expression. static tree_index_expression * @@ -697,25 +697,13 @@ postfix_expr : primary_expr { $$ = $1; } | postfix_expr '(' ')' - { - $$ = make_index_expression ($1, 0, - tree_index_expression::paren); - } + { $$ = make_index_expression ($1, 0, '('); } | postfix_expr '(' arg_list ')' - { - $$ = make_index_expression ($1, $3, - tree_index_expression::paren); - } + { $$ = make_index_expression ($1, $3, '('); } | postfix_expr '{' '}' - { - $$ = make_index_expression ($1, 0, - tree_index_expression::brace); - } + { $$ = make_index_expression ($1, 0, '{'); } | postfix_expr '{' arg_list '}' - { - $$ = make_index_expression ($1, $3, - tree_index_expression::brace); - } + { $$ = make_index_expression ($1, $3, '{'); } | postfix_expr PLUS_PLUS { $$ = make_postfix_op (PLUS_PLUS, $1, $2); } | postfix_expr MINUS_MINUS @@ -852,10 +840,7 @@ ; word_list_cmd : identifier word_list - { - $$ = make_index_expression ($1, $2, - tree_index_expression::paren); - } + { $$ = make_index_expression ($1, $2, '('); } ; word_list : TEXT @@ -2591,7 +2576,7 @@ static tree_index_expression * make_index_expression (tree_expression *expr, tree_argument_list *args, - tree_index_expression::type t) + char type) { tree_index_expression *retval = 0; @@ -2600,7 +2585,16 @@ expr->mark_postfix_indexed (); - retval = new tree_index_expression (expr, args, l, c, t); + if (expr->is_index_expression ()) + { + tree_index_expression *tmp = static_cast (expr); + + tmp->append (args, type); + + retval = tmp; + } + else + retval = new tree_index_expression (expr, args, l, c, type); return retval; } @@ -2615,7 +2609,16 @@ int l = expr->line (); int c = expr->column (); - retval = new tree_index_expression (expr, elt, l, c); + if (expr->is_index_expression ()) + { + tree_index_expression *tmp = static_cast (expr); + + tmp->append (elt); + + retval = tmp; + } + else + retval = new tree_index_expression (expr, elt, l, c); lexer_flags.looking_at_indirect_ref = false; diff --git a/src/pr-output.cc b/src/pr-output.cc --- a/src/pr-output.cc +++ b/src/pr-output.cc @@ -38,12 +38,12 @@ #include "Range.h" #include "cmd-edit.h" #include "dMatrix.h" -#include "Cell.h" #include "lo-mappers.h" #include "mach-info.h" #include "oct-cmplx.h" #include "str-vec.h" +#include "Cell.h" #include "defun.h" #include "error.h" #include "gripes.h" @@ -1755,37 +1755,10 @@ } } -void -octave_print_internal (std::ostream& os, const Cell& cell_val, - bool pr_as_read_syntax, int extra_indent) +extern void +octave_print_internal (std::ostream&, const Cell&, bool, int, bool) { - int nr = cell_val.rows (); - int nc = cell_val.columns(); - - if (nr > 0 && nc > 0) - { - os << "{\n"; - - for (int j = 0; j < nc; j++) - { - for (int i = 0; i < nr; i++) - { - std::ostrstream buf; - buf << "[" << i+1 << "," << j+1 << "]" << std::ends; - const char *nm = buf.str (); - - octave_value val = cell_val(i,j); - - val.print_with_name (os, nm); - - delete [] nm; - } - } - - os << "}"; - } - else - os << "{}"; + panic_impossible (); } DEFUN (disp, args, nargout, diff --git a/src/pr-output.h b/src/pr-output.h --- a/src/pr-output.h +++ b/src/pr-output.h @@ -69,9 +69,10 @@ bool pr_as_string = false); extern void -octave_print_internal (std::ostream& os, const Cell& c, +octave_print_internal (std::ostream& os, const Cell& cell, bool pr_as_read_syntax = false, - int extra_indent = 0); + int extra_indent = 0, + bool pr_as_string = false); #endif diff --git a/src/pt-assign.h b/src/pt-assign.h --- a/src/pt-assign.h +++ b/src/pt-assign.h @@ -59,15 +59,13 @@ ~tree_simple_assignment (void); - bool rvalue_ok (void) const - { return true; } + bool rvalue_ok (void) const { return true; } octave_value rvalue (void); octave_value_list rvalue (int nargout); - bool is_assignment_expression (void) const - { return true; } + bool is_assignment_expression (void) const { return true; } void eval_error (void); @@ -127,11 +125,9 @@ ~tree_multi_assignment (void); - bool is_assignment_expression (void) const - { return true; } + bool is_assignment_expression (void) const { return true; } - bool rvalue_ok (void) const - { return true; } + bool rvalue_ok (void) const { return true; } octave_value rvalue (void); diff --git a/src/pt-binop.h b/src/pt-binop.h --- a/src/pt-binop.h +++ b/src/pt-binop.h @@ -62,8 +62,7 @@ delete op_rhs; } - bool rvalue_ok (void) const - { return true; } + bool rvalue_ok (void) const { return true; } octave_value rvalue (void); @@ -119,8 +118,7 @@ ~tree_boolean_expression (void) { } - bool rvalue_ok (void) const - { return true; } + bool rvalue_ok (void) const { return true; } octave_value rvalue (void); diff --git a/src/pt-bp.cc b/src/pt-bp.cc --- a/src/pt-bp.cc +++ b/src/pt-bp.cc @@ -345,22 +345,21 @@ if (found) return; - if (cmd.expr_type () == tree_index_expression::dot) - { - if (cmd.line () >= line) - take_action (cmd); - } - else + tree_expression *expr = cmd.expression (); + + if (expr && expr->line () >= line) + take_action (*expr); + + SLList lst = cmd.arg_lists (); + + if (! lst.empty ()) { - tree_expression *expr = cmd.expression (); - - if (expr && expr->line () >= line) - take_action (*expr); + for (Pix p = lst.first (); p != 0; lst.next (p)) + { + tree_argument_list *elt = lst(p); - tree_argument_list *lst = cmd.arg_list (); - - if (lst) - lst->accept (*this); + elt->accept (*this); + } } } diff --git a/src/pt-cell.h b/src/pt-cell.h --- a/src/pt-cell.h +++ b/src/pt-cell.h @@ -50,8 +50,7 @@ ~tree_cell (void) { } - bool rvalue_ok (void) const - { return true; } + bool rvalue_ok (void) const { return true; } octave_value rvalue (void); diff --git a/src/pt-check.cc b/src/pt-check.cc --- a/src/pt-check.cc +++ b/src/pt-check.cc @@ -248,10 +248,19 @@ if (e) e->accept (*this); - tree_argument_list *list = expr.arg_list (); + SLList lst = expr.arg_lists (); + + Pix p = lst.first (); - if (list) - list->accept (*this); + while (p) + { + tree_argument_list *elt = lst (p); + + if (elt) + elt->accept (*this); + + lst.next (p); + } } void diff --git a/src/pt-colon.h b/src/pt-colon.h --- a/src/pt-colon.h +++ b/src/pt-colon.h @@ -65,8 +65,7 @@ tree_colon_expression *append (tree_expression *t); - bool rvalue_ok (void) const - { return true; } + bool rvalue_ok (void) const { return true; } octave_value rvalue (void); diff --git a/src/pt-const.h b/src/pt-const.h --- a/src/pt-const.h +++ b/src/pt-const.h @@ -54,19 +54,15 @@ ~tree_constant (void) { } - void *operator new (size_t size) - { return allocator.alloc (size); } + void *operator new (size_t size) { return allocator.alloc (size); } - void operator delete (void *p, size_t size) - { allocator.free (p, size); } + void operator delete (void *p, size_t size) { allocator.free (p, size); } // Type. It would be nice to eliminate the need for this. - bool is_constant (void) const - { return true; } + bool is_constant (void) const { return true; } - void maybe_mutate (void) - { val.maybe_mutate (); } + void maybe_mutate (void) { val.maybe_mutate (); } void print (std::ostream& os, bool pr_as_read_syntax = false, bool pr_orig_txt = true); @@ -74,8 +70,7 @@ void print_raw (std::ostream& os, bool pr_as_read_syntax = false, bool pr_orig_txt = true); - bool rvalue_ok (void) const - { return true; } + bool rvalue_ok (void) const { return true; } octave_value rvalue (void) { @@ -90,11 +85,9 @@ // Store the original text corresponding to this constant for later // pretty printing. - void stash_original_text (const std::string& s) - { orig_text = s; } + void stash_original_text (const std::string& s) { orig_text = s; } - std::string original_text (void) const - { return orig_text; } + std::string original_text (void) const { return orig_text; } private: diff --git a/src/pt-exp.h b/src/pt-exp.h --- a/src/pt-exp.h +++ b/src/pt-exp.h @@ -47,34 +47,23 @@ virtual ~tree_expression (void) { } - virtual bool is_constant (void) const - { return false; } + virtual bool is_constant (void) const { return false; } - virtual bool is_matrix_constant (void) const - { return false; } + virtual bool is_matrix_constant (void) const { return false; } - virtual bool is_identifier (void) const - { return false; } + virtual bool is_identifier (void) const { return false; } - virtual bool is_index_expression (void) const - { return false; } - - virtual bool is_indirect_ref (void) const - { return false; } + virtual bool is_index_expression (void) const { return false; } - virtual bool is_assignment_expression (void) const - { return false; } + virtual bool is_assignment_expression (void) const { return false; } - virtual bool is_prefix_expression (void) const - { return false; } + virtual bool is_prefix_expression (void) const { return false; } virtual bool is_logically_true (const char *); - virtual bool lvalue_ok (void) const - { return false; } + virtual bool lvalue_ok (void) const { return false; } - virtual bool rvalue_ok (void) const - { return false; } + virtual bool rvalue_ok (void) const { return false; } virtual octave_value rvalue (void); @@ -82,20 +71,15 @@ virtual octave_lvalue lvalue (void); - int paren_count (void) const - { return num_parens; } + int paren_count (void) const { return num_parens; } - bool is_postfix_indexed (void) const - { return postfix_indexed; } + bool is_postfix_indexed (void) const { return postfix_indexed; } - bool print_result (void) const - { return print_flag; } + bool print_result (void) const { return print_flag; } - virtual std::string oper (void) const - { return ""; } + virtual std::string oper (void) const { return ""; } - virtual std::string name (void) const - { return ""; } + virtual std::string name (void) const { return ""; } virtual std::string original_text (void) const; diff --git a/src/pt-id.h b/src/pt-id.h --- a/src/pt-id.h +++ b/src/pt-id.h @@ -56,8 +56,7 @@ ~tree_identifier (void) { } - bool is_identifier (void) const - { return true; } + bool is_identifier (void) const { return true; } std::string name (void) const; @@ -81,8 +80,7 @@ // We really need to know whether this symbol referst to a variable // or a function, but we may not know that yet. - bool lvalue_ok (void) const - { return true; } + bool lvalue_ok (void) const { return true; } octave_value rvalue (void); diff --git a/src/pt-idx.cc b/src/pt-idx.cc --- a/src/pt-idx.cc +++ b/src/pt-idx.cc @@ -28,6 +28,7 @@ #include #endif +#include "Cell.h" #include "error.h" #include "oct-map.h" #include "oct-obj.h" @@ -41,24 +42,54 @@ #include "utils.h" #include "variables.h" +#include "SLList.cc" + +template class SLNode; +template class SLList; + // Index expressions. tree_index_expression::tree_index_expression (tree_expression *e, tree_argument_list *lst, - int l, int c, type t) - : tree_expression (l, c), expr (e), list (lst), - itype (t), arg_nm (lst ? lst->get_arg_names () : string_vector ()) { } + int l, int c, char t) + : tree_expression (l, c), expr (e), args (), type (), arg_nm () +{ + append (lst, t); +} tree_index_expression::tree_index_expression (tree_expression *e, const std::string& n, int l = -1, int c = -1) - : tree_expression (l, c), expr (e), list (0), itype (dot), - arg_nm (n) { } + : tree_expression (l, c), expr (e), args (), type (), arg_nm () +{ + append (n); +} + +void +tree_index_expression::append (tree_argument_list *lst, char t) +{ + args.append (lst); + type.append (1, t); + arg_nm.append (lst ? lst->get_arg_names () : string_vector ()); +} + +void +tree_index_expression::append (const std::string& n) +{ + args.append (static_cast (0)); + type.append ("."); + arg_nm.append (n); +} tree_index_expression::~tree_index_expression (void) { delete expr; - delete list; + + while (! args.empty ()) + { + tree_argument_list *t = args.remove_front (); + delete t; + } } // This is useful for printing the name of the variable in an indexed @@ -70,7 +101,101 @@ // ??? FIXME ??? std::string xname = expr->name (); - return (! dot || xname == "") ? xname : xname + "." + arg_nm(0); + return (type[0] != '.' || xname == "") + ? xname : xname + "." + arg_nm.front ()(0); +} + +static Cell +make_subs_cell (tree_argument_list *args, const string_vector& arg_nm) +{ + Cell retval; + + octave_value_list arg_values; + + if (args) + arg_values = args->convert_to_const_vector (); + + if (! error_state) + { + int n = arg_values.length (); + + if (n > 0) + { + arg_values.stash_name_tags (arg_nm); + + retval.resize (1, n); + + for (int i = 0; i < n; i++) + retval(0,i) = arg_values(i); + } + } + + return retval; +} + +static inline octave_value_list +make_value_list (tree_argument_list *args, const string_vector& arg_nm) +{ + octave_value_list retval; + + if (args) + retval = args->convert_to_const_vector (); + + if (! error_state) + { + int n = retval.length (); + + if (n > 0) + retval.stash_name_tags (arg_nm); + } + + return retval; +} + +Octave_map +tree_index_expression::make_arg_struct (void) const +{ + int n = args.length (); + + octave_value_list subs_list (n, octave_value ()); + octave_value_list type_list (n, octave_value ()); + + Pix p_args = args.first (); + Pix p_arg_nm = arg_nm.first (); + + Octave_map m; + + for (int i = 0; i < n; i++) + { + switch (type[i]) + { + case '(': + subs_list(i) = make_subs_cell (args(p_args), arg_nm(p_arg_nm)); + break; + + case '{': + subs_list(i) = make_subs_cell (args(p_args), arg_nm(p_arg_nm)); + break; + + case '.': + subs_list(i) = arg_nm(p_arg_nm)(0); + break; + + default: + panic_impossible (); + } + + if (error_state) + return m; + + args.next (p_args); + arg_nm.next (p_arg_nm); + } + + m ["subs"] = subs_list; + m ["type"] = type_list; + + return m; } octave_value_list @@ -85,66 +210,43 @@ if (! error_state) { - if (itype == dot) - { - MAYBE_DO_BREAKPOINT; + SLList idx; - if (nargout > 1) - error ("invalid number of output arguments for structure reference"); - else - { - octave_value_list tmp = expr->rvalue (nargout); + int n = args.length (); + + Pix p_args = args.first (); + Pix p_arg_nm = arg_nm.first (); - if (tmp.empty ()) - eval_error (); - else - { - octave_value val = tmp(0).do_struct_elt_index_op (arg_nm(0)); + for (int i = 0; i < n; i++) + { + switch (type[i]) + { + case '(': + idx.append (make_value_list (args(p_args), arg_nm(p_arg_nm))); + break; - if (print_result () && nargout == 0 && val.is_defined ()) - { - // ??? FIXME ??? - - std::string xname = name (); - - if (xname == "") - bind_ans (val, true); - else - val.print_with_name (octave_stdout, xname); - } + case '{': + idx.append (make_value_list (args(p_args), arg_nm(p_arg_nm))); + break; - retval = val; - } - } - } - else if (itype == paren || itype == brace) - { - octave_value_list args; + case '.': + idx.append (arg_nm(p_arg_nm)(0)); + break; - if (list) - args = list->convert_to_const_vector (); - - if (! error_state) - { - if (! args.empty ()) - args.stash_name_tags (arg_nm); + default: + panic_impossible (); + } - // XXX FIXME XXX -- is this the right thing to do? - if (tmp.is_constant ()) - retval = tmp.do_index_op (args); - else - retval = tmp.do_multi_index_op (nargout, args); - } - else - eval_error (); + if (error_state) + break; + + args.next (p_args); + arg_nm.next (p_arg_nm); } -#if 0 - else - panic_impossible (); -#endif + + if (! error_state) + retval = tmp.subsref (type, idx, nargout); } - else - eval_error (); return retval; } @@ -167,35 +269,46 @@ { octave_lvalue retval; + SLList idx; + + int n = args.length (); + + Pix p_args = args.first (); + Pix p_arg_nm = arg_nm.first (); + + for (int i = 0; i < n; i++) + { + switch (type[i]) + { + case '(': + idx.append (make_value_list (args(p_args), arg_nm(p_arg_nm))); + break; + + case '{': + idx.append (make_value_list (args(p_args), arg_nm(p_arg_nm))); + break; + + case '.': + idx.append (arg_nm(p_arg_nm)(0)); + break; + + default: + panic_impossible (); + } + + if (error_state) + break; + + args.next (p_args); + arg_nm.next (p_arg_nm); + } + if (! error_state) { - if (itype == dot) - { - octave_lvalue tmp = expr->lvalue (); - - if (tmp.is_undefined () || ! tmp.is_map ()) - tmp.define (Octave_map ()); - - retval = tmp.struct_elt_ref (arg_nm(0)); - } - else if (itype == paren || itype == brace) - { - retval = expr->lvalue (); + retval = expr->lvalue (); - if (! error_state) - { - octave_value_list args; - - if (list) - args = list->convert_to_const_vector (); - - retval.set_index (args); - } -#if 0 - else - panic_impossible (); -#endif - } + if (! error_state) + retval.set_index (type, idx); } return retval; @@ -211,9 +324,9 @@ const char *type_str; - if (itype == dot) + if (type[0] == '.') type_str = "structure reference operator"; - else if (list) + else if (args.front ()) type_str = "index expression"; else type_str = "expression"; diff --git a/src/pt-idx.h b/src/pt-idx.h --- a/src/pt-idx.h +++ b/src/pt-idx.h @@ -31,10 +31,12 @@ class tree_walker; +class Octave_map; class octave_value; class octave_value_list; class octave_lvalue; +#include "SLList.h" #include "str-vec.h" #include "pt-exp.h" @@ -46,46 +48,33 @@ { public: - enum type - { - unknown, - paren, - brace, - dot - }; - tree_index_expression (tree_expression *e = 0, tree_argument_list *lst = 0, - int l = -1, int c = -1, type t = paren); + int l = -1, int c = -1, char t = '('); tree_index_expression (tree_expression *e, const std::string& n, int l = -1, int c = -1); ~tree_index_expression (void); - bool is_index_expression (void) const - { return (itype == paren || itype == brace); } + void append (tree_argument_list *lst = 0, char t = '('); - bool is_indirect_ref (void) const - { return (itype == dot); } + void append (const std::string& n); + + bool is_index_expression (void) const { return true; } std::string name (void) const; - std::string struct_elt_name (void) const - { return itype == dot ? arg_nm(0) : ""; } + tree_expression *expression (void) { return expr; } - type expr_type (void) { return itype; } + SLList arg_lists (void) { return args; } - tree_expression *expression (void) - { return expr; } + std::string type_tags (void) { return type; } - tree_argument_list *arg_list (void) - { return list; } + SLList arg_names (void) { return arg_nm; } - bool lvalue_ok (void) const - { return (itype == dot || expr->lvalue_ok ()); } + bool lvalue_ok (void) const { return expr->lvalue_ok (); } - bool rvalue_ok (void) const - { return true; } + bool rvalue_ok (void) const { return true; } octave_value rvalue (void); @@ -102,14 +91,16 @@ // The LHS of this index expression. tree_expression *expr; - // The indices (only valid if itype == paren || itype == brace). - tree_argument_list *list; + // The indices (only valid if type == paren || type == brace). + SLList args; // The type of this index expression. - type itype; + std::string type; // The names of the arguments. - string_vector arg_nm; + SLList arg_nm; + + Octave_map tree_index_expression::make_arg_struct (void) const; // No copying! diff --git a/src/pt-mat.h b/src/pt-mat.h --- a/src/pt-mat.h +++ b/src/pt-mat.h @@ -58,8 +58,7 @@ bool all_elements_are_constant (void) const; - bool rvalue_ok (void) const - { return true; } + bool rvalue_ok (void) const { return true; } octave_value rvalue (void); diff --git a/src/pt-misc.h b/src/pt-misc.h --- a/src/pt-misc.h +++ b/src/pt-misc.h @@ -57,17 +57,13 @@ void mark_as_formal_parameters (void); - void mark_varargs (void) - { marked_for_varargs = 1; } + void mark_varargs (void) { marked_for_varargs = 1; } - bool takes_varargs (void) const - { return marked_for_varargs != 0; } + bool takes_varargs (void) const { return marked_for_varargs != 0; } - void mark_varargs_only (void) - { marked_for_varargs = -1; } + void mark_varargs_only (void) { marked_for_varargs = -1; } - bool varargs_only (void) - { return (marked_for_varargs < 0); } + bool varargs_only (void) { return (marked_for_varargs < 0); } void initialize_undefined_elements (octave_value& val); diff --git a/src/pt-plot.cc b/src/pt-plot.cc --- a/src/pt-plot.cc +++ b/src/pt-plot.cc @@ -666,7 +666,7 @@ args(1) = val; args(0) = octave_value::magic_colon_t; - retval = data.do_index_op (args); + retval = data.subsref ("(", args); if (error_state) return octave_value (); diff --git a/src/pt-pr-code.cc b/src/pt-pr-code.cc --- a/src/pt-pr-code.cc +++ b/src/pt-pr-code.cc @@ -484,21 +484,53 @@ expr_has_parens = e->is_postfix_indexed (); } - tree_argument_list *list = expr.arg_list (); + SLList arg_lists = expr.arg_lists (); + std::string type_tags = expr.type_tags (); + SLList arg_names = expr.arg_names (); - if (expr.expr_type () == tree_index_expression::dot) - { - os << "." << expr.struct_elt_name (); - } - else if (list) + int n = type_tags.length (); + + Pix arg_lists_p = arg_lists.first (); + Pix arg_names_p = arg_names.first (); + + for (int i = 0; i < n; i++) { - os << " ("; - list->accept (*this); - os << ")"; - } - else if (expr_has_parens) - { - os << " ()"; + switch (type_tags[i]) + { + case '(': + { + os << " ("; + tree_argument_list *l = arg_lists (arg_lists_p); + if (l) + l->accept (*this); + os << ")"; + } + break; + + case '{': + { + os << " {"; + tree_argument_list *l = arg_lists (arg_lists_p); + if (l) + l->accept (*this); + os << "}"; + } + break; + + case '.': + { + string_vector nm = arg_names (arg_names_p); + assert (nm.length () == 1); + os << "." << nm(0); + } + break; + + default: + panic_impossible (); + } + + arg_lists.next (arg_lists_p); + arg_names.next (arg_names_p); } print_parens (expr, ")"); diff --git a/src/pt-pr-code.h b/src/pt-pr-code.h --- a/src/pt-pr-code.h +++ b/src/pt-pr-code.h @@ -155,14 +155,11 @@ // TRUE means we are at the beginning of a line. bool beginning_of_line; - void reset_indent_level (void) - { curr_print_indent_level = 0; } + void reset_indent_level (void) { curr_print_indent_level = 0; } - void increment_indent_level (void) - { curr_print_indent_level += 2; } + void increment_indent_level (void) { curr_print_indent_level += 2; } - void decrement_indent_level (void) - { curr_print_indent_level -= 2; } + void decrement_indent_level (void) { curr_print_indent_level -= 2; } void newline (void); diff --git a/src/pt-select.h b/src/pt-select.h --- a/src/pt-select.h +++ b/src/pt-select.h @@ -181,8 +181,7 @@ ~tree_switch_case (void); - bool is_default_case (void) - { return ! label; } + bool is_default_case (void) { return ! label; } bool label_matches (const octave_value& val); diff --git a/src/pt-stmt.cc b/src/pt-stmt.cc --- a/src/pt-stmt.cc +++ b/src/pt-stmt.cc @@ -126,8 +126,7 @@ do_bind_ans = id->is_function (); } else - do_bind_ans = (! (expr->is_indirect_ref () - || expr->is_assignment_expression ())); + do_bind_ans = (! expr->is_assignment_expression ()); retval = expr->rvalue (nargout); diff --git a/src/pt-stmt.h b/src/pt-stmt.h --- a/src/pt-stmt.h +++ b/src/pt-stmt.h @@ -57,14 +57,11 @@ ~tree_statement (void); - void set_print_flag (bool print) - { print_flag = print; } + void set_print_flag (bool print) { print_flag = print; } - bool is_command (void) - { return cmd != 0; } + bool is_command (void) { return cmd != 0; } - bool is_expression (void) - { return expr != 0; } + bool is_expression (void) { return expr != 0; } int line (void); int column (void); diff --git a/src/pt-unop.h b/src/pt-unop.h --- a/src/pt-unop.h +++ b/src/pt-unop.h @@ -94,8 +94,7 @@ ~tree_prefix_expression (void) { } - bool rvalue_ok (void) const - { return true; } + bool rvalue_ok (void) const { return true; } octave_value rvalue (void); @@ -131,8 +130,7 @@ ~tree_postfix_expression (void) { } - bool rvalue_ok (void) const - { return true; } + bool rvalue_ok (void) const { return true; } octave_value rvalue (void); diff --git a/src/symtab.cc b/src/symtab.cc --- a/src/symtab.cc +++ b/src/symtab.cc @@ -42,7 +42,6 @@ #include "error.h" #include "oct-lvalue.h" #include "ov.h" -#include "pager.h" #include "pt-pr-code.h" #include "symtab.h" #include "utils.h" @@ -179,11 +178,11 @@ } void -SYMBOL_DEF::dump_symbol_info (void) +SYMBOL_DEF::print_info (ostream& os, const std::string& prefix) const { - octave_stdout << "symbol_def::count: " << count << "\n"; - octave_stdout << "def.type_name(): " << definition.type_name () << "\n"; - octave_stdout << "def.count(): " << definition.get_count () << "\n"; + os << prefix << "symbol_def::count: " << count << "\n"; + + definition.print_info (os, prefix + " "); } // Individual records in a symbol table. @@ -445,7 +444,7 @@ } void -symbol_record::print_symbol_info_line (std::ostream& os) +symbol_record::print_symbol_info_line (std::ostream& os) const { os << (is_read_only () ? " r-" : " rw") << (is_eternal () ? "-" : "d") @@ -477,12 +476,12 @@ } void -symbol_record::dump_symbol_info (void) +symbol_record::print_info (ostream& os, const std::string& prefix) const { if (definition) - definition->dump_symbol_info (); + definition->print_info (os, prefix); else - octave_stdout << "symbol " << name () << " is undefined\n"; + os << prefix << "symbol " << name () << " is undefined\n"; } bool @@ -875,7 +874,7 @@ } void -symbol_table::print_stats (void) +symbol_table::print_info (ostream& os) const { int count = 0; int empty_chains = 0; @@ -889,7 +888,7 @@ symbol_record *ptr = table[i].next (); if (ptr) - octave_stdout << "chain number " << i << ":\n"; + os << "chain number " << i << ":\n"; else { empty_chains++; @@ -900,7 +899,9 @@ { num_this_chain++; - octave_stdout << " " << ptr->name () << "\n"; + os << " " << ptr->name () << "\n"; + + ptr->print_info (os, " "); ptr = ptr->next (); } @@ -914,14 +915,14 @@ min_chain_length = num_this_chain; if (num_this_chain > 0) - octave_stdout << "\n"; + os << "\n"; } - octave_stdout << "max chain length: " << max_chain_length << "\n"; - octave_stdout << "min chain length: " << min_chain_length << "\n"; - octave_stdout << "empty chains: " << empty_chains << "\n"; - octave_stdout << "total chains: " << table_size << "\n"; - octave_stdout << "total symbols: " << count << "\n"; + os << "max chain length: " << max_chain_length << "\n"; + os << "min chain length: " << min_chain_length << "\n"; + os << "empty chains: " << empty_chains << "\n"; + os << "total chains: " << table_size << "\n"; + os << "total symbols: " << count << "\n"; } // Chris Torek's fave hash function. diff --git a/src/symtab.h b/src/symtab.h --- a/src/symtab.h +++ b/src/symtab.h @@ -201,7 +201,8 @@ // Reference count. int count; - void dump_symbol_info (void); + void print_info (std::ostream& os, + const std::string& prefix = std::string ()) const; // No copying! @@ -338,9 +339,10 @@ void pop_context (void); - void print_symbol_info_line (std::ostream& os); + void print_symbol_info_line (std::ostream& os) const; - void dump_symbol_info (void); + void print_info (std::ostream& os, + const std::string& prefix = std::string ()) const; private: @@ -444,7 +446,7 @@ void pop_context (void); - void print_stats (void); + void print_info (ostream& os) const; private: diff --git a/src/toplev.cc b/src/toplev.cc --- a/src/toplev.cc +++ b/src/toplev.cc @@ -762,7 +762,7 @@ std::string arg = args(0).string_value (); if (! error_state) - retval = octave_value (m [arg.c_str ()]); + retval = octave_value (m [arg.c_str ()](0)); } else if (nargin == 0) retval = octave_value (m); diff --git a/src/variables.cc b/src/variables.cc --- a/src/variables.cc +++ b/src/variables.cc @@ -45,6 +45,7 @@ #include "oct-map.h" #include "oct-obj.h" #include "ov.h" +#include "ov-usr-fcn.h" #include "pager.h" #include "parse.h" #include "symtab.h" @@ -265,22 +266,14 @@ } string_vector -generate_struct_completions (const std::string& text, std::string& prefix, std::string& hint) +generate_struct_completions (const std::string& text, + std::string& prefix, std::string& hint) { string_vector names; size_t pos = text.rfind ('.'); - std::string id; - string_vector elts; - - if (pos == NPOS) - { - hint = text; - prefix = text; - elts.resize (1, text); - } - else + if (pos != NPOS) { if (pos == text.length ()) hint = ""; @@ -288,41 +281,14 @@ hint = text.substr (pos+1); prefix = text.substr (0, pos); - - elts = get_struct_elts (prefix); } - id = elts[0]; - - symbol_record *sr = curr_sym_tab->lookup (id); - - if (! sr) - sr = global_sym_tab->lookup (id); - - if (sr && sr->is_defined ()) - { - octave_value tmp = sr->def (); + int parse_status; - // XXX FIXME XXX -- make this work for all types that can do - // structure reference operations. - if (tmp.is_map ()) - { - for (int i = 1; i < elts.length (); i++) - { - tmp = tmp.do_struct_elt_index_op (elts[i], true); + octave_value tmp = eval_string (prefix, true, parse_status); - if (! tmp.is_map ()) - break; - } - - if (tmp.is_map ()) - { - Octave_map m = tmp.map_value (); - - names = m.make_name_list (); - } - } - } + if (tmp.is_defined () && tmp.is_map ()) + names = tmp.map_keys (); return names; } @@ -330,44 +296,11 @@ bool looks_like_struct (const std::string& text) { - bool retval = true; - - string_vector elts = get_struct_elts (text); - - std::string id = elts[0]; - - symbol_record *sr = curr_sym_tab->lookup (id); - - if (! sr) - sr = global_sym_tab->lookup (id); - - if (sr && sr->is_defined ()) - { - octave_value tmp = sr->def (); - - // XXX FIXME XXX -- should this work for all types that can do - // structure reference operations? + int parse_status; - if (tmp.is_map ()) - { - for (int i = 1; i < elts.length (); i++) - { - tmp = tmp.do_struct_elt_index_op (elts[i], true); + octave_value tmp = eval_string (text, true, parse_status); - if (! tmp.is_map ()) - { - retval = false; - break; - } - } - } - else - retval = false; - } - else - retval = false; - - return retval; + return (tmp.is_defined () && tmp.is_map ()); } DEFUN (is_global, args, , @@ -1303,9 +1236,9 @@ return retval; } -DEFUN (__dump_symtab_info__, args, , +DEFUN (__print_symtab_info__, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {} __dump_symtab_info__ ()\n\ +@deftypefn {Built-in Function} {} __print_symtab_info__ ()\n\ Print raw symbol table statistices.\n\ @end deftypefn") { @@ -1318,19 +1251,36 @@ std::string arg = args(0).string_value (); if (arg == "global") - global_sym_tab->print_stats (); + global_sym_tab->print_info (octave_stdout); + else if (arg == "top-level") + top_level_sym_tab->print_info (octave_stdout); else - print_usage ("__dump_symtab_info__"); + { + symbol_record *gsr = global_sym_tab->lookup (arg, true); + + if (gsr && gsr->is_user_function ()) + { + octave_value tmp = gsr->def (); + const octave_value& rep = tmp.get_rep (); + + const octave_user_function& fcn + = static_cast (rep); + + fcn.print_symtab_info (octave_stdout); + } + else + error ("no user-defined function named %s", arg.c_str ()); + } } else if (nargin == 0) - curr_sym_tab->print_stats (); + curr_sym_tab->print_info (octave_stdout); else - print_usage ("__dump_symtab_info__"); + print_usage ("__print_symtab_info__"); return retval; } -DEFUN (__dump_symbol_info__, args, , +DEFUN (__print_symbol_info__, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __dump_symbol_info__ (@var{name})\n\ Print symbol table information for the symbol @var{name}.\n\ @@ -1349,16 +1299,16 @@ symbol_record *sr = curr_sym_tab->lookup (symbol_name); if (sr) - sr->dump_symbol_info (); + sr->print_info (octave_stdout); else - error ("__dymp_symbol_info__: symbol %s not found", + error ("__print_symbol_info__: symbol %s not found", symbol_name.c_str ()); } else - print_usage ("__dump_symbol_info__"); + print_usage ("__print_symbol_info__"); } else - print_usage ("__dump_symbol_info__"); + print_usage ("__print_symbol_info__"); return retval; }