No OneTemporary

File Metadata

Created
Sat, Mar 14, 4:46 AM
diff --git a/config/default.json b/config/default.json
index 28e521b..383c9d5 100644
--- a/config/default.json
+++ b/config/default.json
@@ -1,73 +1,73 @@
{
"containers": {
"id": {
"implementations": "impl_fulfill_cluster",
"clusters": "var_cluster",
"prototypes": "proto_cluster",
"linkedlist": "linkedlist"
},
"impl": {
"solid": "solid",
"onthefly": "on_the_fly"
}
},
"logging": {
"id": "logging"
},
"function-entry": "entry",
"clasp": {
"bindings" : {
"variable": "bind",
"function": "bind_func",
"scope": "bind_scope",
"function_demand" : "bind_function_demand",
"scope_decision": "bind_scope_decision"
},
"context" : {
"decisions":{
"dependent": "resolution_dependency"
},
},
"nonevalue": "nonevalue",
"ret": {
"symbol": "retv",
"tag": "ret"
}
},
"tests": {
"template": "containers",
"templates": {
"default": "*-",
"basic": "Basic.*",
"ast": "AST.*",
"cfa": "CFA.*",
"dfa": "DFA.*",
"compilation": "Compilation.*",
- "containers": "Containers.Inference*-",
+ "containers": "Containers.*-",
"diagnostic": "Diagnostic.*",
"serializer": "ExpressionSerializer.*",
"externc": "InterfaceExternC.*",
"context": "ExpressionSerializer.*:Context.*",
"types": "Types.*-",
"log": "Logging*",
"clang": "ClangAPI.*",
"skip": "SkipDetection*:Adhoc_Loop_SkipDetection.*",
"raw-xml": "libxml2*",
"xml": "Xml.*",
"installation": "Compilation.*:Sprint1.*",
"exploitation": "Exploitation.*",
"loops": "Loop.*",
"dsl": "Interpretation.*",
"adhocs": "Adhoc.*",
}
}
}
diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt
index 2200b02..454cdd4 100644
--- a/cpp/src/CMakeLists.txt
+++ b/cpp/src/CMakeLists.txt
@@ -1,217 +1,216 @@
cmake_minimum_required(VERSION 2.8.11)
project(xreate)
cmake_policy(SET CMP0022 NEW)
# LLVM
#======================
#FIND_PACKAGE (LLVM REQUIRED CONFIG PATHS PATH-TO-CMAKE-DIR NO_DEFAULT_PATH)
FIND_PACKAGE (LLVM REQUIRED)
set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake-tools")
#include(PCH_GCC4_v2)
set(LLVM_VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR})
message ("LLVM LIB PATH:" ${LLVM_LIBRARY_DIRS})
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
message ("MPATH:" ${CMAKE_MODULE_PATH})
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
message(STATUS "INCLUDE DIR: ${LLVM_INCLUDE_DIRS}")
INCLUDE_DIRECTORIES(${LLVM_INCLUDE_DIRS})
message("LLVM defs: " ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS})
llvm_map_components_to_libnames(LLVM_LIBS core nativecodegen native executionengine mcjit support)
message("LLVM libs: " ${LLVM_LIBS})
# CLANG
#======================
set(CLANG_LIBS
${LLVM_LIBRARY_DIRS}/libclangCodeGen.so
${LLVM_LIBRARY_DIRS}/libclangASTMatchers.so
${LLVM_LIBRARY_DIRS}/libclangQuery.so
${LLVM_LIBRARY_DIRS}/libclangTooling.so
${LLVM_LIBRARY_DIRS}/libclangFrontend.so
${LLVM_LIBRARY_DIRS}/libclangSerialization.so
${LLVM_LIBRARY_DIRS}/libclangDriver.so
${LLVM_LIBRARY_DIRS}/libclangParse.so
${LLVM_LIBRARY_DIRS}/libclangSema.so
${LLVM_LIBRARY_DIRS}/libclangAnalysis.so
${LLVM_LIBRARY_DIRS}/libclangAST.so
${LLVM_LIBRARY_DIRS}/libclangEdit.so
${LLVM_LIBRARY_DIRS}/libclangLex.so
${LLVM_LIBRARY_DIRS}/libclangBasic.so
)
#find_package(Clang REQUIRED clangTooling libClang)
message(STATUS "CLANG LIBS: " ${CLANG_LIBS})
# POTASSCO
#======================
set(POTASSCO_PATH "/opt/potassco/clingo" CACHE PATH "Path to potassco sources")
set(POTASSCO_INCLUDE_PATH
${POTASSCO_PATH}/libgringo
${POTASSCO_PATH}/libclasp
${POTASSCO_PATH}/libclingo
${POTASSCO_PATH}/libprogram_opts
${POTASSCO_PATH}/liblp
)
INCLUDE_DIRECTORIES(${POTASSCO_INCLUDE_PATH})
set (LIBCLASP_PATH ${POTASSCO_PATH}/build/debug)
set(LIBCLASP_LIBS
clingo
clasp
gringo
program_opts
reify
lp
)
message(STATUS "CLASP LIBS: " ${LIBCLASP_LIBS})
link_directories(${LIBCLASP_PATH})
# OTHER DEPENDENCIES
#===========================
set(JEAYESON_INCLUDE_PATH
${CMAKE_HOME_DIRECTORY}/../vendors/jeayeson/include/
)
INCLUDE_DIRECTORIES(${JEAYESON_INCLUDE_PATH})
# COCO
#===========================
set(COCO_PATH ${CMAKE_HOME_DIRECTORY}/../coco/)
set(COCO_SOURCE_FILES
${COCO_PATH}/Parser.cpp
${COCO_PATH}/Scanner.cpp)
INCLUDE_DIRECTORIES(${COCO_PATH})
add_custom_command(OUTPUT ${COCO_SOURCE_FILES}
COMMAND ${COCO_PATH}/gen-grammar
WORKING_DIRECTORY ${COCO_PATH}
MAIN_DEPENDENCY ${COCO_PATH}/xreate.ATG
)
message(STATUS "COCO GRAMMAR BUILD STATUS:" ${COCO_OUTPUT})
# XREATE
#======================
set(SOURCE_FILES
clasplayer.cpp
pass/compilepass.cpp
pass/interpretationpass.cpp
compilation/targetinterpretation.cpp
ast.cpp
ExternLayer.cpp
attachments.cpp
analysis/cfagraph.cpp
analysis/dfagraph.cpp
analysis/aux.cpp
compilation/containers.cpp
compilation/advanced.cpp
compilation/transformations.cpp
- analysis/DominatorsTreeAnalysisProvider.cpp
compilation/latecontextcompiler2.cpp
query/context.cpp
#compilation/latecontextcompiler.cpp
serialization/expressionserializer.cpp
- serialization/expressionserializer2.cpp
+# serialization/expressionserializer2.cpp
llvmlayer.cpp
utils.cpp
passmanager.cpp
pass/abstractpass.cpp pass/dfapass.cpp
pass/cfapass.cpp
pass/loggerpass.cpp
pass/adhocpass.cpp
query/containers.cpp
contextrule.cpp
#query/ptrvalid.cpp
#pass/rulespass.cpp #
)
set(XREATE_INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/
)
INCLUDE_DIRECTORIES(${XREATE_INCLUDE_DIRS})
set(XREATE_PRIVATE_INCLUDE_DIRS
${XREATE_INCLUDE_DIRS}
${COCO_PATH}
${JEAYESON_INCLUDE_PATH}
${LLVM_INCLUDE_DIRS}
${POTASSCO_INCLUDE_PATH}
)
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${COCO_SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${LIBCLASP_LIBS})
target_include_directories(${PROJECT_NAME} INTERFACE
${XREATE_INCLUDE_DIRS}
${COCO_PATH}
${JEAYESON_INCLUDE_PATH}
${LLVM_INCLUDE_DIRS}
${POTASSCO_INCLUDE_PATH}
)
get_directory_property(DEFINITIONS_ALL DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS)
message("definitions all: " ${DEFINITIONS_ALL})
target_compile_definitions(${PROJECT_NAME} INTERFACE ${DEFINITIONS_ALL})
get_directory_property(COMPILATION_OPTIONS_ALL DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_OPTIONS)
message("compilations all: " ${COMPILATION_OPTIONS_ALL})
target_compile_options(${PROJECT_NAME} INTERFACE ${COMPILATION_OPTIONS_ALL})
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY
INTERFACE_LINK_LIBRARIES ${LLVM_LIBS} ${CLANG_LIBS} tbb
)
#set (LINK_INTERFACE_LIBRARIES "")
# FUNCTION(PREPEND var prefix)
# SET(listVar "")
# FOREACH(f ${ARGN})
# LIST(APPEND listVar "${prefix}/${f}")
# ENDFOREACH(f)
# SET(${var} "${listVar}" PARENT_SCOPE)
# ENDFUNCTION(PREPEND)
#set(COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "-j4")
#cotire(xreate)
# MACRO (ADD_PCH_RULE _header_filename _src_list)
# SET(_gch_filename "${_header_filename}.gch")
# LIST(APPEND ${_src_list} ${_gch_filename})
# SET (_args ${CMAKE_CXX_FLAGS})
# LIST(APPEND _args -c ${_header_filename} -o ${_gch_filename})
# GET_DIRECTORY_PROPERTY(DIRINC INCLUDE_DIRECTORIES)
# foreach (_inc ${DIRINC})
# LIST(APPEND _args "-I" ${_inc})
# endforeach(_inc ${DIRINC})
# SEPARATE_ARGUMENTS(_args)
# add_custom_command(OUTPUT ${_gch_filename}
# COMMAND rm -f ${_gch_filename}
# COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} ${_args}
# DEPENDS ${_header_filename})
# ENDMACRO(ADD_PCH_RULE _header_filename _src_list)
# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/ast.h SOURCE_FILES)
# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/llvmlayer.h SOURCE_FILES)
# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/clasplayer.h SOURCE_FILES)
# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/pass/abstractpass.h SOURCE_FILES)
diff --git a/cpp/src/clasplayer.cpp b/cpp/src/clasplayer.cpp
index 09b2026..b171d05 100644
--- a/cpp/src/clasplayer.cpp
+++ b/cpp/src/clasplayer.cpp
@@ -1,313 +1,308 @@
#include "clasplayer.h"
#include <iostream>
#include "utils.h"
#include <boost/format.hpp>
#include <boost/algorithm/string/join.hpp>
#include <gringo/scripts.hh>
#include "analysis/aux.h"
-#include "analysis/DominatorsTreeAnalysisProvider.h"
#include "analysis/cfagraph.h"
#include "analysis/dfagraph.h"
using namespace std;
//TODO escape identifiers started from upper case symbol
namespace xreate {
void
ClaspLayer::printWarnings(std::ostream& out)
{
const std::string warningTag = "warning";
auto warningsRange = __model.equal_range(warningTag);
for (auto warning=warningsRange.first; warning!= warningsRange.second; ++warning) {
unsigned int warningId;
Gringo::Symbol params;
std::tie(warningId, params) = parse<unsigned int, Gringo::Symbol>(warning->second);
cout << "Warning: " << __warnings.at(warningId) << " ";
params.print(out);
out<<params;
}
}
bool
ClaspLayer::handleSolution(Gringo::Model const &model) {
std::list<std::string> warnings;
cout << "Model: " << endl;
const string& atomBindVar = Config::get("clasp.bindings.variable");
const string& atomBindFunc = Config::get("clasp.bindings.function");
const string& atomBindScope = Config::get("clasp.bindings.scope");
for (Gringo::Symbol atom : model.atoms(clingo_show_type_atoms)) {
atom.print(cout);
cout <<" | "<< endl;
string atomName(atom.name().c_str());
if (atomName == atomBindVar || atomName == atomBindFunc || atomName == atomBindScope){
string name = std::get<1>(parse<Gringo::Symbol, Gringo::Symbol>(atom)).name().c_str();
__model.emplace(move(name), move(atom));
}
__model.emplace(atomName, move(atom));
}
return true;
}
void
ClaspLayer::setCFAData(xreate::analysis::CFAGraph* graph) {
dataCFA.reset(graph);
}
void
ClaspLayer::setDFAData(xreate::analysis::DFAGraph* graph){
dataDFA.reset(graph);
}
void
ClaspLayer::addRuleWarning(const RuleWarning &rule) {
//__partGeneral << rule << endl;
list<string> domains;
boost::format formatDef("%1%(%2%)");
std::transform(rule.__args.begin(), rule.__args.end(), std::inserter(domains, domains.begin()),
[&formatDef](const std::pair<std::string, DomainAnnotation> &argument) {
string domain;
switch (argument.second) {
case DomainAnnotation::FUNCTION:
domain = "function";
break;
case DomainAnnotation::VARIABLE:
domain = "variable";
break;
}
return boost::str(formatDef % domain % argument.first);
});
list<string> vars;
std::transform(rule.__args.begin(), rule.__args.end(), std::inserter(vars, vars.begin()),
[](const std::pair<std::string, DomainAnnotation> &argument) {
return argument.first.c_str();
});
list<list<string>> guardsRaw;
std::transform(rule.__guards.begin(), rule.__guards.end(), std::inserter(guardsRaw, guardsRaw.begin()),
[this](const Expression &guard) {
return xreate::analysis::compile(guard);
});
const list<string>& guards = xreate::analysis::multiplyLists(std::move(guardsRaw));
list<string> &&branches = xreate::analysis::compileNeg(rule.__condition);
boost::format formatWarning("warning(%1%, (%2%)):- %3%, %4%, %5%.");
for (const string &guardsJoined: guards)
for (const string &branch: branches) {
unsigned int hook = registerWarning(string(rule.__message));
__partGeneral << formatWarning
%(hook)
%(boost::algorithm::join(vars, ", "))
%(branch)
%(guardsJoined)
%(boost::algorithm::join(domains, ", "))
<<endl;
}
}
unsigned int
ClaspLayer::registerWarning(std::string &&message) {
static int warningId = 0;
__warnings.emplace(warningId, message);
return warningId++;;
}
void
ClaspLayer::involveImports() {
ostream &out = __partGeneral;
for (string fn: ast->__rawImports)
{
std::ifstream file(fn);
if (!file) continue;
while(!file.eof()){
string line;
std::getline(file, line);
out << line << endl;
}
}
}
void
ClaspLayer::addRawScript(std::string&& script){
__partGeneral << script;
}
void
ClaspLayer::run() {
involveImports();
if (this->dataDFA){
this->dataDFA->print(__partGeneral);
}
if (this->dataCFA){
this->dataCFA->print(__partGeneral);
}
- DominatorsTreeAnalysisProvider providerDominators;
- providerDominators.run(this);
- providerDominators.print(__partGeneral);
-
ostringstream program;
program << __partTags.str() << __partGeneral.str();
cout << FYEL(program.str()) << endl;
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);
// solve
Gringo::SolveResult result = ctl.solve([this](Gringo::Model const &model) {
this->handleSolution(model);
return true;
}, {});
if (result.satisfiable() == Gringo::SolveResult::Satisfiable) {
cout << FGRN("SUCCESSFULLY") << endl;
} else {
cout << FRED("UNSUCCESSFULLY") << endl;
}
// invoke all query plugins to process clasp data
for (auto q: __queries)
{
q.second->init(this);
}
}
bool
ClaspLayer::checkScript(std::string&& script, std::string&& atomCheckSuccess){
//init
std::vector<char const *> args{"clingo", nullptr};
DefaultGringoModule moduleDefault;
Gringo::Scripts scriptsDefault(moduleDefault);
ClingoLib ctl(scriptsDefault, 0, args.data(), {}, 0);
ctl.add("base", {}, script);
ctl.ground({{"base", {}}}, nullptr);
bool flagCheck = false;
Gringo::SolveResult result = ctl.solve([this, &flagCheck, &atomCheckSuccess](Gringo::Model const &model) {
for (Gringo::Symbol atom : model.atoms(clingo_show_type_atoms)) {
atom.print(cout);
cout << endl;
string atomName(atom.name().c_str());
if (atomName == atomCheckSuccess){
flagCheck = true;
break;
}}
return true;
}, {});
if (!result.satisfiable()){
return false;
}
return flagCheck;
}
ClaspLayer::ClaspLayer() {
}
ClaspLayer::ModelFragment
ClaspLayer::query(const std::string& atom)
{
if (! __model.count(atom)){
return boost::none;
}
return ModelFragment(__model.equal_range(atom));
}
ScopePacked
ClaspLayer::pack(CodeScope* const scope) {
auto pos = __indexScopes.emplace(scope, __indexScopes.size());
if (pos.second)
__registryScopes.push_back(scope);
return pos.first->second;
}
size_t
ClaspLayer::getScopesCount() const{
return __registryScopes.size();
}
SymbolPacked
ClaspLayer::pack(const Symbol& symbol, std::string hintSymbolName)
{
SymbolPacked result;
result.scope = pack(symbol.scope);
result.identifier = symbol.identifier;
__indexSymbolNameHints.emplace(result, hintSymbolName);
return result;
}
Symbol
ClaspLayer::unpack(const SymbolPacked& symbol)
{
return Symbol{symbol.identifier, __registryScopes[symbol.scope]};
};
std::string
ClaspLayer::getHintForPackedSymbol(const SymbolPacked& symbol){
if (!symbol.categoryTransient) {
auto result = __indexSymbolNameHints.find(symbol);
return (result == __indexSymbolNameHints.end())? "" : result->second;
} else {
return "anonym(" + to_string(symbol.identifier) + ")";
}
}
bool operator==(const SymbolPacked& s1, const SymbolPacked& s2)
{
return s1.identifier == s2.identifier && s1.scope == s2.scope;
}
bool operator<(const SymbolPacked& s1, const SymbolPacked& s2)
{
return s1.scope < s2.scope || (s1.scope == s2.scope && s1.identifier < s2.identifier);
}
IQuery*
ClaspLayer::registerQuery(IQuery *query, const QueryId& id) {
return __queries.emplace(id, query).first->second;
}
IQuery*
ClaspLayer::getQuery(const QueryId& id){
assert(__queries.count(id) && "Undefined query");
return __queries.at(id);
}
}
diff --git a/cpp/src/serialization/expressionserializer.cpp b/cpp/src/serialization/expressionserializer.cpp
index 42b5a15..0b571ed 100644
--- a/cpp/src/serialization/expressionserializer.cpp
+++ b/cpp/src/serialization/expressionserializer.cpp
@@ -1,303 +1,318 @@
/*
* expressionserializer.cpp
*
* Created on: Jan 4, 2016
* Author: pgess
*/
#include "serialization/expressionserializer.h"
+#include <boost/utility.hpp>
+#include <boost/utility/in_place_factory.hpp>
+
#include <cmath>
using namespace std;
//using namespace boost::bimaps;
namespace xreate {
struct Index {
string name;
size_t degree; //count of parameters
unsigned char level; //level in expression tree (depth of tree layer)
bool operator< (const Index other) const{
if (name != other.name) return name < other.name;
if (degree != other.degree) return degree < other.degree;
if (name != other.name) return level < other.level;
return false;
}
};
class ExpressionSerializerPrivate {
//boost::bimap<Index, multiset_of<size_t>> __registry;
struct {
map<Index,size_t> left;
} __registry;
map<unsigned char, size_t> __range;
public:
void pack(const Expression& e, unsigned char level, OptionalPackedExpression& target){
if (!target) return;
switch (e.op){
case Operator::NONE: {
switch (e.__state) {
case Expression::NUMBER:
case Expression::STRING:
case Expression::IDENT : {
Index index;
if ((e.__state == Expression::NUMBER))
index = {std::to_string(e.getValueDouble()), 0, level};
else index = {e.getValueString(), 0, level};
if (!__registry.left.count(index)){
target = boost::none;
return;
}
size_t id = __registry.left.at(index);
size_t range = __range[level];
(*target) << make_pair(id, range);
return;
}
default: break;
}
break;
}
case Operator::CALL: {
Index index{e.getValueString(), e.operands.size(), level};
if(!__registry.left.count(index)){
target = boost::none;
return;
}
size_t id = __registry.left.at(index);
size_t range = __range[level];
(*target) << make_pair(id, range);
for (const Expression& operand: e.operands){
pack(operand, level+1, target);
}
return;
}
default: break;
}
assert(false && "Expression too complicate for serialization");
}
void registerExpression(const Expression&e, unsigned char level){
switch (e.op){
case Operator::CALL: {
Index index{e.getValueString(), e.operands.size(), level};
if (__registry.left.insert(make_pair(index, __range[level])).second){
__range[level]++;
}
for (const Expression& operand: e.operands){
registerExpression(operand, level+1);
}
return;
}
case Operator::NONE: {
Index index;
switch (e.__state) {
case Expression::STRING:
case Expression::IDENT: {
index = {e.getValueString(), 0, level};
if (__registry.left.insert(make_pair(index, __range[level])).second){
__range[level]++;
}
return;
}
case Expression::NUMBER: {
index = {std::to_string(e.getValueDouble()), 0, level};
if (__registry.left.insert(make_pair(index, __range[level])).second){
__range[level]++;
}
return;
}
default: break;
}
break;
}
default: break;
}
assert(false && "Expression too complicate for serialization");
}
};
ExpressionSerializer::ExpressionSerializer()
: strategy(new ExpressionSerializerPrivate()){
}
ExpressionSerializer::~ExpressionSerializer() {
delete strategy;
}
void
ExpressionSerializer::registerExpression(const Expression&e){
if (e.isValid())
strategy->registerExpression(e, 0);
}
PackedExpression
ExpressionSerializer::getId(const Expression& e){
- OptionalPackedExpression result(move(PackedExpression()));
+ OptionalPackedExpression result(boost::in_place());
+ //move(PackedExpression())
+
strategy->pack(e, 0, result);
assert(result);
return move(*result);
}
OptionalPackedExpression
ExpressionSerializer::getIdOptional(const Expression& e) const{
- OptionalPackedExpression result(move(PackedExpression()));
+ OptionalPackedExpression result(boost::in_place());
+ //move(PackedExpression())
+
strategy->pack(e, 0, result);
return result;
}
ExpressionSerializerIntegral::ExpressionSerializerIntegral():serializer(*this){}
ExpressionSerializerIntegral::ExpressionSerializerIntegral(const std::vector<Expression>&& expressions)
: std::vector<Expression>(move(expressions)), serializer(*this){
size_t id =0;
for (const Expression& e: expressions){
__registry.emplace(serializer.getId(e), id++);
}
}
size_t
ExpressionSerializerIntegral::size() const{
return PARENT::size();
}
size_t
ExpressionSerializerIntegral::count(const Expression& e) const {
return (getIdOptional(e)? 1: 0);
}
ExpressionSerializerIntegral::const_iterator
ExpressionSerializerIntegral::begin() const {
return PARENT::begin();
}
ExpressionSerializerIntegral::const_iterator
ExpressionSerializerIntegral::end() const {
return PARENT::end();
}
size_t
ExpressionSerializerIntegral::getId(const Expression& e) const{
- const auto& exprPacked = serializer.getIdOptional(e);
+ const OptionalPackedExpression exprPacked = serializer.getIdOptional(e);
assert(exprPacked);
return __registry.at(*exprPacked);
}
boost::optional<size_t>
ExpressionSerializerIntegral::getIdOptional(const Expression& e) const{
- const auto& exprPacked = serializer.getIdOptional(e);
+ const OptionalPackedExpression exprPacked = serializer.getIdOptional(e);
if (!exprPacked){
return boost::none;
}
return __registry.at(*exprPacked);
}
const Expression&
ExpressionSerializerIntegral::get(size_t id) const{
return at(id);
}
void
PackedExpression::operator<< (const std::pair<size_t, size_t>& value){
static const size_t sizeSizeT = sizeof(size_t);
const size_t& id = value.first;
const size_t& range = value.second;
int countSufficientBits = range <=1? 0 : ceil(log2(range));
if (0 < countRemainedBits && countRemainedBits < countSufficientBits) {
size_t* tail = reinterpret_cast<size_t*>(__storage + size- sizeSizeT);
(*tail) += id >> (countSufficientBits - countRemainedBits);
countSufficientBits-=countRemainedBits;
countRemainedBits = 0;
}
if (countRemainedBits == 0) {
if (countSufficientBits == 0) return;
char* __storageNew = new char[size+sizeSizeT];
std::memcpy (__storageNew, __storage, size);
std::memset(__storageNew + size, 0, sizeSizeT);
delete[] __storage;
__storage = __storageNew;
size += sizeSizeT;
countRemainedBits = 8 * sizeSizeT;
}
if (countRemainedBits >= countSufficientBits) {
size_t* tail = reinterpret_cast<size_t*>(__storage + size- sizeSizeT);
(*tail) += id << (countRemainedBits - countSufficientBits);
countRemainedBits -= countSufficientBits;
return;
}
assert("Unreachable block");
}
+ #if BOOST_VERSION <= 105500
+PackedExpression::PackedExpression(const PackedExpression& other){
+ __storage = other.__storage;
+ size = other.size;
+ countRemainedBits = other.countRemainedBits;
+}
+ #endif
+
PackedExpression::PackedExpression(PackedExpression&& other){
__storage = other.__storage;
size = other.size;
countRemainedBits = other.countRemainedBits;
other.__storage = nullptr;
}
bool
PackedExpression::operator==(const PackedExpression& other) const{
if (size == other.size && countRemainedBits == other.countRemainedBits){
return std::memcmp(__storage, other.__storage, size) == 0 ;
}
return false;
}
bool
PackedExpression::operator<(const PackedExpression& other) const{
if (size < other.size) { return true; }
if (countRemainedBits < other.countRemainedBits) return true;
if (size == other.size && countRemainedBits == other.countRemainedBits){
return std::memcmp(__storage, other.__storage, size) < 0 ;
}
return false;
}
bool
PackedExpression::operator!=(const PackedExpression& other) const{
return ! ((*this) == other);
}
PackedExpression::~PackedExpression() {
delete[] __storage;
}
//PackedExpression::PackedExpression (const PackedExpression& other)
// : size(other.size), countRemainedBits(other.countRemainedBits)
//{
// __storage = new char[size];
// std::memcpy (__storage, other.__storage, size);
//}
} /* namespace xreate */
diff --git a/cpp/src/serialization/expressionserializer.h b/cpp/src/serialization/expressionserializer.h
index 9acf8c4..ad8cc66 100644
--- a/cpp/src/serialization/expressionserializer.h
+++ b/cpp/src/serialization/expressionserializer.h
@@ -1,103 +1,111 @@
/*
* expressionserializer.h
*
* Created on: Jan 4, 2016
* Author: pgess
*/
#ifndef SRC_EXPRESSIONSERIALIZER_H_
#define SRC_EXPRESSIONSERIALIZER_H_
#include "ast.h"
#include <string>
#include <boost/optional.hpp>
+#include <boost/version.hpp>
namespace xreate {
struct PackedExpression{
PackedExpression(){};
PackedExpression(PackedExpression&& other);
+
+ #if BOOST_VERSION <= 105500
+ PackedExpression (const PackedExpression&);
+
+ #else
+ PackedExpression (const PackedExpression&)=delete;
+ #endif
+
~PackedExpression();
void operator<< (const std::pair<size_t, size_t>& value);
char* operator*(){return __storage;}
bool operator==(const PackedExpression& other) const;
bool operator!=(const PackedExpression& other) const;
bool operator<(const PackedExpression& other) const;
private:
- PackedExpression (const PackedExpression&)=delete;
PackedExpression& operator=(const PackedExpression&)=delete;
PackedExpression& operator=(PackedExpression&&)=delete;
char* __storage = nullptr;
size_t size =0;
unsigned char countRemainedBits =0;
};
typedef boost::optional<PackedExpression> OptionalPackedExpression;
class ExpressionSerializerPrivate;
class ExpressionSerializer {
public:
template<class Container>
ExpressionSerializer(const Container& source): ExpressionSerializer(){
for (const Expression& e: source) {
registerExpression(e);
}
}
template<class Container, class Transformer>
ExpressionSerializer(const Container& source, Transformer op): ExpressionSerializer(){
for (const typename Container::value_type& e: source) {
registerExpression(op(e));
}
}
ExpressionSerializer(ExpressionSerializer&& other)
: strategy(other.strategy) {other.strategy = 0; }
virtual ~ExpressionSerializer();
PackedExpression getId(const Expression& e);
OptionalPackedExpression getIdOptional(const Expression& e) const;
private:
ExpressionSerializerPrivate* strategy;
void registerExpression(const Expression&e);
ExpressionSerializer();
};
class ExpressionSerializerIntegral: private std::vector<Expression>{
typedef std::vector<Expression> PARENT;
public:
ExpressionSerializerIntegral();
ExpressionSerializerIntegral(const std::vector<Expression>&& expressions);
template<class Iterator>
ExpressionSerializerIntegral(Iterator first, Iterator last)
: ExpressionSerializerIntegral(std::vector<Expression>(first, last)){}
ExpressionSerializerIntegral(ExpressionSerializerIntegral&& other)
: PARENT(std::move(other)), __registry(std::move(other.__registry)), serializer(std::move(other.serializer)){}
size_t getId(const Expression& e) const;
boost::optional<size_t> getIdOptional(const Expression& e) const;
const Expression& get(size_t id) const;
size_t size() const;
size_t count(const Expression& e) const;
ExpressionSerializerIntegral::const_iterator begin() const;
ExpressionSerializerIntegral::const_iterator end() const;
private:
ExpressionSerializerIntegral(const ExpressionSerializerIntegral&)=delete;
std::map<PackedExpression, size_t> __registry;
ExpressionSerializer serializer;
};
} /* namespace xreate */
#endif /* SRC_EXPRESSIONSERIALIZER_H_ */
diff --git a/cpp/tests/ExpressionSerializer.cpp b/cpp/tests/ExpressionSerializer.cpp
deleted file mode 100644
index c5dc128..0000000
--- a/cpp/tests/ExpressionSerializer.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * testExpressionSerializer.cpp
- *
- * Created on: Jan 4, 2016
- * Author: pgess
- */
-
-#include "serialization/expressionserializer.h"
-#include "serialization.h"
-#include "ast.h"
-#include "gtest/gtest.h"
-
-using namespace xreate;
-using namespace std;
-
-TEST(ExpressionSerializer, pack1){
- PackedExpression x;
-
- x << std::make_pair(0xA1, 0x100);
- size_t* storage = reinterpret_cast<size_t*> (*x);
- ASSERT_EQ(0xA100000000000000, *storage);
-
- x << std::make_pair(0x23456, 0x100000);
- ASSERT_EQ(0xA123456000000000, *storage);
-
- x << std::make_pair(0x7654321, 0x10000000);
- ASSERT_EQ(0xA123456765432100, *storage);
-
-
- x << std::make_pair(0xABBA, 0x10000);
- storage = reinterpret_cast<size_t*> (*x);
- ASSERT_EQ(0xA1234567654321AB, *storage);
- ASSERT_EQ(0xBA00000000000000, *(storage+1));
-}
-
-TEST(ExpressionSerializer, serialize1){
- Expression a(Operator::CALL, {Expression(string("a")), Expression(string("a"))});
- Expression b(Operator::CALL, {Expression(string("a")), Expression(string("b"))});
-
- ExpressionSerializer serializer(vector<Expression>{a, b});
-
- PackedExpression packA = serializer.getId(a);
- PackedExpression packB = serializer.getId(b);
- PackedExpression packA2 = serializer.getId(a);
-
- ASSERT_EQ(packA, packA2);
- ASSERT_NE(packA, packB);
-}
-
-TEST(ExpressionSerializer, serialize2){
- Expression a(Operator::CALL, {Expression(string("a")), Expression(string("a"))});
- Expression b(Operator::CALL, {Expression(string("a")), Expression(string("b"))});
- Expression c(Atom<Identifier_t>("c"));
-
- typedef ExpressionSerialization<RequirementIntegralCode>::Serializer Serializer;
- Serializer serializer(vector<Expression>{a, b});
-
- ASSERT_EQ(2, serializer.size());
- ASSERT_EQ(1, serializer.count(a));
- ASSERT_EQ(1, serializer.count(b));
- ASSERT_EQ(0, serializer.count(c));
-
- Serializer serializer2(move(serializer));
- ASSERT_EQ(1, serializer2.count(a));
-}
diff --git a/cpp/tests/cfa.cpp b/cpp/tests/cfa.cpp
deleted file mode 100644
index f01028c..0000000
--- a/cpp/tests/cfa.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * testsCFG.cpp
- *
- * Created on: Jul 17, 2015
- * Author: pgess
- */
-
-#include "passmanager.h"
-#include "pass/dfapass.h"
-#include "pass/cfapass.h"
-
-#include "analysis/DominatorsTreeAnalysisProvider.h"
-
-#include "gtest/gtest.h"
-
-#include <boost/scoped_ptr.hpp>
-#include <boost/smart_ptr/scoped_array.hpp>
-
-using namespace xreate;
-using namespace std;
-
-TEST(CFA, testFunctionAnnotationsClasp){
- string&& program =
- "f2 = function::int; annotationF2 {\n"
- " 0\n"
- "}\n"
- "\n"
- "f1 = function:: int; entry; annotationF1 {\n"
- " f2() + 10\n"
- "}";
-
-
- PassManager* man = PassManager::prepareForCode(move(program));
- man->runWithoutCompilation();
-
- ClaspLayer::ModelFragment answer = man->clasp->query("annotationF1");
- int countNoneValue = 0;
- if (answer) countNoneValue = std::distance(answer->first, answer->second);
- EXPECT_EQ(1, countNoneValue);
-
- answer = man->clasp->query("annotationF2");
- countNoneValue = 0;
- if (answer) countNoneValue = std::distance(answer->first, answer->second);
-
- EXPECT_EQ(1, countNoneValue);
-}
-
-TEST(CFA, testLoopContextExists){
- PassManager* man = PassManager::prepareForCode (
- "interface(cfa){\n"
- " operator fold:: annotation1.\n"
- "}\n"
- "\n"
- "main = function:: int; entry {\n"
- " x = [1..10]:: [int].\n"
- " sum = loop fold (x->el:: int, 0->sum):: int {\n"
- " el + sum + f1()\n"
- " }. \n"
- " sum\n"
- "}"
- "case context:: annotation1 {"
- " f1 = function::int {\n"
- " x = 0:: int. "
- " x\n"
- " }"
- "}"
- );
-
- man->runWithoutCompilation();
- ClaspLayer::ModelFragment model = man->clasp->query("annotation1");
- ScopePacked scopeIdActual = std::get<0>(ClaspLayer::parse<ScopePacked>(model->first->second));
-
- CodeScope* scopeEntry = man->root->findFunction("main")->getEntryScope();
- Symbol symbSum = man->root->findFunction("main")->getEntryScope()->findSymbol("sum");
- CodeScope* scopeExpected = scopeEntry->findDeclaration(symbSum).blocks.front();
-
- ScopePacked scopeIdExpected = man->clasp->pack(scopeExpected);
- ASSERT_EQ(scopeIdExpected, scopeIdActual);
-}
-
-TEST(CFA, CFGRoots){
- std::string program =
-R"CODE(
- main = function::int{a()+ b()}
- a= function::int {c1() + c2()}
- b= function::int {c2()}
- c1=function::int{0}
- c2=function::int{0}
-)CODE";
-
- boost::scoped_ptr<PassManager> manager
- (PassManager::prepareForCode(move(program)));
-
- manager->registerPass(new CFAPass(manager.get()) , PassId::CFGPass);
- manager->executePasses();
- manager->clasp->run();
-
- DominatorsTreeAnalysisProvider domProvider;
- domProvider.run(manager->clasp);
-
- DominatorsTreeAnalysisProvider::Dominators expectedFDom= {
- {0, {0, 9}}
- ,{1, {1, 4}}
- ,{2, {7, 8}}
- ,{3, {2, 3}}
- ,{4, {5, 6}}
- };
-
- DominatorsTreeAnalysisProvider::Dominators expectedPostDom= {
- {0, {5, 6}}
- ,{1, {3, 4}}
- ,{2, {8, 9}}
- ,{3, {1, 2}}
- ,{4, {7, 10}}
- };
-
- ASSERT_EQ(expectedFDom, domProvider.getForwardDominators());
- ASSERT_EQ(expectedPostDom, domProvider.getPostDominators());
-}
diff --git a/cpp/tests/context.cpp b/cpp/tests/context.cpp
deleted file mode 100644
index 847dab1..0000000
--- a/cpp/tests/context.cpp
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * frame-context.cpp
- *
- * Created on: Dec 3, 2015
- * Author: pgess
- */
-
-#include "passmanager.h"
-#include "query/context.h"
-
-#include "gtest/gtest.h"
-#include <iostream>
-#include <boost/scoped_ptr.hpp>
-
-using namespace xreate;
-
-TEST(Context, frame_Context1){
- PassManager* man = PassManager::prepareForCode(
- " import raw (\"core/control-context.lp\")\n"
- " compute = function::int {\n"
- " 0\n"
- " }\n"
-
- " computeFast = function:: int {\n"
- " context:: computation(fast).\n"
-
- " compute()\n"
- " }\n"
-
- " computePrecisely = function:: int {\n"
- " context:: computation(precise). \n"
-
- " compute()\n"
- " }\n"
-
- "test = function(cmnd:: int):: int; entry {\n"
- " context:: arithmetic(iee754). \n"
-
- " if (cmnd > 0)::int {computePrecisely()} else {computeFast()} \n"
- "}\n"
- );
-
- ContextQuery* query = (ContextQuery*) man->clasp->registerQuery(new ContextQuery(), QueryId::ContextQuery);
- man->runWithoutCompilation();
-
- CodeScope* scopeTestC = man->root->findFunction("compute")->getEntryScope();
- const Domain& context = query->getContext(man->clasp->pack(scopeTestC));
-
- int contextSize = context.size();
- EXPECT_EQ(1, contextSize); //arithmetic(iee754)
-}
-
-TEST(Context, contextAsRequirementSuccessful1){
- PassManager* man = PassManager::prepareForCode(
- " import raw (\"core/control-context.lp\")\n"
-
- " case context::safe {\n"
- " funcSensitive = function::int {\n"
- " 0\n"
- " }}\n"
-
- " test = function:: int; entry {\n"
- " context:: safe; test.\n"
-
- " funcSensitive()\n"
- " }\n"
- );
-
- int (*main)() = (int (*)()) man->run();
- ASSERT_EQ(0, main());
-}
-
-TEST(Context, contextAsRequirementFailed){
- PassManager* man = PassManager::prepareForCode(
- " import raw (\"core/control-context.lp\")\n"
-
- " case context::safe {\n"
- " funcSensitive = function::int {\n"
- " 0\n"
- " }}\n"
-
- " test = function:: int; entry {\n"
- " context:: non_safe; test.\n"
-
- " funcSensitive()\n"
- " }\n"
- );
-
- ASSERT_DEATH(man->run(), "findFunction");
-}
-
-TEST(Context, ContextPropagationNested){
- PassManager* man = PassManager::prepareForCode(
- " import raw (\"core/control-context.lp\")\n"
-
- " case context::safe {\n"
- " square = function(x:: int) ::int {\n"
- " x * x\n"
- " }}\n"
-
- " test = function:: int; entry {\n"
- " context:: safe; test.\n"
-
- " range = [1..10]:: [int]. \n"
- " loop fold(range->x::int, 0->acc):: int { \n"
- " acc + square(x) \n"
- " } \n"
- " }\n"
- );
-
- int (*main)() = (int (*)()) man->run();
- ASSERT_EQ(385, main());
-}
-
-TEST(Context, ContextPropagationNestedInterfunction){
-
- PassManager* man = PassManager::prepareForCode(
- " import raw (\"core/control-context.lp\")\n"
- " case context::toMillimeters {\n"
- " convertConcrete = function(source:: num)::num {\n"
- " 10 * source \n"
- " }\n"
- " }\n"
-
- " case context::toInches {\n"
- " convertConcrete = function(source:: num)::num {\n"
- " 2 * source \n"
- " }\n"
- " }\n"
-
- "convert= function(source:: num):: num { \n"
- "convertConcrete(source) \n"
- "} \n"
-
- "test = function(source:: num):: num; entry {\n"
- " context:: toMillimeters.\n"
- " convert(1)\n"
- "}\n" );
-
- int (*main)(int) = (int (*)(int)) man->run();
- ASSERT_EQ(10, main(1));
-}
-
-TEST(Context, full_ContextBasedFunctionSpecialization){
-
- PassManager* man = PassManager::prepareForCode(
- " import raw (\"core/control-context.lp\")\n"
- " case context::toMillimeters {\n"
- " convert = function(source:: num)::num {\n"
- " 10 * source \n"
- " }\n"
- " }\n"
-
- " case context::toInches {\n"
- " convert = function(source:: num)::num {\n"
- " 2 * source \n"
- " }\n"
- " }\n"
-
- "test = function(vrnt:: int)::int; entry {\n"
- " switch(vrnt):: int\n"
- " case 0 {\n"
- " context:: toMillimeters.\n"
- " convert(1)\n"
- " }\n"
- "\n"
- " case 1 {\n"
- " context:: toInches.\n"
- " convert(1)\n"
- " }\n"
- " case default {0}\n"
- " }" );
-
- int (*main)(int) = (int (*)(int)) man->run();
- ASSERT_EQ(10, main(0));
- ASSERT_EQ(2, main(1));
-}
-
-//TOODO recover context loop and enable the test
-TEST(Context, full_LoopContext){
-
- PassManager* man = PassManager::prepareForCode(
- " import raw (\"core/control-context.lp\")\n"
- " case context:: a {\n"
- " print = function:: string {\n"
- " \"a\"\n"
- " }}\n"
- "\n"
- " case context:: b {\n"
- " print = function:: string {\n"
- " \"b\"\n"
- " }}\n"
- "\n"
- " case context:: c {\n"
- " print = function:: string {\n"
- " \"c\"\n"
- " }}\n"
- "\n"
- " case context:: d {\n"
- " print = function:: string {\n"
- " \"d\"\n"
- " }}\n"
- "\n"
- " start = function(command::int)::string; entry {\n"
- " switch (command) :: string \n"
- " case 0 {\n"
- " context:: print(a); print(b); print(d).\n"
- "\n"
- " loop context (\"print\") {\n"
- " print()\n"
- " }\n"
- " }\n"
- "\n"
- " case default {\n"
- " context:: print(c).\n"
- " loop context (\"print\") {\n"
- " print()\n"
- " }\n"
- " }\n"
- " }");
-
-
- char* (*main)(int) =(char* (*)(int)) man->run();
- ASSERT_STREQ("c", main(1));
- ASSERT_STREQ("a", main(0));
-}
-
-TEST(Context, full_RuleContext){
- /*
- "rule context:: childs(Child)\n"
- " case artefact(Item)\n"
- " {\n"
- " artefact_depends(Item, Child)\n"
- " }";
- */
-
- PassManager* man = PassManager::prepareForCode(
- " import raw (\"core/control-context.lp\")\n"
- " case context:: toMilli {\n"
- " convert = function(length::int)::int{\n"
- " 10 * length\n"
- " }\n"
- " }\n"
- "\n"
- " case context:: toCenti {\n"
- " convert = function(length::int)::int{\n"
- " length\n"
- " }\n"
- " }\n"
- "\n"
- " main=function::int; entry {\n"
- " context:: output(milli).\n"
- "\n"
- " rule context::toMilli\n"
- " case output(milli) {true}\n"
- "\n"
- " convert(1)\n"
- " }" );
-
- man->clasp->addRawScript("true.");
- int (*entry)() = (int (*)()) man->run();
- ASSERT_EQ(10, entry());
-}
-
-TEST(Context, full_InheritedRuleContext){
- PassManager* man = PassManager::prepareForCode(
-" import raw (\"core/control-context.lp\") \n"
-
-" case context:: toMilli {\n"
-" convert = function(length::int)::int{\n"
-" 10 * length\n"
-" }\n"
-" }\n"
-
-" case context:: toCenti {\n"
-" convert = function(length::int)::int{\n"
-" length\n"
-" }\n"
-" }\n"
-"\n"
-
-"main = function(comm:: num)::num; entry{\n"
-" rule context::X case output(X) {true}\n"
-"\n"
-" switch (comm)::num \n"
-" case 0 {\n"
-" context:: output(toMilli).\n"
-" convert(1)\n"
-" }\n"
-" case default {\n"
-" context:: output(toCenti).\n"
-" convert(1)\n"
-" }\n"
-" }");
-
- man->clasp->addRawScript("true.");
- int (*entry)(int) = (int (*)(int)) man->run();
- ASSERT_EQ(10, entry(0));
- ASSERT_EQ(1, entry(1));
-}
-
-
-
-TEST(Context, full_LateContext){
- PassManager* man = PassManager::prepareForCode(
- "import raw (\"core/control-context.lp\")\n"
-
- " convert = function(length:: num)::num{\n"
- " 0\n"
- " }\n"
-
- "case context:: milli {\n"
- " convert = function(length:: num)::num{\n"
- " 1000 * length\n"
- " }\n"
- "}\n"
- "\n"
- "case context:: centi {\n"
- " convert = function(length:: num)::num{\n"
- " 100 * length\n"
- " }\n"
- "}\n"
- "\n"
- "calculate = function(length:: num)::num {\n"
- " convert(length)\n"
- "}\n"
- "\n"
- "main = function(com:: num):: num; entry {\n"
- " switch (com):: num \n"
- " case 0 {\n"
- " context:: milli.\n"
- " calculate(1)\n"
- " }\n"
- "\n"
- " case default{\n"
- " context:: centi. \n"
- " calculate(1)\n"
- " }\n"
- "}");
-
- man->runWithoutCompilation();
- ContextQuery* queryContext = reinterpret_cast<ContextQuery*>(man->clasp->getQuery(QueryId::ContextQuery));
- Expression exprSwitch = man->root->findFunction("main")->__entry->getBody();
- CodeScope* blockDefault = man->root->findFunction("main")->__entry->getBody().operands[1].blocks.front();
- ScopePacked blockDefaultId = man->clasp->pack(blockDefault);
- const Domain& domDefault = queryContext->getContext(blockDefaultId);
- ASSERT_EQ(1, domDefault.count(Expression(Atom<Identifier_t>("centi"))));
-
- std::list<ManagedFnPtr> variants = man->root->getFunctionVariants("convert");
- for (ManagedFnPtr f: variants){
- const Expression guard = f->guardContext;
- bool result = (guard.getValueString() == "centi" || guard.getValueString() == "milli" || !guard.isValid());
- ASSERT_TRUE(result);
- }
-
- const FunctionDemand& demMain = queryContext->getFunctionDemand("main");
- ASSERT_EQ(0, demMain.size());
-
- const FunctionDemand& demCalculate = queryContext->getFunctionDemand("calculate");
- ASSERT_EQ(1, demCalculate.size());
-
- int (*entry)(int) = (int (*)(int)) man->run();
- ASSERT_EQ(1000, entry(0));
- ASSERT_EQ(100, entry(1));
-}
-
-TEST(Context, loopContextExists){
- PassManager* man = PassManager::prepareForCode (
- "import raw (\"core/control-context.lp\")\n"
-
- "interface(cfa){\n"
- " operator fold:: annotation1.\n"
- "}\n"
- "\n"
- "main = function:: int; entry {\n"
- " x = [1..10]:: [int].\n"
- " sum = loop fold (x->el:: int, 0->sum):: int {\n"
- " el + sum + f1()\n"
- " }. \n"
- " sum\n"
- "}"
- "case context:: annotation1 {"
- " f1 = function::int {\n"
- " x = 0:: int. "
- " x\n"
- " }"
- "}"
- );
-
- man->run();
-}
-
-TEST(Context, pathDependentContext){
- std::string program =
-R"CODE(
-import raw("core/control-context.lp")
-
-convert = function(length:: num) :: num {
- 0
-}
-
-case context:: convert(milli, meters) {
- convert = function(length:: num) :: num {
- 1000 * length
- }
-}
-
-case context:: convert(centi, meters) {
- convert = function(length:: num) :: num {
- 100 * length
- }
-}
-
-case context:: convert(centi, kilo) {
- convert = function(length:: num) :: num {
- 100000 * length
- }
-}
-
-case context:: convert(milli, kilo) {
- convert = function(length:: num) :: num {
- 1000000 * length
- }
-}
-
-main = function(value::num, unitsInput::num, unitsOutput::num)::num; entry{
- switch (unitsInput)::num
- case 0 {
- test_fromMilli(value, unitsOutput)
- }
- case 1 {
- test_fromCenti(value, unitsOutput)
- }
-
- case default {0}
-}
-
-test_fromCenti = function(value::num, output::num)::num{
- context:: input(centi).
-
- switch(output):: num
- case 0 {
- toMeters(value)
- }
-
- case 1 {
- toKilo(value)
- }
-
- case default {0}
-}
-
-test_fromMilli = function(value::num, output::num)::num{
- context:: input(milli).
-
- switch(output):: num
- case 0 {
- toMeters(value)
- }
-
- case 1 {
- toKilo(value)
- }
-
- case default {0}
-}
-
-toMeters = function(value::num)::num {
- rule context:: convert(X, meters) case input(X) {true}
-
- doConvert(value)
-}
-
-toKilo = function(value::num)::num {
- rule context:: convert(X, kilo) case input(X) {true}
-
- doConvert(value)
-}
-
-doConvert = function(value::num)::num{
- convert(value)
-})CODE";
-
- boost::scoped_ptr<PassManager> man(PassManager::prepareForCode(move(program)));
- man->runWithoutCompilation();
-
- int (*test)(int, int, int) = (int (*)(int, int, int))man->run();
-
- enum {INPUT_MILLI, INPUT_CENTI};
- enum {OUTPUT_METERS, OUTPUT_KILO};
-
- ASSERT_EQ(1000000, test(1, INPUT_MILLI, OUTPUT_KILO));
- ASSERT_EQ(200, test(2, INPUT_CENTI, OUTPUT_METERS));
-}
-
diff --git a/vendors/jeayeson b/vendors/jeayeson
index bf3e2ee..20389e5 160000
--- a/vendors/jeayeson
+++ b/vendors/jeayeson
@@ -1 +1 @@
-Subproject commit bf3e2ee13800d0690d5ed0138ac0af6d2f353bbc
+Subproject commit 20389e5ac679f08f0a268ef0886920b1ae3d2d9f

Event Timeline