# HG changeset patch # User John W. Eaton # Date 1418061587 18000 # Node ID b39cbe9f3bb0a08a968c203f88c548d3cf6a0dbd # Parent 9464cfeede2bb7b400fed7a225276064f13d397b allow ranges to be disabled * ov.cc, ov.h: Allow creation of range object to be disabled. Also allow range objects to be forced, even when generally disabled. * pt-exp.h (tree_expression::for_cmd_expr): New member variable. (tree_expression::mark_as_for_cmd_expr, tree_expression::is_for_cmd_expr): New functions. * oct-parse.in.yy: Mark for command expressions. * pt-colon.cc (tree_colon_expression::make_range): Force creation of range if expression is a for command expression. * basics.txi, numbers.txi: Document changes. diff -r 9464cfeede2b -r b39cbe9f3bb0 doc/interpreter/basics.txi --- a/doc/interpreter/basics.txi Mon Dec 08 10:18:35 2014 -0500 +++ b/doc/interpreter/basics.txi Mon Dec 08 12:59:47 2014 -0500 @@ -249,6 +249,7 @@ crash_dumps_octave_core = false disable_diagonal_matrix = true disable_permutation_matrix = true +disable_range = true fixed_point_format = true history_timestamp_format_string = "%%-- %D %I:%M %p --%%" page_screen_output = false diff -r 9464cfeede2b -r b39cbe9f3bb0 doc/interpreter/numbers.txi --- a/doc/interpreter/numbers.txi Mon Dec 08 10:18:35 2014 -0500 +++ b/doc/interpreter/numbers.txi Mon Dec 08 12:59:47 2014 -0500 @@ -396,7 +396,7 @@ defines the set of values @samp{[ 1, 4 ]}. Although a range constant specifies a row vector, Octave does @emph{not} -convert range constants to vectors unless it is necessary to do so. +normally convert range constants to vectors unless it is necessary to do so. This allows you to write a constant like @samp{1 : 10000} without using 80,000 bytes of storage on a typical 32-bit workstation. @@ -420,6 +420,11 @@ defines @var{y} to be of type @code{matrix} and occupies 88 bytes of memory. +This space saving optimization may be disabled using the function +@dfn{disable_range}. + +@DOCSTRING(disable_range) + Note that the upper (or lower, if the increment is negative) bound on the range is not always included in the set of values, and that ranges defined by floating point values can produce surprising results because diff -r 9464cfeede2b -r b39cbe9f3bb0 libinterp/octave-value/ov.cc --- a/libinterp/octave-value/ov.cc Mon Dec 08 10:18:35 2014 -0500 +++ b/libinterp/octave-value/ov.cc Mon Dec 08 12:59:47 2014 -0500 @@ -103,6 +103,10 @@ static bool Vdisable_permutation_matrix = false; +// If TRUE, don't create special range objects. + +static bool Vdisable_range = false; + // FIXME // Octave's value type. @@ -1203,8 +1207,10 @@ maybe_mutate (); } -octave_value::octave_value (const Range& r) - : rep (new octave_range (r)) +octave_value::octave_value (const Range& r, bool force_range) + : rep (force_range || ! Vdisable_range + ? dynamic_cast (new octave_range (r)) + : dynamic_cast (new octave_matrix (r.matrix_value ()))) { maybe_mutate (); } @@ -3244,3 +3250,35 @@ %!assert (typeinfo (fx), "float matrix"); %!assert (typeinfo (fxi), "float complex matrix"); */ + +DEFUN (disable_range, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {@var{val} =} disable_range ()\n\ +@deftypefnx {Built-in Function} {@var{old_val} =} disable_range (@var{new_val})\n\ +@deftypefnx {Built-in Function} {} disable_range (@var{new_val}, \"local\")\n\ +Query or set the internal variable that controls whether permutation\n\ +matrices are stored in a special space-efficient format. The default\n\ +value is true. If this option is disabled Octave will store permutation\n\ +matrices as full matrices.\n\ +\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls.\n\ +The original variable value is restored when exiting the function.\n\ +@end deftypefn") +{ + return SET_INTERNAL_VARIABLE (disable_range); +} + +/* +%!function r = __test_dr__ (dr) +%! disable_range (dr, "local"); +%! ## Constant folding will produce range for 1:13. +%! base = 1; +%! limit = 13; +%! r = base:limit; +%!endfunction + +%!assert (typeinfo (__test_dr__ (false)), "range"); +%!assert (typeinfo (__test_dr__ (true)), "matrix"); +*/ + diff -r 9464cfeede2b -r b39cbe9f3bb0 libinterp/octave-value/ov.h --- a/libinterp/octave-value/ov.h Mon Dec 08 10:18:35 2014 -0500 +++ b/libinterp/octave-value/ov.h Mon Dec 08 12:59:47 2014 -0500 @@ -281,7 +281,7 @@ octave_value (const Array& cellstr); octave_value (const idx_vector& idx, bool lazy = true); octave_value (double base, double limit, double inc); - octave_value (const Range& r); + octave_value (const Range& r, bool force_range = false); octave_value (const octave_map& m); octave_value (const octave_scalar_map& m); octave_value (const octave_map& m, const std::string& id, diff -r 9464cfeede2b -r b39cbe9f3bb0 libinterp/octave.cc --- a/libinterp/octave.cc Mon Dec 08 10:18:35 2014 -0500 +++ b/libinterp/octave.cc Mon Dec 08 12:59:47 2014 -0500 @@ -488,6 +488,7 @@ Fcrash_dumps_octave_core (octave_value (false)); Fdisable_diagonal_matrix (octave_value (true)); Fdisable_permutation_matrix (octave_value (true)); + Fdisable_range (octave_value (true)); Ffixed_point_format (octave_value (true)); Fhistory_timestamp_format_string (octave_value ("%%-- %D %I:%M %p --%%")); Fpage_screen_output (octave_value (false)); diff -r 9464cfeede2b -r b39cbe9f3bb0 libinterp/parse-tree/oct-parse.in.yy --- a/libinterp/parse-tree/oct-parse.in.yy Mon Dec 08 10:18:35 2014 -0500 +++ b/libinterp/parse-tree/oct-parse.in.yy Mon Dec 08 12:59:47 2014 -0500 @@ -2571,6 +2571,8 @@ if (end_token_ok (end_tok, parfor ? token::parfor_end : token::for_end)) { + expr->mark_as_for_cmd_expr (); + octave_comment_list *tc = lexer.comment_buf.get_comment (); lexer.looping--; diff -r 9464cfeede2b -r b39cbe9f3bb0 libinterp/parse-tree/pt-colon.cc --- a/libinterp/parse-tree/pt-colon.cc Mon Dec 08 10:18:35 2014 -0500 +++ b/libinterp/parse-tree/pt-colon.cc Mon Dec 08 12:59:47 2014 -0500 @@ -96,7 +96,12 @@ retval = Range (); else { - retval = Range (m_base(0), m_limit(0), m_increment(0)); + Range r (m_base(0), m_limit(0), m_increment(0)); + + // For compatibility with Matlab, don't allow the range used in + // a FOR loop expression to be converted to a Matrix. + + retval = octave_value (r, is_for_cmd_expr ()); if (result_is_str) retval = retval.convert_to_str (false, true, dq_str ? '"' : '\''); diff -r 9464cfeede2b -r b39cbe9f3bb0 libinterp/parse-tree/pt-exp.h --- a/libinterp/parse-tree/pt-exp.h Mon Dec 08 10:18:35 2014 -0500 +++ b/libinterp/parse-tree/pt-exp.h Mon Dec 08 12:59:47 2014 -0500 @@ -41,7 +41,7 @@ tree_expression (int l = -1, int c = -1) : tree (l, c), num_parens (0), postfix_index_type ('\0'), - print_flag (false) { } + for_cmd_expr (false), print_flag (false) { } virtual ~tree_expression (void) { } @@ -104,6 +104,10 @@ virtual void mark_braindead_shortcircuit (void) { } + void mark_as_for_cmd_expr (void) { for_cmd_expr = true; } + + bool is_for_cmd_expr (void) const { return for_cmd_expr; } + tree_expression *mark_in_parens (void) { num_parens++; @@ -144,6 +148,10 @@ // See the code in tree_identifier::rvalue for the rationale. char postfix_index_type; + // TRUE if this expression is the EXPR in for loop: + // FOR i = EXPR ... END + bool for_cmd_expr; + // Print result of rvalue for this expression? bool print_flag;