generate boolean not
This commit is contained in:
@@ -643,6 +643,10 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
if (isNumberPrimitive(cls)) {
|
||||
if (generateUnaryOp(op, asmType, expression.getBaseExpression())) return;
|
||||
}
|
||||
else if (isClass(cls, "Boolean") && op.getName().equals("not")) {
|
||||
generateNot(expression);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException("Don't know how to generate this prefix expression");
|
||||
}
|
||||
@@ -680,6 +684,13 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void generateNot(JetPrefixExpression expression) {
|
||||
int oldStackSize = myStack.size();
|
||||
gen(expression.getBaseExpression());
|
||||
assert myStack.size() == oldStackSize+1;
|
||||
myStack.set(myStack.size()-1, StackValue.not(myStack.get(myStack.size() - 1)));
|
||||
}
|
||||
|
||||
private int generateIncrement(DeclarationDescriptor op, Type asmType, JetExpression operand) {
|
||||
if (!(operand instanceof JetReferenceExpression)) {
|
||||
throw new UnsupportedOperationException("cannot increment or decrement a non-lvalue");
|
||||
|
||||
@@ -36,6 +36,10 @@ public abstract class StackValue {
|
||||
return new NumberCompare(opToken);
|
||||
}
|
||||
|
||||
public static StackValue not(StackValue stackValue) {
|
||||
return new Invert(stackValue);
|
||||
}
|
||||
|
||||
public abstract void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v);
|
||||
|
||||
private static void box(final Type type, InstructionAdapter v) {
|
||||
@@ -74,6 +78,17 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
protected void putAsBoolean(InstructionAdapter v) {
|
||||
Label ifTrue = new Label();
|
||||
Label end = new Label();
|
||||
condJump(ifTrue, false, v);
|
||||
v.iconst(0);
|
||||
v.goTo(end);
|
||||
v.mark(ifTrue);
|
||||
v.iconst(1);
|
||||
v.mark(end);
|
||||
}
|
||||
|
||||
public static class Local extends StackValue {
|
||||
private final int index;
|
||||
|
||||
@@ -168,14 +183,7 @@ public abstract class StackValue {
|
||||
if (type != Type.BOOLEAN_TYPE) {
|
||||
throw new UnsupportedOperationException("don't know how to put a compare as a non-boolean type");
|
||||
}
|
||||
Label ifTrue = new Label();
|
||||
Label end = new Label();
|
||||
condJump(ifTrue, false, v);
|
||||
v.iconst(0);
|
||||
v.goTo(end);
|
||||
v.mark(ifTrue);
|
||||
v.iconst(1);
|
||||
v.mark(end);
|
||||
putAsBoolean(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -219,4 +227,26 @@ public abstract class StackValue {
|
||||
v.visitJumpInsn(opcode, label);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Invert extends StackValue {
|
||||
private StackValue myOperand;
|
||||
|
||||
private Invert(StackValue operand) {
|
||||
super(operand.type);
|
||||
myOperand = operand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
if (type != Type.BOOLEAN_TYPE) {
|
||||
throw new UnsupportedOperationException("don't know how to put a compare as a non-boolean type");
|
||||
}
|
||||
putAsBoolean(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) {
|
||||
myOperand.condJump(label, !jumpIfFalse, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -437,6 +437,20 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
|
||||
assertEquals(6L, main.invoke(null, 2L));
|
||||
}
|
||||
|
||||
public void testBooleanNot() throws Exception {
|
||||
loadText("fun foo(b: Boolean): Boolean = !b");
|
||||
final Method main = generateFunction();
|
||||
assertEquals(true, main.invoke(null, false));
|
||||
assertEquals(false, main.invoke(null, true));
|
||||
}
|
||||
|
||||
public void testBooleanNotJump() throws Exception {
|
||||
loadText("fun foo(a: Int) : Int = if (!(a < 5)) a else 0");
|
||||
final Method main = generateFunction();
|
||||
assertEquals(6, main.invoke(null, 6));
|
||||
assertEquals(0, main.invoke(null, 4));
|
||||
}
|
||||
|
||||
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