array.indices

This commit is contained in:
Alex Tkachman
2011-10-08 16:26:49 +02:00
parent 78e913762f
commit e94087f41e
8 changed files with 246 additions and 47 deletions
@@ -58,6 +58,7 @@ public class JetTypeMapper {
private final HashMap<JetType,String> knowTypes = new HashMap<JetType, String>();
public static final Type TYPE_FUNCTION1 = Type.getObjectType("jet/Function1");
public static final Type TYPE_ITERATOR = Type.getObjectType("jet/Iterator");
public static final Type TYPE_INT_RANGE = Type.getObjectType("jet/IntRange");
public JetTypeMapper(JetStandardLibrary standardLibrary, BindingContext bindingContext) {
this.standardLibrary = standardLibrary;
@@ -0,0 +1,21 @@
package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
public class ArrayIndices implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
v.arraylength();
v.invokestatic("jet/IntRange", "count", "(I)Ljet/IntRange;");
return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE);
}
}
@@ -29,7 +29,8 @@ public class IntrinsicMethods {
private static final IntrinsicMethod DEC = new Increment(-1);
private static final List<String> PRIMITIVE_NUMBER_TYPES = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double");
public static final ArraySize ARRAY_SIZE = new ArraySize();
public static final IntrinsicMethod ARRAY_SIZE = new ArraySize();
public static final IntrinsicMethod ARRAY_INDICES = new ArrayIndices();
private final Project myProject;
private final JetStandardLibrary myStdLib;
@@ -89,15 +90,29 @@ public class IntrinsicMethods {
declareIntrinsicProperty("CharArray", "size", ARRAY_SIZE);
declareIntrinsicProperty("BooleanArray", "size", ARRAY_SIZE);
declareOverload(myStdLib.getArray().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
declareOverload(myStdLib.getByteArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
declareOverload(myStdLib.getShortArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
declareOverload(myStdLib.getIntArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
declareOverload(myStdLib.getLongArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
declareOverload(myStdLib.getFloatArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
declareOverload(myStdLib.getDoubleArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
declareOverload(myStdLib.getCharArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
declareOverload(myStdLib.getBooleanArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
declareIntrinsicProperty("Array", "indices", ARRAY_INDICES);
declareIntrinsicProperty("ByteArray", "indices", ARRAY_INDICES);
declareIntrinsicProperty("ShortArray", "indices", ARRAY_INDICES);
declareIntrinsicProperty("IntArray", "indices", ARRAY_INDICES);
declareIntrinsicProperty("LongArray", "indices", ARRAY_INDICES);
declareIntrinsicProperty("FloatArray", "indices", ARRAY_INDICES);
declareIntrinsicProperty("DoubleArray", "indices", ARRAY_INDICES);
declareIntrinsicProperty("CharArray", "indices", ARRAY_INDICES);
declareIntrinsicProperty("BooleanArray", "indices", ARRAY_INDICES);
declareIterator(myStdLib.getArray());
declareIterator(myStdLib.getByteArrayClass());
declareIterator(myStdLib.getShortArrayClass());
declareIterator(myStdLib.getIntArrayClass());
declareIterator(myStdLib.getLongArrayClass());
declareIterator(myStdLib.getFloatArrayClass());
declareIterator(myStdLib.getDoubleArrayClass());
declareIterator(myStdLib.getCharArrayClass());
declareIterator(myStdLib.getBooleanArrayClass());
}
private void declareIterator(ClassDescriptor classDescriptor) {
declareOverload(classDescriptor.getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
}
private void declareIntrinsicStringMethods() {
+52 -26
View File
@@ -54,6 +54,8 @@ class Array<T>(val size : Int, init : fun(Int) : T = null ) {
fun set(index : Int, value : T) : Unit
fun iterator() : Iterator<T>
val indices : IntRange
}
class ByteArray(val size : Int) {
@@ -61,6 +63,8 @@ class ByteArray(val size : Int) {
fun set(index : Int, value : Byte) : Unit
fun iterator() : Iterator<Byte>
val indices : IntRange
}
class ShortArray(val size : Int) {
@@ -68,6 +72,8 @@ class ShortArray(val size : Int) {
fun set(index : Int, value : Short) : Unit
fun iterator() : Iterator<Short>
val indices : IntRange
}
class IntArray(val size : Int) {
@@ -75,6 +81,8 @@ class IntArray(val size : Int) {
fun set(index : Int, value : Int) : Unit
fun iterator() : Iterator<Int>
val indices : IntRange
}
class LongArray(val size : Int) {
@@ -82,6 +90,8 @@ class LongArray(val size : Int) {
fun set(index : Int, value : Long) : Unit
fun iterator() : Iterator<Long>
val indices : IntRange
}
class FloatArray(val size : Int) {
@@ -89,6 +99,8 @@ class FloatArray(val size : Int) {
fun set(index : Int, value : Float) : Unit
fun iterator() : Iterator<Float>
val indices : IntRange
}
class DoubleArray(val size : Int) {
@@ -96,6 +108,8 @@ class DoubleArray(val size : Int) {
fun set(index : Int, value : Double) : Unit
fun iterator() : Iterator<Double>
val indices : IntRange
}
class CharArray(val size : Int) {
@@ -103,6 +117,8 @@ class CharArray(val size : Int) {
fun set(index : Int, value : Char) : Unit
fun iterator() : Iterator<Char>
val indices : IntRange
}
class BooleanArray(val size : Int) {
@@ -110,6 +126,8 @@ class BooleanArray(val size : Int) {
fun set(index : Int, value : Boolean) : Unit
fun iterator() : Iterator<Boolean>
val indices : IntRange
}
trait Comparable<in T> {
@@ -152,8 +170,16 @@ trait Range<in T : Comparable<T>> {
fun contains(item : T) : Boolean
}
class IntRange<T : Comparable<T>>(val start : Int, val end : Int) : Range<T>, Iterable<T> {
class IntRange(val start : Int, val excludedEnd : Int) : Range<Int>, Iterable<Int> {
fun iterator () : Iterator<Int>
fun contains (elem: Int) : Boolean
}
class LongRange(val start : Long, val end : Long) : Range<Long>, Iterable<Long> {
fun iterator () : Iterator<Long>
fun contains (elem: Long) : Boolean
}
abstract class Number : Hashable {
@@ -349,11 +375,11 @@ class Long : Number, Comparable<Long> {
fun rangeTo(other : Double) : Range<Double>
fun rangeTo(other : Float) : Range<Double>
fun rangeTo(other : Long) : IntRange<Long>
fun rangeTo(other : Int) : IntRange<Long>
fun rangeTo(other : Short) : IntRange<Long>
fun rangeTo(other : Byte) : IntRange<Long>
fun rangeTo(other : Char) : IntRange<Long>
fun rangeTo(other : Long) : LongRange
fun rangeTo(other : Int) : LongRange
fun rangeTo(other : Short) : LongRange
fun rangeTo(other : Byte) : LongRange
fun rangeTo(other : Char) : LongRange
fun inc() : Long
fun dec() : Long
@@ -420,11 +446,11 @@ class Int : Number, Comparable<Int> {
fun rangeTo(other : Double) : Range<Double>
fun rangeTo(other : Float) : Range<Double>
fun rangeTo(other : Long) : IntRange<Long>
fun rangeTo(other : Int) : IntRange<Int>
fun rangeTo(other : Short) : IntRange<Int>
fun rangeTo(other : Byte) : IntRange<Int>
fun rangeTo(other : Char) : IntRange<Int>
fun rangeTo(other : Long) : LongRange
fun rangeTo(other : Int) : IntRange
fun rangeTo(other : Short) : IntRange
fun rangeTo(other : Byte) : IntRange
fun rangeTo(other : Char) : IntRange
fun inc() : Int
fun dec() : Int
@@ -491,11 +517,11 @@ class Char : Number, Comparable<Char> {
fun rangeTo(other : Double) : Range<Double>
fun rangeTo(other : Float) : Range<Float>
fun rangeTo(other : Long) : IntRange<Long>
fun rangeTo(other : Int) : IntRange<Int>
fun rangeTo(other : Short) : IntRange<Short>
fun rangeTo(other : Byte) : IntRange<Byte>
fun rangeTo(other : Char) : IntRange<Char>
fun rangeTo(other : Long) : LongRange
fun rangeTo(other : Int) : IntRange
fun rangeTo(other : Short) : IntRange
fun rangeTo(other : Byte) : IntRange
fun rangeTo(other : Char) : IntRange
fun inc() : Char
fun dec() : Char
@@ -554,11 +580,11 @@ class Short : Number, Comparable<Short> {
fun rangeTo(other : Double) : Range<Double>
fun rangeTo(other : Float) : Range<Float>
fun rangeTo(other : Long) : IntRange<Long>
fun rangeTo(other : Int) : IntRange<Int>
fun rangeTo(other : Short) : IntRange<Short>
fun rangeTo(other : Byte) : IntRange<Short>
fun rangeTo(other : Char) : IntRange<Int>
fun rangeTo(other : Long) : LongRange
fun rangeTo(other : Int) : IntRange
fun rangeTo(other : Short) : IntRange
fun rangeTo(other : Byte) : IntRange
fun rangeTo(other : Char) : IntRange
fun inc() : Short
fun dec() : Short
@@ -617,11 +643,11 @@ class Byte : Number, Comparable<Byte> {
fun rangeTo(other : Double) : Range<Double>
fun rangeTo(other : Float) : Range<Float>
fun rangeTo(other : Long) : IntRange<Long>
fun rangeTo(other : Int) : IntRange<Int>
fun rangeTo(other : Short) : IntRange<Short>
fun rangeTo(other : Byte) : IntRange<Byte>
fun rangeTo(other : Char) : IntRange<Int>
fun rangeTo(other : Long) : LongRange
fun rangeTo(other : Int) : IntRange
fun rangeTo(other : Short) : IntRange
fun rangeTo(other : Byte) : IntRange
fun rangeTo(other : Char) : IntRange
fun inc() : Byte
fun dec() : Byte
@@ -86,4 +86,18 @@ public class ArrayGenTest extends CodegenTestCase {
Method foo = generateFunction();
foo.invoke(null);
}
public void testArrayIndices () throws Exception {
loadText("fun box() { val x = Array<Int>(5, {it}).indices.iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
System.out.println(generateToText());
Method foo = generateFunction();
foo.invoke(null);
}
public void testCharIndices () throws Exception {
loadText("fun box() { val x = CharArray(5).indices.iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
System.out.println(generateToText());
Method foo = generateFunction();
foo.invoke(null);
}
}
@@ -433,8 +433,8 @@ public class NamespaceGenTest extends CodegenTestCase {
final Method main = generateFunction();
IntRange result = (IntRange) main.invoke(null);
assertTrue(result.contains(1));
assertTrue(result.contains(10));
assertFalse(result.contains(11));
assertTrue(result.contains(9));
assertFalse(result.contains(10));
}
public void testSubstituteJavaMethodTypeParameters() throws Exception {
+56 -9
View File
@@ -1,28 +1,75 @@
package jet;
public class IntRange implements Range<Integer> {
import jet.typeinfo.TypeInfo;
public final class IntRange implements Range<Integer>, Iterable<Integer>, JetObject {
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(IntRange.class, false);
private final int startValue;
private final int endValue;
private final int excludedEndValue;
public IntRange(int startValue, int endValue) {
this.startValue = startValue;
this.endValue = endValue;
this.excludedEndValue = endValue;
}
@Override
public boolean contains(Integer item) {
if (item == null) return false;
if (startValue <= endValue) {
return item >= startValue && item <= endValue;
if (startValue < excludedEndValue) {
return item >= startValue && item < excludedEndValue;
}
return item <= startValue && item >= endValue;
return item <= startValue && item > excludedEndValue;
}
public int getStartValue() {
public int getStart() {
return startValue;
}
public int getEndValue() {
return endValue;
public int getEnd() {
return excludedEndValue;
}
@Override
public Iterator<Integer> iterator() {
return new MyIterator(startValue, excludedEndValue);
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
public static IntRange count(int length) {
return new IntRange(0, length);
}
private static class MyIterator implements Iterator<Integer> {
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false);
private final int lastValue;
private int cur;
private boolean reversed;
public MyIterator(int startValue, int endValue) {
reversed = endValue <= startValue;
this.lastValue = reversed ? startValue : endValue-1;
cur = reversed ? endValue-1 : startValue;
}
@Override
public boolean hasNext() {
return reversed ? cur >= lastValue : cur <= lastValue;
}
@Override
public Integer next() {
return reversed ? cur-- : cur++;
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
}
}
+75
View File
@@ -0,0 +1,75 @@
package jet;
import jet.typeinfo.TypeInfo;
public final class LongRange implements Range<Long>, Iterable<Long>, JetObject {
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(IntRange.class, false);
private final long startValue;
private final long excludedEndValue;
public LongRange(long startValue, long endValue) {
this.startValue = startValue;
this.excludedEndValue = endValue;
}
@Override
public boolean contains(Long item) {
if (item == null) return false;
if (startValue < excludedEndValue) {
return item >= startValue && item < excludedEndValue;
}
return item <= startValue && item > excludedEndValue;
}
public long getStart() {
return startValue;
}
public long getEnd() {
return excludedEndValue;
}
@Override
public Iterator<Long> iterator() {
return new MyIterator(startValue, excludedEndValue);
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
public static IntRange count(int length) {
return new IntRange(0, length);
}
private static class MyIterator implements Iterator<Long> {
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false);
private final long lastValue;
private long cur;
private boolean reversed;
public MyIterator(long startValue, long endValue) {
reversed = endValue <= startValue;
this.lastValue = reversed ? startValue : endValue-1;
cur = reversed ? endValue-1 : startValue;
}
@Override
public boolean hasNext() {
return reversed ? cur >= lastValue : cur <= lastValue;
}
@Override
public Long next() {
return reversed ? cur-- : cur++;
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
}
}