// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.npc.util.expression.compile;

import javax.annotation.Nullable;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.npc.util.expression.ExecutionContext;
import com.hypixel.hytale.server.npc.util.expression.Scope;
import java.util.function.Function;
import com.hypixel.hytale.server.npc.util.expression.ValueType;

public class OperatorBinary
{
    private Token token;
    private ValueType lhs;
    private ValueType rhs;
    private ValueType result;
    private Function<Scope, ExecutionContext.Instruction> codeGen;
    @Nonnull
    private static OperatorBinary[] operators;
    
    private OperatorBinary(final Token token, final ValueType lhs, final ValueType rhs, final ValueType result, final Function<Scope, ExecutionContext.Instruction> codeGen) {
        this.token = token;
        this.lhs = lhs;
        this.rhs = rhs;
        this.result = result;
        this.codeGen = codeGen;
    }
    
    public ValueType getResultType() {
        return this.result;
    }
    
    public Function<Scope, ExecutionContext.Instruction> getCodeGen() {
        return this.codeGen;
    }
    
    @Nonnull
    private static OperatorBinary of(final Token token, final ValueType lhs, final ValueType rhs, final ValueType result, final Function<Scope, ExecutionContext.Instruction> codeGen) {
        return new OperatorBinary(token, lhs, rhs, result, codeGen);
    }
    
    @Nullable
    public static OperatorBinary findOperator(final Token token, final ValueType lhs, final ValueType rhs) {
        for (final OperatorBinary op : OperatorBinary.operators) {
            if (op.token == token && op.lhs == lhs && op.rhs == rhs) {
                return op;
            }
        }
        return null;
    }
    
    static {
        OperatorBinary.operators = new OperatorBinary[] { of(Token.EXPONENTIATION, ValueType.NUMBER, ValueType.NUMBER, ValueType.NUMBER, scope -> ExecutionContext.EXPONENTIATION), of(Token.REMAINDER, ValueType.NUMBER, ValueType.NUMBER, ValueType.NUMBER, scope -> ExecutionContext.REMAINDER), of(Token.DIVIDE, ValueType.NUMBER, ValueType.NUMBER, ValueType.NUMBER, scope -> ExecutionContext.DIVIDE), of(Token.MULTIPLY, ValueType.NUMBER, ValueType.NUMBER, ValueType.NUMBER, scope -> ExecutionContext.MULTIPLY), of(Token.MINUS, ValueType.NUMBER, ValueType.NUMBER, ValueType.NUMBER, scope -> ExecutionContext.MINUS), of(Token.PLUS, ValueType.NUMBER, ValueType.NUMBER, ValueType.NUMBER, scope -> ExecutionContext.PLUS), of(Token.GREATER_EQUAL, ValueType.NUMBER, ValueType.NUMBER, ValueType.BOOLEAN, scope -> ExecutionContext.GREATER_EQUAL), of(Token.GREATER, ValueType.NUMBER, ValueType.NUMBER, ValueType.BOOLEAN, scope -> ExecutionContext.GREATER), of(Token.LESS_EQUAL, ValueType.NUMBER, ValueType.NUMBER, ValueType.BOOLEAN, scope -> ExecutionContext.LESS_EQUAL), of(Token.LESS, ValueType.NUMBER, ValueType.NUMBER, ValueType.BOOLEAN, scope -> ExecutionContext.LESS), of(Token.NOT_EQUAL, ValueType.NUMBER, ValueType.NUMBER, ValueType.BOOLEAN, scope -> ExecutionContext.NOT_EQUAL), of(Token.EQUAL, ValueType.NUMBER, ValueType.NUMBER, ValueType.BOOLEAN, scope -> ExecutionContext.EQUAL), of(Token.NOT_EQUAL, ValueType.BOOLEAN, ValueType.BOOLEAN, ValueType.BOOLEAN, scope -> ExecutionContext.NOT_EQUAL_BOOL), of(Token.EQUAL, ValueType.BOOLEAN, ValueType.BOOLEAN, ValueType.BOOLEAN, scope -> ExecutionContext.EQUAL_BOOL), of(Token.BITWISE_AND, ValueType.NUMBER, ValueType.NUMBER, ValueType.NUMBER, scope -> ExecutionContext.BITWISE_AND), of(Token.BITWISE_XOR, ValueType.NUMBER, ValueType.NUMBER, ValueType.NUMBER, scope -> ExecutionContext.BITWISE_XOR), of(Token.BITWISE_OR, ValueType.NUMBER, ValueType.NUMBER, ValueType.NUMBER, scope -> ExecutionContext.BITWISE_OR), of(Token.LOGICAL_AND, ValueType.BOOLEAN, ValueType.BOOLEAN, ValueType.BOOLEAN, scope -> ExecutionContext.LOGICAL_AND), of(Token.LOGICAL_OR, ValueType.BOOLEAN, ValueType.BOOLEAN, ValueType.BOOLEAN, scope -> ExecutionContext.LOGICAL_OR) };
    }
}
