User Guide
visitor_utils.hpp
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 
8 #pragma once
9 
10 /**
11  * \file
12  * \brief Utility functions for visitors implementation
13  */
14 
15 #include <map>
16 #include <set>
17 #include <string>
18 #include <unordered_set>
19 
20 #include <ast/ast_decl.hpp>
21 #include <utils/common_utils.hpp>
22 
23 namespace nmodl {
24 namespace visitor {
25 
27 
28 /**
29  * \brief Return the "original_string" with a random suffix if "original_string" exists in "vars"
30  *
31  * Return a std::string in the form "original_string"_"random_string", where
32  * random_string is a string defined in the nmodl::utils::SingletonRandomString
33  * for the original_string. Vars is a const ref to std::set<std::string> which
34  * holds the names that need to be checked for uniqueness. Choose if the
35  * "random_string" will include numbers using "use_num"
36  *
37  * \param vars a const ref to std::set<std::string> which holds the names of the variables we should
38  * check for uniqueness. Normally this is a vector of all the variables defined in the
39  * mod file.
40  * \param original_string the original string to be suffixed with a random string
41  * \param use_num a UseNumbersInString enum value to choose if the random string will include
42  * numbers
43  * \return std::string the new string with the proper suffix if needed
44  */
45 std::string suffix_random_string(
46  const std::set<std::string>& vars,
47  const std::string& original_string,
49 
50 /// Return new name variable by appending `_suffix_COUNT` where `COUNT` is
51 /// number of times the given variable is already used.
52 std::string get_new_name(const std::string& name,
53  const std::string& suffix,
54  std::map<std::string, int>& variables);
55 
56 
57 /// Return pointer to local statement in the given block, otherwise nullptr
58 std::shared_ptr<ast::LocalListStatement> get_local_list_statement(const ast::StatementBlock& node);
59 
60 
61 /// Add empty local statement to given block if already doesn't exist
62 void add_local_statement(ast::StatementBlock& node);
63 
64 
65 /// Add new local variable to the block
66 ast::LocalVar* add_local_variable(ast::StatementBlock& node, const std::string& varname);
67 ast::LocalVar* add_local_variable(ast::StatementBlock& node, ast::Identifier* varname);
68 ast::LocalVar* add_local_variable(ast::StatementBlock& node, const std::string& varname, int dim);
69 
70 
71 /// Create ast statement node from given code in string format
72 std::shared_ptr<ast::Statement> create_statement(const std::string& code_statement);
73 
74 /// Same as for create_statement but for vectors of strings
75 std::vector<std::shared_ptr<ast::Statement>> create_statements(
76  const std::vector<std::string>::const_iterator& code_statements_beg,
77  const std::vector<std::string>::const_iterator& code_statements_end);
78 
79 
80 /// Create ast statement block node from given code in string format
81 std::shared_ptr<ast::StatementBlock> create_statement_block(
82  const std::vector<std::string>& code_statements);
83 
84 
85 /// Remove statements from given statement block if they exist
86 void remove_statements_from_block(ast::StatementBlock& block,
87  const std::set<ast::Node*>& statements);
88 
89 
90 /// Return set of strings with the names of all global variables
91 std::set<std::string> get_global_vars(const ast::Program& node);
92 
93 
94 /// Checks whether block contains a call to a particular function
95 bool calls_function(const ast::Ast& node, const std::string& name);
96 
97 } // namespace visitor
98 
99 /// traverse \a node recursively and collect nodes of given \a types
100 std::vector<std::shared_ptr<const ast::Ast>> collect_nodes(
101  const ast::Ast& node,
102  const std::vector<ast::AstNodeType>& types = {});
103 
104 /// traverse \a node recursively and collect nodes of given \a types
105 std::vector<std::shared_ptr<ast::Ast>> collect_nodes(
106  ast::Ast& node,
107  const std::vector<ast::AstNodeType>& types = {});
108 
109 bool sparse_solver_exists(const ast::Ast& node);
110 
111 /// Given AST node, return the NMODL string representation
112 std::string to_nmodl(const ast::Ast& node, const std::set<ast::AstNodeType>& exclude_types = {});
113 
114 /// Given a shared pointer to an AST node, return the NMODL string representation
115 template <typename T>
116 typename std::enable_if<std::is_base_of<ast::Ast, T>::value, std::string>::type to_nmodl(
117  const std::shared_ptr<T>& node,
118  const std::set<ast::AstNodeType>& exclude_types = {}) {
119  return to_nmodl(*node, exclude_types);
120 }
121 
122 /// Given AST node, return the JSON string representation
123 std::string to_json(const ast::Ast& node,
124  bool compact = false,
125  bool expand = false,
126  bool add_nmodl = false);
127 
128 /// If \p lhs and \p rhs combined represent an assignment (we assume to have an "=" in between them)
129 /// we extract the variables on which the assigned variable depends on. We provide the input with
130 /// lhs and rhs because there are a few nodes that have this similar structure but slightly
131 /// different naming (binaryExpression, diff_eq_expression, linExpression)
132 std::pair<std::string, std::unordered_set<std::string>> statement_dependencies(
133  const std::shared_ptr<ast::Expression>& lhs,
134  const std::shared_ptr<ast::Expression>& rhs);
135 
136 /// Given a Indexed node, return the name with index
137 std::string get_indexed_name(const ast::IndexedName& node);
138 
139 /// Given a VarName node, return the full var name including index
140 std::string get_full_var_name(const ast::VarName& node);
141 
142 /// Is given name a one of the function for RANDOM construct
143 bool is_random_construct_function(const std::string& name);
144 
145 } // namespace nmodl
nmodl::get_indexed_name
std::string get_indexed_name(const ast::IndexedName &node)
Given a Indexed node, return the name with index.
Definition: visitor_utils.cpp:270
nmodl::to_nmodl
std::string to_nmodl(const ast::Ast &node, const std::set< ast::AstNodeType > &exclude_types)
Given AST node, return the NMODL string representation.
Definition: visitor_utils.cpp:227
nmodl::visitor::create_statements
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.
Definition: visitor_utils.cpp:136
nmodl::visitor::calls_function
bool calls_function(const ast::Ast &node, const std::string &name)
Checks whether block contains a call to a particular function.
Definition: visitor_utils.cpp:193
ast_decl.hpp
THIS FILE IS GENERATED AT BUILD TIME AND SHALL NOT BE EDITED.
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
nmodl::to_json
std::string to_json(const ast::Ast &node, bool compact, bool expand, bool add_nmodl)
Given AST node, return the JSON string representation.
Definition: visitor_utils.cpp:235
nmodl::is_random_construct_function
bool is_random_construct_function(const std::string &name)
Is given name a one of the function for RANDOM construct.
Definition: visitor_utils.cpp:285
nmodl::statement_dependencies
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...
Definition: visitor_utils.cpp:246
nmodl::utils::UseNumbersInString
UseNumbersInString
Enum to wrap bool variable to select if random string should have numbers or not.
Definition: common_utils.hpp:51
nmodl::utils::WithNumbers
@ WithNumbers
Definition: common_utils.hpp:51
nmodl::get_full_var_name
std::string get_full_var_name(const ast::VarName &node)
Given a VarName node, return the full var name including index.
Definition: visitor_utils.cpp:274
nmodl::visitor::create_statement
std::shared_ptr< Statement > create_statement(const std::string &code_statement)
Convert given code statement (in string format) to corresponding ast node.
Definition: visitor_utils.cpp:126
nmodl::collect_nodes
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
Definition: visitor_utils.cpp:205
nmodl::visitor::add_local_statement
void add_local_statement(StatementBlock &node)
Add empty local statement to given block if already doesn't exist.
Definition: visitor_utils.cpp:83
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::visitor::create_statement_block
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.
Definition: visitor_utils.cpp:155
nmodl::visitor::add_local_variable
LocalVar * add_local_variable(StatementBlock &node, Identifier *varname)
Definition: visitor_utils.cpp:92
nmodl::visitor::remove_statements_from_block
void remove_statements_from_block(ast::StatementBlock &block, const std::set< ast::Node * > &statements)
Remove statements from given statement block if they exist.
nmodl::sparse_solver_exists
bool sparse_solver_exists(const ast::Ast &node)
Definition: visitor_utils.cpp:218
nmodl::visitor::suffix_random_string
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".
Definition: visitor_utils.cpp:32
common_utils.hpp
Common utility functions for file/dir manipulation.
nmodl::visitor::get_global_vars
std::set< std::string > get_global_vars(const Program &node)
Return set of strings with the names of all global variables.
Definition: visitor_utils.cpp:170