KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > ext > jl > ast > Assign_c


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 /**
10  * An <code>Assign</code> represents a Java assignment expression.
11  */

12 public abstract class Assign_c extends Expr_c implements Assign
13 {
14   protected Expr left;
15   protected Operator op;
16   protected Expr right;
17
18   public Assign_c(Position pos, Expr left, Operator op, Expr right) {
19     super(pos);
20     this.left = left;
21     this.op = op;
22     this.right = right;
23   }
24
25   /** Get the precedence of the expression. */
26   public Precedence precedence() {
27     return Precedence.ASSIGN;
28   }
29
30   /** Get the left operand of the expression. */
31   public Expr left() {
32     return this.left;
33   }
34
35   /** Set the left operand of the expression. */
36   public Assign left(Expr left) {
37     Assign_c n = (Assign_c) copy();
38     n.left = left;
39     return n;
40   }
41
42   /** Get the operator of the expression. */
43   public Operator operator() {
44     return this.op;
45   }
46
47   /** Set the operator of the expression. */
48   public Assign operator(Operator op) {
49     Assign_c n = (Assign_c) copy();
50     n.op = op;
51     return n;
52   }
53
54   /** Get the right operand of the expression. */
55   public Expr right() {
56     return this.right;
57   }
58
59   /** Set the right operand of the expression. */
60   public Assign right(Expr right) {
61     Assign_c n = (Assign_c) copy();
62     n.right = right;
63     return n;
64   }
65
66   /** Reconstruct the expression. */
67   protected Assign_c reconstruct(Expr left, Expr right) {
68     if (left != this.left || right != this.right) {
69       Assign_c n = (Assign_c) copy();
70       n.left = left;
71       n.right = right;
72       return n;
73     }
74
75     return this;
76   }
77
78   /** Visit the children of the expression. */
79   public Node visitChildren(NodeVisitor v) {
80     Expr left = (Expr) visitChild(this.left, v);
81     Expr right = (Expr) visitChild(this.right, v);
82     return reconstruct(left, right);
83   }
84
85
86   /** Type check the expression. */
87   public Node typeCheck(TypeChecker tc) throws SemanticException {
88     Type t = left.type();
89     Type s = right.type();
90
91     TypeSystem ts = tc.typeSystem();
92
93     if (! (left instanceof Variable)) {
94         throw new SemanticException("Target of assignment must be a variable.",
95                                     position());
96     }
97
98     if (op == ASSIGN) {
99       if (! ts.isImplicitCastValid(s, t) &&
100           ! ts.equals(s, t) &&
101           ! ts.numericConversionValid(t, right.constantValue())) {
102
103         throw new SemanticException("Cannot assign " + s + " to " + t + ".",
104                                     position());
105       }
106
107       return type(t);
108     }
109
110     if (op == ADD_ASSIGN) {
111       // t += s
112
if (ts.equals(t, ts.String()) && ts.canCoerceToString(s, tc.context())) {
113         return type(ts.String());
114       }
115
116       if (t.isNumeric() && s.isNumeric()) {
117         return type(ts.promote(t, s));
118       }
119
120       throw new SemanticException("The " + op + " operator must have "
121                                   + "numeric or String operands.",
122                                   position());
123     }
124
125     if (op == SUB_ASSIGN || op == MUL_ASSIGN ||
126         op == DIV_ASSIGN || op == MOD_ASSIGN) {
127       if (t.isNumeric() && s.isNumeric()) {
128         return type(ts.promote(t, s));
129       }
130
131       throw new SemanticException("The " + op + " operator must have "
132                                   + "numeric operands.",
133                                   position());
134     }
135
136     if (op == BIT_AND_ASSIGN || op == BIT_OR_ASSIGN || op == BIT_XOR_ASSIGN) {
137       if (t.isBoolean() && s.isBoolean()) {
138         return type(ts.Boolean());
139       }
140
141       if (ts.isImplicitCastValid(t, ts.Long()) &&
142           ts.isImplicitCastValid(s, ts.Long())) {
143         return type(ts.promote(t, s));
144       }
145
146       throw new SemanticException("The " + op + " operator must have "
147                                   + "integral or boolean operands.",
148                                   position());
149     }
150
151     if (op == SHL_ASSIGN || op == SHR_ASSIGN || op == USHR_ASSIGN) {
152       if (ts.isImplicitCastValid(t, ts.Long()) &&
153           ts.isImplicitCastValid(s, ts.Long())) {
154         // Only promote the left of a shift.
155
return type(ts.promote(t));
156       }
157
158       throw new SemanticException("The " + op + " operator must have "
159                                   + "integral operands.",
160                                   position());
161     }
162
163     throw new InternalCompilerError("Unrecognized assignment operator " +
164                                     op + ".");
165   }
166   
167   public Type childExpectedType(Expr child, AscriptionVisitor av) {
168       if (child == right) {
169           TypeSystem ts = av.typeSystem();
170
171           // If the RHS is an integral constant, we can relax the expected
172
// type to the type of the constant.
173
if (ts.numericConversionValid(left.type(), child.constantValue())) {
174               return child.type();
175           }
176           else {
177               return left.type();
178           }
179       }
180
181       return child.type();
182   }
183
184   /** Get the throwsArithmeticException of the expression. */
185   public boolean throwsArithmeticException() {
186     // conservatively assume that any division or mod may throw
187
// ArithmeticException this is NOT true-- floats and doubles don't
188
// throw any exceptions ever...
189
return op == DIV_ASSIGN || op == MOD_ASSIGN;
190   }
191
192   public String JavaDoc toString() {
193     return left + " " + op + " " + right;
194   }
195
196   /** Write the expression to an output file. */
197   public void prettyPrint(CodeWriter w, PrettyPrinter tr) {
198     printSubExpr(left, true, w, tr);
199     w.write(" ");
200     w.write(op.toString());
201     w.allowBreak(2, " ");
202     printSubExpr(right, false, w, tr);
203   }
204
205   /** Dumps the AST. */
206   public void dump(CodeWriter w) {
207     super.dump(w);
208     w.allowBreak(4, " ");
209     w.begin(0);
210     w.write("(operator " + op + ")");
211     w.end();
212   }
213
214   abstract public Term entry();
215
216   public List acceptCFG(CFGBuilder v, List succs) {
217       if (operator() == ASSIGN) {
218           acceptCFGAssign(v);
219       }
220       else {
221           acceptCFGOpAssign(v);
222       }
223     return succs;
224   }
225
226   /**
227    * ###@@@DOCO TODO
228    */

229   protected abstract void acceptCFGAssign(CFGBuilder v);
230
231   /**
232    * ###@@@DOCO TODO
233    */

234   protected abstract void acceptCFGOpAssign(CFGBuilder v);
235   
236   public List throwTypes(TypeSystem ts) {
237     List l = new LinkedList();
238
239     if (throwsArithmeticException()) {
240       l.add(ts.ArithmeticException());
241     }
242
243     return l;
244   }
245 }
246
Popular Tags