Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F2731396
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, Mar 14, 4:46 AM
Size
49 KB
Mime Type
text/x-diff
Expires
Mon, Mar 16, 4:46 AM (1 d, 12 h)
Engine
blob
Format
Raw Data
Handle
244015
Attached To
rXR Xreate
View Options
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
Log In to Comment