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