rangeTo is an intrinsic

This commit is contained in:
Dmitry Jemerov
2011-07-14 18:55:09 +02:00
parent e316989706
commit 0a9c626f21
4 changed files with 46 additions and 27 deletions
@@ -7,7 +7,6 @@ import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import gnu.trove.THashSet;
import jet.IntRange;
import jet.Range;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod;
@@ -41,14 +40,12 @@ public class ExpressionCodegen extends JetVisitor {
private static final String CLASS_ITERATOR = "java/util/Iterator";
private static final String CLASS_RANGE = "jet/Range";
private static final String CLASS_INT_RANGE = "jet/IntRange";
private static final String CLASS_NO_PATTERN_MATCHED_EXCEPTION = "jet/NoPatternMatchedException";
private static final String CLASS_TYPE_CAST_EXCEPTION = "jet/TypeCastException";
private static final String ITERABLE_ITERATOR_DESCRIPTOR = "()Ljava/util/Iterator;";
private static final String ITERATOR_HASNEXT_DESCRIPTOR = "()Z";
private static final String ITERATOR_NEXT_DESCRIPTOR = "()Ljava/lang/Object;";
private static final String INT_RANGE_CONSTRUCTOR_DESCRIPTOR = "(II)V";
private static final Type OBJECT_TYPE = Type.getType(Object.class);
private static final Type INTEGER_TYPE = Type.getType(Integer.class);
@@ -57,7 +54,6 @@ public class ExpressionCodegen extends JetVisitor {
private static final Type STRING_TYPE = Type.getObjectType(CLASS_STRING);
private static final Type RANGE_TYPE = Type.getType(Range.class);
private static final Type INT_RANGE_TYPE = Type.getType(IntRange.class);
private final Stack<Label> myContinueTargets = new Stack<Label>();
private final Stack<Label> myBreakTargets = new Stack<Label>();
@@ -1003,7 +999,7 @@ public class ExpressionCodegen extends JetVisitor {
}
}
private Type expressionType(JetExpression expr) {
public Type expressionType(JetExpression expr) {
return typeMapper.mapType(bindingContext.getExpressionType(expr));
}
@@ -1092,9 +1088,6 @@ public class ExpressionCodegen extends JetVisitor {
else if (opToken == JetTokens.ELVIS) {
generateElvis(expression);
}
else if (opToken == JetTokens.RANGE) {
generateRange(expression);
}
else {
DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationReference());
if (op instanceof FunctionDescriptor) {
@@ -1212,21 +1205,6 @@ public class ExpressionCodegen extends JetVisitor {
myStack.push(StackValue.onStack(exprType));
}
private void generateRange(JetBinaryExpression expression) {
final Type leftType = expressionType(expression.getLeft());
if (JetTypeMapper.isIntPrimitive(leftType)) {
v.anew(INT_RANGE_TYPE);
v.dup();
gen(expression.getLeft(), Type.INT_TYPE);
gen(expression.getRight(), Type.INT_TYPE);
v.invokespecial(CLASS_INT_RANGE, "<init>", INT_RANGE_CONSTRUCTOR_DESCRIPTOR);
myStack.push(StackValue.onStack(INT_RANGE_TYPE));
}
else {
throw new UnsupportedOperationException("ranges are only supported for int objects");
}
}
private static boolean isNumberPrimitive(DeclarationDescriptor descriptor) {
if (!(descriptor instanceof ClassDescriptor)) {
return false;
@@ -43,7 +43,7 @@ public class JetTypeMapper {
return qName.replace(".", "/");
}
static boolean isIntPrimitive(Type type) {
public static boolean isIntPrimitive(Type type) {
return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE;
}
@@ -24,6 +24,7 @@ public class IntrinsicMethods {
private static final IntrinsicMethod INV = new Inv();
private static final IntrinsicMethod TYPEINFO = new TypeInfo();
private static final IntrinsicMethod VALUE_TYPEINFO = new ValueTypeInfo();
private static final IntrinsicMethod RANGE_TO = new RangeTo();
private static final List<String> PRIMITIVE_NUMBER_TYPES = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double");
@@ -40,9 +41,10 @@ public class IntrinsicMethods {
}
declareIntrinsicProperty("Array", "size", new ArraySize());
for (String primitiveNumberType : PRIMITIVE_NUMBER_TYPES) {
declareIntrinsicFunction(primitiveNumberType, "minus", 0, UNARY_MINUS);
declareIntrinsicFunction(primitiveNumberType, "inv", 0, INV);
for (String type : PRIMITIVE_NUMBER_TYPES) {
declareIntrinsicFunction(type, "minus", 0, UNARY_MINUS);
declareIntrinsicFunction(type, "inv", 0, INV);
declareIntrinsicFunction(type, "rangeTo", 1, RANGE_TO);
}
final FunctionGroup typeInfoFunctionGroup = stdlib.getTypeInfoFunctionGroup();
@@ -0,0 +1,39 @@
package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import jet.IntRange;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
/**
* @author yole
*/
public class RangeTo implements IntrinsicMethod {
private static final String INT_RANGE_CONSTRUCTOR_DESCRIPTOR = "(II)V";
private static final Type INT_RANGE_TYPE = Type.getType(IntRange.class);
private static final String CLASS_INT_RANGE = "jet/IntRange";
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, boolean haveReceiver) {
JetBinaryExpression expression = (JetBinaryExpression) element;
final Type leftType = codegen.expressionType(expression.getLeft());
if (JetTypeMapper.isIntPrimitive(leftType)) {
v.anew(INT_RANGE_TYPE);
v.dup();
codegen.gen(expression.getLeft(), Type.INT_TYPE);
codegen.gen(expression.getRight(), Type.INT_TYPE);
v.invokespecial(CLASS_INT_RANGE, "<init>", INT_RANGE_CONSTRUCTOR_DESCRIPTOR);
return StackValue.onStack(INT_RANGE_TYPE);
}
else {
throw new UnsupportedOperationException("ranges are only supported for int objects");
}
}
}