93 #include <type_traits>
100 struct ram_visitor_tag {};
111 template <
typename R = void,
typename... Params>
118 return visit(node, args...);
123 return visit(*node, args...);
137 virtual R
visit(
const Node& node, Params... args) {
140 #define FORWARD(Kind) \
141 if (const auto* n = dynamic_cast<const Kind*>(&node)) return visit##Kind(*n, args...);
213 fatal(
"unsupported type: %s",
typeid(node).name());
216 virtual R
visit(
const Node* node, Params... args) {
217 return visit(*node, args...);
221 #define LINK(Node, Parent) \
222 virtual R visit##Node(const Node& n, Params... args) { \
223 return visit##Parent(n, args...); \
229 LINK(Clear, RelationStatement);
230 LINK(LogSize, RelationStatement);
232 LINK(RelationStatement, Statement);
234 LINK(Swap, BinRelationStatement);
235 LINK(Extend, BinRelationStatement);
236 LINK(BinRelationStatement, Statement);
238 LINK(Sequence, ListStatement);
239 LINK(Loop, Statement);
240 LINK(Parallel, ListStatement);
241 LINK(ListStatement, Statement);
242 LINK(Exit, Statement);
243 LINK(LogTimer, Statement);
244 LINK(LogRelationTimer, Statement);
245 LINK(DebugInfo, Statement);
246 LINK(Call, Statement);
248 LINK(Statement, Node);
251 LINK(Project, Operation);
252 LINK(SubroutineReturn, Operation);
253 LINK(UnpackRecord, TupleOperation);
254 LINK(NestedIntrinsicOperator, TupleOperation)
255 LINK(Scan, RelationOperation);
256 LINK(ParallelScan, Scan);
257 LINK(IndexScan, IndexOperation);
258 LINK(ParallelIndexScan, IndexScan);
259 LINK(Choice, RelationOperation);
260 LINK(ParallelChoice, Choice);
261 LINK(IndexChoice, IndexOperation);
262 LINK(ParallelIndexChoice, IndexChoice);
263 LINK(RelationOperation, TupleOperation);
264 LINK(Aggregate, RelationOperation);
265 LINK(ParallelAggregate, Aggregate);
266 LINK(IndexAggregate, IndexOperation);
267 LINK(ParallelIndexAggregate, IndexAggregate);
268 LINK(IndexOperation, RelationOperation);
269 LINK(TupleOperation, NestedOperation);
270 LINK(Filter, AbstractConditional);
271 LINK(Break, AbstractConditional);
272 LINK(AbstractConditional, NestedOperation);
273 LINK(NestedOperation, Operation);
275 LINK(Operation, Node);
278 LINK(True, Condition);
279 LINK(False, Condition);
280 LINK(Conjunction, Condition);
281 LINK(Negation, Condition);
282 LINK(Constraint, Condition);
283 LINK(ProvenanceExistenceCheck, AbstractExistenceCheck);
284 LINK(ExistenceCheck, AbstractExistenceCheck);
285 LINK(EmptinessCheck, Condition);
286 LINK(AbstractExistenceCheck, Condition);
288 LINK(Condition, Node);
291 LINK(SignedConstant, Constant);
292 LINK(UnsignedConstant, Constant);
293 LINK(FloatConstant, Constant);
294 LINK(Constant, Expression);
295 LINK(UndefValue, Expression);
296 LINK(TupleElement, Expression);
297 LINK(IntrinsicOperator, AbstractOperator);
298 LINK(UserDefinedOperator, AbstractOperator);
299 LINK(AbstractOperator, Expression);
300 LINK(AutoIncrement, Expression);
301 LINK(PackRecord, Expression);
302 LINK(SubroutineArgument, Expression);
303 LINK(RelationSize, Expression);
305 LINK(Expression, Node);
311 LINK(Relation, Node);
316 virtual R
visitNode(
const Node& , Params... ) {
330 template <
typename R,
typename... Ps,
typename... Args>
332 visitor(root, args...);
334 if (cur !=
nullptr) {
349 template <
typename R,
typename... Ps,
typename... Args>
350 void visitDepthFirst(
const Node& root, Visitor<R, Ps...>& visitor, Args&... args) {
360 template <
typename R,
typename N>
362 std::function<R(
const N&)>
lambda;
365 if (
const auto*
n =
dynamic_cast<const N*
>(&node)) {
374 template <
typename R,
typename N>
382 template <
typename T>
384 static constexpr
size_t value = std::is_base_of<ram_visitor_tag, T>::value;
387 template <
typename T>
388 struct is_ram_visitor<const T> :
public is_ram_visitor<T> {};
390 template <
typename T>
403 template <
typename R,
typename N>
406 visitDepthFirst<void>(root, visitor);
418 template <typename Lambda, typename R = typename lambda_traits<Lambda>::result_type,
421 const Node& root,
const Lambda& fun) {