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));