modules.cpp
No OneTemporary

File Metadata

Created
Wed, Jul 8, 9:15 AM

modules.cpp

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* modules.cpp
*
* Author: pgess <v.melnychenko@xreate.org>
* Created on July 22, 2017, 5:13 PM
*/
/**
* \file modules.h
* \brief Modules support
*/
#include "modules.h"
#include "modules/Parser.h"
#include "analysis/utils.h"
#include <clingo/clingocontrol.hh>
#include <boost/format.hpp>
#include <regex>
#include <boost/filesystem.hpp>
#include <fstream>
using namespace std;
namespace fs = boost::filesystem;
namespace xreate { namespace modules{
void
ModuleRecord::addRequest(const Expression& request){
__requests.push_back(request);
}
void
ModuleRecord::addControllerPath(const std::string& path){
__controllers.push_back(path);
}
void
ModuleRecord::addDiscoveryPath(const std::string& path){
__discoveryPaths.push_back(path);
}
void
ModuleRecord::addProperty(const Expression& prop){
__properties.push_back(prop);
}
void
ModulesSolver::loadControllers(const ModuleRecord& module){
for (const std::string& pathController: module.__controllers){
std::fstream fileContent(pathController);
__program << fileContent.rdbuf();
}
}
void
ModulesSolver::extractProperties(const ModuleRecord& module){
// const std::string atomProperty = "bind_module";
// boost::format formatProperty(atomProperty + "(\"%1%\", %2%).");
//
// for (const Expression& property: module.__properties){
// std::list<std::string> reprProp = xreate::analysis::compile(property);
// assert(reprProp.size()== 1);
//
// __program << (formatProperty % module.__path % reprProp.front())
// << std::endl;
// }
}
void
ModulesSolver::discoverModules(const ModuleRecord& moduleClient){
std::regex extXreate("\\.xreate$", std::regex::basic);
for(const std::string& path: moduleClient.__discoveryPaths){
for(fs::directory_entry e: fs::recursive_directory_iterator(path)) {
if (fs::is_regular_file(e.status())){
if (!std::regex_search(e.path().string(), extXreate)) continue;
FILE* script = fopen(e.path().c_str(), "r");
Scanner scanner(script);
Parser parser(&scanner);
parser.Parse();
assert(!parser.errors->count && "Discovery errors");
parser.module.__path = e.path().c_str();
extractProperties(parser.module);
fclose(script);
}
}
}
}
void
ModulesSolver::extractRequirements(const ModuleRecord& module){
// const std::string atomQuery = "modules_require";
// boost::format formatProperty(atomQuery + "(\"%1%\", %2%).");
//
// for (const Expression& query: module.__requests){
// std::list<std::string> reprQuery = xreate::analysis::compile(query);
// assert(reprQuery.size()== 1);
//
// __program << (formatProperty % module.__path % reprQuery.front())
// << std::endl;
// }
}
void
ModulesSolver::add(const std::string& base){
__program << base;
}
void
ModulesSolver::init(const std::string& programBase, const ModuleRecord& module){
add(programBase);
extractRequirements(module);
extractProperties(module);
loadControllers(module);
discoverModules(module);
std::cout << __program.str() << std::endl;
}
std::list<std::string>
ModulesSolver::run(const ModuleRecord& module){
const std::string predicateResolution = "modules_resolution";
std::map<Expression, string> dictResolution;
std::vector<char const *> args{"clingo", nullptr};
DefaultGringoModule moduleDefault;
Gringo::Scripts scriptsDefault(moduleDefault);
ClingoLib ctl(scriptsDefault, 0, args.data(), {}, 0);
ctl.add("base", {}, __program.str());
ctl.ground({{"base", {}}}, nullptr);
ctl.solve([&predicateResolution, this, &dictResolution, &module](Gringo::Model const &model) {
for (Gringo::Symbol atom : model.atoms(clingo_show_type_atoms)) {
std::cout << atom << std::endl;
if (std::strcmp(atom.name().c_str(), predicateResolution.c_str())!=0) continue;
if (atom.arity() == 2){
auto resolution = TranscendLayer::parse<Expression, std::string>(atom);
dictResolution.emplace(get<0>(resolution), get<1>(resolution));
continue;
}
if (atom.arity() == 3){
auto resolution = TranscendLayer::parse<Expression, std::string, std::string>(atom);
if(get<2>(resolution) != module.__path) continue;
dictResolution.emplace(get<0>(resolution), get<1>(resolution));
continue;
}
assert(false && "Wrong resolution format");
}
return true;
}, {});
std::list<std::string> result;
for(const Expression& request: module.__requests){
assert(dictResolution.count(request) && "Can't find requested module");
result.push_back(dictResolution.at(request));
}
return result;
}
}} //namespace xreate::modules

Event Timeline