提交 6c1bda7f 编写于 作者: D Dmitry Jemerov

generate boolean not

上级 5bebb848
......@@ -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());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册