Expression.java revision 608:7e06bf1dcb09
1/*
2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25/*
26 * COMPONENT_NAME: idl.parser
27 *
28 * ORIGINS: 27
29 *
30 * Licensed Materials - Property of IBM
31 * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999
32 * RMI-IIOP v1.0
33 *
34 */
35
36package com.sun.tools.corba.se.idl.constExpr;
37
38// NOTES:
39
40import java.math.BigInteger;
41
42public abstract class Expression
43{
44  /**
45   * Compute the value of this expression.
46   **/
47  public abstract Object evaluate () throws EvaluationException;
48
49  /**
50   * Set the value of this expression.
51   **/
52  public void value (Object value)
53  {
54    _value = value;
55  }
56  /**
57   * Get the value of this expression.
58   **/
59  public Object value ()
60  {
61    return _value;
62  }
63
64  /**
65   * Set the representation of this expression.
66   **/
67  public void rep (String rep)
68  {
69    _rep = rep;
70  }
71  /**
72   * Get the representation of this expression.
73   **/
74  public String rep ()
75  {
76    return _rep;
77  }
78
79  /**
80   * Set the target type of this expression.
81   **/
82  public void type (String type)
83  {
84    _type = type;
85  }
86  /**
87   * Get the target type of this expression.
88   **/
89  public String type ()
90  {
91    return _type;
92  }
93
94  /**
95   * Return the default computation type for the given target type.
96   **/
97  protected static String defaultType (String targetType)
98  {
99    return (targetType == null) ? new String ("") : targetType;
100  } // defaultType
101
102  // BigInteger is a multi-precision number whose representation contains
103  // a signum (sign-number = 1, -1) and a magnitude.  To support "long long",
104  // all integer expressions are now performed over BigInteger and stored as
105  // such.  During the evaluation of an integer expression, the signum of its
106  // value may toggle, which may cause the value of an expression to conflict
107  // with its target type: [Case 1] If the resulting value is negative
108  // (signum=-1) and the target type is unsigned; or [Case 2] if the resulting
109  // value is positive (signum=1) and greater than 2**(target-type-length - 1),
110  // and the target type is signed, then the resulting value will be out of
111  // range.  However, this value is correct and must be coerced to the target
112  // type.  E.G., After appying "not" to a BigInteger, the result is
113  // a BigInteger that represents its 2's-complement (~5 => -6 in a byte-space).
114  // In this example, the signum toggles and the magnatude is 6.  If the target
115  // type of this value were unsigned short, it must be coerced to a positive
116  // number whose bits truly represent -6 in 2's-complement (250 in a byte-space).
117  //
118  // Also, floating types may now be intialized with any integer expression.
119  // The result must be coerced to Double.
120  //
121  // Use the following routines to coerce this expression's value to its
122  // "target" type.
123
124  /**
125   * Coerces a number to the target type of this expression.
126   * @param  obj  The number to coerce.
127   * @return  the value of number coerced to the (target) type of
128   *  this expression.
129   **/
130  public Object coerceToTarget (Object obj)
131  {
132    if (obj instanceof BigInteger)
133    {
134      if (type ().indexOf ("unsigned") >= 0)
135        return toUnsignedTarget ((BigInteger)obj);
136      else
137        return toSignedTarget ((BigInteger)obj);
138    }
139    return obj;
140  } // coerceToTarget
141
142  /**
143   * Coerces an integral value (BigInteger) to its corresponding unsigned
144   * representation, if the target type of this expression is unsigned.
145   * @param b The BigInteger to be coerced.
146   * @return the value of an integral type coerced to its corresponding
147   *  unsigned integral type, if the target type of this expression is
148   *  unsigned.
149   **/
150  protected BigInteger toUnsignedTarget (BigInteger b)
151  {
152    if (type ().equals ("unsigned short")) // target type of this expression
153    {
154      if (b != null && b.compareTo (zero) < 0) // error if value < min = -(2**(l-1)).
155        return b.add (twoPow16);
156    }
157    else if (type ().equals ("unsigned long"))
158    {
159      if (b != null && b.compareTo (zero) < 0)
160        return b.add (twoPow32);
161    }
162    else if (type ().equals ("unsigned long long"))
163    {
164      if (b != null && b.compareTo (zero) < 0)
165        return b.add (twoPow64);
166    }
167    return b;
168  } // toUnsignedTarget
169
170  /**
171   * Coerces an integral value (BigInteger) to its corresponding signed
172   * representation, if the target type of this expression is signed.
173   * @param  b  The BigInteger to be coerced.
174   * @return  the value of an integral type coerced to its corresponding
175   *  signed integral type, if the target type of this expression is
176   *  signed.
177   **/
178  protected BigInteger toSignedTarget (BigInteger b)
179  {
180    if (type ().equals ("short"))
181    {
182      if (b != null && b.compareTo (sMax) > 0)
183        return b.subtract (twoPow16);
184    }
185    else if (type ().equals ("long"))
186    {
187      if (b != null && b.compareTo (lMax) > 0)
188        return b.subtract (twoPow32);
189    }
190    else if (type ().equals ("long long"))
191    {
192      if (b != null && b.compareTo (llMax) > 0)
193        return b.subtract (twoPow64);
194    }
195    return b;
196  } // toSignedTarget
197
198  /**
199   * Return the unsigned value of a BigInteger.
200   **/
201  protected BigInteger toUnsigned (BigInteger b)
202  {
203    if (b != null && b.signum () == -1)
204      if (type ().equals ("short"))
205        return b.add (twoPow16);
206      else if (type ().equals ("long"))
207        return b.add (twoPow32);
208      else if (type ().equals ("long long"))
209        return b.add (twoPow64);
210    return b;
211  }
212
213  // Integral-type boundaries.
214
215  public static final BigInteger negOne = BigInteger.valueOf (-1);
216  public static final BigInteger zero   = BigInteger.valueOf (0);
217  public static final BigInteger one    = BigInteger.valueOf (1);
218  public static final BigInteger two    = BigInteger.valueOf (2);
219
220  public static final BigInteger twoPow15 = two.pow (15);
221  public static final BigInteger twoPow16 = two.pow (16);
222  public static final BigInteger twoPow31 = two.pow (31);
223  public static final BigInteger twoPow32 = two.pow (32);
224  public static final BigInteger twoPow63 = two.pow (63);
225  public static final BigInteger twoPow64 = two.pow (64);
226
227  public static final BigInteger sMax = BigInteger.valueOf (Short.MAX_VALUE);
228  public static final BigInteger sMin = BigInteger.valueOf (Short.MAX_VALUE);
229
230  public static final BigInteger usMax = sMax.multiply (two).add (one);
231  public static final BigInteger usMin = zero;
232
233  public static final BigInteger lMax = BigInteger.valueOf (Integer.MAX_VALUE);
234  public static final BigInteger lMin = BigInteger.valueOf (Integer.MAX_VALUE);
235
236  public static final BigInteger ulMax = lMax.multiply (two).add (one);
237  public static final BigInteger ulMin = zero;
238
239  public static final BigInteger llMax = BigInteger.valueOf (Long.MAX_VALUE);
240  public static final BigInteger llMin = BigInteger.valueOf (Long.MIN_VALUE);
241
242  public static final BigInteger ullMax = llMax.multiply (two).add (one);
243  public static final BigInteger ullMin = zero;
244
245  /**
246   * Value of this expression: Boolean, Char, Byte, BigInteger, Double,
247   * String, Expression, ConstEntry.
248   **/
249  private Object _value = null;
250  /**
251   * String representation of this expression.
252   **/
253  private String _rep   = null;
254  /**
255   * Computation type of this (sub)expression = Target type for now.
256   **/
257  private String _type  = null;
258} // abstract class Expression
259