diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index b8144652ee8..8447375e0ad 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -119,10 +119,9 @@ public class ExpressionCodegen extends JetVisitor { myLoopEnds.push(end); gen(expression.getCondition()); - unboxBoolean(); - v.ifeq(end); + myStack.pop().condJump(end, true, v); - genToUnit(expression.getBody()); + gen(expression.getBody(), Type.VOID_TYPE); v.goTo(condition); v.mark(end); @@ -139,7 +138,7 @@ public class ExpressionCodegen extends JetVisitor { Label end = new Label(); myLoopEnds.push(end); - genToUnit(expression.getBody()); + gen(expression.getBody(), Type.VOID_TYPE); gen(expression.getCondition()); unboxBoolean(); @@ -178,19 +177,11 @@ public class ExpressionCodegen extends JetVisitor { myStack.pop().condJump(endLabel, inverse, v); - genToUnit(expression); + gen(expression, Type.VOID_TYPE); v.mark(endLabel); } - private void genToUnit(JetExpression expression) { - gen(expression); - - if (!isUnitType(expression)) { - v.pop(); - } - } - @Override public void visitConstantExpression(JetConstantExpression expression) { myStack.push(StackValue.constant(expression.getValue())); @@ -227,10 +218,24 @@ public class ExpressionCodegen extends JetVisitor { @Override public void visitBlockExpression(JetBlockExpression expression) { + List statements = expression.getStatements(); + generateBlock(statements); + } + + @Override + public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) { + if (bindingContext.isBlock(expression)) { + generateBlock(expression.getBody()); + } + else { + throw new UnsupportedOperationException("don't know how to generate non-block function literals"); + } + } + + private void generateBlock(List statements) { Label blockStart = new Label(); v.mark(blockStart); - List statements = expression.getStatements(); for (JetElement statement : statements) { if (statement instanceof JetProperty) { myMap.enter(bindingContext.getPropertyDescriptor((JetProperty) statement)); @@ -254,7 +259,6 @@ public class ExpressionCodegen extends JetVisitor { v.visitLocalVariable(var.getName(), outType.getDescriptor(), null, blockStart, blockEnd, index); } } - } @Override @@ -464,6 +468,9 @@ public class ExpressionCodegen extends JetVisitor { 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()); } @@ -508,10 +515,6 @@ public class ExpressionCodegen extends JetVisitor { } } - private boolean isUnitType(JetExpression e) { - return false; // TODO:!!! - } - @Override public void visitProperty(JetProperty property) { PropertyDescriptor propertyDescriptor = bindingContext.getPropertyDescriptor(property); diff --git a/idea/src/org/jetbrains/jet/codegen/StackValue.java b/idea/src/org/jetbrains/jet/codegen/StackValue.java index ed881593f5c..ddf5582a1fd 100644 --- a/idea/src/org/jetbrains/jet/codegen/StackValue.java +++ b/idea/src/org/jetbrains/jet/codegen/StackValue.java @@ -123,6 +123,12 @@ public abstract class StackValue { if (opToken == JetTokens.GT) { opcode = inverse ? Opcodes.IF_ICMPLE : Opcodes.IF_ICMPGT; } + else if (opToken == JetTokens.LT) { + opcode = inverse ? Opcodes.IF_ICMPGE : Opcodes.IF_ICMPLT; + } + else if (opToken == JetTokens.LTEQ) { + opcode = inverse ? Opcodes.IF_ICMPGT : Opcodes.IF_ICMPLE; + } else { throw new UnsupportedOperationException("don't know how to generate this condjump"); } diff --git a/idea/testData/codegen/doWhile.jet b/idea/testData/codegen/doWhile.jet new file mode 100644 index 00000000000..1ffc78729ef --- /dev/null +++ b/idea/testData/codegen/doWhile.jet @@ -0,0 +1,9 @@ +fun fac(i: Int): Int { + var count = 1; + var result = 1; + do { + count = count + 1; + result = result * count; + } while(count != i); + return result; +} diff --git a/idea/testData/codegen/while.jet b/idea/testData/codegen/while.jet index e69de29bb2d..1324c79c0b9 100644 --- a/idea/testData/codegen/while.jet +++ b/idea/testData/codegen/while.jet @@ -0,0 +1,9 @@ +fun fac(i: Int): Int { + var count = 1; + var result = 1; + while(count < i) { + count = count + 1; + result = result * count; + } + 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 f7d9e8bb924..e63f177cca8 100644 --- a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java @@ -12,6 +12,7 @@ import org.objectweb.asm.util.TraceClassVisitor; import java.io.PrintWriter; import java.io.StringWriter; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** @@ -141,6 +142,23 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase { assertEquals(false, main.invoke(null, 0)); } + public void testWhile() throws Exception { + factorialTest("while.jet"); + } + + public void testDoWhile() throws Exception { + factorialTest("doWhile.jet"); + } + + private void factorialTest(final String name) throws IllegalAccessException, InvocationTargetException { + loadFile(name); + + System.out.println(generateToText()); + final Method main = generateFunction(); + assertEquals(6, main.invoke(null, 3)); + assertEquals(120, main.invoke(null, 5)); + } + private void loadFile(final String name) { myFixture.configureByFile(JetParsingTest.getTestDataDir() + "/codegen/" + name); }