5 #include <functional>
\r
8 std::function<void(const Type &, const std::shared_ptr<Context> ctx)> onType = [](auto, auto){};
\r
9 std::function<void(const Expr &, const std::shared_ptr<Context> ctx)> onExpr = [](auto, auto){};
\r
10 std::function<void(const Stmt &, const std::shared_ptr<Context> ctx)> onStmt = [](auto, auto){};
\r
11 std::function<void(const Body &, const std::shared_ptr<Context> ctx)> onBody = [](auto, auto){};
\r
12 std::function<void(const Function &, const std::shared_ptr<Context> ctx)> onFunction = [](auto, auto){};
\r
13 std::function<void(const Variable &, const std::shared_ptr<Context> ctx)> onVariable = [](auto, auto){};
\r
14 std::function<void(const StructMember<Function> &, const std::shared_ptr<Context> ctx)> onStructMethod = [](auto, auto){};
\r
15 std::function<void(const StructMember<Variable> &, const std::shared_ptr<Context> ctx)> onStructMember = [](auto, auto){};
\r
16 std::function<void(const Struct &, const std::shared_ptr<Context> ctx)> onStruct = [](auto, auto){};
\r
17 std::function<void(const Namespace &, const std::shared_ptr<Context> ctx)> onNamespace = [](auto, auto){};
\r
18 std::function<void(const Program &, const std::shared_ptr<Context> ctx)> onProgram = [](auto, auto){};
\r
21 #define VISIT(XS) for (auto x : XS) visit(x);
\r
26 std::shared_ptr<Context> ctx;
\r
32 void visit(const Type & x)
\r
36 void visit(const Expr & x)
\r
42 case ExprType::Func:
\r
43 VISIT(x._func.arguments)
\r
45 case ExprType::Method:
\r
46 visit(*x._method.expr);
\r
47 VISIT(x._method.arguments);
\r
51 case ExprType::Paren:
\r
52 visit(*x._paren.expr);
\r
55 visit(*x._dot.expr);
\r
57 case ExprType::PrefixOp:
\r
58 visit(*x._prefixOp.expr);
\r
60 case ExprType::PostfixOp:
\r
61 visit(*x._postfixOp.expr);
\r
63 case ExprType::BinaryOp:
\r
64 visit(*x._binaryOp.lexpr);
\r
65 visit(*x._binaryOp.rexpr);
\r
67 case ExprType::TernaryOp:
\r
68 visit(*x._ternaryOp.lexpr);
\r
69 visit(*x._ternaryOp.rexprTrue);
\r
70 visit(*x._ternaryOp.rexprFalse);
\r
72 case ExprType::Bracket:
\r
73 visit(*x._brackets.lexpr);
\r
74 visit(*x._brackets.rexpr);
\r
76 case ExprType::Identifier:
\r
80 void visit(const Stmt & x)
\r
86 case StmtType::Assign:
\r
87 visit(x._assign.lexpr);
\r
88 visit(x._assign.rexpr);
\r
90 case StmtType::Expr:
\r
94 visit(x._for.init->lexpr);
\r
95 visit(x._for.init->rexpr);
\r
96 visit(*x._for.condition);
\r
97 visit(*x._for.action);
\r
101 visit(x._if.condition);
\r
103 for (auto e : x._if.elses)
\r
110 case StmtType::Return:
\r
111 visit(x._return.expr);
\r
113 case StmtType::Switch:
\r
114 visit(*x._switch.ident);
\r
115 for (auto c : x._switch.cases)
\r
121 case StmtType::While:
\r
122 visit(x._while.condition);
\r
123 visit(x._while.body);
\r
127 void visit(const Body & x)
\r
133 VISIT(x.ctx->variables)
\r
134 VISIT(x.statements)
\r
138 void visit(const Namespace & x)
\r
140 v.onNamespace(x, ctx);
\r
144 VISIT(x.namespaces)
\r
145 VISIT(x.ctx->variables)
\r
146 VISIT(x.ctx->structs)
\r
147 VISIT(x.ctx->functions)
\r
151 void visit(const Variable & x)
\r
153 v.onVariable(x, ctx);
\r
156 void visit(const Function & x)
\r
158 v.onFunction(x, ctx);
\r
162 for (auto v : x.parameters)
\r
166 void visit(const StructMember<Function> & x)
\r
168 v.onStructMethod(x, ctx);
\r
172 void visit(const StructMember<Variable> & x)
\r
174 v.onStructMember(x, ctx);
\r
178 void visit(const Struct & x)
\r
180 v.onStruct(x, ctx);
\r
185 void visit(const Program & x)
\r
187 v.onProgram(x, ctx);
\r
191 VISIT(x.namespaces)
\r
192 VISIT(x.ctx->variables)
\r
193 VISIT(x.ctx->structs)
\r
194 VISIT(x.ctx->functions)
\r