1 /*
   2  * Copyright (c) 1999, 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