![Logo](logo.png) |
User Guide
|
Go to the documentation of this file.
32 std::unordered_set<std::string> procedure_vars{};
33 for (
const auto& proc_node: procedure_nodes) {
35 for (
const auto& table_node: table_nodes) {
36 const auto& table_vars =
37 std::dynamic_pointer_cast<const ast::TableStatement>(table_node)->get_table_vars();
38 for (
const auto& table_var: table_vars) {
39 const auto& [var_name,
40 inserted] = procedure_vars.insert(table_var->get_node_name());
43 fmt::format(
"SemanticAnalysisVisitor :: TABLE statement variable {} used "
59 std::set<std::string> range_vars{};
60 for (
const auto& range_node: range_nodes) {
61 range_vars.insert(range_node->get_node_name());
64 const auto& function_nodes =
66 std::set<std::string> func_vars{};
67 for (
const auto& function_node: function_nodes) {
68 func_vars.insert(function_node->get_node_name());
71 std::vector<std::string> result;
72 std::set_intersection(func_vars.begin(),
76 std::back_inserter(result));
77 return !result.empty();
86 if (!suffix_node.empty()) {
87 const auto& suffix = std::dynamic_pointer_cast<const ast::Suffix>(suffix_node[0]);
88 const auto& type = suffix->get_type()->get_node_name();
96 using namespace symtab::syminfo;
97 const auto& with_prop = NmodlType::read_ion_var | NmodlType::write_ion_var;
100 assert(sym_table !=
nullptr);
103 const auto& ion_variables = sym_table->get_variables_with_properties(with_prop,
false);
106 for (
const auto& var: ion_variables) {
107 if (var->has_any_property(NmodlType::constant_var)) {
109 fmt::format(
"SemanticAnalysisVisitor :: ion variable {} from the USEION statement "
110 "can not be re-declared in a CONSTANT block",
124 if (derivative_block_nodes.size() > 1) {
125 logger->critical(
"It is not supported to have several DERIVATIVE blocks");
168 if (parent && parent->is_random_var()) {
172 if (parent && parent->is_var_name()) {
174 if (parent && parent->is_function_call()) {
181 if (!arguments.empty() && arguments.front()->is_var_name() &&
182 arguments.front()->get_node_name() == name) {
195 fmt::format(
"SemanticAnalysisVisitor :: RANDOM variable {} at {}"
196 " can be used only as the first arg of a random function",
210 auto position = node.
get_name()->get_token()->position();
214 if (!arguments.empty()) {
215 auto arg0 = arguments.front();
216 if (arg0->is_var_name()) {
217 auto name = arg0->get_node_name();
226 fmt::format(
"SemanticAnalysisVisitor :: random function {} at {} :: The first arg must "
227 "be a random variable",
234 if (
size_t args_size = node.
get_arguments().size(); args_size != 1) {
236 fmt::format(
"nrn_pointing excepts exactly one argument, got: {}", args_size));
249 "SemanticAnalysisVisitor :: The procedure or function containing the TABLE statement "
250 "should contains exactly one argument.");
258 "SemanticAnalysisVisitor :: TABLE statement in FUNCTION cannot have a table name "
263 "SemanticAnalysisVisitor :: TABLE statement in PROCEDURE must have a table name list.");
272 "SemanticAnalysisVisitor :: This mod file is not point process but contains a "
282 if (n->get_value()->get_value() !=
"t") {
284 "SemanticAnalysisVisitor :: '{}' cannot be used as an independent variable, only "
286 n->get_value()->get_value());
296 "SemanticAnalysisVisitor :: Function table '{}' must have one or more arguments.",
306 logger->error(
"PROTECT statement is not supported with GPU execution");
309 logger->warn(
"SemanticAnalysisVisitor :: Find a PROTECT inside a already locked part.");
317 logger->error(
"MUTEXLOCK statement is not supported with GPU execution");
320 logger->warn(
"SemanticAnalysisVisitor :: Found a MUTEXLOCK inside an already locked part.");
329 logger->error(
"MUTEXUNLOCK statement is not supported with GPU execution");
332 logger->warn(
"SemanticAnalysisVisitor :: Found a MUTEXUNLOCK outside a locked part.");
std::string get_node_name() const override
Return name of the node.
@ DERIVATIVE_BLOCK
type of ast::DerivativeBlock
void visit_function_table_block(const ast::FunctionTableBlock &node) override
Visit function table to check that number of args > 0.
@ FUNCTION_BLOCK
type of ast::FunctionBlock
const ArgumentVector & get_parameters() const noexcept override
Getter for member variable ProcedureBlock::parameters.
void visit_children(visitor::Visitor &v) override
visit children i.e.
bool check_name_conflict(const ast::Program &node)
Visitor to check some semantic rules on the AST
void visit_mutex_unlock(const ast::MutexUnlock &node) override
Look if MUTEXUNLOCK is outside a locked block.
const ArgumentVector & get_parameters() const noexcept override
Getter for member variable FunctionTableBlock::parameters.
bool in_mutex
true if we are inside a mutex locked part
bool in_function
true if we are in a function block
bool check(const ast::Program &node)
bool accel_backend
true if accelerator backend is used for code generation
std::shared_ptr< Name > get_name() const noexcept
Getter for member variable FunctionCall::name.
encapsulates code generation backend implementations
Auto generated AST classes declaration.
Represent MUTEXLOCK statement in NMODL.
Represents TABLE statement in NMODL.
Implement various classes to represent various Symbol properties.
void visit_children(visitor::Visitor &v) override
visit children i.e.
void visit_protect_statement(const ast::ProtectStatement &node) override
Look if protect is inside a locked block.
void visit_children(visitor::Visitor &v) override
visit children i.e.
bool is_random_construct_function(const std::string &name)
Is given name a one of the function for RANDOM construct.
void visit_name(const ast::Name &node) override
Only use of random_var is as first arg in random function.
Auto generated AST classes declaration.
void visit_independent_block(const ast::IndependentBlock &node) override
Visit independent block and check if one of the variable is not t.
const ModToken * get_token() const noexcept override
Return associated token for the current ast node.
symtab::SymbolTable * program_symtab
std::string position() const
Return position of the token as string.
std::string get_node_name() const override
Return name of the node.
@ PROCEDURE_BLOCK
type of ast::ProcedureBlock
Auto generated AST classes declaration.
Utility functions for visitors implementation.
Auto generated AST classes declaration.
Auto generated AST classes declaration.
Auto generated AST classes declaration.
const ArgumentVector & get_parameters() const noexcept override
Getter for member variable FunctionBlock::parameters.
Auto generated AST classes declaration.
const NameVector & get_variables() const noexcept
Getter for member variable IndependentBlock::variables.
bool in_procedure
true if we are in a procedure block
Represents a DESTRUCTOR block in the NMODL.
bool check_table_vars(const ast::Program &node)
Auto generated AST classes declaration.
void visit_procedure_block(const ast::ProcedureBlock &node) override
Store if we are in a procedure and if the arity of this is 1.
Represent MUTEXUNLOCK statement in NMODL.
@ SUFFIX
type of ast::Suffix
bool is_nrn_pointing(const std::string &name)
Is given name nrn_pointing.
void visit_children(visitor::Visitor &v) override
visit children i.e.
Auto generated AST classes declaration.
const ExpressionVector & get_arguments() const noexcept
Getter for member variable FunctionCall::arguments.
void visit_mutex_lock(const ast::MutexLock &node) override
Look if MUTEXLOCK is inside a locked block.
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
Auto generated AST classes declaration.
Auto generated AST classes declaration.
const NameVector & get_table_vars() const noexcept
Getter for member variable TableStatement::table_vars.
void visit_table_statement(const ast::TableStatement &node) override
Visit a table statement and check that the arity of the block were 1.
void visit_children(visitor::Visitor &v) override
visit children i.e.
std::string get_node_name() const override
Return name of the node.
Implement logger based on spdlog library.
bool one_arg_in_procedure_function
true if the procedure or the function contains only one argument
void visit_function_call(const ast::FunctionCall &node) override
random function first arg must be random_var
bool is_point_process
true if the mod file is of type point process
symtab::SymbolTable * get_symbol_table() const override
Return associated symbol table for the current ast node.
Represents a INDEPENDENT block in the NMODL.
void visit_function_block(const ast::FunctionBlock &node) override
Store if we are in a function and if the arity of this is 1.
Represents top level AST node for whole NMODL input.
@ random_var
Randomvar Type.
void visit_destructor_block(const ast::DestructorBlock &node) override
Visit destructor and check that the file is of type POINT_PROCESS or ARTIFICIAL_CELL.
Auto generated AST classes declaration.
void visit_program(const ast::Program &node) override
Check number of DERIVATIVE blocks.
std::shared_ptr< Symbol > lookup(const std::string &name) const
check if symbol with given name exist in the current table (but not in parents)
@ TABLE_STATEMENT
type of ast::TableStatement
virtual Ast * get_parent() const
Parent getter.
virtual std::string get_node_name() const
Return name of of the node.
@ RANGE_VAR
type of ast::RangeVar