Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F2647851
dfagraph.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
Mon, Dec 15, 5:58 AM
Size
8 KB
Mime Type
text/x-c++
Expires
Wed, Dec 17, 5:58 AM (15 h, 18 m)
Engine
blob
Format
Raw Data
Handle
225777
Attached To
rXR Xreate
dfagraph.cpp
View Options
#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);
}
}
}
Event Timeline
Log In to Comment