# HG changeset patch # User jwe # Date 949050874 0 # Node ID cbee5fbb696d44fbea7208abb850c8dd4c53c0ef # Parent 85c0ebb78d1e809329d503f93de7bbe37326833e [project @ 2000-01-28 09:14:32 by jwe] diff -r 85c0ebb78d1e -r cbee5fbb696d doc/interpreter/octave.texi --- a/doc/interpreter/octave.texi Fri Jan 28 06:47:58 2000 +0000 +++ b/doc/interpreter/octave.texi Fri Jan 28 09:14:34 2000 +0000 @@ -161,6 +161,7 @@ + @detailmenu --- The Detailed Node Listing --- @@ -284,6 +285,7 @@ * The if Statement:: * The switch Statement:: * The while Statement:: +* The do-until Statement:: * The for Statement:: * The break Statement:: * The continue Statement:: @@ -391,6 +393,7 @@ Statistics * Basic Statistical Functions:: +* Tests:: * Models:: * Distributions:: diff -r 85c0ebb78d1e -r cbee5fbb696d doc/interpreter/stmt.txi --- a/doc/interpreter/stmt.txi Fri Jan 28 06:47:58 2000 +0000 +++ b/doc/interpreter/stmt.txi Fri Jan 28 09:14:34 2000 +0000 @@ -35,6 +35,7 @@ * The if Statement:: * The switch Statement:: * The while Statement:: +* The do-until Statement:: * The for Statement:: * The break Statement:: * The continue Statement:: @@ -293,7 +294,7 @@ @DOCSTRING(warn_variable_switch_label) -@node The while Statement, The for Statement, The switch Statement, Statements +@node The while Statement, The do-until Statement, The switch Statement, Statements @section The @code{while} Statement @cindex @code{while} statement @cindex @code{endwhile} statement @@ -365,7 +366,57 @@ @xref{The if Statement}, for a description of the variable @code{warn_assign_as_truth_value}. -@node The for Statement, The break Statement, The while Statement, Statements +@node The do-until Statement, The for Statement, The while Statement, Statements +@section The @code{do-until} Statement +@cindex @code{do-until} statement + +The @code{do-until} statement is similar to the @code{while} statement, +except that it repeatedly executes a statement until a condition becomes +true, and the test of the condition is at the end of the loop, so the +body of the loop is always executed at least once. As with the +condition in an @code{if} statement, the condition in a @code{do-until} +statement is considered true if its value is non-zero, and false if its +value is zero. If the value of the conditional expression in a +@code{do-until} statement is a vector or a matrix, it is considered +true only if @emph{all} of the elements are non-zero. + +Octave's @code{do-until} statement looks like this: + +@example +@group +do + @var{body} +until (@var{condition}) +@end group +@end example + +@noindent +Here @var{body} is a statement or list of statements that we call the +@dfn{body} of the loop, and @var{condition} is an expression that +controls how long the loop keeps running. + +This example creates a variable @code{fib} that contains the first ten +elements of the Fibonacci sequence. + +@example +@group +fib = ones (1, 10); +i = 2; +do + i++; + fib (i) = fib (i-1) + fib (i-2); +until (i == 10) +@end group +@end example + +A newline is not required between the @code{do} keyword and the +body; but using one makes the program clearer unless the body is very +simple. + +@xref{The if Statement}, for a description of the variable +@code{warn_assign_as_truth_value}. + +@node The for Statement, The break Statement, The do-until Statement, Statements @section The @code{for} Statement @cindex @code{for} statement @cindex @code{endfor} statement diff -r 85c0ebb78d1e -r cbee5fbb696d src/ChangeLog --- a/src/ChangeLog Fri Jan 28 06:47:58 2000 +0000 +++ b/src/ChangeLog Fri Jan 28 09:14:34 2000 +0000 @@ -1,3 +1,15 @@ +2000-01-28 John W. Eaton + + * parse.y (evaluating_function_body): New global flag. + * ov-usr-fcn.cc (octave_user_function::do_index_op): + Protect and set it here. + * parse.y (make_break_command, make_return_command): Check it here. + + * error.cc (warning_state): New global flag. + (warning): Set it here. + * lex.l (reset_parser): Clear it here. + * parse.y (fold): Check it here. + 2000-01-27 John W. Eaton * pt-walk.h (tree_walker::visit_do_until_command): New pure virtual. diff -r 85c0ebb78d1e -r cbee5fbb696d src/error.cc --- a/src/error.cc Fri Jan 28 06:47:58 2000 +0000 +++ b/src/error.cc Fri Jan 28 09:14:34 2000 +0000 @@ -46,6 +46,9 @@ // Current error state. int error_state = 0; +// Current warning state. +int warning_state = 0; + // Tell the error handler whether to print messages, or just store // them for later. Used for handling errors in eval() and // the `unwind_protect' statement. @@ -171,6 +174,7 @@ { va_list args; va_start (args, fmt); + warning_state = 1; verror ("warning", fmt, args); va_end (args); } diff -r 85c0ebb78d1e -r cbee5fbb696d src/error.h --- a/src/error.h Fri Jan 28 06:47:58 2000 +0000 +++ b/src/error.h Fri Jan 28 09:14:34 2000 +0000 @@ -39,6 +39,9 @@ // Current error state. extern int error_state; +// Current warning state. +extern int warning_state; + // Tell the error handler whether to print messages, or just store // them for later. Used for handling errors in eval() and // the `unwind_protect' statement. diff -r 85c0ebb78d1e -r cbee5fbb696d src/lex.l --- a/src/lex.l Fri Jan 28 06:47:58 2000 +0000 +++ b/src/lex.l Fri Jan 28 09:14:34 2000 +0000 @@ -739,6 +739,7 @@ // Start off on the right foot. BEGIN 0; error_state = 0; + warning_state = 0; // We do want a prompt by default. promptflag = 1; diff -r 85c0ebb78d1e -r cbee5fbb696d src/ov-usr-fcn.cc --- a/src/ov-usr-fcn.cc Fri Jan 28 06:47:58 2000 +0000 +++ b/src/ov-usr-fcn.cc Fri Jan 28 09:14:34 2000 +0000 @@ -47,6 +47,7 @@ #include "toplev.h" #include "unwind-prot.h" #include "utils.h" +#include "parse.h" #include "variables.h" // If TRUE, variables returned from functions have default values even @@ -378,6 +379,9 @@ // Evaluate the commands that make up the function. + unwind_protect_bool (evaluating_function_body); + evaluating_function_body = true; + octave_value_list tmp = cmd_list->eval (); octave_value last_computed_value; diff -r 85c0ebb78d1e -r cbee5fbb696d src/parse.h --- a/src/parse.h Fri Jan 28 06:47:58 2000 +0000 +++ b/src/parse.h Fri Jan 28 09:14:34 2000 +0000 @@ -69,6 +69,11 @@ // the command line. extern bool input_from_command_line_file; +// TRUE means that we are in the process of evaluating a function +// body. The parser might be called in that case if we are looking at +// an eval() statement. +extern bool evaluating_function_body; + // TRUE means warn about function files that have time stamps in the future. extern bool Vwarn_future_time_stamp; diff -r 85c0ebb78d1e -r cbee5fbb696d src/parse.y --- a/src/parse.y Fri Jan 28 06:47:58 2000 +0000 +++ b/src/parse.y Fri Jan 28 09:14:34 2000 +0000 @@ -117,6 +117,11 @@ // the command line. bool input_from_command_line_file = true; +// TRUE means that we are in the process of evaluating a function +// body. The parser might be called in that case if we are looking at +// an eval() statement. +bool evaluating_function_body = false; + // Forward declarations for some functions defined at the bottom of // the file. @@ -1617,7 +1622,7 @@ { octave_value tmp = e->rvalue (); - if (! error_state) + if (! (error_state || warning_state)) { tree_constant *tc_retval = new tree_constant (tmp); @@ -1666,7 +1671,7 @@ { octave_value tmp = e->rvalue (); - if (! error_state) + if (! (error_state || warning_state)) { tree_constant *tc_retval = new tree_constant (tmp); @@ -1724,7 +1729,7 @@ { octave_value tmp = e->rvalue (); - if (! error_state) + if (! (error_state || warning_state)) { tree_constant *tc_retval = new tree_constant (tmp); @@ -2143,7 +2148,8 @@ int l = break_tok->line (); int c = break_tok->column (); - if (lexer_flags.looping || lexer_flags.defining_func || reading_script_file) + if (lexer_flags.looping || lexer_flags.defining_func + || reading_script_file || evaluating_function_body) retval = new tree_break_command (l, c); else retval = new tree_no_op_command ("break", l, c); @@ -2179,7 +2185,8 @@ int l = return_tok->line (); int c = return_tok->column (); - if (lexer_flags.defining_func || reading_script_file) + if (lexer_flags.defining_func || reading_script_file + || evaluating_function_body) retval = new tree_return_command (l, c); else retval = new tree_no_op_command ("return", l, c); @@ -2554,7 +2561,7 @@ { octave_value tmp = m->rvalue (); - if (! error_state) + if (! (error_state || warning_state)) { tree_constant *tc_retval = new tree_constant (tmp);