KT-821 and other improvements for ranges

This commit is contained in:
Alex Tkachman
2012-01-05 18:34:32 +02:00
parent 89933439f4
commit 9fbf27eb11
9 changed files with 489 additions and 17 deletions
@@ -30,7 +30,7 @@ public class RangeTo implements IntrinsicMethod {
if (JetTypeMapper.isIntPrimitive(leftType)) {
codegen.gen(expression.getLeft(), Type.INT_TYPE);
codegen.gen(expression.getRight(), Type.INT_TYPE);
v.invokestatic("jet/IntRange", "rangeTo", "(II)Ljet/IntRange;");
v.invokestatic(expectedType.getInternalName(), "rangeTo", "(" + leftType.getDescriptor() + leftType.getDescriptor() + ")" + expectedType.getDescriptor());
return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE);
}
else {
+51 -15
View File
@@ -238,28 +238,64 @@ trait Range<in T : Comparable<T>> {
fun contains(item : T) : Boolean
}
class IntRange(val start : Int, size : Int, reversed : Boolean = false) : Range<Int>, IntIterable {
fun iterator () : Iterator<Int>
class IntRange(val start : Int, val size : Int, val isReversed : Boolean = false) : Range<Int>, IntIterable {
fun iterator () : IntIterator
fun contains (elem: Int) : Boolean
val size : Int
val end : Int
val reversed : Boolean
fun minus() : IntRange
fun step(step: Int) : IntIterable
}
class LongRange(val start : Long, size : Long, reversed : Boolean = false) : Range<Long>, Iterable<Long> {
fun iterator () : Iterator<Long>
class LongRange(val start : Long, val size : Long, val isReversed : Boolean = false) : Range<Long>, LongIterable {
fun iterator () : LongIterator
fun contains (elem: Long) : Boolean
val size : Long
val end : Long
val reversed : Boolean
fun minus() : LongRange
fun step(step: Long) : LongIterable
}
class ByteRange(val start : Byte, val size : Int, val isReversed : Boolean = false) : Range<Byte>, ByteIterable {
fun iterator () : ByteIterator
fun contains (elem: Byte) : Boolean
val end : Byte
fun minus() : ByteRange
fun step(step: Int) : ByteIterable
}
class ShortRange(val start : Short, val size : Int, val isReversed : Boolean = false) : Range<Short>, ShortIterable {
fun iterator () : ShortIterator
fun contains (elem: Byte) : Boolean
val end : Short
fun minus() : ShortRange
fun step(step: Int) : ShortIterable
}
class CharRange(val start : Char, val size : Int, val isReversed : Boolean = false) : Range<Char>, CharIterable {
fun iterator () : CharIterator
fun contains (elem: Char) : Boolean
val end : Char
fun minus() : CharRange
fun step(step: Int) : CharIterable
}
abstract class Number : Hashable {
@@ -601,7 +637,7 @@ class Char : Number, Comparable<Char> {
fun rangeTo(other : Int) : IntRange
fun rangeTo(other : Short) : IntRange
fun rangeTo(other : Byte) : IntRange
fun rangeTo(other : Char) : IntRange
fun rangeTo(other : Char) : CharRange
fun inc() : Char
fun dec() : Char
@@ -662,8 +698,8 @@ class Short : Number, Comparable<Short> {
fun rangeTo(other : Float) : Range<Float>
fun rangeTo(other : Long) : LongRange
fun rangeTo(other : Int) : IntRange
fun rangeTo(other : Short) : IntRange
fun rangeTo(other : Byte) : IntRange
fun rangeTo(other : Short) : ShortRange
fun rangeTo(other : Byte) : ShortRange
fun rangeTo(other : Char) : IntRange
fun inc() : Short
@@ -725,8 +761,8 @@ class Byte : Number, Comparable<Byte> {
fun rangeTo(other : Float) : Range<Float>
fun rangeTo(other : Long) : LongRange
fun rangeTo(other : Int) : IntRange
fun rangeTo(other : Short) : IntRange
fun rangeTo(other : Byte) : IntRange
fun rangeTo(other : Short) : ShortRange
fun rangeTo(other : Byte) : ByteRange
fun rangeTo(other : Char) : IntRange
fun inc() : Byte
@@ -0,0 +1,51 @@
fun box() : String {
val r1 = IntRange(1, 4)
if(r1.end != 4 || r1.isReversed || r1.size != 4) return "fail"
val r2 = IntRange(1, 4, true)
if(r2.end != -2 || !r2.isReversed || r2.size != 4) return "fail"
val r3 = -(0..5)
if(r3.start != 5 || r3.end != 0 || !r3.isReversed || r3.size != 6) return "fail"
val r4 = -r3
if(r4.end != 5 || r4.isReversed || r4.size != 6) return "fail"
val r5 = ByteRange(1, 4)
if(r5.end != 4.byt || r5.isReversed || r5.size != 4) return "fail"
val r6 = ByteRange(1, 4, true)
if(r6.end != -2.byt || !r6.isReversed) return "fail"
val r7 = -(0.byt..5.byt)
if(r7.start != 5.byt || r7.end != 0.byt || !r7.isReversed) return "fail"
val r9 = -r7
if(r9.end != 5.byt || r9.isReversed) return "fail"
val r10 = ShortRange(1, 4)
if(r10.end != 4.sht || r10.isReversed || r10.size != 4) return "fail"
val r11 = ShortRange(1, 4, true)
if(r11.end != -2.sht || !r11.isReversed) return "fail"
val r12 = -(0.sht..5.sht)
if(r12.start != 5.sht || r12.end != 0.sht || !r12.isReversed) return "fail"
val r13 = -r12
if(r13.end != 5.sht || r13.isReversed) return "fail"
val r14 = CharRange('a', 4)
if(r14.end != 'd' || r14.isReversed || r14.size != 4) return "fail"
val r15 = CharRange('D', 4, true)
if(r15.end != 'A' || !r15.isReversed) return "fail"
val r16 = -('a'..'e')
if(r16.start != 'e' || r16.end != 'a' || !r16.isReversed) return "fail"
val r17 = -r16
if(r17.end != 'e' || r17.isReversed) return "fail"
return "OK"
}
@@ -363,4 +363,8 @@ public class PrimitiveTypesTest extends CodegenTestCase {
public void testKt887 () {
blackBoxFile("regressions/kt887.jet");
}
public void testKt821 () {
blackBoxFile("regressions/kt821.kt");
}
}
+119
View File
@@ -0,0 +1,119 @@
package jet;
public final class ByteRange implements Range<Byte>, ByteIterable, JetObject {
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(ByteRange.class, false);
private final byte start;
private final int count;
public ByteRange(byte startValue, int count) {
this.start = startValue;
this.count = count;
}
public ByteRange(byte startValue, int count, boolean reversed) {
this(startValue, reversed ? -count : count);
}
public ByteRange(byte startValue, int count, boolean reversed, int defaultMask) {
this(startValue, reversed ? -count : count, (defaultMask & 4) == 0);
}
@Override
public boolean contains(Byte item) {
if (item == null) return false;
if (count >= 0) {
return item >= start && item < start + count;
}
return item <= start && item > start + count;
}
public boolean getIsReversed() {
return count < 0;
}
public byte getStart() {
return start;
}
public byte getEnd() {
return (byte) (count < 0 ? start + count + 1: start+count-1);
}
public int getSize() {
return count < 0 ? -count : count;
}
public ByteRange minus() {
return new ByteRange(getEnd(), -count);
}
@Override
public ByteIterator iterator() {
return new MyIterator(start, count);
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
@Override
public JetObject getOuterObject() {
return null;
}
public static ByteRange count(int length) {
return new ByteRange((byte) 0, length);
}
public static ByteRange rangeTo(byte from, byte to) {
if(from > to) {
return new ByteRange(to, from-to+1, true);
}
else {
return new ByteRange(from, to-from+1);
}
}
private static class MyIterator extends ByteIterator {
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false);
private byte cur;
private int count;
private final boolean reversed;
public MyIterator(byte startValue, int count) {
cur = startValue;
reversed = count < 0;
this.count = reversed ? -count : count;
}
@Override
public boolean getHasNext() {
return count > 0;
}
@Override
public byte nextByte() {
count--;
if(reversed) {
return cur--;
}
else {
return cur++;
}
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
@Override
public JetObject getOuterObject() {
return null;
}
}
}
+119
View File
@@ -0,0 +1,119 @@
package jet;
public final class CharRange implements Range<Character>, CharIterable, JetObject {
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(CharRange.class, false);
private final char start;
private final int count;
public CharRange(char startValue, int count) {
this.start = startValue;
this.count = count;
}
public CharRange(char startValue, int count, boolean reversed) {
this(startValue, reversed ? -count : count);
}
public CharRange(char startValue, int count, boolean reversed, int defaultMask) {
this(startValue, reversed ? -count : count, (defaultMask & 4) == 0);
}
@Override
public boolean contains(Character item) {
if (item == null) return false;
if (count >= 0) {
return item >= start && item < start + count;
}
return item <= start && item > start + count;
}
public boolean getIsReversed() {
return count < 0;
}
public char getStart() {
return start;
}
public char getEnd() {
return (char) (count < 0 ? start + count + 1: start+count-1);
}
public int getSize() {
return count < 0 ? -count : count;
}
public CharRange minus() {
return new CharRange(getEnd(), -count);
}
@Override
public CharIterator iterator() {
return new MyIterator(start, count);
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
@Override
public JetObject getOuterObject() {
return null;
}
public static CharRange count(int length) {
return new CharRange((char) 0, length);
}
public static CharRange rangeTo(char from, char to) {
if(from > to) {
return new CharRange(to, from-to+1, true);
}
else {
return new CharRange(from, to-from+1);
}
}
private static class MyIterator extends CharIterator {
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false);
private char cur;
private int count;
private final boolean reversed;
public MyIterator(char startValue, int count) {
cur = startValue;
reversed = count < 0;
this.count = reversed ? -count : count;
}
@Override
public boolean getHasNext() {
return count > 0;
}
@Override
public char nextChar() {
count--;
if(reversed) {
return cur--;
}
else {
return cur++;
}
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
@Override
public JetObject getOuterObject() {
return null;
}
}
}
+13 -1
View File
@@ -15,6 +15,10 @@ public final class IntRange implements Range<Integer>, IntIterable, JetObject {
this(startValue, reversed ? -count : count);
}
public IntRange(int startValue, int count, boolean reversed, int defaultMask) {
this(startValue, reversed ? -count : count, (defaultMask & 4) == 0);
}
@Override
public boolean contains(Integer item) {
if (item == null) return false;
@@ -24,18 +28,26 @@ public final class IntRange implements Range<Integer>, IntIterable, JetObject {
return item <= start && item > start + count;
}
public boolean getIsReversed() {
return count < 0;
}
public int getStart() {
return start;
}
public int getEnd() {
return start+count-1;
return count < 0 ? start + count + 1: start+count-1;
}
public int getSize() {
return count < 0 ? -count : count;
}
public IntRange minus() {
return new IntRange(getEnd(), -count);
}
@Override
public IntIterator iterator() {
return new MyIterator(start, count);
+12
View File
@@ -15,6 +15,10 @@ public final class LongRange implements Range<Long>, LongIterable, JetObject {
this(startValue, reversed ? -count : count);
}
public LongRange(int startValue, int count, boolean reversed, int defaultMask) {
this(startValue, reversed ? -count : count, (defaultMask & 4) == 0);
}
@Override
public boolean contains(Long item) {
if (item == null) return false;
@@ -24,6 +28,10 @@ public final class LongRange implements Range<Long>, LongIterable, JetObject {
return item <= start && item > start + count;
}
public boolean getIsReversed() {
return count < 0;
}
public long getStart() {
return start;
}
@@ -36,6 +44,10 @@ public final class LongRange implements Range<Long>, LongIterable, JetObject {
return count < 0 ? -count : count;
}
public LongRange minus() {
return new LongRange(getEnd(), -count);
}
@Override
public LongIterator iterator() {
return new MyIterator(start, count);
+119
View File
@@ -0,0 +1,119 @@
package jet;
public final class ShortRange implements Range<Short>, ShortIterable, JetObject {
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(ShortRange.class, false);
private final short start;
private final int count;
public ShortRange(short startValue, int count) {
this.start = startValue;
this.count = count;
}
public ShortRange(short startValue, int count, boolean reversed) {
this(startValue, reversed ? -count : count);
}
public ShortRange(short startValue, int count, boolean reversed, int defaultMask) {
this(startValue, reversed ? -count : count, (defaultMask & 4) == 0);
}
@Override
public boolean contains(Short item) {
if (item == null) return false;
if (count >= 0) {
return item >= start && item < start + count;
}
return item <= start && item > start + count;
}
public boolean getIsReversed() {
return count < 0;
}
public short getStart() {
return start;
}
public short getEnd() {
return (short) (count < 0 ? start + count + 1: start+count-1);
}
public int getSize() {
return count < 0 ? -count : count;
}
public ShortRange minus() {
return new ShortRange(getEnd(), -count);
}
@Override
public ShortIterator iterator() {
return new MyIterator(start, count);
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
@Override
public JetObject getOuterObject() {
return null;
}
public static ShortRange count(int length) {
return new ShortRange((byte) 0, length);
}
public static ShortRange rangeTo(short from, short to) {
if(from > to) {
return new ShortRange(to, from-to+1, true);
}
else {
return new ShortRange(from, to-from+1);
}
}
private static class MyIterator extends ShortIterator {
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false);
private short cur;
private int count;
private final boolean reversed;
public MyIterator(short startValue, int count) {
cur = startValue;
reversed = count < 0;
this.count = reversed ? -count : count;
}
@Override
public boolean getHasNext() {
return count > 0;
}
@Override
public short nextShort() {
count--;
if(reversed) {
return cur--;
}
else {
return cur++;
}
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
@Override
public JetObject getOuterObject() {
return null;
}
}
}