comparison src/pt-bp.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 5b4d278ec828
children 71742f45571e
comparison
equal deleted inserted replaced
8657:102e05821f93 8658:73c4516fae10
31 31
32 // TRUE means SIGINT should put us in the debugger at the next 32 // TRUE means SIGINT should put us in the debugger at the next
33 // available breakpoint. 33 // available breakpoint.
34 bool octave_debug_on_interrupt_state = false; 34 bool octave_debug_on_interrupt_state = false;
35 35
36 void 36 void
37 tree_breakpoint::take_action (tree &tr) 37 tree_breakpoint::visit_while_command (tree_while_command& cmd)
38 {
39 if (cmd.line () >= line)
40 take_action (cmd);
41
42 if (! found)
43 {
44 tree_statement_list *lst = cmd.body ();
45
46 if (lst)
47 lst->accept (*this);
48 }
49 }
50
51 void
52 tree_breakpoint::visit_do_until_command (tree_do_until_command& cmd)
53 {
54 if (! found)
55 {
56 tree_statement_list *lst = cmd.body ();
57
58 if (lst)
59 lst->accept (*this);
60
61 if (! found)
62 {
63 if (cmd.line () >= line)
64 take_action (cmd);
65 }
66 }
67 }
68
69 void
70 tree_breakpoint::visit_argument_list (tree_argument_list&)
71 {
72 panic_impossible ();
73 }
74
75 void
76 tree_breakpoint::visit_binary_expression (tree_binary_expression&)
77 {
78 panic_impossible ();
79 }
80
81 void
82 tree_breakpoint::visit_break_command (tree_break_command& cmd)
83 {
84 if (cmd.line () >= line)
85 take_action (cmd);
86 }
87
88 void
89 tree_breakpoint::visit_colon_expression (tree_colon_expression&)
90 {
91 panic_impossible ();
92 }
93
94 void
95 tree_breakpoint::visit_continue_command (tree_continue_command& cmd)
96 {
97 if (cmd.line () >= line)
98 take_action (cmd);
99 }
100
101 void
102 tree_breakpoint::do_decl_command (tree_decl_command& cmd)
103 {
104 if (cmd.line () >= line)
105 take_action (cmd);
106 }
107
108 void
109 tree_breakpoint::visit_global_command (tree_global_command& cmd)
110 {
111 do_decl_command (cmd);
112 }
113
114 void
115 tree_breakpoint::visit_static_command (tree_static_command& cmd)
116 {
117 do_decl_command (cmd);
118 }
119
120 void
121 tree_breakpoint::visit_decl_elt (tree_decl_elt&)
122 {
123 panic_impossible ();
124 }
125
126 void
127 tree_breakpoint::visit_decl_init_list (tree_decl_init_list&)
128 {
129 panic_impossible ();
130 }
131
132 void
133 tree_breakpoint::visit_simple_for_command (tree_simple_for_command& cmd)
134 {
135 if (cmd.line () >= line)
136 take_action (cmd);
137
138 if (! found)
139 {
140 tree_statement_list *lst = cmd.body ();
141
142 if (lst)
143 lst->accept (*this);
144 }
145 }
146
147 void
148 tree_breakpoint::visit_complex_for_command (tree_complex_for_command& cmd)
149 {
150 if (cmd.line () >= line)
151 take_action (cmd);
152
153 if (! found)
154 {
155 tree_statement_list *lst = cmd.body ();
156
157 if (lst)
158 lst->accept (*this);
159 }
160 }
161
162 void
163 tree_breakpoint::visit_octave_user_script (octave_user_script&)
164 {
165 panic_impossible ();
166 }
167
168 void
169 tree_breakpoint::visit_octave_user_function (octave_user_function&)
170 {
171 panic_impossible ();
172 }
173
174 void
175 tree_breakpoint::visit_octave_user_function_header (octave_user_function&)
176 {
177 panic_impossible ();
178 }
179
180 void
181 tree_breakpoint::visit_octave_user_function_trailer (octave_user_function&)
182 {
183 panic_impossible ();
184 }
185
186 void
187 tree_breakpoint::visit_function_def (tree_function_def& fdef)
188 {
189 octave_value fcn = fdef.function ();
190
191 octave_function *f = fcn.function_value ();
192
193 if (f)
194 f->accept (*this);
195 }
196
197 void
198 tree_breakpoint::visit_identifier (tree_identifier&)
199 {
200 panic_impossible ();
201 }
202
203 void
204 tree_breakpoint::visit_if_clause (tree_if_clause&)
205 {
206 panic_impossible ();
207 }
208
209 void
210 tree_breakpoint::visit_if_command (tree_if_command& cmd)
211 {
212 tree_if_command_list *lst = cmd.cmd_list ();
213
214 if (lst)
215 lst->accept (*this);
216 }
217
218 void
219 tree_breakpoint::visit_if_command_list (tree_if_command_list& lst)
220 {
221 for (tree_if_command_list::iterator p = lst.begin (); p != lst.end (); p++)
222 {
223 tree_if_clause *t = *p;
224
225 if (t->line () >= line)
226 take_action (*t);
227
228 if (! found)
229 {
230 tree_statement_list *stmt_lst = t->commands ();
231
232 if (stmt_lst)
233 stmt_lst->accept (*this);
234 }
235
236 if (found)
237 break;
238 }
239 }
240
241 void
242 tree_breakpoint::visit_index_expression (tree_index_expression&)
243 {
244 panic_impossible ();
245 }
246
247 void
248 tree_breakpoint::visit_matrix (tree_matrix&)
249 {
250 panic_impossible ();
251 }
252
253 void
254 tree_breakpoint::visit_cell (tree_cell&)
255 {
256 panic_impossible ();
257 }
258
259 void
260 tree_breakpoint::visit_multi_assignment (tree_multi_assignment&)
261 {
262 panic_impossible ();
263 }
264
265 void
266 tree_breakpoint::visit_no_op_command (tree_no_op_command&)
267 {
268 }
269
270 void
271 tree_breakpoint::visit_anon_fcn_handle (tree_anon_fcn_handle&)
272 {
273 panic_impossible ();
274 }
275
276 void
277 tree_breakpoint::visit_constant (tree_constant&)
278 {
279 panic_impossible ();
280 }
281
282 void
283 tree_breakpoint::visit_fcn_handle (tree_fcn_handle&)
284 {
285 panic_impossible ();
286 }
287
288 void
289 tree_breakpoint::visit_parameter_list (tree_parameter_list&)
290 {
291 panic_impossible ();
292 }
293
294 void
295 tree_breakpoint::visit_postfix_expression (tree_postfix_expression&)
296 {
297 panic_impossible ();
298 }
299
300 void
301 tree_breakpoint::visit_prefix_expression (tree_prefix_expression&)
302 {
303 panic_impossible ();
304 }
305
306 void
307 tree_breakpoint::visit_return_command (tree_return_command& cmd)
308 {
309 if (cmd.line () >= line)
310 take_action (cmd);
311 }
312
313 void
314 tree_breakpoint::visit_return_list (tree_return_list&)
315 {
316 panic_impossible ();
317 }
318
319 void
320 tree_breakpoint::visit_simple_assignment (tree_simple_assignment&)
321 {
322 panic_impossible ();
323 }
324
325 void
326 tree_breakpoint::visit_statement (tree_statement& stmt)
327 {
328 if (stmt.line () >= line)
329 {
330 take_action (stmt);
331 }
332 else if (stmt.is_command ())
333 {
334 tree_command *cmd = stmt.command ();
335
336 cmd->accept (*this);
337 }
338
339 // There is no need to do anything for expressions because they
340 // can't contain additional lists of statements.
341 }
342
343 void
344 tree_breakpoint::visit_statement_list (tree_statement_list& lst)
345 {
346 for (tree_statement_list::iterator p = lst.begin (); p != lst.end (); p++)
347 {
348 tree_statement *elt = *p;
349
350 if (elt)
351 {
352 elt->accept (*this);
353
354 if (found)
355 break;
356 }
357 }
358 }
359
360 void
361 tree_breakpoint::visit_switch_case (tree_switch_case&)
362 {
363 panic_impossible ();
364 }
365
366 void
367 tree_breakpoint::visit_switch_case_list (tree_switch_case_list& lst)
368 {
369 for (tree_switch_case_list::iterator p = lst.begin (); p != lst.end (); p++)
370 {
371 tree_switch_case *t = *p;
372
373 if (t->line () >= line)
374 take_action (*t);
375
376 if (! found)
377 {
378 tree_statement_list *stmt_lst = t->commands ();
379
380 if (stmt_lst)
381 stmt_lst->accept (*this);
382 }
383
384 if (found)
385 break;
386 }
387 }
388
389 void
390 tree_breakpoint::visit_switch_command (tree_switch_command& cmd)
391 {
392 if (cmd.line () >= line)
393 take_action (cmd);
394
395 if (! found)
396 {
397 tree_switch_case_list *lst = cmd.case_list ();
398
399 if (lst)
400 lst->accept (*this);
401 }
402 }
403
404 void
405 tree_breakpoint::visit_try_catch_command (tree_try_catch_command& cmd)
406 {
407 tree_statement_list *try_code = cmd.body ();
408
409 if (try_code)
410 try_code->accept (*this);
411
412 if (! found)
413 {
414 tree_statement_list *catch_code = cmd.cleanup ();
415
416 if (catch_code)
417 catch_code->accept (*this);
418 }
419 }
420
421 void
422 tree_breakpoint::visit_unwind_protect_command (tree_unwind_protect_command& cmd)
423 {
424 tree_statement_list *body = cmd.body ();
425
426 if (body)
427 body->accept (*this);
428
429 if (! found)
430 {
431 tree_statement_list *cleanup = cmd.cleanup ();
432
433 if (cleanup)
434 cleanup->accept (*this);
435 }
436 }
437
438 void
439 tree_breakpoint::take_action (tree& tr)
38 { 440 {
39 if (act == set) 441 if (act == set)
40 { 442 {
41 tr.set_breakpoint (); 443 tr.set_breakpoint ();
42 line = tr.line (); 444 line = tr.line ();
55 line = tr.line () + 1; 457 line = tr.line () + 1;
56 } 458 }
57 } 459 }
58 else 460 else
59 panic_impossible (); 461 panic_impossible ();
60 462 }
61 return; 463
62 } 464 void
63 465 tree_breakpoint::take_action (tree_statement& stmt)
64 void 466 {
65 tree_breakpoint::visit_while_command (tree_while_command& cmd) 467 int lineno = stmt.line ();
66 { 468
67 if (found) 469 if (act == set)
68 return; 470 {
69 471 stmt.set_breakpoint ();
70 if (cmd.line () >= line) 472 line = lineno;
71 take_action (cmd); 473 found = true;
72 474 }
73 tree_expression *expr = cmd.condition (); 475 else if (act == clear)
74 476 {
75 if (expr) 477 stmt.delete_breakpoint ();
76 expr->accept (*this); 478 found = true;
77 479 }
78 tree_statement_list *lst = cmd.body (); 480 else if (act == list)
79 481 {
80 if (lst) 482 if (stmt.is_breakpoint ())
81 lst->accept (*this);
82 }
83
84 void
85 tree_breakpoint::visit_do_until_command (tree_do_until_command& cmd)
86 {
87 if (found)
88 return;
89
90 if (cmd.line () >= line)
91 take_action (cmd);
92
93 tree_statement_list *lst = cmd.body ();
94
95 if (lst)
96 lst->accept (*this);
97
98 if (found)
99 return;
100
101 tree_expression *expr = cmd.condition ();
102
103 if (expr)
104 expr->accept (*this);
105 }
106
107 void
108 tree_breakpoint::visit_argument_list (tree_argument_list& lst)
109 {
110 if (found)
111 return;
112
113 for (tree_argument_list::iterator p = lst.begin (); p != lst.end (); p++)
114 {
115 tree_expression *elt = *p;
116
117 if (elt)
118 elt->accept (*this);
119 }
120 }
121
122 void
123 tree_breakpoint::visit_binary_expression (tree_binary_expression& expr)
124 {
125 if (found)
126 return;
127
128 tree_expression *lhs = expr.lhs ();
129 tree_expression *rhs = expr.rhs ();
130
131 if (lhs && lhs->line () >= line)
132 lhs->accept (*this);
133
134 if (rhs && rhs->line () >= line)
135 rhs->accept (*this);
136 }
137
138 void
139 tree_breakpoint::visit_break_command (tree_break_command& cmd)
140 {
141 if (found)
142 return;
143
144 if (cmd.line () >= line)
145 take_action (cmd);
146 }
147
148 void
149 tree_breakpoint::visit_colon_expression (tree_colon_expression& expr)
150 {
151 if (found)
152 return;
153
154 if (expr.line () >= line)
155 take_action (expr);
156
157 tree_expression *base = expr.base ();
158
159 if (base)
160 base->accept (*this);
161
162 tree_expression *increment = expr.increment ();
163
164 if (increment)
165 increment->accept (*this);
166
167 tree_expression *limit = expr.limit ();
168
169 if (limit)
170 limit->accept (*this);
171 }
172
173 void
174 tree_breakpoint::visit_continue_command (tree_continue_command& cmd)
175 {
176 if (found)
177 return;
178
179 if (cmd.line () >= line)
180 take_action (cmd);
181 }
182
183 void
184 tree_breakpoint::visit_decl_command (tree_decl_command& cmd)
185 {
186 if (found)
187 return;
188
189 if (cmd.line () >= line)
190 take_action (cmd);
191
192 tree_decl_init_list *init_list = cmd.initializer_list ();
193
194 if (init_list)
195 init_list->accept (*this);
196 }
197
198 void
199 tree_breakpoint::visit_decl_elt (tree_decl_elt& cmd)
200 {
201 if (found)
202 return;
203
204 tree_identifier *ident = cmd.ident ();
205
206 if (ident)
207 ident->accept (*this);
208
209 tree_expression *expr = cmd.expression ();
210
211 if (expr)
212 expr->accept (*this);
213
214 }
215
216 void
217 tree_breakpoint::visit_decl_init_list (tree_decl_init_list& lst)
218 {
219 if (found)
220 return;
221
222 for (tree_decl_init_list::iterator p = lst.begin (); p != lst.end (); p++)
223 {
224 tree_decl_elt *elt = *p;
225
226 if (elt)
227 elt->accept (*this);
228 }
229 }
230
231 void
232 tree_breakpoint::visit_simple_for_command (tree_simple_for_command& cmd)
233 {
234 if (found)
235 return;
236
237 if (cmd.line () >= line)
238 take_action (cmd);
239
240 tree_expression *expr = cmd.control_expr ();
241
242 if (expr)
243 expr->accept (*this);
244
245 tree_statement_list *lst = cmd.body ();
246
247 if (lst)
248 lst->accept (*this);
249 }
250
251 void
252 tree_breakpoint::visit_complex_for_command (tree_complex_for_command& cmd)
253 {
254 if (found)
255 return;
256
257 if (cmd.line () >= line)
258 take_action (cmd);
259
260 tree_expression *expr = cmd.control_expr ();
261
262 if (expr)
263 expr->accept (*this);
264
265 tree_statement_list *lst = cmd.body ();
266
267 if (lst)
268 lst->accept (*this);
269
270 }
271
272 void
273 tree_breakpoint::visit_octave_user_script (octave_user_script&)
274 {
275 // FIXME -- should anything happen here?
276 }
277
278 void
279 tree_breakpoint::visit_octave_user_function (octave_user_function&)
280 {
281 // We should not visit octave user functions because the function we
282 // are currently in is the function where the breakpoint was
283 // requested.
284 }
285
286 void
287 tree_breakpoint::visit_octave_user_function_header (octave_user_function&)
288 {
289 // Do nothing.
290 }
291
292 void
293 tree_breakpoint::visit_octave_user_function_trailer (octave_user_function&)
294 {
295 // Do nothing.
296 }
297
298 void
299 tree_breakpoint::visit_function_def (tree_function_def& fdef)
300 {
301 if (found)
302 return;
303
304 octave_function *fcn = fdef.function ();
305
306 if (fcn)
307 fcn->accept (*this);
308 }
309
310 void
311 tree_breakpoint::visit_identifier (tree_identifier& id)
312 {
313 if (found)
314 return;
315
316 if (id.line () >= line )
317 take_action (id);
318 }
319
320 void
321 tree_breakpoint::visit_if_clause (tree_if_clause& cmd)
322 {
323 if (found)
324 return;
325
326 tree_expression *expr = cmd.condition ();
327
328 if (expr)
329 expr->accept (*this);
330
331 tree_statement_list *lst = cmd.commands ();
332
333 if (lst)
334 lst->accept (*this);
335 }
336
337 void
338 tree_breakpoint::visit_if_command (tree_if_command& cmd)
339 {
340 if (found)
341 return;
342
343 tree_if_command_list *lst = cmd.cmd_list ();
344
345 if (lst)
346 lst->accept (*this);
347 }
348
349 void
350 tree_breakpoint::visit_if_command_list (tree_if_command_list& lst)
351 {
352 if (found)
353 return;
354
355 for (tree_if_command_list::iterator p = lst.begin (); p != lst.end (); p++)
356 {
357 tree_if_clause *elt = *p;
358
359 if (elt)
360 elt->accept (*this);
361 }
362 }
363
364 void
365 tree_breakpoint::visit_index_expression (tree_index_expression& cmd)
366 {
367 if (found)
368 return;
369
370 tree_expression *expr = cmd.expression ();
371
372 if (expr && expr->line () >= line)
373 take_action (*expr);
374
375 std::list<tree_argument_list *> lst = cmd.arg_lists ();
376
377
378 if (! lst.empty ())
379 {
380 for (std::list<tree_argument_list *>::iterator p = lst.begin ();
381 p != lst.end ();
382 p++)
383 { 483 {
384 tree_argument_list *elt = *p; 484 bp_list.append (octave_value (lineno));
385 485 line = lineno + 1;
386 if (elt) 486 }
387 elt->accept (*this); 487 }
388 }
389 }
390 }
391
392 void
393 tree_breakpoint::visit_matrix (tree_matrix& mat)
394 {
395 if (found)
396 return;
397
398 tree_matrix::iterator p = mat.begin ();
399
400 while (p != mat.end ())
401 {
402 tree_argument_list *elt = *p++;
403
404 if (elt)
405 elt->accept (*this);
406 }
407 }
408
409 void
410 tree_breakpoint::visit_cell (tree_cell& cell)
411 {
412 if (found)
413 return;
414
415 tree_cell::iterator p = cell.begin ();
416
417 while (p != cell.end ())
418 {
419 tree_argument_list *elt = *p++;
420
421 if (elt)
422 elt->accept (*this);
423 }
424 }
425
426 void
427 tree_breakpoint::visit_multi_assignment (tree_multi_assignment& expr)
428 {
429 if (found)
430 return;
431
432 tree_argument_list *lst = expr.left_hand_side ();
433
434 if (lst)
435 lst->accept (*this);
436
437 tree_expression *rhs = expr.right_hand_side ();
438
439 if (rhs)
440 rhs->accept (*this);
441 }
442
443 void
444 tree_breakpoint::visit_no_op_command (tree_no_op_command& cmd)
445 {
446 if (found)
447 return;
448
449 if (cmd.line () >= line)
450 take_action (cmd);
451 }
452
453 void
454 tree_breakpoint::visit_anon_fcn_handle (tree_anon_fcn_handle& afh)
455 {
456 if (found)
457 return;
458
459 if (afh.line () >= line)
460 take_action (afh);
461 }
462
463 void
464 tree_breakpoint::visit_constant (tree_constant& cmd)
465 {
466 if (found)
467 return;
468
469 if (cmd.line () >= line)
470 take_action (cmd);
471 }
472
473 void
474 tree_breakpoint::visit_fcn_handle (tree_fcn_handle& fh)
475 {
476 if (found)
477 return;
478
479 if (fh.line () >= line)
480 take_action (fh);
481 }
482
483 void
484 tree_breakpoint::visit_parameter_list (tree_parameter_list& lst)
485 {
486 if (found)
487 return;
488
489 tree_parameter_list::iterator p = lst.begin ();
490
491 while (p != lst.end ())
492 {
493 tree_decl_elt *elt = *p++;
494
495 if (elt)
496 elt->accept (*this);
497 }
498 }
499
500 void
501 tree_breakpoint::visit_postfix_expression (tree_postfix_expression& expr)
502 {
503 if (found)
504 return;
505
506 if (expr.line () >= line)
507 take_action (expr);
508
509 tree_expression *e = expr.operand ();
510
511 if (e)
512 e->accept (*this);
513 }
514
515 void
516 tree_breakpoint::visit_prefix_expression (tree_prefix_expression& expr)
517 {
518 if (found)
519 return;
520
521 if (expr.line () >= line)
522 take_action (expr);
523
524 tree_expression *e = expr.operand ();
525
526 if (e)
527 e->accept (*this);
528 }
529
530 void
531 tree_breakpoint::visit_return_command (tree_return_command& cmd)
532 {
533 if (found)
534 return;
535
536 if (cmd.line () >= line)
537 take_action (cmd);
538 }
539
540 void
541 tree_breakpoint::visit_return_list (tree_return_list& lst)
542 {
543 if (found)
544 return;
545
546 tree_return_list::iterator p = lst.begin ();
547
548 while (p != lst.end ())
549 {
550 tree_index_expression *elt = *p++;
551
552 if (elt)
553 elt->accept (*this);
554 }
555 }
556
557 void
558 tree_breakpoint::visit_simple_assignment (tree_simple_assignment& expr)
559 {
560 if (found)
561 return;
562
563 if (expr.line () >= line)
564 take_action (expr);
565
566 }
567
568 void
569 tree_breakpoint::visit_statement (tree_statement& stmt)
570 {
571 if (found)
572 return;
573
574 tree_command *cmd = stmt.command ();
575
576 if (cmd)
577 cmd->accept (*this);
578 else 488 else
579 { 489 panic_impossible ();
580 tree_expression *expr = stmt.expression ();
581
582 if (expr)
583 expr->accept (*this);
584 }
585 }
586
587 void
588 tree_breakpoint::visit_statement_list (tree_statement_list& lst)
589 {
590 if (found)
591 return;
592
593 for (tree_statement_list::iterator p = lst.begin (); p != lst.end (); p++)
594 {
595 tree_statement *elt = *p;
596
597 if (elt)
598 elt->accept (*this);
599 }
600 }
601
602 void
603 tree_breakpoint::visit_switch_case (tree_switch_case& cmd)
604 {
605 if (found)
606 return;
607
608 // Disallow breakpoints on the label.
609
610 tree_statement_list *lst = cmd.commands ();
611
612 if (lst)
613 lst->accept (*this);
614 }
615
616 void
617 tree_breakpoint::visit_switch_case_list (tree_switch_case_list& lst)
618 {
619 if (found)
620 return;
621
622 tree_switch_case_list::iterator p = lst.begin ();
623
624 while (p != lst.end ())
625 {
626 tree_switch_case *elt = *p++;
627
628 if (elt)
629 elt->accept (*this);
630 }
631 }
632
633
634 void
635 tree_breakpoint::visit_switch_command (tree_switch_command& cmd)
636 {
637 if (found)
638 return;
639
640 tree_expression *expr = cmd.switch_value ();
641
642 if (expr)
643 expr->accept (*this);
644
645 tree_switch_case_list *lst = cmd.case_list ();
646
647 if (lst)
648 lst->accept (*this);
649 }
650
651 void
652 tree_breakpoint::visit_try_catch_command (tree_try_catch_command& cmd)
653 {
654 if (found)
655 return;
656
657 if (cmd.line () >= line)
658 take_action (cmd);
659
660 tree_statement_list *try_code = cmd.body ();
661
662 if (try_code)
663 try_code->accept (*this);
664
665 tree_statement_list *catch_code = cmd.cleanup ();
666
667 if (catch_code)
668 catch_code->accept (*this);
669 }
670
671 void
672 tree_breakpoint::visit_unwind_protect_command (tree_unwind_protect_command& cmd)
673 {
674 if (found)
675 return;
676
677 if (cmd.line () >= line)
678 take_action (cmd);
679
680 tree_statement_list *lstA = cmd.body ();
681
682 if (lstA)
683 lstA->accept (*this);
684
685 tree_statement_list *lstB = cmd.cleanup ();
686
687 if (lstB)
688 lstB->accept (*this);
689 } 490 }
690 491
691 /* 492 /*
692 ;;; Local Variables: *** 493 ;;; Local Variables: ***
693 ;;; mode: C++ *** 494 ;;; mode: C++ ***