Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

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 }