Search in sources :

Example 6 with OperatorTranslation

use of com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transform.

public JCExpression transform(Tree.WithinOp op) {
    Tree.Term middleTerm = op.getTerm();
    Tree.Bound lowerBound = op.getLowerBound();
    OperatorTranslation lowerOp = Operators.getOperator(lowerBound instanceof Tree.OpenBound ? Tree.SmallerOp.class : Tree.SmallAsOp.class);
    Tree.Term lowerTerm = lowerBound.getTerm();
    Tree.Bound upperBound = op.getUpperBound();
    OperatorTranslation upperOp = Operators.getOperator(upperBound instanceof Tree.OpenBound ? Tree.SmallerOp.class : Tree.SmallAsOp.class);
    Tree.Term upperTerm = upperBound.getTerm();
    Type middleType = getComparableType(middleTerm);
    Type lowerType = getComparableType(lowerTerm);
    Type upperType = getComparableType(upperTerm);
    // If any of the terms is optimizable, then use optimized
    OptimisationStrategy opt;
    boolean optimizeLower = lowerOp.isTermOptimisable(lowerTerm, lowerType, this) == OptimisationStrategy.OPTIMISE || lowerOp.isTermOptimisable(middleTerm, middleType, this) == OptimisationStrategy.OPTIMISE;
    boolean optimizeUpper = upperOp.isTermOptimisable(middleTerm, middleType, this) == OptimisationStrategy.OPTIMISE || upperOp.isTermOptimisable(upperTerm, upperType, this) == OptimisationStrategy.OPTIMISE;
    if ((lowerType.isExactly(middleType) && middleType.isExactly(upperType) && (optimizeLower || // if all same type and any optimizable
    optimizeUpper)) || (// otherwise onle if all optimizable
    optimizeLower && optimizeUpper)) {
        opt = OptimisationStrategy.OPTIMISE;
    } else {
        opt = OptimisationStrategy.NONE;
    }
    SyntheticName middleName = naming.alias("middle");
    List<JCStatement> vars = List.<JCStatement>of(makeVar(middleName, makeJavaType(middleType, opt.getBoxingStrategy() == BoxingStrategy.UNBOXED ? 0 : JT_NO_PRIMITIVES), transformExpression(middleTerm, opt.getBoxingStrategy(), middleType)));
    JCExpression lower = transformBound(middleName, middleType, lowerType, lowerOp, opt, middleTerm, lowerBound, false);
    JCExpression upper = transformBound(middleName, middleType, upperType, upperOp, opt, middleTerm, upperBound, true);
    at(op);
    OperatorTranslation andOp = Operators.getOperator(Tree.AndOp.class);
    OptimisationStrategy optimisationStrategy = OptimisationStrategy.OPTIMISE;
    return make().LetExpr(vars, transformOverridableBinaryOperator(andOp, optimisationStrategy, lower, upper, null, null, op.getTypeModel()));
}
Also used : Term(com.redhat.ceylon.compiler.typechecker.tree.Tree.Term) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) AssignmentOperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation) OperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation) Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) OptimisationStrategy(com.redhat.ceylon.compiler.java.codegen.Operators.OptimisationStrategy)

Example 7 with OperatorTranslation

use of com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transform.

public JCExpression transform(Tree.ScaleOp op) {
    OperatorTranslation operator = Operators.getOperator(Tree.ScaleOp.class);
    Tree.Term scalableTerm = op.getRightTerm();
    Type scalableTermType = getSupertype(scalableTerm, typeFact().getScalableDeclaration());
    SyntheticName scaleableName = naming.alias("scalable");
    JCVariableDecl scaleable = makeVar(scaleableName, makeJavaType(scalableTermType, JT_NO_PRIMITIVES), transformExpression(scalableTerm, BoxingStrategy.BOXED, scalableTermType));
    Tree.Term scaleTerm = op.getLeftTerm();
    SyntheticName scaleName = naming.alias("scale");
    Type scaleType = getTypeArgument(scalableTermType, 0);
    JCExpression scaleValue;
    if (isCeylonInteger(scaleTerm.getTypeModel()) && isCeylonFloat(scaleType)) {
        // Disgusting coercion
        scaleValue = transformExpression(scaleTerm, BoxingStrategy.UNBOXED, scalableTerm.getTypeModel());
        scaleValue = boxType(scaleValue, typeFact().getFloatType());
    } else {
        scaleValue = transformExpression(scaleTerm, BoxingStrategy.BOXED, scaleType);
    }
    JCVariableDecl scale = makeVar(scaleName, makeJavaType(scaleType, JT_NO_PRIMITIVES), scaleValue);
    at(op);
    return make().LetExpr(List.<JCStatement>of(scale, scaleable), transformOverridableBinaryOperator(operator, OptimisationStrategy.NONE, scaleableName.makeIdent(), scaleName.makeIdent(), null, null, op.getTypeModel()));
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Term(com.redhat.ceylon.compiler.typechecker.tree.Tree.Term) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) AssignmentOperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation) OperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation)

Example 8 with OperatorTranslation

use of com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transform.

// Logical operators
public JCExpression transform(Tree.LogicalOp op) {
    OperatorTranslation operator = Operators.getOperator(op.getClass());
    if (operator == null) {
        return makeErroneous(op, "compiler bug: " + op.getNodeType() + " is not a supported logical operator");
    }
    // Both terms are Booleans and can't be erased to anything
    JCExpression left = transformExpression(op.getLeftTerm(), BoxingStrategy.UNBOXED, null);
    return transformLogicalOp(op, operator, left, op.getRightTerm());
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) AssignmentOperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation) OperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation)

Example 9 with OperatorTranslation

use of com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation in project ceylon-compiler by ceylon.

the class ExpressionTransformer method checkForBitwiseOperators.

private JCExpression checkForBitwiseOperators(Tree.Term node, Tree.QualifiedMemberExpression qme, Tree.Term right) {
    // must be a call on Integer
    Tree.Term left = qme.getPrimary();
    if (left == null) {
        return null;
    }
    String signature;
    Type binaryType;
    if (isCeylonInteger(left.getTypeModel())) {
        // must be a supported method/attribute
        binaryType = typeFact().getIntegerType();
        String name = qme.getIdentifier().getText();
        signature = "ceylon.language.Integer." + name;
    } else if (isCeylonByte(left.getTypeModel())) {
        binaryType = typeFact().getByteType();
        String name = qme.getIdentifier().getText();
        signature = "ceylon.language.Byte." + name;
    } else {
        return null;
    }
    // see if we have an operator for it
    OperatorTranslation operator = Operators.getOperator(signature);
    if (operator != null) {
        JCExpression result;
        if (operator.getArity() == 2) {
            if (right == null)
                return null;
            OptimisationStrategy optimisationStrategy = operator.getBinOpOptimisationStrategy(node, left, right, this);
            // check that we can optimise it
            if (!optimisationStrategy.useJavaOperator())
                return null;
            JCExpression leftExpr = transformExpression(left, optimisationStrategy.getBoxingStrategy(), binaryType, EXPR_WIDEN_PRIM);
            JCExpression rightExpr = transformExpression(right, optimisationStrategy.getBoxingStrategy(), binaryType, EXPR_WIDEN_PRIM);
            if (operator.valueMask != 0) {
                leftExpr = make().Binary(JCTree.BITAND, leftExpr, makeInteger(operator.valueMask));
            }
            result = make().Binary(operator.javacOperator, leftExpr, rightExpr);
        } else {
            // must be unary
            if (right != null)
                return null;
            OptimisationStrategy optimisationStrategy = operator.getUnOpOptimisationStrategy(node, left, this);
            // check that we can optimise it
            if (!optimisationStrategy.useJavaOperator())
                return null;
            JCExpression leftExpr = transformExpression(left, optimisationStrategy.getBoxingStrategy(), binaryType, EXPR_WIDEN_PRIM);
            if (operator.valueMask != 0) {
                leftExpr = make().Binary(JCTree.BITAND, leftExpr, makeInteger(operator.valueMask));
            }
            result = make().Unary(operator.javacOperator, leftExpr);
        }
        if (isCeylonByte(binaryType)) {
            result = make().TypeCast(syms().byteType, result);
        }
        return result;
    }
    return null;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Term(com.redhat.ceylon.compiler.typechecker.tree.Tree.Term) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) OptimisationStrategy(com.redhat.ceylon.compiler.java.codegen.Operators.OptimisationStrategy) AssignmentOperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation) OperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation)

Example 10 with OperatorTranslation

use of com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformOverridableBinaryOperator.

private JCExpression transformOverridableBinaryOperator(Tree.BinaryOperatorExpression op, Type leftType, Type rightType) {
    OperatorTranslation operator = Operators.getOperator(op.getClass());
    if (operator == null) {
        return makeErroneous(op, "compiler bug: " + op.getClass() + " is an unhandled operator");
    }
    OptimisationStrategy optimisationStrategy = operator.getBinOpOptimisationStrategy(op, op.getLeftTerm(), leftType, op.getRightTerm(), rightType, this);
    at(op);
    JCExpression left = transformExpression(op.getLeftTerm(), optimisationStrategy.getBoxingStrategy(), leftType, EXPR_WIDEN_PRIM);
    JCExpression right = transformExpression(op.getRightTerm(), optimisationStrategy.getBoxingStrategy(), rightType, EXPR_WIDEN_PRIM);
    return transformOverridableBinaryOperator(operator, optimisationStrategy, left, right, op.getLeftTerm(), op.getRightTerm(), op.getTypeModel());
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) OptimisationStrategy(com.redhat.ceylon.compiler.java.codegen.Operators.OptimisationStrategy) AssignmentOperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation) OperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation)

Aggregations

AssignmentOperatorTranslation (com.redhat.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation)10 OperatorTranslation (com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation)10 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)10 OptimisationStrategy (com.redhat.ceylon.compiler.java.codegen.Operators.OptimisationStrategy)6 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)6 Term (com.redhat.ceylon.compiler.typechecker.tree.Tree.Term)6 Type (com.redhat.ceylon.model.typechecker.model.Type)6 JCTree (com.sun.tools.javac.tree.JCTree)6 SyntheticName (com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName)3 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)2 Interface (com.redhat.ceylon.model.typechecker.model.Interface)2 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)2 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)2 Name (com.sun.tools.javac.util.Name)1