Mercurial > hg > octave-nkf
changeset 19589: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 +++ b/doc/interpreter/basics.txi @@ -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 +++ b/doc/interpreter/numbers.txi @@ -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 +++ b/libinterp/octave-value/ov.cc @@ -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 +++ b/libinterp/octave-value/ov.h @@ -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 +++ b/libinterp/octave.cc @@ -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 +++ b/libinterp/parse-tree/oct-parse.in.yy @@ -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 +++ b/libinterp/parse-tree/pt-colon.cc @@ -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 +++ b/libinterp/parse-tree/pt-exp.h @@ -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;