9
#include "simodo/interpret/Interpret.h"
10
#include "simodo/module/ModuleManagement.h"
11
#include "simodo/module/CodeSupplier.h"
12
#include "simodo/module/HardModuleLoader.h"
13
#include "simodo/module/SoftModule.h"
14
#include "simodo/inout/convert/functions.h"
15
#include "simodo/bormental/DrBormental.h"
16
#include "simodo/inout/format/fmt.h"
20
#if __cplusplus >= __cpp_2017
22
namespace fs = std::filesystem;
24
#include <experimental/filesystem>
25
namespace fs = std::filesystem::experimental;
28
#include <boost/dll/import.hpp>
30
namespace dll = boost::dll;
36
std::vector<std::string> makeSemanticsPlaces(const std::string & loom_dir)
38
fs::path path_to_loom_root(loom_dir);
40
path_to_loom_root += "/bin/semantics";
42
return {path_to_loom_root.lexically_normal().string()};
45
std::vector<std::string> makeHardModulePlaces(const std::string & loom_dir)
47
fs::path path_to_loom_root(loom_dir);
49
path_to_loom_root += "/bin/modules";
51
return {path_to_loom_root.lexically_normal().string()};
54
std::vector<std::string> makeGrammarsPlaces(const std::string & loom_dir)
56
fs::path path_to_loom_root(loom_dir);
58
path_to_loom_root += "/data/grammar";
60
return {path_to_loom_root.lexically_normal().string()};
65
namespace simodo::module
67
ModuleManagement::ModuleManagement( inout::Reporter_abstract & m,
68
inout::InputStreamSupplier_interface & stream_supplier,
69
const std::string & simodo_root_path,
70
interpret::InterpretFactory_interface & interpret_factory,
71
interpret::SemanticDataCollector_interface & semantic_data_collector)
73
, _stream_supplier(stream_supplier)
74
, _simodo_root_path(simodo_root_path)
75
, _interpret_factory(interpret_factory)
76
, _semantic_data_collector(semantic_data_collector)
77
, _hard_module_loader(makeHardModulePlaces(simodo_root_path))
79
_code_generator = std::make_unique<CodeSupplier>(_m, makeGrammarsPlaces(simodo_root_path), _stream_supplier,
80
_interpret_factory, _semantic_data_collector);
81
loadSemanticModules();
83
_interpret_factory.setSemanticFactories(semantic_factories());
86
std::shared_ptr<variable::Module_interface> ModuleManagement::loadHardModule(const std::string & module_name,
87
interpret::Interpret_interface * interpret)
89
return _hard_module_loader.load(module_name, interpret);
92
const ast::Node * ModuleManagement::getCode(const std::string & module_name, const inout::uri_set_t & files)
95
const ast::Node * node = _code_generator->getCode(module_name, files);
100
bool ModuleManagement::isTheModuleLoaded(const std::string & module_name)
102
return _modules.find(module_name) != _modules.end();
105
std::shared_ptr<variable::Module_interface> ModuleManagement::registerSoftModule(const std::string & module_name, std::shared_ptr<variable::Object> module)
107
auto it = _modules.find(module_name);
108
if (it != _modules.end())
109
return std::shared_ptr<variable::Module_interface>();
111
auto [it_new, ok] = _modules.insert({module_name, std::make_shared<SoftModule>(module)});
113
return std::shared_ptr<variable::Module_interface>();
115
return it_new->second;
118
std::shared_ptr<variable::Object> ModuleManagement::produceObject(const std::string & module_name,
119
interpret::Interpret_interface * interpret)
122
auto it = _modules.find(module_name);
124
if (it != _modules.end())
125
return it->second->instantiate(it->second).getObject();
127
std::shared_ptr<variable::Module_interface> module;
128
fs::path path_to_module {module_name};
129
std::string extension {path_to_module.extension().string()};
131
if (extension.empty() || extension == ".") {
132
HardModuleLoader hard_module_loader(makeHardModulePlaces(_simodo_root_path));
134
module = hard_module_loader.load(module_name,interpret);
138
_m.reportFatal(hard_module_loader.last_error());
149
return std::shared_ptr<variable::Object>();
151
version_t v = module->version();
152
if (v.major() != LibVersion_Major || v.minor() > LibVersion_Minor) {
154
_m.reportFatal(inout::fmt("Incorrect version of module '%1'").arg(module_name));
155
return std::shared_ptr<variable::Object>();
158
_modules.insert({module_name, module});
163
return module->instantiate(module).getObject();
166
void ModuleManagement::loadSemanticModules()
168
std::vector<std::string> semantics_places = makeSemanticsPlaces(_simodo_root_path);
170
for(const std::string & interpret_folder_name : semantics_places)
171
if (!interpret_folder_name.empty()) {
172
fs::path path_to_interpret_folder { interpret_folder_name };
174
for (auto const & f : fs::directory_iterator{path_to_interpret_folder})
175
if (f.path().extension() == ".simodo-semantics") {
176
std::function<InterpretFactory_t> creator = nullptr;
181
creator = dll::import_alias<InterpretFactory_t>(f.path().string().c_str(),"create_simodo_interpret");
184
catch(std::runtime_error & e) {
185
throw bormental::DrBormental("ModuleManagement::loadSemanticModules", e.what());
188
_semantic_factories.push_back(creator(*this));