diff --git a/cpp/src/analysis/dfagraph.cpp b/cpp/src/analysis/dfagraph.cpp index f64be93..b63efb6 100644 --- a/cpp/src/analysis/dfagraph.cpp +++ b/cpp/src/analysis/dfagraph.cpp @@ -1,239 +1,239 @@ /* 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: DFAGraph.h * Author: pgess * */ /** * \file dfagraph.h * \brief Data Flow Analysis(DFA) graph data * */ #include "analysis/dfagraph.h" #include "analysis/aux.h" #include using namespace std; namespace xreate {namespace dfa { struct VisitorNodeHash : public boost::static_visitor { std::size_t operator()(const xreate::SymbolPacked& node) const noexcept { return 2* (node.identifier + 2 * node.scope + 3 * std::abs(node.version)) + 1; } std::size_t operator()(const xreate::dfa::SymbolAnonymous& node) const noexcept { return 2 * node.id; } }; }} std::size_t hash::operator()(xreate::dfa::SymbolNode const& s) const noexcept { return boost::apply_visitor(xreate::dfa::VisitorNodeHash(), s); } namespace xreate { namespace dfa { bool operator==(const SymbolAnonymous& s1, const SymbolAnonymous& s2){ return s1.id == s2.id && s1.flagIsUsed == s2.flagIsUsed; } class VisitorFormatSymbol: public boost::static_visitor { public: boost::format operator()(const SymbolPacked& node) const { //boost::format formatSymbNamed("s(%1%, %2%, %3%)"); - boost::format formatSymbNamed("s%1%%2%"); + boost::format formatSymbNamed("s(%1%,%2%)"); return formatSymbNamed % node.identifier /*% node.version*/ % node.scope ; } boost::format operator()(const SymbolAnonymous& node) const { //boost::format formatSymbAnonymous("anon(%1%)"); boost::format formatSymbAnonymous("a%1%"); return formatSymbAnonymous % node.id; } }; void DFACallInstance::print(std::ostringstream& output) const{ boost::format formatArgs; boost::format formatInstance("dfa_callinstance(%1%, %2%)."); boost::format formatRet("dfa_callret(%1%, %2%)."); switch (type) { case WEAK: formatArgs = boost::format("weak(dfa_callargs(%1%, %2%, %3%))."); break; case STRONG: formatArgs = boost::format("weak(dfa_callargs(%1%, %2%, %3%)).\ndfa_callargs(%1%, %2%, %3%)."); break; } output << formatInstance % id % fnName << endl; for(std::pair rec: args) { SymbolNode argFormal(rec.first); output << formatArgs % id % boost::apply_visitor(VisitorFormatSymbol(), argFormal) % boost::apply_visitor(VisitorFormatSymbol(), rec.second) << endl; } output << formatRet % id % boost::apply_visitor(VisitorFormatSymbol(), retActual) << endl; } void DFAGraph::addDependency(const SymbolNode& node, const SymbolNode& subnode){ __dependencies.emplace(node, subnode); if (boost::get(&node)){ __usedSymbols.insert(node); } if (boost::get(&subnode)){ __usedSymbols.insert(node); } } void DFAGraph::printDependencies(std::ostringstream& output) const{ for(const SymbolNode& root: __roots){ printDependency(output, root, root); } } void DFAGraph::printDependency(std::ostringstream& output, const SymbolNode& nodeCurrent, const SymbolNode& nodeDependent) const { auto range = __dependencies.equal_range(nodeCurrent); for (auto it = range.first; it != range.second; ++it){ if (boost::get(&it->second)){ if (!__usedSymbols.count(it->second)){ printDependency(output, it->second, nodeDependent); continue; } } boost::format formatDependency("dfa_depends(%1%, %2%)."); output << formatDependency % boost::apply_visitor(VisitorFormatSymbol(), nodeDependent) % boost::apply_visitor(VisitorFormatSymbol(), it->second) << endl; printDependency(output, it->second, it->second); } } void DFAGraph::printInplaceAnnotations(SymbolNode node, const Expression& expression) { // write down in-place expression tags: boost::format formatBind("bind(%1%, %2%)."); if (expression.tags.size()) __usedSymbols.insert(node); for (const pair& tag : expression.tags){ for (const string& tagPart: xreate::analysis::compile(tag.second)) { __output << formatBind % boost::apply_visitor(VisitorFormatSymbol(), node) % tagPart << endl; } } } void DFAGraph::printAlias(const SymbolNode& symbFormal, const SymbolNode& symbActual){ __usedSymbols.insert(symbFormal); __usedSymbols.insert(symbActual); boost::format formatAlias("dfa_alias(%1%, %2%)."); __output << formatAlias % boost::apply_visitor(VisitorFormatSymbol(), symbFormal) % boost::apply_visitor(VisitorFormatSymbol(), symbActual) << endl; } void DFAGraph::printWeakAlias(const SymbolNode& symbFormal, const SymbolNode& symbActual){ __usedSymbols.insert(symbFormal); __usedSymbols.insert(symbActual); boost::format formatAlias("weak(dfa_alias(%1%, %2%))."); __output << formatAlias % boost::apply_visitor(VisitorFormatSymbol(), symbFormal) % boost::apply_visitor(VisitorFormatSymbol(), symbActual) << endl; } void DFAGraph::printFunctionRet(ManagedFnPtr function, const SymbolNode& symbolRet){ boost::format formatRet("dfa_fnret(%1%, %2%)."); __usedSymbols.insert(symbolRet); __output << formatRet % function->getName() % boost::apply_visitor(VisitorFormatSymbol(), symbolRet) << endl; __roots.insert(symbolRet); } void DFAGraph::addCallInstance(DFACallInstance&& instance){ __usedSymbols.insert(instance.retActual); for(const auto arg: instance.args){ __usedSymbols.insert(SymbolNode(arg.first)); __usedSymbols.insert(arg.second); } __callInstances.push_back(std::move(instance)); } void DFAGraph::print(std::ostringstream& output) const{ output << endl << "%\t\tStatic analysis: DFA" << endl; //Dependencies printDependencies(output); //Add generated report output << __output.str() << endl; //Call instances for(const DFACallInstance& instance: __callInstances){ instance.print(output); } output << endl; } void DFAGraph::printSymbols(ClaspLayer* clasp){ boost::format formatHint("shint(%1%, \"%2%\")."); for (const SymbolNode& node : __usedSymbols) { __output << "v(" << boost::apply_visitor(VisitorFormatSymbol(), node) << "). "; if (const SymbolPacked* symbol = boost::get(&node)){ __output << formatHint % boost::apply_visitor(VisitorFormatSymbol(), node) % clasp->getHintForPackedSymbol(*symbol); } __output << endl; } } }} //end of namespace xreate::dfa