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 17 public class Switch_c extends Stmt_c implements Switch 18 { 19 protected Expr expr; 20 protected List elements; 21 22 public Switch_c(Position pos, Expr expr, List elements) { 23 super(pos); 24 this.expr = expr; 25 this.elements = TypedList.copyAndCheck(elements, SwitchElement.class, true); 26 } 27 28 29 public Expr expr() { 30 return this.expr; 31 } 32 33 34 public Switch expr(Expr expr) { 35 Switch_c n = (Switch_c) copy(); 36 n.expr = expr; 37 return n; 38 } 39 40 41 public List elements() { 42 return Collections.unmodifiableList(this.elements); 43 } 44 45 46 public Switch elements(List elements) { 47 Switch_c n = (Switch_c) copy(); 48 n.elements = TypedList.copyAndCheck(elements, SwitchElement.class, true); 49 return n; 50 } 51 52 53 protected Switch_c reconstruct(Expr expr, List elements) { 54 if (expr != this.expr || ! CollectionUtil.equals(elements, this.elements)) { 55 Switch_c n = (Switch_c) copy(); 56 n.expr = expr; 57 n.elements = TypedList.copyAndCheck(elements, SwitchElement.class, true); 58 return n; 59 } 60 61 return this; 62 } 63 64 public Context enterScope(Context c) { 65 return c.pushBlock(); 66 } 67 68 69 public Node visitChildren(NodeVisitor v) { 70 Expr expr = (Expr) visitChild(this.expr, v); 71 List elements = visitList(this.elements, v); 72 return reconstruct(expr, elements); 73 } 74 75 76 public Node typeCheck(TypeChecker tc) throws SemanticException { 77 TypeSystem ts = tc.typeSystem(); 78 79 if (! ts.isImplicitCastValid(expr.type(), ts.Int())) { 80 throw new SemanticException("Switch index must be an integer.", 81 position()); 82 } 83 84 Collection labels = new HashSet(); 85 86 for (Iterator i = elements.iterator(); i.hasNext();) { 87 SwitchElement s = (SwitchElement) i.next(); 88 89 if (s instanceof Case) { 90 Case c = (Case) s; 91 Object key; 92 String str; 93 94 if (c.isDefault()) { 95 key = "default"; 96 str = "default"; 97 } 98 else if (c.expr().isConstant()) { 99 key = new Long (c.value()); 100 str = c.expr().toString() + " (" + c.value() + ")"; 101 } 102 else { 103 continue; 104 } 105 106 if (labels.contains(key)) { 107 throw new SemanticException("Duplicate case label: " + 108 str + ".", c.position()); 109 } 110 111 labels.add(key); 112 } 113 } 114 115 return this; 116 } 117 118 public Type childExpectedType(Expr child, AscriptionVisitor av) { 119 TypeSystem ts = av.typeSystem(); 120 121 if (child == expr) { 122 return ts.Int(); 123 } 124 125 return child.type(); 126 } 127 128 public String toString() { 129 return "switch (" + expr + ") { ... }"; 130 } 131 132 133 public void prettyPrint(CodeWriter w, PrettyPrinter tr) { 134 w.write("switch ("); 135 printBlock(expr, w, tr); 136 w.write(") {"); 137 w.allowBreak(4, " "); 138 w.begin(0); 139 140 boolean lastWasCase = false; 141 boolean first = true; 142 143 for (Iterator i = elements.iterator(); i.hasNext();) { 144 SwitchElement s = (SwitchElement) i.next(); 145 if (s instanceof Case) { 146 if (lastWasCase) w.newline(0); 147 else if (! first) w.allowBreak(0, " "); 148 printBlock(s, w, tr); 149 lastWasCase = true; 150 } 151 else { 152 w.allowBreak(4," "); 153 print(s, w, tr); 154 lastWasCase = false; 155 } 156 157 first = false; 158 } 159 160 w.end(); 161 w.allowBreak(0, " "); 162 w.write("}"); 163 } 164 165 public Term entry() { 166 return expr.entry(); 167 } 168 169 public List acceptCFG(CFGBuilder v, List succs) { 170 SwitchElement prev = null; 171 172 List cases = new LinkedList(); 173 boolean hasDefault = false; 174 175 for (Iterator i = elements.iterator(); i.hasNext(); ) { 176 SwitchElement s = (SwitchElement) i.next(); 177 178 if (s instanceof Case) { 179 cases.add(s.entry()); 180 if (((Case) s).expr() == null) { 181 hasDefault = true; 182 } 183 } 184 } 185 186 if (! hasDefault) { 188 cases.add(this); 189 } 190 191 v.visitCFG(expr, FlowGraph.EDGE_KEY_OTHER, cases); 192 v.push(this).visitCFGList(elements, this); 193 194 return succs; 195 } 196 } 197 | Popular Tags |