User Guide
codegen_compatibility_visitor.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 \copybrief nmodl::codegen::CodegenCompatibilityVisitor
13  */
14 
15 #include <map>
16 #include <set>
17 
18 #include "ast/ast.hpp"
19 #include "codegen_naming.hpp"
20 #include "lexer/modtoken.hpp"
21 #include "symtab/symbol_table.hpp"
22 #include "utils/logger.hpp"
23 #include "visitors/ast_visitor.hpp"
24 
25 namespace nmodl {
26 namespace codegen {
27 
28 using namespace ast;
29 
30 /**
31  * \addtogroup codegen_backends
32  * \{
33  */
34 
35 /**
36  * \class CodegenCompatibilityVisitor
37  * \brief %Visitor for printing compatibility issues of the mod file
38  *
39  * INDEPENDENT_BLOCK is ignored (no error raised) as stated in:
40  * https://www.neuron.yale.edu/neuron/static/py_doc/modelspec/programmatic/mechanisms/nmodl.html
41  */
43  /// Typedef for defining FunctionPointer that points to the
44  /// function needed to be called for every kind of error
45  typedef std::string (CodegenCompatibilityVisitor::*FunctionPointer)(
46  ast::Ast& node,
47  const std::shared_ptr<ast::Ast>&) const;
48 
49  /// associated container to find the function needed to be called in
50  /// for every ast::AstNodeType that is unsupported
51  static const std::map<ast::AstNodeType, FunctionPointer> unhandled_ast_types_func;
52 
53  /// Set of handled solvers by the NMODL \c C++ code generator
54  static const inline std::set<std::string> handled_solvers{codegen::naming::CNEXP_METHOD,
59 
60  const std::string simulator = "coreneuron";
61 
62  public:
63  /// \name Ctor & dtor
64  /// \{
65 
66  /// Default CodegenCompatibilityVisitor constructor
67  ///
68  /// The argument `simulator` must be `"neuron"` for NEURON, everything else
69  /// refers to CoreNEURON. The compatibility will be checked as if
70  /// generating code for the specified simulator.
71  CodegenCompatibilityVisitor(const std::string& simulator = "coreneuron")
72  : simulator(simulator) {}
73 
74  /// \}
75 
76  /// Search the ast::Ast for nodes that
77  /// are incompatible with NMODL \c C++ code generator
78  ///
79  /// \param node Ast
80  /// \return bool if there are unhandled nodes or not
81  bool find_unhandled_ast_nodes(Ast& node) const;
82 
83  private:
84  /// Takes as parameter an std::shared_ptr<ast::Ast>,
85  /// searches if the method used for solving is supported
86  /// and if it is not it returns a relative error message
87  ///
88  /// \param node Not used by the function
89  /// \param ast_node Ast node which is checked
90  /// \return std::string error
91  std::string return_error_if_solve_method_is_unhandled(
92  ast::Ast& node,
93  const std::shared_ptr<ast::Ast>& ast_node) const;
94 
95  /// Takes as parameter an std::shared_ptr<ast::Ast> node
96  /// and returns a relative error with the name, the type
97  /// and the location of the unhandled statement
98  ///
99  /// \tparam T Type of node parameter in the ast::Ast
100  /// \param node Not used by the function
101  /// \param ast_node Ast node which is checked
102  /// \return std::string error
103  template <typename T>
104  std::string return_error_with_name(ast::Ast& /* node */,
105  const std::shared_ptr<ast::Ast>& ast_node) const {
106  auto real_type_block = std::dynamic_pointer_cast<T>(ast_node);
107  auto token = real_type_block->get_token();
108  try {
109  return fmt::format("\"{}\" {}construct found at [{}] is not handled\n",
110  ast_node->get_node_name(),
111  real_type_block->get_nmodl_name(),
112  token ? token->position() : "unknown location");
113  } catch (const std::logic_error&) {
114  return fmt::format("{}construct found at [{}] is not handled\n",
115  real_type_block->get_nmodl_name(),
116  token ? token->position() : "unknown location");
117  }
118  }
119 
120  /// Takes as parameter an std::shared_ptr<ast::Ast> node
121  /// and returns a relative error with the type and the
122  /// location of the unhandled statement
123  ///
124  /// \tparam T Type of node parameter in the ast::Ast
125  /// \param node Not used by the function
126  /// \param ast_node Ast node which is checked
127  /// \return std::string error
128  template <typename T>
129  std::string return_error_without_name(ast::Ast& /* node */,
130  const std::shared_ptr<ast::Ast>& ast_node) const {
131  auto real_type_block = std::dynamic_pointer_cast<T>(ast_node);
132  return fmt::format("{}construct found at [{}] is not handled\n",
133  real_type_block->get_nmodl_name(),
134  real_type_block->get_token()->position());
135  }
136 
137  /// Callback when detecting EXTERNAL.
138  std::string return_error_extern(ast::Ast& node,
139  const std::shared_ptr<ast::Ast>& ast_node) const;
140 
141  /// Takes as parameter the ast::Ast to read the symbol table
142  /// and an std::shared_ptr<ast::Ast> node and returns relative
143  /// error if a variable that is writen in the mod file is
144  /// defined as GLOBAL instead of RANGE
145  ///
146  /// \param node Ast
147  /// \param ast_node Ast node which is checked
148  /// \return std::string error
149  std::string return_error_global_var(ast::Ast& node,
150  const std::shared_ptr<ast::Ast>& ast_node) const;
151 
152  std::string return_error_param_var(ast::Ast& node,
153  const std::shared_ptr<ast::Ast>& ast_node) const;
154 
155  /// Takes as parameter the ast::Ast and checks if the
156  /// functions "bbcore_read" and "bbcore_write" are defined
157  /// in any of the ast::Ast VERBATIM blocks. The function is
158  /// called if there is a BBCORE_POINTER defined in the mod
159  /// file
160  ///
161  /// \param node Ast
162  /// \param ast_node Not used by the function
163  /// \return std::string error
164  std::string return_error_if_no_bbcore_read_write(
165  ast::Ast& node,
166  const std::shared_ptr<ast::Ast>& ast_node) const;
167 };
168 
169 /** \} */ // end of codegen_backends
170 
171 } // namespace codegen
172 } // namespace nmodl
nmodl::codegen::CodegenCompatibilityVisitor
Visitor for printing compatibility issues of the mod file
Definition: codegen_compatibility_visitor.hpp:42
nmodl::ast::Ast
Base class for all Abstract Syntax Tree node types.
Definition: ast.hpp:69
nmodl::codegen::naming::CNEXP_METHOD
static constexpr char CNEXP_METHOD[]
cnexp method in nmodl
Definition: codegen_naming.hpp:30
nmodl::codegen::CodegenCompatibilityVisitor::CodegenCompatibilityVisitor
CodegenCompatibilityVisitor(const std::string &simulator="coreneuron")
Default CodegenCompatibilityVisitor constructor.
Definition: codegen_compatibility_visitor.hpp:71
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
symbol_table.hpp
Implement classes for representing symbol table at block and file scope.
nmodl::codegen::naming::SPARSE_METHOD
static constexpr char SPARSE_METHOD[]
sparse method in nmodl
Definition: codegen_naming.hpp:42
codegen_naming.hpp
nmodl::codegen::CodegenCompatibilityVisitor::return_error_with_name
std::string return_error_with_name(ast::Ast &, const std::shared_ptr< ast::Ast > &ast_node) const
Takes as parameter an std::shared_ptr<ast::Ast> node and returns a relative error with the name,...
Definition: codegen_compatibility_visitor.hpp:104
nmodl::visitor::AstVisitor
Concrete visitor for all AST classes.
Definition: ast_visitor.hpp:37
nmodl::codegen::CodegenCompatibilityVisitor::return_error_without_name
std::string return_error_without_name(ast::Ast &, const std::shared_ptr< ast::Ast > &ast_node) const
Takes as parameter an std::shared_ptr<ast::Ast> node and returns a relative error with the type and t...
Definition: codegen_compatibility_visitor.hpp:129
ast.hpp
Auto generated AST classes declaration.
nmodl::codegen::naming::DERIVIMPLICIT_METHOD
static constexpr char DERIVIMPLICIT_METHOD[]
derivimplicit method in nmodl
Definition: codegen_naming.hpp:24
logger.hpp
Implement logger based on spdlog library.
nmodl::codegen::naming::EULER_METHOD
static constexpr char EULER_METHOD[]
euler method in nmodl
Definition: codegen_naming.hpp:27
modtoken.hpp
nmodl::codegen::CodegenCompatibilityVisitor::unhandled_ast_types_func
static const std::map< ast::AstNodeType, FunctionPointer > unhandled_ast_types_func
associated container to find the function needed to be called in for every ast::AstNodeType that is u...
Definition: codegen_compatibility_visitor.hpp:51
nmodl::codegen::naming::AFTER_CVODE_METHOD
static constexpr char AFTER_CVODE_METHOD[]
cvode method in nmodl
Definition: codegen_naming.hpp:33
ast_visitor.hpp
Concrete visitor for all AST classes.