View Javadoc
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  
36  package com.sun.tools.corba.se.idl.constExpr;
37  
38  // NOTES:
39  
40  import java.math.BigInteger;
41  
42  public 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