diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index cd4fb136c48..d7b61afc830 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -546,6 +546,12 @@ public class ExpressionCodegen extends JetVisitor { if (name.equals("times")) return Opcodes.IMUL; if (name.equals("div")) return Opcodes.IDIV; if (name.equals("mod")) return Opcodes.IREM; + if (name.equals("shl")) return Opcodes.ISHL; + if (name.equals("shr")) return Opcodes.ISHR; + if (name.equals("ushr")) return Opcodes.IUSHR; + if (name.equals("and")) return Opcodes.IAND; + if (name.equals("or")) return Opcodes.IOR; + if (name.equals("xor")) return Opcodes.IXOR; throw new UnsupportedOperationException("Don't know how to generate binary op method " + name); } @@ -606,6 +612,13 @@ public class ExpressionCodegen extends JetVisitor { myStack.push(StackValue.onStack(asmType)); return true; } + else if (op.getName().equals("inv")) { + gen(operand, asmType); + v.aconst(-1); + v.xor(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"); diff --git a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java index 957c3cc6a64..8c89c63b3d8 100644 --- a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java @@ -378,6 +378,32 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase { assertEquals(2.0, main.invoke(null, 1.0)); } + public void testShl() throws Exception { + binOpTest("fun foo(a: Int, b: Int): Int = a shl b", 1, 3, 8); + } + + public void testShr() throws Exception { + binOpTest("fun foo(a: Int, b: Int): Int = a shr b", 8, 3, 1); + } + + public void testBitAnd() throws Exception { + binOpTest("fun foo(a: Int, b: Int): Int = a and b", 0x77, 0x1f, 0x17); + } + + public void testBitOr() throws Exception { + binOpTest("fun foo(a: Int, b: Int): Int = a or b", 0x77, 0x1f, 0x7f); + } + + public void testBitXor() throws Exception { + binOpTest("fun foo(a: Int, b: Int): Int = a xor b", 0x70, 0x1f, 0x6f); + } + + public void _testBitInv() throws Exception { + loadText("fun foo(a: Int): Int = ~a"); + final Method main = generateFunction(); + assertEquals(0xffff0000, main.invoke(null, 0x0000ffff)); + } + private void binOpTest(final String text, final Object arg1, final Object arg2, final Object expected) throws Exception { loadText(text); System.out.println(generateToText());