com.github.bloodshura.x.utilities.eval.enumeration.Operator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of shurax-utilities Show documentation
Show all versions of shurax-utilities Show documentation
A collection of general utilities.
The newest version!
/*
* Copyright (c) 2013-2018, João Vitor Verona Biazibetti - All Rights Reserved
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*
* https://www.github.com/BloodShura
*/
package com.github.bloodshura.x.utilities.eval.enumeration;
import com.github.bloodshura.x.collection.view.XView;
import com.github.bloodshura.x.enumeration.Enumerations;
import com.github.bloodshura.x.object.Base;
import com.github.bloodshura.x.util.XApi;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.function.Function;
public class Operator extends Base {
public static final Operator ABS = new Operator("ABS", " abs ", 1, 4, 1, 1, operands -> operands[0].abs());
public static final Operator ADD = new Operator("ADD", "+", 2, 2, 1, 1, operands -> operands[0].add(operands[1]));
public static final Operator AND = new Operator("AND", "&&", 2, 0, 0, 0, operands -> operands[0].signum() != 0 && operands[1].signum() != 0);
public static final Operator DIVIDE = new Operator("DIVIDE", "/", 2, 3, 1, 1, operands -> operands[0].divide(operands[1], MathContext.UNLIMITED));
public static final Operator END = new Operator("END", "", 0, -1, Type.NONE, Type.NONE, operands -> null);
public static final Operator EQUAL = new Operator("EQUAL", "==", 2, 1, 1, 0, operands -> operands[0].compareTo(operands[1]) == 0);
public static final Operator GREATER_EQUAL = new Operator("GREATER_EQUAL", ">=", 2, 1, 1, 0, operands -> operands[0].compareTo(operands[1]) >= 0);
public static final Operator GREATER_THAN = new Operator("GREATER_THAN", ">", 2, 1, 1, 0, operands -> operands[0].compareTo(operands[1]) > 0);
public static final Operator INT = new Operator("INT", "int ", 1, 4, 1, 1, operands -> new BigDecimal(operands[0].toBigInteger()));
public static final Operator LOWER_EQUAL = new Operator("LOWER_EQUAL", "<=", 2, 1, 1, 0, operands -> operands[0].compareTo(operands[1]) <= 0);
public static final Operator LOWER_THAN = new Operator("LOWER_THAN", "<", 2, 1, 1, 0, operands -> operands[0].compareTo(operands[1]) < 0);
public static final Operator MULTIPLY = new Operator("MULTIPLY", "*", 2, 3, 1, 1, operands -> operands[0].multiply(operands[1]));
public static final Operator NEGATE = new Operator("NEGATE", "-", 1, 4, 1, 1, operands -> operands[0].negate());
public static final Operator NOP = new Operator("NOP", "", 1, 4, 1, 1, operands -> operands[0]);
public static final Operator NOT_EQUAL = new Operator("NOT_EQUAL", "!=", 2, 1, 1, 0, operands -> operands[0].compareTo(operands[1]) != 0);
public static final Operator OR = new Operator("OR", "||", 2, 0, 0, 0, operands -> operands[0].signum() != 0 || operands[1].signum() != 0);
public static final Operator PLUS = new Operator("PLUS", "+", 1, 4, 1, 1, operands -> operands[0]);
public static final Operator POW = new Operator("POW", "^", 2, 3, 1, 1, operands -> operands[0].pow(operands[1].intValueExact()));
public static final Operator REMAINDER = new Operator("REMAINDER", "%", 2, 3, 1, 1, operands -> operands[0].remainder(operands[1], MathContext.UNLIMITED));
public static final Operator SUBTRACT = new Operator("SUBTRACT", "-", 2, 2, 1, 1, operands -> operands[0].subtract(operands[1]));
public static final Operator TERNARY = new Operator("TERNARY", "?", 3, 0, Type.NONE, Type.NONE, operands -> operands[0].signum() != 0 ? operands[1] : operands[2]);
private final Function function;
private final String identifier;
private final int operandCount;
private final Type operandType;
private final int precedence;
private final Type resultType;
private final String name;
public Operator(@Nonnull String name, @Nonnull String identifier, int operandCount, int precedence, int operandType, int resultType, @Nonnull Function function) {
this(name, identifier, operandCount, precedence, operandType == 1 ? Type.ARITHMETIC : Type.BOOLEAN, resultType == 1 ? Type.ARITHMETIC : Type.BOOLEAN, function);
}
public Operator(@Nonnull String name, @Nonnull String identifier, int operandCount, int precedence, @Nonnull Type operandType, @Nonnull Type resultType, @Nullable Function function) {
this.function = function;
this.identifier = identifier;
this.name = name;
this.operandCount = operandCount;
this.operandType = operandType;
this.precedence = precedence;
this.resultType = resultType;
}
@Nonnull
public Function getFunction() {
return function;
}
@Nonnull
public String getIdentifier() {
return identifier;
}
@Nonnull
public String getName() {
return name;
}
public int getOperandCount() {
return operandCount;
}
@Nonnull
public Type getOperandType() {
return operandType;
}
public int getPrecedence() {
return precedence;
}
@Nonnull
public Type getResultType() {
return resultType;
}
@Nonnull
public BigDecimal perform(@Nonnull BigDecimal... values) {
XApi.require(values.length == getOperandCount(), "Operator \"" + getIdentifier() + "\" requires " + getOperandCount() + " operands");
Object result = getFunction().apply(values);
XApi.require(result instanceof BigDecimal || result instanceof Boolean || result instanceof Integer, "Returned value of operator \"" + this + "\" is neither BigDecimal, nor Integer");
if (result instanceof Boolean) {
return (Boolean) result ? BigDecimal.ONE : BigDecimal.ZERO;
}
if (getResultType() == Type.BOOLEAN) {
if (result instanceof BigDecimal) {
return !result.equals(BigDecimal.ZERO) ? BigDecimal.ONE : BigDecimal.ZERO;
}
if (result instanceof Integer) {
Integer value = (Integer) result;
return value != 0 ? BigDecimal.ONE : BigDecimal.ZERO;
}
}
if (result instanceof Integer) {
return BigDecimal.valueOf((Integer) result);
}
return (BigDecimal) result;
}
@Nonnull
@Override
protected Object[] stringValues() {
return new Object[] { getIdentifier(), getOperandCount(), getPrecedence(), getOperandType(), getResultType() };
}
@Nonnull
public static XView values() {
return Enumerations.values(Operator.class);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy