User Guide
local_var_rename_visitor.cpp
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 
9 
12 #include "ast/statement_block.hpp"
15 
16 
17 namespace nmodl {
18 namespace visitor {
19 
20 using symtab::SymbolTable;
21 
22 /// rename name conflicting variables in the statement block and it's all children
24  /// nothing to do
25  if (node.get_statements().empty()) {
26  return;
27  }
28 
29  auto current_symtab = node.get_symbol_table();
30  if (current_symtab != nullptr) {
31  symtab = current_symtab;
32  }
33 
34  // Some statements like from, while are of type expression statement type.
35  // These statements contain statement block but do not have symbol table. And hence
36  // we push last non-null symbol table on the stack.
37  symtab_stack.push(symtab);
38 
39  // first need to process all children : perform recursively from innermost block
40  for (const auto& item: node.get_statements()) {
41  item->visit_children(*this);
42  }
43 
44  /// go back to previous block in hierarchy
45  symtab = symtab_stack.top();
46  symtab_stack.pop();
47 
48  SymbolTable* parent_symtab = nullptr;
49  if (symtab != nullptr) {
50  parent_symtab = symtab->get_parent_table();
51  }
52 
53  const auto& variables = get_local_list_statement(node);
54 
55  /// global blocks do not change (do no have parent symbol table)
56  /// if no variables in the block then there is nothing to do
57  if (parent_symtab == nullptr || variables == nullptr) {
58  return;
59  }
60 
61  RenameVisitor rename_visitor;
62 
63  for (const auto& var: variables->get_variables()) {
64  std::string name = var->get_node_name();
65  auto s = parent_symtab->lookup_in_scope(name);
66  /// if symbol is a variable name (avoid renaming use of units like mV)
67  if (s && s->is_variable()) {
68  std::string new_name = get_new_name(name, "r", renamed_variables);
69  rename_visitor.set(name, new_name);
70  rename_visitor.visit_statement_block(node);
71  auto symbol = symtab->lookup_in_scope(name);
72  symbol->set_name(new_name);
73  symbol->mark_renamed();
74  }
75  }
76 }
77 
78 } // namespace visitor
79 } // namespace nmodl
local_list_statement.hpp
Auto generated AST classes declaration.
nmodl::symtab::SymbolTable::get_parent_table
SymbolTable * get_parent_table() const noexcept
Definition: symbol_table.hpp:126
nmodl::visitor::ConstAstVisitor::visit_statement_block
void visit_statement_block(const ast::StatementBlock &node) override
visit node of type ast::StatementBlock
Definition: ast_visitor.cpp:491
nmodl::visitor::get_local_list_statement
std::shared_ptr< ast::LocalListStatement > get_local_list_statement(const StatementBlock &node)
Return pointer to local statement in the given block, otherwise nullptr.
Definition: visitor_utils.cpp:73
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
expression_statement.hpp
Auto generated AST classes declaration.
nmodl::ast::StatementBlock::get_statements
const StatementVector & get_statements() const noexcept
Getter for member variable StatementBlock::statements.
Definition: statement_block.hpp:221
visitor_utils.hpp
Utility functions for visitors implementation.
nmodl::visitor::LocalVarRenameVisitor::symtab
const symtab::SymbolTable * symtab
non-null symbol table in the scope hierarchy
Definition: local_var_rename_visitor.hpp:65
statement_block.hpp
Auto generated AST classes declaration.
nmodl::ast::StatementBlock::get_symbol_table
symtab::SymbolTable * get_symbol_table() const override
Return associated symbol table for the current ast node.
Definition: statement_block.hpp:164
local_var_rename_visitor.hpp
Visitor to rename local variables conflicting with global scope
nmodl::visitor::RenameVisitor
Blindly rename given variable to new name
Definition: rename_visitor.hpp:43
nmodl::symtab::SymbolTable
Represent symbol table for a NMODL block.
Definition: symbol_table.hpp:57
nmodl::visitor::RenameVisitor::set
void set(const std::string &old_name, std::string new_name)
Definition: rename_visitor.hpp:97
nmodl::visitor::LocalVarRenameVisitor::renamed_variables
std::map< std::string, int > renamed_variables
variables currently being renamed and their count
Definition: local_var_rename_visitor.hpp:71
nmodl::visitor::LocalVarRenameVisitor::symtab_stack
std::stack< const symtab::SymbolTable * > symtab_stack
symbol tables in case of nested blocks
Definition: local_var_rename_visitor.hpp:68
nmodl::visitor::get_new_name
std::string get_new_name(const std::string &name, const std::string &suffix, std::map< std::string, int > &variables)
Return new name variable by appending _suffix_COUNT where COUNT is number of times the given variable...
Definition: visitor_utils.cpp:61
nmodl::ast::StatementBlock
Represents block encapsulating list of statements.
Definition: statement_block.hpp:53
rename_visitor.hpp
Blindly rename given variable to new name
nmodl::visitor::LocalVarRenameVisitor::visit_statement_block
void visit_statement_block(ast::StatementBlock &node) override
rename name conflicting variables in the statement block and it's all children
Definition: local_var_rename_visitor.cpp:23
nmodl::symtab::SymbolTable::lookup_in_scope
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)
Definition: symbol_table.cpp:164