Merge remote branch 'origin/master'

This commit is contained in:
Andrey Breslav
2011-04-01 16:11:03 +04:00
5 changed files with 120 additions and 18 deletions
+11
View File
@@ -127,6 +127,17 @@
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<codeStyleSettings language="JavaScript">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="PHP">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
</value>
</option>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
@@ -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();
@@ -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);
}
}
}
+4
View File
@@ -0,0 +1,4 @@
fun foo(f: Int): Boolean {
if (f > 0) return true;
return false;
}
@@ -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);
}