00001 /* 00002 00003 Copyright (C) 1996-2012 John W. Eaton 00004 00005 This file is part of Octave. 00006 00007 Octave is free software; you can redistribute it and/or modify it 00008 under the terms of the GNU General Public License as published by the 00009 Free Software Foundation; either version 3 of the License, or (at your 00010 option) any later version. 00011 00012 Octave is distributed in the hope that it will be useful, but WITHOUT 00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00015 for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with Octave; see the file COPYING. If not, see 00019 <http://www.gnu.org/licenses/>. 00020 00021 */ 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include "error.h" 00028 #include "input.h" 00029 #include "ov-usr-fcn.h" 00030 #include "pt-all.h" 00031 00032 void 00033 tree_checker::visit_argument_list (tree_argument_list& lst) 00034 { 00035 tree_argument_list::iterator p = lst.begin (); 00036 00037 while (p != lst.end ()) 00038 { 00039 tree_expression *elt = *p++; 00040 00041 if (elt) 00042 { 00043 if (do_lvalue_check && ! elt->lvalue_ok ()) 00044 gripe ("invalid lvalue in multiple assignment", elt->line ()); 00045 } 00046 } 00047 } 00048 00049 void 00050 tree_checker::visit_binary_expression (tree_binary_expression& expr) 00051 { 00052 tree_expression *op1 = expr.lhs (); 00053 00054 if (op1) 00055 op1->accept (*this); 00056 00057 tree_expression *op2 = expr.rhs (); 00058 00059 if (op2) 00060 op2->accept (*this); 00061 } 00062 00063 void 00064 tree_checker::visit_break_command (tree_break_command&) 00065 { 00066 } 00067 00068 void 00069 tree_checker::visit_colon_expression (tree_colon_expression& expr) 00070 { 00071 tree_expression *op1 = expr.base (); 00072 00073 if (op1) 00074 op1->accept (*this); 00075 00076 tree_expression *op3 = expr.increment (); 00077 00078 if (op3) 00079 op3->accept (*this); 00080 00081 tree_expression *op2 = expr.limit (); 00082 00083 if (op2) 00084 op2->accept (*this); 00085 } 00086 00087 void 00088 tree_checker::visit_continue_command (tree_continue_command&) 00089 { 00090 } 00091 00092 void 00093 tree_checker::do_decl_command (tree_decl_command& cmd) 00094 { 00095 tree_decl_init_list *init_list = cmd.initializer_list (); 00096 00097 if (init_list) 00098 init_list->accept (*this); 00099 } 00100 00101 void 00102 tree_checker::visit_global_command (tree_global_command& cmd) 00103 { 00104 do_decl_command (cmd); 00105 } 00106 00107 void 00108 tree_checker::visit_static_command (tree_static_command& cmd) 00109 { 00110 do_decl_command (cmd); 00111 } 00112 00113 void 00114 tree_checker::visit_decl_elt (tree_decl_elt& cmd) 00115 { 00116 tree_identifier *id = cmd.ident (); 00117 00118 if (id) 00119 id->accept (*this); 00120 00121 tree_expression *expr = cmd.expression (); 00122 00123 if (expr) 00124 expr->accept (*this); 00125 } 00126 00127 void 00128 tree_checker::visit_decl_init_list (tree_decl_init_list& lst) 00129 { 00130 tree_decl_init_list::iterator p = lst.begin (); 00131 00132 while (p != lst.end ()) 00133 { 00134 tree_decl_elt *elt = *p++; 00135 00136 if (elt) 00137 elt->accept (*this); 00138 } 00139 } 00140 00141 void 00142 tree_checker::visit_simple_for_command (tree_simple_for_command& cmd) 00143 { 00144 tree_expression *lhs = cmd.left_hand_side (); 00145 00146 if (lhs) 00147 { 00148 if (! lhs->lvalue_ok ()) 00149 gripe ("invalid lvalue in for command", cmd.line ()); 00150 } 00151 00152 tree_expression *expr = cmd.control_expr (); 00153 00154 if (expr) 00155 expr->accept (*this); 00156 00157 tree_expression *maxproc = cmd.maxproc_expr (); 00158 00159 if (maxproc) 00160 maxproc->accept (*this); 00161 00162 tree_statement_list *list = cmd.body (); 00163 00164 if (list) 00165 list->accept (*this); 00166 } 00167 00168 void 00169 tree_checker::visit_complex_for_command (tree_complex_for_command& cmd) 00170 { 00171 tree_argument_list *lhs = cmd.left_hand_side (); 00172 00173 if (lhs) 00174 { 00175 int len = lhs->length (); 00176 00177 if (len == 0 || len > 2) 00178 gripe ("invalid number of output arguments in for command", 00179 cmd.line ()); 00180 00181 do_lvalue_check = true; 00182 00183 lhs->accept (*this); 00184 00185 do_lvalue_check = false; 00186 } 00187 00188 tree_expression *expr = cmd.control_expr (); 00189 00190 if (expr) 00191 expr->accept (*this); 00192 00193 tree_statement_list *list = cmd.body (); 00194 00195 if (list) 00196 list->accept (*this); 00197 } 00198 00199 void 00200 tree_checker::visit_octave_user_script (octave_user_script& fcn) 00201 { 00202 tree_statement_list *cmd_list = fcn.body (); 00203 00204 if (cmd_list) 00205 cmd_list->accept (*this); 00206 } 00207 00208 void 00209 tree_checker::visit_octave_user_function (octave_user_function& fcn) 00210 { 00211 tree_statement_list *cmd_list = fcn.body (); 00212 00213 if (cmd_list) 00214 cmd_list->accept (*this); 00215 } 00216 00217 void 00218 tree_checker::visit_function_def (tree_function_def& fdef) 00219 { 00220 octave_value fcn = fdef.function (); 00221 00222 octave_function *f = fcn.function_value (); 00223 00224 if (f) 00225 f->accept (*this); 00226 } 00227 00228 void 00229 tree_checker::visit_identifier (tree_identifier& /* id */) 00230 { 00231 } 00232 00233 void 00234 tree_checker::visit_if_clause (tree_if_clause& cmd) 00235 { 00236 tree_expression *expr = cmd.condition (); 00237 00238 if (expr) 00239 expr->accept (*this); 00240 00241 tree_statement_list *list = cmd.commands (); 00242 00243 if (list) 00244 list->accept (*this); 00245 } 00246 00247 void 00248 tree_checker::visit_if_command (tree_if_command& cmd) 00249 { 00250 tree_if_command_list *list = cmd.cmd_list (); 00251 00252 if (list) 00253 list->accept (*this); 00254 } 00255 00256 void 00257 tree_checker::visit_if_command_list (tree_if_command_list& lst) 00258 { 00259 tree_if_command_list::iterator p = lst.begin (); 00260 00261 while (p != lst.end ()) 00262 { 00263 tree_if_clause *elt = *p++; 00264 00265 if (elt) 00266 elt->accept (*this); 00267 } 00268 } 00269 00270 void 00271 tree_checker::visit_index_expression (tree_index_expression& expr) 00272 { 00273 tree_expression *e = expr.expression (); 00274 00275 if (e) 00276 e->accept (*this); 00277 00278 std::list<tree_argument_list *> lst = expr.arg_lists (); 00279 00280 std::list<tree_argument_list *>::iterator p = lst.begin (); 00281 00282 while (p != lst.end ()) 00283 { 00284 tree_argument_list *elt = *p++; 00285 00286 if (elt) 00287 elt->accept (*this); 00288 } 00289 } 00290 00291 void 00292 tree_checker::visit_matrix (tree_matrix& lst) 00293 { 00294 tree_matrix::iterator p = lst.begin (); 00295 00296 while (p != lst.end ()) 00297 { 00298 tree_argument_list *elt = *p++; 00299 00300 if (elt) 00301 elt->accept (*this); 00302 } 00303 } 00304 00305 void 00306 tree_checker::visit_cell (tree_cell& lst) 00307 { 00308 tree_matrix::iterator p = lst.begin (); 00309 00310 while (p != lst.end ()) 00311 { 00312 tree_argument_list *elt = *p++; 00313 00314 if (elt) 00315 elt->accept (*this); 00316 } 00317 } 00318 00319 void 00320 tree_checker::visit_multi_assignment (tree_multi_assignment& expr) 00321 { 00322 tree_argument_list *lhs = expr.left_hand_side (); 00323 00324 if (lhs) 00325 { 00326 do_lvalue_check = true; 00327 00328 lhs->accept (*this); 00329 00330 do_lvalue_check = false; 00331 } 00332 00333 tree_expression *rhs = expr.right_hand_side (); 00334 00335 if (rhs) 00336 rhs->accept (*this); 00337 } 00338 00339 void 00340 tree_checker::visit_no_op_command (tree_no_op_command& /* cmd */) 00341 { 00342 } 00343 00344 void 00345 tree_checker::visit_anon_fcn_handle (tree_anon_fcn_handle& /* afh */) 00346 { 00347 } 00348 00349 void 00350 tree_checker::visit_constant (tree_constant& /* val */) 00351 { 00352 } 00353 00354 void 00355 tree_checker::visit_fcn_handle (tree_fcn_handle& /* fh */) 00356 { 00357 } 00358 00359 void 00360 tree_checker::visit_parameter_list (tree_parameter_list& lst) 00361 { 00362 tree_parameter_list::iterator p = lst.begin (); 00363 00364 while (p != lst.end ()) 00365 { 00366 tree_decl_elt *elt = *p++; 00367 00368 if (elt) 00369 elt->accept (*this); 00370 } 00371 } 00372 00373 void 00374 tree_checker::visit_postfix_expression (tree_postfix_expression& expr) 00375 { 00376 tree_expression *e = expr.operand (); 00377 00378 if (e) 00379 e->accept (*this); 00380 } 00381 00382 void 00383 tree_checker::visit_prefix_expression (tree_prefix_expression& expr) 00384 { 00385 tree_expression *e = expr.operand (); 00386 00387 if (e) 00388 e->accept (*this); 00389 } 00390 00391 void 00392 tree_checker::visit_return_command (tree_return_command&) 00393 { 00394 } 00395 00396 void 00397 tree_checker::visit_return_list (tree_return_list& lst) 00398 { 00399 tree_return_list::iterator p = lst.begin (); 00400 00401 while (p != lst.end ()) 00402 { 00403 tree_index_expression *elt = *p++; 00404 00405 if (elt) 00406 elt->accept (*this); 00407 } 00408 } 00409 00410 void 00411 tree_checker::visit_simple_assignment (tree_simple_assignment& expr) 00412 { 00413 tree_expression *lhs = expr.left_hand_side (); 00414 00415 if (lhs) 00416 { 00417 if (! lhs->lvalue_ok ()) 00418 gripe ("invalid lvalue in assignment", expr.line ()); 00419 } 00420 00421 tree_expression *rhs = expr.right_hand_side (); 00422 00423 if (rhs) 00424 rhs->accept (*this); 00425 } 00426 00427 void 00428 tree_checker::visit_statement (tree_statement& stmt) 00429 { 00430 tree_command *cmd = stmt.command (); 00431 00432 if (cmd) 00433 cmd->accept (*this); 00434 else 00435 { 00436 tree_expression *expr = stmt.expression (); 00437 00438 if (expr) 00439 expr->accept (*this); 00440 } 00441 } 00442 00443 void 00444 tree_checker::visit_statement_list (tree_statement_list& lst) 00445 { 00446 for (tree_statement_list::iterator p = lst.begin (); p != lst.end (); p++) 00447 { 00448 tree_statement *elt = *p; 00449 00450 if (elt) 00451 elt->accept (*this); 00452 } 00453 } 00454 00455 void 00456 tree_checker::visit_switch_case (tree_switch_case& cs) 00457 { 00458 tree_expression *label = cs.case_label (); 00459 00460 if (label) 00461 label->accept (*this); 00462 00463 tree_statement_list *list = cs.commands (); 00464 00465 if (list) 00466 list->accept (*this); 00467 } 00468 00469 void 00470 tree_checker::visit_switch_case_list (tree_switch_case_list& lst) 00471 { 00472 tree_switch_case_list::iterator p = lst.begin (); 00473 00474 while (p != lst.end ()) 00475 { 00476 tree_switch_case *elt = *p++; 00477 00478 if (elt) 00479 elt->accept (*this); 00480 } 00481 } 00482 00483 void 00484 tree_checker::visit_switch_command (tree_switch_command& cmd) 00485 { 00486 tree_expression *expr = cmd.switch_value (); 00487 00488 if (expr) 00489 expr->accept (*this); 00490 00491 tree_switch_case_list *list = cmd.case_list (); 00492 00493 if (list) 00494 list->accept (*this); 00495 } 00496 00497 void 00498 tree_checker::visit_try_catch_command (tree_try_catch_command& cmd) 00499 { 00500 tree_statement_list *try_code = cmd.body (); 00501 00502 if (try_code) 00503 try_code->accept (*this); 00504 00505 tree_statement_list *catch_code = cmd.cleanup (); 00506 00507 if (catch_code) 00508 catch_code->accept (*this); 00509 } 00510 00511 void 00512 tree_checker::visit_unwind_protect_command 00513 (tree_unwind_protect_command& cmd) 00514 { 00515 tree_statement_list *unwind_protect_code = cmd.body (); 00516 00517 if (unwind_protect_code) 00518 unwind_protect_code->accept (*this); 00519 00520 tree_statement_list *cleanup_code = cmd.cleanup (); 00521 00522 if (cleanup_code) 00523 cleanup_code->accept (*this); 00524 } 00525 00526 void 00527 tree_checker::visit_while_command (tree_while_command& cmd) 00528 { 00529 tree_expression *expr = cmd.condition (); 00530 00531 if (expr) 00532 expr->accept (*this); 00533 00534 tree_statement_list *list = cmd.body (); 00535 00536 if (list) 00537 list->accept (*this); 00538 } 00539 00540 void 00541 tree_checker::visit_do_until_command (tree_do_until_command& cmd) 00542 { 00543 tree_statement_list *list = cmd.body (); 00544 00545 if (list) 00546 list->accept (*this); 00547 00548 tree_expression *expr = cmd.condition (); 00549 00550 if (expr) 00551 expr->accept (*this); 00552 } 00553 00554 void 00555 tree_checker::gripe (const std::string& msg, int line) 00556 { 00557 if (curr_fcn_file_name.empty ()) 00558 error ("%s", msg.c_str ()); 00559 else 00560 error ("%s: %d: %s", curr_fcn_file_name.c_str (), line, msg.c_str ()); 00561 }