comparison libinterp/parse-tree/pt-eval.cc @ 22196:dd992fd74fce

put parser, lexer, and evaluator in namespace; interpreter now owns evaluator * oct-parse.in.yy, parse.h: Move parser classes to octave namespace. * lex.ll, lex.h: Move lexer classes to octave namespace. * pt-eval.h, pt-eval.cc: Move evaluator class to octave namespace. Don't define global current evaluator pointer here. * debug.cc, error.cc, input.cc, input.h, ls-mat-ascii.cc, pt-jit.cc, sighandlers.cc, utils.cc, variables.cc, ov-usr-fcn.cc, pt-assign.cc, pt-exp.h, pt-id.cc: Update for namespaces. * interpreter.cc, interpreter.h (current_evaluator): New global var. (interpreter::m_evaluator): New data member. (interpreter::~interpreter): Delete evaluator.
author John W. Eaton <jwe@octave.org>
date Tue, 12 Jul 2016 14:28:07 -0400
parents 5d4a286061c8
children bac0d6f07a3e
comparison
equal deleted inserted replaced
22195:93ed9396f2c3 22196:dd992fd74fce
47 #include "unwind-prot.h" 47 #include "unwind-prot.h"
48 48
49 //FIXME: This should be part of tree_evaluator 49 //FIXME: This should be part of tree_evaluator
50 #include "pt-jit.h" 50 #include "pt-jit.h"
51 51
52 static tree_evaluator std_evaluator;
53
54 tree_evaluator *current_evaluator = &std_evaluator;
55
56 int tree_evaluator::dbstep_flag = 0;
57
58 size_t tree_evaluator::current_frame = 0;
59
60 bool tree_evaluator::debug_mode = false;
61
62 bool tree_evaluator::quiet_breakpoint_flag = false;
63
64 tree_evaluator::stmt_list_type tree_evaluator::statement_context
65 = tree_evaluator::other;
66
67 bool tree_evaluator::in_loop_command = false;
68
69 // Maximum nesting level for functions, scripts, or sourced files called 52 // Maximum nesting level for functions, scripts, or sourced files called
70 // recursively. 53 // recursively.
71 int Vmax_recursion_depth = 256; 54 int Vmax_recursion_depth = 256;
72 55
73 // If TRUE, turn off printing of results in functions (as if a 56 // If TRUE, turn off printing of results in functions (as if a
74 // semicolon has been appended to each statement). 57 // semicolon has been appended to each statement).
75 static bool Vsilent_functions = false; 58 static bool Vsilent_functions = false;
76 59
77 // Normal evaluator. 60 namespace octave
78
79 void
80 tree_evaluator::visit_anon_fcn_handle (tree_anon_fcn_handle&)
81 { 61 {
82 panic_impossible (); 62 int tree_evaluator::dbstep_flag = 0;
83 } 63
84 64 size_t tree_evaluator::current_frame = 0;
85 void 65
86 tree_evaluator::visit_argument_list (tree_argument_list&) 66 bool tree_evaluator::debug_mode = false;
87 { 67
88 panic_impossible (); 68 bool tree_evaluator::quiet_breakpoint_flag = false;
89 } 69
90 70 tree_evaluator::stmt_list_type tree_evaluator::statement_context
91 void 71 = tree_evaluator::other;
92 tree_evaluator::visit_binary_expression (tree_binary_expression&) 72
93 { 73 bool tree_evaluator::in_loop_command = false;
94 panic_impossible (); 74
95 } 75 // Normal evaluator.
96 76
97 void 77 void
98 tree_evaluator::visit_break_command (tree_break_command& cmd) 78 tree_evaluator::visit_anon_fcn_handle (tree_anon_fcn_handle&)
99 { 79 {
100 if (debug_mode) 80 panic_impossible ();
101 do_breakpoint (cmd.is_breakpoint (true)); 81 }
102 82
103 if (statement_context == function || statement_context == script 83 void
104 || in_loop_command) 84 tree_evaluator::visit_argument_list (tree_argument_list&)
105 tree_break_command::breaking = 1; 85 {
106 } 86 panic_impossible ();
107 87 }
108 void 88
109 tree_evaluator::visit_colon_expression (tree_colon_expression&) 89 void
110 { 90 tree_evaluator::visit_binary_expression (tree_binary_expression&)
111 panic_impossible (); 91 {
112 } 92 panic_impossible ();
113 93 }
114 void 94
115 tree_evaluator::visit_continue_command (tree_continue_command& cmd) 95 void
116 { 96 tree_evaluator::visit_break_command (tree_break_command& cmd)
117 if (debug_mode) 97 {
118 do_breakpoint (cmd.is_breakpoint (true)); 98 if (debug_mode)
119 99 do_breakpoint (cmd.is_breakpoint (true));
120 if (statement_context == function || statement_context == script 100
121 || in_loop_command) 101 if (statement_context == function || statement_context == script
122 tree_continue_command::continuing = 1; 102 || in_loop_command)
123 } 103 tree_break_command::breaking = 1;
124 104 }
125 void 105
126 tree_evaluator::reset_debug_state (void) 106 void
127 { 107 tree_evaluator::visit_colon_expression (tree_colon_expression&)
128 debug_mode = bp_table::have_breakpoints () || Vdebugging; 108 {
129 109 panic_impossible ();
130 dbstep_flag = 0; 110 }
131 } 111
132 112 void
133 bool 113 tree_evaluator::visit_continue_command (tree_continue_command& cmd)
134 tree_evaluator::statement_printing_enabled (void) 114 {
135 { 115 if (debug_mode)
136 return ! (Vsilent_functions && (statement_context == function 116 do_breakpoint (cmd.is_breakpoint (true));
137 || statement_context == script)); 117
118 if (statement_context == function || statement_context == script
119 || in_loop_command)
120 tree_continue_command::continuing = 1;
121 }
122
123 void
124 tree_evaluator::reset_debug_state (void)
125 {
126 debug_mode = bp_table::have_breakpoints () || Vdebugging;
127
128 dbstep_flag = 0;
129 }
130
131 bool
132 tree_evaluator::statement_printing_enabled (void)
133 {
134 return ! (Vsilent_functions && (statement_context == function
135 || statement_context == script));
136 }
138 } 137 }
139 138
140 static inline void 139 static inline void
141 do_global_init (tree_decl_elt& elt) 140 do_global_init (tree_decl_elt& elt)
142 { 141 {
189 ult.assign (octave_value::op_asn_eq, init_val); 188 ult.assign (octave_value::op_asn_eq, init_val);
190 } 189 }
191 } 190 }
192 } 191 }
193 192
194 void 193 namespace octave
195 tree_evaluator::do_decl_init_list (decl_elt_init_fcn fcn,
196 tree_decl_init_list *init_list)
197 { 194 {
198 if (init_list) 195 void
199 { 196 tree_evaluator::do_decl_init_list (decl_elt_init_fcn fcn,
200 for (tree_decl_init_list::iterator p = init_list->begin (); 197 tree_decl_init_list *init_list)
201 p != init_list->end (); p++) 198 {
202 { 199 if (init_list)
203 tree_decl_elt *elt = *p; 200 {
204 201 for (tree_decl_init_list::iterator p = init_list->begin ();
205 fcn (*elt); 202 p != init_list->end (); p++)
206 } 203 {
207 } 204 tree_decl_elt *elt = *p;
208 } 205
209 206 fcn (*elt);
210 void 207 }
211 tree_evaluator::visit_global_command (tree_global_command& cmd) 208 }
212 { 209 }
213 if (debug_mode) 210
214 do_breakpoint (cmd.is_breakpoint (true)); 211 void
215 212 tree_evaluator::visit_global_command (tree_global_command& cmd)
216 do_decl_init_list (do_global_init, cmd.initializer_list ()); 213 {
217 } 214 if (debug_mode)
218 215 do_breakpoint (cmd.is_breakpoint (true));
219 void 216
220 tree_evaluator::visit_persistent_command (tree_persistent_command& cmd) 217 do_decl_init_list (do_global_init, cmd.initializer_list ());
221 { 218 }
222 if (debug_mode) 219
223 do_breakpoint (cmd.is_breakpoint (true)); 220 void
224 221 tree_evaluator::visit_persistent_command (tree_persistent_command& cmd)
225 do_decl_init_list (do_static_init, cmd.initializer_list ()); 222 {
226 } 223 if (debug_mode)
227 224 do_breakpoint (cmd.is_breakpoint (true));
228 void 225
229 tree_evaluator::visit_decl_elt (tree_decl_elt&) 226 do_decl_init_list (do_static_init, cmd.initializer_list ());
230 { 227 }
231 panic_impossible (); 228
232 } 229 void
233 230 tree_evaluator::visit_decl_elt (tree_decl_elt&)
234 #if 0 231 {
235 bool 232 panic_impossible ();
236 tree_decl_elt::eval (void) 233 }
237 { 234
238 bool retval = false; 235 void
239 236 tree_evaluator::visit_decl_init_list (tree_decl_init_list&)
240 if (id && expr) 237 {
241 { 238 panic_impossible ();
242 octave_lvalue ult = id->lvalue (); 239 }
243
244 octave_value init_val = expr->rvalue1 ();
245
246 ult.assign (octave_value::op_asn_eq, init_val);
247
248 retval = true;
249 }
250
251 return retval;
252 }
253 #endif
254
255 void
256 tree_evaluator::visit_decl_init_list (tree_decl_init_list&)
257 {
258 panic_impossible ();
259 } 240 }
260 241
261 // Decide if it's time to quit a for or while loop. 242 // Decide if it's time to quit a for or while loop.
262 static inline bool 243 static inline bool
263 quit_loop_now (void) 244 quit_loop_now (void)
277 tree_break_command::breaking--; 258 tree_break_command::breaking--;
278 259
279 return quit; 260 return quit;
280 } 261 }
281 262
282 void 263 namespace octave
283 tree_evaluator::visit_simple_for_command (tree_simple_for_command& cmd)
284 { 264 {
285 if (debug_mode) 265 void
286 do_breakpoint (cmd.is_breakpoint (true)); 266 tree_evaluator::visit_simple_for_command (tree_simple_for_command& cmd)
287 267 {
288 // FIXME: need to handle PARFOR loops here using cmd.in_parallel () 268 if (debug_mode)
289 // and cmd.maxproc_expr (); 269 do_breakpoint (cmd.is_breakpoint (true));
290 270
291 octave::unwind_protect frame; 271 // FIXME: need to handle PARFOR loops here using cmd.in_parallel ()
292 272 // and cmd.maxproc_expr ();
293 frame.protect_var (in_loop_command); 273
294 274 octave::unwind_protect frame;
295 in_loop_command = true; 275
296 276 frame.protect_var (in_loop_command);
297 tree_expression *expr = cmd.control_expr (); 277
298 278 in_loop_command = true;
299 octave_value rhs = expr->rvalue1 (); 279
280 tree_expression *expr = cmd.control_expr ();
281
282 octave_value rhs = expr->rvalue1 ();
300 283
301 #if defined (HAVE_LLVM) 284 #if defined (HAVE_LLVM)
302 if (tree_jit::execute (cmd, rhs)) 285 if (tree_jit::execute (cmd, rhs))
303 return; 286 return;
304 #endif 287 #endif
305 288
306 if (rhs.is_undefined ()) 289 if (rhs.is_undefined ())
307 return; 290 return;
308 291
309 tree_expression *lhs = cmd.left_hand_side (); 292 tree_expression *lhs = cmd.left_hand_side ();
310 293
311 octave_lvalue ult = lhs->lvalue (); 294 octave_lvalue ult = lhs->lvalue ();
312 295
313 tree_statement_list *loop_body = cmd.body (); 296 tree_statement_list *loop_body = cmd.body ();
314 297
315 if (rhs.is_range ()) 298 if (rhs.is_range ())
316 { 299 {
317 Range rng = rhs.range_value (); 300 Range rng = rhs.range_value ();
318 301
319 octave_idx_type steps = rng.numel (); 302 octave_idx_type steps = rng.numel ();
320 303
321 for (octave_idx_type i = 0; i < steps; i++) 304 for (octave_idx_type i = 0; i < steps; i++)
305 {
306 octave_value val (rng.elem (i));
307
308 ult.assign (octave_value::op_asn_eq, val);
309
310 if (loop_body)
311 loop_body->accept (*this);
312
313 if (quit_loop_now ())
314 break;
315 }
316 }
317 else if (rhs.is_scalar_type ())
318 {
319 ult.assign (octave_value::op_asn_eq, rhs);
320
321 if (loop_body)
322 loop_body->accept (*this);
323
324 // Maybe decrement break and continue states.
325 quit_loop_now ();
326 }
327 else if (rhs.is_matrix_type () || rhs.is_cell () || rhs.is_string ()
328 || rhs.is_map ())
329 {
330 // A matrix or cell is reshaped to 2 dimensions and iterated by
331 // columns.
332
333 dim_vector dv = rhs.dims ().redim (2);
334
335 octave_idx_type nrows = dv(0);
336 octave_idx_type steps = dv(1);
337
338 if (steps > 0)
339 {
340 octave_value arg = rhs;
341 if (rhs.ndims () > 2)
342 arg = arg.reshape (dv);
343
344 // for row vectors, use single index to speed things up.
345 octave_value_list idx;
346 octave_idx_type iidx;
347 if (nrows == 1)
348 {
349 idx.resize (1);
350 iidx = 0;
351 }
352 else
353 {
354 idx.resize (2);
355 idx(0) = octave_value::magic_colon_t;
356 iidx = 1;
357 }
358
359 for (octave_idx_type i = 1; i <= steps; i++)
360 {
361 // do_index_op expects one-based indices.
362 idx(iidx) = i;
363 octave_value val = arg.do_index_op (idx);
364
365 ult.assign (octave_value::op_asn_eq, val);
366
367 if (loop_body)
368 loop_body->accept (*this);
369
370 if (quit_loop_now ())
371 break;
372 }
373 }
374 }
375 else
376 error ("invalid type in for loop expression near line %d, column %d",
377 cmd.line (), cmd.column ());
378 }
379
380 void
381 tree_evaluator::visit_complex_for_command (tree_complex_for_command& cmd)
382 {
383 if (debug_mode)
384 do_breakpoint (cmd.is_breakpoint (true));
385
386 octave::unwind_protect frame;
387
388 frame.protect_var (in_loop_command);
389
390 in_loop_command = true;
391
392 tree_expression *expr = cmd.control_expr ();
393
394 octave_value rhs = expr->rvalue1 ();
395
396 if (rhs.is_undefined ())
397 return;
398
399 if (! rhs.is_map ())
400 error ("in statement 'for [X, Y] = VAL', VAL must be a structure");
401
402 // Cycle through structure elements. First element of id_list
403 // is set to value and the second is set to the name of the
404 // structure element.
405
406 tree_argument_list *lhs = cmd.left_hand_side ();
407
408 tree_argument_list::iterator p = lhs->begin ();
409
410 tree_expression *elt = *p++;
411
412 octave_lvalue val_ref = elt->lvalue ();
413
414 elt = *p;
415
416 octave_lvalue key_ref = elt->lvalue ();
417
418 const octave_map tmp_val = rhs.map_value ();
419
420 tree_statement_list *loop_body = cmd.body ();
421
422 string_vector keys = tmp_val.keys ();
423
424 octave_idx_type nel = keys.numel ();
425
426 for (octave_idx_type i = 0; i < nel; i++)
427 {
428 std::string key = keys[i];
429
430 const Cell val_lst = tmp_val.contents (key);
431
432 octave_idx_type n = val_lst.numel ();
433
434 octave_value val = (n == 1) ? val_lst(0) : octave_value (val_lst);
435
436 val_ref.assign (octave_value::op_asn_eq, val);
437 key_ref.assign (octave_value::op_asn_eq, key);
438
439 if (loop_body)
440 loop_body->accept (*this);
441
442 if (quit_loop_now ())
443 break;
444 }
445 }
446
447 void
448 tree_evaluator::visit_octave_user_script (octave_user_script&)
449 {
450 panic_impossible ();
451 }
452
453 void
454 tree_evaluator::visit_octave_user_function (octave_user_function&)
455 {
456 panic_impossible ();
457 }
458
459 void
460 tree_evaluator::visit_octave_user_function_header (octave_user_function&)
461 {
462 panic_impossible ();
463 }
464
465 void
466 tree_evaluator::visit_octave_user_function_trailer (octave_user_function&)
467 {
468 panic_impossible ();
469 }
470
471 void
472 tree_evaluator::visit_function_def (tree_function_def& cmd)
473 {
474 octave_value fcn = cmd.function ();
475
476 octave_function *f = fcn.function_value ();
477
478 if (f)
479 {
480 std::string nm = f->name ();
481
482 symbol_table::install_cmdline_function (nm, fcn);
483
484 // Make sure that any variable with the same name as the new
485 // function is cleared.
486
487 symbol_table::assign (nm);
488 }
489 }
490
491 void
492 tree_evaluator::visit_identifier (tree_identifier&)
493 {
494 panic_impossible ();
495 }
496
497 void
498 tree_evaluator::visit_if_clause (tree_if_clause&)
499 {
500 panic_impossible ();
501 }
502
503 void
504 tree_evaluator::visit_if_command (tree_if_command& cmd)
505 {
506 tree_if_command_list *lst = cmd.cmd_list ();
507
508 if (lst)
509 lst->accept (*this);
510 }
511
512 void
513 tree_evaluator::visit_if_command_list (tree_if_command_list& lst)
514 {
515 for (tree_if_command_list::iterator p = lst.begin (); p != lst.end (); p++)
516 {
517 tree_if_clause *tic = *p;
518
519 tree_expression *expr = tic->condition ();
520
521 if (statement_context == function || statement_context == script)
522 octave_call_stack::set_location (tic->line (), tic->column ());
523
524 if (debug_mode && ! tic->is_else_clause ())
525 do_breakpoint (tic->is_breakpoint (true));
526
527 if (tic->is_else_clause () || expr->is_logically_true ("if"))
528 {
529 tree_statement_list *stmt_lst = tic->commands ();
530
531 if (stmt_lst)
532 stmt_lst->accept (*this);
533
534 break;
535 }
536 }
537 }
538
539 void
540 tree_evaluator::visit_index_expression (tree_index_expression&)
541 {
542 panic_impossible ();
543 }
544
545 void
546 tree_evaluator::visit_matrix (tree_matrix&)
547 {
548 panic_impossible ();
549 }
550
551 void
552 tree_evaluator::visit_cell (tree_cell&)
553 {
554 panic_impossible ();
555 }
556
557 void
558 tree_evaluator::visit_multi_assignment (tree_multi_assignment&)
559 {
560 panic_impossible ();
561 }
562
563 void
564 tree_evaluator::visit_no_op_command (tree_no_op_command& cmd)
565 {
566 if (debug_mode && cmd.is_end_of_fcn_or_script ())
567 do_breakpoint (cmd.is_breakpoint (true), true);
568 }
569
570 void
571 tree_evaluator::visit_constant (tree_constant&)
572 {
573 panic_impossible ();
574 }
575
576 void
577 tree_evaluator::visit_fcn_handle (tree_fcn_handle&)
578 {
579 panic_impossible ();
580 }
581
582 void
583 tree_evaluator::visit_funcall (tree_funcall&)
584 {
585 panic_impossible ();
586 }
587
588 void
589 tree_evaluator::visit_parameter_list (tree_parameter_list&)
590 {
591 panic_impossible ();
592 }
593
594 void
595 tree_evaluator::visit_postfix_expression (tree_postfix_expression&)
596 {
597 panic_impossible ();
598 }
599
600 void
601 tree_evaluator::visit_prefix_expression (tree_prefix_expression&)
602 {
603 panic_impossible ();
604 }
605
606 void
607 tree_evaluator::visit_return_command (tree_return_command& cmd)
608 {
609 if (debug_mode)
610 do_breakpoint (cmd.is_breakpoint (true));
611
612 // Act like dbcont.
613
614 if (Vdebugging
615 && octave_call_stack::current_frame () == current_frame)
616 {
617 Vdebugging = false;
618
619 reset_debug_state ();
620 }
621 else if (statement_context == function || statement_context == script
622 || in_loop_command)
623 tree_return_command::returning = 1;
624 }
625
626 void
627 tree_evaluator::visit_return_list (tree_return_list&)
628 {
629 panic_impossible ();
630 }
631
632 void
633 tree_evaluator::visit_simple_assignment (tree_simple_assignment&)
634 {
635 panic_impossible ();
636 }
637
638 void
639 tree_evaluator::visit_statement (tree_statement& stmt)
640 {
641 tree_command *cmd = stmt.command ();
642 tree_expression *expr = stmt.expression ();
643
644 if (cmd || expr)
645 {
646 if (statement_context == function || statement_context == script)
647 {
648 // Skip commands issued at a debug> prompt to avoid disturbing
649 // the state of the program we are debugging.
650
651 if (Vtrack_line_num)
652 octave_call_stack::set_location (stmt.line (), stmt.column ());
653
654 if ((statement_context == script
655 && ((Vecho_executing_commands & ECHO_SCRIPTS
656 && octave_call_stack::all_scripts ())
657 || Vecho_executing_commands & ECHO_FUNCTIONS))
658 || (statement_context == function
659 && Vecho_executing_commands & ECHO_FUNCTIONS))
660 stmt.echo_code ();
661 }
662
663 try
664 {
665 if (cmd)
666 cmd->accept (*this);
667 else
668 {
669 if (debug_mode)
670 do_breakpoint (expr->is_breakpoint (true));
671
672 // FIXME: maybe all of this should be packaged in
673 // one virtual function that returns a flag saying whether
674 // or not the expression will take care of binding ans and
675 // printing the result.
676
677 // FIXME: it seems that we should just have to
678 // call expr->rvalue1 () and that should take care of
679 // everything, binding ans as necessary?
680
681 bool do_bind_ans = false;
682
683 if (expr->is_identifier ())
684 {
685 tree_identifier *id = dynamic_cast<tree_identifier *> (expr);
686
687 do_bind_ans = (! id->is_variable ());
688 }
689 else
690 do_bind_ans = (! expr->is_assignment_expression ());
691
692 octave_value tmp_result = expr->rvalue1 (0);
693
694 if (do_bind_ans && tmp_result.is_defined ())
695 bind_ans (tmp_result, expr->print_result ()
696 && statement_printing_enabled ());
697
698 // if (tmp_result.is_defined ())
699 // result_values(0) = tmp_result;
700 }
701 }
702 catch (const std::bad_alloc&)
703 {
704 // FIXME: We want to use error_with_id here so that give users
705 // control over this error message but error_with_id will
706 // require some memory allocations. Is there anything we can
707 // do to make those more likely to succeed?
708
709 error_with_id ("Octave:bad-alloc",
710 "out of memory or dimension too large for Octave's index type");
711 }
712 }
713 }
714
715 void
716 tree_evaluator::visit_statement_list (tree_statement_list& lst)
717 {
718 // FIXME: commented out along with else clause below.
719 // static octave_value_list empty_list;
720
721 tree_statement_list::iterator p = lst.begin ();
722
723 if (p != lst.end ())
724 {
725 while (true)
726 {
727 tree_statement *elt = *p++;
728
729 if (! elt)
730 error ("invalid statement found in statement list!");
731
732 octave_quit ();
733
734 elt->accept (*this);
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 previous 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 }
764 }
765
766 void
767 tree_evaluator::visit_switch_case (tree_switch_case&)
768 {
769 panic_impossible ();
770 }
771
772 void
773 tree_evaluator::visit_switch_case_list (tree_switch_case_list&)
774 {
775 panic_impossible ();
776 }
777
778 void
779 tree_evaluator::visit_switch_command (tree_switch_command& cmd)
780 {
781 if (debug_mode)
782 do_breakpoint (cmd.is_breakpoint (true));
783
784 tree_expression *expr = cmd.switch_value ();
785
786 if (! expr)
787 error ("missing value in switch command near line %d, column %d",
788 cmd.line (), cmd.column ());
789
790 octave_value val = expr->rvalue1 ();
791
792 tree_switch_case_list *lst = cmd.case_list ();
793
794 if (lst)
795 {
796 for (tree_switch_case_list::iterator p = lst->begin ();
797 p != lst->end (); p++)
798 {
799 tree_switch_case *t = *p;
800
801 if (t->is_default_case () || t->label_matches (val))
802 {
803 tree_statement_list *stmt_lst = t->commands ();
804
805 if (stmt_lst)
806 stmt_lst->accept (*this);
807
808 break;
809 }
810 }
811 }
812 }
813
814 void
815 tree_evaluator::visit_try_catch_command (tree_try_catch_command& cmd)
816 {
817 bool execution_error = false;
818
819 { // unwind frame before catch block
820 octave::unwind_protect frame;
821
822 frame.protect_var (buffer_error_messages);
823 frame.protect_var (Vdebug_on_error);
824 frame.protect_var (Vdebug_on_warning);
825
826 buffer_error_messages++;
827 Vdebug_on_error = false;
828 Vdebug_on_warning = false;
829
830 // The catch code is *not* added to unwind_protect stack;
831 // it doesn't need to be run on interrupts.
832
833 tree_statement_list *try_code = cmd.body ();
834
835 if (try_code)
322 { 836 {
323 octave_value val (rng.elem (i)); 837 try
324
325 ult.assign (octave_value::op_asn_eq, val);
326
327 if (loop_body)
328 loop_body->accept (*this);
329
330 if (quit_loop_now ())
331 break;
332 }
333 }
334 else if (rhs.is_scalar_type ())
335 {
336 ult.assign (octave_value::op_asn_eq, rhs);
337
338 if (loop_body)
339 loop_body->accept (*this);
340
341 // Maybe decrement break and continue states.
342 quit_loop_now ();
343 }
344 else if (rhs.is_matrix_type () || rhs.is_cell () || rhs.is_string ()
345 || rhs.is_map ())
346 {
347 // A matrix or cell is reshaped to 2 dimensions and iterated by
348 // columns.
349
350 dim_vector dv = rhs.dims ().redim (2);
351
352 octave_idx_type nrows = dv(0);
353 octave_idx_type steps = dv(1);
354
355 if (steps > 0)
356 {
357 octave_value arg = rhs;
358 if (rhs.ndims () > 2)
359 arg = arg.reshape (dv);
360
361 // for row vectors, use single index to speed things up.
362 octave_value_list idx;
363 octave_idx_type iidx;
364 if (nrows == 1)
365 { 838 {
366 idx.resize (1); 839 in_try_catch++;
367 iidx = 0; 840 try_code->accept (*this);
841 in_try_catch--;
368 } 842 }
369 else 843 catch (const octave_execution_exception&)
370 { 844 {
371 idx.resize (2); 845 recover_from_exception ();
372 idx(0) = octave_value::magic_colon_t; 846
373 iidx = 1; 847 in_try_catch--; // must be restored before "catch" block
374 } 848 execution_error = true;
375
376 for (octave_idx_type i = 1; i <= steps; i++)
377 {
378 // do_index_op expects one-based indices.
379 idx(iidx) = i;
380 octave_value val = arg.do_index_op (idx);
381
382 ult.assign (octave_value::op_asn_eq, val);
383
384 if (loop_body)
385 loop_body->accept (*this);
386
387 if (quit_loop_now ())
388 break;
389 } 849 }
390 } 850 }
851 // Unwind to let the user print any messages from
852 // errors that occurred in the body of the try_catch statement,
853 // or throw further errors.
391 } 854 }
392 else 855
393 error ("invalid type in for loop expression near line %d, column %d", 856 if (execution_error)
394 cmd.line (), cmd.column ()); 857 {
395 } 858 tree_statement_list *catch_code = cmd.cleanup ();
396 859 if (catch_code)
397 void 860 {
398 tree_evaluator::visit_complex_for_command (tree_complex_for_command& cmd) 861 tree_identifier *expr_id = cmd.identifier ();
399 { 862 octave_lvalue ult;
400 if (debug_mode) 863
401 do_breakpoint (cmd.is_breakpoint (true)); 864 if (expr_id)
402 865 {
403 octave::unwind_protect frame; 866 ult = expr_id->lvalue ();
404 867
405 frame.protect_var (in_loop_command); 868 octave_scalar_map err;
406 869
407 in_loop_command = true; 870 err.assign ("message", last_error_message ());
408 871 err.assign ("identifier", last_error_id ());
409 tree_expression *expr = cmd.control_expr (); 872 err.assign ("stack", last_error_stack ());
410 873
411 octave_value rhs = expr->rvalue1 (); 874 ult.assign (octave_value::op_asn_eq, err);
412 875 }
413 if (rhs.is_undefined ()) 876
414 return; 877 // perform actual "catch" block
415 878 if (catch_code)
416 if (! rhs.is_map ()) 879 catch_code->accept (*this);
417 error ("in statement 'for [X, Y] = VAL', VAL must be a structure"); 880 }
418 881 }
419 // Cycle through structure elements. First element of id_list 882 }
420 // is set to value and the second is set to the name of the 883
421 // structure element. 884 void
422 885 tree_evaluator::do_unwind_protect_cleanup_code (tree_statement_list *list)
423 tree_argument_list *lhs = cmd.left_hand_side (); 886 {
424 887 octave::unwind_protect frame;
425 tree_argument_list::iterator p = lhs->begin (); 888
426 889 frame.protect_var (octave_interrupt_state);
427 tree_expression *elt = *p++; 890 octave_interrupt_state = 0;
428 891
429 octave_lvalue val_ref = elt->lvalue (); 892 // We want to preserve the last location info for possible
430 893 // backtracking.
431 elt = *p; 894 frame.add_fcn (octave_call_stack::set_line,
432 895 octave_call_stack::current_line ());
433 octave_lvalue key_ref = elt->lvalue (); 896 frame.add_fcn (octave_call_stack::set_column,
434 897 octave_call_stack::current_column ());
435 const octave_map tmp_val = rhs.map_value (); 898
436 899 // Similarly, if we have seen a return or break statement, allow all
437 tree_statement_list *loop_body = cmd.body (); 900 // the cleanup code to run before returning or handling the break.
438 901 // We don't have to worry about continue statements because they can
439 string_vector keys = tmp_val.keys (); 902 // only occur in loops.
440 903
441 octave_idx_type nel = keys.numel (); 904 frame.protect_var (tree_return_command::returning);
442 905 tree_return_command::returning = 0;
443 for (octave_idx_type i = 0; i < nel; i++) 906
444 { 907 frame.protect_var (tree_break_command::breaking);
445 std::string key = keys[i]; 908 tree_break_command::breaking = 0;
446 909
447 const Cell val_lst = tmp_val.contents (key); 910 try
448 911 {
449 octave_idx_type n = val_lst.numel (); 912 if (list)
450 913 list->accept (*this);
451 octave_value val = (n == 1) ? val_lst(0) : octave_value (val_lst); 914 }
452 915 catch (const octave_execution_exception&)
453 val_ref.assign (octave_value::op_asn_eq, val); 916 {
454 key_ref.assign (octave_value::op_asn_eq, key); 917 recover_from_exception ();
455 918
456 if (loop_body) 919 if (tree_break_command::breaking || tree_return_command::returning)
457 loop_body->accept (*this); 920 frame.discard (2);
458 921 else
459 if (quit_loop_now ()) 922 frame.run (2);
460 break; 923
461 } 924 frame.discard (2);
462 } 925
463 926 throw;
464 void 927 }
465 tree_evaluator::visit_octave_user_script (octave_user_script&) 928
466 { 929 // The unwind_protects are popped off the stack in the reverse of
467 panic_impossible (); 930 // the order they are pushed on.
468 } 931
469 932 // FIXME: these statements say that if we see a break or
470 void 933 // return statement in the cleanup block, that we want to use the
471 tree_evaluator::visit_octave_user_function (octave_user_function&) 934 // new value of the breaking or returning flag instead of restoring
472 { 935 // the previous value. Is that the right thing to do? I think so.
473 panic_impossible (); 936 // Consider the case of
474 } 937 //
475 938 // function foo ()
476 void 939 // unwind_protect
477 tree_evaluator::visit_octave_user_function_header (octave_user_function&) 940 // fprintf (stderr, "1: this should always be executed\n");
478 { 941 // break;
479 panic_impossible (); 942 // fprintf (stderr, "1: this should never be executed\n");
480 } 943 // unwind_protect_cleanup
481 944 // fprintf (stderr, "2: this should always be executed\n");
482 void 945 // return;
483 tree_evaluator::visit_octave_user_function_trailer (octave_user_function&) 946 // fprintf (stderr, "2: this should never be executed\n");
484 { 947 // end_unwind_protect
485 panic_impossible (); 948 // endfunction
486 } 949 //
487 950 // If we reset the value of the breaking flag, both the returning
488 void 951 // flag and the breaking flag will be set, and we shouldn't have
489 tree_evaluator::visit_function_def (tree_function_def& cmd) 952 // both. So, use the most recent one. If there is no return or
490 { 953 // break in the cleanup block, the values should be reset to
491 octave_value fcn = cmd.function (); 954 // whatever they were when the cleanup block was entered.
492 955
493 octave_function *f = fcn.function_value (); 956 if (tree_break_command::breaking || tree_return_command::returning)
494 957 frame.discard (2);
495 if (f) 958 else
496 { 959 frame.run (2);
497 std::string nm = f->name (); 960 }
498 961
499 symbol_table::install_cmdline_function (nm, fcn); 962 void
500 963 tree_evaluator::visit_unwind_protect_command (tree_unwind_protect_command& cmd)
501 // Make sure that any variable with the same name as the new 964 {
502 // function is cleared. 965 tree_statement_list *cleanup_code = cmd.cleanup ();
503 966
504 symbol_table::assign (nm); 967 tree_statement_list *unwind_protect_code = cmd.body ();
505 } 968
506 } 969 if (unwind_protect_code)
507 970 {
508 void 971 try
509 tree_evaluator::visit_identifier (tree_identifier&) 972 {
510 { 973 unwind_protect_code->accept (*this);
511 panic_impossible (); 974 }
512 } 975 catch (const octave_execution_exception&)
513 976 {
514 void 977 // FIXME: Maybe we should be able to temporarily set the
515 tree_evaluator::visit_if_clause (tree_if_clause&) 978 // interpreter's exception handling state to something "safe"
516 { 979 // while the cleanup block runs instead of just resetting it
517 panic_impossible (); 980 // here?
518 } 981 recover_from_exception ();
519 982
520 void 983 // Run the cleanup code on exceptions, so that it is run even
521 tree_evaluator::visit_if_command (tree_if_command& cmd) 984 // in case of interrupt or out-of-memory.
522 { 985 do_unwind_protect_cleanup_code (cleanup_code);
523 tree_if_command_list *lst = cmd.cmd_list (); 986
524 987 // If an error occurs inside the cleanup code, a new
525 if (lst) 988 // exception will be thrown instead of the original.
526 lst->accept (*this); 989 throw;
527 } 990 }
528 991
529 void 992 // Also execute the unwind_protect_cleanump code if the
530 tree_evaluator::visit_if_command_list (tree_if_command_list& lst) 993 // unwind_protect block runs without error.
531 { 994 do_unwind_protect_cleanup_code (cleanup_code);
532 for (tree_if_command_list::iterator p = lst.begin (); p != lst.end (); p++) 995 }
533 { 996 }
534 tree_if_clause *tic = *p; 997
535 998 void
536 tree_expression *expr = tic->condition (); 999 tree_evaluator::visit_while_command (tree_while_command& cmd)
537 1000 {
538 if (statement_context == function || statement_context == script) 1001 #if defined (HAVE_LLVM)
539 octave_call_stack::set_location (tic->line (), tic->column ()); 1002 if (tree_jit::execute (cmd))
540 1003 return;
541 if (debug_mode && ! tic->is_else_clause ()) 1004 #endif
542 do_breakpoint (tic->is_breakpoint (true)); 1005
543 1006 octave::unwind_protect frame;
544 if (tic->is_else_clause () || expr->is_logically_true ("if")) 1007
545 { 1008 frame.protect_var (in_loop_command);
546 tree_statement_list *stmt_lst = tic->commands (); 1009
547 1010 in_loop_command = true;
548 if (stmt_lst) 1011
549 stmt_lst->accept (*this); 1012 tree_expression *expr = cmd.condition ();
550 1013
1014 if (! expr)
1015 panic_impossible ();
1016
1017 for (;;)
1018 {
1019 if (debug_mode)
1020 do_breakpoint (cmd.is_breakpoint (true));
1021
1022 if (expr->is_logically_true ("while"))
1023 {
1024 tree_statement_list *loop_body = cmd.body ();
1025
1026 if (loop_body)
1027 loop_body->accept (*this);
1028
1029 if (quit_loop_now ())
1030 break;
1031 }
1032 else
551 break; 1033 break;
552 } 1034 }
553 } 1035 }
554 } 1036
555 1037 void
556 void 1038 tree_evaluator::visit_do_until_command (tree_do_until_command& cmd)
557 tree_evaluator::visit_index_expression (tree_index_expression&) 1039 {
558 { 1040 #if defined (HAVE_LLVM)
559 panic_impossible (); 1041 if (tree_jit::execute (cmd))
560 } 1042 return;
561 1043 #endif
562 void 1044
563 tree_evaluator::visit_matrix (tree_matrix&)
564 {
565 panic_impossible ();
566 }
567
568 void
569 tree_evaluator::visit_cell (tree_cell&)
570 {
571 panic_impossible ();
572 }
573
574 void
575 tree_evaluator::visit_multi_assignment (tree_multi_assignment&)
576 {
577 panic_impossible ();
578 }
579
580 void
581 tree_evaluator::visit_no_op_command (tree_no_op_command& cmd)
582 {
583 if (debug_mode && cmd.is_end_of_fcn_or_script ())
584 do_breakpoint (cmd.is_breakpoint (true), true);
585 }
586
587 void
588 tree_evaluator::visit_constant (tree_constant&)
589 {
590 panic_impossible ();
591 }
592
593 void
594 tree_evaluator::visit_fcn_handle (tree_fcn_handle&)
595 {
596 panic_impossible ();
597 }
598
599 void
600 tree_evaluator::visit_funcall (tree_funcall&)
601 {
602 panic_impossible ();
603 }
604
605 void
606 tree_evaluator::visit_parameter_list (tree_parameter_list&)
607 {
608 panic_impossible ();
609 }
610
611 void
612 tree_evaluator::visit_postfix_expression (tree_postfix_expression&)
613 {
614 panic_impossible ();
615 }
616
617 void
618 tree_evaluator::visit_prefix_expression (tree_prefix_expression&)
619 {
620 panic_impossible ();
621 }
622
623 void
624 tree_evaluator::visit_return_command (tree_return_command& cmd)
625 {
626 if (debug_mode)
627 do_breakpoint (cmd.is_breakpoint (true));
628
629 // Act like dbcont.
630
631 if (Vdebugging
632 && octave_call_stack::current_frame () == current_frame)
633 {
634 Vdebugging = false;
635
636 reset_debug_state ();
637 }
638 else if (statement_context == function || statement_context == script
639 || in_loop_command)
640 tree_return_command::returning = 1;
641 }
642
643 void
644 tree_evaluator::visit_return_list (tree_return_list&)
645 {
646 panic_impossible ();
647 }
648
649 void
650 tree_evaluator::visit_simple_assignment (tree_simple_assignment&)
651 {
652 panic_impossible ();
653 }
654
655 void
656 tree_evaluator::visit_statement (tree_statement& stmt)
657 {
658 tree_command *cmd = stmt.command ();
659 tree_expression *expr = stmt.expression ();
660
661 if (cmd || expr)
662 {
663 if (statement_context == function || statement_context == script)
664 {
665 // Skip commands issued at a debug> prompt to avoid disturbing
666 // the state of the program we are debugging, but still track
667 // progress through user functions called from debug> prompt.
668
669 if (Vtrack_line_num)
670 octave_call_stack::set_location (stmt.line (), stmt.column ());
671
672 if ((statement_context == script
673 && ((Vecho_executing_commands & ECHO_SCRIPTS
674 && octave_call_stack::all_scripts ())
675 || Vecho_executing_commands & ECHO_FUNCTIONS))
676 || (statement_context == function
677 && Vecho_executing_commands & ECHO_FUNCTIONS))
678 stmt.echo_code ();
679 }
680
681 try
682 {
683 if (cmd)
684 cmd->accept (*this);
685 else
686 {
687 if (debug_mode)
688 do_breakpoint (expr->is_breakpoint (true));
689
690 // FIXME: maybe all of this should be packaged in
691 // one virtual function that returns a flag saying whether
692 // or not the expression will take care of binding ans and
693 // printing the result.
694
695 // FIXME: it seems that we should just have to
696 // call expr->rvalue1 () and that should take care of
697 // everything, binding ans as necessary?
698
699 bool do_bind_ans = false;
700
701 if (expr->is_identifier ())
702 {
703 tree_identifier *id = dynamic_cast<tree_identifier *> (expr);
704
705 do_bind_ans = (! id->is_variable ());
706 }
707 else
708 do_bind_ans = (! expr->is_assignment_expression ());
709
710 octave_value tmp_result = expr->rvalue1 (0);
711
712 if (do_bind_ans && tmp_result.is_defined ())
713 bind_ans (tmp_result, expr->print_result ()
714 && statement_printing_enabled ());
715
716 // if (tmp_result.is_defined ())
717 // result_values(0) = tmp_result;
718 }
719 }
720 catch (const std::bad_alloc&)
721 {
722 // FIXME: We want to use error_with_id here so that give users
723 // control over this error message but error_with_id will
724 // require some memory allocations. Is there anything we can
725 // do to make those more likely to succeed?
726
727 error_with_id ("Octave:bad-alloc",
728 "out of memory or dimension too large for Octave's index type");
729 }
730 }
731 }
732
733 void
734 tree_evaluator::visit_statement_list (tree_statement_list& lst)
735 {
736 // FIXME: commented out along with else clause below.
737 // static octave_value_list empty_list;
738
739 tree_statement_list::iterator p = lst.begin ();
740
741 if (p != lst.end ())
742 {
743 while (true)
744 {
745 tree_statement *elt = *p++;
746
747 if (! elt)
748 error ("invalid statement found in statement list!");
749
750 octave_quit ();
751
752 elt->accept (*this);
753
754 if (tree_break_command::breaking
755 || tree_continue_command::continuing)
756 break;
757
758 if (tree_return_command::returning)
759 break;
760
761 if (p == lst.end ())
762 break;
763 else
764 {
765 // Clear previous values before next statement is
766 // evaluated so that we aren't holding an extra
767 // reference to a value that may be used next. For
768 // example, in code like this:
769 //
770 // X = rand (N); # refcount for X should be 1
771 // # after this statement
772 //
773 // X(idx) = val; # no extra copy of X should be
774 // # needed, but we will be faked
775 // # out if retval is not cleared
776 // # between statements here
777
778 // result_values = empty_list;
779 }
780 }
781 }
782 }
783
784 void
785 tree_evaluator::visit_switch_case (tree_switch_case&)
786 {
787 panic_impossible ();
788 }
789
790 void
791 tree_evaluator::visit_switch_case_list (tree_switch_case_list&)
792 {
793 panic_impossible ();
794 }
795
796 void
797 tree_evaluator::visit_switch_command (tree_switch_command& cmd)
798 {
799 if (debug_mode)
800 do_breakpoint (cmd.is_breakpoint (true));
801
802 tree_expression *expr = cmd.switch_value ();
803
804 if (! expr)
805 error ("missing value in switch command near line %d, column %d",
806 cmd.line (), cmd.column ());
807
808 octave_value val = expr->rvalue1 ();
809
810 tree_switch_case_list *lst = cmd.case_list ();
811
812 if (lst)
813 {
814 for (tree_switch_case_list::iterator p = lst->begin ();
815 p != lst->end (); p++)
816 {
817 tree_switch_case *t = *p;
818
819 if (t->is_default_case () || t->label_matches (val))
820 {
821 tree_statement_list *stmt_lst = t->commands ();
822
823 if (stmt_lst)
824 stmt_lst->accept (*this);
825
826 break;
827 }
828 }
829 }
830 }
831
832 void
833 tree_evaluator::visit_try_catch_command (tree_try_catch_command& cmd)
834 {
835 bool execution_error = false;
836
837 { // unwind frame before catch block
838 octave::unwind_protect frame; 1045 octave::unwind_protect frame;
839 1046
840 frame.protect_var (buffer_error_messages); 1047 frame.protect_var (in_loop_command);
841 frame.protect_var (Vdebug_on_error); 1048
842 frame.protect_var (Vdebug_on_warning); 1049 in_loop_command = true;
843 1050
844 buffer_error_messages++; 1051 tree_expression *expr = cmd.condition ();
845 Vdebug_on_error = false; 1052 int until_line = cmd.line ();
846 Vdebug_on_warning = false; 1053 int until_column = cmd.column ();
847 1054
848 // The catch code is *not* added to unwind_protect stack; 1055 if (! expr)
849 // it doesn't need to be run on interrupts. 1056 panic_impossible ();
850 1057
851 tree_statement_list *try_code = cmd.body (); 1058 for (;;)
852 1059 {
853 if (try_code) 1060 tree_statement_list *loop_body = cmd.body ();
854 { 1061
855 try 1062 if (loop_body)
856 { 1063 loop_body->accept (*this);
857 in_try_catch++; 1064
858 try_code->accept (*this); 1065 if (quit_loop_now ())
859 in_try_catch--; 1066 break;
860 } 1067
861 catch (const octave_execution_exception&) 1068 if (debug_mode)
862 { 1069 do_breakpoint (cmd.is_breakpoint (true));
863 recover_from_exception (); 1070
864 1071 octave_call_stack::set_location (until_line, until_column);
865 in_try_catch--; // must be restored before "catch" block 1072
866 execution_error = true; 1073 if (expr->is_logically_true ("do-until"))
867 } 1074 break;
868 } 1075 }
869 // Unwind to let the user print any messages from 1076 }
870 // errors that occurred in the body of the try_catch statement, 1077
871 // or throw further errors. 1078 void
872 } 1079 tree_evaluator::do_breakpoint (tree_statement& stmt) const
873 1080 {
874 if (execution_error) 1081 do_breakpoint (stmt.is_breakpoint (true), stmt.is_end_of_fcn_or_script ());
875 { 1082 }
876 tree_statement_list *catch_code = cmd.cleanup (); 1083
877 if (catch_code) 1084 void
878 { 1085 tree_evaluator::do_breakpoint (bool is_breakpoint,
879 tree_identifier *expr_id = cmd.identifier (); 1086 bool is_end_of_fcn_or_script) const
880 octave_lvalue ult; 1087 {
881 1088 bool break_on_this_statement = false;
882 if (expr_id) 1089
883 { 1090 if (octave_debug_on_interrupt_state)
884 ult = expr_id->lvalue (); 1091 {
885 1092 break_on_this_statement = true;
886 octave_scalar_map err; 1093
887 1094 octave_debug_on_interrupt_state = false;
888 err.assign ("message", last_error_message ()); 1095
889 err.assign ("identifier", last_error_id ()); 1096 current_frame = octave_call_stack::current_frame ();
890 err.assign ("stack", last_error_stack ()); 1097 }
891 1098 else if (is_breakpoint)
892 ult.assign (octave_value::op_asn_eq, err); 1099 {
893 } 1100 break_on_this_statement = true;
894 1101
895 // perform actual "catch" block 1102 dbstep_flag = 0;
896 if (catch_code) 1103
897 catch_code->accept (*this); 1104 current_frame = octave_call_stack::current_frame ();
898 } 1105 }
899 } 1106 else if (dbstep_flag > 0)
900 } 1107 {
901 1108 if (octave_call_stack::current_frame () == current_frame)
902 void 1109 {
903 tree_evaluator::do_unwind_protect_cleanup_code (tree_statement_list *list) 1110 if (dbstep_flag == 1 || is_end_of_fcn_or_script)
904 { 1111 {
905 octave::unwind_protect frame; 1112 // We get here if we are doing a "dbstep" or a "dbstep N" and the
906 1113 // count has reached 1 so that we must stop and return to debug
907 frame.protect_var (octave_interrupt_state); 1114 // prompt. Alternatively, "dbstep N" has been used but the end
908 octave_interrupt_state = 0; 1115 // of the frame has been reached so we stop at the last line and
909 1116 // return to prompt.
910 // We want to preserve the last location info for possible 1117
911 // backtracking. 1118 break_on_this_statement = true;
912 frame.add_fcn (octave_call_stack::set_line, 1119
913 octave_call_stack::current_line ()); 1120 dbstep_flag = 0;
914 frame.add_fcn (octave_call_stack::set_column, 1121 }
915 octave_call_stack::current_column ()); 1122 else
916 1123 {
917 // Similarly, if we have seen a return or break statement, allow all 1124 // Executing "dbstep N". Decrease N by one and continue.
918 // the cleanup code to run before returning or handling the break. 1125
919 // We don't have to worry about continue statements because they can 1126 dbstep_flag--;
920 // only occur in loops. 1127 }
921 1128
922 frame.protect_var (tree_return_command::returning); 1129 }
923 tree_return_command::returning = 0; 1130 else if (dbstep_flag == 1
924 1131 && octave_call_stack::current_frame () < current_frame)
925 frame.protect_var (tree_break_command::breaking); 1132 {
926 tree_break_command::breaking = 0; 1133 // We stepped out from the end of a function.
927 1134
928 try 1135 current_frame = octave_call_stack::current_frame ();
929 { 1136
930 if (list) 1137 break_on_this_statement = true;
931 list->accept (*this); 1138
932 } 1139 dbstep_flag = 0;
933 catch (const octave_execution_exception&) 1140 }
934 { 1141 }
935 recover_from_exception (); 1142 else if (dbstep_flag == -1)
936 1143 {
937 if (tree_break_command::breaking || tree_return_command::returning) 1144 // We get here if we are doing a "dbstep in".
938 frame.discard (2); 1145
939 else 1146 break_on_this_statement = true;
940 frame.run (2); 1147
941 1148 dbstep_flag = 0;
942 frame.discard (2); 1149
943 1150 current_frame = octave_call_stack::current_frame ();
944 throw; 1151 }
945 } 1152 else if (dbstep_flag == -2)
946 1153 {
947 // The unwind_protects are popped off the stack in the reverse of 1154 // We get here if we are doing a "dbstep out". Check for end of
948 // the order they are pushed on. 1155 // function and whether the current frame is the same as the
949 1156 // cached value because we want to step out from the frame where
950 // FIXME: these statements say that if we see a break or 1157 // "dbstep out" was evaluated, not from any functions called from
951 // return statement in the cleanup block, that we want to use the 1158 // that frame.
952 // new value of the breaking or returning flag instead of restoring 1159
953 // the previous value. Is that the right thing to do? I think so. 1160 if (is_end_of_fcn_or_script
954 // Consider the case of 1161 && octave_call_stack::current_frame () == current_frame)
955 // 1162 dbstep_flag = -1;
956 // function foo () 1163 }
957 // unwind_protect 1164
958 // fprintf (stderr, "1: this should always be executed\n"); 1165 if (break_on_this_statement)
959 // break; 1166 do_keyboard ();
960 // fprintf (stderr, "1: this should never be executed\n"); 1167
961 // unwind_protect_cleanup 1168 }
962 // fprintf (stderr, "2: this should always be executed\n"); 1169
963 // return; 1170 // ARGS is currently unused, but since the do_keyboard function in
964 // fprintf (stderr, "2: this should never be executed\n"); 1171 // input.cc accepts an argument list, we preserve it here so that the
965 // end_unwind_protect 1172 // interface won't have to change if we decide to use it in the future.
966 // endfunction 1173
967 // 1174 octave_value
968 // If we reset the value of the breaking flag, both the returning 1175 tree_evaluator::do_keyboard (const octave_value_list& args) const
969 // flag and the breaking flag will be set, and we shouldn't have 1176 {
970 // both. So, use the most recent one. If there is no return or 1177 return ::do_keyboard (args);
971 // break in the cleanup block, the values should be reset to 1178 }
972 // whatever they were when the cleanup block was entered.
973
974 if (tree_break_command::breaking || tree_return_command::returning)
975 frame.discard (2);
976 else
977 frame.run (2);
978 }
979
980 void
981 tree_evaluator::visit_unwind_protect_command (tree_unwind_protect_command& cmd)
982 {
983 tree_statement_list *cleanup_code = cmd.cleanup ();
984
985 tree_statement_list *unwind_protect_code = cmd.body ();
986
987 if (unwind_protect_code)
988 {
989 try
990 {
991 unwind_protect_code->accept (*this);
992 }
993 catch (const octave_execution_exception&)
994 {
995 // FIXME: Maybe we should be able to temporarily set the
996 // interpreter's exception handling state to something "safe"
997 // while the cleanup block runs instead of just resetting it
998 // here?
999 recover_from_exception ();
1000
1001 // Run the cleanup code on exceptions, so that it is run even
1002 // in case of interrupt or out-of-memory.
1003 do_unwind_protect_cleanup_code (cleanup_code);
1004
1005 // If an error occurs inside the cleanup code, a new
1006 // exception will be thrown instead of the original.
1007 throw;
1008 }
1009
1010 // Also execute the unwind_protect_cleanump code if the
1011 // unwind_protect block runs without error.
1012 do_unwind_protect_cleanup_code (cleanup_code);
1013 }
1014 }
1015
1016 void
1017 tree_evaluator::visit_while_command (tree_while_command& cmd)
1018 {
1019 #if defined (HAVE_LLVM)
1020 if (tree_jit::execute (cmd))
1021 return;
1022 #endif
1023
1024 octave::unwind_protect frame;
1025
1026 frame.protect_var (in_loop_command);
1027
1028 in_loop_command = true;
1029
1030 tree_expression *expr = cmd.condition ();
1031
1032 if (! expr)
1033 panic_impossible ();
1034
1035 for (;;)
1036 {
1037 if (debug_mode)
1038 do_breakpoint (cmd.is_breakpoint (true));
1039
1040 if (expr->is_logically_true ("while"))
1041 {
1042 tree_statement_list *loop_body = cmd.body ();
1043
1044 if (loop_body)
1045 loop_body->accept (*this);
1046
1047 if (quit_loop_now ())
1048 break;
1049 }
1050 else
1051 break;
1052 }
1053 }
1054
1055 void
1056 tree_evaluator::visit_do_until_command (tree_do_until_command& cmd)
1057 {
1058 #if defined (HAVE_LLVM)
1059 if (tree_jit::execute (cmd))
1060 return;
1061 #endif
1062
1063 octave::unwind_protect frame;
1064
1065 frame.protect_var (in_loop_command);
1066
1067 in_loop_command = true;
1068
1069 tree_expression *expr = cmd.condition ();
1070 int until_line = cmd.line ();
1071 int until_column = cmd.column ();
1072
1073 if (! expr)
1074 panic_impossible ();
1075
1076 for (;;)
1077 {
1078 tree_statement_list *loop_body = cmd.body ();
1079
1080 if (loop_body)
1081 loop_body->accept (*this);
1082
1083 if (quit_loop_now ())
1084 break;
1085
1086 if (debug_mode)
1087 do_breakpoint (cmd.is_breakpoint (true));
1088
1089 octave_call_stack::set_location (until_line, until_column);
1090
1091 if (expr->is_logically_true ("do-until"))
1092 break;
1093 }
1094 }
1095
1096 void
1097 tree_evaluator::do_breakpoint (tree_statement& stmt) const
1098 {
1099 do_breakpoint (stmt.is_breakpoint (true), stmt.is_end_of_fcn_or_script ());
1100 }
1101
1102 void
1103 tree_evaluator::do_breakpoint (bool is_breakpoint,
1104 bool is_end_of_fcn_or_script) const
1105 {
1106 bool break_on_this_statement = false;
1107
1108 if (octave_debug_on_interrupt_state)
1109 {
1110 break_on_this_statement = true;
1111
1112 octave_debug_on_interrupt_state = false;
1113
1114 current_frame = octave_call_stack::current_frame ();
1115 }
1116 else if (is_breakpoint)
1117 {
1118 break_on_this_statement = true;
1119
1120 dbstep_flag = 0;
1121
1122 current_frame = octave_call_stack::current_frame ();
1123 }
1124 else if (dbstep_flag > 0)
1125 {
1126 if (octave_call_stack::current_frame () == current_frame)
1127 {
1128 if (dbstep_flag == 1 || is_end_of_fcn_or_script)
1129 {
1130 // We get here if we are doing a "dbstep" or a "dbstep N" and the
1131 // count has reached 1 so that we must stop and return to debug
1132 // prompt. Alternatively, "dbstep N" has been used but the end
1133 // of the frame has been reached so we stop at the last line and
1134 // return to prompt.
1135
1136 break_on_this_statement = true;
1137
1138 dbstep_flag = 0;
1139 }
1140 else
1141 {
1142 // Executing "dbstep N". Decrease N by one and continue.
1143
1144 dbstep_flag--;
1145 }
1146
1147 }
1148 else if (dbstep_flag == 1
1149 && octave_call_stack::current_frame () < current_frame)
1150 {
1151 // We stepped out from the end of a function.
1152
1153 current_frame = octave_call_stack::current_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". Check for end of
1173 // function and whether the current frame is the same as the
1174 // cached value because we want to step out from the frame where
1175 // "dbstep out" was evaluated, not from any functions called from
1176 // that frame.
1177
1178 if (is_end_of_fcn_or_script
1179 && octave_call_stack::current_frame () == current_frame)
1180 dbstep_flag = -1;
1181 }
1182
1183 if (break_on_this_statement)
1184 do_keyboard ();
1185
1186 }
1187
1188 // ARGS is currently unused, but since the do_keyboard function in
1189 // input.cc accepts an argument list, we preserve it here so that the
1190 // interface won't have to change if we decide to use it in the future.
1191
1192 octave_value
1193 tree_evaluator::do_keyboard (const octave_value_list& args) const
1194 {
1195 return ::do_keyboard (args);
1196 } 1179 }
1197 1180
1198 DEFUN (max_recursion_depth, args, nargout, 1181 DEFUN (max_recursion_depth, args, nargout,
1199 doc: /* -*- texinfo -*- 1182 doc: /* -*- texinfo -*-
1200 @deftypefn {} {@var{val} =} max_recursion_depth () 1183 @deftypefn {} {@var{val} =} max_recursion_depth ()