2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/sapply.c
15 #include "statement.h"
19 /**************************************
20 * A Statement tree walker that will visit each Statement s in the tree,
21 * in depth-first evaluation order, and call fp(s,param) on it.
22 * fp() signals whether the walking continues with its return value:
26 * It's a bit slower than using virtual functions, but more encapsulated and less brittle.
27 * Creating an iterator for this would be much more complex.
30 class PostorderStatementVisitor
: public StoppableVisitor
34 PostorderStatementVisitor(StoppableVisitor
*v
) : v(v
) {}
36 bool doCond(Statement
*s
)
42 bool applyTo(Statement
*s
)
49 void visit(Statement
*s
)
53 void visit(PeelStatement
*s
)
55 doCond(s
->s
) || applyTo(s
);
57 void visit(CompoundStatement
*s
)
59 for (size_t i
= 0; i
< s
->statements
->dim
; i
++)
60 if (doCond((*s
->statements
)[i
]))
64 void visit(UnrolledLoopStatement
*s
)
66 for (size_t i
= 0; i
< s
->statements
->dim
; i
++)
67 if (doCond((*s
->statements
)[i
]))
71 void visit(ScopeStatement
*s
)
73 doCond(s
->statement
) || applyTo(s
);
75 void visit(WhileStatement
*s
)
77 doCond(s
->_body
) || applyTo(s
);
79 void visit(DoStatement
*s
)
81 doCond(s
->_body
) || applyTo(s
);
83 void visit(ForStatement
*s
)
85 doCond(s
->_init
) || doCond(s
->_body
) || applyTo(s
);
87 void visit(ForeachStatement
*s
)
89 doCond(s
->_body
) || applyTo(s
);
91 void visit(ForeachRangeStatement
*s
)
93 doCond(s
->_body
) || applyTo(s
);
95 void visit(IfStatement
*s
)
97 doCond(s
->ifbody
) || doCond(s
->elsebody
) || applyTo(s
);
99 void visit(PragmaStatement
*s
)
101 doCond(s
->_body
) || applyTo(s
);
103 void visit(SwitchStatement
*s
)
105 doCond(s
->_body
) || applyTo(s
);
107 void visit(CaseStatement
*s
)
109 doCond(s
->statement
) || applyTo(s
);
111 void visit(DefaultStatement
*s
)
113 doCond(s
->statement
) || applyTo(s
);
115 void visit(SynchronizedStatement
*s
)
117 doCond(s
->_body
) || applyTo(s
);
119 void visit(WithStatement
*s
)
121 doCond(s
->_body
) || applyTo(s
);
123 void visit(TryCatchStatement
*s
)
125 if (doCond(s
->_body
))
128 for (size_t i
= 0; i
< s
->catches
->dim
; i
++)
129 if (doCond((*s
->catches
)[i
]->handler
))
133 void visit(TryFinallyStatement
*s
)
135 doCond(s
->_body
) || doCond(s
->finalbody
) || applyTo(s
);
137 void visit(OnScopeStatement
*s
)
139 doCond(s
->statement
) || applyTo(s
);
141 void visit(DebugStatement
*s
)
143 doCond(s
->statement
) || applyTo(s
);
145 void visit(LabelStatement
*s
)
147 doCond(s
->statement
) || applyTo(s
);
151 bool walkPostorder(Statement
*s
, StoppableVisitor
*v
)
153 PostorderStatementVisitor
pv(v
);