cfatemporalseqpass.cpp
No OneTemporary

File Metadata

Created
Tue, Jul 7, 1:12 PM

cfatemporalseqpass.cpp

/* 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: cfatemporalseqpass.cpp
* Author: pgess
*
* Created on February 4, 2019, 4:43 PM
*/
/**
* \file cfatemporalseqpass.h
* \brief Context Blocks' compilation order analysis.
*/
#include "pass/cfatemporalseqpass.h"
#include "analysis/temporalseqgraph.h"
using namespace xreate::cfa;
using namespace std;
namespace xreate {
template<>
cfa::Socket defaultValue<cfa::Socket>() {
const cfa::TemporalNode invalidNode{(ScopePacked) - 1, cfa::TemporalOperator::EMPTY};
return make_pair(invalidNode, invalidNode);
};
}
CFATemporalSeqPass::CFATemporalSeqPass(PassManager* manager)
: AbstractPass(manager), __graph(new TemporalSeqGraph(manager->transcend)) { }
void
CFATemporalSeqPass::finish() {
man->transcend->registerReport(__graph);
return AbstractPass::finish();
}
void
CFATemporalSeqPass::process(
const Expression &expression,
PassContext context,
const std::string &varDecl) {
TranscendLayer* transcend = man->transcend;
if(expression.__state == Expression::COMPOUND) {
Operator op = expression.op;
switch(op) {
case Operator::QUERY_LATE:
case Operator::MAP:
case Operator::FOLD:
case Operator::INF:
{
__graph->addSubScopes(context.scope,
expression.blocks);
break;
}
case Operator::IF:
case Operator::SWITCH:
case Operator::SWITCH_LATE:
case Operator::SWITCH_VARIANT:
{
__graph->addBranchScopes(context.scope,
expression.blocks);
break;
}
case Operator::SEQUENCE:
{
auto socket = __graph->addSocket(context.scope, TemporalOperator::AND);
auto nodeFrom = socket.first;
for(auto scopeIt = expression.blocks.begin(); scopeIt != expression.blocks.end(); ++scopeIt) {
ScopePacked scope = transcend->pack(*scopeIt);
TemporalNode node{scope, TemporalOperator::SCOPE};
__graph->connect(nodeFrom, node);
nodeFrom = node;
}
__graph->connect(nodeFrom, socket.second);
}
default:
break;
}
}
return Parent::process(expression, context, varDecl);
}
void
CFATemporalSeqPass::processFnCall(ManagedFnPtr functionCallee, PassContext context) {
auto callerSock = __graph->addSocket(context.scope, TemporalOperator::AND);
auto calleeSock = __graph->getFnSocket(functionCallee);
__graph->connectGuarded(callerSock, calleeSock);
}
void
CFATemporalSeqPass::processFnCallUncertain(const std::string& calleeName, const std::list<ManagedFnPtr>& candidates, PassContext context) {
auto callerSock = __graph->addSocket(context.scope, TemporalOperator::AND);
auto calleeSock = __graph->getUncertainFnSocket(calleeName, candidates);
__graph->connectGuarded(callerSock, calleeSock);
}
void
CFATemporalSeqPass::process(ManagedFnPtr function) {
TranscendLayer* transcend = man->transcend;
Socket fnSocket = __graph->getFnSocket(function);
TemporalNode entryNode{
transcend->pack(function->getEntryScope()),
TemporalOperator::SCOPE
};
__graph->connect(fnSocket.first, entryNode);
__graph->connect(entryNode, fnSocket.second);
return Parent::process(function);
}

Event Timeline