KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > debugger > jpda > expr > Operators


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.debugger.jpda.expr;
21
22 import com.sun.jdi.*;
23
24 /**
25  * Helper class containing methods that evaluate various unary and binary Java operators.
26  *
27  * @author Maros Sandor
28  */

29 class Operators implements JavaParserConstants {
30
31     private VirtualMachine vm;
32
33     public Operators(VirtualMachine vm) {
34
35         this.vm = vm;
36     }
37
38     public PrimitiveValue evaluate(Token operator, PrimitiveValue value) {
39         switch (operator.kind) {
40         case BANG:
41             if (value instanceof BooleanValue) {
42                 return vm.mirrorOf(!value.booleanValue());
43             }
44             break;
45
46         case TILDE:
47             if (value instanceof BooleanValue || value instanceof DoubleValue || value instanceof FloatValue) break;
48             if (value instanceof LongValue) {
49                 return vm.mirrorOf(~value.longValue());
50             } else {
51                 return vm.mirrorOf(~value.intValue());
52             }
53
54         case PLUS:
55             if (value instanceof BooleanValue) break;
56             return value;
57
58         case MINUS:
59             if (value instanceof BooleanValue) break;
60             if (value instanceof DoubleValue) {
61                 return vm.mirrorOf(-value.doubleValue());
62             } else if (value instanceof FloatValue) {
63                 return vm.mirrorOf(-value.floatValue());
64             } else if (value instanceof LongValue) {
65                 return vm.mirrorOf(-value.longValue());
66             } else {
67                 return vm.mirrorOf(-value.intValue());
68             }
69
70         case DECR:
71         case INCR:
72             // NOTE: Values of variables are not changed by this operator !
73
byte val = operator.kind == INCR ? 1 : (byte)-1;
74             if (value instanceof BooleanValue) break;
75             if (value instanceof DoubleValue) {
76                 return vm.mirrorOf(value.doubleValue() + val);
77             } else if (value instanceof FloatValue) {
78                 return vm.mirrorOf(value.floatValue() + val);
79             } else if (value instanceof LongValue) {
80                 return vm.mirrorOf(value.longValue() + val);
81             } else {
82                 return vm.mirrorOf(value.intValue() + val);
83             }
84
85         }
86         throw new IllegalArgumentException JavaDoc("badUnarySemantics");
87     }
88
89     public Value evaluate(Value left, Token operator, Value right) {
90
91         if ((left instanceof BooleanValue) && (right instanceof BooleanValue)) {
92             boolean op1 = ((BooleanValue)left).booleanValue();
93             boolean op2 = ((BooleanValue)right).booleanValue();
94             boolean res = false;
95             switch (operator.kind) {
96                 case EQ: res = op1 == op2; break;
97                 case NE: res = op1 != op2; break;
98                 case BIT_OR: res = op1 | op2; break;
99                 case BIT_AND: res = op1 & op2; break;
100                 case XOR: res = op1 ^ op2; break;
101                 default:
102                     throw new IllegalArgumentException JavaDoc("badBinarySemantics");
103             }
104             return vm.mirrorOf(res);
105         } // (boolean, bin_op, boolean)
106

107         boolean isLeftNumeric = left instanceof PrimitiveValue && !(left instanceof BooleanValue);
108         boolean isRightNumeric = right instanceof PrimitiveValue && !(right instanceof BooleanValue);
109
110         if (isLeftNumeric && isRightNumeric) {
111             switch (operator.kind) {
112                 case PLUS: // +
113
case MINUS: // -
114
case REM: // %
115
case STAR: // *
116
case SLASH: // /
117
return evaluateAddOperator((PrimitiveValue) left, (PrimitiveValue) right, operator.kind);
118
119                 case LSHIFT: // <<
120
case RSIGNEDSHIFT: // >>
121
case RUNSIGNEDSHIFT: // >>>
122
return evaluateShiftOperator((PrimitiveValue) left, (PrimitiveValue) right, operator.kind);
123
124                 case XOR:
125                 case BIT_AND:
126                 case BIT_OR:
127                     return evaluateBitOperator((PrimitiveValue) left, (PrimitiveValue) right, operator.kind);
128
129                 case LT: // <
130
case GT: // >
131
case LE: // <=
132
case GE: // >=
133
case EQ: // ==
134
case NE: // !=
135
return evaluateComparisonOperator((PrimitiveValue) left, (PrimitiveValue) right, operator.kind);
136             }
137         } // (number, bin_op, number)
138

139         if ((operator.kind == EQ) || (operator.kind == NE)) {
140             if (left == null) {
141                 if (right == null)
142                     return vm.mirrorOf(operator.kind == EQ);
143                 if (right instanceof ObjectReference)
144                     return vm.mirrorOf(operator.kind == NE);
145             }
146             if (left instanceof ObjectReference) {
147                 if (right == null)
148                     return vm.mirrorOf(operator.kind == NE);
149                 if (right instanceof ObjectReference)
150                     if (operator.kind == EQ)
151                         return vm.mirrorOf(right.equals(left));
152                     else return vm.mirrorOf( ! right.equals(left));
153             }
154         }
155
156         if ((left == null || left instanceof StringReference || right == null || right instanceof StringReference)
157             && operator.kind == PLUS) {
158             String JavaDoc s1 = null, s2 = null;
159             if (left instanceof StringReference) s1 = ((StringReference)left).value();
160             else if (left == null) s1 = "null";
161             else s1 = left.toString();
162             if (right instanceof StringReference) s2 = ((StringReference)right).value();
163             else if (right == null) s2 = "null";
164             else s2 = right.toString();
165             return vm.mirrorOf(s1 + s2);
166         }
167
168         throw new IllegalArgumentException JavaDoc("Bad semantics for binary operator");
169     }
170
171     private PrimitiveValue evaluateAddOperator(PrimitiveValue op1, PrimitiveValue op2, int id) {
172         if ((op1 instanceof DoubleValue) || (op2 instanceof DoubleValue)) {
173             double d1 = op1.doubleValue ();
174             double d2 = op2.doubleValue ();
175             double res = 0;
176             switch (id) {
177                 case PLUS: res = d1 + d2; break;
178                 case MINUS: res = d1 - d2; break;
179                 case REM: res = d1 % d2; break;
180                 case STAR: res = d1 * d2; break;
181                 case SLASH: res = d1 / d2; break;
182             } // switch (id)
183
return vm.mirrorOf(res);
184         }
185         if ((op1 instanceof FloatValue) || (op2 instanceof FloatValue)) {
186             float f1 = op1.floatValue ();
187             float f2 = op2.floatValue ();
188             float res_f = 0;
189             switch (id) {
190                 case PLUS: res_f = f1 + f2; break;
191                 case MINUS: res_f = f1 - f2; break;
192                 case REM: res_f = f1 % f2; break;
193                 case STAR: res_f = f1 * f2; break;
194                 case SLASH: res_f = f1 / f2; break;
195             } // switch (id)
196
return vm.mirrorOf(res_f);
197         }
198         if ((op1 instanceof LongValue) || (op2 instanceof LongValue)) {
199             long long1 = op1.longValue ();
200             long long2 = op2.longValue ();
201             long res_long = 0;
202             switch (id) {
203                 case PLUS: res_long = long1 + long2; break;
204                 case MINUS: res_long = long1 - long2; break;
205                 case REM: res_long = long1 % long2; break;
206                 case STAR: res_long = long1 * long2; break;
207                 case SLASH: res_long = long1 / long2; break;
208             } // switch (id)
209
return vm.mirrorOf(res_long);
210         }
211         int i1 = op1.intValue ();
212         int i2 = op2.intValue ();
213         int res_i = 0;
214         switch (id) {
215             case PLUS: res_i = i1 + i2; break;
216             case MINUS: res_i = i1 - i2; break;
217             case REM: res_i = i1 % i2; break;
218             case STAR: res_i = i1 * i2; break;
219             case SLASH: res_i = i1 / i2; break;
220         } // switch (id)
221
return vm.mirrorOf(res_i);
222     }
223
224     private PrimitiveValue evaluateShiftOperator(PrimitiveValue op1, PrimitiveValue op2, int id) {
225         if ((op1 instanceof FloatValue) || (op1 instanceof DoubleValue) ||
226             (op2 instanceof FloatValue) || (op2 instanceof DoubleValue)) {
227                 throw new IllegalArgumentException JavaDoc("Bad semantics for shift operator");
228         }
229         if (op1 instanceof LongValue) {
230             long n1 = op1.longValue ();
231             long n2 = op2.longValue ();
232             long res = 0;
233             switch (id) {
234                 case LSHIFT: res = n1 << n2; break;
235                 case RSIGNEDSHIFT: res = n1 >> n2; break;
236                 case RUNSIGNEDSHIFT: res = n1 >>> n2; break;
237             }
238             return vm.mirrorOf(res);
239         } else {
240             int i1 = op1.intValue ();
241             long i2 = op2.longValue ();
242             int res_i = 0;
243             switch (id) {
244                 case LSHIFT: res_i = i1 << i2; break;
245                 case RSIGNEDSHIFT: res_i = i1 >> i2; break;
246                 case RUNSIGNEDSHIFT: res_i = i1 >>> i2; break;
247             }
248             return vm.mirrorOf(res_i);
249         }
250     }
251
252     private PrimitiveValue evaluateBitOperator(PrimitiveValue op1, PrimitiveValue op2, int id) {
253         if ((op1 instanceof FloatValue) || (op1 instanceof DoubleValue) ||
254             (op2 instanceof FloatValue) || (op2 instanceof DoubleValue)) {
255                 throw new IllegalArgumentException JavaDoc("Bad semantics for bit operator");
256         }
257         if ((op1 instanceof LongValue) || (op2 instanceof LongValue)) {
258             long n1 = op1.longValue ();
259             long n2 = op2.longValue ();
260             long res = 0;
261             switch (id) {
262                 case BIT_AND: res = n1 & n2; break;
263                 case BIT_OR: res = n1 | n2; break;
264                 case XOR: res = n1 ^ n2; break;
265             }
266             return vm.mirrorOf(res);
267         } else {
268             int i1 = op1.intValue ();
269             int i2 = op2.intValue ();
270             int res_i = 0;
271             switch (id) {
272                 case BIT_AND: res_i = i1 & i2; break;
273                 case BIT_OR: res_i = i1 | i2; break;
274                 case XOR: res_i = i1 ^ i2; break;
275             }
276             return vm.mirrorOf(res_i);
277         }
278     }
279
280     private BooleanValue evaluateComparisonOperator(PrimitiveValue op1, PrimitiveValue op2, int id) {
281         boolean res = false;
282         if ((op1 instanceof DoubleValue) || (op2 instanceof DoubleValue)) {
283             double d1 = op1.doubleValue ();
284             double d2 = op2.doubleValue ();
285             switch (id) {
286                 case LT: res = d1 < d2; break;
287                 case GT: res = d1 > d2; break;
288                 case LE: res = d1 <= d2; break;
289                 case GE: res = d1 >= d2; break;
290                 case EQ: res = d1 == d2; break;
291                 case NE: res = d1 != d2; break;
292             } // switch (id)
293
} // if
294
else if ((op1 instanceof FloatValue) || (op2 instanceof FloatValue)) {
295             float f1 = op1.floatValue ();
296             float f2 = op2.floatValue ();
297             switch (id) {
298                 case LT: res = f1 < f2; break;
299                 case GT: res = f1 > f2; break;
300                 case LE: res = f1 <= f2; break;
301                 case GE: res = f1 >= f2; break;
302                 case EQ: res = f1 == f2; break;
303                 case NE: res = f1 != f2; break;
304             } // switch (id)
305
} // if
306
else if ((op1 instanceof LongValue) || (op1 instanceof LongValue)) {
307             long n1 = op1.longValue ();
308             long n2 = op2.longValue ();
309             switch (id) {
310                 case LT: res = n1 < n2; break;
311                 case GT: res = n1 > n2; break;
312                 case LE: res = n1 <= n2; break;
313                 case GE: res = n1 >= n2; break;
314                 case EQ: res = n1 == n2; break;
315                 case NE: res = n1 != n2; break;
316             } // switch (id)
317
} // if
318
else
319         {
320         float i1 = op1.intValue ();
321             float i2 = op2.intValue ();
322             switch (id) {
323                 case LT: res = i1 < i2; break;
324                 case GT: res = i1 > i2; break;
325                 case LE: res = i1 <= i2; break;
326                 case GE: res = i1 >= i2; break;
327                 case EQ: res = i1 == i2; break;
328                 case NE: res = i1 != i2; break;
329             } // switch (id)
330
}
331         return vm.mirrorOf(res);
332     }
333 }
334
Popular Tags