Package joust.optimisers.shortfunc

Source Code of joust.optimisers.shortfunc.ShortFuncFunctionTemplates

package joust.optimisers.shortfunc;

import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.List;
import joust.tree.annotatedtree.AJCTree;
import joust.utils.logging.LogUtils;
import joust.utils.tree.functiontemplates.FunctionTemplate;
import lombok.experimental.ExtensionMethod;
import lombok.extern.java.Log;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import static com.sun.tools.javac.code.Symbol.*;
import static com.sun.tools.javac.tree.JCTree.*;
import static joust.tree.annotatedtree.AJCTree.*;
import static joust.utils.compiler.StaticCompilerUtils.*;
import static joust.utils.tree.TreeUtils.findMethod;

@Log
@ExtensionMethod({Logger.class, LogUtils.LogExtensions.class})
public class ShortFuncFunctionTemplates {
    public static Map<MethodSymbol, FunctionTemplate> functionTemplates;

    public static void init() {
        functionTemplates = new HashMap<MethodSymbol, FunctionTemplate>();

        ClassSymbol langMath = reader.enterClass(names.fromString("java.lang.Math"));
        // Math.min
        functionTemplates.put(findMethod("min", langMath, true, symtab.intType, symtab.intType), getMinMax(symtab.intType, true));
        functionTemplates.put(findMethod("min", langMath, true, symtab.longType, symtab.longType), getMinMax(symtab.longType, true));

        // Math.max
        functionTemplates.put(findMethod("max", langMath, true, symtab.intType, symtab.intType), getMinMax(symtab.intType, false));
        functionTemplates.put(findMethod("max", langMath, true, symtab.longType, symtab.longType), getMinMax(symtab.longType, false));
        // Not supporting floating point types here - it's not as trivial.

        // Math.abs
        functionTemplates.put(findMethod("abs", langMath, true, symtab.intType), getAbs(symtab.intType));
        functionTemplates.put(findMethod("abs", langMath, true, symtab.longType), getAbs(symtab.longType));
        functionTemplates.put(findMethod("abs", langMath, true, symtab.floatType), getAbs(symtab.floatType));
        functionTemplates.put(findMethod("abs", langMath, true, symtab.doubleType), getAbs(symtab.doubleType));

        // Math.toDegrees
        AJCExpressionTree toDegrees = treeMaker.Binary(Tag.MUL, param(0, symtab.doubleType), treeMaker.Literal(57.2957795131D));
        toDegrees.setType(symtab.doubleType);
        functionTemplates.put(findMethod("toDegrees", langMath, true, symtab.doubleType), new FunctionTemplate(toDegrees, true, symtab.doubleType));

        // Math.toRadians
        AJCExpressionTree toRadians = treeMaker.Binary(Tag.MUL, param(0, symtab.doubleType), treeMaker.Literal(0.0174532925D));
        toDegrees.setType(symtab.doubleType);
        functionTemplates.put(findMethod("toRadians", langMath, true, symtab.doubleType), new FunctionTemplate(toRadians, true, symtab.doubleType));

        ClassSymbol langString = reader.enterClass(names.fromString("java.lang.String"));
        // String.valueOf
        AJCExpressionTree valueOfBoolean = treeMaker.Conditional(param(0, symtab.booleanType), treeMaker.Literal("true"), treeMaker.Literal("false"));
        functionTemplates.put(findMethod("valueOf", langString, true, symtab.booleanType), new FunctionTemplate(valueOfBoolean, true, symtab.booleanType));

        // String.toString()...
        functionTemplates.put(findMethod("toString", langString, false), new FunctionTemplate(param(0, symtab.stringType), false, symtab.stringType));
    }

    /**
     * Get a FunctionTemplate for one of the Math.min/Math.max methods.
     * @param t The argument type of the method to get.
     * @param min If true, get a Math.min method, else a Math.max one.
     */
    private static FunctionTemplate getMinMax(Type t, boolean min) {
        AJCExpressionTree mathMin =
            treeMaker.Conditional(
                treeMaker.Binary(min ? Tag.LE : Tag.GE, param(0, t), param(1, t)),
                param(0, t),
                param(1, t)
            );
        mathMin.setType(t);

        return new FunctionTemplate(mathMin, true, t, t);
    }

    /**
     * Get a FunctionTemplate representing Math.abs on the given type.
     */
    private static FunctionTemplate getAbs(Type t) {
        // Determine if the input is a floating point type.
        TypeTag tag = t.getTag();
        boolean isFP = tag == TypeTag.FLOAT ||
                       tag == TypeTag.DOUBLE;

        AJCExpressionTree abs =
            treeMaker.Conditional(
                    treeMaker.Binary(Tag.LE, param(0, t), getZero(t)),
                    isFP ?
                        treeMaker.Binary(Tag.MINUS, getZero(t), param(0, t))
                    :
                        treeMaker.Unary(Tag.NEG, param(0, t)),
                    param(0, t)
            );
        abs.setType(t);

        return new FunctionTemplate(abs, true, t);
    }

    /**
     * Get an appropriately-typed zero literal for a given primitive type.
     */
    private static AJCLiteral getZero(Type t) {
        switch(t.getTag()) {
            case DOUBLE:
                return treeMaker.Literal(0.0D);
            case FLOAT:
                return treeMaker.Literal(0.0F);
            case INT:
                return treeMaker.Literal(0);
            case LONG:
                return treeMaker.Literal(0L);
            default:
                log.fatal("Getting zero literal for unknown type: {}", t);
        }

        return null;
    }

    private static AJCIdent param(int index, Type type) {
        AJCIdent ident = treeMaker.Ident(names.fromString(index + "$PARAM"));
        ident.setType(type);

        return ident;
    }
}
TOP

Related Classes of joust.optimisers.shortfunc.ShortFuncFunctionTemplates

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.