No OneTemporary

File Metadata

Created
Sat, Mar 14, 4:37 AM
diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt
index d98c03e..e51bf9c 100644
--- a/cpp/src/CMakeLists.txt
+++ b/cpp/src/CMakeLists.txt
@@ -1,218 +1,210 @@
cmake_minimum_required(VERSION 2.8.11)
project(xreate)
cmake_policy(SET CMP0022 NEW)
+message("MODULES" ${CMAKE_MODULE_PATH})
+
# 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("LLVM LIB PATH:" ${LLVM_LIBRARY_DIRS})
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})
+message(STATUS "INCLUDE DIR: ${LLVM_INCLUDE_DIRS}")
+
add_definitions(${LLVM_DEFINITIONS})
-llvm_map_components_to_libnames(LLVM_LIBS core nativecodegen native executionengine mcjit support)
-message("LLVM libs: " ${LLVM_LIBS})
+message("LLVM DEFS: " ${LLVM_DEFINITIONS})
+
+llvm_map_components_to_libnames(LLVM_LIBS core nativecodegen native executionengine mcjit support option)
+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
+ clangCodeGen
+ clangASTMatchers
+ clangQuery
+ clangTooling
+ clangFrontend
+ clangSerialization
+ clangDriver
+ clangParse
+ clangSema
+ clangAnalysis
+ clangAST
+ clangEdit
+ clangLex
+ clangBasic
)
-#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})
+message("CLASP LIBS: " ${LIBCLASP_LIBS})
# OTHER DEPENDENCIES
#===========================
set(JEAYESON_INCLUDE_PATH
${CMAKE_HOME_DIRECTORY}/../vendors/jeayeson/include/
)
INCLUDE_DIRECTORIES(${JEAYESON_INCLUDE_PATH})
# COCO
#===========================
set(COCO_EXECUTABLE "" CACHE PATH "Path to coco executable")
set(COCO_GRAMMAR_PATH ${CMAKE_HOME_DIRECTORY}/../coco/)
set(COCO_SOURCE_FILES
${COCO_GRAMMAR_PATH}/Parser.cpp
${COCO_GRAMMAR_PATH}/Scanner.cpp)
INCLUDE_DIRECTORIES(${COCO_GRAMMAR_PATH})
add_custom_command(OUTPUT ${COCO_SOURCE_FILES}
COMMAND ${COCO_GRAMMAR_PATH}/gen-grammar ${COCO_EXECUTABLE}
WORKING_DIRECTORY ${COCO_GRAMMAR_PATH}
MAIN_DEPENDENCY ${COCO_GRAMMAR_PATH}/xreate.ATG
)
message(STATUS "COCO GRAMMAR BUILD STATUS:" ${COCO_OUTPUT})
# XREATE
#======================
set(SOURCE_FILES
- pass/compilepass.cpp
- pass/interpretationpass.cpp
- compilation/targetinterpretation.cpp
-
+ pass/compilepass.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
clasplayer.cpp
compilation/latecontextcompiler2.cpp
query/context.cpp
#compilation/latecontextcompiler.cpp
- serialization/expressionserializer.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/containers.cpp
+ pass/loggerpass.cpp
+ pass/interpretationpass.cpp
+ serialization/expressionserializer.cpp
+ compilation/targetinterpretation.cpp
+ analysis/DominatorsTreeAnalysisProvider.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_GRAMMAR_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_link_libraries(${PROJECT_NAME})
target_include_directories(${PROJECT_NAME} INTERFACE
${XREATE_INCLUDE_DIRS}
${COCO_GRAMMAR_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
+ INTERFACE_LINK_LIBRARIES ${LIBCLASP_LIBS} ${CLANG_LIBS} ${LLVM_LIBS} tbb
)
+#${CLANG_LIBS}
+
+
#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/analysis/DominatorsTreeAnalysisProvider.cpp b/cpp/src/analysis/DominatorsTreeAnalysisProvider.cpp
index 7d08a2d..9bd280d 100644
--- a/cpp/src/analysis/DominatorsTreeAnalysisProvider.cpp
+++ b/cpp/src/analysis/DominatorsTreeAnalysisProvider.cpp
@@ -1,233 +1,233 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
-/*
+/*
* File: DominatorsTreeAnalysisProvider.cpp
* Author: pgess
- *
+ *
* Created on May 13, 2016, 11:39 AM
*/
#include "analysis/cfagraph.h"
#include "analysis/DominatorsTreeAnalysisProvider.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/Support/GenericDomTreeConstruction.h"
#include "llvm/Support/GenericDomTree.h"
#include <list>
#include <iostream>
#include <boost/format.hpp>
using namespace std;
using namespace xreate;
using namespace boost;
using namespace boost::bimaps;
struct ControlFlowTree;
struct Node {
ScopePacked scope;
ControlFlowTree* tree;
};
/*
bool operator !=(const Node& a, const Node& b){
return (a.tree != b.tree) || (a.scope != b.scope);
}
Node& operator++(Node& a){
++a.scope;
return a;
}
*/
struct ControlFlowTree{
typedef bimap<multiset_of<ScopePacked>, multiset_of<ScopePacked>> CHILD_RELATIONS;
CHILD_RELATIONS edges;
std::vector<Node> nodes;
Node* entry = nullptr;
size_t size;
-
+
ControlFlowTree(const size_t nodesCount): nodes(nodesCount), size(nodesCount){
}
-
+
static ControlFlowTree* build(const ClaspLayer* engine){
ControlFlowTree* tree = new ControlFlowTree(engine->getScopesCount());
-
+
xreate::analysis::CFAGraph* graph = engine->dataCFA.get();
-
+
for (const auto& edge: graph->__parentScopeRelations){
tree->edges.insert(CHILD_RELATIONS::value_type(edge.second, edge.first));
}
-
+
for (const auto& edge: graph->__callRelations){
unsigned int calleeFunction = edge.right;
ScopePacked caller = edge.left;
-
+
auto range = graph->__parentFunctionRelations.right.equal_range(calleeFunction);
for (auto& i=range.first; i!= range.second; ++i){
tree->edges.insert(CHILD_RELATIONS::value_type(caller, i->second));
}
}
-
+
for (size_t i=0; i<tree->size; ++i){
tree->nodes[i]= Node{(unsigned int) i, tree};
}
-
+
return tree;
}
-
+
std::list<unsigned int> getRootFunctions() const{
size_t idMax = size;
size_t id =0;
std::list<unsigned int> results;
auto i = edges.right.begin();
-
+
while (id < idMax) {
if (i!= edges.right.end() && i->first == id){
i = edges.right.upper_bound(i->first);
-
+
} else {
results.push_back(id);
}
-
+
++id;
}
-
+
return std::move(results);
}
};
namespace llvm {
template <> struct GraphTraits<Node*> {
typedef Node* nodes_iterator;
typedef Node NodeType;
typedef std::function<Node*(ControlFlowTree::CHILD_RELATIONS::left_value_type)> Transformer;
- typedef typename boost::iterators::transform_iterator<Transformer, ControlFlowTree::CHILD_RELATIONS::left_iterator> ChildIteratorType;
-
+ typedef typename boost::transform_iterator<Transformer, ControlFlowTree::CHILD_RELATIONS::left_iterator> ChildIteratorType;
+
static ChildIteratorType child_begin(const nodes_iterator& node) {
auto range = node->tree->edges.left.equal_range(node->scope);
Transformer x = [node](auto edge){return &node->tree->nodes[edge.second];};
-
+
return boost::make_transform_iterator(range.first, x);
}
-
+
static ChildIteratorType child_end(const nodes_iterator& node) {
auto range = node->tree->edges.left.equal_range(node->scope);
Transformer x = [node](auto edge){return &node->tree->nodes[edge.second];};
-
- return boost::make_transform_iterator(range.second, x);
+
+ return boost::make_transform_iterator(range.second, x);
}
};
-
+
template <> struct GraphTraits<Inverse<Node*>> {
typedef Node* nodes_iterator;
typedef Node NodeType;
typedef std::function<Node*(ControlFlowTree::CHILD_RELATIONS::right_value_type)> Transformer;
- typedef typename boost::iterators::transform_iterator<Transformer, ControlFlowTree::CHILD_RELATIONS::right_iterator> ChildIteratorType;
-
+ typedef typename boost::transform_iterator<Transformer, ControlFlowTree::CHILD_RELATIONS::right_iterator> ChildIteratorType;
+
static ChildIteratorType child_begin(const nodes_iterator& node) {
auto range = node->tree->edges.right.equal_range(node->scope);
Transformer x = [node](auto edge){return &node->tree->nodes[edge.second];};
-
+
return boost::make_transform_iterator(range.first, x);
}
-
+
static ChildIteratorType child_end(const nodes_iterator& node) {
auto range = node->tree->edges.right.equal_range(node->scope);
Transformer x = [node](auto edge){return &node->tree->nodes[edge.second];};
-
- return boost::make_transform_iterator(range.second, x);
+
+ return boost::make_transform_iterator(range.second, x);
}
};
-
+
template <> struct GraphTraits<ControlFlowTree*>: public GraphTraits<Node*> {
static NodeType*
- getEntryNode(ControlFlowTree* F) {
+ getEntryNode(ControlFlowTree* F) {
if (F->entry) return F->entry;
-
+
list<unsigned int>&& roots = F->getRootFunctions();
assert(roots.size()==1);
-
+
return F->entry = &F->nodes[roots.front()];
}
static nodes_iterator nodes_begin(ControlFlowTree* F) { return &F->nodes[0]; }
static nodes_iterator nodes_end(ControlFlowTree* F) { return &F->nodes[F->size]; }
static size_t size(ControlFlowTree* F) { return F->size; }
};
}
class xreate::DominatorTree: public llvm::DominatorTreeBase<Node> {
public:
DominatorsTreeAnalysisProvider::Dominators dominators;
-
+
DominatorTree(bool isPostDom): llvm::DominatorTreeBase<Node>(isPostDom) {}
-
+
void run(ControlFlowTree& program){
recalculate(program);
-
+
//extract dominators info
for (auto& entry: DomTreeNodes){
if (!entry.getFirst()) continue;
-
+
dominators.emplace(entry.getFirst()->scope, make_pair(entry.getSecond()->getDFSNumIn(), entry.getSecond()->getDFSNumOut()));
}
}
-
+
void print(std::ostringstream& output, const std::string& atom) const {
boost::format formatAtom(atom + "(%1%, range(%2%, %3%)).");
for (auto entry: dominators){
output << formatAtom % (entry.first) % (entry.second.first) % (entry.second.second)
<< endl;
}
}
};
void
DominatorsTreeAnalysisProvider::run(const ClaspLayer* engine){
boost::scoped_ptr<ControlFlowTree> program(ControlFlowTree::build(engine));
-
+
treeForwardDominators->run(*program);
treePostDominators->run(*program);
}
void
DominatorsTreeAnalysisProvider::print(std::ostringstream& output) const{
treeForwardDominators->print(output, "cfa_forwdom");
treePostDominators->print(output, "cfa_postdom");
}
-const DominatorsTreeAnalysisProvider::Dominators&
+const DominatorsTreeAnalysisProvider::Dominators&
DominatorsTreeAnalysisProvider::getForwardDominators() const{
return treeForwardDominators->dominators;
}
-const DominatorsTreeAnalysisProvider::Dominators&
+const DominatorsTreeAnalysisProvider::Dominators&
DominatorsTreeAnalysisProvider::getPostDominators() const{
return treePostDominators->dominators;
}
DominatorsTreeAnalysisProvider::DominatorsTreeAnalysisProvider()
: treeForwardDominators(new DominatorTree(false))
, treePostDominators(new DominatorTree(true))
{}
DominatorsTreeAnalysisProvider::~DominatorsTreeAnalysisProvider() {}
-//void
+//void
//CodeScopesTree::print(){
// typedef llvm::GraphTraits<Node*> Traits;
// for (size_t i=0; i<size; ++i){
//
// for (auto j = Traits::child_begin(&nodes[i]); j!= Traits::child_end(&nodes[i]); ++j){
// cout << i << "->" << (*j)->scope << endl;
// }
// }
//}
\ No newline at end of file
diff --git a/cpp/src/analysis/dfagraph.cpp b/cpp/src/analysis/dfagraph.cpp
index 7ccf9e0..00a3006 100644
--- a/cpp/src/analysis/dfagraph.cpp
+++ b/cpp/src/analysis/dfagraph.cpp
@@ -1,250 +1,250 @@
#include "analysis/dfagraph.h"
#include "analysis/aux.h"
#include <list>
using namespace xreate;
using namespace xreate::analysis;
using namespace std;
namespace xreate {
namespace analysis {
void
DFAGraph::print(std::ostringstream& output) const {
std::set<SymbolPacked> symbols;
output << endl << "%\t\tStatic analysis: DFA" << endl;
std::vector<std::pair<SymbolPacked, SymbolPacked>>::const_iterator i1;
std::vector<DFGConnection>::const_iterator i2;
boost::format formatDfaConnection("dfa_connection(%1%, %2%, %3%).");
for (i1 = this->__edges.begin(), i2 = this->__data.begin(); i1 != this->__edges.end(); ++i1, ++i2) {
string edgeName;
switch (*i2) {
case DFGConnection::WEAK: edgeName = "weak";
break;
case DFGConnection::STRONG: edgeName = "strong";
break;
case DFGConnection::PROTOTYPE: edgeName = "proto";
break;
}
output << formatDfaConnection
% formatSymbol(i1->first)
% formatSymbol(i1->second)
% edgeName
<< " %" << this->__clasp->getHintForPackedSymbol(i1->first) << " - " << this->__clasp->getHintForPackedSymbol(i1->second)
<< endl;
symbols.insert(i1->first);
symbols.insert(i1->second);
}
boost::format formatDfaDependency("dfa_dependency(%1%, %2%).");
for (auto i = this->__dependencies.begin(); i != this->__dependencies.end(); ++i) {
output << formatDfaDependency
% formatSymbol(i->first)
% formatSymbol(i->second)
<< " %"
<< this->__clasp->getHintForPackedSymbol(i->first) << " - "
<< this->__clasp->getHintForPackedSymbol(i->second)
<< endl;
}
boost::format formatBind("bind(%1%, %2%).");
for (const pair<SymbolPacked, Expression>& tag : this->__tags) {
for (string variant : xreate::analysis::compile(tag.second)) {
output << formatBind
% formatSymbol(tag.first)
% (variant)
<< "%" << this->__clasp->getHintForPackedSymbol(tag.first)
<< endl;
}
symbols.insert(tag.first);
}
for (const SymbolPacked& s : symbols) {
output << "v(" << formatSymbol(s) << ")."
<< " %" << this->__clasp->getHintForPackedSymbol(s)
<< endl;
}
}
class VisitorAddTag : public boost::static_visitor<> {
public:
void operator()(const SymbolPacked& symbol) {
__graph->__tags.emplace(symbol, move(__tag));
}
void operator()(SymbolTransient& symbol) {
symbol.tags.push_back(move(__tag));
}
void operator()(const SymbolInvalid& symbol) {
assert(false && "Undefined behaviour");
}
VisitorAddTag(DFAGraph * const dfagraph, Expression&& tag) :
__graph(dfagraph), __tag(tag) {
}
private:
DFAGraph * const __graph;
Expression __tag;
};
class VisitorAddLink : public boost::static_visitor<> {
public:
void operator()(const SymbolPacked& nodeFrom) {
if (!__graph->isConnected(__nodeTo, nodeFrom)) {
__graph->__edges.emplace_back(__nodeTo, nodeFrom);
__graph->__data.push_back(__link);
DFAGraph::EdgeId eid = __graph->__edges.size() - 1;
__graph->__outEdges.emplace(nodeFrom, eid);
}
}
void operator()(const SymbolTransient& symbolFrom) {
switch (__link) {
case DFGConnection::WEAK:
{
//virtual symbol to hold transient annotations
SymbolPacked symbPivot = __graph->createAnonymousSymbol(symbolFrom.scope);
__graph->addConnection(symbPivot, symbolFrom, DFGConnection::STRONG);
__graph->addConnection(__nodeTo, symbPivot, DFGConnection::WEAK);
break;
}
case DFGConnection::STRONG:
{
for (const Expression& tag : symbolFrom.tags) {
__graph->__tags.emplace(__nodeTo, tag);
}
break;
}
default:
assert(false && "Undefined behavior");
}
}
void operator()(const SymbolInvalid&) {
if (__link == DFGConnection::STRONG) return;
if (__link == DFGConnection::WEAK) return;
assert(false && "Undefined behavior");
}
VisitorAddLink(DFAGraph * const dfagraph, const SymbolPacked& nodeTo, DFGConnection link) :
__graph(dfagraph), __nodeTo(nodeTo), __link(link) {
}
private:
DFAGraph * const __graph;
SymbolPacked __nodeTo;
DFGConnection __link;
};
class VisitorGetDependencyConnection : public boost::static_visitor<list<SymbolPacked>>
{
public:
list<SymbolPacked>
operator()(const SymbolPacked & nodeFrom) {
return
{
nodeFrom
};
}
list<SymbolPacked>
operator()(const SymbolTransient & nodeFrom) {
return nodeFrom.dependencies;
}
list<SymbolPacked>
operator()(const SymbolInvalid&) {
assert(false && "Undefined behavior");
}
VisitorGetDependencyConnection(DFAGraph * const g) : graph(g) {
}
DFAGraph * const graph;
};
class VisitorSetDependencyConnection : public boost::static_visitor<> {
public:
void operator()(SymbolPacked& nodeTo) {
VisitorGetDependencyConnection visitorGetDepenencies(graph);
auto deps = boost::apply_visitor(visitorGetDepenencies, nodeFrom);
for (const SymbolPacked& dep : deps) {
graph->__dependencies.emplace(nodeTo, dep);
}
}
void operator()(SymbolTransient& nodeTo) {
VisitorGetDependencyConnection visitorGetDepenencies(graph);
auto deps = boost::apply_visitor(visitorGetDepenencies, nodeFrom);
for (const SymbolPacked& dep : deps) {
nodeTo.dependencies.push_back(dep);
}
}
void operator()(SymbolInvalid&) {
assert(false && "Undefined behavior");
}
VisitorSetDependencyConnection(DFAGraph * const g, SymbolNode s) : graph(g), nodeFrom(s) {
}
DFAGraph * const graph;
SymbolNode nodeFrom;
};
bool
DFAGraph::isConnected(const SymbolPacked& identifierTo, const SymbolPacked& identifierFrom) {
auto range = __outEdges.equal_range(identifierFrom);
for (std::multimap<SymbolPacked, EdgeId>::iterator edge = range.first; edge != range.second; ++edge) {
if (__edges[edge->second].second == identifierTo)
return true;
}
return false;
}
void
DFAGraph::addConnection(const SymbolPacked& nodeTo, const SymbolNode& nodeFrom, DFGConnection link) {
VisitorAddLink visitor(this, nodeTo, link);
boost::apply_visitor(visitor, nodeFrom);
}
void
DFAGraph::addDependencyConnection(SymbolNode& identifierTo, SymbolNode& identifierFrom) {
VisitorSetDependencyConnection visitor(this, identifierFrom);
boost::apply_visitor(visitor, identifierTo);
}
void
DFAGraph::addAnnotation(SymbolNode& node, Expression&& tag) {
VisitorAddTag visitor(this, move(tag));
boost::apply_visitor(visitor, node);
}
SymbolPacked
DFAGraph::createAnonymousSymbol(const ScopePacked& scope) {
- return SymbolPacked{__countAnonymousSymbols++, scope, true};
+ return SymbolPacked(__countAnonymousSymbols++, scope, true);
}
}
}
\ No newline at end of file
diff --git a/cpp/src/clasplayer.cpp b/cpp/src/clasplayer.cpp
index 76509c6..6434235 100644
--- a/cpp/src/clasplayer.cpp
+++ b/cpp/src/clasplayer.cpp
@@ -1,279 +1,275 @@
#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);
}
}
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;
+ SymbolPacked result(symbol.identifier, pack(symbol.scope));
__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);
}
-}
-
+}
\ No newline at end of file
diff --git a/cpp/src/clasplayer.h b/cpp/src/clasplayer.h
index ad8da19..6961026 100644
--- a/cpp/src/clasplayer.h
+++ b/cpp/src/clasplayer.h
@@ -1,227 +1,230 @@
#ifndef CLASPLAYER_H
#define CLASPLAYER_H
#include "ast.h"
#include "contextrule.h"
#include <clingo/clingocontrol.hh>
#include <string>
#include <climits>
#include <boost/bimap.hpp>
#include <boost/bimap/multiset_of.hpp>
#include <boost/optional.hpp>
#include <boost/scoped_ptr.hpp>
#include <list>
namespace xreate {
typedef unsigned int ScopePacked;
struct SymbolPacked {
VID identifier;
ScopePacked scope;
- bool categoryTransient = false;
+ bool categoryTransient;
+
+ SymbolPacked(): categoryTransient(false){}
+ SymbolPacked(VID i, ScopePacked s, bool isTransient = false): identifier(i), scope(s), categoryTransient(isTransient){}
};
bool operator==(const SymbolPacked& s1, const SymbolPacked& s2);
bool operator<(const SymbolPacked& s1, const SymbolPacked& s2);
enum class DFGConnection {
STRONG, WEAK, PROTOTYPE
};
class IAnalysisData {
public:
void print(std::ostringstream& output) const;
virtual ~IAnalysisData(){};
};
class IQuery {
public:
virtual void init(ClaspLayer* clasp) = 0;
virtual ~IQuery() {}
};
enum class QueryId {
ContainersQuery,
ContextQuery,
PtrvalidQuery
};
namespace analysis{
class DFAGraph;
class CFAGraph;
}
class ClaspLayer {
friend class ContextRule;
//PROVIDERS:
public:
boost::scoped_ptr<xreate::analysis::DFAGraph> dataDFA;
void setDFAData(xreate::analysis::DFAGraph* graph);
boost::scoped_ptr<xreate::analysis::CFAGraph> dataCFA;
void setCFAData(xreate::analysis::CFAGraph* graph);
void addRawScript(std::string&& script);
private:
void involveImports();
//QUERIES
public:
IQuery* registerQuery(IQuery* query, const QueryId& id);
IQuery* getQuery(const QueryId& id);
template<class ...Types>
static std::tuple<Types...> parse(const Gringo::Symbol& atom);
typedef std::multimap<std::string, Gringo::Symbol>::const_iterator ModelIterator;
typedef boost::optional<std::pair<ClaspLayer::ModelIterator, ClaspLayer::ModelIterator>> ModelFragment;
ModelFragment query(const std::string& atom);
size_t getScopesCount() const;
SymbolPacked pack(const Symbol& symbol, std::string hintSymbolName = "");
ScopePacked pack(CodeScope * const scope);
Symbol unpack(const SymbolPacked& symbol);
std::string getHintForPackedSymbol(const SymbolPacked& symbol);
private:
std::map<QueryId, IQuery*> __queries;
std::multimap<std::string, Gringo::Symbol> __model;
std::map<SymbolPacked, std::string> __indexSymbolNameHints;
std::unordered_map<const CodeScope*, unsigned int> __indexScopes;
std::vector<CodeScope*> __registryScopes;
//WARNINGS
//TODO move to separate provider/query
public:
void addRuleWarning(const RuleWarning &rule);
unsigned int registerWarning(std::string &&message);
private:
std::map<unsigned int, std::string> __warnings;
void printWarnings(std::ostream& out);
//DEFAULT
public:
AST *ast;
ClaspLayer();
void run();
private:
std::ostringstream __partTags;
std::ostringstream __partGeneral;
bool handleSolution(Gringo::Model const &model);
};
template<class typ>
struct ParseImplAtom {
static typ get(const Gringo::Symbol& atom) {
return atom.num();
}
};
template<>
struct ParseImplAtom<std::string> {
static std::string get(const Gringo::Symbol& atom) {
switch (atom.type()) {
case Gringo::SymbolType::Str: return atom.string().c_str();
case Gringo::SymbolType::Fun: return atom.name().c_str();
default: break;
}
assert(false && "Inappropriate symbol type");
}
};
template<>
struct ParseImplAtom<SymbolPacked> {
static SymbolPacked get(const Gringo::Symbol& atom) {
auto result = ClaspLayer::parse<unsigned int, unsigned int>(atom);
- return SymbolPacked{std::get<0>(result), std::get<1>(result)};
+ return SymbolPacked(std::get<0>(result), std::get<1>(result));
}
};
template<>
struct ParseImplAtom<Gringo::Symbol> {
static Gringo::Symbol get(const Gringo::Symbol& atom) {
return atom;
}
};
template<>
struct ParseImplAtom<Expression> {
static Expression get(const Gringo::Symbol& atom) {
switch (atom.type()) {
case Gringo::SymbolType::Num: return Expression(atom.num());
case Gringo::SymbolType::Str: return Expression(std::string(atom.string().c_str()));
case Gringo::SymbolType::Fun:
{
//ID
if (!atom.args().size){
return Expression(std::string(atom.name().c_str()));
}
//FUNC
Expression result(Operator::CALL,{Expression(std::string(atom.name().c_str()))});
for (const Gringo::Symbol& arg : atom.args()) {
result.addArg(ParseImplAtom<Expression>::get(arg));
}
return result;
}
default:
{
assert(false);
}
}
}
};
template<class Tuple, size_t index>
struct Parse_Impl {
static void parse(Tuple& tup, Gringo::SymSpan::iterator arg) {
const size_t tupleSize = std::tuple_size<Tuple>::value;
typedef typename std::tuple_element < tupleSize - index, Tuple>::type ElType;
ElType& el = std::get < tupleSize - index > (tup);
Gringo::Symbol atom = *arg;
el = ParseImplAtom<ElType>::get(atom);
Parse_Impl<Tuple, index - 1 > ::parse(tup, ++arg);
}
};
template<class Tuple>
struct Parse_Impl<Tuple, 0> {
static void parse(Tuple& tup, Gringo::SymSpan::iterator arg) {
}
};
template<class ...Types>
std::tuple<Types...>
ClaspLayer::parse(const Gringo::Symbol& atom) {
typedef std::tuple < Types...> Tuple;
Tuple tup;
Parse_Impl<Tuple, std::tuple_size<Tuple>::value>::parse(tup, atom.args().first);
return tup;
}
}
-#endif
+#endif
\ No newline at end of file
diff --git a/cpp/src/compilation/targetinterpretation.cpp b/cpp/src/compilation/targetinterpretation.cpp
index 90c48fb..b50bf13 100644
--- a/cpp/src/compilation/targetinterpretation.cpp
+++ b/cpp/src/compilation/targetinterpretation.cpp
@@ -1,447 +1,446 @@
/*
* File: targetinterpretation.cpp
* Author: pgess
*
* Created on June 29, 2016, 6:45 PM
*/
#include "compilation/targetinterpretation.h"
#include "pass/interpretationpass.h"
#include "llvmlayer.h"
#include <boost/scoped_ptr.hpp>
#include <iostream>
using namespace std;
namespace xreate{ namespace compilation {
const Expression EXPRESSION_FALSE = Expression(Atom<Number_t>(0));
const Expression EXPRESSION_TRUE = Expression(Atom<Number_t>(1));
//Expression
//InterpretationScope::compile(const Expression& expression){}
CodeScope*
InterpretationScope::processOperatorIf(const Expression& expression){
const Expression& exprCondition = process(expression.getOperands()[0]);
if (exprCondition == EXPRESSION_TRUE){
return expression.blocks.front();
}
return expression.blocks.back();
}
CodeScope*
InterpretationScope::processOperatorSwitch(const Expression& expression) {
const Expression& exprCondition = process(expression.operands[0]);
bool flagHasDefault = expression.operands[1].op == Operator::CASE_DEFAULT;
//TODO check that one and only one case variant is appropriate
for (size_t size = expression.operands.size(), i= flagHasDefault? 2: 1; i<size; ++i){
const Expression& exprCase = process(expression.operands[i]);
if (function->getScope(exprCase.blocks.front())->processScope() == exprCondition){
return exprCase.blocks.back();
}
}
if (flagHasDefault){
const Expression& exprCaseDefault = expression.operands[1];
return exprCaseDefault.blocks.front();
}
assert(false && "Switch has no appropriate variant");
return nullptr;
}
llvm::Value*
InterpretationScope::compileHybrid(const InterpretationOperator& op, const Expression& expression, const Context& context){
switch(op){
case IF_INTERPRET_CONDITION: {
CodeScope* scopeResult = processOperatorIf(expression);
llvm::Value* result = context.function->getScopeUnit(scopeResult)->compile();
return result;
}
case SWITCH_INTERPRET_CONDITION:{
CodeScope* scopeResult = processOperatorSwitch(expression);
llvm::Value* result = context.function->getScopeUnit(scopeResult)->compile();
return result;
}
case FOLD_INTERPRET_INPUT: {
//initialization
const Expression& exprInput = process(expression.getOperands()[0]);
assert(exprInput.op == Operator::LIST);
CodeScope* scopeBody = expression.blocks.front();
const string& nameEl = expression.bindings[0];
const Symbol& symbolEl = scopeBody->findSymbol(nameEl);
const std::string& idAccum = expression.bindings[1];
llvm::Value* rawAccum = context.scope->process(expression.getOperands()[1]);
compilation::CodeScopeUnit* unitBody = context.function->getScopeUnit(scopeBody);
InterpretationScope* intrBody = function->getScope(scopeBody);
const std::vector<Expression> elementsInput= exprInput.getOperands();
for (size_t i=0; i<elementsInput.size(); ++i){
Expression exprElement = elementsInput[i];
unitBody->reset();
intrBody->overrideBinding(exprElement, nameEl);
unitBody->overrideDeclaration(symbolEl, move(exprElement));
unitBody->bindArg(rawAccum, string(idAccum));
rawAccum = unitBody->compile();
}
return rawAccum;
}
case CALL_INTERPRET_PARTIAL: {
const std::string &calleeName = expression.getValueString();
CodeScopeUnit* scopeUnitSelf = context.scope;
ManagedFnPtr callee = this->function->man->ast->findFunction(calleeName);
const FunctionInterpretationData& calleeData = FunctionInterpretationHelper::getSignature(callee);
std::vector<llvm::Value *> argsActual;
PIFSignature sig;
sig.declaration = callee;
for(size_t no=0, size = expression.operands.size(); no < size; ++no){
const Expression& op = expression.operands[no];
if (calleeData.signature.at(no) == INTR_ONLY){
sig.bindings.push_back(process(op));
continue;
}
argsActual.push_back(scopeUnitSelf->process(op));
}
TargetInterpretation* man = dynamic_cast<TargetInterpretation*>(this->function->man);
PIFunction* pifunction = man->getFunction(move(sig));
llvm::Function* raw = pifunction->compile();
boost::scoped_ptr<CallStatementRaw> statement(new CallStatementRaw(raw, man->pass->man->llvm));
return (*statement)(move(argsActual));
}
default: break;
}
assert(false&& "Unknown hybrid operator");
return nullptr;
}
llvm::Value*
InterpretationScope::compile(const Expression& expression, const Context& context){
const InterpretationData& data = Attachments::get<Expression, InterpretationData>(expression);
if (data.op != InterpretationOperator::NONE){
return compileHybrid(data.op, expression, context);
}
Expression result = process(expression);
return context.scope->processLowlevel(result);
}
Expression
InterpretationScope::process(const Expression& expression){
switch (expression.__state){
case Expression::VARIANT:
case Expression::INVALID:
assert(false);
case Expression::NUMBER:
case Expression::STRING:
return expression;
case Expression::IDENT:{
const std::string &ident = expression.getValueString();
Symbol s = scope->findSymbol(ident);
return Parent::processSymbol(s);
}
case Expression::COMPOUND:
break;
default: assert(false);
}
switch (expression.op) {
case Operator::EQU: {
const Expression& left = process(expression.operands[0]);
const Expression& right = process(expression.operands[1]);
if (left == right) return EXPRESSION_TRUE;
return EXPRESSION_FALSE;
}
case Operator::NE: {
const Expression& left = process(expression.operands[0]);
const Expression& right = process(expression.operands[1]);
if (left == right) return EXPRESSION_FALSE;
return EXPRESSION_TRUE;
}
case Operator::LOGIC_AND: {
assert(expression.operands.size() == 1);
return process (expression.operands[0]);
}
// case Operator::LOGIC_OR:
case Operator::CALL: {
const std::string &fnName = expression.getValueString();
ManagedFnPtr fnAst = this->function->man->ast->findFunction(fnName);
- InterpretatonFunction* fnUnit = this->function->man->getFunction(fnAst);
+ InterpretationFunction* fnUnit = this->function->man->getFunction(fnAst);
vector<Expression> args;
args.reserve(expression.getOperands().size());
for(size_t i=0, size = expression.getOperands().size(); i<size; ++i) {
args.push_back(process(expression.getOperands()[i]));
}
return fnUnit->process(args);
}
case Operator::IF:{
CodeScope* scopeResult = processOperatorIf(expression);
return function->getScope(scopeResult)->processScope();
}
case Operator::SWITCH: {
CodeScope* scopeResult = processOperatorSwitch(expression);
return function->getScope(scopeResult)->processScope();
}
case Operator::INDEX: {
const Expression& exprKey = process(expression.operands[0]);
const Expression& exprData = processSymbol(scope->findSymbol(expression.getValueString()));
if (exprKey.__state == Expression::STRING){
const string& key = exprKey.getValueString();
assert(exprData.__indexBindings.count(key));
return exprData.operands[exprData.__indexBindings.at(key)];
}
if (exprKey.__state == Expression::NUMBER){
int key = exprKey.getValueDouble();
return exprData.operands[key];
}
assert(false);
}
case Operator::FOLD: {
const Expression& exprInput = process(expression.getOperands()[0]);
const Expression& exprInit = process(expression.getOperands()[1]);
const std::string& argEl = expression.bindings[0];
const std::string& argAccum = expression.bindings[1];
InterpretationScope* body = function->getScope(expression.blocks.front());
Expression accum = exprInit;
for(size_t size=exprInput.getOperands().size(), i=0; i<size; ++i){
body->overrideBinding(exprInput.getOperands()[i], argEl);
body->overrideBinding(accum, argAccum);
accum = body->processScope();
}
return accum;
}
// case Operator::MAP: {
// break;
// }
default: break;
}
return expression;
}
-InterpretatonFunction*
+InterpretationFunction*
TargetInterpretation::getFunction(FunctionUnit* unit){
if (__dictFunctionsByUnit.count(unit)) {
return __dictFunctionsByUnit.at(unit);
}
- InterpretatonFunction* f = new InterpretatonFunction(unit->function, this);
+ InterpretationFunction* f = new InterpretationFunction(unit->function, this);
__dictFunctionsByUnit.emplace(unit, f);
assert(__functions.emplace(unit->function.id(), f).second);
return f;
}
PIFunction*
TargetInterpretation::getFunction(PIFSignature&& sig){
- auto f = __pifunctions.find<PIFSignature>(sig);
+ auto f = __pifunctions.find(sig);
if (f != __pifunctions.end()){
- return *f;
+ return f->second;
}
- PIFunction* result = new PIFunction(move(sig), __pifunctions.size(), this);
- __pifunctions.insert(result);
+ PIFunction* result = new PIFunction(PIFSignature(sig), __pifunctions.size(), this);
+ __pifunctions.emplace(move(sig), result);
assert(__dictFunctionsByUnit.emplace(result->functionUnit, result).second);
return result;
}
InterpretationScope*
TargetInterpretation::transformContext(const Context& c){
return this->getFunction(c.function)->getScope(c.scope->scope);
}
llvm::Value*
TargetInterpretation::transform(const Expression& expression, llvm::Value* raw, const Context& ctx){
return raw;
}
Expression
TargetInterpretation::transform(const Expression& expression, const Context& ctx){
return transformContext(ctx)->process(expression);
}
llvm::Value*
TargetInterpretation::compile(const Expression& expression, const Context& ctx){
return transformContext(ctx)->compile(expression, ctx);
}
bool
TargetInterpretation::isAcceptable(const Expression& expression){
const InterpretationData& data = Attachments::get<Expression, InterpretationData>(expression, {ANY, NONE});
return (data.resolution == INTR_ONLY || data.op != InterpretationOperator::NONE);
}
-InterpretatonFunction::InterpretatonFunction(const ManagedFnPtr& function, Target<TargetInterpretation>* target)
+InterpretationFunction::InterpretationFunction(const ManagedFnPtr& function, Target<TargetInterpretation>* target)
: Function<TargetInterpretation>(function, target)
{}
Expression
-InterpretatonFunction::process(const std::vector<Expression>& args){
+InterpretationFunction::process(const std::vector<Expression>& args){
InterpretationScope* body = getScope(__function->__entry);
for(size_t i=0, size = args.size(); i<size; ++i) {
body->overrideBinding(args.at(i), string(body->scope->__bindings.at(i)));
}
return body->processScope();
}
// Partial function interpretation
typedef BasicFunctionDecorator PIFunctionUnitParent;
class PIFunctionUnit: public PIFunctionUnitParent{
public:
PIFunctionUnit(ManagedFnPtr f, std::set<size_t>&& arguments, size_t id, CompilePass* p)
: PIFunctionUnitParent(f, p), argumentsActual(move(arguments)), __id(id)
{}
protected:
std::vector<llvm::Type*> prepareArguments(){
LLVMLayer* llvm = PIFunctionUnitParent::pass->man->llvm;
AST* ast = PIFunctionUnitParent::pass->man->root;
CodeScope* entry = PIFunctionUnitParent::function->__entry;
std::vector<llvm::Type*> signature;
for(size_t no: argumentsActual){
Symbol arg = entry->findSymbol(entry->__bindings[no]);
signature.push_back(llvm->toLLVMType(ast->expandType(entry->__declarations[arg.identifier].type)));
}
return signature;
}
llvm::Function::arg_iterator prepareBindings(){
CodeScope* entry = PIFunctionUnitParent::function->__entry;
CodeScopeUnit* entryCompilation = PIFunctionUnitParent::getScopeUnit(entry);
llvm::Function::arg_iterator fargsI = PIFunctionUnitParent::raw->arg_begin();
for(size_t no: argumentsActual){
Symbol arg = entry->findSymbol(entry->__bindings[no]);
entryCompilation->__rawVars[arg.identifier] = &*fargsI;
fargsI->setName(entry->__bindings[no]);
++fargsI;
}
return fargsI;
}
virtual std::string prepareName(){
return PIFunctionUnitParent::prepareName() + "_" + std::to_string(__id);
}
private:
std::set<size_t> argumentsActual;
size_t __id;
};
PIFunction::PIFunction(PIFSignature&& sig, size_t id, TargetInterpretation* target)
- : InterpretatonFunction(sig.declaration, target), signatureInstance(move(sig))
+ : InterpretationFunction(sig.declaration, target), signatureInstance(move(sig))
{
const FunctionInterpretationData& functionData = FunctionInterpretationHelper::getSignature(signatureInstance.declaration);
std::set<size_t> argumentsActual;
for (size_t no=0, size=functionData.signature.size(); no < size; ++no){
if (functionData.signature.at(no) != INTR_ONLY){
argumentsActual.insert(no);
}
}
functionUnit = new PIFunctionUnit(signatureInstance.declaration, move(argumentsActual), id, target->pass);
CodeScope* entry = signatureInstance.declaration->__entry;
CodeScopeUnit* entryUnit = functionUnit->getEntry();
- InterpretationScope* entryIntrp = InterpretatonFunction::getScope(entry);
+ InterpretationScope* entryIntrp = InterpretationFunction::getScope(entry);
for(size_t no=0, sigNo=0, size = entry->__bindings.size(); no < size; ++no){
if (functionData.signature.at(no) == INTR_ONLY){
entryIntrp->overrideBinding(signatureInstance.bindings[sigNo], entry->__bindings[no]);
entryUnit->overrideDeclaration(entry->findSymbol(entry->__bindings[no]), Expression(signatureInstance.bindings[sigNo]));
++sigNo;
}
}
}
llvm::Function*
PIFunction::compile(){
llvm::Function* raw = functionUnit->compile();
return raw;
}
bool operator<(const PIFSignature& lhs, const PIFSignature& rhs){
if (lhs.declaration.id() != rhs.declaration.id()) {
return lhs.declaration.id() < rhs.declaration.id();
}
return lhs.bindings < rhs.bindings;
}
bool operator<(const PIFSignature& lhs, PIFunction* const rhs){
return lhs < rhs->signatureInstance;
}
bool operator<(PIFunction* const lhs, const PIFSignature& rhs){
return lhs->signatureInstance < rhs;
}
-}}
-
+}}
\ No newline at end of file
diff --git a/cpp/src/compilation/targetinterpretation.h b/cpp/src/compilation/targetinterpretation.h
index 2d7444e..0ef32e7 100644
--- a/cpp/src/compilation/targetinterpretation.h
+++ b/cpp/src/compilation/targetinterpretation.h
@@ -1,117 +1,116 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: targetstatic.h
* Author: pgess
*
* Created on July 2, 2016, 1:25 PM
*/
#ifndef TARGETSTATIC_H
#define TARGETSTATIC_H
#include "ast.h"
#include "compilation/targets.h"
#include "transformations.h"
#include "pass/interpretationpass.h"
namespace xreate{ namespace compilation {
class TargetInterpretation;
class InterpretationScope;
-class InterpretatonFunction;
+class InterpretationFunction;
template <>
struct TargetInfo<TargetInterpretation> {
typedef Expression Result;
typedef InterpretationScope Scope;
- typedef InterpretatonFunction Function;
+ typedef InterpretationFunction Function;
};
template<>
struct TransformerInfo<TargetInterpretation> {
static const int id = 1;
};
class InterpretationScope: public Scope<TargetInterpretation>{
typedef Scope<TargetInterpretation> Parent;
public:
InterpretationScope(CodeScope* scope, Function<TargetInterpretation>* f): Parent(scope, f) {}
Expression process(const Expression& expression) override;
llvm::Value* compile(const Expression& expression, const Context& context);
private:
llvm::Value* compileHybrid(const InterpretationOperator& op, const Expression& expression, const Context& context);
//llvm::Value* compilePartialFnCall(const Expression& expression, const Context& context);
CodeScope* processOperatorIf(const Expression& expression);
CodeScope* processOperatorSwitch(const Expression& expression);
};
-class InterpretatonFunction: public Function<TargetInterpretation>{
+class InterpretationFunction: public Function<TargetInterpretation>{
public:
- InterpretatonFunction(const ManagedFnPtr& function, Target<TargetInterpretation>* target);
+ InterpretationFunction(const ManagedFnPtr& function, Target<TargetInterpretation>* target);
Expression process(const std::vector<Expression>& args);
};
/*
* Partially interpreted function signature
*/
struct PIFSignature{
ManagedFnPtr declaration;
std::vector<Expression> bindings;
};
class PIFunctionUnit;
-class PIFunction: public InterpretatonFunction{
+class PIFunction: public InterpretationFunction{
public:
PIFunctionUnit* functionUnit;
PIFSignature signatureInstance;
PIFunction(PIFSignature&& sig, size_t id, TargetInterpretation* target);
llvm::Function* compile();
};
bool operator<(const PIFSignature& lhs, PIFunction* const rhs);
bool operator<(PIFunction* const lhs, const PIFSignature& rhs);
class TargetInterpretation: public Target<TargetInterpretation>, public Transformer{
public:
TargetInterpretation(AST* root, CompilePass* passCompilation): Target<TargetInterpretation>(root), pass(passCompilation){}
//transformer:
public:
virtual llvm::Value* transform(const Expression& expression, llvm::Value* raw, const Context& ctx) override;
virtual Expression transform(const Expression& expression, const Context& ctx) override;
virtual bool isAcceptable(const Expression& expression) override;
//target:
public:
- InterpretatonFunction* getFunction(FunctionUnit* unit);
+ InterpretationFunction* getFunction(FunctionUnit* unit);
PIFunction* getFunction(PIFSignature&& sig);
private:
- std::set<PIFunction*, std::less<>> __pifunctions;
- std::map<FunctionUnit*, InterpretatonFunction*> __dictFunctionsByUnit;
+ std::map<PIFSignature, PIFunction*> __pifunctions;
+ std::map<FunctionUnit*, InterpretationFunction*> __dictFunctionsByUnit;
//self:
public:
CompilePass* pass;
llvm::Value* compile(const Expression& expression, const Context& ctx);
private:
InterpretationScope* transformContext(const Context& c);
};
}}
-#endif /* TARGETSTATIC_H */
-
+#endif /* TARGETSTATIC_H */
\ No newline at end of file
diff --git a/cpp/src/compilation/targets.h b/cpp/src/compilation/targets.h
index b1821e3..f6b47bb 100644
--- a/cpp/src/compilation/targets.h
+++ b/cpp/src/compilation/targets.h
@@ -1,156 +1,161 @@
/*
* File: targetabstract.h
* Author: pgess
*
* Created on July 2, 2016, 1:25 PM
*/
#ifndef TARGETABSTRACT_H
#define TARGETABSTRACT_H
#include "ast.h"
#include <boost/optional.hpp>
#include <map>
namespace xreate{ namespace compilation {
template <typename ConcreteTarget>
struct TargetInfo{
//typedef Result
//typedef Function
//typedef Scope
};
template<typename ConcreteTarget>
class Function;
template<typename ConcreteTarget>
class Target;
template<typename ConcreteTarget>
class Scope{
public:
CodeScope* scope;
typename TargetInfo<ConcreteTarget>::Result
processSymbol(const Symbol& s){
CodeScope* scope = s.scope;
typename TargetInfo<ConcreteTarget>::Scope* self = function->getScope(scope);
if (self->__bindings.count(s.identifier)) {
return self->__bindings[s.identifier];
}
const Expression& declaration = CodeScope::findDeclaration(s);
if (!declaration.isDefined()){
assert(false); //for bindings there should be result already
}
return self->__bindings[s.identifier] = self->process(declaration);
}
typename TargetInfo<ConcreteTarget>::Result
processScope() {
if (raw) return *raw;
raw = process(scope->getBody());
return *raw;
}
// typename TargetInfo<ConcreteTarget>::Result
// processFunction(typename TargetInfo<ConcreteTarget>::Function* fnRemote, const std::vector<typename TargetInfo<ConcreteTarget>::Result>& args){
// Scope<ConcreteTarget> scopeRemote = fnRemote->getScope(fnRemote->__function->__entry);
//
// if (scopeRemote->raw){
// return scopeRemote->raw;
// }
//
// return fnRemote->process(args);
// }
virtual typename TargetInfo<ConcreteTarget>::Result
process(const Expression& expression)=0;
Scope(CodeScope* codeScope, Function<ConcreteTarget>* f)
: scope(codeScope), function(f) {}
virtual ~Scope(){}
void
overrideBinding(typename TargetInfo<ConcreteTarget>::Result arg, const std::string& name){
assert(scope->__identifiers.count(name));
VID id = scope->__identifiers.at(name);
__bindings[id] = arg;
//reset the result if any:
raw.reset();
}
protected:
Function<ConcreteTarget>* function=0;
std::map<VID, typename TargetInfo<ConcreteTarget>::Result> __bindings;
typename boost::optional<typename TargetInfo<ConcreteTarget>::Result> raw;
//ResultType findFunction(const std::string& callee);
};
template<typename ConcreteTarget>
class Function{
typedef typename TargetInfo<ConcreteTarget>::Result Result;
public:
Function(const ManagedFnPtr& function, Target<ConcreteTarget>* target)
: man(target), __function(function) {}
+ virtual ~Function(){};
+
typename TargetInfo<ConcreteTarget>::Scope*
getScope(CodeScope* scope){
if (!__scopes.count(scope)){
typename TargetInfo<ConcreteTarget>::Scope* unit = new typename TargetInfo<ConcreteTarget>::Scope(scope, this);
__scopes.emplace(scope, std::unique_ptr<typename TargetInfo<ConcreteTarget>::Scope>(unit));
}
return __scopes.at(scope).get();
}
virtual Result
process(const std::vector<Result>& args)=0;
Target<ConcreteTarget>* man=0;
ManagedFnPtr __function;
protected:
std::map<CodeScope*, std::unique_ptr<typename TargetInfo<ConcreteTarget>::Scope>> __scopes;
};
template<typename ConcreteTarget>
class Target {
typedef typename TargetInfo<ConcreteTarget>::Function ConcreteFunction;
public:
Target(AST* root): ast(root){}
ConcreteFunction*
getFunction(const ManagedFnPtr& function){
unsigned int id = function.id();
if (!__functions.count(id)){
ConcreteFunction* unit = new ConcreteFunction(function, this);
- __functions.emplace(id, std::unique_ptr<ConcreteFunction>(unit));
+ __functions.emplace(id, unit);
return unit;
}
- return __functions.at(id).get();
+ return __functions.at(id);
}
AST* ast;
- virtual ~Target(){}
+ virtual ~Target(){
+ for (const auto& entry: __functions){
+ delete entry.second;
+ }
+ }
protected:
- std::map<unsigned int, std::unique_ptr<ConcreteFunction>> __functions;
+ std::map<unsigned int, ConcreteFunction*> __functions;
};
}}
-#endif /* TARGETABSTRACT_H */
-
+#endif /* TARGETABSTRACT_H */
\ No newline at end of file
diff --git a/cpp/src/serialization/expressionserializer.cpp b/cpp/src/serialization/expressionserializer.cpp
index 42b5a15..53d6ee5 100644
--- a/cpp/src/serialization/expressionserializer.cpp
+++ b/cpp/src/serialization/expressionserializer.cpp
@@ -1,303 +1,316 @@
/*
* expressionserializer.cpp
*
* Created on: Jan 4, 2016
* Author: pgess
*/
#include "serialization/expressionserializer.h"
+#include <boost/utility.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 */
+} /* namespace xreate */
\ No newline at end of file
diff --git a/cpp/src/serialization/expressionserializer.h b/cpp/src/serialization/expressionserializer.h
index 9acf8c4..52daba8 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_ */
+#endif /* SRC_EXPRESSIONSERIALIZER_H_ */
\ No newline at end of file
diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt
index e980a74..25f9a64 100644
--- a/cpp/tests/CMakeLists.txt
+++ b/cpp/tests/CMakeLists.txt
@@ -1,18 +1,25 @@
cmake_minimum_required(VERSION 2.8.11)
project(xreate-tests)
find_package(GTest REQUIRED)
INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS})
INCLUDE_DIRECTORIES("/usr/include/libxml2")
INCLUDE_DIRECTORIES($<TARGET_PROPERTY:xreate,INCLUDE_DIRECTORIES>)
# TESTS
#=========================
+FIND_PACKAGE (LLVM REQUIRED)
+message("LLVM_LIBRARY_DIRS: " ${LLVM_LIBRARY_DIRS})
+link_directories(${LLVM_LIBRARY_DIRS})
+
+set (LIBCLASP_PATH ${POTASSCO_PATH}/build/debug)
+link_directories(${LIBCLASP_PATH})
+
aux_source_directory(. TEST_FILES)
add_executable(${PROJECT_NAME} ${TEST_FILES})
target_link_libraries(${PROJECT_NAME} xreate ${GTEST_LIBRARIES} pthread xml2 gcov)
add_custom_target (coverage
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/src/code-coverage.sh
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})

Event Timeline