All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gnu.jel.OPbinary Maven / Gradle / Ivy

There is a newer version: 0.8.1
Show newest version
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 
 * $Id: OPbinary.java 490 2006-10-01 16:08:04Z metlov $
 *
 * This file is part of the Java Expressions Library (JEL).
 *   For more information about JEL visit :
 *    http://kinetic.ac.donetsk.ua/JEL/
 *
 * (c) 1998 -- 2007 by Konstantin Metlov([email protected]);
 *
 * JEL is Distributed under the terms of GNU General Public License.
 *    This code comes with ABSOLUTELY NO WARRANTY.
 *  For license details see COPYING file in this directory.
 */

package gnu.jel;

import gnu.jel.debug.Debug;
import java.util.Stack;

/**
 * A tree node, representing binary operation.
 */
public class OPbinary extends OP {

  /** code of this operation */
  public int code;

  /** index into ops array to get code for this op. */
  private int opsIDX; 

  // Names of binary operations by ID in the readable form.
  private final static String[] opNames;

  /** binary promotions of base types */
  protected final static byte[][] promotions;

  // code chunks to implement the ops
  private final static  int[][] ops;
  
  // type of operands promotion by the opcode
  private static final byte[] promotionTypes;

  static {
    promotions=(byte[][])TableKeeper.getTable("promotions");
    ops=(int[][])TableKeeper.getTable("ops");
    promotionTypes=(byte[])TableKeeper.getTable("promotionTypes");
    opNames=(String[])TableKeeper.getTable("binOpNames");
  };

  /**
   * Constructs a new binary operation.
   * 

Codes are following: *

   * 0   --  addition
   * 1   --  substraction
   * 2   --  multiplication
   * 3   --  division
   * 4   --  remainder
   * 5   --  bitwise AND
   * 6   --  bitwise OR
   * 7   --  bitwise and logical XOR
   * 8   --  comparizon for equality
   * 9   --  comparizon for non-equality
   * 10  --  comparizon for "less" <
   * 11  --  comparizon for "greater or equal" >=
   * 12  --  comparizon for "greater" >
   * 13  --  comparizon for "less or equal" <=
   * 14  --  bitwise left shift <<
   * 15  --  bitwise right signed shift >>
   * 16  --  bitwise right unsigned shift >>>
   * 17  --  logical conjunction operator (AND)
   * 18  --  logical disjunction operator (OR)
   * 19  --  array element access operation
   * 20  --  reserved (used internally for string concatenation)
   * 
* @param paramOPs stack holding the operands * @param opcode is the operation code */ public OPbinary(Stack paramOPs, int opcode) throws CompilationException { if (Debug.enabled) Debug.check((opcode>=0) && (opcode=8) || (c2ID>=8)) { // the only way the objects appear in this context // are the comparisons if (Debug.enabled) { Debug.check((code>=8)||(code<=13), "only comparisons and concatenation binops can "+ "operate on objects."); Debug.check(c1ID!=10, "No TSB in this context 1"); Debug.check(c1ID!=10, "No TSB in this context 2"); }; // only string literal comparisons are interpreted if ((c1ID!=11) || (c2ID!=11)) throw new Exception(); // compare the strings int res=CompiledExpression.compare((String)c1w,(String)c2w); c1w=((0x3172A>>>(3*(code-8)))&((res>0)?1:((res<0)?4:2)))>0 ?Boolean.TRUE:Boolean.FALSE; } else { // binary on primitive types // Widen Number n1=widen(c1w,c1ID); Number n2=widen(c2w,c2ID); // Perform boolean boolres=false; boolean resbool=false; if ((opsIDX>=6) && (opsIDX<=7)) { // operations on floating point double d1=n1.doubleValue(),d2=n2.doubleValue(); boolean wrop=false; switch (code) { case 0 : d1=d1+d2; break; //PL case 1 : d1=d1-d2; break; //MI case 2 : d1=d1*d2; break; //MU case 3 : d1=d1/d2; break; //DI case 4 : d1=d1%d2; break; //RE case 5 : wrop=true;break; //AN case 6 : wrop=true;break; //OR case 7 : wrop=true;break; //XO case 8 : boolres=true; resbool=(d1==d2); break; //EQ case 9 : boolres=true; resbool=(d1!=d2); break; //NE case 10: boolres=true; resbool=(d1=d2); break; //GE case 12: boolres=true; resbool=(d1>d2); break; //GT case 13: boolres=true; resbool=(d1<=d2); break; //LE default : wrop=true; }; if (Debug.enabled && wrop) Debug.println("Wrong operation on float ("+code+")."); if (!boolres) n1=new Double(d1); else { // booleans are represented by longs temporarily if (resbool) n1=new Long(1L); else n1=new Long(0); }; } else { // operations on integers long l1=n1.longValue(),l2=n2.longValue(); switch (code) { case 0: l1=l1+l2;break; //PL case 1: l1=l1-l2;break; //MI case 2: l1=l1*l2; break; //MU case 3: l1=l1/l2; break; //DI case 4: l1=l1%l2; break; //RE case 17: case 5: l1=l1&l2; break; //AN case 18: case 6: l1=l1|l2; break; //OR case 7: l1=l1^l2; break; //XO case 8 : boolres=true; l1=(l1==l2?1L:0L); break; //EQ case 9 : boolres=true; l1=(l1!=l2?1L:0L); break; //NE case 10: boolres=true; l1=(l1< l2?1L:0L); break; //LT case 11: boolres=true; l1=(l1>=l2?1L:0L); break; //GE case 12: boolres=true; l1=(l1> l2?1L:0L); break; //GT case 13: boolres=true; l1=(l1<=l2?1L:0L); break; //LE case 14: l1=l1<>l2; break; // RS case 16: { // for this kind of shifts the bit width of variable is // important if (resID==4) //=because there is unary numeric promotion before op l1=(int)l1>>>l2; else l1=l1>>>l2; break; } // RUS default : if (Debug.enabled) Debug.println("Wrong operation on integer ("+code+")."); }; n1=new Long(l1); }; // Narrow if (boolres) { c1w=narrow(n1,0); } else c1w=narrow(n1,resID); }; return c1w; } catch (Exception thr) { // if can't evaluate -- replace operands at least if (!ep1) chi[0]=new OPload(chi[0],c1w); if (!ep2) chi[1]=new OPload(chi[1],c2w); throw thr; // Debug.reportThrowable(thr); // IGNORE } }; };




© 2015 - 2024 Weber Informatics LLC | Privacy Policy