1 //////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (C) 1996-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 (octave_pt_select_h) 27 #define octave_pt_select_h 1 28 29 #include "octave-config.h" 30 31 #include "base-list.h" 32 #include "comment-list.h" 33 #include "pt-cmd.h" 34 #include "pt-walk.h" 35 36 namespace octave 37 { 38 class tree_expression; 39 class tree_statement_list; 40 41 // If. 42 43 class tree_if_clause : public tree 44 { 45 public: 46 47 tree_if_clause (int l = -1, int c = -1) tree(l,c)48 : tree (l, c), m_expr (nullptr), m_list (nullptr), m_lead_comm (nullptr) { } 49 50 tree_if_clause (tree_statement_list *sl, comment_list *lc = nullptr, 51 int l = -1, int c = -1) tree(l,c)52 : tree (l, c), m_expr (nullptr), m_list (sl), m_lead_comm (lc) { } 53 54 tree_if_clause (tree_expression *e, tree_statement_list *sl, 55 comment_list *lc = nullptr, 56 int l = -1, int c = -1) tree(l,c)57 : tree (l, c), m_expr (e), m_list (sl), m_lead_comm (lc) { } 58 59 // No copying! 60 61 tree_if_clause (const tree_if_clause&) = delete; 62 63 tree_if_clause& operator = (const tree_if_clause&) = delete; 64 65 ~tree_if_clause (void); 66 is_else_clause(void)67 bool is_else_clause (void) { return ! m_expr; } 68 condition(void)69 tree_expression * condition (void) { return m_expr; } 70 commands(void)71 tree_statement_list * commands (void) { return m_list; } 72 leading_comment(void)73 comment_list * leading_comment (void) { return m_lead_comm; } 74 accept(tree_walker & tw)75 void accept (tree_walker& tw) 76 { 77 tw.visit_if_clause (*this); 78 } 79 80 private: 81 82 // The condition to test. 83 tree_expression *m_expr; 84 85 // The list of statements to evaluate if expr is true. 86 tree_statement_list *m_list; 87 88 // Comment preceding ELSE or ELSEIF token. 89 comment_list *m_lead_comm; 90 }; 91 92 class tree_if_command_list : public base_list<tree_if_clause *> 93 { 94 public: 95 tree_if_command_list(void)96 tree_if_command_list (void) { } 97 tree_if_command_list(tree_if_clause * t)98 tree_if_command_list (tree_if_clause *t) { append (t); } 99 100 // No copying! 101 102 tree_if_command_list (const tree_if_command_list&) = delete; 103 104 tree_if_command_list& operator = (const tree_if_command_list&) = delete; 105 ~tree_if_command_list(void)106 ~tree_if_command_list (void) 107 { 108 while (! empty ()) 109 { 110 auto p = begin (); 111 delete *p; 112 erase (p); 113 } 114 } 115 accept(tree_walker & tw)116 void accept (tree_walker& tw) 117 { 118 tw.visit_if_command_list (*this); 119 } 120 }; 121 122 class tree_if_command : public tree_command 123 { 124 public: 125 126 tree_if_command (int l = -1, int c = -1) tree_command(l,c)127 : tree_command (l, c), m_list (nullptr), 128 m_lead_comm (nullptr), m_trail_comm (nullptr) 129 { } 130 131 tree_if_command (tree_if_command_list *lst, comment_list *lc, 132 comment_list *tc, int l = -1, int c = -1) tree_command(l,c)133 : tree_command (l, c), m_list (lst), m_lead_comm (lc), m_trail_comm (tc) { } 134 135 // No copying! 136 137 tree_if_command (const tree_if_command&) = delete; 138 139 tree_if_command& operator = (const tree_if_command&) = delete; 140 141 ~tree_if_command (void); 142 cmd_list(void)143 tree_if_command_list * cmd_list (void) { return m_list; } 144 leading_comment(void)145 comment_list * leading_comment (void) { return m_lead_comm; } 146 trailing_comment(void)147 comment_list * trailing_comment (void) { return m_trail_comm; } 148 accept(tree_walker & tw)149 void accept (tree_walker& tw) 150 { 151 tw.visit_if_command (*this); 152 } 153 154 private: 155 156 // List of if commands (if, elseif, elseif, ... else, endif) 157 tree_if_command_list *m_list; 158 159 // Comment preceding IF token. 160 comment_list *m_lead_comm; 161 162 // Comment preceding ENDIF token. 163 comment_list *m_trail_comm; 164 }; 165 166 // Switch. 167 168 class tree_switch_case : public tree 169 { 170 public: 171 172 tree_switch_case (int l = -1, int c = -1) tree(l,c)173 : tree (l, c), m_label (nullptr), m_list (nullptr), m_lead_comm (nullptr) { } 174 175 tree_switch_case (tree_statement_list *sl, comment_list *lc = nullptr, 176 int l = -1, int c = -1) tree(l,c)177 : tree (l, c), m_label (nullptr), m_list (sl), m_lead_comm (lc) { } 178 179 tree_switch_case (tree_expression *e, tree_statement_list *sl, 180 comment_list *lc = nullptr, 181 int l = -1, int c = -1) tree(l,c)182 : tree (l, c), m_label (e), m_list (sl), m_lead_comm (lc) { } 183 184 // No copying! 185 186 tree_switch_case (const tree_switch_case&) = delete; 187 188 tree_switch_case& operator = (const tree_switch_case&) = delete; 189 190 ~tree_switch_case (void); 191 is_default_case(void)192 bool is_default_case (void) { return ! m_label; } 193 case_label(void)194 tree_expression * case_label (void) { return m_label; } 195 commands(void)196 tree_statement_list * commands (void) { return m_list; } 197 leading_comment(void)198 comment_list * leading_comment (void) { return m_lead_comm; } 199 accept(tree_walker & tw)200 void accept (tree_walker& tw) 201 { 202 tw.visit_switch_case (*this); 203 } 204 205 private: 206 207 // The case label. 208 tree_expression *m_label; 209 210 // The list of statements to evaluate if the label matches. 211 tree_statement_list *m_list; 212 213 // Comment preceding CASE or OTHERWISE token. 214 comment_list *m_lead_comm; 215 }; 216 217 class tree_switch_case_list : public base_list<tree_switch_case *> 218 { 219 public: 220 tree_switch_case_list(void)221 tree_switch_case_list (void) { } 222 tree_switch_case_list(tree_switch_case * t)223 tree_switch_case_list (tree_switch_case *t) { append (t); } 224 225 // No copying! 226 227 tree_switch_case_list (const tree_switch_case_list&) = delete; 228 229 tree_switch_case_list& operator = (const tree_switch_case_list&) = delete; 230 ~tree_switch_case_list(void)231 ~tree_switch_case_list (void) 232 { 233 while (! empty ()) 234 { 235 auto p = begin (); 236 delete *p; 237 erase (p); 238 } 239 } 240 accept(tree_walker & tw)241 void accept (tree_walker& tw) 242 { 243 tw.visit_switch_case_list (*this); 244 } 245 }; 246 247 class tree_switch_command : public tree_command 248 { 249 public: 250 251 tree_switch_command (int l = -1, int c = -1) tree_command(l,c)252 : tree_command (l, c), m_expr (nullptr), m_list (nullptr), 253 m_lead_comm (nullptr), m_trail_comm (nullptr) { } 254 255 tree_switch_command (tree_expression *e, tree_switch_case_list *lst, 256 comment_list *lc, comment_list *tc, 257 int l = -1, int c = -1) tree_command(l,c)258 : tree_command (l, c), m_expr (e), m_list (lst), m_lead_comm (lc), 259 m_trail_comm (tc) { } 260 261 // No copying! 262 263 tree_switch_command (const tree_switch_command&) = delete; 264 265 tree_switch_command& operator = (const tree_switch_command&) = delete; 266 267 ~tree_switch_command (void); 268 switch_value(void)269 tree_expression * switch_value (void) { return m_expr; } 270 case_list(void)271 tree_switch_case_list * case_list (void) { return m_list; } 272 leading_comment(void)273 comment_list * leading_comment (void) { return m_lead_comm; } 274 trailing_comment(void)275 comment_list * trailing_comment (void) { return m_trail_comm; } 276 accept(tree_walker & tw)277 void accept (tree_walker& tw) 278 { 279 tw.visit_switch_command (*this); 280 } 281 282 private: 283 284 // Value on which to switch. 285 tree_expression *m_expr; 286 287 // List of cases (case 1, case 2, ..., default) 288 tree_switch_case_list *m_list; 289 290 // Comment preceding SWITCH token. 291 comment_list *m_lead_comm; 292 293 // Comment preceding ENDSWITCH token. 294 comment_list *m_trail_comm; 295 }; 296 } 297 298 #endif 299