/* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * COMPONENT_NAME: idl.parser * * ORIGINS: 27 * * Licensed Materials - Property of IBM * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999 * RMI-IIOP v1.0 * */ package com.sun.tools.corba.se.idl.constExpr; // NOTES: import java.math.BigInteger; public abstract class Expression { /** * Compute the value of this expression. **/ public abstract Object evaluate () throws EvaluationException; /** * Set the value of this expression. **/ public void value (Object value) { _value = value; } /** * Get the value of this expression. **/ public Object value () { return _value; } /** * Set the representation of this expression. **/ public void rep (String rep) { _rep = rep; } /** * Get the representation of this expression. **/ public String rep () { return _rep; } /** * Set the target type of this expression. **/ public void type (String type) { _type = type; } /** * Get the target type of this expression. **/ public String type () { return _type; } /** * Return the default computation type for the given target type. **/ protected static String defaultType (String targetType) { return (targetType == null) ? new String ("") : targetType; } // defaultType // BigInteger is a multi-precision number whose representation contains // a signum (sign-number = 1, -1) and a magnitude. To support "long long", // all integer expressions are now performed over BigInteger and stored as // such. During the evaluation of an integer expression, the signum of its // value may toggle, which may cause the value of an expression to conflict // with its target type: [Case 1] If the resulting value is negative // (signum=-1) and the target type is unsigned; or [Case 2] if the resulting // value is positive (signum=1) and greater than 2**(target-type-length - 1), // and the target type is signed, then the resulting value will be out of // range. However, this value is correct and must be coerced to the target // type. E.G., After appying "not" to a BigInteger, the result is // a BigInteger that represents its 2's-complement (~5 => -6 in a byte-space). // In this example, the signum toggles and the magnatude is 6. If the target // type of this value were unsigned short, it must be coerced to a positive // number whose bits truly represent -6 in 2's-complement (250 in a byte-space). // // Also, floating types may now be intialized with any integer expression. // The result must be coerced to Double. // // Use the following routines to coerce this expression's value to its // "target" type. /** * Coerces a number to the target type of this expression. * @param obj The number to coerce. * @return the value of number coerced to the (target) type of * this expression. **/ public Object coerceToTarget (Object obj) { if (obj instanceof BigInteger) { if (type ().indexOf ("unsigned") >= 0) return toUnsignedTarget ((BigInteger)obj); else return toSignedTarget ((BigInteger)obj); } return obj; } // coerceToTarget /** * Coerces an integral value (BigInteger) to its corresponding unsigned * representation, if the target type of this expression is unsigned. * @param b The BigInteger to be coerced. * @return the value of an integral type coerced to its corresponding * unsigned integral type, if the target type of this expression is * unsigned. **/ protected BigInteger toUnsignedTarget (BigInteger b) { if (type ().equals ("unsigned short")) // target type of this expression { if (b != null && b.compareTo (zero) < 0) // error if value < min = -(2**(l-1)). return b.add (twoPow16); } else if (type ().equals ("unsigned long")) { if (b != null && b.compareTo (zero) < 0) return b.add (twoPow32); } else if (type ().equals ("unsigned long long")) { if (b != null && b.compareTo (zero) < 0) return b.add (twoPow64); } return b; } // toUnsignedTarget /** * Coerces an integral value (BigInteger) to its corresponding signed * representation, if the target type of this expression is signed. * @param b The BigInteger to be coerced. * @return the value of an integral type coerced to its corresponding * signed integral type, if the target type of this expression is * signed. **/ protected BigInteger toSignedTarget (BigInteger b) { if (type ().equals ("short")) { if (b != null && b.compareTo (sMax) > 0) return b.subtract (twoPow16); } else if (type ().equals ("long")) { if (b != null && b.compareTo (lMax) > 0) return b.subtract (twoPow32); } else if (type ().equals ("long long")) { if (b != null && b.compareTo (llMax) > 0) return b.subtract (twoPow64); } return b; } // toSignedTarget /** * Return the unsigned value of a BigInteger. **/ protected BigInteger toUnsigned (BigInteger b) { if (b != null && b.signum () == -1) if (type ().equals ("short")) return b.add (twoPow16); else if (type ().equals ("long")) return b.add (twoPow32); else if (type ().equals ("long long")) return b.add (twoPow64); return b; } // Integral-type boundaries. public static final BigInteger negOne = BigInteger.valueOf (-1); public static final BigInteger zero = BigInteger.valueOf (0); public static final BigInteger one = BigInteger.valueOf (1); public static final BigInteger two = BigInteger.valueOf (2); public static final BigInteger twoPow15 = two.pow (15); public static final BigInteger twoPow16 = two.pow (16); public static final BigInteger twoPow31 = two.pow (31); public static final BigInteger twoPow32 = two.pow (32); public static final BigInteger twoPow63 = two.pow (63); public static final BigInteger twoPow64 = two.pow (64); public static final BigInteger sMax = BigInteger.valueOf (Short.MAX_VALUE); public static final BigInteger sMin = BigInteger.valueOf (Short.MAX_VALUE); public static final BigInteger usMax = sMax.multiply (two).add (one); public static final BigInteger usMin = zero; public static final BigInteger lMax = BigInteger.valueOf (Integer.MAX_VALUE); public static final BigInteger lMin = BigInteger.valueOf (Integer.MAX_VALUE); public static final BigInteger ulMax = lMax.multiply (two).add (one); public static final BigInteger ulMin = zero; public static final BigInteger llMax = BigInteger.valueOf (Long.MAX_VALUE); public static final BigInteger llMin = BigInteger.valueOf (Long.MIN_VALUE); public static final BigInteger ullMax = llMax.multiply (two).add (one); public static final BigInteger ullMin = zero; /** * Value of this expression: Boolean, Char, Byte, BigInteger, Double, * String, Expression, ConstEntry. **/ private Object _value = null; /** * String representation of this expression. **/ private String _rep = null; /** * Computation type of this (sub)expression = Target type for now. **/ private String _type = null; } // abstract class Expression