Mercurial > hg > octave-nkf
annotate src/pt-check.cc @ 10811:e38c071bbc41
allow user query the maximum array size
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Wed, 21 Jul 2010 08:47:34 +0200 |
parents | 57a59eae83cc |
children | fd0a3ac60b0e |
rev | line source |
---|---|
3011 | 1 /* |
2 | |
8920 | 3 Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2006, 2007, |
4 2008, 2009 John W. Eaton | |
3011 | 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. | |
3011 | 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/>. | |
3011 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
28 #include "error.h" | |
29 #include "input.h" | |
30 #include "ov-usr-fcn.h" | |
31 #include "pt-all.h" | |
32 | |
33 void | |
34 tree_checker::visit_argument_list (tree_argument_list& lst) | |
35 { | |
4219 | 36 tree_argument_list::iterator p = lst.begin (); |
3011 | 37 |
4219 | 38 while (p != lst.end ()) |
3011 | 39 { |
4219 | 40 tree_expression *elt = *p++; |
3011 | 41 |
42 if (elt) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
43 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
44 if (do_lvalue_check && ! elt->lvalue_ok ()) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
45 gripe ("invalid lvalue in multiple assignment", elt->line ()); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
46 } |
3011 | 47 } |
48 } | |
49 | |
50 void | |
51 tree_checker::visit_binary_expression (tree_binary_expression& expr) | |
52 { | |
53 tree_expression *op1 = expr.lhs (); | |
54 | |
55 if (op1) | |
56 op1->accept (*this); | |
57 | |
58 tree_expression *op2 = expr.rhs (); | |
59 | |
60 if (op2) | |
61 op2->accept (*this); | |
62 } | |
63 | |
64 void | |
4207 | 65 tree_checker::visit_break_command (tree_break_command&) |
3011 | 66 { |
67 } | |
68 | |
69 void | |
70 tree_checker::visit_colon_expression (tree_colon_expression& expr) | |
71 { | |
72 tree_expression *op1 = expr.base (); | |
73 | |
74 if (op1) | |
75 op1->accept (*this); | |
76 | |
77 tree_expression *op3 = expr.increment (); | |
78 | |
79 if (op3) | |
80 op3->accept (*this); | |
81 | |
82 tree_expression *op2 = expr.limit (); | |
83 | |
84 if (op2) | |
85 op2->accept (*this); | |
86 } | |
87 | |
88 void | |
4207 | 89 tree_checker::visit_continue_command (tree_continue_command&) |
3011 | 90 { |
91 } | |
92 | |
93 void | |
8658
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
94 tree_checker::do_decl_command (tree_decl_command& cmd) |
3011 | 95 { |
96 tree_decl_init_list *init_list = cmd.initializer_list (); | |
97 | |
98 if (init_list) | |
99 init_list->accept (*this); | |
100 } | |
101 | |
102 void | |
8658
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
103 tree_checker::visit_global_command (tree_global_command& cmd) |
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
104 { |
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
105 do_decl_command (cmd); |
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
106 } |
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
107 |
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
108 void |
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
109 tree_checker::visit_static_command (tree_static_command& cmd) |
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
110 { |
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
111 do_decl_command (cmd); |
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
112 } |
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
113 |
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
114 void |
3011 | 115 tree_checker::visit_decl_elt (tree_decl_elt& cmd) |
116 { | |
117 tree_identifier *id = cmd.ident (); | |
118 | |
119 if (id) | |
120 id->accept (*this); | |
121 | |
122 tree_expression *expr = cmd.expression (); | |
123 | |
124 if (expr) | |
125 expr->accept (*this); | |
126 } | |
127 | |
128 void | |
129 tree_checker::visit_decl_init_list (tree_decl_init_list& lst) | |
130 { | |
4219 | 131 tree_decl_init_list::iterator p = lst.begin (); |
3011 | 132 |
4219 | 133 while (p != lst.end ()) |
3011 | 134 { |
4219 | 135 tree_decl_elt *elt = *p++; |
3011 | 136 |
137 if (elt) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
138 elt->accept (*this); |
3011 | 139 } |
140 } | |
141 | |
142 void | |
143 tree_checker::visit_simple_for_command (tree_simple_for_command& cmd) | |
144 { | |
145 tree_expression *lhs = cmd.left_hand_side (); | |
146 | |
147 if (lhs) | |
148 { | |
149 if (! lhs->lvalue_ok ()) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
150 gripe ("invalid lvalue in for command", cmd.line ()); |
3011 | 151 } |
152 | |
153 tree_expression *expr = cmd.control_expr (); | |
154 | |
155 if (expr) | |
156 expr->accept (*this); | |
157 | |
158 tree_statement_list *list = cmd.body (); | |
159 | |
160 if (list) | |
161 list->accept (*this); | |
162 } | |
163 | |
164 void | |
165 tree_checker::visit_complex_for_command (tree_complex_for_command& cmd) | |
166 { | |
167 tree_argument_list *lhs = cmd.left_hand_side (); | |
168 | |
169 if (lhs) | |
170 { | |
171 int len = lhs->length (); | |
172 | |
3018 | 173 if (len == 0 || len > 2) |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
174 gripe ("invalid number of output arguments in for command", |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
175 cmd.line ()); |
3011 | 176 |
177 do_lvalue_check = true; | |
178 | |
179 lhs->accept (*this); | |
180 | |
181 do_lvalue_check = false; | |
182 } | |
183 | |
184 tree_expression *expr = cmd.control_expr (); | |
185 | |
186 if (expr) | |
187 expr->accept (*this); | |
188 | |
189 tree_statement_list *list = cmd.body (); | |
190 | |
191 if (list) | |
192 list->accept (*this); | |
193 } | |
194 | |
195 void | |
7715
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
196 tree_checker::visit_octave_user_script (octave_user_script& fcn) |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
197 { |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
198 tree_statement_list *cmd_list = fcn.body (); |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
199 |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
200 if (cmd_list) |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
201 cmd_list->accept (*this); |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
202 } |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
203 |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
204 void |
3011 | 205 tree_checker::visit_octave_user_function (octave_user_function& fcn) |
206 { | |
207 tree_statement_list *cmd_list = fcn.body (); | |
208 | |
209 if (cmd_list) | |
210 cmd_list->accept (*this); | |
211 } | |
212 | |
213 void | |
7715
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
214 tree_checker::visit_function_def (tree_function_def& fdef) |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
215 { |
8658
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
216 octave_value fcn = fdef.function (); |
7715
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
217 |
8658
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
218 octave_function *f = fcn.function_value (); |
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
219 |
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
220 if (f) |
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
7715
diff
changeset
|
221 f->accept (*this); |
7715
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
222 } |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
223 |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
224 void |
3011 | 225 tree_checker::visit_identifier (tree_identifier& /* id */) |
226 { | |
227 } | |
228 | |
229 void | |
230 tree_checker::visit_if_clause (tree_if_clause& cmd) | |
231 { | |
232 tree_expression *expr = cmd.condition (); | |
233 | |
234 if (expr) | |
235 expr->accept (*this); | |
236 | |
237 tree_statement_list *list = cmd.commands (); | |
238 | |
239 if (list) | |
240 list->accept (*this); | |
241 } | |
242 | |
243 void | |
244 tree_checker::visit_if_command (tree_if_command& cmd) | |
245 { | |
246 tree_if_command_list *list = cmd.cmd_list (); | |
247 | |
248 if (list) | |
249 list->accept (*this); | |
250 } | |
251 | |
252 void | |
253 tree_checker::visit_if_command_list (tree_if_command_list& lst) | |
254 { | |
4219 | 255 tree_if_command_list::iterator p = lst.begin (); |
3011 | 256 |
4219 | 257 while (p != lst.end ()) |
3011 | 258 { |
4219 | 259 tree_if_clause *elt = *p++; |
3011 | 260 |
261 if (elt) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
262 elt->accept (*this); |
3011 | 263 } |
264 } | |
265 | |
266 void | |
267 tree_checker::visit_index_expression (tree_index_expression& expr) | |
268 { | |
269 tree_expression *e = expr.expression (); | |
270 | |
271 if (e) | |
272 e->accept (*this); | |
273 | |
4219 | 274 std::list<tree_argument_list *> lst = expr.arg_lists (); |
3933 | 275 |
4219 | 276 std::list<tree_argument_list *>::iterator p = lst.begin (); |
3011 | 277 |
4219 | 278 while (p != lst.end ()) |
3933 | 279 { |
4219 | 280 tree_argument_list *elt = *p++; |
3933 | 281 |
282 if (elt) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
283 elt->accept (*this); |
3933 | 284 } |
3011 | 285 } |
286 | |
287 void | |
288 tree_checker::visit_matrix (tree_matrix& lst) | |
289 { | |
4219 | 290 tree_matrix::iterator p = lst.begin (); |
3011 | 291 |
4219 | 292 while (p != lst.end ()) |
3011 | 293 { |
4219 | 294 tree_argument_list *elt = *p++; |
295 | |
296 if (elt) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
297 elt->accept (*this); |
4219 | 298 } |
299 } | |
3011 | 300 |
4219 | 301 void |
302 tree_checker::visit_cell (tree_cell& lst) | |
303 { | |
304 tree_matrix::iterator p = lst.begin (); | |
305 | |
306 while (p != lst.end ()) | |
307 { | |
308 tree_argument_list *elt = *p++; | |
3011 | 309 |
310 if (elt) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
311 elt->accept (*this); |
3011 | 312 } |
313 } | |
314 | |
315 void | |
316 tree_checker::visit_multi_assignment (tree_multi_assignment& expr) | |
317 { | |
318 tree_argument_list *lhs = expr.left_hand_side (); | |
319 | |
320 if (lhs) | |
321 { | |
322 do_lvalue_check = true; | |
323 | |
324 lhs->accept (*this); | |
325 | |
326 do_lvalue_check = false; | |
327 } | |
328 | |
329 tree_expression *rhs = expr.right_hand_side (); | |
330 | |
331 if (rhs) | |
332 rhs->accept (*this); | |
333 } | |
334 | |
335 void | |
336 tree_checker::visit_no_op_command (tree_no_op_command& /* cmd */) | |
337 { | |
338 } | |
339 | |
340 void | |
5861 | 341 tree_checker::visit_anon_fcn_handle (tree_anon_fcn_handle& /* afh */) |
342 { | |
343 } | |
344 | |
345 void | |
3011 | 346 tree_checker::visit_constant (tree_constant& /* val */) |
347 { | |
348 } | |
349 | |
350 void | |
4342 | 351 tree_checker::visit_fcn_handle (tree_fcn_handle& /* fh */) |
352 { | |
353 } | |
354 | |
355 void | |
3011 | 356 tree_checker::visit_parameter_list (tree_parameter_list& lst) |
357 { | |
4219 | 358 tree_parameter_list::iterator p = lst.begin (); |
3011 | 359 |
4219 | 360 while (p != lst.end ()) |
3011 | 361 { |
6215 | 362 tree_decl_elt *elt = *p++; |
3011 | 363 |
364 if (elt) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
365 elt->accept (*this); |
3011 | 366 } |
367 } | |
368 | |
369 void | |
370 tree_checker::visit_postfix_expression (tree_postfix_expression& expr) | |
371 { | |
372 tree_expression *e = expr.operand (); | |
373 | |
374 if (e) | |
375 e->accept (*this); | |
376 } | |
377 | |
378 void | |
379 tree_checker::visit_prefix_expression (tree_prefix_expression& expr) | |
380 { | |
381 tree_expression *e = expr.operand (); | |
382 | |
383 if (e) | |
384 e->accept (*this); | |
385 } | |
386 | |
387 void | |
4207 | 388 tree_checker::visit_return_command (tree_return_command&) |
3011 | 389 { |
390 } | |
391 | |
392 void | |
393 tree_checker::visit_return_list (tree_return_list& lst) | |
394 { | |
4219 | 395 tree_return_list::iterator p = lst.begin (); |
3011 | 396 |
4219 | 397 while (p != lst.end ()) |
3011 | 398 { |
4219 | 399 tree_index_expression *elt = *p++; |
3011 | 400 |
401 if (elt) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
402 elt->accept (*this); |
3011 | 403 } |
404 } | |
405 | |
406 void | |
407 tree_checker::visit_simple_assignment (tree_simple_assignment& expr) | |
408 { | |
409 tree_expression *lhs = expr.left_hand_side (); | |
410 | |
411 if (lhs) | |
412 { | |
413 if (! lhs->lvalue_ok ()) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
414 gripe ("invalid lvalue in assignment", expr.line ()); |
3011 | 415 } |
416 | |
417 tree_expression *rhs = expr.right_hand_side (); | |
418 | |
419 if (rhs) | |
420 rhs->accept (*this); | |
421 } | |
422 | |
423 void | |
424 tree_checker::visit_statement (tree_statement& stmt) | |
425 { | |
426 tree_command *cmd = stmt.command (); | |
427 | |
428 if (cmd) | |
429 cmd->accept (*this); | |
430 else | |
431 { | |
432 tree_expression *expr = stmt.expression (); | |
433 | |
434 if (expr) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
435 expr->accept (*this); |
3011 | 436 } |
437 } | |
438 | |
439 void | |
440 tree_checker::visit_statement_list (tree_statement_list& lst) | |
441 { | |
4219 | 442 for (tree_statement_list::iterator p = lst.begin (); p != lst.end (); p++) |
3011 | 443 { |
4219 | 444 tree_statement *elt = *p; |
3011 | 445 |
446 if (elt) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
447 elt->accept (*this); |
3011 | 448 } |
449 } | |
450 | |
451 void | |
452 tree_checker::visit_switch_case (tree_switch_case& cs) | |
453 { | |
454 tree_expression *label = cs.case_label (); | |
455 | |
456 if (label) | |
457 label->accept (*this); | |
458 | |
459 tree_statement_list *list = cs.commands (); | |
460 | |
461 if (list) | |
462 list->accept (*this); | |
463 } | |
464 | |
465 void | |
466 tree_checker::visit_switch_case_list (tree_switch_case_list& lst) | |
467 { | |
4219 | 468 tree_switch_case_list::iterator p = lst.begin (); |
3011 | 469 |
4219 | 470 while (p != lst.end ()) |
3011 | 471 { |
4219 | 472 tree_switch_case *elt = *p++; |
3011 | 473 |
474 if (elt) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
475 elt->accept (*this); |
3011 | 476 } |
477 } | |
478 | |
479 void | |
480 tree_checker::visit_switch_command (tree_switch_command& cmd) | |
481 { | |
482 tree_expression *expr = cmd.switch_value (); | |
483 | |
484 if (expr) | |
485 expr->accept (*this); | |
486 | |
487 tree_switch_case_list *list = cmd.case_list (); | |
488 | |
489 if (list) | |
490 list->accept (*this); | |
491 } | |
492 | |
493 void | |
494 tree_checker::visit_try_catch_command (tree_try_catch_command& cmd) | |
495 { | |
496 tree_statement_list *try_code = cmd.body (); | |
497 | |
498 if (try_code) | |
499 try_code->accept (*this); | |
500 | |
501 tree_statement_list *catch_code = cmd.cleanup (); | |
502 | |
503 if (catch_code) | |
504 catch_code->accept (*this); | |
505 } | |
506 | |
507 void | |
508 tree_checker::visit_unwind_protect_command | |
509 (tree_unwind_protect_command& cmd) | |
510 { | |
511 tree_statement_list *unwind_protect_code = cmd.body (); | |
512 | |
513 if (unwind_protect_code) | |
514 unwind_protect_code->accept (*this); | |
515 | |
516 tree_statement_list *cleanup_code = cmd.cleanup (); | |
517 | |
518 if (cleanup_code) | |
519 cleanup_code->accept (*this); | |
520 } | |
521 | |
522 void | |
523 tree_checker::visit_while_command (tree_while_command& cmd) | |
524 { | |
525 tree_expression *expr = cmd.condition (); | |
526 | |
527 if (expr) | |
528 expr->accept (*this); | |
529 | |
530 tree_statement_list *list = cmd.body (); | |
531 | |
532 if (list) | |
533 list->accept (*this); | |
534 } | |
535 | |
536 void | |
4229 | 537 tree_checker::visit_do_until_command (tree_do_until_command& cmd) |
538 { | |
539 tree_statement_list *list = cmd.body (); | |
540 | |
541 if (list) | |
542 list->accept (*this); | |
543 | |
544 tree_expression *expr = cmd.condition (); | |
545 | |
546 if (expr) | |
547 expr->accept (*this); | |
548 } | |
549 | |
550 void | |
3523 | 551 tree_checker::gripe (const std::string& msg, int line) |
3011 | 552 { |
553 if (curr_fcn_file_name.empty ()) | |
554 error ("%s", msg.c_str ()); | |
555 else | |
556 error ("%s: %d: %s", curr_fcn_file_name.c_str (), line, msg.c_str ()); | |
557 } |