12 #include <nlohmann/json.hpp>
34 const std::string& original_string,
38 if (vars.find(original_string) == vars.end()) {
39 return original_string;
41 std::string new_string = original_string;
46 if (singleton_random_string_class.random_string_exists(original_string)) {
47 const auto random_suffix =
"_" +
48 singleton_random_string_class.get_random_string(original_string);
49 new_string = original_string + random_suffix;
53 while (vars.find(new_string) != vars.end()) {
54 const auto random_suffix =
55 "_" + singleton_random_string_class.reset_random_string(original_string, use_num);
56 new_string = original_string + random_suffix;
64 std::map<std::string, int>& variables) {
65 auto it = variables.emplace(
name, 0);
66 auto counter = it.first->second;
69 std::ostringstream oss;
70 oss <<
name <<
'_' <<
suffix <<
'_' << counter;
75 const auto& statements =
node.get_statements();
76 for (
const auto& statement: statements) {
77 if (statement->is_local_list_statement()) {
78 return std::static_pointer_cast<LocalListStatement>(statement);
86 const auto& statements =
node.get_statements();
87 if (variables ==
nullptr) {
88 auto statement = std::make_shared<LocalListStatement>(
LocalVarVector());
89 node.insert_statement(statements.begin(), statement);
98 if (local_list_statement ==
nullptr) {
99 throw std::logic_error(
"no local statement");
101 auto var = std::make_shared<LocalVar>(varname);
102 local_list_statement->emplace_back_local_var(
var);
129 auto nmodl_text =
"PROCEDURE dummy() { " + code_statement +
" }";
131 auto procedure = std::dynamic_pointer_cast<ProcedureBlock>(ast->get_blocks().front());
132 auto statement = std::shared_ptr<Statement>(
133 procedure->get_statement_block()->get_statements()[0]->clone());
138 const std::vector<std::string>::const_iterator& code_statements_beg,
139 const std::vector<std::string>::const_iterator& code_statements_end) {
140 std::vector<std::shared_ptr<Statement>> statements;
141 statements.reserve(code_statements_end - code_statements_beg);
144 std::back_inserter(statements),
157 const std::vector<std::string>& code_statements) {
159 std::string
nmodl_text =
"PROCEDURE dummy() {\n";
160 for (
auto& statement: code_statements) {
165 auto procedure = std::dynamic_pointer_cast<ProcedureBlock>(ast->get_blocks().front());
166 auto statement_block = std::shared_ptr<StatementBlock>(
167 procedure->get_statement_block()->clone());
168 return statement_block;
172 std::set<std::string> vars;
173 if (
auto* symtab =
node.get_symbol_table()) {
175 NmodlType property = NmodlType::global_var | NmodlType::local_var | NmodlType::range_var |
176 NmodlType::param_assign | NmodlType::extern_var |
177 NmodlType::prime_name | NmodlType::assigned_definition |
178 NmodlType::read_ion_var | NmodlType::write_ion_var |
179 NmodlType::nonspecific_cur_var | NmodlType::electrode_cur_var |
180 NmodlType::constant_var | NmodlType::extern_neuron_variable |
181 NmodlType::state_var | NmodlType::factor_def;
182 for (
const auto& globalvar: symtab->get_variables_with_properties(property)) {
183 std::string var_name = globalvar->get_name();
184 if (globalvar->is_array()) {
187 vars.insert(var_name);
197 function_calls.begin(),
198 function_calls.end(),
199 [&
name](
const std::shared_ptr<const ast::Ast>& f) {
200 return std::dynamic_pointer_cast<const ast::FunctionCall>(f)->get_node_name() == name;
208 const std::vector<ast::AstNodeType>& types) {
214 const std::vector<ast::AstNodeType>& types) {
221 return !blocks.empty();
226 return std::any_of(solve_blocks.begin(), solve_blocks.end(), [&
name](
auto const& solve_block) {
228 const auto& method = dynamic_cast<ast::SolveBlock const&>(*solve_block).get_method();
229 return method && method->get_node_name() == name;
235 std::stringstream stream;
243 std::stringstream stream;
245 v.compact_json(compact);
246 v.add_nmodl(add_nmodl);
247 v.expand_keys(expand);
254 if (!lhs->is_var_name()) {
258 const auto& lhs_var_name = std::dynamic_pointer_cast<ast::VarName>(lhs);
263 const std::shared_ptr<ast::Expression>& lhs,
264 const std::shared_ptr<ast::Expression>&
rhs) {
266 std::unordered_set<std::string> out;
267 if (!lhs->is_var_name()) {
273 auto rhs_nodes = lookup_visitor.
get_nodes();
274 std::for_each(rhs_nodes.begin(),
276 [&out](
const std::shared_ptr<ast::Ast>&
node) { out.emplace(to_nmodl(node)); });
287 std::string full_var_name;
289 auto index_name_node = std::dynamic_pointer_cast<ast::IndexedName>(
node.get_name());
294 return full_var_name;
Auto generated AST classes declaration.
Base class for all identifiers.
Represents specific element of an array variable.
Represents an integer variable.
void accept(visitor::Visitor &v) override
accept (or visit) the current AST node using provided visitor
Represents top level AST node for whole NMODL input.
Represents block encapsulating list of statements.
Class that binds all pieces together for parsing nmodl file.
static SingletonRandomString & instance()
Function to instantiate the SingletonRandomString class.
Visitor for printing AST in JSON format
Visitor for printing AST back to NMODL
virtual bool is_indexed_name() const noexcept
Check if the ast node is an instance of ast::IndexedName.
virtual std::string get_node_name() const
Return name of of the node.
AstNodeType
Enum type for every AST node type.
@ VAR_NAME
type of ast::VarName
@ SOLVE_BLOCK
type of ast::SolveBlock
@ FUNCTION_CALL
type of ast::FunctionCall
std::vector< std::shared_ptr< LocalVar > > LocalVarVector
bool parse_string(const std::string &input)
parser Units provided as string (used for testing)
UseNumbersInString
Enum to wrap bool variable to select if random string should have numbers or not.
double var(InputIterator begin, InputIterator end)
THIS FILE IS GENERATED AT BUILD TIME AND SHALL NOT BE EDITED.
THIS FILE IS GENERATED AT BUILD TIME AND SHALL NOT BE EDITED.
static constexpr char NRN_POINTING_METHOD[]
nrn_pointing function in nmodl
static std::unordered_map< std::string, std::string > RANDOM_FUNCTIONS_MAPPING
std::string to_string(const T &obj)
NmodlType
NMODL variable properties.
std::vector< std::shared_ptr< Statement > > create_statements(const std::vector< std::string >::const_iterator &code_statements_beg, const std::vector< std::string >::const_iterator &code_statements_end)
Same as for create_statement but for vectors of strings.
LocalVar * add_local_variable(StatementBlock &node, Identifier *varname)
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".
bool calls_function(const ast::Ast &node, const std::string &name)
Checks whether block contains a call to a particular function.
std::shared_ptr< Statement > create_statement(const std::string &code_statement)
Convert given code statement (in string format) to corresponding ast node.
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...
std::set< std::string > get_global_vars(const Program &node)
Return set of strings with the names of all global variables.
void add_local_statement(StatementBlock &node)
Add empty local statement to given block if already doesn't exist.
std::shared_ptr< ast::LocalListStatement > get_local_list_statement(const StatementBlock &node)
Return pointer to local statement in the given block, otherwise nullptr.
std::shared_ptr< StatementBlock > create_statement_block(const std::vector< std::string > &code_statements)
Convert given code statement (in string format) to corresponding ast node.
encapsulates code generation backend implementations
bool is_random_construct_function(const std::string &name)
Is given name a one of the function for RANDOM construct.
std::vector< std::shared_ptr< const ast::Ast > > collect_nodes(const ast::Ast &node, const std::vector< ast::AstNodeType > &types)
traverse node recursively and collect nodes of given types
std::pair< std::string, std::unordered_set< std::string > > statement_dependencies(const std::shared_ptr< ast::Expression > &lhs, const std::shared_ptr< ast::Expression > &rhs)
If lhs and rhs combined represent an assignment (we assume to have an "=" in between them) we extract...
std::string to_json(const ast::Ast &node, bool compact, bool expand, bool add_nmodl)
Given AST node, return the JSON string representation.
std::string statement_dependencies_key(const std::shared_ptr< ast::Expression > &lhs)
The result.first of statement_dependencies.
std::string to_nmodl(const ast::Ast &node, const std::set< ast::AstNodeType > &exclude_types)
Given AST node, return the NMODL string representation.
std::string get_indexed_name(const ast::IndexedName &node)
Given a Indexed node, return the name with index.
std::string get_full_var_name(const ast::VarName &node)
Given a VarName node, return the full var name including index.
bool node_exists(const ast::Ast &node, ast::AstNodeType ast_type)
Whether a node of type ast_type exists as a subnode of node.
bool is_nrn_pointing(const std::string &name)
Is given name nrn_pointing.
bool solver_exists(const ast::Ast &node, const std::string &name)
Whether or not a solver of type name exists in the AST.
THIS FILE IS GENERATED AT BUILD TIME AND SHALL NOT BE EDITED.
data_handle< T > transform(data_handle< T > handle, Transform type)
static Node * node(Object *)
Implement string manipulation functions.
Base class for all Abstract Syntax Tree node types.
nmodl::parser::UnitDriver driver
Utility functions for visitors implementation.