User Guide
main.cpp
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 #include <CLI/CLI.hpp>
9 #include <filesystem>
10 
11 #include "ast/program.hpp"
12 #include "config/config.h"
13 #include "parser/nmodl_driver.hpp"
14 #include "pybind/pyembed.hpp"
15 #include "utils/logger.hpp"
16 #include "visitors/ast_visitor.hpp"
33 
34 
35 using namespace nmodl;
36 using namespace visitor;
37 namespace fs = std::filesystem;
38 
39 /**
40  * \file
41  * \brief Standalone program demonstrating usage of different visitors and driver classes.
42  **/
43 
44 template <typename T>
45 struct ClassInfo {
46  std::shared_ptr<T> v;
47  std::string id;
48  std::string description;
49 };
52 
53 template <typename Visitor>
54 void visit_program(const std::string& mod_file,
55  const ClassInfo<Visitor>& visitor,
56  ast::Program& ast) {
57  logger->info("Running {}", visitor.description);
58  visitor.v->visit_program(ast);
59  const std::string file = fmt::format("{}.{}.mod", mod_file, visitor.id);
60  NmodlPrintVisitor(file).visit_program(ast);
61  logger->info("NMODL visitor generated {}", file);
62 };
63 
64 int main(int argc, const char* argv[]) {
65  CLI::App app{
66  fmt::format("NMODL Visitor : Runs standalone visitor classes({})", Version::to_string())};
67 
68  bool verbose = false;
69  std::vector<fs::path> files;
70 
71  app.add_flag("-v,--verbose", verbose, "Enable debug log level");
72  app.add_option("-f,--file,file", files, "One or more MOD files to process")
73  ->required()
74  ->check(CLI::ExistingFile);
75 
76  CLI11_PARSE(app, argc, argv);
77 
78  if (verbose) {
79  logger->set_level(spdlog::level::debug);
80  }
81 
82  const std::vector<VisitorInfo> visitors = {
83  {std::make_shared<AstVisitor>(), "astvis", "AstVisitor"},
84  {std::make_shared<SymtabVisitor>(), "symtab", "SymtabVisitor"},
85  {std::make_shared<VerbatimVarRenameVisitor>(),
86  "verbatim-rename",
87  "VerbatimVarRenameVisitor"},
88  {std::make_shared<KineticBlockVisitor>(), "kinetic-rewrite", "KineticBlockVisitor"},
89  {std::make_shared<ConstantFolderVisitor>(), "const-fold", "ConstantFolderVisitor"},
90  {std::make_shared<InlineVisitor>(), "inline", "InlineVisitor"},
91  {std::make_shared<LocalVarRenameVisitor>(), "local-rename", "LocalVarRenameVisitor"},
92  {std::make_shared<SymtabVisitor>(), "symtab", "SymtabVisitor"},
93  {std::make_shared<SympyConductanceVisitor>(),
94  "sympy-conductance",
95  "SympyConductanceVisitor"},
96  {std::make_shared<SympySolverVisitor>(), "sympy-solve", "SympySolverVisitor"},
97  {std::make_shared<NeuronSolveVisitor>(), "neuron-solve", "NeuronSolveVisitor"},
98  {std::make_shared<UnitsVisitor>(NrnUnitsLib::get_path()), "units", "UnitsVisitor"},
99  };
100 
101  const std::vector<ConstVisitorInfo> const_visitors = {
102  {std::make_shared<JSONVisitor>(), "json", "JSONVisitor"},
103  {std::make_shared<test::CheckParentVisitor>(), "check-parent", "CheckParentVisitor"},
104  {std::make_shared<PerfVisitor>(), "perf", "PerfVisitor"},
105  {std::make_shared<LocalizeVisitor>(), "localize", "LocalizeVisitor"},
106  {std::make_shared<VerbatimVisitor>(), "verbatim", "VerbatimVisitor"},
107  };
108 
110 
111  for (const auto& filename: files) {
112  logger->info("Processing {}", filename.string());
113 
114  const std::string mod_file = filename.stem().string();
115 
116  /// driver object that creates lexer and parser
118 
119  /// shared_ptr to ast constructed from parsing nmodl file
120  const auto& ast = driver.parse_file(filename);
121 
122  /// run all visitors and generate mod file after each run
123  for (const auto& visitor: visitors) {
124  visit_program(mod_file, visitor, *ast);
125  }
126  for (const auto& visitor: const_visitors) {
127  visit_program(mod_file, visitor, *ast);
128  }
129  }
130 
132 
133  return 0;
134 }
ClassInfo::id
std::string id
Definition: main.cpp:47
ClassInfo::v
std::shared_ptr< T > v
Definition: main.cpp:46
nmodl::parser::NmodlDriver
Class that binds all pieces together for parsing nmodl file.
Definition: nmodl_driver.hpp:67
nmodl::pybind_wrappers::EmbeddedPythonLoader::get_instance
static EmbeddedPythonLoader & get_instance()
Construct (if not already done) and get the only instance of this class.
Definition: pyembed.hpp:29
localize_visitor.hpp
Visitor to transform global variable usage to local
perf_visitor.hpp
Visitor for measuring performance related information
ClassInfo::description
std::string description
Definition: main.cpp:48
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
ClassInfo
Definition: main.cpp:45
constant_folder_visitor.hpp
Perform constant folding of integer/float/double expressions.
nmodl::logger
logger_type logger
Definition: logger.cpp:34
nmodl::pybind_wrappers::pybind_wrap_api::initialize_interpreter
decltype(&initialize_interpreter_func) initialize_interpreter
Definition: wrapper.hpp:61
kinetic_block_visitor.hpp
Visitor for kinetic block statements
nmodl::pybind_wrappers::pybind_wrap_api::finalize_interpreter
decltype(&finalize_interpreter_func) finalize_interpreter
Definition: wrapper.hpp:62
sympy_conductance_visitor.hpp
Visitor for generating CONDUCTANCE statements for ions
program.hpp
Auto generated AST classes declaration.
driver
nmodl::parser::UnitDriver driver
Definition: parser.cpp:28
verbatim_var_rename_visitor.hpp
Rename variable in verbatim block.
nmodl::pybind_wrappers::EmbeddedPythonLoader::api
const pybind_wrap_api & api()
Get a pointer to the pybind_wrap_api struct.
Definition: pyembed.cpp:135
local_var_rename_visitor.hpp
Visitor to rename local variables conflicting with global scope
nmodl::Version::to_string
static std::string to_string()
return version string (version + git id) as a string
Definition: config.h:39
verbatim_visitor.hpp
Visitor for verbatim blocks of AST
units_visitor.hpp
Visitor for Units blocks of AST.
logger.hpp
Implement logger based on spdlog library.
visit_program
void visit_program(const std::string &mod_file, const ClassInfo< Visitor > &visitor, ast::Program &ast)
Definition: main.cpp:54
neuron_solve_visitor.hpp
Visitor that solves ODEs using old solvers of NEURON
checkparent_visitor.hpp
Visitor for checking parents of ast nodes
inline_visitor.hpp
Visitor to inline local procedure and function calls
nmodl_driver.hpp
config.h
Version information and units file path.
nmodl::ast::Program
Represents top level AST node for whole NMODL input.
Definition: program.hpp:39
symtab_visitor.hpp
THIS FILE IS GENERATED AT BUILD TIME AND SHALL NOT BE EDITED.
main
int main(int argc, const char *argv[])
Definition: main.cpp:656
json_visitor.hpp
THIS FILE IS GENERATED AT BUILD TIME AND SHALL NOT BE EDITED.
nmodl::NrnUnitsLib::get_path
static std::string get_path()
Return path of units database file.
Definition: config.h:54
nmodl::parser::UnitDriver::parse_file
bool parse_file(const std::string &filename)
parse Units file
Definition: unit_driver.cpp:29
sympy_solver_visitor.hpp
Visitor for systems of algebraic and differential equations
nmodl_visitor.hpp
THIS FILE IS GENERATED AT BUILD TIME AND SHALL NOT BE EDITED.
pyembed.hpp
ast_visitor.hpp
Concrete visitor for all AST classes.