changeset 19428:b39cbe9f3bb0

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.
author John W. Eaton <jwe@octave.org>
date Mon, 08 Dec 2014 12:59:47 -0500
parents 9464cfeede2b
children fb09907f4e49
files doc/interpreter/basics.txi doc/interpreter/numbers.txi libinterp/octave-value/ov.cc libinterp/octave-value/ov.h libinterp/octave.cc libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/pt-colon.cc libinterp/parse-tree/pt-exp.h
diffstat 8 files changed, 66 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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
--- 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<octave_base_value *> (new octave_range (r))
+         : dynamic_cast<octave_base_value *> (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");
+*/
+
--- 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<std::string>& 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,
--- 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));
--- 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--;
--- 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 ? '"' : '\'');
--- 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;