Source code: openjava/ptree/BinaryExpression.java
1 /*
2 * BinaryExpression.java 1.0
3 *
4 *
5 * Jun 20, 1997 by mich
6 * Sep 29, 1997 by bv
7 * Oct 10, 1997 by mich
8 *
9 * @see openjava.ptree.ParseTree
10 * @version 1.0 last updated: Oct 10, 1997
11 * @author Michiaki Tatsubori
12 */
13 package openjava.ptree;
14
15 import openjava.mop.Environment;
16 import openjava.mop.OJClass;
17 import openjava.mop.OJSystem;
18 import openjava.ptree.util.ParseTreeVisitor;
19
20 /**
21 * The <code>BinaryExpression</code> class represents
22 * an expression which consists of an operators and two operands.
23 * <br>
24 * This doesn't includes the expression whose operator is
25 * the <code>instanceof</code> operator
26 * nor the expression whose operator is one of the
27 * assignment operators.
28 * <br>
29 * If the operator in the expression of the left operand or
30 * the right operand has week unity,
31 * this automatically produces the code in which the left operand
32 * is enclosed by parenthesises.
33 * <br>
34 * In the case the left is <code>a + b</code>,
35 * the operator is <code>*</code>
36 * the right is <code>c + d</code>,
37 * this produces the code :
38 * <br><blockquote><pre>
39 * (a + b) * (c + d)
40 * </pre></blockquote><br>
41 *
42 * @see openjava.ptree.Expression
43 * @see openjava.ptree.InstanceofExpression
44 * @see openjava.ptree.AssignmentExpression
45 */
46 public class BinaryExpression extends NonLeaf implements Expression {
47 public static final int TIMES = 0;
48 public static final int DIVIDE = 1;
49 public static final int MOD = 2;
50 public static final int PLUS = 3;
51 public static final int MINUS = 4;
52 public static final int SHIFT_L = 5;
53 public static final int SHIFT_R = 6;
54 public static final int SHIFT_RR = 7;
55 public static final int LESS = 8;
56 public static final int GREATER = 9;
57 public static final int LESSEQUAL = 10;
58 public static final int GREATEREQUAL = 11;
59 public static final int INSTANCEOF = 12;
60 public static final int EQUAL = 13;
61 public static final int NOTEQUAL = 14;
62 public static final int BITAND = 15;
63 public static final int XOR = 16;
64 public static final int BITOR = 17;
65 public static final int LOGICAL_AND = 18;
66 public static final int LOGICAL_OR = 19;
67
68 static final String[] opr_string =
69 {
70 "*",
71 "/",
72 "%",
73 "+",
74 "-",
75 "<<",
76 ">>",
77 ">>>",
78 "<",
79 ">",
80 "<=",
81 ">=",
82 "instanceof",
83 "==",
84 "!=",
85 "&",
86 "^",
87 "|",
88 "&&",
89 "||" };
90
91 /** the operator */
92 private int opr = -1;
93
94 /**
95 * Allocates a new object.
96 *
97 * @param lexp the expression of the left operand.
98 * @param opr the id number of operator.
99 * @param rexp the expression of the right operand.
100 */
101 public BinaryExpression(Expression lexp, int opr, Expression rexp) {
102 super();
103 set((ParseTree) lexp, (ParseTree) rexp);
104 this.opr = opr;
105 }
106
107 public BinaryExpression(Expression lexp, String opr, Expression rexp) {
108 this(lexp, 0, rexp);
109 for (int i = 0; i < 20; ++i) {
110 if (opr_string[i].equals(opr))
111 this.opr = i;
112 }
113 }
114
115 BinaryExpression() {
116 super();
117 }
118
119 public ParseTree makeRecursiveCopy() {
120 BinaryExpression result = (BinaryExpression) super.makeRecursiveCopy();
121 result.opr = this.opr;
122 return result;
123 }
124
125 public ParseTree makeCopy() {
126 BinaryExpression result = (BinaryExpression) super.makeCopy();
127 result.opr = this.opr;
128 return result;
129 }
130
131 private final boolean needsLeftPar(Expression leftexpr) {
132 if (leftexpr instanceof AssignmentExpression
133 || leftexpr instanceof ConditionalExpression) {
134 return true;
135 }
136
137 int op = strength(getOperator());
138
139 if (leftexpr instanceof InstanceofExpression) {
140 if (op > strength(INSTANCEOF))
141 return true;
142 return false;
143 }
144
145 if (!(leftexpr instanceof BinaryExpression))
146 return false;
147
148 BinaryExpression lbexpr = (BinaryExpression) leftexpr;
149 if (op > strength(lbexpr.getOperator()))
150 return true;
151 return false;
152 }
153
154 private final boolean needsRightPar(Expression rightexpr) {
155 if (rightexpr instanceof AssignmentExpression
156 || rightexpr instanceof ConditionalExpression) {
157 return true;
158 }
159
160 int op = strength(getOperator());
161
162 if (rightexpr instanceof InstanceofExpression) {
163 if (op >= strength(INSTANCEOF))
164 return true;
165 return false;
166 }
167
168 if (!(rightexpr instanceof BinaryExpression))
169 return false;
170
171 BinaryExpression lbexpr = (BinaryExpression) rightexpr;
172 if (op >= strength(lbexpr.getOperator()))
173 return true;
174 return false;
175 }
176
177 /**
178 * Returns the strength of the union of the operator.
179 *
180 * @param op the id number of operator.
181 * @return the strength of the union.
182 */
183 protected static final int strength(int op) {
184 switch (op) {
185 case TIMES :
186 case DIVIDE :
187 case MOD :
188 return 40;
189 case PLUS :
190 case MINUS :
191 return 35;
192 case SHIFT_L :
193 case SHIFT_R :
194 case SHIFT_RR :
195 return 30;
196 case LESS :
197 case GREATER :
198 case LESSEQUAL :
199 case GREATEREQUAL :
200 case INSTANCEOF :
201 return 25;
202 case EQUAL :
203 case NOTEQUAL :
204 return 20;
205 case BITAND :
206 return 16;
207 case XOR :
208 return 14;
209 case BITOR :
210 return 12;
211 case LOGICAL_AND :
212 return 10;
213 case LOGICAL_OR :
214 return 8;
215 }
216 return 100;
217 }
218
219 /**
220 * Gets the expression of the left operand.
221 *
222 * @return the left expression.
223 */
224 public Expression getLeft() {
225 return (Expression) elementAt(0);
226 }
227
228 /**
229 * Sets the expression of the left operand.
230 *
231 * @param lexpr the left expression.
232 */
233 public void setLeft(Expression lexpr) {
234 setElementAt(lexpr, 0);
235 }
236
237 /**
238 * Gets the expression of the right operand.
239 *
240 * @return the right expression.
241 */
242 public Expression getRight() {
243 return (Expression) elementAt(1);
244 }
245
246 /**
247 * Sets the expression of the right operand.
248 *
249 * @param rexpr the right expression.
250 */
251 public void setRight(Expression rexpr) {
252 setElementAt(rexpr, 1);
253 }
254
255 /**
256 * Gets the id number of the operator.
257 *
258 * @return the id number of the operator.
259 * @see openjava.ptree.BinaryExpression#TIMES
260 * @see openjava.ptree.BinaryExpression#DIVIDE
261 * @see openjava.ptree.BinaryExpression#MOD
262 * @see openjava.ptree.BinaryExpression#PLUS
263 * @see openjava.ptree.BinaryExpression#MINUS
264 * @see openjava.ptree.BinaryExpression#SHIFT_L
265 * @see openjava.ptree.BinaryExpression#SHIFT_R
266 * @see openjava.ptree.BinaryExpression#SHIFT_RR
267 * @see openjava.ptree.BinaryExpression#LESS
268 * @see openjava.ptree.BinaryExpression#GREATER
269 * @see openjava.ptree.BinaryExpression#LESSEQUAL
270 * @see openjava.ptree.BinaryExpression#GREATEREQUAL
271 * @see openjava.ptree.BinaryExpression#INSTANCEOF
272 * @see openjava.ptree.BinaryExpression#EQUAL
273 * @see openjava.ptree.BinaryExpression#NOTEQUAL
274 * @see openjava.ptree.BinaryExpression#BITAND
275 * @see openjava.ptree.BinaryExpression#XOR
276 * @see openjava.ptree.BinaryExpression#BITOR
277 * @see openjava.ptree.BinaryExpression#LOGICAL_AND
278 * @see openjava.ptree.BinaryExpression#LOGICAL_OR
279 */
280 public int getOperator() {
281 return this.opr;
282 }
283
284 /**
285 * Sets the id number of the operator.
286 *
287 * @param opr the id number of the operator.
288 * @see openjava.ptree.BinaryExpression#TIMES
289 * @see openjava.ptree.BinaryExpression#DIVIDE
290 * @see openjava.ptree.BinaryExpression#MOD
291 * @see openjava.ptree.BinaryExpression#PLUS
292 * @see openjava.ptree.BinaryExpression#MINUS
293 * @see openjava.ptree.BinaryExpression#SHIFT_L
294 * @see openjava.ptree.BinaryExpression#SHIFT_R
295 * @see openjava.ptree.BinaryExpression#SHIFT_RR
296 * @see openjava.ptree.BinaryExpression#LESS
297 * @see openjava.ptree.BinaryExpression#GREATER
298 * @see openjava.ptree.BinaryExpression#LESSEQUAL
299 * @see openjava.ptree.BinaryExpression#GREATEREQUAL
300 * @see openjava.ptree.BinaryExpression#INSTANCEOF
301 * @see openjava.ptree.BinaryExpression#EQUAL
302 * @see openjava.ptree.BinaryExpression#NOTEQUAL
303 * @see openjava.ptree.BinaryExpression#BITAND
304 * @see openjava.ptree.BinaryExpression#XOR
305 * @see openjava.ptree.BinaryExpression#BITOR
306 * @see openjava.ptree.BinaryExpression#LOGICAL_AND
307 * @see openjava.ptree.BinaryExpression#LOGICAL_OR
308 */
309 public void setOperator(int opr) {
310 this.opr = opr;
311 }
312
313 public String operatorString() {
314 return opr_string[getOperator()];
315 }
316
317 public void accept(ParseTreeVisitor v) throws ParseTreeException {
318 v.visit(this);
319 }
320
321 public OJClass getType(Environment env) throws Exception {
322 switch (this.opr) {
323 case LESS :
324 case GREATER :
325 case LESSEQUAL :
326 case GREATEREQUAL :
327 case EQUAL :
328 case NOTEQUAL :
329 case INSTANCEOF :
330 return OJSystem.BOOLEAN;
331 default :
332 return chooseType(
333 getLeft().getType(env),
334 getRight().getType(env));
335 }
336 }
337
338 static OJClass chooseType(OJClass left, OJClass right) {
339 int leftst = strength(left), rightst = strength(right);
340 if (leftst == OTHER && rightst == OTHER) {
341 if (left.isAssignableFrom(right))
342 return left;
343 if (right.isAssignableFrom(left))
344 return right;
345 return right;
346 }
347 return ((leftst > rightst) ? left : right);
348 }
349
350 private static final int STRING = 30;
351 private static final int OTHER = 4;
352 private static int strength(OJClass type) {
353 if (type == OJSystem.STRING)
354 return STRING;
355 if (type == OJSystem.DOUBLE)
356 return 20;
357 if (type == OJSystem.FLOAT)
358 return 18;
359 if (type == OJSystem.LONG)
360 return 16;
361 if (type == OJSystem.INT)
362 return 14;
363 if (type == OJSystem.CHAR)
364 return 12;
365 if (type == OJSystem.BYTE)
366 return 10;
367 if (type == OJSystem.NULLTYPE)
368 return 0; /*****/
369 return OTHER;
370 }
371
372 }