comparison src/pt-eval.cc @ 8658:73c4516fae10

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