Mercurial > hg > octave-thorsten
annotate src/pt-stmt.cc @ 7752:40c428ea3408
initial implementation of dbup and dbdown
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sun, 04 May 2008 03:42:19 -0400 |
parents | a059b5679fbb |
children | 71f068b22fcc |
rev | line source |
---|---|
2982 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, |
4 2006, 2007 John W. Eaton | |
2982 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
2982 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
2982 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
4153 | 28 #include "quit.h" |
29 | |
2982 | 30 #include "defun.h" |
31 #include "error.h" | |
32 #include "ov.h" | |
33 #include "oct-lvalue.h" | |
34 #include "input.h" | |
35 #include "pager.h" | |
3770 | 36 #include "pt-bp.h" |
2982 | 37 #include "pt-cmd.h" |
38 #include "pt-id.h" | |
39 #include "pt-idx.h" | |
2985 | 40 #include "pt-jump.h" |
2982 | 41 #include "pt-pr-code.h" |
42 #include "pt-stmt.h" | |
43 #include "pt-walk.h" | |
3707 | 44 #include "unwind-prot.h" |
2982 | 45 #include "utils.h" |
46 #include "variables.h" | |
47 | |
48 // A list of commands to be executed. | |
49 | |
50 tree_statement::~tree_statement (void) | |
51 { | |
52 delete cmd; | |
53 delete expr; | |
3665 | 54 delete comm; |
2982 | 55 } |
56 | |
57 int | |
58 tree_statement::line (void) | |
59 { | |
60 return cmd ? cmd->line () : (expr ? expr->line () : -1); | |
61 } | |
62 | |
63 int | |
64 tree_statement::column (void) | |
65 { | |
66 return cmd ? cmd->column () : (expr ? expr->column () : -1); | |
67 } | |
68 | |
69 void | |
7736 | 70 tree_statement::maybe_echo_code (bool in_function_or_script_body) |
2982 | 71 { |
7736 | 72 if (in_function_or_script_body |
2982 | 73 && (Vecho_executing_commands & ECHO_FUNCTIONS)) |
74 { | |
5794 | 75 tree_print_code tpc (octave_stdout, VPS4); |
2982 | 76 |
77 accept (tpc); | |
78 } | |
79 } | |
80 | |
81 octave_value_list | |
7736 | 82 tree_statement::eval (bool silent, int nargout, |
83 bool in_function_or_script_body) | |
2982 | 84 { |
85 octave_value_list retval; | |
86 | |
87 bool pf = silent ? false : print_flag; | |
88 | |
89 if (cmd || expr) | |
90 { | |
7752
40c428ea3408
initial implementation of dbup and dbdown
John W. Eaton <jwe@octave.org>
parents:
7736
diff
changeset
|
91 if (! (symbol_table::at_top_level () || Vdebugging)) |
7736 | 92 octave_call_stack::set_statement (this); |
3708 | 93 |
7736 | 94 maybe_echo_code (in_function_or_script_body); |
2982 | 95 |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
96 try |
2982 | 97 { |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
98 if (cmd) |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
99 cmd->eval (); |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
100 else |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
101 { |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
102 expr->set_print_flag (pf); |
2982 | 103 |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
104 // FIXME -- maybe all of this should be packaged in |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
105 // one virtual function that returns a flag saying whether |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
106 // or not the expression will take care of binding ans and |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
107 // printing the result. |
2982 | 108 |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
109 // FIXME -- it seems that we should just have to |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
110 // call expr->rvalue () and that should take care of |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
111 // everything, binding ans as necessary? |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
112 |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
113 bool do_bind_ans = false; |
4203 | 114 |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
115 if (expr->is_identifier ()) |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
116 { |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
117 tree_identifier *id = dynamic_cast<tree_identifier *> (expr); |
2982 | 118 |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
119 do_bind_ans = (! id->is_variable ()); |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
120 } |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
121 else |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
122 do_bind_ans = (! expr->is_assignment_expression ()); |
2982 | 123 |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
124 retval = expr->rvalue (nargout); |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
125 |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
126 if (do_bind_ans && ! (error_state || retval.empty ())) |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
127 bind_ans (retval(0), pf); |
2982 | 128 } |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
129 } |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
130 catch (octave_execution_exception) |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
131 { |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
132 octave_exception_state = octave_no_exception; |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
133 error ("caught execution error in library function"); |
2982 | 134 } |
135 } | |
136 | |
137 return retval; | |
138 } | |
139 | |
5861 | 140 tree_statement * |
7336 | 141 tree_statement::dup (symbol_table::scope_id scope) |
5861 | 142 { |
143 tree_statement *new_stmt = new tree_statement (); | |
144 | |
7336 | 145 new_stmt->cmd = cmd ? cmd->dup (scope) : 0; |
5861 | 146 |
7336 | 147 new_stmt->expr = expr ? expr->dup (scope) : 0; |
5861 | 148 |
149 new_stmt->comm = comm ? comm->dup () : 0; | |
150 | |
151 new_stmt->print_flag = print_flag; | |
152 | |
153 return new_stmt; | |
154 } | |
155 | |
2982 | 156 void |
157 tree_statement::accept (tree_walker& tw) | |
158 { | |
159 tw.visit_statement (*this); | |
160 } | |
161 | |
162 octave_value_list | |
163 tree_statement_list::eval (bool silent, int nargout) | |
164 { | |
165 octave_value_list retval; | |
166 | |
5858 | 167 static octave_value_list empty_list; |
168 | |
2982 | 169 if (error_state) |
170 return retval; | |
171 | |
5858 | 172 iterator p = begin (); |
2982 | 173 |
5858 | 174 if (p != end ()) |
175 { | |
176 while (true) | |
2982 | 177 { |
5858 | 178 tree_statement *elt = *p++; |
179 | |
180 if (elt) | |
181 { | |
182 OCTAVE_QUIT; | |
4153 | 183 |
7736 | 184 retval = elt->eval (silent, nargout, |
185 function_body || script_body); | |
5858 | 186 |
187 if (error_state) | |
188 break; | |
189 | |
190 if (tree_break_command::breaking | |
191 || tree_continue_command::continuing) | |
192 break; | |
193 | |
194 if (tree_return_command::returning) | |
195 break; | |
5855 | 196 |
5858 | 197 if (p == end ()) |
198 break; | |
199 else | |
200 { | |
201 // Clear preivous values before next statement is | |
202 // evaluated so that we aren't holding an extra | |
203 // reference to a value that may be used next. For | |
204 // example, in code like this: | |
205 // | |
206 // X = rand (N); ## refcount for X should be 1 | |
207 // ## after this statement | |
208 // | |
209 // X(idx) = val; ## no extra copy of X should be | |
210 // ## needed, but we will be faked | |
211 // ## out if retval is not cleared | |
212 // ## between statements here | |
2982 | 213 |
5858 | 214 retval = empty_list; |
215 } | |
216 } | |
217 else | |
218 error ("invalid statement found in statement list!"); | |
2982 | 219 } |
220 } | |
221 | |
222 return retval; | |
223 } | |
224 | |
3770 | 225 int |
226 tree_statement_list::set_breakpoint (int line) | |
227 { | |
228 tree_breakpoint tbp (line, tree_breakpoint::set); | |
229 accept (tbp); | |
230 | |
231 return tbp.get_line (); | |
232 } | |
233 | |
234 void | |
235 tree_statement_list::delete_breakpoint (int line) | |
236 { | |
3895 | 237 if (line < 0) |
238 { | |
4212 | 239 octave_value_list bp_lst = list_breakpoints (); |
3895 | 240 |
4212 | 241 int len = bp_lst.length (); |
3895 | 242 |
4587 | 243 for (int i = 0; i < len; i++) |
3895 | 244 { |
4587 | 245 tree_breakpoint tbp (i, tree_breakpoint::clear); |
3895 | 246 accept (tbp); |
247 } | |
248 } | |
249 else | |
250 { | |
251 tree_breakpoint tbp (line, tree_breakpoint::clear); | |
252 accept (tbp); | |
253 } | |
3770 | 254 } |
255 | |
256 octave_value_list | |
257 tree_statement_list::list_breakpoints (void) | |
258 { | |
259 tree_breakpoint tbp (0, tree_breakpoint::list); | |
260 accept (tbp); | |
261 | |
262 return tbp.get_list (); | |
263 } | |
264 | |
5861 | 265 tree_statement_list * |
7336 | 266 tree_statement_list::dup (symbol_table::scope_id scope) |
5861 | 267 { |
268 tree_statement_list *new_list = new tree_statement_list (); | |
269 | |
270 new_list->function_body = function_body; | |
271 | |
272 for (iterator p = begin (); p != end (); p++) | |
273 { | |
274 tree_statement *elt = *p; | |
275 | |
7336 | 276 new_list->append (elt ? elt->dup (scope) : 0); |
5861 | 277 } |
278 | |
279 return new_list; | |
280 } | |
281 | |
2982 | 282 void |
283 tree_statement_list::accept (tree_walker& tw) | |
284 { | |
285 tw.visit_statement_list (*this); | |
286 } | |
287 | |
288 /* | |
289 ;;; Local Variables: *** | |
290 ;;; mode: C++ *** | |
291 ;;; End: *** | |
292 */ |