diff --git a/.idea/projectCodeStyle.xml b/.idea/projectCodeStyle.xml
index cdd7d881640..43813395c7f 100644
--- a/.idea/projectCodeStyle.xml
+++ b/.idea/projectCodeStyle.xml
@@ -127,6 +127,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
index dc54bafc9cf..b8144652ee8 100644
--- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
+++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
@@ -1,6 +1,7 @@
package org.jetbrains.jet.codegen;
import com.intellij.psi.*;
+import com.intellij.psi.tree.IElementType;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.*;
@@ -72,7 +73,9 @@ public class ExpressionCodegen extends JetVisitor {
public void visitIfExpression(JetIfExpression expression) {
JetType expressionType = bindingContext.getExpressionType(expression);
Type asmType = typeMapper.mapType(expressionType);
- gen(expression.getCondition(), Type.BOOLEAN_TYPE);
+ int oldStackDepth = myStack.size();
+ gen(expression.getCondition());
+ assert myStack.size() == oldStackDepth+1;
JetExpression thenExpression = expression.getThen();
JetExpression elseExpression = expression.getElse();
@@ -93,7 +96,7 @@ public class ExpressionCodegen extends JetVisitor {
Label elseLabel = new Label();
- v.ifeq(elseLabel); // == 0, i.e. false
+ myStack.pop().condJump(elseLabel, true, v); // == 0, i.e. false
gen(thenExpression, asmType);
@@ -173,12 +176,7 @@ public class ExpressionCodegen extends JetVisitor {
private void generateSingleBranchIf(JetExpression expression, boolean inverse) {
Label endLabel = new Label();
- if (inverse) {
- v.ifeq(endLabel);
- }
- else {
- v.ifne(endLabel);
- }
+ myStack.pop().condJump(endLabel, inverse, v);
genToUnit(expression);
@@ -449,7 +447,8 @@ public class ExpressionCodegen extends JetVisitor {
@Override
public void visitBinaryExpression(JetBinaryExpression expression) {
- if (expression.getOperationReference().getReferencedNameElementType() == JetTokens.EQ) {
+ final IElementType opToken = expression.getOperationReference().getReferencedNameElementType();
+ if (opToken == JetTokens.EQ) {
generateAssignmentExpression(expression);
return;
}
@@ -457,21 +456,44 @@ public class ExpressionCodegen extends JetVisitor {
if (op instanceof FunctionDescriptor) {
DeclarationDescriptor cls = op.getContainingDeclaration();
if (cls instanceof ClassDescriptor && cls.getName().equals("Int")) {
- if (op.getName().equals("plus")) {
- JetType returnType = ((FunctionDescriptor) op).getUnsubstitutedReturnType();
- if (returnType.equals(stdlib.getIntType())) {
- gen(expression.getLeft(), Type.INT_TYPE);
- gen(expression.getRight(), Type.INT_TYPE);
- v.add(Type.INT_TYPE);
- myStack.push(StackValue.onStack(Type.INT_TYPE));
- return;
- }
+ if (op.getName().equals("compareTo")) {
+ generateCompareOp(expression, opToken);
}
+ else {
+ int opcode;
+ if (op.getName().equals("plus")) {
+ opcode = Opcodes.IADD;
+ }
+ else {
+ throw new UnsupportedOperationException("Don't know how to generate binary op method " + op.getName());
+ }
+ generateBinaryOp(expression, (FunctionDescriptor) op, opcode);
+ }
+ return;
}
}
throw new UnsupportedOperationException("Don't know how to generate binary op " + expression);
}
+ private void generateBinaryOp(JetBinaryExpression expression, FunctionDescriptor op, int opcode) {
+ JetType returnType = op.getUnsubstitutedReturnType();
+ if (returnType.equals(stdlib.getIntType())) {
+ gen(expression.getLeft(), Type.INT_TYPE);
+ gen(expression.getRight(), Type.INT_TYPE);
+ v.visitInsn(Type.INT_TYPE.getOpcode(opcode));
+ myStack.push(StackValue.onStack(Type.INT_TYPE));
+ }
+ else {
+ throw new UnsupportedOperationException("Don't know how to generate binary op with return type " + returnType);
+ }
+ }
+
+ private void generateCompareOp(JetBinaryExpression expression, IElementType opToken) {
+ gen(expression.getLeft(), Type.INT_TYPE);
+ gen(expression.getRight(), Type.INT_TYPE);
+ myStack.push(StackValue.icmp(opToken));
+ }
+
private void generateAssignmentExpression(JetBinaryExpression expression) {
if (expression.getLeft() instanceof JetReferenceExpression) {
final JetReferenceExpression lhs = (JetReferenceExpression) expression.getLeft();
diff --git a/idea/src/org/jetbrains/jet/codegen/StackValue.java b/idea/src/org/jetbrains/jet/codegen/StackValue.java
index df855a340d7..ed881593f5c 100644
--- a/idea/src/org/jetbrains/jet/codegen/StackValue.java
+++ b/idea/src/org/jetbrains/jet/codegen/StackValue.java
@@ -1,6 +1,10 @@
package org.jetbrains.jet.codegen;
+import com.intellij.psi.tree.IElementType;
import org.jetbrains.jet.lang.types.JetType;
+import org.jetbrains.jet.lexer.JetTokens;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
@@ -22,6 +26,12 @@ public abstract class StackValue {
return new Constant(value);
}
+ public static StackValue icmp(IElementType opToken) {
+ return new IntCompare(opToken);
+ }
+
+ public abstract void condJump(Label label, boolean inverse, InstructionAdapter v);
+
public static class Local extends StackValue {
private final int index;
private final JetType type;
@@ -36,6 +46,17 @@ public abstract class StackValue {
v.load(index, type);
// TODO box/unbox
}
+
+ @Override
+ public void condJump(Label label, boolean inverse, InstructionAdapter v) {
+ put(Type.INT_TYPE, v);
+ if (inverse) {
+ v.ifeq(label);
+ }
+ else {
+ v.ifne(label);
+ }
+ }
}
public static class OnStack extends StackValue {
@@ -48,6 +69,11 @@ public abstract class StackValue {
@Override
public void put(Type type, InstructionAdapter v) {
}
+
+ @Override
+ public void condJump(Label label, boolean inverse, InstructionAdapter v) {
+ throw new UnsupportedOperationException("don't know how to generate this condjump");
+ }
}
public static class Constant extends StackValue {
@@ -72,5 +98,35 @@ public abstract class StackValue {
v.aconst(value);
}
}
+
+ @Override
+ public void condJump(Label label, boolean inverse, InstructionAdapter v) {
+ throw new UnsupportedOperationException("don't know how to generate this condjump");
+ }
+ }
+
+ private static class IntCompare extends StackValue {
+ private final IElementType opToken;
+
+ public IntCompare(IElementType opToken) {
+ this.opToken = opToken;
+ }
+
+ @Override
+ public void put(Type type, InstructionAdapter v) {
+ throw new UnsupportedOperationException("don't know how to put an IntCompare on stack");
+ }
+
+ @Override
+ public void condJump(Label label, boolean inverse, InstructionAdapter v) {
+ int opcode;
+ if (opToken == JetTokens.GT) {
+ opcode = inverse ? Opcodes.IF_ICMPLE : Opcodes.IF_ICMPGT;
+ }
+ else {
+ throw new UnsupportedOperationException("don't know how to generate this condjump");
+ }
+ v.visitJumpInsn(opcode, label);
+ }
}
}
diff --git a/idea/testData/codegen/gt.jet b/idea/testData/codegen/gt.jet
new file mode 100644
index 00000000000..c859ae89a38
--- /dev/null
+++ b/idea/testData/codegen/gt.jet
@@ -0,0 +1,4 @@
+fun foo(f: Int): Boolean {
+ if (f > 0) return true;
+ return false;
+}
diff --git a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java
index 5c7cae20435..f7d9e8bb924 100644
--- a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java
+++ b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java
@@ -132,6 +132,15 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
assertEquals(2, main.invoke(null));
}
+ public void testGt() throws Exception {
+ loadFile("gt.jet");
+
+ System.out.println(generateToText());
+ final Method main = generateFunction();
+ assertEquals(true, main.invoke(null, 1));
+ assertEquals(false, main.invoke(null, 0));
+ }
+
private void loadFile(final String name) {
myFixture.configureByFile(JetParsingTest.getTestDataDir() + "/codegen/" + name);
}