generate boolean not
This commit is contained in:
@@ -643,6 +643,10 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
if (isNumberPrimitive(cls)) {
|
if (isNumberPrimitive(cls)) {
|
||||||
if (generateUnaryOp(op, asmType, expression.getBaseExpression())) return;
|
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");
|
throw new UnsupportedOperationException("Don't know how to generate this prefix expression");
|
||||||
}
|
}
|
||||||
@@ -680,6 +684,13 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
return false;
|
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) {
|
private int generateIncrement(DeclarationDescriptor op, Type asmType, JetExpression operand) {
|
||||||
if (!(operand instanceof JetReferenceExpression)) {
|
if (!(operand instanceof JetReferenceExpression)) {
|
||||||
throw new UnsupportedOperationException("cannot increment or decrement a non-lvalue");
|
throw new UnsupportedOperationException("cannot increment or decrement a non-lvalue");
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ public abstract class StackValue {
|
|||||||
return new NumberCompare(opToken);
|
return new NumberCompare(opToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static StackValue not(StackValue stackValue) {
|
||||||
|
return new Invert(stackValue);
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v);
|
public abstract void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v);
|
||||||
|
|
||||||
private static void box(final Type type, 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 {
|
public static class Local extends StackValue {
|
||||||
private final int index;
|
private final int index;
|
||||||
|
|
||||||
@@ -168,14 +183,7 @@ public abstract class StackValue {
|
|||||||
if (type != Type.BOOLEAN_TYPE) {
|
if (type != Type.BOOLEAN_TYPE) {
|
||||||
throw new UnsupportedOperationException("don't know how to put a compare as a non-boolean type");
|
throw new UnsupportedOperationException("don't know how to put a compare as a non-boolean type");
|
||||||
}
|
}
|
||||||
Label ifTrue = new Label();
|
putAsBoolean(v);
|
||||||
Label end = new Label();
|
|
||||||
condJump(ifTrue, false, v);
|
|
||||||
v.iconst(0);
|
|
||||||
v.goTo(end);
|
|
||||||
v.mark(ifTrue);
|
|
||||||
v.iconst(1);
|
|
||||||
v.mark(end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -219,4 +227,26 @@ public abstract class StackValue {
|
|||||||
v.visitJumpInsn(opcode, label);
|
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));
|
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 {
|
private void binOpTest(final String text, final Object arg1, final Object arg2, final Object expected) throws Exception {
|
||||||
loadText(text);
|
loadText(text);
|
||||||
System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
|
|||||||
Reference in New Issue
Block a user