001: /*
002: * Copyright 1994-2003 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: package sun.tools.tree;
027:
028: import sun.tools.java.*;
029: import java.io.PrintStream;
030: import java.util.Hashtable;
031:
032: /**
033: * WARNING: The contents of this source file are not part of any
034: * supported API. Code that depends on them does so at its own risk:
035: * they are subject to change or removal without notice.
036: */
037: public class UnaryExpression extends Expression {
038: Expression right;
039:
040: /**
041: * Constructor
042: */
043: UnaryExpression(int op, long where, Type type, Expression right) {
044: super (op, where, type);
045: this .right = right;
046: }
047:
048: /**
049: * Order the expression based on precedence
050: */
051: public Expression order() {
052: if (precedence() > right.precedence()) {
053: UnaryExpression e = (UnaryExpression) right;
054: right = e.right;
055: e.right = order();
056: return e;
057: }
058: return this ;
059: }
060:
061: /**
062: * Select the type of the expression
063: */
064: void selectType(Environment env, Context ctx, int tm) {
065: throw new CompilerError("selectType: " + opNames[op]);
066: }
067:
068: /**
069: * Check a unary expression
070: */
071: public Vset checkValue(Environment env, Context ctx, Vset vset,
072: Hashtable exp) {
073: vset = right.checkValue(env, ctx, vset, exp);
074:
075: int tm = right.type.getTypeMask();
076: selectType(env, ctx, tm);
077: if (((tm & TM_ERROR) == 0) && type.isType(TC_ERROR)) {
078: env.error(where, "invalid.arg", opNames[op]);
079: }
080: return vset;
081: }
082:
083: /**
084: * Check if constant
085: */
086: public boolean isConstant() {
087: switch (op) {
088: case POS:
089: case NEG:
090: case BITNOT:
091: case NOT:
092: case EXPR:
093: case CONVERT: // generated inside of CastExpression
094: return right.isConstant();
095: }
096: return false;
097: }
098:
099: /**
100: * Evaluate
101: */
102: Expression eval(int a) {
103: return this ;
104: }
105:
106: Expression eval(long a) {
107: return this ;
108: }
109:
110: Expression eval(float a) {
111: return this ;
112: }
113:
114: Expression eval(double a) {
115: return this ;
116: }
117:
118: Expression eval(boolean a) {
119: return this ;
120: }
121:
122: Expression eval(String a) {
123: return this ;
124: }
125:
126: Expression eval() {
127: switch (right.op) {
128: case BYTEVAL:
129: case CHARVAL:
130: case SHORTVAL:
131: case INTVAL:
132: return eval(((IntegerExpression) right).value);
133: case LONGVAL:
134: return eval(((LongExpression) right).value);
135: case FLOATVAL:
136: return eval(((FloatExpression) right).value);
137: case DOUBLEVAL:
138: return eval(((DoubleExpression) right).value);
139: case BOOLEANVAL:
140: return eval(((BooleanExpression) right).value);
141: case STRINGVAL:
142: return eval(((StringExpression) right).value);
143: }
144: return this ;
145: }
146:
147: /**
148: * Inline
149: */
150: public Expression inline(Environment env, Context ctx) {
151: return right.inline(env, ctx);
152: }
153:
154: public Expression inlineValue(Environment env, Context ctx) {
155: right = right.inlineValue(env, ctx);
156: try {
157: return eval().simplify();
158: } catch (ArithmeticException e) {
159: // Got rid of this error message. It isn't illegal to
160: // have a program which does a constant division by
161: // zero. We return `this' to make the compiler to
162: // generate code here.
163: // (bugs 4019304, 4089107).
164: //
165: // I am not positive that this catch is ever reached.
166: //
167: // env.error(where, "arithmetic.exception");
168: return this ;
169: }
170: }
171:
172: /**
173: * Create a copy of the expression for method inlining
174: */
175: public Expression copyInline(Context ctx) {
176: UnaryExpression e = (UnaryExpression) clone();
177: if (right != null) {
178: e.right = right.copyInline(ctx);
179: }
180: return e;
181: }
182:
183: /**
184: * The cost of inlining this expression
185: */
186: public int costInline(int thresh, Environment env, Context ctx) {
187: return 1 + right.costInline(thresh, env, ctx);
188: }
189:
190: /**
191: * Print
192: */
193: public void print(PrintStream out) {
194: out.print("(" + opNames[op] + " ");
195: right.print(out);
196: out.print(")");
197: }
198: }
|