src/pt-eval.cc
author Jaroslav Hajek <highegg@gmail.com>
Fri Jul 03 18:59:07 2009 +0200 (2009-07-03)
changeset 9377 bcb3e85add22
parent 9355 88a5cb3e7b25
child 9399 0014ff1747a6
permissions -rw-r--r--
fix missing unwind_protect::run in pt-eval.cc
     1 /*
     2 
     3 Copyright (C) 2009 John W. Eaton
     4 
     5 This file is part of Octave.
     6 
     7 Octave is free software; you can redistribute it and/or modify it
     8 under the terms of the GNU General Public License as published by the
     9 Free Software Foundation; either version 3 of the License, or (at your
    10 option) any later version.
    11 
    12 Octave is distributed in the hope that it will be useful, but WITHOUT
    13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    15 for more details.
    16 
    17 You should have received a copy of the GNU General Public License
    18 along with Octave; see the file COPYING.  If not, see
    19 <http://www.gnu.org/licenses/>.
    20 
    21 */
    22 
    23 #ifdef HAVE_CONFIG_H
    24 #include <config.h>
    25 #endif
    26 
    27 #include <cctype>
    28 
    29 #include <iostream>
    30 
    31 #include <fstream>
    32 #include <typeinfo>
    33 
    34 #include "defun.h"
    35 #include "error.h"
    36 #include "gripes.h"
    37 #include "input.h"
    38 #include "ov-fcn-handle.h"
    39 #include "ov-usr-fcn.h"
    40 #include "variables.h"
    41 #include "pt-all.h"
    42 #include "pt-eval.h"
    43 #include "symtab.h"
    44 #include "unwind-prot.h"
    45 
    46 static tree_evaluator std_evaluator;
    47 
    48 tree_evaluator *current_evaluator = &std_evaluator;
    49 
    50 int tree_evaluator::dbstep_flag = 0;
    51 
    52 size_t tree_evaluator::current_frame = 0;
    53 
    54 bool tree_evaluator::debug_mode = false;
    55 
    56 bool tree_evaluator::in_fcn_or_script_body = false;
    57 
    58 bool tree_evaluator::in_loop_command = false;
    59 
    60 int tree_evaluator::db_line = -1;
    61 int tree_evaluator::db_column = -1;
    62 
    63 // If TRUE, turn off printing of results in functions (as if a
    64 // semicolon has been appended to each statement).
    65 static bool Vsilent_functions = false;
    66 
    67 // Normal evaluator.
    68 
    69 void
    70 tree_evaluator::visit_anon_fcn_handle (tree_anon_fcn_handle&)
    71 {
    72   panic_impossible ();
    73 }
    74 
    75 void
    76 tree_evaluator::visit_argument_list (tree_argument_list&)
    77 {
    78   panic_impossible ();
    79 }
    80 
    81 void
    82 tree_evaluator::visit_binary_expression (tree_binary_expression&)
    83 {
    84   panic_impossible ();
    85 }
    86 
    87 void
    88 tree_evaluator::visit_break_command (tree_break_command& cmd)
    89 {
    90   if (! error_state)
    91     {
    92       if (debug_mode)
    93 	do_breakpoint (cmd.is_breakpoint (), cmd.line (), cmd.column ());
    94 
    95       tree_break_command::breaking = 1;
    96     }
    97 }
    98 
    99 void
   100 tree_evaluator::visit_colon_expression (tree_colon_expression&)
   101 {
   102   panic_impossible ();
   103 }
   104 
   105 void
   106 tree_evaluator::visit_continue_command (tree_continue_command&)
   107 {
   108   if (! error_state)
   109     tree_continue_command::continuing = 1;
   110 }
   111 
   112 static inline void
   113 do_global_init (tree_decl_elt& elt)
   114 {
   115   tree_identifier *id = elt.ident ();
   116 
   117   if (id)
   118     {
   119       id->mark_global ();
   120 
   121       if (! error_state)
   122 	{
   123 	  octave_lvalue ult = id->lvalue ();
   124 
   125 	  if (ult.is_undefined ())
   126 	    {
   127 	      tree_expression *expr = elt.expression ();
   128 
   129 	      octave_value init_val;
   130 
   131 	      if (expr)
   132 		init_val = expr->rvalue1 ();
   133 	      else
   134 		init_val = Matrix ();
   135 
   136 	      ult.assign (octave_value::op_asn_eq, init_val);
   137 	    }
   138 	}
   139     }
   140 }
   141 
   142 static inline void
   143 do_static_init (tree_decl_elt& elt)
   144 {
   145   tree_identifier *id = elt.ident ();
   146 
   147   if (id)
   148     {
   149       id->mark_as_static ();
   150 
   151       octave_lvalue ult = id->lvalue ();
   152 
   153       if (ult.is_undefined ())
   154 	{
   155 	  tree_expression *expr = elt.expression ();
   156 
   157 	  octave_value init_val;
   158 
   159 	  if (expr)
   160 	    init_val = expr->rvalue1 ();
   161 	  else
   162 	    init_val = Matrix ();
   163 
   164 	  ult.assign (octave_value::op_asn_eq, init_val);
   165 	}
   166     }
   167 }
   168 
   169 void
   170 tree_evaluator::do_decl_init_list (decl_elt_init_fcn fcn,
   171 				   tree_decl_init_list *init_list)
   172 {
   173   if (init_list)
   174     {
   175       for (tree_decl_init_list::iterator p = init_list->begin ();
   176 	   p != init_list->end (); p++)
   177 	{
   178 	  tree_decl_elt *elt = *p;
   179 
   180 	  fcn (*elt);
   181 
   182 	  if (error_state)
   183 	    break;
   184 	}
   185     }
   186 }
   187 
   188 void
   189 tree_evaluator::visit_global_command (tree_global_command& cmd)
   190 {
   191   if (debug_mode)
   192     do_breakpoint (cmd.is_breakpoint (), cmd.line (), cmd.column ());
   193 
   194   do_decl_init_list (do_global_init, cmd.initializer_list ());
   195 }
   196 
   197 void
   198 tree_evaluator::visit_static_command (tree_static_command& cmd)
   199 {
   200   if (debug_mode)
   201     do_breakpoint (cmd.is_breakpoint (), cmd.line (), cmd.column ());
   202 
   203   do_decl_init_list (do_static_init, cmd.initializer_list ());
   204 }
   205 
   206 void
   207 tree_evaluator::visit_decl_elt (tree_decl_elt&)
   208 {
   209   panic_impossible ();
   210 }
   211 
   212 #if 0
   213 bool
   214 tree_decl_elt::eval (void)
   215 {
   216   bool retval = false;
   217 
   218   if (id && expr)
   219     {
   220       octave_lvalue ult = id->lvalue ();
   221 
   222       octave_value init_val = expr->rvalue1 ();
   223 
   224       if (! error_state)
   225        {
   226          ult.assign (octave_value::op_asn_eq, init_val);
   227 
   228          retval = true;
   229        }
   230     }
   231 
   232   return retval;
   233 }
   234 #endif
   235 
   236 void
   237 tree_evaluator::visit_decl_init_list (tree_decl_init_list&)
   238 {
   239   panic_impossible ();
   240 }
   241 
   242 // Decide if it's time to quit a for or while loop.
   243 static inline bool
   244 quit_loop_now (void)
   245 {
   246   OCTAVE_QUIT;
   247 
   248   // Maybe handle `continue N' someday...
   249 
   250   if (tree_continue_command::continuing)
   251     tree_continue_command::continuing--;
   252 
   253   bool quit = (error_state
   254 	       || tree_return_command::returning
   255 	       || tree_break_command::breaking
   256 	       || tree_continue_command::continuing);
   257 
   258   if (tree_break_command::breaking)
   259     tree_break_command::breaking--;
   260 
   261   return quit;
   262 }
   263 
   264 #define DO_SIMPLE_FOR_LOOP_ONCE(VAL) \
   265   do \
   266     { \
   267       ult.assign (octave_value::op_asn_eq, VAL); \
   268  \
   269       if (! error_state && loop_body) \
   270 	loop_body->accept (*this); \
   271  \
   272       quit = quit_loop_now (); \
   273     } \
   274   while (0)
   275 
   276 void
   277 tree_evaluator::visit_simple_for_command (tree_simple_for_command& cmd)
   278 {
   279   if (error_state)
   280     return;
   281 
   282   if (debug_mode)
   283     do_breakpoint (cmd.is_breakpoint (), cmd.line (), cmd.column ());
   284 
   285   unwind_protect::begin_frame ("tree_evaluator::visit_simple_for_command");
   286 
   287   unwind_protect_bool (in_loop_command);
   288 
   289   in_loop_command = true;
   290 
   291   tree_expression *expr = cmd.control_expr ();
   292 
   293   octave_value rhs = expr->rvalue1 ();
   294 
   295   if (error_state || rhs.is_undefined ())
   296     goto cleanup;
   297 
   298   {
   299     tree_expression *lhs = cmd.left_hand_side ();
   300 
   301     octave_lvalue ult = lhs->lvalue ();
   302 
   303     if (error_state)
   304       goto cleanup;
   305 
   306     tree_statement_list *loop_body = cmd.body ();
   307 
   308     if (rhs.is_range ())
   309       {
   310 	Range rng = rhs.range_value ();
   311 
   312 	octave_idx_type steps = rng.nelem ();
   313 	double b = rng.base ();
   314 	double increment = rng.inc ();
   315 	bool quit = false;
   316 
   317 	for (octave_idx_type i = 0; i < steps; i++)
   318 	  {
   319 	    // Use multiplication here rather than declaring a
   320 	    // temporary variable outside the loop and using
   321 	    //
   322 	    //   tmp_val += increment
   323 	    //
   324 	    // to avoid problems with limited precision.  Also, this
   325 	    // is consistent with the way Range::matrix_value is
   326 	    // implemented.
   327 
   328 	    octave_value val (b + i * increment);
   329 
   330 	    DO_SIMPLE_FOR_LOOP_ONCE (val);
   331 
   332 	    if (quit)
   333 	      break;
   334 	  }
   335       }
   336     else if (rhs.is_scalar_type ())
   337       {
   338 	bool quit = false;
   339 
   340 	DO_SIMPLE_FOR_LOOP_ONCE (rhs);
   341       }
   342     else if (rhs.is_matrix_type () || rhs.is_cell () || rhs.is_string ()
   343              || rhs.is_map ())
   344       {
   345         // A matrix or cell is reshaped to 2 dimensions and iterated by
   346         // columns.
   347 
   348         bool quit = false;
   349 
   350         dim_vector dv = rhs.dims ().redim (2);
   351 
   352         octave_idx_type nrows = dv(0), steps = dv(1);
   353 
   354         if (steps > 0)
   355           {
   356             octave_value arg = rhs;
   357             if (rhs.ndims () > 2)
   358               arg = arg.reshape (dv);
   359 
   360             // for row vectors, use single index to speed things up.
   361             octave_value_list idx;
   362             octave_idx_type iidx;
   363             if (nrows == 1)
   364               {
   365                 idx.resize (1);
   366                 iidx = 0;
   367               }
   368             else
   369               {
   370                 idx.resize (2);
   371                 idx(0) = octave_value::magic_colon_t;
   372                 iidx = 1;
   373               }
   374 
   375             for (octave_idx_type i = 1; i <= steps; i++)
   376               {
   377                 // do_index_op expects one-based indices.
   378                 idx(iidx) = i;
   379                 octave_value val = arg.do_index_op (idx);
   380                 DO_SIMPLE_FOR_LOOP_ONCE (val);
   381 
   382                 if (quit)
   383                   break;
   384               }
   385           }
   386       }
   387     else
   388       {
   389 	::error ("invalid type in for loop expression near line %d, column %d",
   390 		 cmd.line (), cmd.column ());
   391       }
   392   }
   393 
   394  cleanup:
   395   unwind_protect::run_frame ("tree_evaluator::visit_simple_for_command");
   396 }
   397 
   398 void
   399 tree_evaluator::visit_complex_for_command (tree_complex_for_command& cmd)
   400 {
   401   if (error_state)
   402     return;
   403 
   404   if (debug_mode)
   405     do_breakpoint (cmd.is_breakpoint (), cmd.line (), cmd.column ());
   406 
   407   unwind_protect::begin_frame ("tree_evaluator::visit_complex_for_command");
   408 
   409   unwind_protect_bool (in_loop_command);
   410 
   411   in_loop_command = true;
   412 
   413   tree_expression *expr = cmd.control_expr ();
   414 
   415   octave_value rhs = expr->rvalue1 ();
   416 
   417   if (error_state || rhs.is_undefined ())
   418     goto cleanup;
   419 
   420   if (rhs.is_map ())
   421     {
   422       // Cycle through structure elements.  First element of id_list
   423       // is set to value and the second is set to the name of the
   424       // structure element.
   425 
   426       tree_argument_list *lhs = cmd.left_hand_side ();
   427 
   428       tree_argument_list::iterator p = lhs->begin ();
   429 
   430       tree_expression *elt = *p++;
   431 
   432       octave_lvalue val_ref = elt->lvalue ();
   433 
   434       elt = *p;
   435 
   436       octave_lvalue key_ref = elt->lvalue ();
   437 
   438       const Octave_map tmp_val (rhs.map_value ());
   439 
   440       tree_statement_list *loop_body = cmd.body ();
   441 
   442       for (Octave_map::const_iterator q = tmp_val.begin (); q != tmp_val.end (); q++)
   443 	{
   444 	  octave_value key = tmp_val.key (q);
   445 
   446 	  const Cell val_lst = tmp_val.contents (q);
   447 
   448 	  octave_idx_type n = tmp_val.numel ();
   449 
   450 	  octave_value val = (n == 1) ? val_lst(0) : octave_value (val_lst);
   451 
   452 	  val_ref.assign (octave_value::op_asn_eq, val);
   453 	  key_ref.assign (octave_value::op_asn_eq, key);
   454 
   455 	  if (! error_state && loop_body)
   456 	    loop_body->accept (*this);
   457 
   458 	  if (quit_loop_now ())
   459 	    break;
   460 	}
   461     }
   462   else
   463     error ("in statement `for [X, Y] = VAL', VAL must be a structure");
   464 
   465  cleanup:
   466   unwind_protect::run_frame ("tree_evaluator::visit_complex_for_command");
   467 }
   468 
   469 void
   470 tree_evaluator::visit_octave_user_script (octave_user_script&)
   471 {
   472   panic_impossible ();
   473 }
   474 
   475 void
   476 tree_evaluator::visit_octave_user_function (octave_user_function&)
   477 {
   478   panic_impossible ();
   479 }
   480 
   481 void
   482 tree_evaluator::visit_octave_user_function_header (octave_user_function&)
   483 {
   484   panic_impossible ();
   485 }
   486 
   487 void
   488 tree_evaluator::visit_octave_user_function_trailer (octave_user_function&)
   489 {
   490   panic_impossible ();
   491 }
   492 
   493 void
   494 tree_evaluator::visit_function_def (tree_function_def& cmd)
   495 {
   496   octave_value fcn = cmd.function ();
   497 
   498   octave_function *f = fcn.function_value ();
   499 
   500   if (f)
   501     {
   502       std::string nm = f->name ();
   503 
   504       symbol_table::install_cmdline_function (nm, fcn);
   505 
   506       // Make sure that any variable with the same name as the new
   507       // function is cleared.
   508 
   509       symbol_table::varref (nm) = octave_value ();
   510     }
   511 }
   512 
   513 void
   514 tree_evaluator::visit_identifier (tree_identifier&)
   515 {
   516   panic_impossible ();
   517 }
   518 
   519 void
   520 tree_evaluator::visit_if_clause (tree_if_clause&)
   521 {
   522   panic_impossible ();
   523 }
   524 
   525 void
   526 tree_evaluator::visit_if_command (tree_if_command& cmd)
   527 {
   528   tree_if_command_list *lst = cmd.cmd_list ();
   529 
   530   if (lst)
   531     lst->accept (*this);
   532 }
   533 
   534 void
   535 tree_evaluator::visit_if_command_list (tree_if_command_list& lst)
   536 {
   537   for (tree_if_command_list::iterator p = lst.begin (); p != lst.end (); p++)
   538     {
   539       tree_if_clause *tic = *p;
   540 
   541       tree_expression *expr = tic->condition ();
   542 
   543       if (debug_mode && ! tic->is_else_clause ())
   544 	do_breakpoint (tic->is_breakpoint (), tic->line (), tic->column ());
   545 
   546       if (tic->is_else_clause () || expr->is_logically_true ("if"))
   547 	{
   548 	  if (! error_state)
   549 	    {
   550 	      tree_statement_list *stmt_lst = tic->commands ();
   551 
   552 	      if (stmt_lst)
   553 		stmt_lst->accept (*this);
   554 	    }
   555 
   556 	  break;
   557 	}
   558     }
   559 }
   560 
   561 void
   562 tree_evaluator::visit_index_expression (tree_index_expression&)
   563 {
   564   panic_impossible ();
   565 }
   566 
   567 void
   568 tree_evaluator::visit_matrix (tree_matrix&)
   569 {
   570   panic_impossible ();
   571 }
   572 
   573 void
   574 tree_evaluator::visit_cell (tree_cell&)
   575 {
   576   panic_impossible ();
   577 }
   578 
   579 void
   580 tree_evaluator::visit_multi_assignment (tree_multi_assignment&)
   581 {
   582   panic_impossible ();
   583 }
   584 
   585 void
   586 tree_evaluator::visit_no_op_command (tree_no_op_command& cmd)
   587 {
   588   if (debug_mode && cmd.is_end_of_fcn_or_script ())
   589     do_breakpoint (cmd.is_breakpoint (), cmd.line (), cmd.column (), true);
   590 }
   591 
   592 void
   593 tree_evaluator::visit_constant (tree_constant&)
   594 {
   595   panic_impossible ();
   596 }
   597 
   598 void
   599 tree_evaluator::visit_fcn_handle (tree_fcn_handle&)
   600 {
   601   panic_impossible ();
   602 }
   603 
   604 void
   605 tree_evaluator::visit_parameter_list (tree_parameter_list&)
   606 {
   607   panic_impossible ();
   608 }
   609 
   610 void
   611 tree_evaluator::visit_postfix_expression (tree_postfix_expression&)
   612 {
   613   panic_impossible ();
   614 }
   615 
   616 void
   617 tree_evaluator::visit_prefix_expression (tree_prefix_expression&)
   618 {
   619   panic_impossible ();
   620 }
   621 
   622 void
   623 tree_evaluator::visit_return_command (tree_return_command& cmd)
   624 {
   625   if (! error_state)
   626     {
   627       if (debug_mode)
   628 	do_breakpoint (cmd.is_breakpoint (), cmd.line (), cmd.column ());
   629 
   630       tree_return_command::returning = 1;
   631     }
   632 }
   633 
   634 void
   635 tree_evaluator::visit_return_list (tree_return_list&)
   636 {
   637   panic_impossible ();
   638 }
   639 
   640 void
   641 tree_evaluator::visit_simple_assignment (tree_simple_assignment&)
   642 {
   643   panic_impossible ();
   644 }
   645 
   646 void
   647 tree_evaluator::visit_statement (tree_statement& stmt)
   648 {
   649   tree_command *cmd = stmt.command ();
   650   tree_expression *expr = stmt.expression ();
   651 
   652   if (cmd || expr)
   653     {
   654       if (in_fcn_or_script_body)
   655 	{
   656 	  octave_call_stack::set_statement (&stmt);
   657 
   658 	  if (Vecho_executing_commands & ECHO_FUNCTIONS)
   659 	    stmt.echo_code ();
   660 	}
   661 
   662       try
   663 	{
   664 	  if (cmd)
   665 	    cmd->accept (*this);
   666 	  else
   667 	    {
   668 	      if (debug_mode)
   669 		do_breakpoint (expr->is_breakpoint (), expr->line (),
   670 			       expr->column ());
   671 
   672 	      if (in_fcn_or_script_body && Vsilent_functions)
   673 		expr->set_print_flag (false);
   674 
   675 	      // FIXME -- maybe all of this should be packaged in
   676 	      // one virtual function that returns a flag saying whether
   677 	      // or not the expression will take care of binding ans and
   678 	      // printing the result.
   679 
   680 	      // FIXME -- it seems that we should just have to
   681 	      // call expr->rvalue1 () and that should take care of
   682 	      // everything, binding ans as necessary?
   683 
   684 	      bool do_bind_ans = false;
   685 
   686 	      if (expr->is_identifier ())
   687 		{
   688 		  tree_identifier *id = dynamic_cast<tree_identifier *> (expr);
   689 
   690 		  do_bind_ans = (! id->is_variable ());
   691 		}
   692 	      else
   693 		do_bind_ans = (! expr->is_assignment_expression ());
   694 
   695 	      octave_value tmp_result = expr->rvalue1 (0);
   696 
   697 	      if (do_bind_ans && ! (error_state || tmp_result.is_undefined ()))
   698 		bind_ans (tmp_result, expr->print_result ());
   699 
   700 	      //	      if (tmp_result.is_defined ())
   701 	      //		result_values(0) = tmp_result;
   702 	    }
   703 	}
   704       catch (octave_execution_exception)
   705 	{
   706 	  gripe_library_execution_error ();
   707 	}
   708     }
   709 }
   710 
   711 void
   712 tree_evaluator::visit_statement_list (tree_statement_list& lst)
   713 {
   714   static octave_value_list empty_list;
   715 
   716   if (error_state)
   717     return;
   718 
   719   tree_statement_list::iterator p = lst.begin ();
   720 
   721   if (p != lst.end ())
   722     {
   723       while (true)
   724 	{
   725 	  tree_statement *elt = *p++;
   726 
   727 	  if (elt)
   728 	    {
   729 	      OCTAVE_QUIT;
   730 
   731 	      elt->accept (*this);
   732 
   733 	      if (error_state)
   734 		break;
   735 
   736 	      if (tree_break_command::breaking
   737 		  || tree_continue_command::continuing)
   738 		break;
   739 
   740 	      if (tree_return_command::returning)
   741 		break;
   742 
   743 	      if (p == lst.end ())
   744 		break;
   745 	      else
   746 		{
   747 		  // Clear preivous values before next statement is
   748 		  // evaluated so that we aren't holding an extra
   749 		  // reference to a value that may be used next.  For
   750 		  // example, in code like this:
   751 		  //
   752 		  //   X = rand (N);  ## refcount for X should be 1
   753 		  //                  ## after this statement
   754 		  //
   755 		  //   X(idx) = val;  ## no extra copy of X should be
   756 		  //                  ## needed, but we will be faked
   757 		  //                  ## out if retval is not cleared
   758 		  //                  ## between statements here
   759 
   760 		  //		  result_values = empty_list;
   761 		}
   762 	    }
   763 	  else
   764 	    error ("invalid statement found in statement list!");
   765 	}
   766     }
   767 }
   768 
   769 void
   770 tree_evaluator::visit_switch_case (tree_switch_case&)
   771 {
   772   panic_impossible ();
   773 }
   774 
   775 void
   776 tree_evaluator::visit_switch_case_list (tree_switch_case_list&)
   777 {
   778   panic_impossible ();
   779 }
   780 
   781 void
   782 tree_evaluator::visit_switch_command (tree_switch_command& cmd)
   783 {
   784   tree_expression *expr = cmd.switch_value ();
   785 
   786   if (expr)
   787     {
   788       octave_value val = expr->rvalue1 ();
   789 
   790       tree_switch_case_list *lst = cmd.case_list ();
   791 
   792       if (! error_state && lst)
   793 	{
   794 	  for (tree_switch_case_list::iterator p = lst->begin ();
   795 	       p != lst->end (); p++)
   796 	    {
   797 	      tree_switch_case *t = *p;
   798 
   799 	      if (debug_mode && ! t->is_default_case ())
   800 		do_breakpoint (t->is_breakpoint (), t->line (), t->column ());
   801 
   802 	      if (t->is_default_case () || t->label_matches (val))
   803 		{
   804 		  if (error_state)
   805 		    break;
   806 
   807 		  tree_statement_list *stmt_lst = t->commands ();
   808 
   809 		  if (stmt_lst)
   810 		    stmt_lst->accept (*this);
   811 
   812 		  break;
   813 		}
   814 	    }
   815 	}
   816     }
   817   else
   818     ::error ("missing value in switch command near line %d, column %d",
   819 	     cmd.line (), cmd.column ());
   820 }
   821 
   822 static void
   823 do_catch_code (void *ptr)
   824 {
   825   // Is it safe to call OCTAVE_QUIT here?  We are already running
   826   // something on the unwind_protect stack, but the element for this
   827   // action would have already been popped from the top of the stack,
   828   // so we should not be attempting to run it again.
   829 
   830   OCTAVE_QUIT;
   831 
   832   // If we are interrupting immediately, or if an interrupt is in
   833   // progress (octave_interrupt_state < 0), then we don't want to run
   834   // the catch code (it should only run on errors, not interrupts).
   835 
   836   // If octave_interrupt_state is positive, an interrupt is pending.
   837   // The only way that could happen would be for the interrupt to
   838   // come in after the OCTAVE_QUIT above and before the if statement
   839   // below -- it's possible, but unlikely.  In any case, we should
   840   // probably let the catch code throw the exception because we don't
   841   // want to skip that and potentially run some other code.  For
   842   // example, an error may have originally brought us here for some
   843   // cleanup operation and we shouldn't skip that.
   844 
   845   if (octave_interrupt_immediately || octave_interrupt_state < 0)
   846     return;
   847 
   848   tree_statement_list *list = static_cast<tree_statement_list *> (ptr);
   849 
   850   // Set up for letting the user print any messages from errors that
   851   // occurred in the body of the try_catch statement.
   852 
   853   buffer_error_messages--;
   854 
   855   if (list)
   856     list->accept (*current_evaluator);
   857 }
   858 
   859 void
   860 tree_evaluator::visit_try_catch_command (tree_try_catch_command& cmd)
   861 {
   862   unwind_protect::begin_frame ("tree_evaluator::visit_try_catch_command");
   863   
   864   unwind_protect_int (buffer_error_messages);
   865   unwind_protect_bool (Vdebug_on_error);
   866   unwind_protect_bool (Vdebug_on_warning);
   867 
   868   buffer_error_messages++;
   869   Vdebug_on_error = false;
   870   Vdebug_on_warning = false;
   871 
   872   tree_statement_list *catch_code = cmd.cleanup ();
   873 
   874   unwind_protect::add (do_catch_code, catch_code);
   875 
   876   tree_statement_list *try_code = cmd.body ();
   877 
   878   if (try_code)
   879     try_code->accept (*this);
   880 
   881   if (catch_code && error_state)
   882     {
   883       error_state = 0;
   884       unwind_protect::run_frame ("tree_evaluator::visit_try_catch_command");
   885     }
   886   else
   887     {
   888       error_state = 0;
   889 
   890       // Unwind stack elements must be cleared or run in the reverse
   891       // order in which they were added to the stack.
   892 
   893       // For clearing the do_catch_code cleanup function.
   894       unwind_protect::discard ();
   895 
   896       // For restoring Vdebug_on_warning, Vdebug_on_error, and
   897       // buffer_error_messages.
   898       unwind_protect::run ();
   899       unwind_protect::run ();
   900       unwind_protect::run ();
   901 
   902       // Also clear the frame marker.
   903       unwind_protect::discard ();
   904     }
   905 }
   906 
   907 void restore_interrupt_state (void *ptr)
   908 {
   909   octave_interrupt_state = *(reinterpret_cast<sig_atomic_t *> (ptr));
   910 }
   911 
   912 static void
   913 do_unwind_protect_cleanup_code (void *ptr)
   914 {
   915   tree_statement_list *list = static_cast<tree_statement_list *> (ptr);
   916 
   917   sig_atomic_t saved_octave_interrupt_state = octave_interrupt_state;
   918   unwind_protect::add (restore_interrupt_state, &saved_octave_interrupt_state);
   919   octave_interrupt_state = 0;
   920 
   921   // We want to run the cleanup code without error_state being set,
   922   // but we need to restore its value, so that any errors encountered
   923   // in the first part of the unwind_protect are not completely
   924   // ignored.
   925 
   926   unwind_protect_int (error_state);
   927   error_state = 0;
   928 
   929   // Similarly, if we have seen a return or break statement, allow all
   930   // the cleanup code to run before returning or handling the break.
   931   // We don't have to worry about continue statements because they can
   932   // only occur in loops.
   933 
   934   unwind_protect_int (tree_return_command::returning);
   935   tree_return_command::returning = 0;
   936 
   937   unwind_protect_int (tree_break_command::breaking);
   938   tree_break_command::breaking = 0;
   939 
   940   if (list)
   941     list->accept (*current_evaluator);
   942 
   943   // The unwind_protects are popped off the stack in the reverse of
   944   // the order they are pushed on.
   945 
   946   // FIXME -- these statements say that if we see a break or
   947   // return statement in the cleanup block, that we want to use the
   948   // new value of the breaking or returning flag instead of restoring
   949   // the previous value.  Is that the right thing to do?  I think so.
   950   // Consider the case of
   951   //
   952   //   function foo ()
   953   //     unwind_protect
   954   //       stderr << "1: this should always be executed\n";
   955   //       break;
   956   //       stderr << "1: this should never be executed\n";
   957   //     unwind_protect_cleanup
   958   //       stderr << "2: this should always be executed\n";
   959   //       return;
   960   //       stderr << "2: this should never be executed\n";
   961   //     end_unwind_protect
   962   //   endfunction
   963   //
   964   // If we reset the value of the breaking flag, both the returning
   965   // flag and the breaking flag will be set, and we shouldn't have
   966   // both.  So, use the most recent one.  If there is no return or
   967   // break in the cleanup block, the values should be reset to
   968   // whatever they were when the cleanup block was entered.
   969 
   970   if (tree_break_command::breaking || tree_return_command::returning)
   971     {
   972       unwind_protect::discard ();
   973       unwind_protect::discard ();
   974     }
   975   else
   976     {
   977       unwind_protect::run ();
   978       unwind_protect::run ();
   979     }
   980 
   981   // We don't want to ignore errors that occur in the cleanup code, so
   982   // if an error is encountered there, leave error_state alone.
   983   // Otherwise, set it back to what it was before.
   984 
   985   if (error_state)
   986     unwind_protect::discard ();
   987   else
   988     unwind_protect::run ();
   989 
   990   unwind_protect::run ();
   991 }
   992 
   993 void
   994 tree_evaluator::visit_unwind_protect_command (tree_unwind_protect_command& cmd)
   995 {
   996   tree_statement_list *cleanup_code = cmd.cleanup ();
   997 
   998   unwind_protect::add (do_unwind_protect_cleanup_code, cleanup_code);
   999 
  1000   tree_statement_list *unwind_protect_code = cmd.body ();
  1001 
  1002   if (unwind_protect_code)
  1003     unwind_protect_code->accept (*this);
  1004 
  1005   unwind_protect::run ();
  1006 }
  1007 
  1008 void
  1009 tree_evaluator::visit_while_command (tree_while_command& cmd)
  1010 {
  1011   if (error_state)
  1012     return;
  1013 
  1014   unwind_protect::begin_frame ("tree_evaluator::visit_while_command");
  1015 
  1016   unwind_protect_bool (in_loop_command);
  1017 
  1018   in_loop_command = true;
  1019 
  1020   tree_expression *expr = cmd.condition ();
  1021 
  1022   if (! expr)
  1023     panic_impossible ();
  1024 
  1025   int l = expr->line ();
  1026   int c = expr->column ();
  1027 
  1028   for (;;)
  1029     {
  1030       if (debug_mode)
  1031 	do_breakpoint (cmd.is_breakpoint (), l, c);
  1032 
  1033       if (expr->is_logically_true ("while"))
  1034 	{
  1035 	  tree_statement_list *loop_body = cmd.body ();
  1036 
  1037 	  if (loop_body)
  1038 	    {
  1039 	      loop_body->accept (*this);
  1040 
  1041 	      if (error_state)
  1042 		goto cleanup;
  1043 	    }
  1044 
  1045 	  if (quit_loop_now ())
  1046 	    break;
  1047 	}
  1048       else
  1049 	break;
  1050     }
  1051 
  1052  cleanup:
  1053   unwind_protect::run_frame ("tree_evaluator::visit_while_command");
  1054 }
  1055 
  1056 void
  1057 tree_evaluator::visit_do_until_command (tree_do_until_command& cmd)
  1058 {
  1059   if (error_state)
  1060     return;
  1061 
  1062   unwind_protect::begin_frame ("tree_evaluator::visit_do_until_command");
  1063 
  1064   unwind_protect_bool (in_loop_command);
  1065 
  1066   in_loop_command = true;
  1067 
  1068   tree_expression *expr = cmd.condition ();
  1069 
  1070   if (! expr)
  1071     panic_impossible ();
  1072 
  1073   int l = expr->line ();
  1074   int c = expr->column ();
  1075 
  1076   for (;;)
  1077     {
  1078       tree_statement_list *loop_body = cmd.body ();
  1079 
  1080       if (loop_body)
  1081 	{
  1082 	  loop_body->accept (*this);
  1083 
  1084 	  if (error_state)
  1085 	    goto cleanup;
  1086 	}
  1087 
  1088       if (quit_loop_now ())
  1089 	break;
  1090 
  1091       if (debug_mode)
  1092 	do_breakpoint (cmd.is_breakpoint (), l, c);
  1093 
  1094       if (expr->is_logically_true ("do-until"))
  1095 	break;
  1096     }
  1097 
  1098  cleanup:
  1099   unwind_protect::run_frame ("tree_evaluator::visit_do_until_command");
  1100 }
  1101 
  1102 void
  1103 tree_evaluator::do_breakpoint (tree_statement& stmt) const
  1104 {
  1105   do_breakpoint (stmt.is_breakpoint (), stmt.line (), stmt.column (),
  1106 		 stmt.is_end_of_fcn_or_script ());
  1107 }
  1108 
  1109 void
  1110 tree_evaluator::do_breakpoint (bool is_breakpoint, int l, int c,
  1111 			       bool is_end_of_fcn_or_script) const
  1112 {
  1113   bool break_on_this_statement = false;
  1114 
  1115   // Don't decrement break flag unless we are in the same frame as we
  1116   // were when we saw the "dbstep N" command.
  1117 
  1118   if (dbstep_flag > 1)
  1119     {
  1120       if (octave_call_stack::current_frame () == current_frame)
  1121 	{
  1122 	  // Don't allow dbstep N to step past end of current frame.
  1123 
  1124 	  if (is_end_of_fcn_or_script)
  1125 	    dbstep_flag = 1;
  1126 	  else
  1127 	    dbstep_flag--;
  1128 	}
  1129     }
  1130 
  1131   if (octave_debug_on_interrupt_state)
  1132     {
  1133       break_on_this_statement = true;
  1134 
  1135       octave_debug_on_interrupt_state = false;
  1136 
  1137       current_frame = octave_call_stack::current_frame ();
  1138     }
  1139   else if (is_breakpoint)
  1140     {
  1141       break_on_this_statement = true;
  1142 
  1143       dbstep_flag = 0;
  1144 
  1145       current_frame = octave_call_stack::current_frame ();
  1146     }
  1147   else if (dbstep_flag == 1)
  1148     {
  1149       if (octave_call_stack::current_frame () == current_frame)
  1150 	{
  1151 	  // We get here if we are doing a "dbstep" or a "dbstep N"
  1152 	  // and the count has reached 1 and we are in the current
  1153 	  // debugging frame.
  1154 
  1155 	  break_on_this_statement = true;
  1156 
  1157 	  dbstep_flag = 0;
  1158 	}
  1159     }
  1160   else if (dbstep_flag == -1)
  1161     {
  1162       // We get here if we are doing a "dbstep in".
  1163 
  1164       break_on_this_statement = true;
  1165 
  1166       dbstep_flag = 0;
  1167 
  1168       current_frame = octave_call_stack::current_frame ();
  1169     }
  1170   else if (dbstep_flag == -2)
  1171     {
  1172       // We get here if we are doing a "dbstep out".
  1173 
  1174       if (is_end_of_fcn_or_script)
  1175 	dbstep_flag = -1;
  1176     }
  1177 
  1178   if (break_on_this_statement)
  1179     {
  1180       octave_function *xfcn = octave_call_stack::current ();
  1181 
  1182       if (xfcn)
  1183 	std::cerr << xfcn->name () << ": "; 
  1184 
  1185       std::cerr << "line " << l << ", " << "column " << c << std::endl;
  1186 
  1187       db_line = l;
  1188       db_column = c;
  1189 
  1190       // FIXME -- probably we just want to print one line, not the
  1191       // entire statement, which might span many lines...
  1192       //
  1193       // tree_print_code tpc (octave_stdout);
  1194       // stmt.accept (tpc);
  1195 
  1196       do_keyboard ();
  1197     }
  1198 }
  1199 
  1200 DEFUN (silent_functions, args, nargout,
  1201   "-*- texinfo -*-\n\
  1202 @deftypefn {Built-in Function} {@var{val} =} silent_functions ()\n\
  1203 @deftypefnx {Built-in Function} {@var{old_val} =} silent_functions (@var{new_val})\n\
  1204 Query or set the internal variable that controls whether internal\n\
  1205 output from a function is suppressed.  If this option is disabled,\n\
  1206 Octave will display the results produced by evaluating expressions\n\
  1207 within a function body that are not terminated with a semicolon.\n\
  1208 @end deftypefn")
  1209 {
  1210   return SET_INTERNAL_VARIABLE (silent_functions);
  1211 }
  1212 
  1213 /*
  1214 ;;; Local Variables: ***
  1215 ;;; mode: C++ ***
  1216 ;;; End: ***
  1217 */