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