1 package polyglot.ext.jl.ast; 2 3 import polyglot.ast.*; 4 import polyglot.types.*; 5 import polyglot.util.*; 6 import polyglot.visit.*; 7 import java.util.*; 8 9 15 public class ArrayInit_c extends Expr_c implements ArrayInit 16 { 17 protected List elements; 18 19 public ArrayInit_c(Position pos, List elements) { 20 super(pos); 21 this.elements = TypedList.copyAndCheck(elements, Expr.class, true); 22 } 23 24 25 public List elements() { 26 return this.elements; 27 } 28 29 30 public ArrayInit elements(List elements) { 31 ArrayInit_c n = (ArrayInit_c) copy(); 32 n.elements = TypedList.copyAndCheck(elements, Expr.class, true); 33 return n; 34 } 35 36 37 protected ArrayInit_c reconstruct(List elements) { 38 if (! CollectionUtil.equals(elements, this.elements)) { 39 ArrayInit_c n = (ArrayInit_c) copy(); 40 n.elements = TypedList.copyAndCheck(elements, Expr.class, true); 41 return n; 42 } 43 44 return this; 45 } 46 47 48 public Node visitChildren(NodeVisitor v) { 49 List elements = visitList(this.elements, v); 50 return reconstruct(elements); 51 } 52 53 54 public Node typeCheck(TypeChecker tc) throws SemanticException { 55 TypeSystem ts = tc.typeSystem(); 56 57 Type type = null; 58 59 for (Iterator i = elements.iterator(); i.hasNext(); ) { 60 Expr e = (Expr) i.next(); 61 62 if (type == null) { 63 type = e.type(); 64 } 65 else { 66 type = ts.leastCommonAncestor(type, e.type()); 67 } 68 } 69 70 if (type == null) { 71 return type(ts.Null()); 72 } 73 else { 74 return type(ts.arrayOf(type)); 75 } 76 } 77 78 public Type childExpectedType(Expr child, AscriptionVisitor av) { 79 if (elements.isEmpty()) { 80 return child.type(); 81 } 82 83 Type t = av.toType(); 84 85 if (! t.isArray()) { 86 throw new InternalCompilerError("Type of array initializer must " + 87 "be an array.", position()); 88 } 89 90 t = t.toArray().base(); 91 92 TypeSystem ts = av.typeSystem(); 93 94 for (Iterator i = elements.iterator(); i.hasNext(); ) { 95 Expr e = (Expr) i.next(); 96 97 if (e == child) { 98 if (ts.numericConversionValid(t, e.constantValue())) { 99 return child.type(); 100 } 101 else { 102 return t; 103 } 104 } 105 } 106 107 return child.type(); 108 } 109 110 public void typeCheckElements(Type lhsType) throws SemanticException { 111 TypeSystem ts = lhsType.typeSystem(); 112 113 if (! lhsType.isArray()) { 114 throw new SemanticException("Cannot initialize " + lhsType + 115 " with " + type + ".", position()); 116 } 117 118 Type t = lhsType.toArray().base(); 120 121 for (Iterator i = elements.iterator(); i.hasNext(); ) { 122 Expr e = (Expr) i.next(); 123 Type s = e.type(); 124 125 if (e instanceof ArrayInit) { 126 ((ArrayInit) e).typeCheckElements(t); 127 continue; 128 } 129 130 if (! ts.isImplicitCastValid(s, t) && 131 ! ts.equals(s, t) && 132 ! ts.numericConversionValid(t, e.constantValue())) { 133 throw new SemanticException("Cannot assign " + s + 134 " to " + t + ".", e.position()); 135 } 136 } 137 } 138 139 public String toString() { 140 return "{ ... }"; 141 } 142 143 144 public void prettyPrint(CodeWriter w, PrettyPrinter tr) { 145 w.write("{ "); 146 147 for (Iterator i = elements.iterator(); i.hasNext(); ) { 148 Expr e = (Expr) i.next(); 149 print(e, w, tr); 150 151 if (i.hasNext()) { 152 w.write(", "); 153 } 154 } 155 156 w.write(" }"); 157 } 158 159 public Term entry() { 160 return listEntry(elements, this); 161 } 162 163 public List acceptCFG(CFGBuilder v, List succs) { 164 v.visitCFGList(elements, this); 165 return succs; 166 } 167 } 168 | Popular Tags |