001: /*
002: * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025: /*
026: * COMPONENT_NAME: idl.parser
027: *
028: * ORIGINS: 27
029: *
030: * Licensed Materials - Property of IBM
031: * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999
032: * RMI-IIOP v1.0
033: *
034: * @(#)Expression.java 1.20 07/05/05
035: */
036:
037: package com.sun.tools.corba.se.idl.constExpr;
038:
039: // NOTES:
040:
041: import java.math.BigInteger;
042:
043: public abstract class Expression {
044: /**
045: * Compute the value of this expression.
046: **/
047: public abstract Object evaluate() throws EvaluationException;
048:
049: /**
050: * Set the value of this expression.
051: **/
052: public void value(Object value) {
053: _value = value;
054: }
055:
056: /**
057: * Get the value of this expression.
058: **/
059: public Object value() {
060: return _value;
061: }
062:
063: /**
064: * Set the representation of this expression.
065: **/
066: public void rep(String rep) {
067: _rep = rep;
068: }
069:
070: /**
071: * Get the representation of this expression.
072: **/
073: public String rep() {
074: return _rep;
075: }
076:
077: /**
078: * Set the target type of this expression.
079: **/
080: public void type(String type) {
081: _type = type;
082: }
083:
084: /**
085: * Get the target type of this expression.
086: **/
087: public String type() {
088: return _type;
089: }
090:
091: /**
092: * Return the default computation type for the given target type.
093: **/
094: protected static String defaultType(String targetType) {
095: return (targetType == null) ? new String("") : targetType;
096: } // defaultType
097:
098: // BigInteger is a multi-precision number whose representation contains
099: // a signum (sign-number = 1, -1) and a magnitude. To support "long long",
100: // all integer expressions are now performed over BigInteger and stored as
101: // such. During the evaluation of an integer expression, the signum of its
102: // value may toggle, which may cause the value of an expression to conflict
103: // with its target type: [Case 1] If the resulting value is negative
104: // (signum=-1) and the target type is unsigned; or [Case 2] if the resulting
105: // value is positive (signum=1) and greater than 2**(target-type-length - 1),
106: // and the target type is signed, then the resulting value will be out of
107: // range. However, this value is correct and must be coerced to the target
108: // type. E.G., After appying "not" to a BigInteger, the result is
109: // a BigInteger that represents its 2's-complement (~5 => -6 in a byte-space).
110: // In this example, the signum toggles and the magnatude is 6. If the target
111: // type of this value were unsigned short, it must be coerced to a positive
112: // number whose bits truly represent -6 in 2's-complement (250 in a byte-space).
113: //
114: // Also, floating types may now be intialized with any integer expression.
115: // The result must be coerced to Double.
116: //
117: // Use the following routines to coerce this expression's value to its
118: // "target" type.
119:
120: /**
121: * Coerces a number to the target type of this expression.
122: * @parm number The number to coerce.
123: * @return the value of number coerced to the (target) type of
124: * this expression.
125: **/
126: public Object coerceToTarget(Object obj) {
127: if (obj instanceof BigInteger) {
128: if (type().indexOf("unsigned") >= 0)
129: return toUnsignedTarget((BigInteger) obj);
130: else
131: return toSignedTarget((BigInteger) obj);
132: }
133: return obj;
134: } // coerceToTarget
135:
136: /**
137: * Coerces an integral value (BigInteger) to its corresponding unsigned
138: * representation, if the target type of this expression is unsigned.
139: * @parm b The BigInteger to be coerced.
140: * @return the value of an integral type coerced to its corresponding
141: * unsigned integral type, if the target type of this expression is
142: * unsigned.
143: **/
144: protected BigInteger toUnsignedTarget(BigInteger b) {
145: if (type().equals("unsigned short")) // target type of this expression
146: {
147: if (b != null && b.compareTo(zero) < 0) // error if value < min = -(2**(l-1)).
148: return b.add(twoPow16);
149: } else if (type().equals("unsigned long")) {
150: if (b != null && b.compareTo(zero) < 0)
151: return b.add(twoPow32);
152: } else if (type().equals("unsigned long long")) {
153: if (b != null && b.compareTo(zero) < 0)
154: return b.add(twoPow64);
155: }
156: return b;
157: } // toUnsignedTarget
158:
159: /**
160: * Coerces an integral value (BigInteger) to its corresponding signed
161: * representation, if the target type of this expression is signed.
162: * @parm b The BigInteger to be coerced.
163: * @return the value of an integral type coerced to its corresponding
164: * signed integral type, if the target type of this expression is
165: * signed.
166: **/
167: protected BigInteger toSignedTarget(BigInteger b) {
168: if (type().equals("short")) {
169: if (b != null && b.compareTo(sMax) > 0)
170: return b.subtract(twoPow16);
171: } else if (type().equals("long")) {
172: if (b != null && b.compareTo(lMax) > 0)
173: return b.subtract(twoPow32);
174: } else if (type().equals("long long")) {
175: if (b != null && b.compareTo(llMax) > 0)
176: return b.subtract(twoPow64);
177: }
178: return b;
179: } // toSignedTarget
180:
181: /**
182: * Return the unsigned value of a BigInteger.
183: **/
184: protected BigInteger toUnsigned(BigInteger b) {
185: if (b != null && b.signum() == -1)
186: if (type().equals("short"))
187: return b.add(twoPow16);
188: else if (type().equals("long"))
189: return b.add(twoPow32);
190: else if (type().equals("long long"))
191: return b.add(twoPow64);
192: return b;
193: }
194:
195: // Integral-type boundaries.
196:
197: public static final BigInteger negOne = BigInteger.valueOf(-1);
198: public static final BigInteger zero = BigInteger.valueOf(0);
199: public static final BigInteger one = BigInteger.valueOf(1);
200: public static final BigInteger two = BigInteger.valueOf(2);
201:
202: public static final BigInteger twoPow15 = two.pow(15);
203: public static final BigInteger twoPow16 = two.pow(16);
204: public static final BigInteger twoPow31 = two.pow(31);
205: public static final BigInteger twoPow32 = two.pow(32);
206: public static final BigInteger twoPow63 = two.pow(63);
207: public static final BigInteger twoPow64 = two.pow(64);
208:
209: public static final BigInteger sMax = BigInteger
210: .valueOf(Short.MAX_VALUE);
211: public static final BigInteger sMin = BigInteger
212: .valueOf(Short.MAX_VALUE);
213:
214: public static final BigInteger usMax = sMax.multiply(two).add(one);
215: public static final BigInteger usMin = zero;
216:
217: public static final BigInteger lMax = BigInteger
218: .valueOf(Integer.MAX_VALUE);
219: public static final BigInteger lMin = BigInteger
220: .valueOf(Integer.MAX_VALUE);
221:
222: public static final BigInteger ulMax = lMax.multiply(two).add(one);
223: public static final BigInteger ulMin = zero;
224:
225: public static final BigInteger llMax = BigInteger
226: .valueOf(Long.MAX_VALUE);
227: public static final BigInteger llMin = BigInteger
228: .valueOf(Long.MIN_VALUE);
229:
230: public static final BigInteger ullMax = llMax.multiply(two)
231: .add(one);
232: public static final BigInteger ullMin = zero;
233:
234: /**
235: * Value of this expression: Boolean, Char, Byte, BigInteger, Double,
236: * String, Expression, ConstEntry.
237: **/
238: private Object _value = null;
239: /**
240: * String representation of this expression.
241: **/
242: private String _rep = null;
243: /**
244: * Computation type of this (sub)expression = Target type for now.
245: **/
246: private String _type = null;
247: } // abstract class Expression
|