diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 8447375e0ad..ee56cc8c2ad 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -459,24 +459,30 @@ public class ExpressionCodegen extends JetVisitor { DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationReference()); if (op instanceof FunctionDescriptor) { DeclarationDescriptor cls = op.getContainingDeclaration(); - if (cls instanceof ClassDescriptor && cls.getName().equals("Int")) { - if (op.getName().equals("compareTo")) { - generateCompareOp(expression, opToken); - } - else { - int opcode; - if (op.getName().equals("plus")) { - opcode = Opcodes.IADD; - } - else if (op.getName().equals("times")) { - opcode = Opcodes.IMUL; + if (cls instanceof ClassDescriptor) { + final String className = cls.getName(); + if (className.equals("Int")) { + if (op.getName().equals("compareTo")) { + generateCompareOp(expression, opToken); } else { - throw new UnsupportedOperationException("Don't know how to generate binary op method " + op.getName()); + int opcode; + if (op.getName().equals("plus")) { + opcode = Opcodes.IADD; + } + else if (op.getName().equals("times")) { + opcode = Opcodes.IMUL; + } + else { + throw new UnsupportedOperationException("Don't know how to generate binary op method " + op.getName()); + } + generateBinaryOp(expression, (FunctionDescriptor) op, opcode); } - generateBinaryOp(expression, (FunctionDescriptor) op, opcode); + return; + } + else { + throw new UnsupportedOperationException("Don't know how to generate binary op for class " + className); } - return; } } throw new UnsupportedOperationException("Don't know how to generate binary op " + expression); diff --git a/idea/src/org/jetbrains/jet/codegen/StackValue.java b/idea/src/org/jetbrains/jet/codegen/StackValue.java index ddf5582a1fd..e7cb625ca02 100644 --- a/idea/src/org/jetbrains/jet/codegen/StackValue.java +++ b/idea/src/org/jetbrains/jet/codegen/StackValue.java @@ -30,7 +30,7 @@ public abstract class StackValue { return new IntCompare(opToken); } - public abstract void condJump(Label label, boolean inverse, InstructionAdapter v); + public abstract void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v); public static class Local extends StackValue { private final int index; @@ -48,9 +48,9 @@ public abstract class StackValue { } @Override - public void condJump(Label label, boolean inverse, InstructionAdapter v) { + public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) { put(Type.INT_TYPE, v); - if (inverse) { + if (jumpIfFalse) { v.ifeq(label); } else { @@ -71,7 +71,7 @@ public abstract class StackValue { } @Override - public void condJump(Label label, boolean inverse, InstructionAdapter v) { + public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) { throw new UnsupportedOperationException("don't know how to generate this condjump"); } } @@ -100,8 +100,16 @@ public abstract class StackValue { } @Override - public void condJump(Label label, boolean inverse, InstructionAdapter v) { - throw new UnsupportedOperationException("don't know how to generate this condjump"); + public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) { + if (value instanceof Boolean) { + boolean boolValue = ((Boolean) value).booleanValue(); + if (boolValue ^ jumpIfFalse) { + v.goTo(label); + } + } + else { + throw new UnsupportedOperationException("don't know how to generate this condjump"); + } } } @@ -118,16 +126,16 @@ public abstract class StackValue { } @Override - public void condJump(Label label, boolean inverse, InstructionAdapter v) { + public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) { int opcode; if (opToken == JetTokens.GT) { - opcode = inverse ? Opcodes.IF_ICMPLE : Opcodes.IF_ICMPGT; + opcode = jumpIfFalse ? Opcodes.IF_ICMPLE : Opcodes.IF_ICMPGT; } else if (opToken == JetTokens.LT) { - opcode = inverse ? Opcodes.IF_ICMPGE : Opcodes.IF_ICMPLT; + opcode = jumpIfFalse ? Opcodes.IF_ICMPGE : Opcodes.IF_ICMPLT; } else if (opToken == JetTokens.LTEQ) { - opcode = inverse ? Opcodes.IF_ICMPGT : Opcodes.IF_ICMPLE; + opcode = jumpIfFalse ? Opcodes.IF_ICMPGT : Opcodes.IF_ICMPLE; } else { throw new UnsupportedOperationException("don't know how to generate this condjump"); diff --git a/idea/testData/codegen/break.jet b/idea/testData/codegen/break.jet new file mode 100644 index 00000000000..c2b0073d4e4 --- /dev/null +++ b/idea/testData/codegen/break.jet @@ -0,0 +1,10 @@ +fun fac(i: Int): Int { + var count = 1; + var result = 1; + while(true) { + count = count + 1; + result = result * count; + if (count == i) break; + } + return result; +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java index e63f177cca8..05912f28602 100644 --- a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java @@ -150,6 +150,10 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase { factorialTest("doWhile.jet"); } + public void testBreak() throws Exception { + factorialTest("break.jet"); + } + private void factorialTest(final String name) throws IllegalAccessException, InvocationTargetException { loadFile(name);