1 package polyglot.ext.jl.ast; 2 3 import polyglot.ast.*; 4 5 import polyglot.types.*; 6 import polyglot.visit.*; 7 import polyglot.util.*; 8 import java.util.*; 9 10 14 public class LocalDecl_c extends Stmt_c implements LocalDecl { 15 Flags flags; 16 TypeNode type; 17 String name; 18 Expr init; 19 LocalInstance li; 20 21 public LocalDecl_c(Position pos, Flags flags, TypeNode type, 22 String name, Expr init) 23 { 24 super(pos); 25 this.flags = flags; 26 this.type = type; 27 this.name = name; 28 this.init = init; 29 } 30 31 32 public Type declType() { 33 return type.type(); 34 } 35 36 37 public Flags flags() { 38 return flags; 39 } 40 41 42 public LocalDecl flags(Flags flags) { 43 LocalDecl_c n = (LocalDecl_c) copy(); 44 n.flags = flags; 45 return n; 46 } 47 48 49 public TypeNode type() { 50 return type; 51 } 52 53 54 public LocalDecl type(TypeNode type) { 55 if (type == this.type) return this; 56 LocalDecl_c n = (LocalDecl_c) copy(); 57 n.type = type; 58 return n; 59 } 60 61 62 public String name() { 63 return name; 64 } 65 66 67 public LocalDecl name(String name) { 68 if (name.equals(this.name)) return this; 69 LocalDecl_c n = (LocalDecl_c) copy(); 70 n.name = name; 71 return n; 72 } 73 74 75 public Expr init() { 76 return init; 77 } 78 79 80 public LocalDecl init(Expr init) { 81 if (init == this.init) return this; 82 LocalDecl_c n = (LocalDecl_c) copy(); 83 n.init = init; 84 return n; 85 } 86 87 88 public LocalDecl localInstance(LocalInstance li) { 89 if (li == this.li) return this; 90 LocalDecl_c n = (LocalDecl_c) copy(); 91 n.li = li; 92 return n; 93 } 94 95 96 public LocalInstance localInstance() { 97 return li; 98 } 99 100 101 protected LocalDecl_c reconstruct(TypeNode type, Expr init) { 102 if (this.type != type || this.init != init) { 103 LocalDecl_c n = (LocalDecl_c) copy(); 104 n.type = type; 105 n.init = init; 106 return n; 107 } 108 109 return this; 110 } 111 112 113 public Node visitChildren(NodeVisitor v) { 114 TypeNode type = (TypeNode) visitChild(this.type, v); 115 Expr init = (Expr) visitChild(this.init, v); 116 return reconstruct(type, init); 117 } 118 119 123 public Context enterScope(Node child, Context c) { 124 if (child == init) { 125 c.addVariable(li); 126 } 127 return super.enterScope(child, c); 128 } 129 130 public void addDecls(Context c) { 131 c.addVariable(li); 134 } 135 136 public Node buildTypes(TypeBuilder tb) throws SemanticException { 137 LocalDecl_c n = (LocalDecl_c) super.buildTypes(tb); 138 139 TypeSystem ts = tb.typeSystem(); 140 141 LocalInstance li = ts.localInstance(position(), Flags.NONE, 142 ts.unknownType(position()), name()); 143 return n.localInstance(li); 144 } 145 146 public Node disambiguate(AmbiguityRemover ar) throws SemanticException { 147 TypeSystem ts = ar.typeSystem(); 148 149 LocalInstance li = ts.localInstance(position(), 150 flags(), declType(), name()); 151 152 return localInstance(li); 153 } 154 155 159 public NodeVisitor typeCheckEnter(TypeChecker tc) throws SemanticException { 160 Context c = tc.context(); 165 166 LocalInstance outerLocal = null; 167 168 try { 169 outerLocal = c.findLocal(li.name()); 170 } 171 catch (SemanticException e) { 172 } 174 175 if (outerLocal != null && c.isLocal(li.name())) { 176 throw new SemanticException( 177 "Local variable \"" + name + "\" multiply defined. " 178 + "Previous definition at " + outerLocal.position() + ".", 179 position()); 180 } 181 182 return super.typeCheckEnter(tc); 183 184 } 185 186 187 public Node typeCheck(TypeChecker tc) throws SemanticException { 188 TypeSystem ts = tc.typeSystem(); 189 190 LocalInstance li = this.li; 191 192 if (li.flags().isFinal() && init() != null && init().isConstant()) { 193 Object value = init().constantValue(); 194 li = (LocalInstance) li.constantValue(value); 195 } 196 197 try { 198 ts.checkLocalFlags(flags); 199 } 200 catch (SemanticException e) { 201 throw new SemanticException(e.getMessage(), position()); 202 } 203 204 if (init != null) { 205 if (init instanceof ArrayInit) { 206 ((ArrayInit) init).typeCheckElements(type.type()); 207 } 208 else { 209 if (! ts.isImplicitCastValid(init.type(), type.type()) && 210 ! ts.equals(init.type(), type.type()) && 211 ! ts.numericConversionValid(type.type(), 212 init.constantValue())) { 213 throw new SemanticException("The type of the variable " + 214 "initializer \"" + init.type() + 215 "\" does not match that of " + 216 "the declaration \"" + 217 type.type() + "\".", 218 init.position()); 219 } 220 } 221 } 222 223 return localInstance(li); 224 } 225 226 public Type childExpectedType(Expr child, AscriptionVisitor av) { 227 if (child == init) { 228 TypeSystem ts = av.typeSystem(); 229 230 if (ts.numericConversionValid(type.type(), child.constantValue())) { 233 return child.type(); 234 } 235 else { 236 return type.type(); 237 } 238 } 239 240 return child.type(); 241 } 242 243 public String toString() { 244 return flags.translate() + type + " " + name + 245 (init != null ? " = " + init : "") + ";"; 246 } 247 248 public void prettyPrint(CodeWriter w, PrettyPrinter tr) { 249 boolean printSemi = tr.appendSemicolon(true); 250 boolean printType = tr.printType(true); 251 252 w.write(flags.translate()); 253 if (printType) { 254 print(type, w, tr); 255 w.write(" "); 256 } 257 w.write(name); 258 259 if (init != null) { 260 w.write(" ="); 261 w.allowBreak(2, " "); 262 print(init, w, tr); 263 } 264 265 if (printSemi) { 266 w.write(";"); 267 } 268 269 tr.printType(printType); 270 tr.appendSemicolon(printSemi); 271 } 272 273 public void dump(CodeWriter w) { 274 super.dump(w); 275 276 if (li != null) { 277 w.allowBreak(4, " "); 278 w.begin(0); 279 w.write("(instance " + li + ")"); 280 w.end(); 281 } 282 283 w.allowBreak(4, " "); 284 w.begin(0); 285 w.write("(name " + name + ")"); 286 w.end(); 287 } 288 289 public Term entry() { 290 if (init() != null) { 291 return init().entry(); 292 } 293 return this; 294 } 295 296 public List acceptCFG(CFGBuilder v, List succs) { 297 if (init() != null) { 298 v.visitCFG(init(), this); 299 } 300 301 return succs; 302 } 303 } 304 | Popular Tags |