19 const std::map<ast::AstNodeType, CodegenCompatibilityVisitor::FunctionPointer>
 
   21         {{AstNodeType::DISCRETE_BLOCK,
 
   22           &CodegenCompatibilityVisitor::return_error_with_name<DiscreteBlock>},
 
   23          {AstNodeType::SOLVE_BLOCK,
 
   27          {AstNodeType::BBCORE_POINTER_VAR,
 
   34     const std::shared_ptr<ast::Ast>& ast_node)
 const {
 
   35     auto solve_block_ast_node = std::dynamic_pointer_cast<ast::SolveBlock>(ast_node);
 
   36     std::stringstream unhandled_method_error_message;
 
   37     auto method = solve_block_ast_node->get_method();
 
   41     auto unhandled_solver_method = 
handled_solvers.find(method->get_node_name()) ==
 
   43     if (unhandled_solver_method) {
 
   44         unhandled_method_error_message << fmt::format(
 
   45             "\"{}\" solving method used at [{}] not handled. Supported methods are cnexp, euler, " 
   46             "derivimplicit and sparse\n",
 
   47             method->get_node_name(),
 
   48             method->get_token()->position());
 
   50     return unhandled_method_error_message.str();
 
   56     const std::shared_ptr<ast::Ast>& ast_node)
 const {
 
   64     auto external = std::dynamic_pointer_cast<ast::External>(ast_node);
 
   65     return fmt::format(
"Found EXTERNAL at [{}] while generating code for CoreNEURON.\n",
 
   66                        external->get_token()->position());
 
   72     const std::shared_ptr<ast::Ast>& ast_node)
 const {
 
   81     auto global_var = std::dynamic_pointer_cast<ast::GlobalVar>(ast_node);
 
   82     std::stringstream error_message_global_var;
 
   84         error_message_global_var << fmt::format(
 
   85             "\"{}\" variable found at [{}] should be defined as a RANGE variable instead of GLOBAL " 
   86             "to enable backend transformations\n",
 
   87             global_var->get_node_name(),
 
   88             global_var->get_token()->position());
 
   90     return error_message_global_var.str();
 
   96     const std::shared_ptr<ast::Ast>& ast_node)
 const {
 
   97     auto param_assign = std::dynamic_pointer_cast<ast::ParamAssign>(ast_node);
 
   98     std::stringstream error_message_global_var;
 
  100     if (!symbol->is_writable() && symbol->get_write_count() > 0) {
 
  101         error_message_global_var << fmt::format(
 
  102             "\"{}\" variable found at [{}] should be writable if it needs to be written\n",
 
  104             symbol->get_token().position());
 
  106     return error_message_global_var.str();
 
  112     const std::shared_ptr<ast::Ast>& )
 const {
 
  113     std::stringstream error_message_no_bbcore_read_write;
 
  114     const auto& verbatim_nodes = 
collect_nodes(node, {AstNodeType::VERBATIM});
 
  115     auto found_bbcore_read = 
false;
 
  116     auto found_bbcore_write = 
false;
 
  117     for (
const auto& it: verbatim_nodes) {
 
  118         auto verbatim = std::dynamic_pointer_cast<ast::Verbatim>(it);
 
  120         auto verbatim_statement_string = verbatim->get_statement()->get_value();
 
  127         driver.scan_string(verbatim_statement_string);
 
  128         auto tokens = 
driver.all_tokens();
 
  130         for (
const auto& token: tokens) {
 
  131             if (token == 
"bbcore_read") {
 
  132                 found_bbcore_read = 
true;
 
  134             if (token == 
"bbcore_write") {
 
  135                 found_bbcore_write = 
true;
 
  139     if (!found_bbcore_read) {
 
  140         error_message_no_bbcore_read_write
 
  141             << 
"\"bbcore_read\" function not defined in any VERBATIM block\n";
 
  143     if (!found_bbcore_write) {
 
  144         error_message_no_bbcore_read_write
 
  145             << 
"\"bbcore_write\" function not defined in any VERBATIM block\n";
 
  147     return error_message_no_bbcore_read_write.str();
 
  157     std::vector<ast::AstNodeType> unhandled_ast_types;
 
  160         unhandled_ast_types.push_back(node_type);
 
  162     const auto& unhandled_ast_nodes = 
collect_nodes(node, unhandled_ast_types);
 
  164     std::ostringstream ss;
 
  165     for (
const auto& it: unhandled_ast_nodes) {
 
  166         auto node_type = it->get_node_type();
 
  167         ss << (this->*unhandled_ast_types_func.find(node_type)->second)(node, it);
 
  169     if (!ss.str().empty()) {
 
  170         logger->error(
"Code incompatibility detected");
 
  171         logger->error(
"Cannot translate mod file to .cpp file");
 
  172         logger->error(
"Fix the following errors and try again");
 
  174         std::istringstream ss_stringstream(ss.str());
 
  175         while (std::getline(ss_stringstream, line)) {
 
  177                 logger->error(fmt::format(
"Code Incompatibility :: {}", line));