2023-04-12 11:15:36 +02:00
|
|
|
|
|
|
|
#include <stack>
|
|
|
|
#include <unordered_set>
|
|
|
|
|
|
|
|
#include "zen/config.hpp"
|
|
|
|
|
|
|
|
#include "bolt/CST.hpp"
|
|
|
|
#include "bolt/IPRGraph.hpp"
|
|
|
|
|
|
|
|
namespace bolt {
|
|
|
|
|
|
|
|
void IPRGraph::populate(Node* X, Node* Decl) {
|
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
switch (X->getKind()) {
|
2023-04-12 11:15:36 +02:00
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
case NodeKind::SourceFile:
|
2023-04-12 11:15:36 +02:00
|
|
|
{
|
|
|
|
auto Y = static_cast<SourceFile*>(X);
|
|
|
|
for (auto Element: Y->Elements) {
|
|
|
|
populate(Element, Decl);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
case NodeKind::IfStatement:
|
2023-04-12 11:15:36 +02:00
|
|
|
{
|
|
|
|
auto Y = static_cast<IfStatement*>(X);
|
|
|
|
for (auto Part: Y->Parts) {
|
|
|
|
for (auto Element: Part->Elements) {
|
|
|
|
populate(Element, Decl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
case NodeKind::LetDeclaration:
|
2023-04-12 11:15:36 +02:00
|
|
|
{
|
|
|
|
auto Y = static_cast<LetDeclaration*>(X);
|
|
|
|
if (Y->Body) {
|
2023-05-20 23:48:26 +02:00
|
|
|
switch (Y->Body->getKind()) {
|
|
|
|
case NodeKind::LetBlockBody:
|
2023-04-12 11:15:36 +02:00
|
|
|
{
|
|
|
|
auto Z = static_cast<LetBlockBody*>(Y->Body);
|
|
|
|
for (auto Element: Z->Elements) {
|
|
|
|
populate(Element, Y);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2023-05-20 23:48:26 +02:00
|
|
|
case NodeKind::LetExprBody:
|
2023-04-12 11:15:36 +02:00
|
|
|
{
|
|
|
|
auto Z = static_cast<LetExprBody*>(Y->Body);
|
|
|
|
populate(Z->Expression, Y);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
ZEN_UNREACHABLE
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
case NodeKind::ConstantExpression:
|
2023-04-12 11:15:36 +02:00
|
|
|
break;
|
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
case NodeKind::CallExpression:
|
2023-04-12 11:15:36 +02:00
|
|
|
{
|
|
|
|
auto Y = static_cast<CallExpression*>(X);
|
|
|
|
populate(Y->Function, Decl);
|
|
|
|
for (auto Arg: Y->Args) {
|
|
|
|
populate(Arg, Decl);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
case NodeKind::ReferenceExpression:
|
2023-04-12 11:15:36 +02:00
|
|
|
{
|
|
|
|
auto Y = static_cast<ReferenceExpression*>(X);
|
|
|
|
auto Def = Y->getScope()->lookup(Y->Name->getSymbolPath());
|
|
|
|
ZEN_ASSERT(Def != nullptr);
|
|
|
|
if (Decl != nullptr) {
|
|
|
|
Edges.emplace(Decl, Y);
|
|
|
|
}
|
|
|
|
Edges.emplace(Y, Def);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
ZEN_UNREACHABLE
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* bool IPRGraph::isRecursive(ReferenceExpression* From) { */
|
|
|
|
/* std::unordered_set<Node*> Visited; */
|
|
|
|
/* std::stack<Node*> Queue; */
|
|
|
|
/* while (Queue.size()) { */
|
|
|
|
/* auto A = Queue.top(); */
|
|
|
|
/* Queue.pop(); */
|
|
|
|
/* if (Visited.count(A)) { */
|
|
|
|
/* return true; */
|
|
|
|
/* } */
|
|
|
|
/* for (auto B: getOutEdges(A)) { */
|
|
|
|
/* } */
|
|
|
|
/* } */
|
|
|
|
/* return false; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
}
|