Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

TrivialExpression.java

00001 package edu.ksu.cis.bandera.jjjc.optimizer;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 1999, 2000   Robby (robby@cis.ksu.edu)              *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project in the SAnToS Laboratory,         *
00009  * Department of Computing and Information Sciences, Kansas State    *
00010  * University, USA (http://www.cis.ksu.edu/santos).                  *
00011  * It is understood that any modification not identified as such is  *
00012  * not covered by the preceding statement.                           *
00013  *                                                                   *
00014  * This work is free software; you can redistribute it and/or        *
00015  * modify it under the terms of the GNU Library General Public       *
00016  * License as published by the Free Software Foundation; either      *
00017  * version 2 of the License, or (at your option) any later version.  *
00018  *                                                                   *
00019  * This work is distributed in the hope that it will be useful,      *
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00022  * Library General Public License for more details.                  *
00023  *                                                                   *
00024  * You should have received a copy of the GNU Library General Public *
00025  * License along with this toolkit; if not, write to the             *
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00027  * Boston, MA  02111-1307, USA.                                      *
00028  *                                                                   *
00029  * Java is a trademark of Sun Microsystems, Inc.                     *
00030  *                                                                   *
00031  * To submit a bug report, send a comment, or get the latest news on *
00032  * this project and other SAnToS projects, please visit the web-site *
00033  *                http://www.cis.ksu.edu/santos                      *
00034  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00035 import java.io.*;
00036 import java.math.*;
00037 import java.util.*;
00038 
00039 import edu.ksu.cis.bandera.jjjc.node.*;
00040 import edu.ksu.cis.bandera.jjjc.lexer.*;
00041 import edu.ksu.cis.bandera.jjjc.parser.*;
00042 import edu.ksu.cis.bandera.jjjc.analysis.*;
00043 import edu.ksu.cis.bandera.jjjc.unicodepreprocessor.*;
00044 
00045 import ca.mcgill.sable.laleh.java.astfix.*;
00046 import ca.mcgill.sable.soot.jimple.*;
00047 
00048 public final class TrivialExpression extends DepthFirstAdapter {
00049     private static TrivialExpression te = new TrivialExpression();
00050     private static boolean number = false;
00051 /**
00052  * 
00053  */
00054 private TrivialExpression() {
00055 }
00056 /**
00057  * 
00058  * @param node edu.ksu.cis.bandera.jjjc.node.ABinaryExp
00059  */
00060 public void caseABinaryExp(ABinaryExp node) {
00061     PBinaryOperator op = node.getBinaryOperator();
00062     node.getFirst().apply(this);
00063     node.getSecond().apply(this);
00064 
00065     PExp trueValue = new ALiteralExp(new ABooleanLiteralLiteral(new ATrueBooleanLiteral(new TTrue())));
00066     PExp falseValue = new ALiteralExp(new ABooleanLiteralLiteral(new AFalseBooleanLiteral(new TFalse())));
00067     PExp first = getExp(node.getFirst());
00068     PExp second = getExp(node.getSecond());
00069     
00070     if (op instanceof AOrBinaryOperator) {
00071         String firstExp = first.toString().trim();
00072         String secondExp = second.toString().trim();
00073         if ("true".equals(firstExp) || "true".equals(secondExp)) {
00074             node.replaceBy(trueValue);
00075         } else if ("false".equals(firstExp)) {
00076             node.replaceBy(node.getSecond());
00077         } else if ("false".equals(secondExp)) {
00078             node.replaceBy(node.getFirst());
00079         }
00080     } else if (op instanceof AAndBinaryOperator) {
00081         String firstExp = first.toString().trim();
00082         String secondExp = second.toString().trim();
00083         if ("false".equals(firstExp) || "false".equals(secondExp)) {
00084             node.replaceBy(falseValue);
00085         } else if ("true".equals(firstExp)) {
00086             node.replaceBy(node.getSecond());
00087         } else if ("true".equals(secondExp)) {
00088             node.replaceBy(node.getFirst());
00089         }
00090     } else if (((op instanceof AGtBinaryOperator) || (op instanceof ALtBinaryOperator)
00091             || (op instanceof ALteqBinaryOperator) || (op instanceof AGteqBinaryOperator)
00092             || (op instanceof AGteqBinaryOperator)) && (first instanceof ALiteralExp)
00093             && (second instanceof ALiteralExp)) {
00094         try {
00095             if (((Boolean) doNumber(op.toString().trim(), ((ALiteralExp) first).getLiteral(),
00096                     ((ALiteralExp) second).getLiteral())).booleanValue()) {
00097                 node.replaceBy(trueValue);
00098             } else {
00099                 node.replaceBy(falseValue);
00100             }
00101         } catch (Exception e) {}
00102     } else if (((op instanceof AEqBinaryOperator) || (op instanceof ANeqBinaryOperator))
00103             && (first instanceof ALiteralExp)   && (second instanceof ALiteralExp)) {
00104         try {
00105             if (((Boolean) doNumber(op.toString().trim(), ((ALiteralExp) first).getLiteral(),
00106                     ((ALiteralExp) second).getLiteral())).booleanValue()) {
00107                 node.replaceBy(trueValue);
00108             } else {
00109                 node.replaceBy(falseValue);
00110             }
00111         } catch (Exception e) {
00112             if (first.toString().trim().equals(second.toString().trim())) {
00113                 node.replaceBy(trueValue);
00114             } else {
00115                 node.replaceBy(falseValue);
00116             }
00117         }
00118     }   else if (op instanceof APlusBinaryOperator || op instanceof AMinusBinaryOperator || op instanceof AModBinaryOperator || op instanceof ADivBinaryOperator || op instanceof AStarBinaryOperator || op instanceof ABitXorBinaryOperator || op instanceof ABitAndBinaryOperator || op instanceof AShiftLeftBinaryOperator || op instanceof ASignedShiftRightBinaryOperator || op instanceof AUnsignedShiftRightBinaryOperator || op instanceof ABitOrBinaryOperator) {
00119         if (number)
00120             try {
00121                 Object o = doNumber(op.toString().trim(), ((ALiteralExp) first).getLiteral(),
00122                         ((ALiteralExp) second).getLiteral());
00123     
00124                 if (o instanceof Double) {
00125                     String str = "" + ((Double) o).doubleValue();
00126                     node.replaceBy(new ALiteralExp(new AFloatingPointLiteralLiteral(new TFloatingPointLiteral(str))));
00127                 } else if (o instanceof Long) {
00128                     String str = "" + ((Long) o).longValue() + "L";
00129                     node.replaceBy(new ALiteralExp(new AIntegerLiteralLiteral(new ADecimalIntegerLiteral(new TDecimalIntegerLiteral(str)))));
00130                 }
00131             } catch (Exception e) {}
00132     } 
00133 }
00134 /**
00135  * 
00136  * @return java.lang.Object
00137  * @param op java.lang.String
00138  * @param first double
00139  * @param second double
00140  */
00141 private Object doNumber(String op, double first, double second) throws Exception {
00142         if ("==".equals(op)) {
00143         return new Boolean(first == second);
00144     } else if ("!=".equals(op)) {
00145         return new Boolean(first != second);
00146     } else if (">=".equals(op)) {
00147         return new Boolean(first >= second);
00148     } else if ("<=".equals(op)) {
00149         return new Boolean(first <= second);
00150     } else if (">".equals(op)) {
00151         return new Boolean(first > second);
00152     } else if ("<".equals(op)) {
00153         return new Boolean(first < second);
00154     } else if ("+".equals(op)) {
00155         return new Double(first + second);
00156     } else if ("-".equals(op)) {
00157         return new Double(first - second);
00158     } else if ("%".equals(op)) {
00159         return new Double(first % second);
00160     } else if ("/".equals(op)) {
00161         return new Double(first / second);
00162     } else if ("*".equals(op)) {
00163         return new Double(first * second);
00164     } else {
00165         throw new Exception();
00166     }
00167 }
00168 /**
00169  * 
00170  * @return java.lang.Object
00171  * @param op java.lang.String
00172  * @param first double
00173  * @param second long
00174  */
00175 private Object doNumber(String op, double first, long second) throws Exception {
00176     return doNumber(op, first, (double) second);
00177 }
00178 /**
00179  * 
00180  * @return Object
00181  * @param op java.lang.String
00182  * @param first long
00183  * @param second double
00184  */
00185 private Object doNumber(String op, long first, double second) throws Exception {
00186     return doNumber(op, (double) first, second);
00187 }
00188 /**
00189  * 
00190  * @return int
00191  * @param op java.lang.String
00192  * @param first long
00193  * @param second long
00194  */
00195 private Object doNumber(String op, long first, long second) throws Exception {
00196         if ("==".equals(op)) {
00197         return new Boolean(first == second);
00198     } else if ("!=".equals(op)) {
00199         return new Boolean(first != second);
00200     } else if (">=".equals(op)) {
00201         return new Boolean(first >= second);
00202     } else if ("<=".equals(op)) {
00203         return new Boolean(first <= second);
00204     } else if (">".equals(op)) {
00205         return new Boolean(first > second);
00206     } else if ("<".equals(op)) {
00207         return new Boolean(first < second);
00208     } else if ("+".equals(op)) {
00209         return new Long(first + second);
00210     } else if ("-".equals(op)) {
00211         return new Long(first - second);
00212     } else if ("%".equals(op)) {
00213         return new Long(first % second);
00214     } else if ("/".equals(op)) {
00215         return new Long(first / second);
00216     } else if ("*".equals(op)) {
00217         return new Long(first * second);
00218     } else if ("^".equals(op)) {
00219         return new Long(first ^ second);
00220     } else if ("&".equals(op)) {
00221         return new Long(first & second);
00222     } else if ("<<".equals(op)) {
00223         return new Long(first << second);
00224     } else if (">>".equals(op)) {
00225         return new Long(first >> second);
00226     } else {
00227         return new Long(first >>> second);
00228     }
00229 }
00230 /**
00231  * 
00232  * @return java.lang.Object
00233  * @param op java.lang.String
00234  * @param first edu.ksu.cis.bandera.jjjc.node.PLiteral
00235  * @param second edu.ksu.cis.bandera.jjjc.node.PLiteral
00236  */
00237 private Object doNumber(String op, PLiteral first, PLiteral second) throws Exception {
00238     Node node1, node2;
00239 
00240     if (first instanceof AIntegerLiteralLiteral) {
00241         node1 = ((AIntegerLiteralLiteral) first).getIntegerLiteral();
00242     } else {
00243         node1 = ((AFloatingPointLiteralLiteral) first).getFloatingPointLiteral();
00244     }
00245 
00246     if (second instanceof AIntegerLiteralLiteral) {
00247         node2 = ((AIntegerLiteralLiteral) second).getIntegerLiteral();
00248     } else {
00249         node2 = ((AFloatingPointLiteralLiteral) second).getFloatingPointLiteral();
00250     }
00251     
00252     Number number1 = getNumber(node1);
00253     Number number2 = getNumber(node2);
00254 
00255     long longValue1 = 0, longValue2 = 0;
00256     double doubleValue1 = 0.0, doubleValue2 = 0.0;
00257     boolean isDouble1, isDouble2;
00258     
00259     if (number1 instanceof Double) {
00260         isDouble1 = true;
00261         doubleValue1 = number1.doubleValue();
00262     } else {
00263         isDouble1 = false;
00264         longValue1 = number1.longValue();
00265     }
00266     
00267     if (number2 instanceof Double) {
00268         isDouble2 = true;
00269         doubleValue2 = number2.doubleValue();
00270     } else {
00271         isDouble2 = false;
00272         longValue2 = number2.longValue();
00273     }
00274 
00275     if (isDouble1) {
00276         if (isDouble2)
00277             return doNumber(op, doubleValue1, doubleValue2);
00278         else
00279             return doNumber(op, doubleValue1, longValue2);
00280     } else {
00281         if (isDouble2)
00282             return doNumber(op, longValue1, doubleValue2);
00283         else
00284             return doNumber(op, longValue1, longValue2);
00285     }
00286 }
00287 /**
00288  * 
00289  * @return edu.ksu.cis.bandera.jjjc.node.PExp
00290  * @param exp edu.ksu.cis.bandera.jjjc.node.PExp
00291  */
00292 private PExp getExp(PExp exp) {
00293     PExp result = exp;
00294 
00295     while (result instanceof AParExp)
00296         result = ((AParExp) result).getExp();
00297         
00298     return result;
00299 }
00300 /**
00301  * 
00302  * @return java.lang.Number
00303  * @param literal edu.ksu.cis.bandera.jjjc.node.PLiteral
00304  */
00305 private Number getNumber(Node literal) throws Exception {
00306     Number result;
00307     
00308     if (literal instanceof ADecimalIntegerLiteral) {
00309         String lit = literal.toString().trim();
00310         if (lit.endsWith("L") || lit.endsWith("l")) {
00311             result = Long.valueOf(lit.substring(0, lit.length() - 1));
00312         } else {
00313             result = Integer.valueOf(lit);
00314         }
00315     } else if (literal instanceof AOctalIntegerLiteral) {
00316         String lit = literal.toString().substring(1).trim();
00317         if (lit.endsWith("L") || lit.endsWith("l")) {
00318             result = new Long((new BigInteger(lit.substring(0, lit.length() - 1), 8)).longValue());
00319         } else {
00320             result = new Integer(Long.valueOf(lit, 8).intValue());
00321         }
00322     } else if (literal instanceof AHexIntegerLiteral) {
00323         String lit = literal.toString().substring(2).trim();
00324         if (lit.endsWith("L") || lit.endsWith("l")) {
00325             result = new Long((new BigInteger(lit.substring(0, lit.length() - 1), 16)).longValue());
00326         } else {
00327             result = new Integer(Long.valueOf(lit, 16).intValue());
00328         }
00329     } else if (literal instanceof TFloatingPointLiteral) {
00330         String lit = literal.toString().trim();
00331         if (lit.endsWith("F") || lit.endsWith("f")) {
00332             result = Float.valueOf(lit);
00333         } else {
00334             result = Double.valueOf(lit);
00335         }
00336     } else throw new Exception();
00337     
00338     return result;
00339 }
00340 /**
00341  * 
00342  * @param node edu.ksu.cis.bandera.jjjc.node.Node
00343  */
00344 public static void optimize(Node node) {
00345     number = false;
00346     node.apply(te);
00347 }
00348 /**
00349  * 
00350  * @param node edu.ksu.cis.bandera.jjjc.node.Node
00351  * @param doNumberOperation boolean
00352  */
00353 public static void optimize(Node node, boolean doNumberOperation) {
00354     number = doNumberOperation;
00355     node.apply(te);
00356 }
00357 }

Generated at Thu Feb 7 06:58:09 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001