User Guide
codegen_cpp_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  * \dir
12  * \brief Code generation backend implementations for CoreNEURON
13  *
14  * \file
15  * \brief \copybrief nmodl::codegen::CodegenCppVisitor
16  */
17 
18 #include <algorithm>
19 #include <cmath>
20 #include <ctime>
21 #include <numeric>
22 #include <ostream>
23 #include <string>
24 #include <string_view>
25 #include <utility>
26 
27 #include "codegen/codegen_info.hpp"
29 #include "printer/code_printer.hpp"
30 #include "symtab/symbol_table.hpp"
31 #include "utils/logger.hpp"
32 #include "visitors/ast_visitor.hpp"
33 
34 /// encapsulates code generation backend implementations
35 namespace nmodl {
36 
37 namespace codegen {
38 
39 /**
40  * \defgroup codegen Code Generation Implementation
41  * \brief Implementations of code generation backends
42  *
43  * \defgroup codegen_details Codegen Helpers
44  * \ingroup codegen
45  * \brief Helper routines/types for code generation
46  * \{
47  */
48 
49 /**
50  * \enum BlockType
51  * \brief Helper to represent various block types
52  *
53  * Note: do not assign integers to these enums
54  *
55  */
56 enum class BlockType {
57  /// initial block
58  Initial,
59 
60  /// constructor block
62 
63  /// destructor block
64  Destructor,
65 
66  /// breakpoint block
67  Equation,
68 
69  /// derivative block
70  State,
71 
72  /// watch block
73  Watch,
74 
75  /// net_receive block
76  NetReceive,
77 
78  /// before / after block
80 
81  /// fake ending block type for loops on the enums. Keep it at the end
83 };
84 
85 
86 /**
87  * \enum MemberType
88  * \brief Helper to represent various variables types
89  *
90  */
91 enum class MemberType {
92  /// index / int variables
93  index,
94 
95  /// range / double variables
96  range,
97 
98  /// global variables
99  global,
100 
101  /// thread variables
102  thread
103 };
104 
105 
106 /// various specifiers (mostly for function codegen)
107 enum class CppObjectSpecifier {
108  Inline,
109  Static,
110  Virtual,
111  Explicit,
112  Friend,
113  Constexpr,
114  Extern,
115  ExternC,
116  ThreadLocal,
117  Const,
118  Volatile
119 };
120 
121 
122 /**
123  * \class IndexVariableInfo
124  * \brief Helper to represent information about index/int variables
125  *
126  */
128  /// symbol for the variable
129  const std::shared_ptr<symtab::Symbol> symbol;
130 
131  /// if variable resides in vdata field of NrnThread
132  /// typically true for bbcore pointer
133  bool is_vdata = false;
134 
135  /// if this is pure index (e.g. style_ion) variables is directly
136  /// index and shouldn't be printed with data/vdata
137  bool is_index = false;
138 
139  /// if this is an integer (e.g. tqitem, point_process) variable which
140  /// is printed as array accesses
141  bool is_integer = false;
142 
143  /// if the variable is qualified as constant (this is property of IndexVariable)
144  bool is_constant = false;
145 
146  explicit IndexVariableInfo(std::shared_ptr<symtab::Symbol> symbol,
147  bool is_vdata = false,
148  bool is_index = false,
149  bool is_integer = false)
150  : symbol(std::move(symbol))
151  , is_vdata(is_vdata)
152  , is_index(is_index)
153  , is_integer(is_integer) {}
154 };
155 
156 
157 /**
158  * \class ShadowUseStatement
159  * \brief Represents ion write statement during code generation
160  *
161  * Ion update statement needs use of shadow vectors for certain backends
162  * as atomics operations are not supported on cpu backend.
163  *
164  * \todo If shadow_lhs is empty then we assume shadow statement not required
165  */
167  std::string lhs;
168  std::string op;
169  std::string rhs;
170 };
171 
172 inline std::string get_name(ast::Ast const* sym) {
173  return sym->get_node_name();
174 }
175 
176 inline std::string get_name(const std::shared_ptr<symtab::Symbol>& sym) {
177  return sym->get_name();
178 }
179 
180 inline std::string get_name(const IndexVariableInfo& var) {
181  return var.symbol->get_name();
182 }
183 
184 template <class T>
185 int get_index_from_name(const std::vector<T>& variables, const std::string& name) {
186  auto it = std::find_if(variables.cbegin(), variables.cend(), [&name](const auto& var) {
187  return get_name(var) == name;
188  });
189 
190  if (it == variables.cend()) {
191  throw std::runtime_error(fmt::format("Unknown variable: {}", name));
192  }
193 
194  return static_cast<int>(it - variables.cbegin());
195 }
196 
197 inline int get_length(const std::shared_ptr<symtab::Symbol>& sym) {
198  return sym->get_length();
199 }
200 
201 inline int get_length(const IndexVariableInfo& var) {
202  return var.symbol->get_length();
203 }
204 
205 template <class T>
206 int get_prefixsum_from_name(const std::vector<T>& variables, const std::string& name) {
207  int index = 0;
208  for (const auto& var: variables) {
209  if (get_name(var) == name) {
210  return index;
211  }
212  index += get_length(var);
213  }
214  throw std::logic_error(name + " variable not found");
215 }
216 
217 /** \} */ // end of codegen_details
218 
219 
221 
222 
223 /**
224  * \defgroup codegen_backends Codegen Backends
225  * \ingroup codegen
226  * \brief Code generation backends for CoreNEURON
227  * \{
228  */
229 
230 /**
231  * \class CodegenCppVisitor
232  * \brief %Visitor for printing C++ code compatible with legacy api of CoreNEURON
233  *
234  * \todo
235  * - Handle define statement (i.e. macros)
236  * - If there is a return statement in the verbatim block
237  * of inlined function then it will be error. Need better
238  * error checking. For example, see netstim.mod where we
239  * have removed return from verbatim block.
240  */
242  public:
243  /**
244  * \brief Constructs the C++ code generator visitor
245  *
246  * This constructor instantiates an NMODL C++ code generator and allows writing generated code
247  * into an output stream.
248  *
249  * \note No code generation is performed at this stage. Since the code
250  * generator classes are all based on \c AstVisitor the AST must be visited using e.g. \c
251  * visit_program in order to generate the C++ code corresponding to the AST.
252  *
253  * \param mod_filename The name of the model for which code should be generated.
254  * It is used for constructing an output filename.
255  * \param stream The output stream onto which to write the generated code
256  * \param float_type The float type to use in the generated code. The string will be used
257  * as-is in the target code. This defaults to \c double.
258  */
260  std::ostream& stream,
261  std::string float_type,
262  const bool optimize_ionvar_copies,
263  std::unique_ptr<nmodl::utils::Blame> blame = nullptr)
264  : printer(std::make_unique<CodePrinter>(stream, std::move(blame)))
265  , mod_filename(std::move(mod_filename))
266  , float_type(std::move(float_type))
268 
270  std::ostream& stream,
271  std::string float_type,
272  const bool optimize_ionvar_copies,
273  const bool enable_cvode,
274  std::unique_ptr<nmodl::utils::Blame> blame = nullptr)
275  : printer(std::make_unique<CodePrinter>(stream, std::move(blame)))
276  , mod_filename(std::move(mod_filename))
277  , float_type(std::move(float_type))
280 
281  private:
282  bool enable_cvode = false;
283 
284  protected:
285  using SymbolType = std::shared_ptr<symtab::Symbol>;
286 
287 
288  /**
289  * A vector of parameters represented by a 4-tuple of strings:
290  *
291  * - type qualifier (e.g. \c const)
292  * - type (e.g. \c double)
293  * - pointer qualifier (e.g. \c \_\_restrict\_\_)
294  * - parameter name (e.g. \c data)
295  *
296  */
297  using ParamVector = std::vector<std::tuple<std::string, std::string, std::string, std::string>>;
298 
299 
300  /****************************************************************************************/
301  /* Member variables */
302  /****************************************************************************************/
303 
304  /**
305  * Code printer object for target (C++)
306  */
307  std::unique_ptr<CodePrinter> printer;
308 
309 
310  /**
311  * Name of mod file (without .mod suffix)
312  */
313  std::string mod_filename;
314 
315 
316  /**
317  * Data type of floating point variables
318  */
320 
321 
322  /**
323  * Flag to indicate if visitor should avoid ion variable copies
324  */
326 
327 
328  /**
329  * All ast information for code generation
330  */
332 
333 
334  /**
335  * Symbol table for the program
336  */
338 
339 
340  /**
341  * All float variables for the model
342  */
343  std::vector<SymbolType> codegen_float_variables;
344 
345 
346  /**
347  * All int variables for the model
348  */
349  std::vector<IndexVariableInfo> codegen_int_variables;
350 
351 
352  /**
353  * All global variables for the model
354  * \todo: this has become different than CodegenInfo
355  */
356  std::vector<SymbolType> codegen_global_variables;
357 
358 
359  /**
360  * Variable name should be converted to instance name (but not for function arguments)
361  */
363 
364 
365  /**
366  * \c true if currently net_receive block being printed
367  */
368  bool printing_net_receive = false;
369 
370 
371  /**
372  * \c true if currently initial block of net_receive being printed
373  */
374  bool printing_net_init = false;
375 
376 
377  /**
378  * \c true if currently printing top level verbatim blocks
379  */
381 
382 
383  /**
384  * \c true if internal method call was encountered while processing verbatim block
385  */
387 
388 
389  /**
390  * Index of watch statement being printed
391  */
393 
394 
395  /****************************************************************************************/
396  /* Generic information getters */
397  /****************************************************************************************/
398 
399  /**
400  * Return Nmodl language version
401  * \return A version
402  */
403  std::string nmodl_version() const noexcept {
405  }
406 
407 
408  /**
409  * Name of the simulator the code was generated for
410  */
411  virtual std::string simulator_name() = 0;
412 
413 
414  /**
415  * Name of structure that wraps range variables
416  */
417  std::string instance_struct() const {
418  return fmt::format("{}_Instance", info.mod_suffix);
419  }
420 
421  /**
422  * Name of structure that wraps node variables
423  */
424  std::string node_data_struct() const {
425  return fmt::format("{}_NodeData", info.mod_suffix);
426  }
427 
428  std::string thread_variables_struct() const {
429  return fmt::format("{}_ThreadVariables", info.mod_suffix);
430  }
431 
432 
433  /**
434  * Name of structure that wraps global variables
435  */
436  std::string global_struct() const {
437  return fmt::format("{}_Store", info.mod_suffix);
438  }
439 
440 
441  /**
442  * Name of the (host-only) global instance of `global_struct`
443  */
444  std::string global_struct_instance() const {
445  return info.mod_suffix + "_global";
446  }
447 
448 
449  /**
450  * Name of the code generation backend
451  */
452  virtual std::string backend_name() const = 0;
453 
454 
455  /**
456  * Data type for the local variables
457  */
458  const char* local_var_type() const noexcept {
460  }
461 
462 
463  /**
464  * Check if a semicolon is required at the end of given statement
465  * \param node The AST Statement node to check
466  * \return \c true if this Statement requires a semicolon
467  */
468  static bool need_semicolon(const ast::Statement& node);
469 
470 
471  /**
472  * Default data type for floating point elements
473  */
474  const char* default_float_data_type() const noexcept {
476  }
477 
478 
479  /**
480  * Data type for floating point elements specified on command line
481  */
482  const std::string& float_data_type() const noexcept {
483  return float_type;
484  }
485 
486 
487  /**
488  * Default data type for integer (offset) elements
489  */
490  const char* default_int_data_type() const noexcept {
492  }
493 
494 
495  /**
496  * Operator for rhs vector update (matrix update)
497  */
498  const char* operator_for_rhs() const noexcept {
499  return info.electrode_current ? "+=" : "-=";
500  }
501 
502 
503  /**
504  * Operator for diagonal vector update (matrix update)
505  */
506  const char* operator_for_d() const noexcept {
507  return info.electrode_current ? "-=" : "+=";
508  }
509 
510  /**
511  * Name of channel info variable
512  *
513  */
514  std::string get_channel_info_var_name() const noexcept {
515  return std::string("mechanism_info");
516  }
517 
518 
519  /****************************************************************************************/
520  /* Common helper routines accross codegen functions */
521  /****************************************************************************************/
522 
523  /**
524  * Check if a structure for ion variables is required
525  * \return \c true if a structure fot ion variables must be generated
526  */
527  bool ion_variable_struct_required() const;
528 
529 
530  /**
531  * Generate the string representing the procedure parameter declaration
532  *
533  * The procedure parameters are stored in a vector of 4-tuples each representing a parameter.
534  *
535  * \param params The parameters that should be concatenated into the function parameter
536  * declaration
537  * \return The string representing the declaration of function parameters
538  */
539  static std::string get_parameter_str(const ParamVector& params);
540 
541 
542  /**
543  * Generate the string representing the parameters in a function call
544  *
545  * The procedure parameters are stored in a vector of 4-tuples each representing a parameter.
546  *
547  * \param params The parameters that should be concatenated into the function parameter
548  * declaration
549  * \return The string representing the function call parameters
550  */
551  static std::string get_arg_str(const ParamVector& params);
552 
553 
554  /**
555  * Check if function or procedure node has parameter with given name
556  *
557  * \tparam T Node type (either procedure or function)
558  * \param node AST node (either procedure or function)
559  * \param name Name of parameter
560  * \return True if argument with name exist
561  */
562  template <typename T>
563  bool has_parameter_of_name(const T& node, const std::string& name);
564 
565 
566  /**
567  * Check if given statement should be skipped during code generation
568  * \param node The AST Statement node to check
569  * \return \c true if this Statement is to be skipped
570  */
571  static bool statement_to_skip(const ast::Statement& node);
572 
573 
574  /**
575  * Check if net_send_buffer is required
576  */
577  bool net_send_buffer_required() const noexcept;
578 
579 
580  /**
581  * Check if net receive/send buffering kernels required
582  */
583  bool net_receive_buffering_required() const noexcept;
584 
585 
586  /**
587  * Check if nrn_state function is required
588  */
589  bool nrn_state_required() const noexcept;
590 
591 
592  /**
593  * Check if nrn_cur function is required
594  */
595  bool nrn_cur_required() const noexcept;
596 
597 
598  /**
599  * Check if net_receive function is required
600  */
601  bool net_receive_required() const noexcept;
602 
603 
604  /**
605  * Check if setup_range_variable function is required
606  * \return
607  */
608  bool range_variable_setup_required() const noexcept;
609 
610 
611  /**
612  * Check if net_receive node exist
613  */
614  bool net_receive_exist() const noexcept;
615 
616 
617  /**
618  * Check if breakpoint node exist
619  */
620  bool breakpoint_exist() const noexcept;
621 
622 
623  /**
624  * Check if given method is defined in this model
625  * \param name The name of the method to check
626  * \return \c true if the method is defined
627  */
628  bool defined_method(const std::string& name) const;
629 
630 
631  /**
632  * Checks if given function name is \c net_send
633  * \param name The function name to check
634  * \return \c true if the function is net_send
635  */
636  bool is_net_send(const std::string& name) const noexcept {
637  return name == codegen::naming::NET_SEND_METHOD;
638  }
639 
640  bool is_nrn_pointing(const std::string& name) const noexcept {
642  }
643 
644 
645  /**
646  * Checks if given function name is \c net_move
647  * \param name The function name to check
648  * \return \c true if the function is net_move
649  */
650  bool is_net_move(const std::string& name) const noexcept {
651  return name == codegen::naming::NET_MOVE_METHOD;
652  }
653 
654 
655  /**
656  * Checks if given function name is \c net_event
657  * \param name The function name to check
658  * \return \c true if the function is net_event
659  */
660  bool is_net_event(const std::string& name) const noexcept {
661  return name == codegen::naming::NET_EVENT_METHOD;
662  }
663 
664 
665  bool is_function_table_call(const std::string& name) const;
666 
667 
668  /**
669  * Determine the position in the data array for a given float variable
670  * \param name The name of a float variable
671  * \return The position index in the data array
672  */
673  virtual int position_of_float_var(const std::string& name) const = 0;
674 
675 
676  /**
677  * Determine the position in the data array for a given int variable
678  * \param name The name of an int variable
679  * \return The position index in the data array
680  */
681  virtual int position_of_int_var(const std::string& name) const = 0;
682 
683 
684  /**
685  * Number of float variables in the model
686  */
687  int float_variables_size() const;
688 
689 
690  /**
691  * Number of integer variables in the model
692  */
693  int int_variables_size() const;
694 
695 
696  /**
697  * Convert a given \c double value to its string representation
698  * \param value The number to convert given as string as it is parsed by the modfile
699  * \return Its string representation
700  */
701  std::string format_double_string(const std::string& value);
702 
703 
704  /**
705  * Convert a given \c float value to its string representation
706  * \param value The number to convert given as string as it is parsed by the modfile
707  * \return Its string representation
708  */
709  std::string format_float_string(const std::string& value);
710 
711 
712  /**
713  * populate all index semantics needed for registration with coreneuron
714  */
715  void update_index_semantics();
716 
717 
718  /**
719  * Determine all \c float variables required during code generation
720  * \return A \c vector of \c float variables
721  */
722  std::vector<SymbolType> get_float_variables() const;
723 
724  virtual bool needs_v_unused() const = 0;
725 
726 
727  /**
728  * Determine all \c int variables required during code generation
729  * \return A \c vector of \c int variables
730  */
731  std::vector<IndexVariableInfo> get_int_variables();
732 
733 
734  /**
735  * For a given output block type, return statements for all read ion variables
736  *
737  * \param type The type of code block being generated
738  * \return A \c vector of strings representing the reading of ion variables
739  */
740  std::vector<std::string> ion_read_statements(BlockType type) const;
741 
742 
743  /**
744  * For a given output block type, return minimal statements for all read ion variables
745  *
746  * \param type The type of code block being generated
747  * \return A \c vector of strings representing the reading of ion variables
748  */
749  std::vector<std::string> ion_read_statements_optimized(BlockType type) const;
750 
751 
752  /**
753  * For a given output block type, return statements for writing back ion variables
754  *
755  * \param type The type of code block being generated
756  * \return A \c vector of strings representing the write-back of ion variables
757  */
758  std::vector<ShadowUseStatement> ion_write_statements(BlockType type);
759 
760 
761  /**
762  * Process shadow update statement
763  *
764  * If the statement requires reduction then add it to vector of reduction statement and return
765  * statement using shadow update
766  *
767  * \param statement The statement that might require shadow updates
768  * \param type The target backend code block type
769  * \return The generated target backend code
770  */
771  std::string process_shadow_update_statement(const ShadowUseStatement& statement,
772  BlockType type);
773 
774 
775  /**
776  * Determine the variable name for the "current" used in breakpoint block taking into account
777  * intermediate code transformations.
778  * \param current The variable name for the current used in the model
779  * \return The name for the current to be printed in C++
780  */
781  std::string breakpoint_current(std::string current) const;
782 
783 
784  /**
785  * Print pragma annotations for channel iterations
786  *
787  * This can be overriden by backends to provide additonal annotations or pragmas to enable
788  * for example SIMD code generation (e.g. through \c ivdep)
789  * The default implementation prints
790  *
791  * \code
792  * #pragma ivdep
793  * \endcode
794  *
795  * \param type The block type
796  */
797  virtual void print_parallel_iteration_hint(BlockType type, const ast::Block* block);
798 
799 
800  /****************************************************************************************/
801  /* Backend specific routines */
802  /****************************************************************************************/
803 
804 
805  /**
806  * Instantiate global var instance
807  *
808  * For C++ code generation this is empty
809  * \return ""
810  */
811  virtual void print_global_var_struct_decl();
812 
813  /**
814  * Check if ion variable copies should be avoided
815  */
816  virtual bool optimize_ion_variable_copies() const = 0;
817 
818  /****************************************************************************************/
819  /* Printing routines for code generation */
820  /****************************************************************************************/
821 
822 
823  /**
824  * Print any statement block in nmodl with option to (not) print braces
825  *
826  * The individual statements (of type nmodl::ast::Statement) in the StatementBlock are printed
827  * by accepting \c this visistor.
828  *
829  * \param node A (possibly empty) statement block AST node
830  * \param open_brace Print an opening brace if \c false
831  * \param close_brace Print a closing brace if \c true
832  */
834  bool open_brace = true,
835  bool close_brace = true);
836 
837 
838  /**
839  * Print call to internal or external function
840  * \param node The AST node representing a function call
841  */
842  virtual void print_function_call(const ast::FunctionCall& node);
843 
844  /**
845  * Print call to \c net\_send
846  * \param node The AST node representing the function call
847  */
848  virtual void print_net_send_call(const ast::FunctionCall& node) = 0;
849 
850  /**
851  * Print \c nrn\_pointing.
852  */
853  virtual void print_nrn_pointing(const ast::FunctionCall& node);
854 
855 
856  /**
857  * Print call to net\_move
858  * \param node The AST node representing the function call
859  */
860  virtual void print_net_move_call(const ast::FunctionCall& node) = 0;
861 
862 
863  /**
864  * Print call to net\_event
865  * \param node The AST node representing the function call
866  */
867  virtual void print_net_event_call(const ast::FunctionCall& node) = 0;
868 
869  /** Print special code when calling FUNCTION_TABLEs.
870  */
871  virtual void print_function_table_call(const ast::FunctionCall& node) = 0;
872 
873  /**
874  * Print function and procedures prototype declaration
875  */
876  virtual void print_function_prototypes() = 0;
877 
878 
879  /**
880  * Print nmodl function or procedure (common code)
881  * \param node the AST node representing the function or procedure in NMODL
882  * \param name the name of the function or procedure
883  * \param specifiers the set of C++ specifiers to apply to the function signature
884  */
885  virtual void print_function_or_procedure(
886  const ast::Block& node,
887  const std::string& name,
888  const std::unordered_set<CppObjectSpecifier>& specifiers) = 0;
889 
890 
891  /**
892  * Common helper function to help printing function or procedure blocks
893  * \param node the AST node representing the function or procedure in NMODL
894  */
895  virtual void print_function_procedure_helper(const ast::Block& node) = 0;
896 
897 
898  /**
899  * Print NMODL procedure in target backend code
900  * \param node
901  */
902  void print_procedure(const ast::ProcedureBlock& node);
903 
904 
905  /**
906  * Print NMODL function in target backend code
907  * \param node
908  */
909  void print_function(const ast::FunctionBlock& node);
910 
911  /**
912  * Print the internal function for FUNCTION_TABLES.
913  *
914  * Here internal refers to the function called from BREAKPOINT, INITIAL and
915  * other FUNCTIONs. Therefore this function doesn't print the functions required
916  * to call function tables from HOC/Python.
917  */
919 
920  /**
921  * Parameters of the function itself `"{}"` and `"table_{}"`.
922  */
923  virtual std::pair<ParamVector, ParamVector> function_table_parameters(
924  const ast::FunctionTableBlock& node) = 0;
925 
926  /**
927  * @brief Checks whether the functor_block generated by sympy solver modifies any variable
928  * outside its scope. If it does then return false, so that the operator() of the struct functor
929  * of the Eigen Newton solver doesn't have const qualifier.
930  *
931  * @param variable_block Statement Block of the variables declarations used in the functor
932  * struct of the solver
933  * @param functor_block Actual code being printed in the operator() of the functor struct of the
934  * solver
935  * @return True if operator() is const else False
936  */
937  bool is_functor_const(const ast::StatementBlock& variable_block,
938  const ast::StatementBlock& functor_block);
939 
940 
941  /** The parameters of the Newton solver "functor". */
942  virtual ParamVector functor_params() = 0;
943 
944  /**
945  * \brief Based on the \c EigenNewtonSolverBlock passed print the definition needed for its
946  * functor
947  *
948  * \param node \c EigenNewtonSolverBlock for which to print the functor
949  */
951 
952  /** \brief Print all Newton functor structs. */
954 
955  /** Print linear solver using Eigen.
956  */
957  void print_eigen_linear_solver(const std::string& float_type, int N);
958 
959  /**
960  * Print the items in a vector as a list
961  *
962  * This function prints a given vector of elements as a list with given separator onto the
963  * current printer. Elements are expected to be of type nmodl::ast::Ast and are printed by being
964  * visited. Care is taken to omit the separator after the the last element.
965  *
966  * \tparam T The element type in the vector, which must be of type nmodl::ast::Ast
967  * \param elements The vector of elements to be printed
968  * \param separator The separator string to print between all elements
969  * \param prefix A prefix string to print before each element
970  */
971  template <typename T>
972  void print_vector_elements(const std::vector<T>& elements,
973  const std::string& separator,
974  const std::string& prefix = "");
975 
976  virtual void print_ion_variable() = 0;
977 
978  /****************************************************************************************/
979  /* Code-specific helper routines */
980  /****************************************************************************************/
981 
982  /**
983  * Add the variable tqitem during `get_int_variables`.
984  */
985  virtual void add_variable_tqitem(std::vector<IndexVariableInfo>& variables) = 0;
986 
987  /**
988  * Add the variable point_process during `get_int_variables`.
989  */
990  virtual void add_variable_point_process(std::vector<IndexVariableInfo>& variables) = 0;
991 
992  /**
993  * Arguments for functions that are defined and used internally.
994  * \return the method arguments
995  */
996  virtual std::string internal_method_arguments() = 0;
997 
998 
999  /**
1000  * Parameters for internally defined functions
1001  * \return the method parameters
1002  */
1004 
1005 
1006  /**
1007  * Arguments for external functions called from generated code
1008  * \return A string representing the arguments passed to an external function
1009  */
1010  virtual const std::string external_method_arguments() noexcept = 0;
1011 
1012 
1013  /**
1014  * Parameters for functions in generated code that are called back from external code
1015  *
1016  * Functions registered in NEURON during initialization for callback must adhere to a prescribed
1017  * calling convention. This method generates the string representing the function parameters for
1018  * these externally called functions.
1019  * \param table
1020  * \return A string representing the parameters of the function
1021  */
1022  virtual const ParamVector external_method_parameters(bool table = false) noexcept = 0;
1023 
1024 
1025  /**
1026  * Arguments for "_threadargs_" macro in neuron implementation
1027  */
1028  virtual std::string nrn_thread_arguments() const = 0;
1029 
1030 
1031  /**
1032  * Arguments for "_threadargs_" macro in neuron implementation
1033  */
1034  virtual std::string nrn_thread_internal_arguments() = 0;
1035 
1036  /**
1037  * Arguments for register_mech or point_register_mech function
1038  */
1039  virtual std::string register_mechanism_arguments() const = 0;
1040 
1041 
1042  /**
1043  * Add quotes to string to be output
1044  *
1045  * \param text The string to be quoted
1046  * \return The same string with double-quotes pre- and postfixed
1047  */
1048  std::string add_escape_quote(const std::string& text) const {
1049  return "\"" + text + "\"";
1050  }
1051 
1052 
1053  /**
1054  * Constructs the name of a function or procedure
1055  * \param name The name of the function or procedure
1056  * \return The name of the function or procedure postfixed with the model name
1057  */
1058  std::string method_name(const std::string& name) const {
1059  return name + "_" + info.mod_suffix;
1060  }
1061 
1062  /**
1063  * Check if the given name exist in the symbol
1064  * \return \c return a tuple <true, array_length> if variable
1065  * is an array otherwise <false, 0>
1066  */
1067  std::tuple<bool, int> check_if_var_is_array(const std::string& name);
1068 
1069 
1070  /**
1071  * Creates a temporary symbol
1072  * \param name The name of the symbol
1073  * \return A symbol based on the given name
1074  */
1075  SymbolType make_symbol(const std::string& name) const {
1076  return std::make_shared<symtab::Symbol>(name, ModToken());
1077  }
1078 
1079  /**
1080  * Generate Function call statement for nrn_wrote_conc
1081  * \param statements Statements are appended to this vector.
1082  * \param ion The ion variable.
1083  * \param concentration The name of the concentration variable
1084  * \return The string representing the function call
1085  */
1086  virtual void append_conc_write_statements(std::vector<ShadowUseStatement>& statements,
1087  const Ion& ion,
1088  const std::string& concentration) = 0;
1089 
1090  /****************************************************************************************/
1091  /* Code-specific printing routines for code generations */
1092  /****************************************************************************************/
1093 
1094  /** Name of "our" namespace.
1095  */
1096  virtual std::string namespace_name() = 0;
1097 
1098  /**
1099  * Prints the start of the simulator namespace
1100  */
1101  void print_namespace_start();
1102 
1103 
1104  /**
1105  * Prints the end of the simulator namespace
1106  */
1107  void print_namespace_stop();
1108 
1109  /**
1110  * Prints f"using namespace {namespace_name()}".
1111  */
1112  void print_using_namespace();
1113 
1114  /****************************************************************************************/
1115  /* Routines for returning variable name */
1116  /****************************************************************************************/
1117 
1118  /**
1119  * Determine the updated name if the ion variable has been optimized
1120  * \param name The ion variable name
1121  * \return The updated name of the variable has been optimized (e.g. \c ena --> \c ion_ena)
1122  */
1123  std::string update_if_ion_variable_name(const std::string& name) const;
1124 
1125 
1126  /**
1127  * Determine the name of a \c float variable given its symbol
1128  *
1129  * This function typically returns the accessor expression in backend code for the given symbol.
1130  * Since the model variables are stored in data arrays and accessed by offset, this function
1131  * will return the C++ string representing the array access at the correct offset
1132  *
1133  * \param symbol The symbol of a variable for which we want to obtain its name
1134  * \param use_instance Should the variable be accessed via instance or data array
1135  * \return The backend code string representing the access to the given variable
1136  * symbol
1137  */
1138  virtual std::string float_variable_name(const SymbolType& symbol, bool use_instance) const = 0;
1139 
1140 
1141  /**
1142  * Determine the name of an \c int variable given its symbol
1143  *
1144  * This function typically returns the accessor expression in backend code for the given symbol.
1145  * Since the model variables are stored in data arrays and accessed by offset, this function
1146  * will return the C++ string representing the array access at the correct offset
1147  *
1148  * \param symbol The symbol of a variable for which we want to obtain its name
1149  * \param name The name of the index variable
1150  * \param use_instance Should the variable be accessed via instance or data array
1151  * \return The backend code string representing the access to the given variable
1152  * symbol
1153  */
1154  virtual std::string int_variable_name(const IndexVariableInfo& symbol,
1155  const std::string& name,
1156  bool use_instance) const = 0;
1157 
1158 
1159  /**
1160  * Determine the variable name for a global variable given its symbol
1161  * \param symbol The symbol of a variable for which we want to obtain its name
1162  * \param use_instance Should the variable be accessed via the (host-only)
1163  * global variable or the instance-specific copy (also available on GPU).
1164  * \return The C++ string representing the access to the global variable
1165  */
1166  virtual std::string global_variable_name(const SymbolType& symbol,
1167  bool use_instance = true) const = 0;
1168 
1169 
1170  /**
1171  * Determine variable name in the structure of mechanism properties
1172  *
1173  * \param name Variable name that is being printed
1174  * \param use_instance Should the variable be accessed via instance or data array
1175  * \return The C++ string representing the access to the variable in the neuron
1176  * thread structure
1177  */
1178  virtual std::string get_variable_name(const std::string& name,
1179  bool use_instance = true) const = 0;
1180 
1181  /**
1182  * The name of the function that updates the table value if the parameters
1183  * changed.
1184  *
1185  * \param block_name The name of the block that contains the TABLE.
1186  */
1187  std::string table_update_function_name(const std::string& block_name) const;
1188 
1189  /**
1190  * Return ion variable name and corresponding ion read variable name.
1191  *
1192  * Example:
1193  * {"ena", "ion_ena"} = read_ion_variable_name("ena");
1194  *
1195  * \param name The ion variable name
1196  * \return The ion read variable name
1197  */
1198  static std::pair<std::string, std::string> read_ion_variable_name(const std::string& name);
1199 
1200 
1201  /**
1202  * Return ion variable name and corresponding ion write variable name
1203  *
1204  * Example:
1205  * {"ion_ena", "ena"} = write_ion_variable_name("ena");
1206  *
1207  * \param name The ion variable name
1208  * \return The ion write variable name
1209  */
1210  static std::pair<std::string, std::string> write_ion_variable_name(const std::string& name);
1211 
1212 
1213  int get_int_variable_index(const std::string& var_name);
1214 
1215  /****************************************************************************************/
1216  /* Main printing routines for code generation */
1217  /****************************************************************************************/
1218 
1219 
1220  /**
1221  * Print top file header printed in generated code
1222  */
1223  void print_backend_info();
1224 
1225 
1226  /**
1227  * Print standard C/C++ includes
1228  */
1229  virtual void print_standard_includes() = 0;
1230 
1231 
1232  virtual void print_sdlists_init(bool print_initializers) = 0;
1233 
1234 
1235  /**
1236  * Print the structure that wraps all global variables used in the NMODL
1237  *
1238  * \param print_initializers Whether to include default values in the struct
1239  * definition (true: int foo{42}; false: int foo;)
1240  */
1241  virtual void print_mechanism_global_var_structure(bool print_initializers) = 0;
1242 
1243 
1244  /**
1245  * Print static assertions about the global variable struct.
1246  */
1247  virtual void print_global_var_struct_assertions() const;
1248 
1249 
1250  /**
1251  * Print the entries of for FUNCTION_TABLEs in the global struct.
1252  *
1253  * And creates the required GLOBAL variables.
1254  */
1256 
1257 
1258  /**
1259  * Print declaration of macro NRN_PRCELLSTATE for debugging
1260  */
1261  void print_prcellstate_macros() const;
1262 
1263 
1264  /**
1265  * Print backend code for byte array that has mechanism information (to be registered
1266  * with NEURON/CoreNEURON)
1267  */
1268  void print_mechanism_info();
1269 
1270 
1271  /**
1272  * Print byte arrays that register scalar and vector variables for hoc interface
1273  *
1274  */
1275  virtual void print_global_variables_for_hoc() = 0;
1276 
1277 
1278  /**
1279  * Print the mechanism registration function
1280  *
1281  */
1282  virtual void print_mechanism_register() = 0;
1283 
1284 
1285  /**
1286  * Print common code for global functions like nrn_init, nrn_cur and nrn_state
1287  * \param type The target backend code block type
1288  */
1289  virtual void print_global_function_common_code(BlockType type,
1290  const std::string& function_name = "") = 0;
1291 
1292 
1293  /**
1294  * Print nrn_constructor function definition
1295  *
1296  */
1297  virtual void print_nrn_constructor() = 0;
1298 
1299 
1300  /**
1301  * Print nrn_destructor function definition
1302  *
1303  */
1304  virtual void print_nrn_destructor() = 0;
1305 
1306 
1307  /**
1308  * Print nrn_alloc function definition
1309  *
1310  */
1311  virtual void print_nrn_alloc() = 0;
1312 
1313 
1314  /****************************************************************************************/
1315  /* Print nrn_state routine */
1316  /****************************************************************************************/
1317 
1318 
1319  /**
1320  * Print nrn_state / state update function definition
1321  */
1322  virtual void print_nrn_state() = 0;
1323 
1324 
1325  /****************************************************************************************/
1326  /* Print nrn_cur related routines */
1327  /****************************************************************************************/
1328 
1329 
1330  /**
1331  * Print the \c nrn_current kernel
1332  *
1333  * \note nrn_cur_kernel will have two calls to nrn_current if no conductance keywords specified
1334  * \param node the AST node representing the NMODL breakpoint block
1335  */
1336  virtual void print_nrn_current(const ast::BreakpointBlock& node) = 0;
1337 
1338 
1339  /**
1340  * Print the \c nrn\_cur kernel with NMODL \c conductance keyword provisions
1341  *
1342  * If the NMODL \c conductance keyword is used in the \c breakpoint block, then
1343  * CodegenCoreneuronCppVisitor::print_nrn_cur_kernel will use this printer
1344  *
1345  * \param node the AST node representing the NMODL breakpoint block
1346  */
1347  virtual void print_nrn_cur_conductance_kernel(const ast::BreakpointBlock& node) = 0;
1348 
1349 
1350  /**
1351  * Print the \c nrn\_cur kernel without NMODL \c conductance keyword provisions
1352  *
1353  * If the NMODL \c conductance keyword is \b not used in the \c breakpoint block, then
1354  * CodegenCoreneuronCppVisitor::print_nrn_cur_kernel will use this printer
1355  */
1356  virtual void print_nrn_cur_non_conductance_kernel() = 0;
1357 
1358 
1359  /**
1360  * Print main body of nrn_cur function
1361  * \param node the AST node representing the NMODL breakpoint block
1362  */
1363  virtual void print_nrn_cur_kernel(const ast::BreakpointBlock& node) = 0;
1364 
1365 
1366  /**
1367  * Print fast membrane current calculation code
1368  */
1369  virtual void print_fast_imem_calculation() = 0;
1370 
1371 
1372  /**
1373  * Print nrn_cur / current update function definition
1374  */
1375  virtual void print_nrn_cur() = 0;
1376 
1377 
1378  /****************************************************************************************/
1379  /* Main code printing entry points */
1380  /****************************************************************************************/
1381 
1382 
1383  /**
1384  * Print all includes
1385  *
1386  */
1387  virtual void print_headers_include() = 0;
1388 
1389 
1390  /**
1391  * Print all classes
1392  * \param print_initializers Whether to include default values.
1393  */
1394  virtual void print_data_structures(bool print_initializers) = 0;
1395 
1396 
1397  /**
1398  * Set v_unused (voltage) for NRN_PRCELLSTATE feature
1399  */
1400  virtual void print_v_unused() const = 0;
1401 
1402 
1403  /**
1404  * Set g_unused (conductance) for NRN_PRCELLSTATE feature
1405  */
1406  virtual void print_g_unused() const = 0;
1407 
1408 
1409  /**
1410  * Print all compute functions for every backend
1411  *
1412  */
1413  virtual void print_compute_functions() = 0;
1414 
1415 
1416  /**
1417  * Print entry point to code generation
1418  *
1419  */
1420  virtual void print_codegen_routines() = 0;
1421 
1422  std::unordered_map<CppObjectSpecifier, std::string> object_specifier_map = {
1423  {CppObjectSpecifier::Inline, "inline"},
1424  {CppObjectSpecifier::Static, "static"},
1425  {CppObjectSpecifier::Constexpr, "constexpr"},
1426  {CppObjectSpecifier::Volatile, "volatile"},
1427  {CppObjectSpecifier::Virtual, "virtual"},
1428  {CppObjectSpecifier::Explicit, "explicit"},
1429  {CppObjectSpecifier::Friend, "friend"},
1430  {CppObjectSpecifier::Extern, "extern"},
1431  {CppObjectSpecifier::ExternC, "extern \"C\""},
1432  {CppObjectSpecifier::ThreadLocal, "thread_local"},
1433  {CppObjectSpecifier::Const, "const"}};
1434 
1435 
1436  /**
1437  * Print the nmodl constants used in backend code
1438  *
1439  * Currently we define three basic constants, which are assumed to be present in NMODL, directly
1440  * in the backend code:
1441  *
1442  * \code
1443  * static const double FARADAY = 96485.3;
1444  * static const double PI = 3.14159;
1445  * static const double R = 8.3145;
1446  * \endcode
1447  */
1448  void print_nmodl_constants();
1449 
1450  /**
1451  * Print top level (global scope) verbatim blocks
1452  */
1454 
1455 
1456  /****************************************************************************************/
1457  /* Overloaded visitor routines */
1458  /****************************************************************************************/
1459  void visit_binary_expression(const ast::BinaryExpression& node) override;
1460  void visit_binary_operator(const ast::BinaryOperator& node) override;
1461  void visit_boolean(const ast::Boolean& node) override;
1462  void visit_double(const ast::Double& node) override;
1463  void visit_else_if_statement(const ast::ElseIfStatement& node) override;
1464  void visit_else_statement(const ast::ElseStatement& node) override;
1465  void visit_float(const ast::Float& node) override;
1466  void visit_from_statement(const ast::FromStatement& node) override;
1467  void visit_function_call(const ast::FunctionCall& node) override;
1468  void visit_if_statement(const ast::IfStatement& node) override;
1469  void visit_indexed_name(const ast::IndexedName& node) override;
1470  void visit_integer(const ast::Integer& node) override;
1471  void visit_local_list_statement(const ast::LocalListStatement& node) override;
1472  void visit_name(const ast::Name& node) override;
1473  void visit_paren_expression(const ast::ParenExpression& node) override;
1474  void visit_prime_name(const ast::PrimeName& node) override;
1475  void visit_statement_block(const ast::StatementBlock& node) override;
1476  void visit_string(const ast::String& node) override;
1477  void visit_unary_operator(const ast::UnaryOperator& node) override;
1478  void visit_unit(const ast::Unit& node) override;
1479  void visit_var_name(const ast::VarName& node) override;
1480  void visit_while_statement(const ast::WhileStatement& node) override;
1481  void visit_update_dt(const ast::UpdateDt& node) override;
1482  void visit_mutex_lock(const ast::MutexLock& node) override;
1483  void visit_mutex_unlock(const ast::MutexUnlock& node) override;
1484  void visit_solution_expression(const ast::SolutionExpression& node) override;
1487 
1488  std::string compute_method_name(BlockType type) const;
1489 
1490  // Automatically called as part of `visit_program`.
1491  virtual void setup(const ast::Program& node);
1492 
1493  public:
1494 
1495  /**
1496  * Main and only member function to call after creating an instance of this class.
1497  * \param program the AST to translate to C++ code
1498  */
1499  void visit_program(const ast::Program& program) override;
1500 
1501 
1502  protected:
1503 
1504  /**
1505  * Print the structure that wraps all range and int variables required for the NMODL
1506  *
1507  * \param print_initializers Whether or not default values for variables
1508  * be included in the struct declaration.
1509  */
1510  virtual void print_mechanism_range_var_structure(bool print_initializers) = 0;
1511 
1512 
1513  /**
1514  * Print replacement function for function or procedure using table
1515  * \param node The AST node representing a function or procedure block
1516  */
1518 
1519 
1520  /**
1521  * Print \c check\_function() for functions or procedure using table
1522  * \param node The AST node representing a function or procedure block
1523  */
1525 
1526 
1528 
1529  std::string get_object_specifiers(const std::unordered_set<CppObjectSpecifier>&);
1530 
1531  /**
1532  * Print prototype declarations of functions or procedures
1533  * \tparam T The AST node type of the node (must be of nmodl::ast::Ast or subclass)
1534  * \param node The AST node representing the function or procedure block
1535  * \param name A user defined name for the function
1536  */
1537  template <typename T>
1538  void print_function_declaration(const T& node,
1539  const std::string& name,
1540  const std::unordered_set<CppObjectSpecifier>& =
1542 
1543  void print_rename_state_vars() const;
1544 };
1545 
1546 template <typename T>
1547 void CodegenCppVisitor::print_vector_elements(const std::vector<T>& elements,
1548  const std::string& separator,
1549  const std::string& prefix) {
1550  for (auto iter = elements.begin(); iter != elements.end(); iter++) {
1551  printer->add_text(prefix);
1552  (*iter)->accept(*this);
1553  if (!separator.empty() && !nmodl::utils::is_last(iter, elements)) {
1554  printer->add_text(separator);
1555  }
1556  }
1557 }
1558 
1559 
1560 /**
1561  * \details If there is an argument with name (say alpha) same as range variable (say alpha),
1562  * we want to avoid it being printed as instance->alpha. And hence we disable variable
1563  * name lookup during prototype declaration. Note that the name of procedure can be
1564  * different in case of table statement.
1565  */
1566 template <typename T>
1568  const T& node,
1569  const std::string& name,
1570  const std::unordered_set<CppObjectSpecifier>& specifiers) {
1572  auto type = default_float_data_type();
1573 
1574  // internal and user provided arguments
1575  auto internal_params = internal_method_parameters();
1576  const auto& params = node.get_parameters();
1577  for (const auto& param: params) {
1578  internal_params.emplace_back("", type, "", param.get()->get_node_name());
1579  }
1580 
1581  // procedures have "int" return type by default
1582  const char* return_type = "int";
1583  if (node.is_function_block()) {
1584  return_type = default_float_data_type();
1585  }
1586 
1587  printer->add_indent();
1588  printer->fmt_text("{} {} {}({})",
1589  get_object_specifiers(specifiers),
1590  return_type,
1591  method_name(name),
1592  get_parameter_str(internal_params));
1593 
1595 }
1596 
1597 /** \} */ // end of codegen_backends
1598 
1599 } // namespace codegen
1600 } // namespace nmodl
nmodl::codegen::CodegenCppVisitor::print_nrn_constructor
virtual void print_nrn_constructor()=0
Print nrn_constructor function definition.
nmodl::codegen::CodegenCppVisitor::table_update_function_name
std::string table_update_function_name(const std::string &block_name) const
The name of the function that updates the table value if the parameters changed.
Definition: codegen_cpp_visitor.cpp:76
nmodl::codegen::CodegenCppVisitor::visit_eigen_linear_solver_block
void visit_eigen_linear_solver_block(const ast::EigenLinearSolverBlock &node) override
visit node of type ast::EigenLinearSolverBlock
Definition: codegen_cpp_visitor.cpp:1161
nmodl::codegen::CodegenCppVisitor::ion_variable_struct_required
bool ion_variable_struct_required() const
Check if a structure for ion variables is required.
Definition: codegen_cpp_visitor.cpp:39
nmodl::utils::is_last
bool is_last(Iter iter, const Cont &cont)
Check if the iterator is pointing to last element in the container.
Definition: common_utils.hpp:37
nmodl::codegen::get_length
int get_length(const std::shared_ptr< symtab::Symbol > &sym)
Definition: codegen_cpp_visitor.hpp:197
nmodl::codegen::CodegenCppVisitor::need_semicolon
static bool need_semicolon(const ast::Statement &node)
Check if a semicolon is required at the end of given statement.
Definition: codegen_cpp_visitor.cpp:217
nmodl::ast::UnaryOperator
TODO.
Definition: unary_operator.hpp:38
nmodl::codegen::CodegenCppVisitor::update_index_semantics
void update_index_semantics()
populate all index semantics needed for registration with coreneuron
Definition: codegen_cpp_visitor.cpp:1191
nmodl::codegen::CodegenCppVisitor::print_table_replacement_function
void print_table_replacement_function(const ast::Block &)
Print replacement function for function or procedure using table.
Definition: codegen_cpp_visitor.cpp:1514
nmodl::ast::Unit
TODO.
Definition: unit.hpp:38
nmodl::codegen::CodegenCppVisitor::register_mechanism_arguments
virtual std::string register_mechanism_arguments() const =0
Arguments for register_mech or point_register_mech function.
nmodl::codegen::CodegenCppVisitor::function_table_parameters
virtual std::pair< ParamVector, ParamVector > function_table_parameters(const ast::FunctionTableBlock &node)=0
Parameters of the function itself "{}" and "table_{}".
nmodl::codegen::CodegenCppVisitor::print_g_unused
virtual void print_g_unused() const =0
Set g_unused (conductance) for NRN_PRCELLSTATE feature.
nmodl::codegen::IndexVariableInfo::is_index
bool is_index
if this is pure index (e.g.
Definition: codegen_cpp_visitor.hpp:137
nmodl::codegen::CodegenCppVisitor::visit_name
void visit_name(const ast::Name &node) override
visit node of type ast::Name
Definition: codegen_cpp_visitor.cpp:945
nmodl::codegen::CodegenCppVisitor::has_parameter_of_name
bool has_parameter_of_name(const T &node, const std::string &name)
Check if function or procedure node has parameter with given name.
Definition: codegen_cpp_visitor.cpp:66
nmodl::codegen::CodegenCppVisitor::int_variables_size
int int_variables_size() const
Number of integer variables in the model.
Definition: codegen_cpp_visitor.cpp:187
nmodl::codegen::CodegenCppVisitor::print_sdlists_init
virtual void print_sdlists_init(bool print_initializers)=0
nmodl::codegen::CodegenCppVisitor::print_global_struct_function_table_ptrs
virtual void print_global_struct_function_table_ptrs()
Print the entries of for FUNCTION_TABLEs in the global struct.
Definition: codegen_cpp_visitor.cpp:479
nmodl::codegen::CodegenCppVisitor::visit_if_statement
void visit_if_statement(const ast::IfStatement &node) override
visit node of type ast::IfStatement
Definition: codegen_cpp_visitor.cpp:998
nmodl::codegen::CppObjectSpecifier
CppObjectSpecifier
various specifiers (mostly for function codegen)
Definition: codegen_cpp_visitor.hpp:107
nmodl::codegen::MemberType::global
@ global
global variables
nmodl::codegen::CodegenCppVisitor::ion_write_statements
std::vector< ShadowUseStatement > ion_write_statements(BlockType type)
For a given output block type, return statements for writing back ion variables.
Definition: codegen_cpp_visitor.cpp:298
nmodl::codegen::CodegenCppVisitor::visit_else_statement
void visit_else_statement(const ast::ElseStatement &node) override
visit node of type ast::ElseStatement
Definition: codegen_cpp_visitor.cpp:1019
nmodl::codegen::IndexVariableInfo
Helper to represent information about index/int variables.
Definition: codegen_cpp_visitor.hpp:127
nmodl::codegen::CodegenCppVisitor::breakpoint_exist
bool breakpoint_exist() const noexcept
Check if breakpoint node exist.
Definition: codegen_cpp_visitor.cpp:144
nmodl::visitor::ConstAstVisitor
Concrete constant visitor for all AST classes.
Definition: ast_visitor.hpp:168
nmodl::ast::Ast
Base class for all Abstract Syntax Tree node types.
Definition: ast.hpp:69
nmodl::codegen::CodegenCppVisitor::print_nrn_current
virtual void print_nrn_current(const ast::BreakpointBlock &node)=0
Print the nrn_current kernel.
nmodl::codegen::BlockType::Destructor
@ Destructor
destructor block
nmodl::codegen::naming::DEFAULT_LOCAL_VAR_TYPE
static constexpr char DEFAULT_LOCAL_VAR_TYPE[]
default local variable type
Definition: codegen_naming.hpp:114
nmodl::codegen::CodegenCppVisitor::CodegenCppVisitor
CodegenCppVisitor(std::string mod_filename, std::ostream &stream, std::string float_type, const bool optimize_ionvar_copies, const bool enable_cvode, std::unique_ptr< nmodl::utils::Blame > blame=nullptr)
Definition: codegen_cpp_visitor.hpp:269
nmodl::codegen::CodegenCppVisitor::print_eigen_linear_solver
void print_eigen_linear_solver(const std::string &float_type, int N)
Print linear solver using Eigen.
Definition: codegen_cpp_visitor.cpp:849
nmodl::codegen::IndexVariableInfo::symbol
const std::shared_ptr< symtab::Symbol > symbol
symbol for the variable
Definition: codegen_cpp_visitor.hpp:129
nmodl::codegen::CodegenCppVisitor::info
codegen::CodegenInfo info
All ast information for code generation.
Definition: codegen_cpp_visitor.hpp:331
nmodl::codegen::CodegenCppVisitor::global_struct_instance
std::string global_struct_instance() const
Name of the (host-only) global instance of global_struct
Definition: codegen_cpp_visitor.hpp:444
nmodl::ast::Double
Represents a double variable.
Definition: double.hpp:53
nmodl::ast::FunctionBlock
TODO.
Definition: function_block.hpp:39
nmodl::codegen::CodegenCppVisitor::write_ion_variable_name
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.
Definition: codegen_cpp_visitor.cpp:443
nmodl::codegen::CodegenCppVisitor::position_of_float_var
virtual int position_of_float_var(const std::string &name) const =0
Determine the position in the data array for a given float variable.
nmodl::codegen::CodegenCppVisitor::operator_for_d
const char * operator_for_d() const noexcept
Operator for diagonal vector update (matrix update)
Definition: codegen_cpp_visitor.hpp:506
nmodl::codegen::CodegenCppVisitor::optimize_ionvar_copies
bool optimize_ionvar_copies
Flag to indicate if visitor should avoid ion variable copies.
Definition: codegen_cpp_visitor.hpp:325
nmodl::codegen::CodegenCppVisitor::net_receive_exist
bool net_receive_exist() const noexcept
Check if net_receive node exist.
Definition: codegen_cpp_visitor.cpp:139
nmodl::codegen::CodegenCppVisitor::append_conc_write_statements
virtual void append_conc_write_statements(std::vector< ShadowUseStatement > &statements, const Ion &ion, const std::string &concentration)=0
Generate Function call statement for nrn_wrote_conc.
nmodl::codegen::CodegenCppVisitor::SymbolType
std::shared_ptr< symtab::Symbol > SymbolType
Definition: codegen_cpp_visitor.hpp:285
nmodl::codegen::CodegenCppVisitor::get_int_variable_index
int get_int_variable_index(const std::string &var_name)
Definition: codegen_cpp_visitor.cpp:449
nmodl::codegen::MemberType::thread
@ thread
thread variables
nmodl::ast::FunctionTableBlock
TODO.
Definition: function_table_block.hpp:39
nmodl::codegen::CodegenCppVisitor::optimize_ion_variable_copies
virtual bool optimize_ion_variable_copies() const =0
Check if ion variable copies should be avoided.
nmodl::codegen::get_name
std::string get_name(ast::Ast const *sym)
Definition: codegen_cpp_visitor.hpp:172
nmodl::codegen::CodegenCppVisitor::print_procedure
void print_procedure(const ast::ProcedureBlock &node)
Print NMODL procedure in target backend code.
Definition: codegen_cpp_visitor.cpp:569
nmodl::codegen::CodegenCppVisitor::nmodl_version
std::string nmodl_version() const noexcept
Return Nmodl language version.
Definition: codegen_cpp_visitor.hpp:403
nmodl::codegen::CodegenCppVisitor::printing_top_verbatim_blocks
bool printing_top_verbatim_blocks
true if currently printing top level verbatim blocks
Definition: codegen_cpp_visitor.hpp:380
nmodl::codegen::CodegenCppVisitor::float_variables_size
int float_variables_size() const
Number of float variables in the model.
Definition: codegen_cpp_visitor.cpp:177
nmodl::codegen::IndexVariableInfo::is_constant
bool is_constant
if the variable is qualified as constant (this is property of IndexVariable)
Definition: codegen_cpp_visitor.hpp:144
nmodl::codegen::CodegenCppVisitor::print_backend_info
void print_backend_info()
Print top file header printed in generated code.
Definition: codegen_cpp_visitor.cpp:459
nmodl::codegen::CodegenCppVisitor::visit_from_statement
void visit_from_statement(const ast::FromStatement &node) override
visit node of type ast::FromStatement
Definition: codegen_cpp_visitor.cpp:1033
nmodl::codegen::CodegenCppVisitor::print_functor_definition
void print_functor_definition(const ast::EigenNewtonSolverBlock &node)
Based on the EigenNewtonSolverBlock passed print the definition needed for its functor.
Definition: codegen_cpp_visitor.cpp:775
nmodl::codegen::CodegenCppVisitor::print_global_var_struct_assertions
virtual void print_global_var_struct_assertions() const
Print static assertions about the global variable struct.
Definition: codegen_cpp_visitor.cpp:487
nmodl::codegen::CodegenCppVisitor::printing_net_init
bool printing_net_init
true if currently initial block of net_receive being printed
Definition: codegen_cpp_visitor.hpp:374
nmodl::codegen::CodegenCppVisitor::print_mechanism_info
void print_mechanism_info()
Print backend code for byte array that has mechanism information (to be registered with NEURON/CoreNE...
Definition: codegen_cpp_visitor.cpp:626
nmodl::codegen::CodegenCppVisitor::visit_eigen_newton_solver_block
void visit_eigen_newton_solver_block(const ast::EigenNewtonSolverBlock &node) override
visit node of type ast::EigenNewtonSolverBlock
Definition: codegen_cpp_visitor.cpp:1132
nmodl::codegen::CodegenCppVisitor::print_global_function_common_code
virtual void print_global_function_common_code(BlockType type, const std::string &function_name="")=0
Print common code for global functions like nrn_init, nrn_cur and nrn_state.
nmodl::codegen::CodegenCppVisitor::print_standard_includes
virtual void print_standard_includes()=0
Print standard C/C++ includes.
nmodl::codegen::CodegenCppVisitor::visit_prime_name
void visit_prime_name(const ast::PrimeName &node) override
visit node of type ast::PrimeName
Definition: codegen_cpp_visitor.cpp:955
nmodl::codegen::CodegenCppVisitor::print_nrn_cur_non_conductance_kernel
virtual void print_nrn_cur_non_conductance_kernel()=0
Print the nrn_cur kernel without NMODL conductance keyword provisions.
nmodl::codegen::CppObjectSpecifier::Friend
@ Friend
nmodl::codegen::CodegenCppVisitor::print_function_procedure_helper
virtual void print_function_procedure_helper(const ast::Block &node)=0
Common helper function to help printing function or procedure blocks.
nmodl::codegen::ShadowUseStatement::lhs
std::string lhs
Definition: codegen_cpp_visitor.hpp:167
nmodl::codegen::ShadowUseStatement::rhs
std::string rhs
Definition: codegen_cpp_visitor.hpp:169
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
nmodl::codegen::MemberType::index
@ index
index / int variables
nmodl::codegen::CodegenCppVisitor::float_data_type
const std::string & float_data_type() const noexcept
Data type for floating point elements specified on command line.
Definition: codegen_cpp_visitor.hpp:482
nmodl::codegen::Ion
Represent ions used in mod file.
Definition: codegen_info.hpp:53
nmodl::codegen::CodegenCppVisitor::print_ion_variable
virtual void print_ion_variable()=0
symbol_table.hpp
Implement classes for representing symbol table at block and file scope.
nmodl::codegen::CodegenCppVisitor::nrn_thread_arguments
virtual std::string nrn_thread_arguments() const =0
Arguments for "_threadargs_" macro in neuron implementation.
nmodl::codegen::CodegenCppVisitor::range_variable_setup_required
bool range_variable_setup_required() const noexcept
Check if setup_range_variable function is required.
Definition: codegen_cpp_visitor.cpp:158
nmodl::ast::MutexLock
Represent MUTEXLOCK statement in NMODL.
Definition: mutex_lock.hpp:38
nmodl::codegen::CodegenCppVisitor::print_statement_block
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.
Definition: codegen_cpp_visitor.cpp:700
nmodl::codegen::get_prefixsum_from_name
int get_prefixsum_from_name(const std::vector< T > &variables, const std::string &name)
Definition: codegen_cpp_visitor.hpp:206
nmodl::codegen::CodegenCppVisitor::print_function_declaration
void print_function_declaration(const T &node, const std::string &name, const std::unordered_set< CppObjectSpecifier > &={CppObjectSpecifier::Static, CppObjectSpecifier::Inline})
Print prototype declarations of functions or procedures.
Definition: codegen_cpp_visitor.hpp:1567
nmodl::ast::WhileStatement
TODO.
Definition: while_statement.hpp:38
nmodl::codegen::CodegenCppVisitor::global_variable_name
virtual std::string global_variable_name(const SymbolType &symbol, bool use_instance=true) const =0
Determine the variable name for a global variable given its symbol.
nmodl::ast::TableStatement
Represents TABLE statement in NMODL.
Definition: table_statement.hpp:39
nmodl::codegen::CodegenCppVisitor::visit_binary_expression
void visit_binary_expression(const ast::BinaryExpression &node) override
visit node of type ast::BinaryExpression
Definition: codegen_cpp_visitor.cpp:1061
nmodl::ast::VarName
Represents a variable.
Definition: var_name.hpp:43
nmodl::ast::Integer
Represents an integer variable.
Definition: integer.hpp:49
nmodl::codegen::BlockType::BlockTypeEnd
@ BlockTypeEnd
fake ending block type for loops on the enums. Keep it at the end
nmodl::codegen::CodegenCppVisitor::get_object_specifiers
std::string get_object_specifiers(const std::unordered_set< CppObjectSpecifier > &)
Definition: codegen_cpp_visitor.cpp:1719
nmodl::codegen::CodegenCppVisitor::get_float_variables
std::vector< SymbolType > get_float_variables() const
Determine all float variables required during code generation.
Definition: codegen_cpp_visitor.cpp:1267
nmodl::ast::ElseIfStatement
TODO.
Definition: else_if_statement.hpp:38
nmodl::codegen::CodegenCppVisitor::print_net_move_call
virtual void print_net_move_call(const ast::FunctionCall &node)=0
Print call to net_move.
nmodl::codegen::CodegenCppVisitor::default_int_data_type
const char * default_int_data_type() const noexcept
Default data type for integer (offset) elements.
Definition: codegen_cpp_visitor.hpp:490
nmodl::codegen::CodegenInfo::mod_suffix
std::string mod_suffix
name of the suffix
Definition: codegen_info.hpp:340
nmodl::codegen::CodegenCppVisitor::print_top_verbatim_blocks
void print_top_verbatim_blocks()
Print top level (global scope) verbatim blocks.
Definition: codegen_cpp_visitor.cpp:673
nmodl::codegen::CodegenCppVisitor::print_function_tables
void print_function_tables(const ast::FunctionTableBlock &node)
Print the internal function for FUNCTION_TABLES.
Definition: codegen_cpp_visitor.cpp:594
nmodl::codegen::CodegenInfo
Represent information collected from AST for code generation.
Definition: codegen_info.hpp:335
nmodl::codegen::CodegenCppVisitor::visit_paren_expression
void visit_paren_expression(const ast::ParenExpression &node) override
visit node of type ast::ParenExpression
Definition: codegen_cpp_visitor.cpp:1054
nmodl::codegen::CodegenCppVisitor::print_namespace_start
void print_namespace_start()
Prints the start of the simulator namespace.
Definition: codegen_cpp_visitor.cpp:662
nmodl::codegen::CodegenCppVisitor::default_float_data_type
const char * default_float_data_type() const noexcept
Default data type for floating point elements.
Definition: codegen_cpp_visitor.hpp:474
nmodl::codegen::CodegenCppVisitor::net_receive_buffering_required
bool net_receive_buffering_required() const noexcept
Check if net receive/send buffering kernels required.
Definition: codegen_cpp_visitor.cpp:121
nmodl::codegen::CodegenCppVisitor::update_if_ion_variable_name
std::string update_if_ion_variable_name(const std::string &name) const
Determine the updated name if the ion variable has been optimized.
Definition: codegen_cpp_visitor.cpp:420
nmodl::codegen::CodegenCppVisitor::print_function
void print_function(const ast::FunctionBlock &node)
Print NMODL function in target backend code.
Definition: codegen_cpp_visitor.cpp:574
nmodl::codegen::CodegenCppVisitor::print_nrn_cur_conductance_kernel
virtual void print_nrn_cur_conductance_kernel(const ast::BreakpointBlock &node)=0
Print the nrn_cur kernel with NMODL conductance keyword provisions.
nmodl::codegen::ShadowUseStatement::op
std::string op
Definition: codegen_cpp_visitor.hpp:168
nmodl::codegen::CodegenCppVisitor::visit_mutex_unlock
void visit_mutex_unlock(const ast::MutexUnlock &node) override
visit node of type ast::MutexUnlock
Definition: codegen_cpp_visitor.cpp:1116
nmodl::codegen::IndexVariableInfo::is_integer
bool is_integer
if this is an integer (e.g.
Definition: codegen_cpp_visitor.hpp:141
nmodl::codegen::CodegenCppVisitor::int_variable_name
virtual std::string int_variable_name(const IndexVariableInfo &symbol, const std::string &name, bool use_instance) const =0
Determine the name of an int variable given its symbol.
nmodl::codegen::CodegenCppVisitor::visit_unit
void visit_unit(const ast::Unit &node) override
visit node of type ast::Unit
Definition: codegen_cpp_visitor.cpp:950
nmodl::codegen::CodegenCppVisitor::object_specifier_map
std::unordered_map< CppObjectSpecifier, std::string > object_specifier_map
Definition: codegen_cpp_visitor.hpp:1422
nmodl::ast::EigenNewtonSolverBlock
Represent newton solver solution block based on Eigen.
Definition: eigen_newton_solver_block.hpp:38
nmodl::codegen::CodegenCppVisitor::visit_update_dt
void visit_update_dt(const ast::UpdateDt &node) override
visit node of type ast::UpdateDt
Definition: codegen_cpp_visitor.cpp:1104
nmodl::codegen::CodegenCppVisitor::print_vector_elements
void print_vector_elements(const std::vector< T > &elements, const std::string &separator, const std::string &prefix="")
Print the items in a vector as a list.
Definition: codegen_cpp_visitor.hpp:1547
nmodl::codegen::CodegenCppVisitor::is_function_table_call
bool is_function_table_call(const std::string &name) const
Definition: codegen_cpp_visitor.cpp:170
nmodl::codegen::IndexVariableInfo::IndexVariableInfo
IndexVariableInfo(std::shared_ptr< symtab::Symbol > symbol, bool is_vdata=false, bool is_index=false, bool is_integer=false)
Definition: codegen_cpp_visitor.hpp:146
nmodl::codegen::CodegenCppVisitor::add_variable_point_process
virtual void add_variable_point_process(std::vector< IndexVariableInfo > &variables)=0
Add the variable point_process during get_int_variables.
nmodl::codegen::naming::DEFAULT_FLOAT_TYPE
static constexpr char DEFAULT_FLOAT_TYPE[]
default float variable type
Definition: codegen_naming.hpp:111
nmodl::codegen::CodegenCppVisitor::get_int_variables
std::vector< IndexVariableInfo > get_int_variables()
Determine all int variables required during code generation.
Definition: codegen_cpp_visitor.cpp:1343
codegen_naming.hpp
nmodl::codegen::CodegenCppVisitor::nrn_thread_internal_arguments
virtual std::string nrn_thread_internal_arguments()=0
Arguments for "_threadargs_" macro in neuron implementation.
nmodl::codegen::CodegenCppVisitor::visit_function_call
void visit_function_call(const ast::FunctionCall &node) override
visit node of type ast::FunctionCall
Definition: codegen_cpp_visitor.cpp:1099
nmodl::ast::Block
Base class for all block scoped nodes.
Definition: block.hpp:41
nmodl::codegen::CodegenCppVisitor::external_method_parameters
virtual const ParamVector external_method_parameters(bool table=false) noexcept=0
Parameters for functions in generated code that are called back from external code.
nmodl::codegen::CodegenCppVisitor::position_of_int_var
virtual int position_of_int_var(const std::string &name) const =0
Determine the position in the data array for a given int variable.
nmodl::codegen::CodegenCppVisitor::print_parallel_iteration_hint
virtual void print_parallel_iteration_hint(BlockType type, const ast::Block *block)
Print pragma annotations for channel iterations.
Definition: codegen_cpp_visitor.cpp:394
nmodl::ast::LocalListStatement
TODO.
Definition: local_list_statement.hpp:39
nmodl::codegen::CodegenCppVisitor::program_symtab
symtab::SymbolTable * program_symtab
Symbol table for the program.
Definition: codegen_cpp_visitor.hpp:337
nmodl::codegen::BlockType::Equation
@ Equation
breakpoint block
nmodl::codegen::MemberType
MemberType
Helper to represent various variables types.
Definition: codegen_cpp_visitor.hpp:91
nmodl::codegen::CodegenCppVisitor::external_method_arguments
virtual const std::string external_method_arguments() noexcept=0
Arguments for external functions called from generated code.
nmodl::codegen::CodegenCppVisitor::is_net_move
bool is_net_move(const std::string &name) const noexcept
Checks if given function name is net_move.
Definition: codegen_cpp_visitor.hpp:650
nmodl::ast::Float
Represents a float variable.
Definition: float.hpp:44
nmodl::codegen::CodegenCppVisitor::print_mechanism_global_var_structure
virtual void print_mechanism_global_var_structure(bool print_initializers)=0
Print the structure that wraps all global variables used in the NMODL.
nmodl::ast::BreakpointBlock
Represents a BREAKPOINT block in NMODL.
Definition: breakpoint_block.hpp:53
nmodl::codegen::CodegenCppVisitor::print_compute_functions
virtual void print_compute_functions()=0
Print all compute functions for every backend.
nmodl::codegen::CodegenCppVisitor::codegen_global_variables
std::vector< SymbolType > codegen_global_variables
All global variables for the model.
Definition: codegen_cpp_visitor.hpp:356
nmodl::ast::IndexedName
Represents specific element of an array variable.
Definition: indexed_name.hpp:48
nmodl::codegen::CodegenCppVisitor::add_variable_tqitem
virtual void add_variable_tqitem(std::vector< IndexVariableInfo > &variables)=0
Add the variable tqitem during get_int_variables.
nmodl::ast::FunctionCall
TODO.
Definition: function_call.hpp:38
nmodl::codegen::CodegenCppVisitor::simulator_name
virtual std::string simulator_name()=0
Name of the simulator the code was generated for.
nmodl::codegen::CodegenCppVisitor::setup
virtual void setup(const ast::Program &node)
Definition: codegen_cpp_visitor.cpp:1457
nmodl::codegen::CodegenCppVisitor::visit_unary_operator
void visit_unary_operator(const ast::UnaryOperator &node) override
visit node of type ast::UnaryOperator
Definition: codegen_cpp_visitor.cpp:1084
nmodl::codegen::CodegenCppVisitor::visit_mutex_lock
void visit_mutex_lock(const ast::MutexLock &node) override
visit node of type ast::MutexLock
Definition: codegen_cpp_visitor.cpp:1109
nmodl::codegen::CodegenCppVisitor::print_net_event_call
virtual void print_net_event_call(const ast::FunctionCall &node)=0
Print call to net_event.
nmodl::codegen::CodegenCppVisitor::visit_boolean
void visit_boolean(const ast::Boolean &node) override
visit node of type ast::Boolean
Definition: codegen_cpp_visitor.cpp:940
nmodl::codegen::CodegenCppVisitor::nrn_cur_required
bool nrn_cur_required() const noexcept
Check if nrn_cur function is required.
Definition: codegen_cpp_visitor.cpp:134
nmodl::codegen::CodegenCppVisitor::ion_read_statements_optimized
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.
Definition: codegen_cpp_visitor.cpp:282
nmodl::codegen::CppObjectSpecifier::Constexpr
@ Constexpr
nmodl::codegen::CodegenCppVisitor::print_net_send_call
virtual void print_net_send_call(const ast::FunctionCall &node)=0
Print call to net_send.
nmodl::codegen::BlockType::Constructor
@ Constructor
constructor block
nmodl::codegen::CppObjectSpecifier::Explicit
@ Explicit
nmodl::codegen::CodegenCppVisitor::print_codegen_routines
virtual void print_codegen_routines()=0
Print entry point to code generation.
nmodl::ast::MutexUnlock
Represent MUTEXUNLOCK statement in NMODL.
Definition: mutex_unlock.hpp:38
code_printer.hpp
Helper class for printing C/C++ code.
nmodl::codegen::CodegenCppVisitor::visit_double
void visit_double(const ast::Double &node) override
visit node of type ast::Double
Definition: codegen_cpp_visitor.cpp:935
nmodl::codegen::CodegenCppVisitor::print_using_namespace
void print_using_namespace()
Prints f"using namespace {namespace_name()}".
Definition: codegen_cpp_visitor.cpp:658
nmodl::codegen::CodegenCppVisitor::net_send_buffer_required
bool net_send_buffer_required() const noexcept
Check if net_send_buffer is required.
Definition: codegen_cpp_visitor.cpp:111
nmodl::codegen::naming::NMODL_VERSION
static constexpr char NMODL_VERSION[]
nmodl language version
Definition: codegen_naming.hpp:21
nmodl::codegen::CodegenCppVisitor::codegen_int_variables
std::vector< IndexVariableInfo > codegen_int_variables
All int variables for the model.
Definition: codegen_cpp_visitor.hpp:349
nmodl::codegen::CodegenCppVisitor::visit_float
void visit_float(const ast::Float &node) override
visit node of type ast::Float
Definition: codegen_cpp_visitor.cpp:930
nmodl::codegen::CodegenCppVisitor::visit_string
void visit_string(const ast::String &node) override
visit node of type ast::String
Definition: codegen_cpp_visitor.cpp:915
nmodl::codegen::BlockType::Watch
@ Watch
watch block
nmodl::codegen::BlockType::NetReceive
@ NetReceive
net_receive block
nmodl::codegen::CodegenCppVisitor::visit_solution_expression
void visit_solution_expression(const ast::SolutionExpression &node) override
visit node of type ast::SolutionExpression
Definition: codegen_cpp_visitor.cpp:1121
nmodl::codegen::CodegenCppVisitor::print_nrn_pointing
virtual void print_nrn_pointing(const ast::FunctionCall &node)
Print nrn_pointing.
Definition: codegen_cpp_visitor.cpp:563
nmodl::codegen::CodegenCppVisitor::local_var_type
const char * local_var_type() const noexcept
Data type for the local variables.
Definition: codegen_cpp_visitor.hpp:458
nmodl::codegen::CodegenCppVisitor::enable_cvode
bool enable_cvode
Definition: codegen_cpp_visitor.hpp:282
nmodl::codegen::CodegenCppVisitor::print_global_var_struct_decl
virtual void print_global_var_struct_decl()
Instantiate global var instance.
Definition: codegen_cpp_visitor.cpp:500
nmodl::codegen::CodegenCppVisitor::get_channel_info_var_name
std::string get_channel_info_var_name() const noexcept
Name of channel info variable.
Definition: codegen_cpp_visitor.hpp:514
nmodl::codegen::CodegenCppVisitor::visit_var_name
void visit_var_name(const ast::VarName &node) override
Definition: codegen_cpp_visitor.cpp:963
nmodl::codegen::CodegenCppVisitor::print_function_table_call
virtual void print_function_table_call(const ast::FunctionCall &node)=0
Print special code when calling FUNCTION_TABLEs.
nmodl::codegen::CppObjectSpecifier::Extern
@ Extern
nmodl::codegen::CodegenCppVisitor::print_nmodl_constants
void print_nmodl_constants()
Print the nmodl constants used in backend code.
Definition: codegen_cpp_visitor.cpp:895
nmodl::codegen::CodegenCppVisitor::print_table_check_function
void print_table_check_function(const ast::Block &)
Print check_function() for functions or procedure using table.
Definition: codegen_cpp_visitor.cpp:1623
nmodl::ast::PrimeName
Represents a prime variable (for ODE)
Definition: prime_name.hpp:48
nmodl::codegen::CodegenCppVisitor::read_ion_variable_name
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.
Definition: codegen_cpp_visitor.cpp:437
nmodl::codegen::CodegenCppVisitor::get_arg_str
static std::string get_arg_str(const ParamVector &params)
Generate the string representing the parameters in a function call.
Definition: codegen_cpp_visitor.cpp:43
nmodl::codegen::CodegenCppVisitor::functor_params
virtual ParamVector functor_params()=0
The parameters of the Newton solver "functor".
nmodl::ast::IfStatement
TODO.
Definition: if_statement.hpp:39
codegen_info.hpp
Various types to store code generation specific information.
nmodl::ast::Boolean
Represents a boolean variable.
Definition: boolean.hpp:42
nmodl::codegen::naming::DEFAULT_INTEGER_TYPE
static constexpr char DEFAULT_INTEGER_TYPE[]
default integer variable type
Definition: codegen_naming.hpp:117
nmodl::codegen::CodegenCppVisitor::print_function_or_procedure
virtual void print_function_or_procedure(const ast::Block &node, const std::string &name, const std::unordered_set< CppObjectSpecifier > &specifiers)=0
Print nmodl function or procedure (common code)
nmodl::symtab::SymbolTable
Represent symbol table for a NMODL block.
Definition: symbol_table.hpp:57
nmodl::codegen::CodegenCppVisitor::is_nrn_pointing
bool is_nrn_pointing(const std::string &name) const noexcept
Definition: codegen_cpp_visitor.hpp:640
nmodl::codegen::CodegenCppVisitor::visit_integer
void visit_integer(const ast::Integer &node) override
visit node of type ast::Integer
Definition: codegen_cpp_visitor.cpp:924
nmodl::ast::EigenLinearSolverBlock
Represent linear solver solution block based on Eigen.
Definition: eigen_linear_solver_block.hpp:38
nmodl::codegen::CodegenCppVisitor::printing_net_receive
bool printing_net_receive
true if currently net_receive block being printed
Definition: codegen_cpp_visitor.hpp:368
nmodl::ast::UpdateDt
Statement to indicate a change in timestep in a given block.
Definition: update_dt.hpp:38
nmodl::codegen::CodegenCppVisitor::get_table_statement
const ast::TableStatement * get_table_statement(const ast::Block &)
Definition: codegen_cpp_visitor.cpp:1732
nmodl::codegen::CodegenCppVisitor::print_global_variables_for_hoc
virtual void print_global_variables_for_hoc()=0
Print byte arrays that register scalar and vector variables for hoc interface.
nmodl::ast::Statement
TODO.
Definition: statement.hpp:38
nmodl::codegen::CppObjectSpecifier::ThreadLocal
@ ThreadLocal
nmodl::codegen::CodegenCppVisitor::format_float_string
std::string format_float_string(const std::string &value)
Convert a given float value to its string representation.
Definition: codegen_cpp_visitor.cpp:206
nmodl::codegen::CodegenCppVisitor::check_if_var_is_array
std::tuple< bool, int > check_if_var_is_array(const std::string &name)
Check if the given name exist in the symbol.
Definition: codegen_cpp_visitor.cpp:1745
nmodl::codegen::CodegenCppVisitor::is_functor_const
bool is_functor_const(const ast::StatementBlock &variable_block, const ast::StatementBlock &functor_block)
Checks whether the functor_block generated by sympy solver modifies any variable outside its scope.
Definition: codegen_cpp_visitor.cpp:732
nmodl::codegen::CppObjectSpecifier::Inline
@ Inline
nmodl::codegen::CodegenCppVisitor::get_parameter_str
static std::string get_parameter_str(const ParamVector &params)
Generate the string representing the procedure parameter declaration.
Definition: codegen_cpp_visitor.cpp:52
nmodl::codegen::CodegenCppVisitor::needs_v_unused
virtual bool needs_v_unused() const =0
nmodl::codegen::CodegenCppVisitor::print_nrn_cur
virtual void print_nrn_cur()=0
Print nrn_cur / current update function definition.
nmodl::codegen::CodegenCppVisitor::is_net_send
bool is_net_send(const std::string &name) const noexcept
Checks if given function name is net_send.
Definition: codegen_cpp_visitor.hpp:636
nmodl::ast::StatementBlock
Represents block encapsulating list of statements.
Definition: statement_block.hpp:53
nmodl::codegen::CodegenCppVisitor::print_nrn_cur_kernel
virtual void print_nrn_cur_kernel(const ast::BreakpointBlock &node)=0
Print main body of nrn_cur function.
nmodl::codegen::CodegenCppVisitor::net_receive_required
bool net_receive_required() const noexcept
Check if net_receive function is required.
Definition: codegen_cpp_visitor.cpp:149
nmodl::codegen::CodegenCppVisitor::float_variable_name
virtual std::string float_variable_name(const SymbolType &symbol, bool use_instance) const =0
Determine the name of a float variable given its symbol.
nmodl::codegen::CodegenCppVisitor::internal_method_arguments
virtual std::string internal_method_arguments()=0
Arguments for functions that are defined and used internally.
nmodl::codegen::CodegenCppVisitor::global_struct
std::string global_struct() const
Name of structure that wraps global variables.
Definition: codegen_cpp_visitor.hpp:436
nmodl::ast::ParenExpression
TODO.
Definition: paren_expression.hpp:38
nmodl::codegen::CodegenInfo::electrode_current
bool electrode_current
if electrode current specified
Definition: codegen_info.hpp:368
nmodl::codegen::CodegenCppVisitor::internal_method_parameters
virtual ParamVector internal_method_parameters()=0
Parameters for internally defined functions.
nmodl::codegen::CodegenCppVisitor::print_nrn_destructor
virtual void print_nrn_destructor()=0
Print nrn_destructor function definition.
nmodl::codegen::CodegenCppVisitor::visit_local_list_statement
void visit_local_list_statement(const ast::LocalListStatement &node) override
visit node of type ast::LocalListStatement
Definition: codegen_cpp_visitor.cpp:992
nmodl::codegen::ShadowUseStatement
Represents ion write statement during code generation.
Definition: codegen_cpp_visitor.hpp:166
nmodl::ast::ProcedureBlock
TODO.
Definition: procedure_block.hpp:39
nmodl::codegen::CodegenCppVisitor::print_mechanism_range_var_structure
virtual void print_mechanism_range_var_structure(bool print_initializers)=0
Print the structure that wraps all range and int variables required for the NMODL.
nmodl::codegen::CodegenCppVisitor::make_symbol
SymbolType make_symbol(const std::string &name) const
Creates a temporary symbol.
Definition: codegen_cpp_visitor.hpp:1075
nmodl::codegen::CodegenCppVisitor::float_type
std::string float_type
Data type of floating point variables.
Definition: codegen_cpp_visitor.hpp:319
nmodl::ast::BinaryOperator
Operator used in ast::BinaryExpression.
Definition: binary_operator.hpp:38
nmodl::codegen::CodegenCppVisitor::defined_method
bool defined_method(const std::string &name) const
Check if given method is defined in this model.
Definition: codegen_cpp_visitor.cpp:164
nmodl::codegen::naming::NET_MOVE_METHOD
static constexpr char NET_MOVE_METHOD[]
net_move function call in nmodl
Definition: codegen_naming.hpp:48
logger.hpp
Implement logger based on spdlog library.
nmodl::codegen::CodegenCppVisitor::node_data_struct
std::string node_data_struct() const
Name of structure that wraps node variables.
Definition: codegen_cpp_visitor.hpp:424
nmodl::codegen::IndexVariableInfo::is_vdata
bool is_vdata
if variable resides in vdata field of NrnThread typically true for bbcore pointer
Definition: codegen_cpp_visitor.hpp:133
nmodl::codegen::CodegenCppVisitor::print_function_call
virtual void print_function_call(const ast::FunctionCall &node)
Print call to internal or external function.
Definition: codegen_cpp_visitor.cpp:505
nmodl::ast::SolutionExpression
Represent solution of a block in the AST.
Definition: solution_expression.hpp:38
nmodl::codegen::CodegenCppVisitor::process_shadow_update_statement
std::string process_shadow_update_statement(const ShadowUseStatement &statement, BlockType type)
Process shadow update statement.
Definition: codegen_cpp_visitor.cpp:340
nmodl::SymbolType
parser::NmodlParser::symbol_type SymbolType
Definition: main_nmodl.cpp:33
nmodl::codegen::CodegenCppVisitor::enable_variable_name_lookup
bool enable_variable_name_lookup
Variable name should be converted to instance name (but not for function arguments)
Definition: codegen_cpp_visitor.hpp:362
nmodl::codegen::BlockType
BlockType
Helper to represent various block types.
Definition: codegen_cpp_visitor.hpp:56
nmodl::codegen::CodegenCppVisitor::current_watch_statement
int current_watch_statement
Index of watch statement being printed.
Definition: codegen_cpp_visitor.hpp:392
nmodl::codegen::naming::NET_EVENT_METHOD
static constexpr char NET_EVENT_METHOD[]
net_event function call in nmodl
Definition: codegen_naming.hpp:45
nmodl::codegen::CodegenCppVisitor::print_fast_imem_calculation
virtual void print_fast_imem_calculation()=0
Print fast membrane current calculation code.
nmodl::codegen::naming::NRN_POINTING_METHOD
static constexpr char NRN_POINTING_METHOD[]
nrn_pointing function in nmodl
Definition: codegen_naming.hpp:54
nmodl::codegen::CodegenCppVisitor::print_mechanism_register
virtual void print_mechanism_register()=0
Print the mechanism registration function.
nmodl::codegen::CodegenCppVisitor::breakpoint_current
std::string breakpoint_current(std::string current) const
Determine the variable name for the "current" used in breakpoint block taking into account intermedia...
Definition: codegen_cpp_visitor.cpp:363
nmodl::codegen::CodegenCppVisitor::visit_binary_operator
void visit_binary_operator(const ast::BinaryOperator &node) override
visit node of type ast::BinaryOperator
Definition: codegen_cpp_visitor.cpp:1079
nmodl::codegen::CodegenCppVisitor::visit_else_if_statement
void visit_else_if_statement(const ast::ElseIfStatement &node) override
visit node of type ast::ElseIfStatement
Definition: codegen_cpp_visitor.cpp:1011
nmodl::codegen::CppObjectSpecifier::Volatile
@ Volatile
nmodl::codegen::CppObjectSpecifier::ExternC
@ ExternC
nmodl::codegen::CodegenCppVisitor
Visitor for printing C++ code compatible with legacy api of CoreNEURON
Definition: codegen_cpp_visitor.hpp:241
nmodl::codegen::CodegenCppVisitor::CodegenCppVisitor
CodegenCppVisitor(std::string mod_filename, std::ostream &stream, std::string float_type, const bool optimize_ionvar_copies, std::unique_ptr< nmodl::utils::Blame > blame=nullptr)
Constructs the C++ code generator visitor.
Definition: codegen_cpp_visitor.hpp:259
nmodl::codegen::CodegenCppVisitor::instance_struct
std::string instance_struct() const
Name of structure that wraps range variables.
Definition: codegen_cpp_visitor.hpp:417
nmodl::codegen::CodegenCppVisitor::compute_method_name
std::string compute_method_name(BlockType type) const
Definition: codegen_cpp_visitor.cpp:1485
nmodl::ast::Name
Represents a name.
Definition: name.hpp:44
nmodl::codegen::CodegenCppVisitor::visit_program
void visit_program(const ast::Program &program) override
Main and only member function to call after creating an instance of this class.
Definition: codegen_cpp_visitor.cpp:1508
nmodl::codegen::CodegenCppVisitor::mod_filename
std::string mod_filename
Name of mod file (without .mod suffix)
Definition: codegen_cpp_visitor.hpp:313
nmodl::codegen::CodegenCppVisitor::get_variable_name
virtual std::string get_variable_name(const std::string &name, bool use_instance=true) const =0
Determine variable name in the structure of mechanism properties.
nmodl::ast::Program
Represents top level AST node for whole NMODL input.
Definition: program.hpp:39
nmodl::codegen::CodegenCppVisitor::visit_indexed_name
void visit_indexed_name(const ast::IndexedName &node) override
visit node of type ast::IndexedName
Definition: codegen_cpp_visitor.cpp:982
nmodl::codegen::CodegenCppVisitor::operator_for_rhs
const char * operator_for_rhs() const noexcept
Operator for rhs vector update (matrix update)
Definition: codegen_cpp_visitor.hpp:498
nmodl::codegen::CodegenCppVisitor::print_prcellstate_macros
void print_prcellstate_macros() const
Print declaration of macro NRN_PRCELLSTATE for debugging.
Definition: codegen_cpp_visitor.cpp:619
nmodl::codegen::CppObjectSpecifier::Static
@ Static
nmodl::codegen::CodegenCppVisitor::printer
std::unique_ptr< CodePrinter > printer
Code printer object for target (C++)
Definition: codegen_cpp_visitor.hpp:307
nmodl::codegen::CodegenCppVisitor::print_rename_state_vars
void print_rename_state_vars() const
Definition: codegen_cpp_visitor.cpp:1759
nmodl::codegen::CodegenCppVisitor::nrn_state_required
bool nrn_state_required() const noexcept
Check if nrn_state function is required.
Definition: codegen_cpp_visitor.cpp:126
nmodl::codegen::BlockType::State
@ State
derivative block
nmodl::codegen::CodegenCppVisitor::add_escape_quote
std::string add_escape_quote(const std::string &text) const
Add quotes to string to be output.
Definition: codegen_cpp_visitor.hpp:1048
nmodl::ast::ElseStatement
TODO.
Definition: else_statement.hpp:38
nmodl::codegen::CodegenCppVisitor::internal_method_call_encountered
bool internal_method_call_encountered
true if internal method call was encountered while processing verbatim block
Definition: codegen_cpp_visitor.hpp:386
nmodl::codegen::CodegenCppVisitor::print_v_unused
virtual void print_v_unused() const =0
Set v_unused (voltage) for NRN_PRCELLSTATE feature.
nmodl::codegen::CodegenCppVisitor::method_name
std::string method_name(const std::string &name) const
Constructs the name of a function or procedure.
Definition: codegen_cpp_visitor.hpp:1058
nmodl::codegen::CodegenCppVisitor::is_net_event
bool is_net_event(const std::string &name) const noexcept
Checks if given function name is net_event.
Definition: codegen_cpp_visitor.hpp:660
nmodl::ast::BinaryExpression
Represents binary expression in the NMODL.
Definition: binary_expression.hpp:52
nmodl::codegen::CodegenCppVisitor::thread_variables_struct
std::string thread_variables_struct() const
Definition: codegen_cpp_visitor.hpp:428
nmodl::codegen::CodegenCppVisitor::print_headers_include
virtual void print_headers_include()=0
Print all includes.
nmodl::codegen::CppObjectSpecifier::Const
@ Const
nmodl::codegen::CodegenCppVisitor::codegen_float_variables
std::vector< SymbolType > codegen_float_variables
All float variables for the model.
Definition: codegen_cpp_visitor.hpp:343
nmodl::printer::CodePrinter
Helper class for printing C/C++ code.
Definition: code_printer.hpp:44
nmodl::codegen::BlockType::Initial
@ Initial
initial block
nmodl::codegen::CodegenCppVisitor::statement_to_skip
static bool statement_to_skip(const ast::Statement &node)
Check if given statement should be skipped during code generation.
Definition: codegen_cpp_visitor.cpp:87
nmodl::codegen::CppObjectSpecifier::Virtual
@ Virtual
nmodl::codegen::CodegenCppVisitor::namespace_name
virtual std::string namespace_name()=0
Name of "our" namespace.
nmodl::codegen::CodegenCppVisitor::ion_read_statements
std::vector< std::string > ion_read_statements(BlockType type) const
For a given output block type, return statements for all read ion variables.
Definition: codegen_cpp_visitor.cpp:252
nmodl::codegen::CodegenCppVisitor::print_functors_definitions
void print_functors_definitions()
Print all Newton functor structs.
Definition: codegen_cpp_visitor.cpp:768
nmodl::codegen::BlockType::BeforeAfter
@ BeforeAfter
before / after block
nmodl::codegen::CodegenCppVisitor::print_data_structures
virtual void print_data_structures(bool print_initializers)=0
Print all classes.
nmodl::codegen::CodegenCppVisitor::format_double_string
std::string format_double_string(const std::string &value)
Convert a given double value to its string representation.
Definition: codegen_cpp_visitor.cpp:201
nmodl::ModToken
Represent token returned by scanner.
Definition: modtoken.hpp:50
nmodl::codegen::get_index_from_name
int get_index_from_name(const std::vector< T > &variables, const std::string &name)
Definition: codegen_cpp_visitor.hpp:185
nmodl::codegen::CodegenCppVisitor::print_namespace_stop
void print_namespace_stop()
Prints the end of the simulator namespace.
Definition: codegen_cpp_visitor.cpp:668
nmodl::ast::Ast::get_node_name
virtual std::string get_node_name() const
Return name of of the node.
Definition: ast.cpp:28
nmodl::ast::String
Represents a string.
Definition: string.hpp:52
nmodl::codegen::CodegenCppVisitor::print_nrn_state
virtual void print_nrn_state()=0
Print nrn_state / state update function definition.
nmodl::codegen::CodegenCppVisitor::backend_name
virtual std::string backend_name() const =0
Name of the code generation backend.
nmodl::ast::FromStatement
TODO.
Definition: from_statement.hpp:38
nmodl::codegen::CodegenCppVisitor::print_function_prototypes
virtual void print_function_prototypes()=0
Print function and procedures prototype declaration.
nmodl::codegen::naming::NET_SEND_METHOD
static constexpr char NET_SEND_METHOD[]
net_send function call in nmodl
Definition: codegen_naming.hpp:51
nmodl::codegen::CodegenCppVisitor::print_nrn_alloc
virtual void print_nrn_alloc()=0
Print nrn_alloc function definition.
nmodl::codegen::CodegenCppVisitor::visit_while_statement
void visit_while_statement(const ast::WhileStatement &node) override
visit node of type ast::WhileStatement
Definition: codegen_cpp_visitor.cpp:1025
nmodl::codegen::MemberType::range
@ range
range / double variables
nmodl::codegen::CodegenCppVisitor::ParamVector
std::vector< std::tuple< std::string, std::string, std::string, std::string > > ParamVector
A vector of parameters represented by a 4-tuple of strings:
Definition: codegen_cpp_visitor.hpp:297
nmodl::codegen::CodegenCppVisitor::visit_statement_block
void visit_statement_block(const ast::StatementBlock &node) override
Definition: codegen_cpp_visitor.cpp:1094
ast_visitor.hpp
Concrete visitor for all AST classes.