User Guide
verbatim_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 
10 #include "ast/statement_block.hpp"
11 #include "ast/string.hpp"
12 #include "ast/verbatim.hpp"
13 #include "parser/c11_driver.hpp"
14 #include "src/utils/logger.hpp"
15 
16 
17 namespace nmodl {
18 namespace visitor {
19 
21  if (node.get_statements().empty()) {
22  return;
23  }
24 
25  auto current_symtab = node.get_symbol_table();
26  if (current_symtab != nullptr) {
27  symtab = current_symtab;
28  }
29 
30  // some statements like from, while are of type expression statement type.
31  // These statements contain statement block but do not have symbol table. And hence
32  // we push last non-null symbol table on the stack.
33  symtab_stack.push(symtab);
34 
35  // first need to process all children : perform recursively from innermost block
36  for (const auto& item: node.get_statements()) {
37  item->accept(*this);
38  }
39 
40  /// go back to previous block in hierarchy
41  symtab = symtab_stack.top();
42  symtab_stack.pop();
43 }
44 
45 /**
46  * Rename variable used in verbatim block if defined in NMODL scope
47  *
48  * Check if variable is candidate for renaming and check if it is
49  * defined in the nmodl blocks. If so, return "original" name of the
50  * variable.
51  */
52 std::string VerbatimVarRenameVisitor::rename_variable(const std::string& name) {
53  bool rename_plausible = false;
54  auto new_name = name;
55  if (name.find(LOCAL_PREFIX) == 0) {
56  new_name.erase(0, 2);
57  rename_plausible = true;
58  }
59  if (name.find(RANGE_PREFIX) == 0) {
60  new_name.erase(0, 3);
61  rename_plausible = true;
62  }
63  if (name.find(ION_PREFIX) == 0) {
64  new_name.erase(0, 1);
65  rename_plausible = true;
66  }
67  if (rename_plausible) {
68  auto symbol = symtab->lookup_in_scope(new_name);
69  if (symbol != nullptr) {
70  return new_name;
71  }
72  logger->warn("could not find {} definition in nmodl", name);
73  }
74  return name;
75 }
76 
77 
78 /**
79  * Parse verbatim blocks and rename variables used
80  */
82  const auto& statement = node.get_statement();
83  const auto& text = statement->eval();
85 
86  driver.scan_string(text);
87  const auto& tokens = driver.all_tokens();
88 
89  std::ostringstream oss;
90  for (const auto& token: tokens) {
91  oss << rename_variable(token);
92  }
93  statement->set(oss.str());
94 }
95 
96 } // namespace visitor
97 } // namespace nmodl
nmodl::visitor::VerbatimVarRenameVisitor::ION_PREFIX
const std::string ION_PREFIX
prefix used for range variables
Definition: verbatim_var_rename_visitor.hpp:62
nmodl::ast::Verbatim
Represents a C code block.
Definition: verbatim.hpp:38
nmodl::visitor::VerbatimVarRenameVisitor::visit_verbatim
void visit_verbatim(ast::Verbatim &node) override
Parse verbatim blocks and rename variables used.
Definition: verbatim_var_rename_visitor.cpp:81
nmodl::visitor::VerbatimVarRenameVisitor::symtab
symtab::SymbolTable * symtab
non-null symbol table in the scope hierarchy
Definition: verbatim_var_rename_visitor.hpp:50
nmodl::visitor::VerbatimVarRenameVisitor::rename_variable
std::string rename_variable(const std::string &name)
Rename variable used in verbatim block if defined in NMODL scope.
Definition: verbatim_var_rename_visitor.cpp:52
verbatim.hpp
Auto generated AST classes declaration.
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
nmodl::logger
logger_type logger
Definition: logger.cpp:34
nmodl::ast::Verbatim::get_statement
std::shared_ptr< String > get_statement() const noexcept
Getter for member variable Verbatim::statement.
Definition: verbatim.hpp:157
nmodl::parser::CDriver
Class that binds all pieces together for parsing C verbatim blocks.
Definition: c11_driver.hpp:37
nmodl::ast::StatementBlock::get_statements
const StatementVector & get_statements() const noexcept
Getter for member variable StatementBlock::statements.
Definition: statement_block.hpp:221
string.hpp
Auto generated AST classes declaration.
statement_block.hpp
Auto generated AST classes declaration.
driver
nmodl::parser::UnitDriver driver
Definition: parser.cpp:28
verbatim_var_rename_visitor.hpp
Rename variable in verbatim block.
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
c11_driver.hpp
nmodl::ast::StatementBlock
Represents block encapsulating list of statements.
Definition: statement_block.hpp:53
nmodl::visitor::VerbatimVarRenameVisitor::visit_statement_block
void visit_statement_block(ast::StatementBlock &node) override
visit node of type ast::StatementBlock
Definition: verbatim_var_rename_visitor.cpp:20
nmodl::visitor::VerbatimVarRenameVisitor::symtab_stack
std::stack< symtab::SymbolTable * > symtab_stack
symbol tables in nested blocks
Definition: verbatim_var_rename_visitor.hpp:53
logger.hpp
Implement logger based on spdlog library.
nmodl::visitor::VerbatimVarRenameVisitor::RANGE_PREFIX
const std::string RANGE_PREFIX
prefix used for range variables
Definition: verbatim_var_rename_visitor.hpp:59
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
nmodl::visitor::VerbatimVarRenameVisitor::LOCAL_PREFIX
const std::string LOCAL_PREFIX
prefix used for local variable
Definition: verbatim_var_rename_visitor.hpp:56