1 //////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (C) 2017-2021 The Octave Project Developers 4 // 5 // See the file COPYRIGHT.md in the top-level directory of this 6 // distribution or <https://octave.org/copyright/>. 7 // 8 // This file is part of Octave. 9 // 10 // Octave is free software: you can redistribute it and/or modify it 11 // under the terms of the GNU General Public License as published by 12 // the Free Software Foundation, either version 3 of the License, or 13 // (at your option) any later version. 14 // 15 // Octave is distributed in the hope that it will be useful, but 16 // WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 // GNU General Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with Octave; see the file COPYING. If not, see 22 // <https://www.gnu.org/licenses/>. 23 // 24 //////////////////////////////////////////////////////////////////////// 25 26 #if defined (HAVE_CONFIG_H) 27 # include "config.h" 28 #endif 29 30 #include "pt-all.h" 31 32 namespace octave 33 { visit_anon_fcn_handle(tree_anon_fcn_handle &)34 void tree_walker::visit_anon_fcn_handle (tree_anon_fcn_handle&) 35 { 36 // FIXME? 37 } 38 visit_argument_list(tree_argument_list & lst)39 void tree_walker::visit_argument_list (tree_argument_list& lst) 40 { 41 auto p = lst.begin (); 42 43 while (p != lst.end ()) 44 { 45 tree_expression *elt = *p++; 46 47 if (elt) 48 elt->accept (*this); 49 } 50 } 51 visit_binary_expression(tree_binary_expression & expr)52 void tree_walker::visit_binary_expression (tree_binary_expression& expr) 53 { 54 tree_expression *op1 = expr.lhs (); 55 56 if (op1) 57 op1->accept (*this); 58 59 tree_expression *op2 = expr.rhs (); 60 61 if (op2) 62 op2->accept (*this); 63 } 64 visit_boolean_expression(tree_boolean_expression & expr)65 void tree_walker::visit_boolean_expression (tree_boolean_expression& expr) 66 { 67 visit_binary_expression (expr); 68 } 69 visit_compound_binary_expression(tree_compound_binary_expression & expr)70 void tree_walker::visit_compound_binary_expression (tree_compound_binary_expression& expr) 71 { 72 visit_binary_expression (expr); 73 } 74 visit_break_command(tree_break_command &)75 void tree_walker::visit_break_command (tree_break_command&) 76 { 77 // Nothing to do. 78 } 79 visit_colon_expression(tree_colon_expression & expr)80 void tree_walker::visit_colon_expression (tree_colon_expression& expr) 81 { 82 tree_expression *op1 = expr.base (); 83 84 if (op1) 85 op1->accept (*this); 86 87 tree_expression *op3 = expr.increment (); 88 89 if (op3) 90 op3->accept (*this); 91 92 tree_expression *op2 = expr.limit (); 93 94 if (op2) 95 op2->accept (*this); 96 } 97 visit_continue_command(tree_continue_command &)98 void tree_walker::visit_continue_command (tree_continue_command&) 99 { 100 // Nothing to do. 101 } 102 visit_decl_command(tree_decl_command & cmd)103 void tree_walker::visit_decl_command (tree_decl_command& cmd) 104 { 105 tree_decl_init_list *init_list = cmd.initializer_list (); 106 107 if (init_list) 108 init_list->accept (*this); 109 } 110 visit_decl_elt(tree_decl_elt & cmd)111 void tree_walker::visit_decl_elt (tree_decl_elt& cmd) 112 { 113 tree_identifier *id = cmd.ident (); 114 115 if (id) 116 id->accept (*this); 117 118 tree_expression *expr = cmd.expression (); 119 120 if (expr) 121 expr->accept (*this); 122 } 123 visit_decl_init_list(tree_decl_init_list & lst)124 void tree_walker::visit_decl_init_list (tree_decl_init_list& lst) 125 { 126 // FIXME: tree_decl_elt is not derived from tree, so should it 127 // really have an accept method? 128 129 for (tree_decl_elt *elt : lst) 130 { 131 if (elt) 132 elt->accept (*this); 133 } 134 } 135 visit_simple_for_command(tree_simple_for_command & cmd)136 void tree_walker::visit_simple_for_command (tree_simple_for_command& cmd) 137 { 138 tree_expression *lhs = cmd.left_hand_side (); 139 140 if (lhs) 141 lhs->accept (*this); 142 143 tree_expression *expr = cmd.control_expr (); 144 145 if (expr) 146 expr->accept (*this); 147 148 tree_expression *maxproc = cmd.maxproc_expr (); 149 150 if (maxproc) 151 maxproc->accept (*this); 152 153 tree_statement_list *list = cmd.body (); 154 155 if (list) 156 list->accept (*this); 157 } 158 visit_complex_for_command(tree_complex_for_command & cmd)159 void tree_walker::visit_complex_for_command (tree_complex_for_command& cmd) 160 { 161 tree_argument_list *lhs = cmd.left_hand_side (); 162 163 if (lhs) 164 lhs->accept (*this); 165 166 tree_expression *expr = cmd.control_expr (); 167 168 if (expr) 169 expr->accept (*this); 170 171 tree_statement_list *list = cmd.body (); 172 173 if (list) 174 list->accept (*this); 175 } 176 visit_octave_user_script(octave_user_script & fcn)177 void tree_walker::visit_octave_user_script (octave_user_script& fcn) 178 { 179 tree_statement_list *cmd_list = fcn.body (); 180 181 if (cmd_list) 182 cmd_list->accept (*this); 183 } 184 visit_octave_user_function(octave_user_function & fcn)185 void tree_walker::visit_octave_user_function (octave_user_function& fcn) 186 { 187 tree_statement_list *cmd_list = fcn.body (); 188 189 if (cmd_list) 190 cmd_list->accept (*this); 191 } 192 visit_function_def(tree_function_def & fdef)193 void tree_walker::visit_function_def (tree_function_def& fdef) 194 { 195 octave_value fcn = fdef.function (); 196 197 octave_function *f = fcn.function_value (); 198 199 if (f) 200 f->accept (*this); 201 } 202 visit_identifier(tree_identifier &)203 void tree_walker::visit_identifier (tree_identifier&) 204 { 205 // Nothing to do. 206 } 207 visit_if_clause(tree_if_clause & cmd)208 void tree_walker::visit_if_clause (tree_if_clause& cmd) 209 { 210 tree_expression *expr = cmd.condition (); 211 212 if (expr) 213 expr->accept (*this); 214 215 tree_statement_list *list = cmd.commands (); 216 217 if (list) 218 list->accept (*this); 219 } 220 visit_if_command(tree_if_command & cmd)221 void tree_walker::visit_if_command (tree_if_command& cmd) 222 { 223 tree_if_command_list *list = cmd.cmd_list (); 224 225 if (list) 226 list->accept (*this); 227 } 228 visit_if_command_list(tree_if_command_list & lst)229 void tree_walker::visit_if_command_list (tree_if_command_list& lst) 230 { 231 auto p = lst.begin (); 232 233 while (p != lst.end ()) 234 { 235 tree_if_clause *elt = *p++; 236 237 if (elt) 238 elt->accept (*this); 239 } 240 } 241 visit_switch_case(tree_switch_case & cs)242 void tree_walker::visit_switch_case (tree_switch_case& cs) 243 { 244 tree_expression *label = cs.case_label (); 245 246 if (label) 247 label->accept (*this); 248 249 tree_statement_list *list = cs.commands (); 250 251 if (list) 252 list->accept (*this); 253 } 254 visit_switch_case_list(tree_switch_case_list & lst)255 void tree_walker::visit_switch_case_list (tree_switch_case_list& lst) 256 { 257 auto p = lst.begin (); 258 259 while (p != lst.end ()) 260 { 261 tree_switch_case *elt = *p++; 262 263 if (elt) 264 elt->accept (*this); 265 } 266 } 267 visit_switch_command(tree_switch_command & cmd)268 void tree_walker::visit_switch_command (tree_switch_command& cmd) 269 { 270 tree_expression *expr = cmd.switch_value (); 271 272 if (expr) 273 expr->accept (*this); 274 275 tree_switch_case_list *list = cmd.case_list (); 276 277 if (list) 278 list->accept (*this); 279 } 280 visit_index_expression(tree_index_expression & expr)281 void tree_walker::visit_index_expression (tree_index_expression& expr) 282 { 283 tree_expression *e = expr.expression (); 284 285 if (e) 286 e->accept (*this); 287 288 std::list<tree_argument_list *> arg_lists = expr.arg_lists (); 289 std::list<string_vector> arg_names = expr.arg_names (); 290 std::list<tree_expression *> dyn_fields = expr.dyn_fields (); 291 292 auto p_arg_lists = arg_lists.begin (); 293 auto p_arg_names = arg_names.begin (); 294 auto p_dyn_fields = dyn_fields.begin (); 295 296 std::string type_tags = expr.type_tags (); 297 int n = type_tags.length (); 298 299 for (int i = 0; i < n; i++) 300 { 301 switch (type_tags[i]) 302 { 303 case '(': 304 case '{': 305 { 306 tree_argument_list *l = *p_arg_lists; 307 if (l) 308 l->accept (*this); 309 } 310 break; 311 312 case '.': 313 { 314 std::string fn = (*p_arg_names)(0); 315 if (fn.empty ()) 316 { 317 tree_expression *df = *p_dyn_fields; 318 if (df) 319 df->accept (*this); 320 } 321 } 322 break; 323 324 default: 325 panic_impossible (); 326 } 327 328 p_arg_lists++; 329 p_arg_names++; 330 p_dyn_fields++; 331 } 332 } 333 visit_matrix(tree_matrix & lst)334 void tree_walker::visit_matrix (tree_matrix& lst) 335 { 336 auto p = lst.begin (); 337 338 while (p != lst.end ()) 339 { 340 tree_argument_list *elt = *p++; 341 342 if (elt) 343 elt->accept (*this); 344 } 345 } 346 visit_cell(tree_cell & lst)347 void tree_walker::visit_cell (tree_cell& lst) 348 { 349 auto p = lst.begin (); 350 351 while (p != lst.end ()) 352 { 353 tree_argument_list *elt = *p++; 354 355 if (elt) 356 elt->accept (*this); 357 } 358 } 359 visit_multi_assignment(tree_multi_assignment & expr)360 void tree_walker::visit_multi_assignment (tree_multi_assignment& expr) 361 { 362 tree_argument_list *lhs = expr.left_hand_side (); 363 364 if (lhs) 365 lhs->accept (*this); 366 367 tree_expression *rhs = expr.right_hand_side (); 368 369 if (rhs) 370 rhs->accept (*this); 371 } 372 visit_no_op_command(tree_no_op_command &)373 void tree_walker::visit_no_op_command (tree_no_op_command&) 374 { 375 // Nothing to do. 376 } 377 visit_constant(tree_constant &)378 void tree_walker::visit_constant (tree_constant&) 379 { 380 // Nothing to do. 381 } 382 visit_fcn_handle(tree_fcn_handle &)383 void tree_walker::visit_fcn_handle (tree_fcn_handle&) 384 { 385 // Nothing to do. 386 } 387 visit_parameter_list(tree_parameter_list & lst)388 void tree_walker::visit_parameter_list (tree_parameter_list& lst) 389 { 390 auto p = lst.begin (); 391 392 while (p != lst.end ()) 393 { 394 tree_decl_elt *elt = *p++; 395 396 if (elt) 397 elt->accept (*this); 398 } 399 } 400 visit_postfix_expression(tree_postfix_expression & expr)401 void tree_walker::visit_postfix_expression (tree_postfix_expression& expr) 402 { 403 tree_expression *e = expr.operand (); 404 405 if (e) 406 e->accept (*this); 407 } 408 visit_prefix_expression(tree_prefix_expression & expr)409 void tree_walker::visit_prefix_expression (tree_prefix_expression& expr) 410 { 411 tree_expression *e = expr.operand (); 412 413 if (e) 414 e->accept (*this); 415 } 416 visit_return_command(tree_return_command &)417 void tree_walker::visit_return_command (tree_return_command&) 418 { 419 // Nothing to do. 420 } 421 visit_simple_assignment(tree_simple_assignment & expr)422 void tree_walker::visit_simple_assignment (tree_simple_assignment& expr) 423 { 424 tree_expression *lhs = expr.left_hand_side (); 425 426 if (lhs) 427 lhs->accept (*this); 428 429 tree_expression *rhs = expr.right_hand_side (); 430 431 if (rhs) 432 rhs->accept (*this); 433 } 434 visit_statement(tree_statement & stmt)435 void tree_walker::visit_statement (tree_statement& stmt) 436 { 437 tree_command *cmd = stmt.command (); 438 439 if (cmd) 440 cmd->accept (*this); 441 else 442 { 443 tree_expression *expr = stmt.expression (); 444 445 if (expr) 446 expr->accept (*this); 447 } 448 } 449 visit_statement_list(tree_statement_list & lst)450 void tree_walker::visit_statement_list (tree_statement_list& lst) 451 { 452 for (tree_statement *elt : lst) 453 { 454 if (elt) 455 elt->accept (*this); 456 } 457 } 458 visit_try_catch_command(tree_try_catch_command & cmd)459 void tree_walker::visit_try_catch_command (tree_try_catch_command& cmd) 460 { 461 tree_statement_list *try_code = cmd.body (); 462 463 if (try_code) 464 try_code->accept (*this); 465 466 tree_identifier *expr_id = cmd.identifier (); 467 468 if (expr_id) 469 expr_id->accept (*this); 470 471 tree_statement_list *catch_code = cmd.cleanup (); 472 473 if (catch_code) 474 catch_code->accept (*this); 475 } 476 visit_unwind_protect_command(tree_unwind_protect_command & cmd)477 void tree_walker::visit_unwind_protect_command (tree_unwind_protect_command& cmd) 478 { 479 tree_statement_list *unwind_protect_code = cmd.body (); 480 481 if (unwind_protect_code) 482 unwind_protect_code->accept (*this); 483 484 tree_statement_list *cleanup_code = cmd.cleanup (); 485 486 if (cleanup_code) 487 cleanup_code->accept (*this); 488 } 489 visit_while_command(tree_while_command & cmd)490 void tree_walker::visit_while_command (tree_while_command& cmd) 491 { 492 tree_expression *expr = cmd.condition (); 493 494 if (expr) 495 expr->accept (*this); 496 497 tree_statement_list *list = cmd.body (); 498 499 if (list) 500 list->accept (*this); 501 } 502 visit_do_until_command(tree_do_until_command & cmd)503 void tree_walker::visit_do_until_command (tree_do_until_command& cmd) 504 { 505 tree_statement_list *list = cmd.body (); 506 507 if (list) 508 list->accept (*this); 509 510 tree_expression *expr = cmd.condition (); 511 512 if (expr) 513 expr->accept (*this); 514 } 515 visit_superclass_ref(tree_superclass_ref &)516 void tree_walker::visit_superclass_ref (tree_superclass_ref&) 517 { 518 // FIXME? 519 } 520 visit_metaclass_query(tree_metaclass_query &)521 void tree_walker::visit_metaclass_query (tree_metaclass_query&) 522 { 523 // FIXME? 524 } 525 visit_classdef_attribute(tree_classdef_attribute &)526 void tree_walker::visit_classdef_attribute (tree_classdef_attribute&) 527 { 528 // FIXME? 529 } 530 visit_classdef_attribute_list(tree_classdef_attribute_list &)531 void tree_walker::visit_classdef_attribute_list (tree_classdef_attribute_list&) 532 { 533 // FIXME? 534 } 535 visit_classdef_superclass(tree_classdef_superclass &)536 void tree_walker::visit_classdef_superclass (tree_classdef_superclass&) 537 { 538 // FIXME? 539 } 540 visit_classdef_superclass_list(tree_classdef_superclass_list &)541 void tree_walker::visit_classdef_superclass_list (tree_classdef_superclass_list&) 542 { 543 // FIXME? 544 } 545 visit_classdef_property(tree_classdef_property &)546 void tree_walker::visit_classdef_property (tree_classdef_property&) 547 { 548 // FIXME? 549 } 550 visit_classdef_property_list(tree_classdef_property_list &)551 void tree_walker::visit_classdef_property_list (tree_classdef_property_list&) 552 { 553 // FIXME? 554 } 555 visit_classdef_properties_block(tree_classdef_properties_block &)556 void tree_walker::visit_classdef_properties_block (tree_classdef_properties_block&) 557 { 558 // FIXME? 559 } 560 visit_classdef_methods_list(tree_classdef_methods_list &)561 void tree_walker::visit_classdef_methods_list (tree_classdef_methods_list&) 562 { 563 // FIXME? 564 } 565 visit_classdef_methods_block(tree_classdef_methods_block &)566 void tree_walker::visit_classdef_methods_block (tree_classdef_methods_block&) 567 { 568 // FIXME? 569 } 570 visit_classdef_event(tree_classdef_event &)571 void tree_walker::visit_classdef_event (tree_classdef_event&) 572 { 573 // FIXME? 574 } 575 visit_classdef_events_list(tree_classdef_events_list &)576 void tree_walker::visit_classdef_events_list (tree_classdef_events_list&) 577 { 578 // FIXME? 579 } 580 visit_classdef_events_block(tree_classdef_events_block &)581 void tree_walker::visit_classdef_events_block (tree_classdef_events_block&) 582 { 583 // FIXME? 584 } 585 visit_classdef_enum(tree_classdef_enum &)586 void tree_walker::visit_classdef_enum (tree_classdef_enum&) 587 { 588 // FIXME? 589 } 590 visit_classdef_enum_list(tree_classdef_enum_list &)591 void tree_walker::visit_classdef_enum_list (tree_classdef_enum_list&) 592 { 593 // FIXME? 594 } 595 visit_classdef_enum_block(tree_classdef_enum_block &)596 void tree_walker::visit_classdef_enum_block (tree_classdef_enum_block&) 597 { 598 // FIXME? 599 } 600 visit_classdef_body(tree_classdef_body &)601 void tree_walker::visit_classdef_body (tree_classdef_body&) 602 { 603 // FIXME? 604 } 605 visit_classdef(tree_classdef &)606 void tree_walker::visit_classdef (tree_classdef&) 607 { 608 // FIXME? 609 } 610 } 611