![Logo](logo.png) |
User Guide
|
Go to the documentation of this file.
31 const auto& name = symbol->get_name();
32 if (lookup(name) !=
nullptr) {
33 throw std::runtime_error(
"Trying to re-insert symbol " + name);
35 symbol->set_id(counter++);
36 symbols.push_back(symbol);
41 for (
const auto& symbol: symbols) {
42 if (symbol->get_name() == name) {
51 : symtab_name{
table.name()}
52 , global{table.global_scope()}
58 if (symbol ==
nullptr) {
61 const auto& nodes = symbol->get_nodes_by_type(
62 {AstNodeType::FUNCTION_BLOCK, AstNodeType::PROCEDURE_BLOCK});
63 return !nodes.empty();
70 if (token !=
nullptr) {
81 throw std::runtime_error(
"Trying to re-insert SymbolTable " +
name);
91 std::vector<std::shared_ptr<Symbol>> variables;
94 if (symbol->has_all_properties(properties)) {
95 variables.push_back(symbol);
98 if (symbol->has_any_property(properties)) {
99 variables.push_back(symbol);
110 std::decay_t<decltype(variables)> result;
111 for (
auto& variable: variables) {
112 if (!variable->has_any_property(without)) {
113 result.push_back(variable);
121 std::vector<std::shared_ptr<Symbol>> variables;
124 if (symbol->has_all_status(status)) {
125 variables.push_back(symbol);
128 if (symbol->has_any_status(status)) {
129 variables.push_back(symbol);
149 auto parent_table =
parent;
153 parent_table = parent_table->
parent;
154 if (parent_table !=
nullptr) {
165 if (!symbol && (
parent !=
nullptr)) {
174 throw std::logic_error(
"Lookup with previous symtab = nullptr ");
182 while (parent !=
nullptr) {
183 symbol = parent->
lookup(name);
187 parent = parent->get_parent_table();
196 const std::shared_ptr<Symbol>& second,
198 const auto& nodes = first->get_nodes();
199 const auto& name = first->get_name();
200 auto properties =
to_string(second->get_properties());
201 std::string type =
"UNKNOWN";
202 if (!nodes.empty()) {
204 type = nodes.front()->get_node_type_name();
208 auto msg = fmt::format(
"Re-declaration of {} [{}] <{}> in {} with one in {}",
213 second->get_scope());
214 throw std::runtime_error(msg);
216 logger->debug(
"SYMTAB :: {} [{}] in {} shadows <{}> definition in {}",
245 const std::shared_ptr<Symbol>& symbol) {
247 symbol->mark_created();
249 const auto& name = symbol->get_name();
250 auto search_symbol =
lookup(name);
253 if (search_symbol ==
nullptr) {
260 search_symbol->add_properties(symbol->get_properties());
261 return search_symbol;
272 const std::shared_ptr<Symbol>& new_symbol) {
273 const auto& symbol = (present_symbol !=
nullptr) ? present_symbol : new_symbol;
275 const bool is_parameter = new_symbol->has_any_property(NmodlType::param_assign);
276 const bool is_assigned_definition = new_symbol->has_any_property(
277 NmodlType::assigned_definition);
279 if (symbol->get_definition_order() == -1) {
280 if (is_parameter || is_assigned_definition) {
288 throw std::logic_error(
"Can not insert symbol without entering scope");
291 const auto& search_symbol =
lookup(symbol->get_name());
302 if (search_symbol ==
nullptr) {
316 if (search_symbol->has_any_property(symbol->get_properties())) {
319 search_symbol->add_properties(symbol->get_properties());
320 for (
const auto& n: symbol->get_nodes()) {
321 search_symbol->add_node(n);
324 return search_symbol;
344 if (symbol->get_name() !=
"v") {
359 static int block_counter = 0;
360 std::string new_name(name);
381 if (node ==
nullptr) {
382 throw std::runtime_error(
"Can't enter with empty node");
400 auto new_symtab = std::make_shared<SymbolTable>(new_name, node, global);
408 node_symtab = new_symtab.get();
422 throw std::logic_error(
"Trying leave scope without entering");
436 if (update_mode &&
symtab ==
nullptr) {
460 "NAME",
"# NODES",
"PROPERTIES",
"STATUS",
"LOCATION",
"VALUE",
"# READS",
"# WRITES"};
461 table.alignments = {text_alignment::left,
462 text_alignment::left,
463 text_alignment::left,
464 text_alignment::right,
465 text_alignment::right,
466 text_alignment::right};
468 for (
const auto& symbol:
symbols) {
469 auto is_external = symbol->is_external_variable();
470 auto read_count = symbol->get_read_count();
471 auto write_count = symbol->get_write_count();
474 if (is_external && read_count == 0 && write_count == 0) {
478 auto name = symbol->get_name();
479 if (symbol->is_array()) {
482 const auto&
position = symbol->get_token().position();
488 const auto& sym_value = symbol->get_value();
493 table.rows.push_back({
name, nodes, properties, status,
position, value, reads, writes});
504 const auto& location =
"POSITION : " +
position();
505 const auto scope =
global ?
"GLOBAL" :
"LOCAL";
506 return name + location +
" SCOPE : " + scope;
516 auto next_level = level;
523 if (item.second->symbol_count() >= 0) {
524 (item.second)->
print(ss, ++next_level);
SymbolTable * parent
pointer to the symbol table of parent block in the mod file
std::shared_ptr< Symbol > lookup(const std::string &name) const
check if symbol with given name exist
Base class for all Abstract Syntax Tree node types.
bool global_scope() const noexcept
SymbolTable * get_parent_table() const noexcept
std::shared_ptr< Symbol > insert(const std::shared_ptr< Symbol > &symbol)
insert new symbol into current table
SymbolTable(std::string name, const ast::Ast *node, bool global=false)
std::shared_ptr< SymbolTable > symtab
symbol table for mod file (always top level symbol table)
const std::string symtab_name
name of the block
THIS FILE IS GENERATED AT BUILD TIME AND SHALL NOT BE EDITED.
void insert(const std::shared_ptr< Symbol > &symbol)
insert new symbol into table
encapsulates code generation backend implementations
const std::string & name() const noexcept
Implement classes for representing symbol table at block and file scope.
std::vector< std::shared_ptr< Symbol > > get_variables_with_properties(syminfo::NmodlType properties, bool all=false) const
get variables with properties
std::string position() const
void leave_scope()
leaving current nmodl block
Status
state during various compiler passes
int definition_order
current order of variable being defined
std::string position() const
Return position of the token as string.
std::vector< std::shared_ptr< Symbol > > get_variables(syminfo::NmodlType with=syminfo::NmodlType::empty, syminfo::NmodlType without=syminfo::NmodlType::empty) const
get variables
void emit_message(const std::shared_ptr< Symbol > &first, const std::shared_ptr< Symbol > &second, bool redefinition)
Class to construct and pretty-print tabular data.
std::map< std::string, std::shared_ptr< SymbolTable > > children
symbol table for each enclosing block in the current nmodl block construct.
virtual std::string get_node_type_name() const =0
Return type (ast::AstNodeType) of ast node as std::string.
bool is_method_defined(const std::string &name) const
check if procedure/function with given name is defined
std::string title() const
construct title for symbol table
std::shared_ptr< Symbol > update_mode_insert(const std::shared_ptr< Symbol > &symbol)
insert symbol table in update mode
Implement generic table data structure.
std::string to_string(const T &obj)
SymbolTable * current_symtab
current symbol table being constructed
void insert_table(const std::string &name, const std::shared_ptr< SymbolTable > &table)
insert new symbol table as one of the children block
std::shared_ptr< Symbol > lookup(const std::string &name)
lookup for symbol into current as well as all parent tables
std::vector< std::shared_ptr< Symbol > > get_variables_with_status(syminfo::Status status, bool all=false) const
virtual const ModToken * get_token() const
Return associated token for the AST node.
std::string get_parent_table_name() const
Represent symbol table for a NMODL block.
bool global
true if current symbol table is global.
void insert(const std::shared_ptr< Symbol > &symbol)
void print(std::ostream &stream, std::string title, int indent) const
pretty print
Auto generated AST classes declaration.
SymbolTable * enter_scope(const std::string &name, ast::Ast *node, bool global, SymbolTable *node_symtab)
entering into new nmodl block
const ast::Ast * node
pointer to ast node for which current symbol table created
text_alignment
text alignment when printing in the tabular form
virtual bool is_statement_block() const noexcept
Check if the ast node is an instance of ast::StatementBlock.
void set_mode(bool update_mode)
re-initialize members to throw away old symbol tables this is required as symtab visitor pass runs mu...
NmodlType
NMODL variable properties.
Implement logger based on spdlog library.
const std::string GLOBAL_SYMTAB_NAME
name of top level global symbol table
virtual bool is_solve_block() const noexcept
Check if the ast node is an instance of ast::SolveBlock.
static int counter
number of tables
void update_order(const std::shared_ptr< Symbol > &present_symbol, const std::shared_ptr< Symbol > &new_symbol)
void print(std::ostream &ss, int level) const
virtual bool is_before_block() const noexcept
Check if the ast node is an instance of ast::BeforeBlock.
std::shared_ptr< Symbol > lookup(const std::string &name) const
check if symbol with given name exist in the current table (but not in parents)
Table table
table holding all symbols in the current block
virtual bool is_after_block() const noexcept
Check if the ast node is an instance of ast::AfterBlock.
Represent token returned by scanner.
bool update_table
default mode of symbol table: if update is true then we update exisiting symbols otherwise we throw a...
std::string get_unique_name(const std::string &name, ast::Ast *node, bool is_global)
return unique name by appending some counter value
std::shared_ptr< Symbol > lookup_in_scope(const std::string &name) const
check if symbol with given name exist in the current table (including all parents)
std::vector< std::shared_ptr< Symbol > > symbols
map of symbol name and associated symbol for faster lookup
bool under_global_scope()
check if currently we are visiting global scope node