1 package polyglot.ext.jl.ast; 2 3 import polyglot.ast.*; 4 import polyglot.types.*; 5 import polyglot.visit.*; 6 import polyglot.util.*; 7 import java.util.*; 8 9 14 public class For_c extends Loop_c implements For 15 { 16 protected List inits; 17 protected Expr cond; 18 protected List iters; 19 protected Stmt body; 20 21 public For_c(Position pos, List inits, Expr cond, List iters, Stmt body) { 22 super(pos); 23 this.inits = TypedList.copyAndCheck(inits, ForInit.class, true); 24 this.cond = cond; 25 this.iters = TypedList.copyAndCheck(iters, ForUpdate.class, true); 26 this.body = body; 27 } 28 29 30 public List inits() { 31 return Collections.unmodifiableList(this.inits); 32 } 33 34 35 public For inits(List inits) { 36 For_c n = (For_c) copy(); 37 n.inits = TypedList.copyAndCheck(inits, ForInit.class, true); 38 return n; 39 } 40 41 42 public Expr cond() { 43 return this.cond; 44 } 45 46 47 public For cond(Expr cond) { 48 For_c n = (For_c) copy(); 49 n.cond = cond; 50 return n; 51 } 52 53 54 public List iters() { 55 return Collections.unmodifiableList(this.iters); 56 } 57 58 59 public For iters(List iters) { 60 For_c n = (For_c) copy(); 61 n.iters = TypedList.copyAndCheck(iters, ForUpdate.class, true); 62 return n; 63 } 64 65 66 public Stmt body() { 67 return this.body; 68 } 69 70 71 public For body(Stmt body) { 72 For_c n = (For_c) copy(); 73 n.body = body; 74 return n; 75 } 76 77 78 protected For_c reconstruct(List inits, Expr cond, List iters, Stmt body) { 79 if (! CollectionUtil.equals(inits, this.inits) || cond != this.cond || ! CollectionUtil.equals(iters, this.iters) || body != this.body) { 80 For_c n = (For_c) copy(); 81 n.inits = TypedList.copyAndCheck(inits, ForInit.class, true); 82 n.cond = cond; 83 n.iters = TypedList.copyAndCheck(iters, ForUpdate.class, true); 84 n.body = body; 85 return n; 86 } 87 88 return this; 89 } 90 91 92 public Node visitChildren(NodeVisitor v) { 93 List inits = visitList(this.inits, v); 94 Expr cond = (Expr) visitChild(this.cond, v); 95 List iters = visitList(this.iters, v); 96 Stmt body = (Stmt) visitChild(this.body, v); 97 return reconstruct(inits, cond, iters, body); 98 } 99 100 public Context enterScope(Context c) { 101 return c.pushBlock(); 102 } 103 104 105 public Node typeCheck(TypeChecker tc) throws SemanticException { 106 TypeSystem ts = tc.typeSystem(); 107 108 Type t = null; 112 113 for (Iterator i = inits.iterator(); i.hasNext(); ) { 114 ForInit s = (ForInit) i.next(); 115 116 if (s instanceof LocalDecl) { 117 LocalDecl d = (LocalDecl) s; 118 Type dt = d.type().type(); 119 if (t == null) { 120 t = dt; 121 } 122 else if (! t.equals(dt)) { 123 throw new InternalCompilerError("Local variable " + 124 "declarations in a for loop initializer must all " + 125 "be the same type, in this case " + t + ", not " + 126 dt + ".", d.position()); 127 } 128 } 129 } 130 131 if (cond != null && 132 ! ts.isImplicitCastValid(cond.type(), ts.Boolean())) { 133 throw new SemanticException( 134 "The condition of a for statement must have boolean type.", 135 cond.position()); 136 } 137 138 return this; 139 } 140 141 public Type childExpectedType(Expr child, AscriptionVisitor av) { 142 TypeSystem ts = av.typeSystem(); 143 144 if (child == cond) { 145 return ts.Boolean(); 146 } 147 148 return child.type(); 149 } 150 151 152 public void prettyPrint(CodeWriter w, PrettyPrinter tr) { 153 w.write("for ("); 154 w.begin(0); 155 156 if (inits != null) { 157 boolean first = true; 158 for (Iterator i = inits.iterator(); i.hasNext(); ) { 159 ForInit s = (ForInit) i.next(); 160 printForInit(s, w, tr, first); 161 first = false; 162 163 if (i.hasNext()) { 164 w.write(","); 165 w.allowBreak(2, " "); 166 } 167 } 168 } 169 170 w.write(";"); 171 w.allowBreak(0); 172 173 if (cond != null) { 174 printBlock(cond, w, tr); 175 } 176 177 w.write (";"); 178 w.allowBreak(0); 179 180 if (iters != null) { 181 for (Iterator i = iters.iterator(); i.hasNext();) { 182 ForUpdate s = (ForUpdate) i.next(); 183 printForUpdate(s, w, tr); 184 185 if (i.hasNext()) { 186 w.write(","); 187 w.allowBreak(2, " "); 188 } 189 } 190 } 191 192 w.end(); 193 w.write(")"); 194 195 printSubStmt(body, w, tr); 196 } 197 198 public String toString() { 199 return "for (...) ..."; 200 } 201 202 private void printForInit(ForInit s, CodeWriter w, PrettyPrinter tr, boolean printType) { 203 boolean oldSemiColon = tr.appendSemicolon(false); 204 boolean oldPrintType = tr.printType(printType); 205 printBlock(s, w, tr); 206 tr.printType(oldPrintType); 207 tr.appendSemicolon(oldSemiColon); 208 } 209 210 private void printForUpdate(ForUpdate s, CodeWriter w, PrettyPrinter tr) { 211 boolean oldSemiColon = tr.appendSemicolon(false); 212 printBlock(s, w, tr); 213 tr.appendSemicolon(oldSemiColon); 214 } 215 216 public Term entry() { 217 return listEntry(inits, (cond != null ? cond.entry() : body.entry())); 218 } 219 220 public List acceptCFG(CFGBuilder v, List succs) { 221 v.visitCFGList(inits, (cond != null ? cond.entry() : body.entry())); 222 223 if (cond != null) { 224 if (condIsConstantTrue()) { 225 v.visitCFG(cond, body.entry()); 226 } 227 else { 228 v.visitCFG(cond, FlowGraph.EDGE_KEY_TRUE, body.entry(), 229 FlowGraph.EDGE_KEY_FALSE, this); 230 } 231 } 232 233 v.push(this).visitCFG(body, continueTarget()); 234 v.visitCFGList(iters, (cond != null ? cond.entry() : body.entry())); 235 236 return succs; 237 } 238 239 public Term continueTarget() { 240 return listEntry(iters, (cond != null ? cond.entry() : body.entry())); 241 } 242 } 243 | Popular Tags |