\r
#include <functional>\r
\r
+// struct with callback functions for all relevant types\r
+// tree can be walked selectively by providing only\r
+// needed callbacks\r
struct Visitor {\r
- std::function<void(const Type &, const std::shared_ptr<Context> ctx)> onType = [](auto, auto){};\r
- std::function<void(const Expr &, const std::shared_ptr<Context> ctx)> onExpr = [](auto, auto){};\r
- std::function<void(const Stmt &, const std::shared_ptr<Context> ctx)> onStmt = [](auto, auto){};\r
- std::function<void(const Body &, const std::shared_ptr<Context> ctx)> onBody = [](auto, auto){};\r
- std::function<void(const Function &, const std::shared_ptr<Context> ctx)> onFunction = [](auto, auto){};\r
- std::function<void(const Variable &, const std::shared_ptr<Context> ctx)> onVariable = [](auto, auto){};\r
+ std::function<void(const Type &, const std::shared_ptr<Context> ctx)> onType = [](auto, auto){};\r
+ std::function<void(const Expr &, const std::shared_ptr<Context> ctx)> onExpr = [](auto, auto){};\r
+ std::function<void(const Stmt &, const std::shared_ptr<Context> ctx)> onStmt = [](auto, auto){};\r
+ std::function<void(const Body &, const std::shared_ptr<Context> ctx)> onBody = [](auto, auto){};\r
+ std::function<void(const Function &, const std::shared_ptr<Context> ctx)> onFunction = [](auto, auto){};\r
+ std::function<void(const Variable &, const std::shared_ptr<Context> ctx)> onVariable = [](auto, auto){};\r
std::function<void(const StructMember<Function> &, const std::shared_ptr<Context> ctx)> onStructMethod = [](auto, auto){};\r
std::function<void(const StructMember<Variable> &, const std::shared_ptr<Context> ctx)> onStructMember = [](auto, auto){};\r
- std::function<void(const Struct &, const std::shared_ptr<Context> ctx)> onStruct = [](auto, auto){};\r
- std::function<void(const Namespace &, const std::shared_ptr<Context> ctx)> onNamespace = [](auto, auto){};\r
- std::function<void(const Program &, const std::shared_ptr<Context> ctx)> onProgram = [](auto, auto){};\r
+ std::function<void(const Struct &, const std::shared_ptr<Context> ctx)> onStruct = [](auto, auto){};\r
+ std::function<void(const Namespace &, const std::shared_ptr<Context> ctx)> onNamespace = [](auto, auto){};\r
+ std::function<void(const Program &, const std::shared_ptr<Context> ctx)> onProgram = [](auto, auto){};\r
};\r
\r
#define VISIT(XS) for (auto x : XS) visit(x);\r
\r
+// simply walk IR by recursively calling functions for all children\r
struct Visit {\r
private:\r
Visitor v;\r
v.onFunction(x, ctx);\r
\r
if (x.defined) {\r
- visit(x.body);\r
for (auto v : x.parameters)\r
visit(v.type);\r
+ visit(x.body);\r
}\r
}\r
void visit(const StructMember<Function> & x)\r