|
User Guide
|
Go to the documentation of this file.
20 using visitor::RenameVisitor;
30 return optimize_ion_variable_copies() && info.ion_has_write_variable();
37 for (
const auto& param: params) {
43 str += fmt::format(
"{}{} {}{}",
55 auto parameters = node->get_parameters();
56 return std::any_of(parameters.begin(),
58 [&name](
const decltype(*parameters.begin()) arg) {
59 return arg->get_node_name() == name;
83 if (expression->is_solve_block()) {
86 if (expression->is_initial_block()) {
95 if (net_receive_required() && !info.artificial_cell) {
96 if (info.net_event_used || info.net_send_used || info.is_watch_used()) {
105 return info.point_process && !info.artificial_cell && info.net_receive_node !=
nullptr;
110 if (info.artificial_cell) {
113 return info.nrn_state_block !=
nullptr || breakpoint_exist();
118 return info.breakpoint_node !=
nullptr && !info.currents.empty();
123 return info.net_receive_node !=
nullptr;
128 return info.breakpoint_node !=
nullptr;
133 return net_receive_exist();
148 const auto&
function = program_symtab->lookup(name);
149 auto properties = NmodlType::function_block | NmodlType::procedure_block;
150 return function &&
function->has_any_property(properties);
154 return codegen_float_variables.size();
159 const auto count_semantics = [](
int sum,
const IndexSemantics& sem) {
return sum += sem.size; };
160 return std::accumulate(info.semantics.begin(), info.semantics.end(), 0, count_semantics);
204 if (expression->is_statement_block()
205 || expression->is_eigen_newton_solver_block()
206 || expression->is_eigen_linear_solver_block()
207 || expression->is_solution_expression()
208 || expression->is_for_netcon()) {
224 if (optimize_ion_variable_copies()) {
225 return ion_read_statements_optimized(type);
227 std::vector<std::string> statements;
228 for (
const auto& ion: info.ions) {
229 auto name = ion.name;
230 for (
const auto& var: ion.reads) {
231 auto const iter = std::find(ion.implicit_reads.begin(), ion.implicit_reads.end(), var);
232 if (iter != ion.implicit_reads.end()) {
235 auto variable_names = read_ion_variable_name(var);
236 auto first = get_variable_name(variable_names.first);
237 auto second = get_variable_name(variable_names.second);
238 statements.push_back(fmt::format(
"{} = {};", first, second));
240 for (
const auto& var: ion.writes) {
241 if (ion.is_ionic_conc(var)) {
242 auto variables = read_ion_variable_name(var);
243 auto first = get_variable_name(variables.first);
244 auto second = get_variable_name(variables.second);
245 statements.push_back(fmt::format(
"{} = {};", first, second));
254 std::vector<std::string> statements;
255 for (
const auto& ion: info.ions) {
256 for (
const auto& var: ion.writes) {
257 if (ion.is_ionic_conc(var)) {
258 auto variables = read_ion_variable_name(var);
259 auto first =
"ionvar." + variables.first;
260 const auto& second = get_variable_name(variables.second);
261 statements.push_back(fmt::format(
"{} = {};", first, second));
270 std::vector<ShadowUseStatement> statements;
271 for (
const auto& ion: info.ions) {
272 std::string concentration;
273 auto name = ion.name;
274 for (
const auto& var: ion.writes) {
275 auto variable_names = write_ion_variable_name(var);
276 if (ion.is_ionic_current(var)) {
278 auto current = breakpoint_current(var);
279 auto lhs = variable_names.first;
281 auto rhs = get_variable_name(current);
282 if (info.point_process) {
284 rhs += fmt::format(
"*(1.e2/{})", area);
289 if (!ion.is_rev_potential(var)) {
292 auto lhs = variable_names.first;
294 auto rhs = get_variable_name(variable_names.second);
301 if (ion.is_intra_cell_conc(concentration)) {
303 }
else if (ion.is_extra_cell_conc(concentration)) {
307 throw std::logic_error(fmt::format(
"codegen error for {} ion", ion.name));
309 auto ion_type_name = fmt::format(
"{}_type", ion.name);
310 auto lhs = fmt::format(
"int {}", ion_type_name);
312 auto rhs = get_variable_name(ion_type_name);
314 auto statement = conc_write_statement(ion.name, concentration,
index);
330 if (statement.
op.empty() && statement.
rhs.empty()) {
331 auto text = statement.
lhs +
";";
336 auto lhs = get_variable_name(statement.
lhs);
337 auto text = fmt::format(
"{} {} {};", lhs, statement.
op, statement.
rhs);
351 auto breakpoint = info.breakpoint_node;
352 if (breakpoint ==
nullptr) {
355 auto symtab = breakpoint->get_statement_block()->get_symbol_table();
356 auto variables = symtab->get_variables_with_properties(NmodlType::local_var);
357 for (
const auto& var: variables) {
358 auto renamed_name = var->get_name();
359 auto original_name = var->get_original_name();
360 if (current == original_name) {
361 current = renamed_name;
374 std::string result(name);
375 if (ion_variable_struct_required()) {
376 if (info.is_ion_read_variable(name)) {
379 if (info.is_ion_write_variable(name)) {
380 result =
"ionvar." + name;
382 if (info.is_current(name)) {
383 result =
"ionvar." + name;
391 const std::string& name) {
397 const std::string& name) {
410 printer->fmt_line(
"static_assert(std::is_trivially_copy_constructible_v<{}>);",
412 printer->fmt_line(
"static_assert(std::is_trivially_move_constructible_v<{}>);",
414 printer->fmt_line(
"static_assert(std::is_trivially_copy_assignable_v<{}>);", global_struct());
415 printer->fmt_line(
"static_assert(std::is_trivially_move_assignable_v<{}>);", global_struct());
416 printer->fmt_line(
"static_assert(std::is_trivially_destructible_v<{}>);", global_struct());
421 printer->add_line(global_struct(),
' ', global_struct_instance(),
';');
430 auto get_renamed_random_function =
431 [&](
const std::string& name) -> std::pair<std::string, bool> {
435 return {name,
false};
437 std::string function_name;
438 bool is_random_function;
439 std::tie(function_name, is_random_function) = get_renamed_random_function(name);
441 if (defined_method(name)) {
442 function_name = method_name(name);
445 if (is_net_send(name)) {
446 print_net_send_call(node);
450 if (is_net_move(name)) {
451 print_net_move_call(node);
455 if (is_net_event(name)) {
456 print_net_event_call(node);
461 printer->add_text(function_name,
'(');
463 if (defined_method(name)) {
464 printer->add_text(internal_method_arguments());
465 if (!arguments.empty()) {
466 printer->add_text(
", ");
472 if (is_random_function && !arguments.empty()) {
473 printer->add_text(
"(nrnran123_State*)");
476 print_vector_elements(arguments,
", ");
477 printer->add_text(
')');
482 printer->add_line(
"#ifndef NRN_PRCELLSTATE");
483 printer->add_line(
"#define NRN_PRCELLSTATE 0");
484 printer->add_line(
"#endif");
489 auto variable_printer = [&](
const std::vector<SymbolType>& variables) {
490 for (
const auto& v: variables) {
491 auto name = v->get_name();
492 if (!info.point_process) {
493 name +=
"_" + info.mod_suffix;
496 name += fmt::format(
"[{}]", v->get_length());
498 printer->add_line(add_escape_quote(name),
",");
502 printer->add_newline(2);
503 printer->add_line(
"/** channel information */");
504 printer->fmt_line(
"static const char *{}[] = {{", get_channel_info_var_name());
505 printer->increase_indent();
506 printer->add_line(add_escape_quote(nmodl_version()),
",");
507 printer->add_line(add_escape_quote(info.mod_suffix),
",");
508 variable_printer(info.range_parameter_vars);
509 printer->add_line(
"0,");
510 variable_printer(info.range_assigned_vars);
511 printer->add_line(
"0,");
512 variable_printer(info.range_state_vars);
513 printer->add_line(
"0,");
514 variable_printer(info.pointer_variables);
515 printer->add_line(
"0");
516 printer->decrease_indent();
517 printer->add_line(
"};");
530 printer->push_block();
534 for (
const auto& statement: statements) {
535 if (statement_to_skip(*statement)) {
539 if (!statement->is_verbatim() && !statement->is_mutex_lock() &&
540 !statement->is_mutex_unlock() && !statement->is_protect_statement()) {
541 printer->add_indent();
543 statement->accept(*
this);
544 if (need_semicolon(*statement)) {
545 printer->add_text(
';');
547 if (!statement->is_mutex_lock() && !statement->is_mutex_unlock()) {
548 printer->add_newline();
553 printer->pop_block_nl(0);
567 for (
const auto& dirty_arg: default_arguments) {
570 for (
const auto&
function: info.functions) {
571 if (has_parameter_of_name(
function, arg)) {
575 for (
const auto&
function: info.procedures) {
576 if (has_parameter_of_name(
function, arg)) {
594 if (!info.factor_definitions.empty()) {
595 printer->add_newline(2);
596 printer->add_line(
"/** constants used in nmodl from UNITS */");
597 for (
const auto& it: info.factor_definitions) {
598 const std::string format_string =
"static const double {} = {};";
599 printer->fmt_line(format_string, it->get_node_name(), it->get_value()->get_value());
614 std::string name = node.
eval();
615 if (enable_variable_name_lookup) {
616 name = get_variable_name(name);
618 printer->add_text(name);
654 throw std::runtime_error(
"PRIME encountered during code generation, ODEs not solved?");
663 const auto& at_index = node.
get_at();
667 printer->add_text(
"@");
668 at_index->accept(*
this);
671 printer->add_text(
"[");
672 printer->add_text(
"static_cast<int>(");
673 index->accept(*
this);
674 printer->add_text(
")");
675 printer->add_text(
"]");
682 printer->add_text(
"[");
683 printer->add_text(
"static_cast<int>(");
685 printer->add_text(
")");
686 printer->add_text(
"]");
691 printer->add_text(local_var_type(),
' ');
697 printer->add_text(
"if (");
699 printer->add_text(
") ");
704 elses->accept(*
this);
710 printer->add_text(
" else if (");
712 printer->add_text(
") ");
718 printer->add_text(
" else ");
724 printer->add_text(
"while (");
726 printer->add_text(
") ");
734 const auto& to = node.
get_to();
737 printer->fmt_text(
"for (int {} = ", name);
739 printer->fmt_text(
"; {} <= ", name);
742 printer->fmt_text(
"; {} += ", name);
745 printer->fmt_text(
"; {}++", name);
747 printer->add_text(
") ");
748 block->accept(*
this);
753 printer->add_text(
"(");
755 printer->add_text(
")");
761 const auto& lhs = node.
get_lhs();
762 const auto& rhs = node.
get_rhs();
764 printer->add_text(
"pow(");
766 printer->add_text(
", ");
768 printer->add_text(
")");
771 printer->add_text(
" " + op +
" ");
778 printer->add_text(node.
eval());
783 printer->add_text(
" " + node.
eval());
793 print_statement_block(node);
798 print_function_call(node);
804 const auto& result = process_verbatim_text(text);
807 for (
const auto& statement: statements) {
809 if (trimed_stmt.find_first_not_of(
' ') != std::string::npos) {
810 printer->add_line(trimed_stmt);
822 print_atomic_reduction_pragma();
823 printer->add_indent();
825 printer->add_text(
";");
830 printer->fmt_line(
"#pragma omp critical ({})", info.mod_suffix);
831 printer->add_indent();
832 printer->push_block();
837 printer->pop_block();
843 if (block->is_statement_block()) {
845 print_statement_block(*statement_block,
false,
false);
847 block->accept(*
this);
858 info.semantics.clear();
860 if (info.point_process) {
864 for (
const auto& ion: info.ions) {
865 for (
auto i = 0; i < ion.reads.size(); ++i) {
866 info.semantics.emplace_back(
index++, ion.name +
"_ion", 1);
868 for (
const auto& var: ion.writes) {
870 if (std::find(ion.reads.begin(), ion.reads.end(), var) == ion.reads.end()) {
871 info.semantics.emplace_back(
index++, ion.name +
"_ion", 1);
873 if (ion.is_ionic_current(var)) {
874 info.semantics.emplace_back(
index++, ion.name +
"_ion", 1);
877 if (ion.need_style) {
878 info.semantics.emplace_back(
index++, fmt::format(
"{}_ion", ion.name), 1);
879 info.semantics.emplace_back(
index++, fmt::format(
"#{}_ion", ion.name), 1);
882 for (
auto& var: info.pointer_variables) {
883 if (info.first_pointer_var_index == -1) {
884 info.first_pointer_var_index =
index;
886 int size = var->get_length();
887 if (var->has_any_property(NmodlType::pointer_var)) {
895 for (
auto& var: info.random_variables) {
896 if (info.first_random_var_index == -1) {
897 info.first_random_var_index =
index;
899 int size = var->get_length();
904 if (info.diam_used) {
908 if (info.area_used) {
912 if (info.net_send_used) {
920 if (!info.watch_statements.empty()) {
921 for (
int i = 0; i < info.watch_statements.size() + 1; i++) {
926 if (info.for_netcon_used) {
935 return first->get_definition_order() < second->get_definition_order();
938 auto assigned = info.assigned_vars;
939 auto states = info.state_vars;
942 for (
const auto& state: states) {
943 auto name =
"D" + state->get_name();
944 auto symbol = make_symbol(name);
945 if (state->is_array()) {
946 symbol->set_as_array(state->get_length());
948 symbol->set_definition_order(state->get_definition_order());
949 assigned.push_back(symbol);
951 std::sort(assigned.begin(), assigned.end(), comparator);
953 auto variables = info.range_parameter_vars;
954 variables.insert(variables.end(),
955 info.range_assigned_vars.begin(),
956 info.range_assigned_vars.end());
957 variables.insert(variables.end(), info.range_state_vars.begin(), info.range_state_vars.end());
958 variables.insert(variables.end(), assigned.begin(), assigned.end());
960 if (info.vectorize) {
964 if (breakpoint_exist()) {
969 if (
auto r = std::find_if(variables.cbegin(),
971 [&](
const auto& s) { return name == s->get_name(); });
972 r == variables.cend()) {
973 variables.push_back(make_symbol(name));
977 if (net_receive_exist()) {
999 std::vector<IndexVariableInfo> variables;
1000 if (info.point_process) {
1002 variables.back().is_constant =
true;
1004 if (info.artificial_cell) {
1008 variables.back().is_constant =
true;
1012 for (
auto& ion: info.ions) {
1013 bool need_style =
false;
1014 std::unordered_map<std::string, int> ion_vars;
1018 auto const has_var = [&ion](
const char* suffix) ->
bool {
1019 auto const pred = [name = ion.name + suffix](
auto const& x) {
return x == name; };
1020 return std::any_of(ion.reads.begin(), ion.reads.end(), pred) ||
1021 std::any_of(ion.writes.begin(), ion.writes.end(), pred);
1023 auto const add_implicit_read = [&ion](
const char* suffix) {
1024 auto name = ion.name + suffix;
1025 ion.reads.push_back(name);
1026 ion.implicit_reads.push_back(std::move(name));
1028 bool const have_ionin{has_var(
"i")}, have_ionout{has_var(
"o")};
1029 if (have_ionin && !have_ionout) {
1030 add_implicit_read(
"o");
1031 }
else if (have_ionout && !have_ionin) {
1032 add_implicit_read(
"i");
1034 for (
const auto& var: ion.reads) {
1036 variables.emplace_back(make_symbol(name));
1037 variables.back().is_constant =
true;
1038 ion_vars[name] =
static_cast<int>(variables.size() - 1);
1042 std::shared_ptr<symtab::Symbol> ion_di_dv_var =
nullptr;
1044 for (
const auto& var: ion.writes) {
1047 const auto ion_vars_it = ion_vars.find(name);
1048 if (ion_vars_it != ion_vars.end()) {
1049 variables[ion_vars_it->second].is_constant =
false;
1053 if (ion.is_ionic_current(var)) {
1057 if (ion.is_intra_cell_conc(var) || ion.is_extra_cell_conc(var)) {
1063 if (ion_di_dv_var !=
nullptr) {
1064 variables.emplace_back(ion_di_dv_var);
1069 variables.emplace_back(make_symbol(
"style_" + ion.name),
false,
true);
1070 variables.back().is_constant =
true;
1074 for (
const auto& var: info.pointer_variables) {
1075 auto name = var->get_name();
1076 if (var->has_any_property(NmodlType::pointer_var)) {
1077 variables.emplace_back(make_symbol(name));
1079 variables.emplace_back(make_symbol(name),
true);
1083 for (
const auto& var: info.random_variables) {
1084 auto name = var->get_name();
1085 variables.emplace_back(make_symbol(name),
true);
1086 variables.back().symbol->add_properties(NmodlType::random_var);
1089 if (info.diam_used) {
1093 if (info.area_used) {
1099 if (info.net_send_used) {
1100 if (info.artificial_cell) {
1104 variables.back().is_constant =
true;
1106 info.tqitem_index =
static_cast<int>(variables.size() - 1);
1114 if (!info.watch_statements.empty()) {
1115 for (
int i = 0; i < info.watch_statements.size() + 1; i++) {
1116 variables.emplace_back(make_symbol(fmt::format(
"watch{}", i)),
false,
false,
true);
1130 if (!info.vectorize) {
1132 "CodegenCoreneuronCppVisitor : MOD file uses non-thread safe constructs of NMODL");
1135 codegen_float_variables = get_float_variables();
1136 codegen_int_variables = get_int_variables();
1138 update_index_semantics();
1139 rename_function_arguments();
1141 info.semantic_variable_count = int_variables_size();
1163 throw std::logic_error(
"compute_method_name not implemented");
1169 print_codegen_routines();
std::string get_node_name() const override
Return name of the node.
std::shared_ptr< Expression > get_length() const noexcept
Getter for member variable IndexedName::length.
bool ion_variable_struct_required() const
Check if a structure for ion variables is required.
static bool need_semicolon(const ast::Statement &node)
Check if a semicolon is required at the end of given statement.
void update_index_semantics()
populate all index semantics needed for registration with coreneuron
std::string format_double_string< CodegenCppVisitor >(const std::string &s_value)
const LocalVarVector & get_variables() const noexcept
Getter for member variable LocalListStatement::variables.
static constexpr char RANDOM_SEMANTIC[]
semantic type for RANDOM variable
Represents a C code block.
static constexpr char NET_SEND_SEMANTIC[]
semantic type for net send call
void visit_name(const ast::Name &node) override
visit node of type ast::Name
bool has_parameter_of_name(const T &node, const std::string &name)
Check if function or procedure node has parameter with given name.
int int_variables_size() const
Number of integer variables in the model.
void visit_children(visitor::Visitor &v) override
visit children i.e.
void visit_if_statement(const ast::IfStatement &node) override
visit node of type ast::IfStatement
std::vector< ShadowUseStatement > ion_write_statements(BlockType type)
For a given output block type, return statements for writing back ion variables.
void visit_else_statement(const ast::ElseStatement &node) override
visit node of type ast::ElseStatement
bool breakpoint_exist() const noexcept
Check if breakpoint node exist.
@ Destructor
destructor block
Represents a double variable.
static std::pair< std::string, std::string > write_ion_variable_name(const std::string &name)
Return ion variable name and corresponding ion write variable name.
static constexpr char POINT_PROCESS_VARIABLE[]
inbuilt neuron variable for point process
bool net_receive_exist() const noexcept
Check if net_receive node exist.
std::shared_ptr< symtab::Symbol > SymbolType
static constexpr char VOLTAGE_UNUSED_VARIABLE[]
range variable for voltage when unused (for vectorized model)
static constexpr char NRN_WATCH_CHECK_METHOD[]
nrn_watch_check method in generated c++ file
virtual bool is_conductance_hint() const noexcept
Check if the ast node is an instance of ast::ConductanceHint.
int float_variables_size() const
Number of float variables in the model.
void visit_from_statement(const ast::FromStatement &node) override
visit node of type ast::FromStatement
virtual void print_global_var_struct_assertions() const
Print static assertions about the global variable struct.
void print_mechanism_info()
Print backend code for byte array that has mechanism information (to be registered with NEURON/CoreNE...
void visit_prime_name(const ast::PrimeName &node) override
visit node of type ast::PrimeName
encapsulates code generation backend implementations
@ index
index / int variables
static constexpr char NRN_CONSTRUCTOR_METHOD[]
nrn_constructor method in generated code
std::string format_float_string< CodegenCppVisitor >(const std::string &s_value)
int get_value() const noexcept
Getter for member variable Integer::value.
std::shared_ptr< Identifier > get_name() const noexcept
Getter for member variable IndexedName::name.
bool range_variable_setup_required() const noexcept
Check if setup_range_variable function is required.
Represent MUTEXLOCK statement in NMODL.
void print_statement_block(const ast::StatementBlock &node, bool open_brace=true, bool close_brace=true)
Print any statement block in nmodl with option to (not) print braces.
const std::string & get_value() const noexcept
Getter for member variable Double::value.
virtual bool is_protect_statement() const noexcept
Check if the ast node is an instance of ast::ProtectStatement.
void visit_binary_expression(const ast::BinaryExpression &node) override
visit node of type ast::BinaryExpression
Represents an integer variable.
std::vector< SymbolType > get_float_variables() const
Determine all float variables required during code generation.
virtual bool is_expression_statement() const noexcept
Check if the ast node is an instance of ast::ExpressionStatement.
static constexpr char NODE_AREA_VARIABLE[]
inbuilt neuron variable for area of the compartment
void visit_paren_expression(const ast::ParenExpression &node) override
visit node of type ast::ParenExpression
bool net_receive_buffering_required() const noexcept
Check if net receive/send buffering kernels required.
std::string update_if_ion_variable_name(const std::string &name) const
Determine the updated name if the ion variable has been optimized.
void visit_children(visitor::Visitor &v) override
visit children i.e.
std::shared_ptr< Expression > get_index() const noexcept
Getter for member variable VarName::index.
void visit_mutex_unlock(const ast::MutexUnlock &node) override
visit node of type ast::MutexUnlock
std::shared_ptr< String > get_statement() const noexcept
Getter for member variable Verbatim::statement.
void visit_unit(const ast::Unit &node) override
visit node of type ast::Unit
std::shared_ptr< Expression > get_rhs() const noexcept
Getter for member variable BinaryExpression::rhs.
bool eval() const
Return value of the ast node.
void visit_update_dt(const ast::UpdateDt &node) override
visit node of type ast::UpdateDt
Helper visitor to gather AST information to help code generation.
std::shared_ptr< Expression > get_increment() const noexcept
Getter for member variable FromStatement::increment.
static constexpr char CONDUCTANCE_VARIABLE[]
range variable for conductance
std::shared_ptr< Integer > get_at() const noexcept
Getter for member variable VarName::at.
static std::string trim_newline(std::string text)
static constexpr char DEFAULT_FLOAT_TYPE[]
default float variable type
std::vector< IndexVariableInfo > get_int_variables()
Determine all int variables required during code generation.
Visitor for printing C++ code compatible with legacy api of CoreNEURON
const StatementVector & get_statements() const noexcept
Getter for member variable StatementBlock::statements.
void visit_function_call(const ast::FunctionCall &node) override
visit node of type ast::FunctionCall
const ElseIfStatementVector & get_elseifs() const noexcept
Getter for member variable IfStatement::elseifs.
virtual bool is_mutex_lock() const noexcept
Check if the ast node is an instance of ast::MutexLock.
std::shared_ptr< Expression > get_condition() const noexcept
Getter for member variable IfStatement::condition.
virtual bool is_if_statement() const noexcept
Check if the ast node is an instance of ast::IfStatement.
static std::string trim(std::string text)
Utility functions for visitors implementation.
@ Equation
breakpoint block
const std::string & get_value() const noexcept
Getter for member variable Float::value.
Represents a float variable.
virtual bool is_verbatim() const noexcept
Check if the ast node is an instance of ast::Verbatim.
Represents specific element of an array variable.
std::string eval() const
Return value of the ast node.
const std::regex regex_special_chars
std::shared_ptr< Expression > get_from() const noexcept
Getter for member variable FromStatement::from.
void setup(const ast::Program &node)
Setup the target backend code generator.
void visit_unary_operator(const ast::UnaryOperator &node) override
visit node of type ast::UnaryOperator
static constexpr char POINT_PROCESS_SEMANTIC[]
semantic type for point process variable
void visit_mutex_lock(const ast::MutexLock &node) override
visit node of type ast::MutexLock
void visit_boolean(const ast::Boolean &node) override
visit node of type ast::Boolean
virtual bool is_else_if_statement() const noexcept
Check if the ast node is an instance of ast::ElseIfStatement.
bool nrn_cur_required() const noexcept
Check if nrn_cur function is required.
virtual bool is_table_statement() const noexcept
Check if the ast node is an instance of ast::TableStatement.
std::vector< std::string > ion_read_statements_optimized(BlockType type) const
For a given output block type, return minimal statements for all read ion variables.
@ Constructor
constructor block
Represent MUTEXUNLOCK statement in NMODL.
void visit_double(const ast::Double &node) override
visit node of type ast::Double
bool net_send_buffer_required() const noexcept
Check if net_send_buffer is required.
void visit_float(const ast::Float &node) override
visit node of type ast::Float
void visit_string(const ast::String &node) override
visit node of type ast::String
Represent semantic information for index variable.
std::string to_string(const T &obj)
virtual bool is_block_comment() const noexcept
Check if the ast node is an instance of ast::BlockComment.
std::string format_float_string(const std::string &s_value)
Handles the float constants format being printed in the generated code.
void visit_solution_expression(const ast::SolutionExpression &node) override
visit node of type ast::SolutionExpression
static constexpr char NRN_INIT_METHOD[]
nrn_init method in generated code
const ExpressionVector & get_arguments() const noexcept
Getter for member variable FunctionCall::arguments.
static constexpr char POINTER_SEMANTIC[]
semantic type for pointer variable
virtual void print_global_var_struct_decl()
Instantiate global var instance.
static constexpr char AREA_SEMANTIC[]
semantic type for area variable
void visit_var_name(const ast::VarName &node) override
std::string mod_file
name of mod file
void print_nmodl_constants()
Print the nmodl constants used in backend code.
std::shared_ptr< Expression > get_expression() const noexcept
Getter for member variable ParenExpression::expression.
const BinaryOperator & get_op() const noexcept
Getter for member variable BinaryExpression::op.
virtual bool is_from_statement() const noexcept
Check if the ast node is an instance of ast::FromStatement.
Represents a prime variable (for ODE)
static std::pair< std::string, std::string > read_ion_variable_name(const std::string &name)
Return ion variable name and corresponding ion read variable name.
std::shared_ptr< StatementBlock > get_statement_block() const noexcept override
Getter for member variable ElseIfStatement::statement_block.
Blindly rename given variable to new name
static constexpr char NRN_CUR_METHOD[]
nrn_cur method in generated code
std::string eval() const
Return enum value in string form.
static std::unordered_map< std::string, std::string > RANDOM_FUNCTIONS_MAPPING
Implement utility functions for codegen visitors.
static constexpr char TQITEM_VARIABLE[]
inbuilt neuron variable for tqitem process
Represents a boolean variable.
std::string eval() const
Return enum value in string form.
virtual bool is_mutex_unlock() const noexcept
Check if the ast node is an instance of ast::MutexUnlock.
codegen::CodegenInfo analyze(const ast::Program &node)
run visitor and return information for code generation
std::shared_ptr< StatementBlock > get_statement_block() const noexcept override
Getter for member variable WhileStatement::statement_block.
void visit_integer(const ast::Integer &node) override
visit node of type ast::Integer
Statement to indicate a change in timestep in a given block.
std::string format_float_string(const std::string &value)
Convert a given float value to its string representation.
std::shared_ptr< Expression > get_node_to_solve() const noexcept
Getter for member variable SolutionExpression::node_to_solve.
static std::vector< std::string > split_string(const std::string &text, char delimiter)
Split a text in a list of words, using a given delimiter character.
static std::string get_parameter_str(const ParamVector ¶ms)
Generate the string representing the procedure parameter declaration.
std::shared_ptr< StatementBlock > get_statement_block() const noexcept override
Getter for member variable IfStatement::statement_block.
Represents block encapsulating list of statements.
virtual bool is_unit_state() const noexcept
Check if the ast node is an instance of ast::UnitState.
NmodlType
NMODL variable properties.
bool net_receive_required() const noexcept
Check if net_receive function is required.
static constexpr char CORE_POINTER_SEMANTIC[]
semantic type for core pointer variable
void rename_function_arguments()
Rename function/procedure arguments that conflict with default arguments.
void visit_local_list_statement(const ast::LocalListStatement &node) override
visit node of type ast::LocalListStatement
void visit_protect_statement(const ast::ProtectStatement &node) override
visit node of type ast::ProtectStatement
Represents ion write statement during code generation.
static constexpr char WATCH_SEMANTIC[]
semantic type for watch statement
Operator used in ast::BinaryExpression.
bool defined_method(const std::string &name) const
Check if given method is defined in this model.
std::shared_ptr< Expression > get_condition() const noexcept
Getter for member variable ElseIfStatement::condition.
virtual void print_function_call(const ast::FunctionCall &node)
Print call to internal or external function.
Represent solution of a block in the AST.
std::string process_shadow_update_statement(const ShadowUseStatement &statement, BlockType type)
Process shadow update statement.
Helper visitor to gather AST information to help code generation.
BlockType
Helper to represent various block types.
std::shared_ptr< Identifier > get_name() const noexcept
Getter for member variable VarName::name.
symtab::SymbolTable * get_symbol_table() const override
Return associated symbol table for the current ast node.
static constexpr char NRN_STATE_METHOD[]
nrn_state method in generated code
std::string breakpoint_current(std::string current) const
Determine the variable name for the "current" used in breakpoint block taking into account intermedia...
void visit_binary_operator(const ast::BinaryOperator &node) override
visit node of type ast::BinaryOperator
virtual bool is_solve_block() const noexcept
Check if the ast node is an instance of ast::SolveBlock.
void visit_else_if_statement(const ast::ElseIfStatement &node) override
visit node of type ast::ElseIfStatement
std::shared_ptr< ElseStatement > get_elses() const noexcept
Getter for member variable IfStatement::elses.
std::shared_ptr< Expression > get_lhs() const noexcept
Getter for member variable BinaryExpression::lhs.
virtual bool is_line_comment() const noexcept
Check if the ast node is an instance of ast::LineComment.
std::string compute_method_name(BlockType type) const
static constexpr char AREA_VARIABLE[]
similar to node_area but user can explicitly declare it as area
virtual bool is_while_statement() const noexcept
Check if the ast node is an instance of ast::WhileStatement.
void visit_program(const ast::Program &program) override
Main and only member function to call after creating an instance of this class.
virtual bool is_else_statement() const noexcept
Check if the ast node is an instance of ast::ElseStatement.
std::shared_ptr< StatementBlock > get_statement_block() const noexcept override
Getter for member variable FromStatement::statement_block.
Represents top level AST node for whole NMODL input.
void visit_indexed_name(const ast::IndexedName &node) override
visit node of type ast::IndexedName
std::shared_ptr< Expression > get_to() const noexcept
Getter for member variable FromStatement::to.
static constexpr char T_SAVE_VARIABLE[]
variable t indicating last execution time of net receive block
void print_prcellstate_macros() const
Print declaration of macro NRN_PRCELLSTATE for debugging.
static constexpr char FOR_NETCON_SEMANTIC[]
semantic type for for_netcon statement
std::string format_double_string(const std::string &s_value)
Handles the double constants format being printed in the generated code.
Blindly rename given variable to new name
bool nrn_state_required() const noexcept
Check if nrn_state function is required.
static constexpr char DIAM_VARIABLE[]
inbuilt neuron variable for diameter of the compartment
void visit_verbatim(const ast::Verbatim &node) override
visit node of type ast::Verbatim
Represents binary expression in the NMODL.
static constexpr char NRN_DESTRUCTOR_METHOD[]
nrn_destructor method in generated code
static constexpr char CONDUCTANCE_UNUSED_VARIABLE[]
range variable when conductance is not used (for vectorized model)
static bool statement_to_skip(const ast::Statement &node)
Check if given statement should be skipped during code generation.
std::vector< std::string > ion_read_statements(BlockType type) const
For a given output block type, return statements for all read ion variables.
std::string format_double_string(const std::string &value)
Convert a given double value to its string representation.
std::shared_ptr< Expression > get_expression() const noexcept
Getter for member variable ProtectStatement::expression.
Auto generated AST classes declaration.
std::string get_node_name() const override
Return name of the node.
void visit_while_statement(const ast::WhileStatement &node) override
visit node of type ast::WhileStatement
std::vector< std::tuple< std::string, std::string, std::string, std::string > > ParamVector
A vector of parameters represented by a 4-tuple of strings:
static constexpr char ION_VARNAME_PREFIX[]
prefix for ion variable
std::shared_ptr< Expression > get_condition() const noexcept
Getter for member variable WhileStatement::condition.
void visit_statement_block(const ast::StatementBlock &node) override