1 package polyglot.ext.jl.ast; 2 3 import polyglot.ast.*; 4 import polyglot.visit.*; 5 import polyglot.types.*; 6 import polyglot.util.*; 7 import java.util.*; 8 9 13 public class Conditional_c extends Expr_c implements Conditional 14 { 15 protected Expr cond; 16 protected Expr consequent; 17 protected Expr alternative; 18 19 public Conditional_c(Position pos, Expr cond, Expr consequent, Expr alternative) { 20 super(pos); 21 this.cond = cond; 22 this.consequent = consequent; 23 this.alternative = alternative; 24 } 25 26 27 public Precedence precedence() { 28 return Precedence.CONDITIONAL; 29 } 30 31 32 public Expr cond() { 33 return this.cond; 34 } 35 36 37 public Conditional cond(Expr cond) { 38 Conditional_c n = (Conditional_c) copy(); 39 n.cond = cond; 40 return n; 41 } 42 43 44 public Expr consequent() { 45 return this.consequent; 46 } 47 48 49 public Conditional consequent(Expr consequent) { 50 Conditional_c n = (Conditional_c) copy(); 51 n.consequent = consequent; 52 return n; 53 } 54 55 56 public Expr alternative() { 57 return this.alternative; 58 } 59 60 61 public Conditional alternative(Expr alternative) { 62 Conditional_c n = (Conditional_c) copy(); 63 n.alternative = alternative; 64 return n; 65 } 66 67 68 protected Conditional_c reconstruct(Expr cond, Expr consequent, Expr alternative) { 69 if (cond != this.cond || consequent != this.consequent || alternative != this.alternative) { 70 Conditional_c n = (Conditional_c) copy(); 71 n.cond = cond; 72 n.consequent = consequent; 73 n.alternative = alternative; 74 return n; 75 } 76 77 return this; 78 } 79 80 81 public Node visitChildren(NodeVisitor v) { 82 Expr cond = (Expr) visitChild(this.cond, v); 83 Expr consequent = (Expr) visitChild(this.consequent, v); 84 Expr alternative = (Expr) visitChild(this.alternative, v); 85 return reconstruct(cond, consequent, alternative); 86 } 87 88 89 public Node typeCheck(TypeChecker tc) throws SemanticException { 90 TypeSystem ts = tc.typeSystem(); 91 92 if (! ts.equals(cond.type(), ts.Boolean())) { 93 throw new SemanticException( 94 "Condition of ternary expression must be of type boolean.", 95 cond.position()); 96 } 97 98 Expr e1 = consequent; 99 Expr e2 = alternative; 100 Type t1 = e1.type(); 101 Type t2 = e2.type(); 102 103 if (ts.equals(t1, t2)) { 107 return type(t1); 108 } 109 110 if (t1.isNumeric() && t2.isNumeric()) { 113 if (t1.isByte() && t2.isShort() || t1.isShort() && t2.isByte()) { 117 return type(ts.Short()); 118 } 119 120 125 if (t1.isIntOrLess() && 126 t2.isInt() && 127 ts.numericConversionValid(t1, e2.constantValue())) { 128 return type(t1); 129 } 130 131 if (t2.isIntOrLess() && 132 t1.isInt() && 133 ts.numericConversionValid(t2, e1.constantValue())) { 134 return type(t2); 135 } 136 137 return type(ts.promote(t1, t2)); 142 } 143 144 if (t1.isNull() && t2.isReference()) return type(t2); 148 if (t2.isNull() && t1.isReference()) return type(t1); 149 150 156 if (t1.isReference() && t2.isReference()) { 157 if (ts.isImplicitCastValid(t1, t2)) { 158 return type(t2); 159 } 160 if (ts.isImplicitCastValid(t2, t1)) { 161 return type(t1); 162 } 163 } 164 165 throw new SemanticException( 166 "Could not find a type for ternary conditional expression.", 167 position()); 168 } 169 170 public Type childExpectedType(Expr child, AscriptionVisitor av) { 171 TypeSystem ts = av.typeSystem(); 172 173 if (child == cond) { 174 return ts.Boolean(); 175 } 176 177 if (child == consequent || child == alternative) { 178 return type(); 179 } 180 181 return child.type(); 182 } 183 184 public String toString() { 185 return cond + " ? " + consequent + " : " + alternative; 186 } 187 188 189 public void prettyPrint(CodeWriter w, PrettyPrinter tr) 190 { 191 printSubExpr(cond, false, w, tr); 192 w.write(" ? "); 193 printSubExpr(consequent, false, w, tr); 194 w.write(" : "); 195 printSubExpr(alternative, false, w, tr); 196 } 197 198 public Term entry() { 199 return cond.entry(); 200 } 201 202 public List acceptCFG(CFGBuilder v, List succs) { 203 v.visitCFG(cond, FlowGraph.EDGE_KEY_TRUE, consequent.entry(), 204 FlowGraph.EDGE_KEY_FALSE, alternative.entry()); 205 v.visitCFG(consequent, this); 206 v.visitCFG(alternative, this); 207 208 return succs; 209 } 210 211 public boolean isConstant() { 212 return cond.isConstant() && consequent.isConstant() && alternative.isConstant(); 213 } 214 215 public Object constantValue() { 216 Object cond_ = cond.constantValue(); 217 Object then_ = consequent.constantValue(); 218 Object else_ = alternative.constantValue(); 219 220 if (cond_ instanceof Boolean && then_ != null && else_ != null) { 221 boolean c = ((Boolean ) cond_).booleanValue(); 222 if (c) { 223 return then_; 224 } 225 else { 226 return else_; 227 } 228 } 229 230 return null; 231 } 232 } 233 | Popular Tags |