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 13 public class Unary_c extends Expr_c implements Unary 14 { 15 protected Unary.Operator op; 16 protected Expr expr; 17 18 public Unary_c(Position pos, Unary.Operator op, Expr expr) { 19 super(pos); 20 this.op = op; 21 this.expr = expr; 22 } 23 24 25 public Precedence precedence() { 26 return Precedence.UNARY; 27 } 28 29 30 public Expr expr() { 31 return this.expr; 32 } 33 34 35 public Unary expr(Expr expr) { Unary_c n = (Unary_c) copy(); n.expr = expr; 36 return n; } 37 38 39 public Unary.Operator operator() { 40 return this.op; 41 } 42 43 44 public Unary operator(Unary.Operator op) { 45 Unary_c n = (Unary_c) copy(); 46 n.op = op; 47 return n; 48 } 49 50 51 protected Unary_c reconstruct(Expr expr) { 52 if (expr != this.expr) { 53 Unary_c n = (Unary_c) copy(); 54 n.expr = expr; 55 return n; 56 } 57 58 return this; 59 } 60 61 62 public Node visitChildren(NodeVisitor v) { 63 Expr expr = (Expr) visitChild(this.expr, v); 64 return reconstruct(expr); 65 } 66 67 68 public Node typeCheck(TypeChecker tc) throws SemanticException { 69 TypeSystem ts = tc.typeSystem(); 70 71 if (op == POST_INC || op == POST_DEC || 72 op == PRE_INC || op == PRE_DEC) { 73 74 if (! expr.type().isNumeric()) { 75 throw new SemanticException("Operand of " + op + 76 " operator must be numeric.", expr.position()); 77 } 78 79 if (! (expr instanceof Variable)) { 80 throw new SemanticException("Operand of " + op + 81 " operator must be a variable.", expr.position()); 82 } 83 84 if (((Variable) expr).flags().isFinal()) { 85 throw new SemanticException("Operand of " + op + 86 " operator must be a non-final variable.", 87 expr.position()); 88 } 89 90 return type(expr.type()); 91 } 92 93 if (op == BIT_NOT) { 94 if (! ts.isImplicitCastValid(expr.type(), ts.Long())) { 95 throw new SemanticException("Operand of " + op + 96 " operator must be numeric.", expr.position()); 97 } 98 99 return type(ts.promote(expr.type())); 100 } 101 102 if (op == NEG || op == POS) { 103 if (! expr.type().isNumeric()) { 104 throw new SemanticException("Operand of " + op + 105 " operator must be numeric.", expr.position()); 106 } 107 108 return type(ts.promote(expr.type())); 109 } 110 111 if (op == NOT) { 112 if (! expr.type().isBoolean()) { 113 throw new SemanticException("Operand of " + op + 114 " operator must be boolean.", expr.position()); 115 } 116 117 return type(expr.type()); 118 } 119 120 return this; 121 } 122 123 public Type childExpectedType(Expr child, AscriptionVisitor av) { 124 TypeSystem ts = av.typeSystem(); 125 126 try { 127 if (child == expr) { 128 if (op == POST_INC || op == POST_DEC || 129 op == PRE_INC || op == PRE_DEC) { 130 131 if (ts.isImplicitCastValid(child.type(), av.toType())) { 132 return ts.promote(child.type()); 133 } 134 else { 135 return av.toType(); 136 } 137 } 138 else if (op == NEG || op == POS) { 139 if (ts.isImplicitCastValid(child.type(), av.toType())) { 140 return ts.promote(child.type()); 141 } 142 else { 143 return av.toType(); 144 } 145 } 146 else if (op == BIT_NOT) { 147 if (ts.isImplicitCastValid(child.type(), av.toType())) { 148 return ts.promote(child.type()); 149 } 150 else { 151 return av.toType(); 152 } 153 } 154 else if (op == NOT) { 155 return ts.Boolean(); 156 } 157 } 158 } 159 catch (SemanticException e) { 160 } 161 162 return child.type(); 163 } 164 165 166 public String toString() { 167 if (op == NEG && expr instanceof IntLit && ((IntLit) expr).boundary()) { 168 return op.toString() + ((IntLit) expr).positiveToString(); 169 } 170 else if (op.isPrefix()) { 171 return op.toString() + expr.toString(); 172 } 173 else { 174 return expr.toString() + op.toString(); 175 } 176 } 177 178 public void prettyPrint(CodeWriter w, PrettyPrinter tr) { 179 if (op == NEG && expr instanceof IntLit && ((IntLit) expr).boundary()) { 180 w.write(op.toString()); 181 w.write(((IntLit) expr).positiveToString()); 182 } 183 else if (op.isPrefix()) { 184 w.write(op.toString()); 185 printSubExpr(expr, false, w, tr); 186 } 187 else { 188 printSubExpr(expr, false, w, tr); 189 w.write(op.toString()); 190 } 191 } 192 193 public Term entry() { 194 return expr.entry(); 195 } 196 197 public List acceptCFG(CFGBuilder v, List succs) { 198 if (expr.type().isBoolean()) { 199 v.visitCFG(expr, FlowGraph.EDGE_KEY_TRUE, this, 200 FlowGraph.EDGE_KEY_FALSE, this); 201 } 202 else { 203 v.visitCFG(expr, this); 204 } 205 return succs; 206 } 207 208 public boolean isConstant() { 209 return expr.isConstant(); 210 } 211 212 public Object constantValue() { 213 if (! isConstant()) { 214 return null; 215 } 216 217 Object v = expr.constantValue(); 218 219 if (v instanceof Boolean ) { 220 boolean vv = ((Boolean ) v).booleanValue(); 221 if (op == NOT) return Boolean.valueOf(!vv); 222 } 223 if (v instanceof Double ) { 224 double vv = ((Double ) v).doubleValue(); 225 if (op == POS) return new Double (+vv); 226 if (op == NEG) return new Double (-vv); 227 } 228 if (v instanceof Float ) { 229 float vv = ((Float ) v).floatValue(); 230 if (op == POS) return new Float (+vv); 231 if (op == NEG) return new Float (-vv); 232 } 233 if (v instanceof Long ) { 234 long vv = ((Long ) v).longValue(); 235 if (op == BIT_NOT) return new Long (~vv); 236 if (op == POS) return new Long (+vv); 237 if (op == NEG) return new Long (-vv); 238 } 239 if (v instanceof Integer ) { 240 int vv = ((Integer ) v).intValue(); 241 if (op == BIT_NOT) return new Integer (~vv); 242 if (op == POS) return new Integer (+vv); 243 if (op == NEG) return new Integer (-vv); 244 } 245 if (v instanceof Character ) { 246 char vv = ((Character ) v).charValue(); 247 if (op == BIT_NOT) return new Integer (~vv); 248 if (op == POS) return new Integer (+vv); 249 if (op == NEG) return new Integer (-vv); 250 } 251 if (v instanceof Short ) { 252 short vv = ((Short ) v).shortValue(); 253 if (op == BIT_NOT) return new Integer (~vv); 254 if (op == POS) return new Integer (+vv); 255 if (op == NEG) return new Integer (-vv); 256 } 257 if (v instanceof Byte ) { 258 byte vv = ((Byte ) v).byteValue(); 259 if (op == BIT_NOT) return new Integer (~vv); 260 if (op == POS) return new Integer (+vv); 261 if (op == NEG) return new Integer (-vv); 262 } 263 264 return null; 266 } 267 } 268 | Popular Tags |