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

org.snapscript.tree.math.NumericOperator Maven / Gradle / Ivy

package org.snapscript.tree.math;

import static org.snapscript.tree.math.ValueCalculator.BYTE;
import static org.snapscript.tree.math.ValueCalculator.DOUBLE;
import static org.snapscript.tree.math.ValueCalculator.FLOAT;
import static org.snapscript.tree.math.ValueCalculator.INTEGER;
import static org.snapscript.tree.math.ValueCalculator.LONG;
import static org.snapscript.tree.math.ValueCalculator.SHORT;

import org.snapscript.core.variable.Value;
import org.snapscript.parse.StringToken;

public enum NumericOperator {
   REPLACE("", 0) {
      @Override
      public Value operate(Value left, Value right) {
         return right;
      }
      @Override
      public Value operate(Value left, Value right, ValueCalculator calculator) {
         return calculator.replace(left, right);
      }        
   },
   COALESCE("??", 1){
      @Override
      public Value operate(Value left, Value right, ValueCalculator calculator) {
         return calculator.coalesce(left, right);
      }      
   },   
   POWER("**", 2){
      @Override
      public Value operate(Value left, Value right, ValueCalculator calculator) {
         return calculator.power(left, right);
      }      
   },   
   DIVIDE("/", 3){
      @Override
      public Value operate(Value left, Value right, ValueCalculator calculator) {
         return calculator.divide(left, right);
      }      
   },
   MULTIPLY("*", 3){
      @Override
      public Value operate(Value left, Value right, ValueCalculator calculator) {
         return calculator.multiply(left, right);
      }      
   }, 
   MODULUS("%", 3){
      @Override
      public Value operate(Value left, Value right, ValueCalculator calculator) {
         return calculator.modulus(left, right);
      }      
   },   
   PLUS("+", 4){
      @Override
      public Value operate(Value left, Value right, ValueCalculator calculator) {
         return calculator.add(left, right);
      }      
   }, 
   MINUS("-", 4){
      @Override
      public Value operate(Value left, Value right, ValueCalculator calculator) {
         return calculator.subtract(left, right);
      }      
   },
   SHIFT_RIGHT(">>", 5){
      @Override
      public Value operate(Value left, Value right, ValueCalculator calculator) {
         return calculator.shiftRight(left, right);
      }      
   }, 
   SHIFT_LEFT("<<", 5){
      @Override
      public Value operate(Value left, Value right, ValueCalculator calculator) {
         return calculator.shiftLeft(left, right);
      }      
   },  
   UNSIGNED_SHIFT_RIGHT(">>>", 5){
      @Override
      public Value operate(Value left, Value right, ValueCalculator calculator) {
         return calculator.unsignedShiftRight(left, right);
      }      
   },
   AND("&", 6){
      @Override
      public Value operate(Value left, Value right, ValueCalculator calculator) {
         return calculator.and(left, right);
      }      
   },  
   OR("|", 6){
      @Override
      public Value operate(Value left, Value right, ValueCalculator calculator) {
         return calculator.or(left, right);
      }      
   }, 
   XOR("^", 6){
      @Override
      public Value operate(Value left, Value right, ValueCalculator calculator) {
         return calculator.xor(left, right); 
      }      
   };
   
   public final String operator;
   public final int priority;
   
   private NumericOperator(String operator, int priority) {
      this.priority = -priority; // invert value to sort
      this.operator = operator;
   }   
   
   public Value operate(Value left, Value right) {
      Class primary = left.getType();
      Class secondary = right.getType();
      
      if(Double.class == primary || Double.class == secondary) {
         return operate(left, right, DOUBLE);
      }
      if(Long.class == primary || Long.class == secondary) {
         return operate(left, right, LONG);
      }
      if(Float.class == primary || Float.class == secondary) {
         return operate(left, right, FLOAT);
      }
      if(Integer.class == primary || Integer.class == secondary) {
         return operate(left, right, INTEGER);
      }
      if(Short.class == primary || Short.class == secondary) {
         return operate(left, right, SHORT);
      }
      if(Byte.class == primary || Byte.class == secondary) {
         return operate(left, right, BYTE);
      }
      if(Character.class == primary || Character.class == secondary) {
         return operate(left, right, INTEGER);
      }
      return operate(left, right, DOUBLE);
   }
   
   public abstract Value operate(Value left, Value right, ValueCalculator calculator);
   
   public static NumericOperator resolveOperator(StringToken token) {
      if(token != null) {
         String value = token.getValue();
         
         for(NumericOperator operator : VALUES) {
            if(operator.operator.equals(value)) {
               return operator;
            }
         }
      }
      return null;
   }   
   
   private static final NumericOperator[] VALUES = {
      PLUS,
      MINUS,
      DIVIDE,
      MULTIPLY,
      MODULUS,
      AND,
      OR,
      XOR,
      SHIFT_LEFT,
      SHIFT_RIGHT,
      UNSIGNED_SHIFT_RIGHT,
      POWER,
      COALESCE,
      REPLACE
   };
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy