comparison libinterp/parse-tree/pt-check.cc @ 15195:2fc554ffbc28

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