use of org.codehaus.groovy.ast.expr.BinaryExpression in project groovy by apache.
the class BinaryExpressionHelper method evaluateBinaryExpressionWithAssignment.
protected void evaluateBinaryExpressionWithAssignment(String method, BinaryExpression expression) {
Expression leftExpression = expression.getLeftExpression();
AsmClassGenerator acg = controller.getAcg();
OperandStack operandStack = controller.getOperandStack();
if (leftExpression instanceof BinaryExpression) {
BinaryExpression leftBinExpr = (BinaryExpression) leftExpression;
if (leftBinExpr.getOperation().getType() == Types.LEFT_SQUARE_BRACKET) {
evaluateArrayAssignmentWithOperator(method, expression, leftBinExpr);
return;
}
}
evaluateBinaryExpression(method, expression);
// br to leave a copy of rvalue on the stack. see also isPopRequired()
operandStack.dup();
controller.getCompileStack().pushLHS(true);
leftExpression.visit(acg);
controller.getCompileStack().popLHS();
}
use of org.codehaus.groovy.ast.expr.BinaryExpression in project groovy by apache.
the class BinaryExpressionHelper method evaluateBinaryExpression.
protected void evaluateBinaryExpression(String message, BinaryExpression binExp) {
CompileStack compileStack = controller.getCompileStack();
Expression receiver = binExp.getLeftExpression();
Expression arguments = binExp.getRightExpression();
// ensure VariableArguments are read, not stored
compileStack.pushLHS(false);
controller.getInvocationWriter().makeSingleArgumentCall(receiver, message, arguments);
compileStack.popLHS();
}
use of org.codehaus.groovy.ast.expr.BinaryExpression in project groovy by apache.
the class BinaryExpressionHelper method evaluateCompareTo.
private void evaluateCompareTo(BinaryExpression expression) {
Expression leftExpression = expression.getLeftExpression();
AsmClassGenerator acg = controller.getAcg();
OperandStack operandStack = controller.getOperandStack();
leftExpression.visit(acg);
operandStack.box();
// if the right hand side is a boolean expression, we need to autobox
Expression rightExpression = expression.getRightExpression();
rightExpression.visit(acg);
operandStack.box();
compareToMethod.call(controller.getMethodVisitor());
operandStack.replace(ClassHelper.Integer_TYPE, 2);
}
use of org.codehaus.groovy.ast.expr.BinaryExpression in project groovy by apache.
the class BinaryExpressionHelper method execMethodAndStoreForSubscriptOperator.
private void execMethodAndStoreForSubscriptOperator(int op, String method, Expression expression, VariableSlotLoader usesSubscript, Expression orig) {
final OperandStack operandStack = controller.getOperandStack();
writePostOrPrefixMethod(op, method, expression, orig);
// we need special code for arrays to store the result (like for a[1]++)
if (usesSubscript != null) {
CompileStack compileStack = controller.getCompileStack();
BinaryExpression be = (BinaryExpression) expression;
ClassNode methodResultType = operandStack.getTopOperand();
final int resultIdx = compileStack.defineTemporaryVariable("postfix_" + method, methodResultType, true);
BytecodeExpression methodResultLoader = new VariableSlotLoader(methodResultType, resultIdx, operandStack);
// execute the assignment, this will leave the right side
// (here the method call result) on the stack
assignToArray(be, be.getLeftExpression(), usesSubscript, methodResultLoader);
compileStack.removeVar(resultIdx);
} else // here we handle a.b++ and a++
if (expression instanceof VariableExpression || expression instanceof FieldExpression || expression instanceof PropertyExpression) {
operandStack.dup();
controller.getCompileStack().pushLHS(true);
expression.visit(controller.getAcg());
controller.getCompileStack().popLHS();
}
// other cases don't need storing, so nothing to be done for them
}
use of org.codehaus.groovy.ast.expr.BinaryExpression in project groovy by apache.
the class BinaryExpressionHelper method evaluateEqual.
public void evaluateEqual(BinaryExpression expression, boolean defineVariable) {
AsmClassGenerator acg = controller.getAcg();
CompileStack compileStack = controller.getCompileStack();
OperandStack operandStack = controller.getOperandStack();
Expression rightExpression = expression.getRightExpression();
Expression leftExpression = expression.getLeftExpression();
ClassNode lhsType = controller.getTypeChooser().resolveType(leftExpression, controller.getClassNode());
if (defineVariable && rightExpression instanceof EmptyExpression && !(leftExpression instanceof TupleExpression)) {
VariableExpression ve = (VariableExpression) leftExpression;
BytecodeVariable var = compileStack.defineVariable(ve, controller.getTypeChooser().resolveType(ve, controller.getClassNode()), false);
operandStack.loadOrStoreVariable(var, false);
return;
}
// let's evaluate the RHS and store the result
ClassNode rhsType;
if (rightExpression instanceof ListExpression && lhsType.isArray()) {
ListExpression list = (ListExpression) rightExpression;
ArrayExpression array = new ArrayExpression(lhsType.getComponentType(), list.getExpressions());
array.setSourcePosition(list);
array.visit(acg);
} else if (rightExpression instanceof EmptyExpression) {
rhsType = leftExpression.getType();
loadInitValue(rhsType);
} else {
rightExpression.visit(acg);
}
rhsType = operandStack.getTopOperand();
boolean directAssignment = defineVariable && !(leftExpression instanceof TupleExpression);
int rhsValueId;
if (directAssignment) {
VariableExpression var = (VariableExpression) leftExpression;
if (var.isClosureSharedVariable() && ClassHelper.isPrimitiveType(rhsType)) {
// GROOVY-5570: if a closure shared variable is a primitive type, it must be boxed
rhsType = ClassHelper.getWrapper(rhsType);
operandStack.box();
}
// form as it is closure shared
if (var.isClosureSharedVariable() && ClassHelper.isPrimitiveType(var.getOriginType()) && isNull(rightExpression)) {
operandStack.doGroovyCast(var.getOriginType());
// these two are never reached in bytecode and only there
// to avoid verifyerrors and compiler infrastructure hazzle
operandStack.box();
operandStack.doGroovyCast(lhsType);
}
// normal type transformation
if (!ClassHelper.isPrimitiveType(lhsType) && isNull(rightExpression)) {
operandStack.replace(lhsType);
} else {
operandStack.doGroovyCast(lhsType);
}
rhsType = lhsType;
rhsValueId = compileStack.defineVariable(var, lhsType, true).getIndex();
} else {
rhsValueId = compileStack.defineTemporaryVariable("$rhs", rhsType, true);
}
//TODO: if rhs is VariableSlotLoader already, then skip crating a new one
BytecodeExpression rhsValueLoader = new VariableSlotLoader(rhsType, rhsValueId, operandStack);
// assignment for subscript
if (leftExpression instanceof BinaryExpression) {
BinaryExpression leftBinExpr = (BinaryExpression) leftExpression;
if (leftBinExpr.getOperation().getType() == Types.LEFT_SQUARE_BRACKET) {
assignToArray(expression, leftBinExpr.getLeftExpression(), leftBinExpr.getRightExpression(), rhsValueLoader);
}
compileStack.removeVar(rhsValueId);
return;
}
compileStack.pushLHS(true);
// multiple declaration
if (leftExpression instanceof TupleExpression) {
TupleExpression tuple = (TupleExpression) leftExpression;
int i = 0;
for (Expression e : tuple.getExpressions()) {
VariableExpression var = (VariableExpression) e;
MethodCallExpression call = new MethodCallExpression(rhsValueLoader, "getAt", new ArgumentListExpression(new ConstantExpression(i)));
call.visit(acg);
i++;
if (defineVariable) {
operandStack.doGroovyCast(var);
compileStack.defineVariable(var, true);
operandStack.remove(1);
} else {
acg.visitVariableExpression(var);
}
}
} else // single declaration
if (defineVariable) {
rhsValueLoader.visit(acg);
operandStack.remove(1);
compileStack.popLHS();
return;
} else // normal assignment
{
int mark = operandStack.getStackLength();
// to leave a copy of the rightExpression value on the stack after the assignment.
rhsValueLoader.visit(acg);
TypeChooser typeChooser = controller.getTypeChooser();
ClassNode targetType = typeChooser.resolveType(leftExpression, controller.getClassNode());
operandStack.doGroovyCast(targetType);
leftExpression.visit(acg);
operandStack.remove(operandStack.getStackLength() - mark);
}
compileStack.popLHS();
// return value of assignment
rhsValueLoader.visit(acg);
compileStack.removeVar(rhsValueId);
}
Aggregations