dfapass.cpp
No OneTemporary

File Metadata

Created
Sun, Apr 19, 10:26 AM

dfapass.cpp

#include "pass/dfapass.h"
#include "analysis/dfagraph.h"
#include "xreatemanager.h"
#include "clasplayer.h"
#include <boost/format.hpp>
using namespace std;
namespace xreate { namespace dfa {
class DfaExpressionProcessor {
std::vector<SymbolNode> operands;
std::vector<SymbolPacked> blocks;
const Expression expression;
SymbolNode result;
DFAPass * const pass;
const PassContext context;
public:
DfaExpressionProcessor(const Expression& expr, SymbolNode resInitial, DFAPass * const p, const PassContext c)
: expression(expr), result(resInitial), pass(p), context(c) {
operands.reserve(expression.getOperands().size());
for (const Expression &op : expression.getOperands()) {
SymbolAnonymous symbOp(op.id);
operands.push_back(DfaExpressionProcessor(op, symbOp, pass, context).process());
}
blocks.reserve(expression.blocks.size());
for (CodeScope* scope : expression.blocks) {
blocks.push_back(pass->process(scope, context));
}
}
SymbolNode
process() {
if (expression.__state == Expression::COMPOUND) {
processCompoundOp();
} else {
processElementaryOp();
}
applySignatureAnnotations();
applyInPlaceAnnotations();
return result;
}
private:
void
processElementaryOp() {
switch (expression.__state) {
case Expression::IDENT:
{
SymbolPacked symbFrom = pass->processSymbol(Attachments::get<Symbol>(expression), context, expression.getValueString());
SymbolPacked* symbTo = boost::get<SymbolPacked>(&result);
if (symbTo) {
pass->__context.graph->addConnection(*symbTo, SymbolNode(symbFrom), DFGConnection::STRONG);
} else {
result = SymbolNode(symbFrom);
}
break;
}
default: break;
}
}
void
processCompoundOp() {
switch (expression.op) {
//DEBT provide CALL processing
// case Operator::CALL: {
// const string &nameCalleeFunction = expression.getValueString();
//
// //TODO implement processFnCall/Uncertain
// list<ManagedFnPtr> variantsCalleeFunction = man->root->getFunctionVariants(nameCalleeFunction);
// if (variantsCalleeFunction.size()!=1) return;
// ManagedFnPtr function= variantsCalleeFunction.front();
//
// // set calling relations:
// CodeScope *scopeRemote = function->getEntryScope();
// std::vector<SymbolNode>::iterator nodeActual = cache.operands.begin();
// for (const std::string &identFormal: scopeRemote->__bindings){
// const ScopedSymbol symbolFormal{scopeRemote->__identifiers.at(identFormal), versions::VERSION_NONE};
//
// __context.graph->addConnection(clasp->pack(Symbol{symbolFormal, scopeRemote}, nameCalleeFunction + ":" + identFormal), *nodeActual, DFGConnection::WEAK);
// ++nodeActual;
// }
//
// //TODO add RET connection
// break;
// }
//MAP processing: apply PROTOTYPE relation
case Operator::MAP:
{
SymbolNode nodeFrom = operands.front();
SymbolPacked* nodeTo = boost::get<SymbolPacked>(&result);
assert(nodeTo);
pass->__context.graph->addConnection(*nodeTo, nodeFrom, DFGConnection::PROTOTYPE);
break;
}
default: break;
}
}
void
applySignatureAnnotations() {
if (pass->__signatures.count(expression.op)) {
const Expression &scheme = pass->__signatures.at(expression.op);
std::vector<SymbolNode>::iterator arg = operands.begin();
std::vector<Expression>::const_iterator tag = scheme.getOperands().begin();
//Assign scheme RET annotation
Expression retTag = *scheme.getOperands().begin();
if (retTag.__state != Expression::INVALID) {
pass->__context.graph->addAnnotation(result, move(retTag));
}
++tag;
while (tag != scheme.getOperands().end()) {
if (tag->__state != Expression::INVALID) {
pass->__context.graph->addAnnotation(*arg, Expression(*tag));
}
++arg;
++tag;
}
// TODO add possibility to have specific signature for a particular function
// if (expression.op == Operator::CALL || expression.op == Operator::INDEX){
// string caption = expression.getValueString();
// operands.push_back(process(Expression(move(caption)), context, ""));
// }
}
}
void
applyInPlaceAnnotations() {
// write down in-place expression tags:
for (pair<std::string, Expression> tag : expression.tags) {
pass->__context.graph->addAnnotation(result, Expression(tag.second));
}
}
};
DFAPass::DFAPass(PassManager* manager)
: AbstractPass(manager)
, __context{new DFAGraph(manager->clasp)}
, clasp(manager->clasp)
{}
SymbolPacked
DFAPass::process(CodeScope* scope, PassContext context, const std::string& hintBlockDecl) {
const SymbolPacked& symbRet = AbstractPass::process(scope, context, hintBlockDecl);
return symbRet;
}
SymbolPacked
DFAPass::processSymbol(const Symbol& symbol, PassContext context, const std::string& hintSymbol) {
const Expression& declaration = CodeScope::getDeclaration(symbol);
const SymbolPacked& symbPacked = clasp->pack(symbol, hintSymbol);
DfaExpressionProcessor(declaration, symbPacked, this, context).process();
return symbPacked;
}
void
DFAPass::run() {
init();
return AbstractPass::run();
}
void
DFAPass::init() {
for (const Expression& scheme : man->root->__dfadata) {
__signatures.emplace(scheme.op, scheme);
}
}
void
DFAPass::finish() {
clasp->setDFAData(move(__context.graph));
}
} //end of namespace dfa
template<>
SymbolPacked defaultValue(){
assert(false);
}
} //xreate namespace
//DEBT represent VersionaPass in declarative form using applyDependencies
// applyDependencies(expression, context, cache, decl);
//DEBT prepare static annotations and represent InterpretationPass in declarative form
// applyStaticAnnotations(expression, context, cache, decl);
//TODO Null ad hoc DFG implementation/None symbol
//DISABLEDFEATURE None value
// if (expression.isNone()){
// return SymbolTransient{{Atom<Identifier_t>(Config::get("clasp.nonevalue"))}};
// }
// non initialized(SymbolInvalid) value
//void
//DFAPass::applyDependencies(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& decl){
// for (SymbolNode &op: cache.operands) {
// __context.graph->addDependencyConnection(cache.result, op);
// }
//
// for (SymbolNode &block: cache.blocks) {
// __context.graph->addDependencyConnection(cache.result, block);
// }
//
// switch(expression.__state) {
// case Expression::IDENT: {
// SymbolNode identSymbol = clasp->pack(Attachments::get<Symbol>(expression), context.function->getName() + ":" + expression.getValueString());
// __context.graph->addDependencyConnection(cache.result, identSymbol);
// }
//
// default: break;
// }
//}
//void
//DFAPass::applyStaticAnnotations(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& decl){
//
// switch(expression.__state) {
// case Expression::NUMBER:
// case Expression::STRING:
// __context.graph->addAnnotation(cache.result, Expression(Atom<Identifier_t>("static")));
// break;
//
// default: break;
// }
//}

Event Timeline