Float
This commit is contained in:
@@ -468,13 +468,14 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
}
|
}
|
||||||
DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationReference());
|
DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationReference());
|
||||||
if (op instanceof FunctionDescriptor) {
|
if (op instanceof FunctionDescriptor) {
|
||||||
|
JetType returnType = bindingContext.getExpressionType(expression);
|
||||||
|
final Type asmType = typeMapper.mapType(returnType);
|
||||||
DeclarationDescriptor cls = op.getContainingDeclaration();
|
DeclarationDescriptor cls = op.getContainingDeclaration();
|
||||||
if (cls instanceof ClassDescriptor) {
|
if (cls instanceof ClassDescriptor) {
|
||||||
final String className = cls.getName();
|
final String className = cls.getName();
|
||||||
if (className.equals("Int") || className.equals("Long") || className.equals("Short") ||
|
if (isNumberPrimitive(className)) {
|
||||||
className.equals("Byte") || className.equals("Char")) {
|
|
||||||
if (op.getName().equals("compareTo")) {
|
if (op.getName().equals("compareTo")) {
|
||||||
generateCompareOp(expression, opToken);
|
generateCompareOp(expression, opToken, asmType);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int opcode = opcodeForMethod(op.getName());
|
int opcode = opcodeForMethod(op.getName());
|
||||||
@@ -486,10 +487,8 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
if (op.getName().equals("equals")) {
|
if (op.getName().equals("equals")) {
|
||||||
final Type leftType = typeMapper.mapType(bindingContext.getExpressionType(expression.getLeft()));
|
final Type leftType = typeMapper.mapType(bindingContext.getExpressionType(expression.getLeft()));
|
||||||
final Type rightType = typeMapper.mapType(bindingContext.getExpressionType(expression.getRight()));
|
final Type rightType = typeMapper.mapType(bindingContext.getExpressionType(expression.getRight()));
|
||||||
if (isIntLikePrimitive(leftType) && isIntLikePrimitive(rightType)) {
|
if (isNumberPrimitive(leftType) && leftType == rightType) {
|
||||||
gen(expression.getLeft(), Type.INT_TYPE);
|
generateCompareOp(expression, opToken, leftType);
|
||||||
gen(expression.getRight(), Type.INT_TYPE);
|
|
||||||
myStack.push(StackValue.icmp(opToken));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -505,8 +504,14 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
throw new UnsupportedOperationException("Don't know how to generate binary op " + expression);
|
throw new UnsupportedOperationException("Don't know how to generate binary op " + expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isIntLikePrimitive(Type type) {
|
private static boolean isNumberPrimitive(String className) {
|
||||||
return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE;
|
return className.equals("Int") || className.equals("Long") || className.equals("Short") ||
|
||||||
|
className.equals("Byte") || className.equals("Char") || className.equals("Float");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isNumberPrimitive(Type type) {
|
||||||
|
return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE ||
|
||||||
|
type == Type.FLOAT_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int opcodeForMethod(final String name) {
|
private static int opcodeForMethod(final String name) {
|
||||||
@@ -521,7 +526,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
private void generateBinaryOp(JetBinaryExpression expression, FunctionDescriptor op, int opcode) {
|
private void generateBinaryOp(JetBinaryExpression expression, FunctionDescriptor op, int opcode) {
|
||||||
JetType returnType = op.getUnsubstitutedReturnType();
|
JetType returnType = op.getUnsubstitutedReturnType();
|
||||||
final Type asmType = typeMapper.mapType(returnType);
|
final Type asmType = typeMapper.mapType(returnType);
|
||||||
if (asmType == Type.INT_TYPE || asmType == Type.LONG_TYPE) {
|
if (asmType == Type.INT_TYPE || asmType == Type.LONG_TYPE || asmType == Type.FLOAT_TYPE) {
|
||||||
gen(expression.getLeft(), asmType);
|
gen(expression.getLeft(), asmType);
|
||||||
gen(expression.getRight(), asmType);
|
gen(expression.getRight(), asmType);
|
||||||
v.visitInsn(asmType.getOpcode(opcode));
|
v.visitInsn(asmType.getOpcode(opcode));
|
||||||
@@ -532,10 +537,10 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateCompareOp(JetBinaryExpression expression, IElementType opToken) {
|
private void generateCompareOp(JetBinaryExpression expression, IElementType opToken, Type type) {
|
||||||
gen(expression.getLeft(), Type.INT_TYPE);
|
gen(expression.getLeft(), type);
|
||||||
gen(expression.getRight(), Type.INT_TYPE);
|
gen(expression.getRight(), type);
|
||||||
myStack.push(StackValue.icmp(opToken));
|
myStack.push(StackValue.cmp(opToken, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateAssignmentExpression(JetBinaryExpression expression) {
|
private void generateAssignmentExpression(JetBinaryExpression expression) {
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ public class JetTypeMapper {
|
|||||||
if (jetType.equals(standardLibrary.getCharType())) {
|
if (jetType.equals(standardLibrary.getCharType())) {
|
||||||
return Type.CHAR_TYPE;
|
return Type.CHAR_TYPE;
|
||||||
}
|
}
|
||||||
|
if (jetType.equals(standardLibrary.getFloatType())) {
|
||||||
|
return Type.FLOAT_TYPE;
|
||||||
|
}
|
||||||
if (jetType.equals(standardLibrary.getBooleanType())) {
|
if (jetType.equals(standardLibrary.getBooleanType())) {
|
||||||
return Type.BOOLEAN_TYPE;
|
return Type.BOOLEAN_TYPE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ public abstract class StackValue {
|
|||||||
return new Constant(value);
|
return new Constant(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StackValue icmp(IElementType opToken) {
|
public static StackValue cmp(IElementType opToken, Type type) {
|
||||||
return new IntCompare(opToken);
|
return new NumberCompare(opToken, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v);
|
public abstract void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v);
|
||||||
@@ -113,11 +113,13 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class IntCompare extends StackValue {
|
private static class NumberCompare extends StackValue {
|
||||||
private final IElementType opToken;
|
private final IElementType opToken;
|
||||||
|
private final Type type;
|
||||||
|
|
||||||
public IntCompare(IElementType opToken) {
|
public NumberCompare(IElementType opToken, Type type) {
|
||||||
this.opToken = opToken;
|
this.opToken = opToken;
|
||||||
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -136,26 +138,37 @@ public abstract class StackValue {
|
|||||||
public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) {
|
public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) {
|
||||||
int opcode;
|
int opcode;
|
||||||
if (opToken == JetTokens.EQEQ) {
|
if (opToken == JetTokens.EQEQ) {
|
||||||
opcode = jumpIfFalse ? Opcodes.IF_ICMPNE : Opcodes.IF_ICMPEQ;
|
opcode = jumpIfFalse ? Opcodes.IFNE : Opcodes.IFEQ;
|
||||||
}
|
}
|
||||||
else if (opToken == JetTokens.EXCLEQ) {
|
else if (opToken == JetTokens.EXCLEQ) {
|
||||||
opcode = jumpIfFalse ? Opcodes.IF_ICMPEQ : Opcodes.IF_ICMPNE;
|
opcode = jumpIfFalse ? Opcodes.IFEQ : Opcodes.IFNE;
|
||||||
}
|
}
|
||||||
else if (opToken == JetTokens.GT) {
|
else if (opToken == JetTokens.GT) {
|
||||||
opcode = jumpIfFalse ? Opcodes.IF_ICMPLE : Opcodes.IF_ICMPGT;
|
opcode = jumpIfFalse ? Opcodes.IFLE : Opcodes.IFGT;
|
||||||
}
|
}
|
||||||
else if (opToken == JetTokens.GTEQ) {
|
else if (opToken == JetTokens.GTEQ) {
|
||||||
opcode = jumpIfFalse ? Opcodes.IF_ICMPLT : Opcodes.IF_ICMPGE;
|
opcode = jumpIfFalse ? Opcodes.IFLT : Opcodes.IFGE;
|
||||||
}
|
}
|
||||||
else if (opToken == JetTokens.LT) {
|
else if (opToken == JetTokens.LT) {
|
||||||
opcode = jumpIfFalse ? Opcodes.IF_ICMPGE : Opcodes.IF_ICMPLT;
|
opcode = jumpIfFalse ? Opcodes.IFGE : Opcodes.IFLT;
|
||||||
}
|
}
|
||||||
else if (opToken == JetTokens.LTEQ) {
|
else if (opToken == JetTokens.LTEQ) {
|
||||||
opcode = jumpIfFalse ? Opcodes.IF_ICMPGT : Opcodes.IF_ICMPLE;
|
opcode = jumpIfFalse ? Opcodes.IFGT : Opcodes.IFLE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new UnsupportedOperationException("don't know how to generate this condjump");
|
throw new UnsupportedOperationException("don't know how to generate this condjump");
|
||||||
}
|
}
|
||||||
|
if (type == Type.FLOAT_TYPE) {
|
||||||
|
if (opToken == JetTokens.GT || opToken == JetTokens.GTEQ) {
|
||||||
|
v.cmpg(type);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
v.cmpl(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
opcode += (Opcodes.IF_ICMPEQ - Opcodes.IFEQ);
|
||||||
|
}
|
||||||
v.visitJumpInsn(opcode, label);
|
v.visitJumpInsn(opcode, label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -279,6 +279,14 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
|
|||||||
binOpTest("fun foo(a: Char, b: Char): Int = a + b", 'A', (char) 3, (int) 'D');
|
binOpTest("fun foo(a: Char, b: Char): Int = a + b", 'A', (char) 3, (int) 'D');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testFloat() throws Exception {
|
||||||
|
binOpTest("fun foo(a: Float, b: Float): Float = a + b", 1.0f, 2.0f, 3.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFloatCmp() throws Exception {
|
||||||
|
binOpTest("fun foo(a: Float, b: Float): Boolean = a == b", 1.0f, 1.0f, true);
|
||||||
|
}
|
||||||
|
|
||||||
private void binOpTest(final String text, final Object arg1, final Object arg2, final Object expected) throws Exception {
|
private void binOpTest(final String text, final Object arg1, final Object arg2, final Object expected) throws Exception {
|
||||||
loadText(text);
|
loadText(text);
|
||||||
System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
|
|||||||
Reference in New Issue
Block a user