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