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