1 /** 2 * Compiler implementation of the 3 * $(LINK2 http://www.dlang.org, D programming language). 4 * 5 * Copyright: Copyright (c) 1999-2016 by Digital Mars, All Rights Reserved 6 * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) 7 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 8 * Source: $(DMDSRC _sparse.d) 9 */ 10 11 module ddmd.sapply; 12 13 import ddmd.statement; 14 import ddmd.visitor; 15 16 /************************************** 17 * A Statement tree walker that will visit each Statement s in the tree, 18 * in depth-first evaluation order, and call fp(s,param) on it. 19 * fp() signals whether the walking continues with its return value: 20 * Returns: 21 * 0 continue 22 * 1 done 23 * It's a bit slower than using virtual functions, but more encapsulated and less brittle. 24 * Creating an iterator for this would be much more complex. 25 */ 26 extern (C++) final class PostorderStatementVisitor : StoppableVisitor 27 { 28 alias visit = super.visit; 29 public: 30 StoppableVisitor v; 31 32 extern (D) this(StoppableVisitor v) 33 { 34 this.v = v; 35 } 36 37 bool doCond(Statement s) 38 { 39 if (!stop && s) 40 s.accept(this); 41 return stop; 42 } 43 44 bool applyTo(Statement s) 45 { 46 s.accept(v); 47 stop = v.stop; 48 return true; 49 } 50 51 override void visit(Statement s) 52 { 53 applyTo(s); 54 } 55 56 override void visit(PeelStatement s) 57 { 58 doCond(s.s) || applyTo(s); 59 } 60 61 override void visit(CompoundStatement s) 62 { 63 for (size_t i = 0; i < s.statements.dim; i++) 64 if (doCond((*s.statements)[i])) 65 return; 66 applyTo(s); 67 } 68 69 override void visit(UnrolledLoopStatement s) 70 { 71 for (size_t i = 0; i < s.statements.dim; i++) 72 if (doCond((*s.statements)[i])) 73 return; 74 applyTo(s); 75 } 76 77 override void visit(ScopeStatement s) 78 { 79 doCond(s.statement) || applyTo(s); 80 } 81 82 override void visit(WhileStatement s) 83 { 84 doCond(s._body) || applyTo(s); 85 } 86 87 override void visit(DoStatement s) 88 { 89 doCond(s._body) || applyTo(s); 90 } 91 92 override void visit(ForStatement s) 93 { 94 doCond(s._init) || doCond(s._body) || applyTo(s); 95 } 96 97 override void visit(ForeachStatement s) 98 { 99 doCond(s._body) || applyTo(s); 100 } 101 102 override void visit(ForeachRangeStatement s) 103 { 104 doCond(s._body) || applyTo(s); 105 } 106 107 override void visit(IfStatement s) 108 { 109 doCond(s.ifbody) || doCond(s.elsebody) || applyTo(s); 110 } 111 112 override void visit(PragmaStatement s) 113 { 114 doCond(s._body) || applyTo(s); 115 } 116 117 override void visit(SwitchStatement s) 118 { 119 doCond(s._body) || applyTo(s); 120 } 121 122 override void visit(CaseStatement s) 123 { 124 doCond(s.statement) || applyTo(s); 125 } 126 127 override void visit(DefaultStatement s) 128 { 129 doCond(s.statement) || applyTo(s); 130 } 131 132 override void visit(SynchronizedStatement s) 133 { 134 doCond(s._body) || applyTo(s); 135 } 136 137 override void visit(WithStatement s) 138 { 139 doCond(s._body) || applyTo(s); 140 } 141 142 override void visit(TryCatchStatement s) 143 { 144 if (doCond(s._body)) 145 return; 146 for (size_t i = 0; i < s.catches.dim; i++) 147 if (doCond((*s.catches)[i].handler)) 148 return; 149 applyTo(s); 150 } 151 152 override void visit(TryFinallyStatement s) 153 { 154 doCond(s._body) || doCond(s.finalbody) || applyTo(s); 155 } 156 157 override void visit(OnScopeStatement s) 158 { 159 doCond(s.statement) || applyTo(s); 160 } 161 162 override void visit(DebugStatement s) 163 { 164 doCond(s.statement) || applyTo(s); 165 } 166 167 override void visit(LabelStatement s) 168 { 169 doCond(s.statement) || applyTo(s); 170 } 171 } 172 173 extern (C++) bool walkPostorder(Statement s, StoppableVisitor v) 174 { 175 scope PostorderStatementVisitor pv = new PostorderStatementVisitor(v); 176 s.accept(pv); 177 return v.stop; 178 }