NEURON
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/all.hpp"
11 #include "parser/c11_driver.hpp"
12 #include "utils/logger.hpp"
14 
15 
16 namespace nmodl {
17 namespace visitor {
18 
19 
20 std::string RenameVisitor::new_name_generator(const std::string& old_name) {
21  std::string new_name;
22  if (add_random_suffix) {
23  if (renamed_variables.find(old_name) != renamed_variables.end()) {
24  new_name = renamed_variables[old_name];
25  } else {
26  const auto& vars = get_global_vars(*ast);
27  if (add_prefix) {
28  new_name = suffix_random_string(vars,
29  new_var_name_prefix + old_name,
31  } else {
32  new_name =
34  }
35  renamed_variables[old_name] = new_name;
36  }
37  } else {
38  if (add_prefix) {
39  new_name = new_var_name_prefix + old_name;
40  } else {
41  new_name = new_var_name;
42  }
43  }
44  return new_name;
45 }
46 
47 /// rename matching variable
49  const auto& name = node.get_node_name();
50  if (std::regex_match(name, var_name_regex) && node.get_parent() &&
51  !node.get_parent()->is_function_call()) {
52  std::string new_name = new_name_generator(name);
53  node.get_value()->set(new_name);
54  std::string token_string = node.get_token() != nullptr
55  ? " at " + node.get_token()->position()
56  : "";
57  logger->debug("RenameVisitor :: Renaming variable {}{} to {}",
58  name,
59  token_string,
60  new_name);
61  }
62 }
63 
64 /** Prime name has member order which is an integer. In theory
65  * integer could be "macro name" and hence could end-up renaming
66  * macro. In practice this won't be an issue as we order is set
67  * by parser. To be safe we are only renaming prime variable.
68  */
70  node.visit_children(*this);
71 }
72 
73 /**
74  * Parse verbatim blocks and rename variable if it is used.
75  */
77  if (!rename_verbatim) {
78  return;
79  }
80 
81  const auto& statement = node.get_statement();
82  const auto& text = statement->eval();
84 
85  driver.scan_string(text);
86  auto tokens = driver.all_tokens();
87 
88  std::ostringstream result;
89  for (auto& token: tokens) {
90  if (std::regex_match(token, var_name_regex)) {
91  /// Check if variable is already renamed and use the same naming otherwise add the
92  /// new_name to the renamed_variables map
93  const std::string& new_name = new_name_generator(token);
94  result << new_name;
95  logger->debug("RenameVisitor :: Renaming variable {} in VERBATIM block to {}",
96  token,
97  new_name);
98  } else {
99  result << token;
100  }
101  }
102  statement->set(result.str());
103 }
104 
105 } // namespace visitor
106 } // namespace nmodl
Auto generated AST classes declaration.
Represents a name.
Definition: name.hpp:44
Represents a prime variable (for ODE)
Definition: prime_name.hpp:48
Represents a C code block.
Definition: verbatim.hpp:38
Class that binds all pieces together for parsing C verbatim blocks.
Definition: c11_driver.hpp:37
std::string new_var_name
new name
void visit_verbatim(const ast::Verbatim &node) override
Parse verbatim blocks and rename variable if it is used.
bool rename_verbatim
rename verbatim blocks as well
void visit_prime_name(const ast::PrimeName &node) override
Prime name has member order which is an integer.
void visit_name(const ast::Name &node) override
rename matching variable
bool add_prefix
add prefix to variable name
std::string new_name_generator(const std::string &old_name)
Check if variable is already renamed and use the same naming otherwise add the new_name to the rename...
std::unordered_map< std::string, std::string > renamed_variables
Map that keeps the renamed variables to keep the same random suffix when a variable is renamed across...
bool add_random_suffix
add random suffix
std::regex var_name_regex
regex for searching which variables to replace
std::string new_var_name_prefix
variable prefix
std::shared_ptr< ast::Program > ast
ast::Ast* node
const char * name
Definition: init.cpp:16
std::string suffix_random_string(const std::set< std::string > &vars, const std::string &original_string, const UseNumbersInString use_num)
Return the "original_string" with a random suffix if "original_string" exists in "vars".
std::set< std::string > get_global_vars(const Program &node)
Return set of strings with the names of all global variables.
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
logger_type logger
Definition: logger.cpp:34
static Node * node(Object *)
Definition: netcvode.cpp:291
#define text
Definition: plot.cpp:60
Blindly rename given variable to new name
nmodl::parser::UnitDriver driver
Definition: parser.cpp:28
Utility functions for visitors implementation.