org.formulacompiler.compiler.internal.bytecode.ExpressionCompilerForScaledLongs_Base.java Source code

Java tutorial

Introduction

Here is the source code for org.formulacompiler.compiler.internal.bytecode.ExpressionCompilerForScaledLongs_Base.java

Source

/*
 * Copyright (c) 2006-2009 by Abacus Research AG, Switzerland.
 * All rights reserved.
 *
 * This file is part of the Abacus Formula Compiler (AFC).
 *
 * For commercial licensing, please contact sales(at)formulacompiler.com.
 *
 * AFC is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * AFC 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with AFC.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.formulacompiler.compiler.internal.bytecode;

import org.formulacompiler.compiler.CompilerException;
import org.formulacompiler.compiler.NumericType;
import org.formulacompiler.compiler.internal.AbstractLongType;
import org.formulacompiler.runtime.ScaledLong;
import org.formulacompiler.runtime.ScaledLongSupport;
import org.objectweb.asm.Opcodes;

abstract class ExpressionCompilerForScaledLongs_Base extends ExpressionCompilerForNumbers {
    private static final String RUNTIME_CONTEXT_DESCRIPTOR = TypeCompilerForScaledLongs.RUNTIME_CONTEXT_DESCRIPTOR;
    private static final String RUNTIME_CONTEXT_NAME = TypeCompilerForScaledLongs.RUNTIME_CONTEXT_NAME;

    private final int scale;
    private final long one;
    private final TypeCompilerForScaledLongs longCompiler = ((TypeCompilerForScaledLongs) typeCompiler());

    public ExpressionCompilerForScaledLongs_Base(MethodCompiler _methodCompiler, NumericType _numericType) {
        super(_methodCompiler, _numericType);
        this.scale = _numericType.scale();
        this.one = ((AbstractLongType) _numericType).one();
    }

    protected final int scale() {
        return this.scale;
    }

    @Override
    protected void compileConversionFromLong() throws CompilerException {
        compile_util_fromLong();
        compileScaleUp();
    }

    @Override
    protected void compileConversionFromInt() throws CompilerException {
        compile_util_fromInt();
        compileScaleUp();
    }

    @Override
    protected void compileConversionFromNumber() throws CompilerException {
        compile_util_fromNumber();
        compileScaleUp();
    }

    @Override
    protected void compileConversionFromBigInteger() throws CompilerException {
        compile_util_fromBigInteger();
        compileScaleUp();
    }

    @Override
    protected void compileConversionFromBigDecimal() throws CompilerException {
        if (isScaled()) {
            compile_util_fromBigDecimal_Scaled();
        } else {
            compile_util_fromBigDecimal();
        }
    }

    @Override
    protected void compileConversionFromFloat() throws CompilerException {
        if (isScaled()) {
            compile_util_fromFloat_Scaled();
        } else {
            compile_util_fromFloat();
        }
    }

    @Override
    protected void compileConversionFromDouble() throws CompilerException {
        if (isScaled()) {
            compile_util_fromDouble_Scaled();
        } else {
            compile_util_fromDouble();
        }
    }

    @Override
    protected void compileConversionToLong() throws CompilerException {
        compileScaleDown();
        compile_util_toLong();
    }

    @Override
    protected void compileConversionToInt() throws CompilerException {
        compileScaleDown();
        compile_util_toInt();
    }

    @Override
    protected void compileConversionToShort() throws CompilerException {
        compileScaleDown();
        compile_util_toShort();
    }

    @Override
    protected void compileConversionToByte() throws CompilerException {
        compileScaleDown();
        compile_util_toByte();
    }

    @Override
    protected void compileConversionToBigDecimal() throws CompilerException {
        if (isScaled()) {
            compile_util_toBigDecimal_Scaled();
        } else {
            compile_util_toBigDecimal();
        }
    }

    @Override
    protected void compileConversionToBigInteger() throws CompilerException {
        compileScaleDown();
        compile_util_toBigInteger();
    }

    @Override
    protected void compileConversionToFloat() throws CompilerException {
        if (isScaled()) {
            compile_util_toFloat_Scaled();
        } else {
            compile_util_toFloat();
        }
    }

    @Override
    protected void compileConversionToDouble() throws CompilerException {
        if (isScaled()) {
            compile_util_toDouble_Scaled();
        } else {
            compile_util_toDouble();
        }
    }

    @Override
    protected void compileConversionToBoolean() throws CompilerException {
        compileScaleDown();
        compile_util_toBoolean();
    }

    @Override
    protected void compileConversionToNumber() throws CompilerException {
        if (isScaled()) {
            compile_util_toNumber_Scaled();
        } else {
            compile_util_toNumber();
        }
    }

    protected final boolean isScaled() {
        return (scale() != 0);
    }

    protected final void compile_scale() {
        mv().push(scale());
    }

    protected final void compile_context() {
        this.longCompiler.buildStaticContext();
        mv().visitFieldInsn(Opcodes.GETSTATIC, typeCompiler().rootCompiler().classInternalName(),
                RUNTIME_CONTEXT_NAME, RUNTIME_CONTEXT_DESCRIPTOR);
    }

    protected final void compile_one() {
        mv().push(this.one);
    }

    private void compileScaleUp() throws CompilerException {
        if (scale() > 0) {
            compile_util_scaleUp(this.one);
        }
    }

    private void compileScaleDown() throws CompilerException {
        if (scale() > 0) {
            compile_util_scaleDown(this.one);
        }
    }

    private final void compileScaleCorrection(int _have, int _want) throws CompilerException {
        if (_have > _want) {
            long correct = ScaledLongSupport.ONE[_have] / ScaledLongSupport.ONE[_want];
            compile_util_scaleDown(correct);
        } else if (_have < _want) {
            long correct = ScaledLongSupport.ONE[_want] / ScaledLongSupport.ONE[_have];
            compile_util_scaleUp(correct);
        }
    }

    @Override
    protected void compileConversionFrom(ScaledLong _scale) throws CompilerException {
        compileScaleCorrection(_scale.value(), scale());
    }

    @Override
    protected void compileConversionTo(ScaledLong _scale) throws CompilerException {
        compileScaleCorrection(scale(), _scale.value());
    }

    @Override
    protected int compileComparison(int _ifOpcode, int _comparisonOpcode) throws CompilerException {
        mv().visitInsn(Opcodes.LCMP);
        return _ifOpcode;
    }

    @Override
    protected void compileDup() {
        mv().visitInsn(Opcodes.DUP2);
    }

    @Override
    protected void compilePop() {
        mv().visitInsn(Opcodes.POP2);
    }

    protected abstract void compile_util_scaleUp(long _one) throws CompilerException;

    protected abstract void compile_util_scaleDown(long _one) throws CompilerException;

    protected abstract void compile_util_toDouble_Scaled() throws CompilerException;

    protected abstract void compile_util_toFloat_Scaled() throws CompilerException;

    protected abstract void compile_util_toBigDecimal_Scaled() throws CompilerException;

    protected abstract void compile_util_toNumber_Scaled() throws CompilerException;

    protected abstract void compile_util_fromDouble_Scaled() throws CompilerException;

    protected abstract void compile_util_fromFloat_Scaled() throws CompilerException;

    protected abstract void compile_util_fromBigDecimal_Scaled() throws CompilerException;

}