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_decl_h) 27 #define octave_pt_decl_h 1 28 29 #include "octave-config.h" 30 31 #include <list> 32 #include <string> 33 34 #include "base-list.h" 35 #include "oct-lvalue.h" 36 #include "pt-cmd.h" 37 #include "pt-id.h" 38 #include "pt-walk.h" 39 40 namespace octave 41 { 42 class symbol_scope; 43 class tree_evaluator; 44 class tree_expression; 45 class tree_identifier; 46 47 // List of expressions that make up a declaration statement. 48 49 class tree_decl_elt 50 { 51 public: 52 53 enum decl_type 54 { 55 unknown, 56 global, 57 persistent 58 }; 59 60 tree_decl_elt (tree_identifier *i, tree_expression *e = nullptr); 61 62 // No copying! 63 64 tree_decl_elt (const tree_decl_elt&) = delete; 65 66 tree_decl_elt& operator = (const tree_decl_elt&) = delete; 67 68 ~tree_decl_elt (void); 69 mark_as_formal_parameter(void)70 void mark_as_formal_parameter (void) 71 { 72 m_id->mark_as_formal_parameter (); 73 } 74 lvalue_ok(void)75 bool lvalue_ok (void) { return m_id->lvalue_ok (); } 76 lvalue(tree_evaluator & tw)77 octave_lvalue lvalue (tree_evaluator& tw) 78 { 79 return m_id->lvalue (tw); 80 } 81 mark_global(void)82 void mark_global (void) { type = global; } is_global(void)83 bool is_global (void) const { return type == global; } 84 mark_persistent(void)85 void mark_persistent (void) { type = persistent; } is_persistent(void)86 bool is_persistent (void) const { return type == persistent; } 87 ident(void)88 tree_identifier * ident (void) { return m_id; } 89 name(void)90 std::string name (void) const { return m_id->name (); } 91 expression(void)92 tree_expression * expression (void) { return m_expr; } 93 94 tree_decl_elt * dup (symbol_scope& scope) const; 95 accept(tree_walker & tw)96 void accept (tree_walker& tw) 97 { 98 tw.visit_decl_elt (*this); 99 } 100 101 private: 102 103 decl_type type; 104 105 // An identifier to tag with the declared property. 106 tree_identifier *m_id; 107 108 // An initializer expression (may be zero); 109 tree_expression *m_expr; 110 }; 111 112 class tree_decl_init_list : public base_list<tree_decl_elt *> 113 { 114 public: 115 tree_decl_init_list(void)116 tree_decl_init_list (void) { } 117 tree_decl_init_list(tree_decl_elt * t)118 tree_decl_init_list (tree_decl_elt *t) { append (t); } 119 120 // No copying! 121 122 tree_decl_init_list (const tree_decl_init_list&) = delete; 123 124 tree_decl_init_list& operator = (const tree_decl_init_list&) = delete; 125 ~tree_decl_init_list(void)126 ~tree_decl_init_list (void) 127 { 128 while (! empty ()) 129 { 130 auto p = begin (); 131 delete *p; 132 erase (p); 133 } 134 } 135 mark_global(void)136 void mark_global (void) 137 { 138 for (tree_decl_elt *elt : *this) 139 elt->mark_global (); 140 } 141 mark_persistent(void)142 void mark_persistent (void) 143 { 144 for (tree_decl_elt *elt : *this) 145 elt->mark_persistent (); 146 } 147 variable_names(void)148 std::list<std::string> variable_names (void) const 149 { 150 std::list<std::string> retval; 151 152 for (const tree_decl_elt *elt : *this) 153 { 154 std::string nm = elt->name (); 155 156 if (! nm.empty ()) 157 retval.push_back (nm); 158 } 159 160 return retval; 161 } 162 accept(tree_walker & tw)163 void accept (tree_walker& tw) 164 { 165 tw.visit_decl_init_list (*this); 166 } 167 }; 168 169 // Base class for declaration commands -- global, static, etc. 170 171 class tree_decl_command : public tree_command 172 { 173 public: 174 175 tree_decl_command (const std::string& n, int l = -1, int c = -1) tree_command(l,c)176 : tree_command (l, c), m_cmd_name (n), m_init_list (nullptr) { } 177 178 tree_decl_command (const std::string& n, tree_decl_init_list *t, 179 int l = -1, int c = -1); 180 181 // No copying! 182 183 tree_decl_command (const tree_decl_command&) = delete; 184 185 tree_decl_command& operator = (const tree_decl_command&) = delete; 186 187 ~tree_decl_command (void); 188 mark_global(void)189 void mark_global (void) 190 { 191 if (m_init_list) 192 m_init_list->mark_global (); 193 } 194 mark_persistent(void)195 void mark_persistent (void) 196 { 197 if (m_init_list) 198 m_init_list->mark_persistent (); 199 } 200 initializer_list(void)201 tree_decl_init_list * initializer_list (void) { return m_init_list; } 202 name(void)203 std::string name (void) const { return m_cmd_name; } 204 accept(tree_walker & tw)205 void accept (tree_walker& tw) 206 { 207 tw.visit_decl_command (*this); 208 } 209 210 private: 211 212 // The name of this command -- global, static, etc. 213 std::string m_cmd_name; 214 215 // The list of variables or initializers in this declaration command. 216 tree_decl_init_list *m_init_list; 217 }; 218 } 219 220 #endif 221