Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F4001031
temporalseqgraph.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, Jul 9, 5:39 AM
Size
6 KB
Mime Type
text/x-c++
Expires
Sat, Jul 11, 5:39 AM (1 d, 4 h)
Engine
blob
Format
Raw Data
Handle
273128
Attached To
rXR Xreate
temporalseqgraph.cpp
View Options
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* File: temporalseqgraph.cpp
* Author: pgess
*
* Created on February 4, 2019, 4:51 PM
*/
#include "temporalseqgraph.h"
using namespace xreate::cfa;
using namespace std;
namespace std {
bool operator<(const xreate::cfa::TemporalNode& x, const xreate::cfa::TemporalNode& y) {
if(x.scope != y.scope) return x.scope < y.scope;
return x.mark < y.mark;
}
};
TemporalSeqGraph::TemporalSeqGraph(TranscendLayer* transcend)
: __transcend(transcend) { }
void
TemporalSeqGraph::addSubScopes(const CodeScope* scopeIn, const std::list<CodeScope*>& scopesChild) {
auto socket = addSocket(scopeIn, TemporalOperator::AND);
for(auto scopeChild : scopesChild) {
TemporalNode nodeChild = TemporalNode{__transcend->pack(scopeChild), TemporalOperator::SCOPE};
connect(socket.first, nodeChild);
connect(nodeChild, socket.second);
}
}
void
TemporalSeqGraph::addBranchScopes(const CodeScope* scopeIn, const std::list<CodeScope*>& scopesChild) {
auto socket = addSocket(scopeIn, TemporalOperator::AND);
TemporalNode toNode{__idNextVacant++, TemporalOperator::OR};
connect(toNode, socket.second);
for(auto scopeChild : scopesChild) {
TemporalNode nodeChild = TemporalNode{__transcend->pack(scopeChild), TemporalOperator::SCOPE};
connect(socket.first, nodeChild);
connect(nodeChild, toNode);
}
}
std::pair<TemporalNode, TemporalNode>
TemporalSeqGraph::addSocket(const CodeScope* scopeIn, TemporalOperator mark) {
TemporalNode nodeFrom;
TemporalNode nodeIn = TemporalNode{__transcend->pack(scopeIn), TemporalOperator::SCOPE};
auto rangeInward = graph.right.equal_range(nodeIn);
size_t sizeInward = std::distance(rangeInward.first, rangeInward.second);
if (sizeInward == 1) {
//if scope has single inward connection
nodeFrom = rangeInward.first->second;
} else if (sizeInward > 1) {
//if scope has multy inward con:
nodeFrom = insertBefore(nodeIn, EMPTY);
} else {
//no inward connections:
nodeFrom = insertBefore(nodeIn, EMPTY);
}
TemporalNode nodeTo = insertAfter(nodeIn, mark);
return {nodeFrom, nodeTo};
}
Socket
TemporalSeqGraph::getFnSocket(ManagedFnPtr calleeFn) {
if(__cacheFnSockets.count(calleeFn)) {
return __cacheFnSockets.at(calleeFn);
}
TemporalNode fromNode{__idNextVacant++, TemporalOperator::EMPTY};
TemporalNode toNode{__idNextVacant++, TemporalOperator::EMPTY};
Socket fnSock = make_pair(fromNode, toNode);
__cacheFnSockets.emplace(calleeFn, fnSock);
return fnSock;
}
Socket
TemporalSeqGraph::getUncertainFnSocket(const std::string& calleeName, const std::list<ManagedFnPtr>& candidates) {
if(__cacheUncertainFnSockets.count(calleeName)) {
return __cacheUncertainFnSockets.at(calleeName);
}
Socket fnSock;
if(candidates.size() == 0) {
//External Function
TemporalNode node{__idNextVacant++, TemporalOperator::EMPTY};
fnSock = make_pair(node, node);
} else {
//Multiple specializations
TemporalNode fromNode{__idNextVacant++, TemporalOperator::EMPTY};
TemporalNode toNode{__idNextVacant++, TemporalOperator::OR};
fnSock = make_pair(fromNode, toNode);
for (const ManagedFnPtr& candidate : candidates) {
Socket candidateSock = getFnSocket(candidate);
connect(fromNode, candidateSock.first);
connect(candidateSock.second, toNode);
}
}
__cacheUncertainFnSockets.emplace(calleeName, fnSock);
return fnSock;
}
TemporalNode
TemporalSeqGraph::insertBefore(TemporalNode node, TemporalOperator mark) {
TemporalNode nodeNew{__idNextVacant++, mark};
auto nodesInRange = graph.right.equal_range(node);
list<TemporalNode> nodesIn;
for(auto nodeInIt = nodesInRange.first; nodeInIt != nodesInRange.second; ++nodeInIt) {
nodesIn.push_back(nodeInIt->second);
}
graph.right.erase(node);
for(auto nodeIn : nodesIn) {
connect(nodeIn, nodeNew);
}
connect(nodeNew, node);
return nodeNew;
}
TemporalNode
TemporalSeqGraph::insertAfter(TemporalNode node, TemporalOperator mark) {
TemporalNode nodeNew{__idNextVacant++, mark};
auto nodesOutRange = graph.left.equal_range(node);
list<TemporalNode> nodesOut;
for(auto nodeOutIt = nodesOutRange.first; nodeOutIt != nodesOutRange.second; ++nodeOutIt) {
nodesOut.push_back(nodeOutIt->second);
}
graph.left.erase(node);
for(auto nodeOut : nodesOut) {
connect(nodeNew, nodeOut);
}
connect(node, nodeNew);
return nodeNew;
}
void
TemporalSeqGraph::connect(TemporalNode nodeFrom, TemporalNode nodeTo) {
graph.insert(Graph::value_type(nodeFrom, nodeTo));
}
void
TemporalSeqGraph::connectGuarded(const Socket& from, const Socket& to) {
unsigned int guard = __guardNextVacant++;
graphGuarded.emplace(from.first, make_pair(to.first, TemporalGuard{TemporalGuard::IN, guard}));
graphGuarded.emplace(to.second, make_pair(from.second, TemporalGuard{TemporalGuard::OUT, guard}));
}
void
TemporalSeqGraph::print(std::ostringstream &output) const {
for (auto entry : graph) {
output
<< "cfa_seq("
<< entry.left << ", "
<< entry.right << ").\n";
}
for (auto entry : graphGuarded) {
output
<< "cfa_seq_guarded("
<< entry.first << ", "
<< entry.second.first << ", "
<< (entry.second.second.mark == TemporalGuard::IN ? "in(" : "out(")
<< entry.second.second.id << ")).\n";
}
}
bool TemporalSeqGraph::isOrdered(const ScopePacked& scopeAfter, const ScopePacked& scopeBefore) const {
set<TemporalNode> visitedNodes;
return isOrdered(TemporalNode{scopeAfter, TemporalOperator::SCOPE},
TemporalNode{scopeBefore, TemporalOperator::SCOPE},
visitedNodes);
}
bool
TemporalSeqGraph::isOrdered(const TemporalNode& nodeAfter, const TemporalNode& nodeBefore, set<TemporalNode>& visitedNodes) const {
if (nodeAfter.scope == nodeBefore.scope && nodeAfter.mark == nodeBefore.mark) return true;
if (visitedNodes.count(nodeAfter)) return false;
visitedNodes.insert(nodeAfter);
auto frontierList = graph.right.equal_range(nodeAfter);
for(auto frontierIt = frontierList.first; frontierIt != frontierList.second; ++frontierIt) {
if(isOrdered(frontierIt->second, nodeBefore, visitedNodes)) return true;
}
return false;
}
namespace xreate {
namespace cfa {
static string dictNodes[] = {"scope", "empty", "and", "or"};
std::ostream&
operator << (std::ostream& output, const TemporalNode& node) {
string op = dictNodes[node.mark];
output << op << "(" << node.scope << ")";
return output;
}
}}
Event Timeline
Log In to Comment