User Guide
symbol.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2023 Blue Brain Project, EPFL.
3  * See the top-level LICENSE file for details.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #pragma once
9 
10 /**
11  * \file
12  * \brief Implement class to represent a symbol in Symbol Table
13  */
14 
15 #include <map>
16 #include <memory>
17 
18 #include "ast/ast_decl.hpp"
19 #include "lexer/modtoken.hpp"
21 
22 
23 namespace nmodl {
24 
25 namespace ast {
26 struct Ast;
27 }
28 
29 /// %Symbol table related implementations
30 namespace symtab {
31 
32 /**
33  * @ingroup sym_tab
34  * @{
35  */
36 
37 /**
38  * \class Symbol
39  * \brief Represent symbol in symbol table
40  *
41  * Symbol table generator pass visit the AST and insert symbol for
42  * each node into symtab::SymbolTable. Symbol could appear multiple
43  * times in a block or different global blocks. NmodlType object has all
44  * nmodl properties information.
45  *
46  * \todo
47  * - Multiple tokens (i.e. location information) for symbol should
48  * be tracked
49  * - Scope information should be more than just string
50  * - Perf block should track information about all usage of the symbol
51  * (would be helpful for perf modeling)
52  * - Need to keep track of all renaming information, currently only we
53  * keep last state
54  */
55 class Symbol {
56  /// name of the symbol
57  std::string name;
58 
59  /// original name of the symbol if renamed
60  std::string renamed_from;
61 
62  /// unique id or index position when symbol is inserted into specific table
63  int id = 0;
64 
65  /// All given AST nodes for this symbol.
66  /// Variable can appear multiple times in the mod file.
67  std::vector<ast::Ast*> nodes{};
68 
69  /// token associated with symbol (from node)
71 
72  /// properties of symbol as a result of usage across whole mod file
74 
75  /// status of symbol after processing through various passes
77 
78  /// scope of the symbol (nmodl block name where it appears)
79  std::string scope;
80 
81  /// order in case of state / prime variable
82  int order = 0;
83 
84  /// order in which symbol appears in the mod file
85  /// Different variables appear in different blocks (NEURON, PARAMETER, STATE)
86  /// and accordingly they appear in the data array (in NEURON). This order is
87  /// based on appearance in the mod file.
88  int definition_order = -1;
89 
90  /// associated value in case of parameters, constant variable
91  std::shared_ptr<double> value;
92 
93  /// true if symbol represent array variable
94  bool array = false;
95 
96  /// dimension/length in case of array variable
97  int length = 1;
98 
99  /// number of values that variable can take in case of table variable
100  int num_values = 0;
101 
102  /// number of times symbol is read
103  int read_count = 0;
104 
105  /// number of times symbol is written
106  int write_count = 0;
107 
108  public:
109  /// \name Ctor & dtor
110  /// \{
111 
112  Symbol() = delete;
113 
114  explicit Symbol(std::string name)
115  : name(std::move(name)) {}
116 
117  Symbol(std::string name, ast::Ast* node)
118  : name(std::move(name)) {
119  nodes.push_back(node);
120  }
121 
122  Symbol(std::string name, ModToken token)
123  : name(std::move(name))
124  , token(std::move(token)) {}
125 
126  Symbol(std::string name, ast::Ast* node, ModToken token)
127  : name(std::move(name))
128  , token(std::move(token)) {
129  nodes.push_back(node);
130  }
131 
132  /// \}
133 
134  /// increment read count
135  void read() noexcept {
136  read_count++;
137  }
138 
139  /// increment write count
140  void write() noexcept {
141  write_count++;
142  }
143 
144  /// \name Setter
145  /// \{
146 
147  void set_scope(const std::string& s) {
148  scope = s;
149  }
150 
151  void set_id(int i) noexcept {
152  id = i;
153  }
154 
155  /**
156  * Set new name for the symbol
157  *
158  * If symbol is already renamed, do not rename it again
159  * as we want to keep track of original name and not intermediate
160  * renames
161  */
162  void set_name(const std::string& new_name) {
163  if (renamed_from.empty()) {
164  renamed_from = name;
165  }
166  name = new_name;
167  }
168 
169  /**
170  * Set order in case of prime/state variable
171  *
172  * Prime variable will appear in different block and could have
173  * multiple derivative orders. We have to store highest order.
174  */
175  void set_order(int new_order) noexcept {
176  if (new_order > order) {
177  order = new_order;
178  }
179  }
180 
181  void set_definition_order(int order) noexcept {
183  }
184 
185  void set_value(double val) {
186  value = std::make_shared<double>(val);
187  }
188 
189  void set_as_array(int len) noexcept {
190  array = true;
191  length = len;
192  }
193 
194  void set_num_values(int n) noexcept {
195  num_values = n;
196  }
197 
198  void set_original_name(const std::string& new_name) {
199  renamed_from = new_name;
200  }
201 
202  /// \}
203 
204  /// \name Getter
205  /// \{
206 
207  int get_length() const noexcept {
208  return length;
209  }
210 
211  int get_num_values() const noexcept {
212  return num_values;
213  }
214 
215  const std::string& get_original_name() const noexcept {
216  return renamed_from;
217  }
218 
219  const std::shared_ptr<double>& get_value() const noexcept {
220  return value;
221  }
222 
223  const std::string& get_name() const noexcept {
224  return name;
225  }
226 
227  int get_id() const noexcept {
228  return id;
229  }
230 
231  const std::string& get_scope() const noexcept {
232  return scope;
233  }
234 
235  const syminfo::NmodlType& get_properties() const noexcept {
236  return properties;
237  }
238 
239  const syminfo::Status& get_status() const noexcept {
240  return status;
241  }
242 
243  void add_node(ast::Ast* node) noexcept {
244  nodes.push_back(node);
245  }
246 
247  const std::vector<ast::Ast*>& get_nodes() const noexcept {
248  return nodes;
249  }
250 
251  std::vector<ast::Ast*> get_nodes_by_type(
252  std::initializer_list<ast::AstNodeType> l) const noexcept;
253 
254  const ModToken& get_token() const noexcept {
255  return token;
256  }
257 
258  int get_read_count() const noexcept {
259  return read_count;
260  }
261 
262  int get_write_count() const noexcept {
263  return write_count;
264  }
265 
266  int get_definition_order() const noexcept {
267  return definition_order;
268  }
269 
270  /// \}
271 
272  /**
273  * Check if symbol represent an external variable
274  *
275  * External variables are the variables that are defined in NEURON
276  * and available in mod file.
277  *
278  * \todo Need to check if we should check two properties using
279  * has_any_property instead of exact comparison
280  *
281  * \sa nmodl::details::NEURON_VARIABLES
282  */
283  bool is_external_variable() const noexcept {
286  }
287 
288  /// check if symbol has any of the given property
289  bool has_any_property(syminfo::NmodlType new_properties) const noexcept {
290  return static_cast<bool>(properties & new_properties);
291  }
292 
293  /// check if symbol has all of the given properties
294  bool has_all_properties(syminfo::NmodlType new_properties) const noexcept {
295  return ((properties & new_properties) == new_properties);
296  }
297 
298  /// check if symbol has any of the status
299  bool has_any_status(syminfo::Status new_status) const noexcept {
300  return static_cast<bool>(status & new_status);
301  }
302 
303  /// check if symbol has all of the status
304  bool has_all_status(syminfo::Status new_status) const noexcept {
305  return ((status & new_status) == new_status);
306  }
307 
308  /// add new properties to symbol
309  void add_properties(syminfo::NmodlType new_properties) noexcept {
310  properties |= new_properties;
311  }
312 
313  /// add new property to symbol
314  void add_property(syminfo::NmodlType property) noexcept {
315  properties |= property;
316  }
317 
318  /// remove property from symbol
320  properties &= ~property;
321  }
322 
323  /// mark symbol as inlined (in case of procedure/function)
324  void mark_inlined() noexcept {
326  }
327 
328  /// mark symbol as newly created (in case of new variable)
329  void mark_created() noexcept {
331  }
332 
333  void mark_renamed() noexcept {
335  }
336 
337  /// mark symbol as localized (e.g. from RANGE to LOCAL conversion)
338  void mark_localized() noexcept {
340  }
341 
342  void mark_thread_safe() noexcept {
344  }
345 
346  /// mark symbol as newly created variable for the STATE variable
347  /// this is used with legacy euler/derivimplicit solver where DState
348  /// variables are created
349  void created_from_state() noexcept {
350  mark_created();
352  }
353 
354  bool is_array() const noexcept {
355  return array;
356  }
357 
358  /// check if symbol is a variable in nmodl
359  bool is_variable() const noexcept;
360 
361  std::string to_string() const;
362 
363  bool is_writable() const noexcept {
369  }
370 };
371 
372 /** @} */ // end of sym_tab
373 
374 } // namespace symtab
375 } // namespace nmodl
nmodl::symtab::Symbol::definition_order
int definition_order
order in which symbol appears in the mod file Different variables appear in different blocks (NEURON,...
Definition: symbol.hpp:88
nmodl::symtab::Symbol::set_as_array
void set_as_array(int len) noexcept
Definition: symbol.hpp:189
nmodl::symtab::syminfo::Status::from_state
@ from_state
derived from state
nmodl::symtab::syminfo::NmodlType::write_ion_var
@ write_ion_var
Write Ion.
nmodl::symtab::Symbol::value
std::shared_ptr< double > value
associated value in case of parameters, constant variable
Definition: symbol.hpp:91
nmodl::symtab::Symbol::set_id
void set_id(int i) noexcept
Definition: symbol.hpp:151
nmodl::symtab::Symbol::get_nodes
const std::vector< ast::Ast * > & get_nodes() const noexcept
Definition: symbol.hpp:247
nmodl::symtab::syminfo::NmodlType::extern_method
@ extern_method
neuron solver methods and math functions
nmodl::symtab::Symbol::renamed_from
std::string renamed_from
original name of the symbol if renamed
Definition: symbol.hpp:60
nmodl::symtab::syminfo::Status::thread_safe
@ thread_safe
variable marked as thread safe
nmodl::ast::Ast
Base class for all Abstract Syntax Tree node types.
Definition: ast.hpp:69
nmodl::symtab::Symbol::has_all_status
bool has_all_status(syminfo::Status new_status) const noexcept
check if symbol has all of the status
Definition: symbol.hpp:304
nmodl::symtab::Symbol::Symbol
Symbol(std::string name, ModToken token)
Definition: symbol.hpp:122
nmodl::symtab::Symbol
Represent symbol in symbol table.
Definition: symbol.hpp:55
nmodl::symtab::Symbol::set_value
void set_value(double val)
Definition: symbol.hpp:185
ast_decl.hpp
THIS FILE IS GENERATED AT BUILD TIME AND SHALL NOT BE EDITED.
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
nmodl::symtab::Symbol::get_num_values
int get_num_values() const noexcept
Definition: symbol.hpp:211
nmodl::symtab::Symbol::num_values
int num_values
number of values that variable can take in case of table variable
Definition: symbol.hpp:100
nmodl::symtab::Symbol::is_writable
bool is_writable() const noexcept
Definition: symbol.hpp:363
nmodl::symtab::Symbol::array
bool array
true if symbol represent array variable
Definition: symbol.hpp:94
nmodl::symtab::Symbol::Symbol
Symbol()=delete
symbol_properties.hpp
Implement various classes to represent various Symbol properties.
nmodl::symtab::syminfo::Status
Status
state during various compiler passes
Definition: symbol_properties.hpp:54
nmodl::symtab::Symbol::add_node
void add_node(ast::Ast *node) noexcept
Definition: symbol.hpp:243
nmodl::symtab::Symbol::get_length
int get_length() const noexcept
Definition: symbol.hpp:207
nmodl::symtab::syminfo::NmodlType::range_var
@ range_var
Range Variable.
nmodl::symtab::syminfo::Status::created
@ created
created
nmodl::symtab::Symbol::get_read_count
int get_read_count() const noexcept
Definition: symbol.hpp:258
nmodl::symtab::Symbol::mark_created
void mark_created() noexcept
mark symbol as newly created (in case of new variable)
Definition: symbol.hpp:329
nmodl::symtab::syminfo::Status::inlined
@ inlined
inlined
nmodl::symtab::Symbol::token
ModToken token
token associated with symbol (from node)
Definition: symbol.hpp:70
nmodl::symtab::Symbol::Symbol
Symbol(std::string name, ast::Ast *node)
Definition: symbol.hpp:117
nmodl::symtab::Symbol::get_status
const syminfo::Status & get_status() const noexcept
Definition: symbol.hpp:239
nmodl::symtab::Symbol::scope
std::string scope
scope of the symbol (nmodl block name where it appears)
Definition: symbol.hpp:79
nmodl::symtab::Symbol::get_properties
const syminfo::NmodlType & get_properties() const noexcept
Definition: symbol.hpp:235
nmodl::symtab::Symbol::id
int id
unique id or index position when symbol is inserted into specific table
Definition: symbol.hpp:63
nmodl::symtab::Symbol::is_array
bool is_array() const noexcept
Definition: symbol.hpp:354
nmodl::symtab::Symbol::nodes
std::vector< ast::Ast * > nodes
All given AST nodes for this symbol.
Definition: symbol.hpp:67
nmodl::symtab::Symbol::read_count
int read_count
number of times symbol is read
Definition: symbol.hpp:103
nmodl::symtab::Symbol::mark_renamed
void mark_renamed() noexcept
Definition: symbol.hpp:333
nmodl::symtab::Symbol::has_any_property
bool has_any_property(syminfo::NmodlType new_properties) const noexcept
check if symbol has any of the given property
Definition: symbol.hpp:289
nmodl::symtab::Symbol::get_id
int get_id() const noexcept
Definition: symbol.hpp:227
nmodl::symtab::Symbol::set_num_values
void set_num_values(int n) noexcept
Definition: symbol.hpp:194
nmodl::symtab::Symbol::set_scope
void set_scope(const std::string &s)
Definition: symbol.hpp:147
nmodl::symtab::Symbol::get_name
const std::string & get_name() const noexcept
Definition: symbol.hpp:223
nmodl::symtab::Symbol::set_definition_order
void set_definition_order(int order) noexcept
Definition: symbol.hpp:181
nmodl::symtab::Symbol::get_token
const ModToken & get_token() const noexcept
Definition: symbol.hpp:254
nmodl::symtab::Symbol::add_property
void add_property(syminfo::NmodlType property) noexcept
add new property to symbol
Definition: symbol.hpp:314
nmodl::symtab::syminfo::NmodlType::empty
@ empty
nmodl::symtab::Symbol::get_scope
const std::string & get_scope() const noexcept
Definition: symbol.hpp:231
nmodl::symtab::Symbol::is_external_variable
bool is_external_variable() const noexcept
Check if symbol represent an external variable.
Definition: symbol.hpp:283
nmodl::symtab::Symbol::status
syminfo::Status status
status of symbol after processing through various passes
Definition: symbol.hpp:76
nmodl::symtab::Symbol::mark_inlined
void mark_inlined() noexcept
mark symbol as inlined (in case of procedure/function)
Definition: symbol.hpp:324
nmodl::symtab::syminfo::NmodlType::assigned_definition
@ assigned_definition
Assigned Definition.
nmodl::symtab::Symbol::name
std::string name
name of the symbol
Definition: symbol.hpp:57
nmodl::symtab::Symbol::read
void read() noexcept
increment read count
Definition: symbol.hpp:135
nmodl::symtab::syminfo::NmodlType
NmodlType
NMODL variable properties.
Definition: symbol_properties.hpp:116
nmodl::symtab::Symbol::length
int length
dimension/length in case of array variable
Definition: symbol.hpp:97
nmodl::symtab::Symbol::add_properties
void add_properties(syminfo::NmodlType new_properties) noexcept
add new properties to symbol
Definition: symbol.hpp:309
nmodl::symtab::Symbol::get_write_count
int get_write_count() const noexcept
Definition: symbol.hpp:262
nmodl::symtab::Symbol::remove_property
void remove_property(syminfo::NmodlType property)
remove property from symbol
Definition: symbol.hpp:319
nmodl::symtab::Symbol::get_definition_order
int get_definition_order() const noexcept
Definition: symbol.hpp:266
nmodl::symtab::Symbol::has_any_status
bool has_any_status(syminfo::Status new_status) const noexcept
check if symbol has any of the status
Definition: symbol.hpp:299
nmodl::symtab::syminfo::NmodlType::read_ion_var
@ read_ion_var
Read Ion.
nmodl::symtab::syminfo::NmodlType::state_var
@ state_var
state variable
nmodl::symtab::Symbol::get_nodes_by_type
std::vector< ast::Ast * > get_nodes_by_type(std::initializer_list< ast::AstNodeType > l) const noexcept
Definition: symbol.cpp:52
nmodl::symtab::Symbol::Symbol
Symbol(std::string name)
Definition: symbol.hpp:114
nmodl::symtab::syminfo::Status::empty
@ empty
nmodl::symtab::Symbol::get_value
const std::shared_ptr< double > & get_value() const noexcept
Definition: symbol.hpp:219
modtoken.hpp
nmodl::symtab::Symbol::Symbol
Symbol(std::string name, ast::Ast *node, ModToken token)
Definition: symbol.hpp:126
nmodl::symtab::Symbol::created_from_state
void created_from_state() noexcept
mark symbol as newly created variable for the STATE variable this is used with legacy euler/derivimpl...
Definition: symbol.hpp:349
nmodl::symtab::Symbol::write
void write() noexcept
increment write count
Definition: symbol.hpp:140
nmodl::symtab::Symbol::set_original_name
void set_original_name(const std::string &new_name)
Definition: symbol.hpp:198
nmodl::symtab::Symbol::mark_thread_safe
void mark_thread_safe() noexcept
Definition: symbol.hpp:342
nmodl::symtab::Symbol::write_count
int write_count
number of times symbol is written
Definition: symbol.hpp:106
nmodl::symtab::Symbol::is_variable
bool is_variable() const noexcept
check if symbol is a variable in nmodl
Definition: symbol.cpp:19
nmodl::symtab::Symbol::get_original_name
const std::string & get_original_name() const noexcept
Definition: symbol.hpp:215
nmodl::symtab::Symbol::has_all_properties
bool has_all_properties(syminfo::NmodlType new_properties) const noexcept
check if symbol has all of the given properties
Definition: symbol.hpp:294
nmodl::symtab::syminfo::Status::renamed
@ renamed
renamed
nmodl::symtab::Symbol::order
int order
order in case of state / prime variable
Definition: symbol.hpp:82
nmodl::ModToken
Represent token returned by scanner.
Definition: modtoken.hpp:50
nmodl::symtab::syminfo::Status::localized
@ localized
converted to local
nmodl::symtab::Symbol::properties
syminfo::NmodlType properties
properties of symbol as a result of usage across whole mod file
Definition: symbol.hpp:73
nmodl::symtab::Symbol::set_name
void set_name(const std::string &new_name)
Set new name for the symbol.
Definition: symbol.hpp:162
nmodl::symtab::Symbol::mark_localized
void mark_localized() noexcept
mark symbol as localized (e.g. from RANGE to LOCAL conversion)
Definition: symbol.hpp:338
nmodl::symtab::Symbol::set_order
void set_order(int new_order) noexcept
Set order in case of prime/state variable.
Definition: symbol.hpp:175
nmodl::symtab::Symbol::to_string
std::string to_string() const
Definition: symbol.cpp:41
nmodl::symtab::syminfo::NmodlType::extern_neuron_variable
@ extern_neuron_variable
neuron variable accessible in mod file