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()));
}
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()));
}
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());
}
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;
}
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());
}
Aggregations