pre-increment, pre-decrement
This commit is contained in:
@@ -533,8 +533,11 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
}
|
||||
|
||||
private static boolean isNumberPrimitive(Type type) {
|
||||
return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE ||
|
||||
type == Type.FLOAT_TYPE || type == Type.DOUBLE_TYPE || type == Type.LONG_TYPE;
|
||||
return isIntPrimitive(type) || type == Type.FLOAT_TYPE || type == Type.DOUBLE_TYPE || type == Type.LONG_TYPE;
|
||||
}
|
||||
|
||||
private static boolean isIntPrimitive(Type type) {
|
||||
return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE;
|
||||
}
|
||||
|
||||
private static int opcodeForMethod(final String name) {
|
||||
@@ -588,16 +591,57 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
JetType returnType = bindingContext.getExpressionType(expression);
|
||||
final Type asmType = typeMapper.mapType(returnType);
|
||||
DeclarationDescriptor cls = op.getContainingDeclaration();
|
||||
if (isNumberPrimitive(cls) && op.getName().equals("minus")) {
|
||||
gen(expression.getBaseExpression(), asmType);
|
||||
v.neg(asmType);
|
||||
myStack.push(StackValue.onStack(asmType));
|
||||
return;
|
||||
if (isNumberPrimitive(cls)) {
|
||||
if (generateUnaryOp(expression, op, asmType)) return;
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException("Don't know how to generate this prefix expression");
|
||||
}
|
||||
|
||||
private boolean generateUnaryOp(JetPrefixExpression expression, DeclarationDescriptor op, Type asmType) {
|
||||
final JetExpression operand = expression.getBaseExpression();
|
||||
if (op.getName().equals("minus")) {
|
||||
gen(operand, asmType);
|
||||
v.neg(asmType);
|
||||
myStack.push(StackValue.onStack(asmType));
|
||||
return true;
|
||||
}
|
||||
else if (op.getName().equals("inc") || op.getName().equals("dec")) {
|
||||
if (!(operand instanceof JetReferenceExpression)) {
|
||||
throw new UnsupportedOperationException("cannot increment or decrement a non-lvalue");
|
||||
}
|
||||
int increment = op.getName().equals("inc") ? 1 : -1;
|
||||
final DeclarationDescriptor descriptor = bindingContext.resolveReferenceExpression((JetReferenceExpression) operand);
|
||||
final int index = myMap.getIndex(descriptor);
|
||||
if (index >= 0) {
|
||||
if (isIntPrimitive(asmType)) {
|
||||
v.iinc(index, increment);
|
||||
}
|
||||
else {
|
||||
gen(operand, asmType);
|
||||
if (asmType == Type.LONG_TYPE) {
|
||||
v.aconst(Long.valueOf(increment));
|
||||
}
|
||||
else if (asmType == Type.FLOAT_TYPE) {
|
||||
v.aconst(Float.valueOf(increment));
|
||||
}
|
||||
else if (asmType == Type.DOUBLE_TYPE) {
|
||||
v.aconst(Double.valueOf(increment));
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
v.add(asmType);
|
||||
v.store(index, asmType);
|
||||
}
|
||||
myStack.push(StackValue.local(index, asmType));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitProperty(JetProperty property) {
|
||||
PropertyDescriptor propertyDescriptor = bindingContext.getPropertyDescriptor(property);
|
||||
|
||||
@@ -25,7 +25,7 @@ public class FrameMap {
|
||||
}
|
||||
|
||||
public int getIndex(DeclarationDescriptor descriptor) {
|
||||
return myVarIndex.get(descriptor);
|
||||
return myVarIndex.contains(descriptor) ? myVarIndex.get(descriptor) : -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -342,6 +342,42 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
|
||||
assertEquals(-10, main.invoke(null, 10));
|
||||
}
|
||||
|
||||
public void testPreIncrement() throws Exception {
|
||||
loadText("fun foo(a: Int): Int { var x = a; ++x; return x;");
|
||||
final Method main = generateFunction();
|
||||
assertEquals(11, main.invoke(null, 10));
|
||||
}
|
||||
|
||||
public void testPreIncrementValue() throws Exception {
|
||||
loadText("fun foo(a: Int): Int { var x = a; return ++x;");
|
||||
final Method main = generateFunction();
|
||||
assertEquals(11, main.invoke(null, 10));
|
||||
}
|
||||
|
||||
public void testPreDecrement() throws Exception {
|
||||
loadText("fun foo(a: Int): Int { return --a;");
|
||||
final Method main = generateFunction();
|
||||
assertEquals(9, main.invoke(null, 10));
|
||||
}
|
||||
|
||||
public void testPreIncrementLong() throws Exception {
|
||||
loadText("fun foo(a: Long): Long = ++a");
|
||||
final Method main = generateFunction();
|
||||
assertEquals(11L, main.invoke(null, 10L));
|
||||
}
|
||||
|
||||
public void testPreIncrementFloat() throws Exception {
|
||||
loadText("fun foo(a: Float): Float = ++a");
|
||||
final Method main = generateFunction();
|
||||
assertEquals(2.0f, main.invoke(null, 1.0f));
|
||||
}
|
||||
|
||||
public void testPreIncrementDouble() throws Exception {
|
||||
loadText("fun foo(a: Double): Double = ++a");
|
||||
final Method main = generateFunction();
|
||||
assertEquals(2.0, main.invoke(null, 1.0));
|
||||
}
|
||||
|
||||
private void binOpTest(final String text, final Object arg1, final Object arg2, final Object expected) throws Exception {
|
||||
loadText(text);
|
||||
System.out.println(generateToText());
|
||||
|
||||
Reference in New Issue
Block a user