diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java index 7ed14f5bbef..3dc18b19361 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java @@ -30,15 +30,15 @@ public class RangeTo implements IntrinsicMethod { JetBinaryExpression expression = (JetBinaryExpression) element; final Type leftType = codegen.expressionType(expression.getLeft()); final Type rightType = codegen.expressionType(expression.getRight()); - if (JetTypeMapper.isIntPrimitive(leftType)) { +// if (JetTypeMapper.isIntPrimitive(leftType)) { codegen.gen(expression.getLeft(), leftType); codegen.gen(expression.getRight(), rightType); v.invokestatic("jet/runtime/Ranges", "rangeTo", "(" + leftType.getDescriptor() + rightType.getDescriptor() + ")" + expectedType.getDescriptor()); return StackValue.onStack(expectedType); - } - else { - throw new UnsupportedOperationException("ranges are only supported for int objects"); - } +// } +// else { +// throw new UnsupportedOperationException("ranges are only supported for int objects"); +// } } } } diff --git a/compiler/frontend/src/jet/Library.jet b/compiler/frontend/src/jet/Library.jet index cdbbde0740f..f782b5e0473 100644 --- a/compiler/frontend/src/jet/Library.jet +++ b/compiler/frontend/src/jet/Library.jet @@ -326,6 +326,30 @@ class CharRange(val start : Char, val size : Int) : Range, CharIterable { val isReversed : Boolean } +class FloatRange(val start : Float, val size : Float) : Range { + fun contains (elem: Float) : Boolean + + val end : Float + + fun minus() : FloatRange + + fun step(step: Float) : FloatIterator + + val isReversed : Boolean +} + +class DoubleRange(val start : Double, val size : Double) : Range { + fun contains (elem: Double) : Boolean + + val end : Double + + fun minus() : DoubleRange + + fun step(step: Double) : DoubleIterator + + val isReversed : Boolean +} + abstract class Number : Hashable { abstract val dbl : Double abstract val flt : Float @@ -391,13 +415,13 @@ class Double : Number, Comparable { fun mod(other : Short) : Double fun mod(other : Byte) : Double - fun rangeTo(other : Double) : Range - fun rangeTo(other : Float) : Range - fun rangeTo(other : Long) : Range - fun rangeTo(other : Int) : Range - fun rangeTo(other : Short) : Range - fun rangeTo(other : Byte) : Range - fun rangeTo(other : Char) : Range + fun rangeTo(other : Double) : DoubleRange + fun rangeTo(other : Float) : DoubleRange + fun rangeTo(other : Long) : DoubleRange + fun rangeTo(other : Int) : DoubleRange + fun rangeTo(other : Short) : DoubleRange + fun rangeTo(other : Byte) : DoubleRange + fun rangeTo(other : Char) : DoubleRange fun inc() : Double fun dec() : Double @@ -454,13 +478,13 @@ class Float : Number, Comparable { fun mod(other : Byte) : Float fun mod(other : Char) : Float - fun rangeTo(other : Double) : Range - fun rangeTo(other : Float) : Range - fun rangeTo(other : Long) : Range - fun rangeTo(other : Int) : Range - fun rangeTo(other : Short) : Range - fun rangeTo(other : Byte) : Range - fun rangeTo(other : Char) : Range + fun rangeTo(other : Double) : DoubleRange + fun rangeTo(other : Float) : FloatRange + fun rangeTo(other : Long) : DoubleRange + fun rangeTo(other : Int) : DoubleRange + fun rangeTo(other : Short) : FloatRange + fun rangeTo(other : Byte) : FloatRange + fun rangeTo(other : Char) : FloatRange fun inc() : Float fun dec() : Float @@ -517,8 +541,8 @@ class Long : Number, Comparable { fun mod(other : Byte) : Long fun mod(other : Char) : Long - fun rangeTo(other : Double) : Range - fun rangeTo(other : Float) : Range + fun rangeTo(other : Double) : DoubleRange + fun rangeTo(other : Float) : FloatRange fun rangeTo(other : Long) : LongRange fun rangeTo(other : Int) : LongRange fun rangeTo(other : Short) : LongRange @@ -588,8 +612,8 @@ class Int : Number, Comparable { fun mod(other : Byte) : Int fun mod(other : Char) : Int - fun rangeTo(other : Double) : Range - fun rangeTo(other : Float) : Range + fun rangeTo(other : Double) : DoubleRange + fun rangeTo(other : Float) : FloatRange fun rangeTo(other : Long) : LongRange fun rangeTo(other : Int) : IntRange fun rangeTo(other : Short) : IntRange @@ -659,8 +683,8 @@ class Char : Number, Comparable { fun mod(other : Byte) : Int // fun mod(other : Char) : Int - fun rangeTo(other : Double) : Range - fun rangeTo(other : Float) : Range + fun rangeTo(other : Double) : DoubleRange + fun rangeTo(other : Float) : FloatRange fun rangeTo(other : Long) : LongRange fun rangeTo(other : Int) : IntRange fun rangeTo(other : Short) : ShortRange @@ -722,8 +746,8 @@ class Short : Number, Comparable { fun mod(other : Byte) : Int fun mod(other : Char) : Int - fun rangeTo(other : Double) : Range - fun rangeTo(other : Float) : Range + fun rangeTo(other : Double) : DoubleRange + fun rangeTo(other : Float) : FloatRange fun rangeTo(other : Long) : LongRange fun rangeTo(other : Int) : IntRange fun rangeTo(other : Short) : ShortRange @@ -785,8 +809,8 @@ class Byte : Number, Comparable { fun mod(other : Byte) : Int fun mod(other : Char) : Int - fun rangeTo(other : Double) : Range - fun rangeTo(other : Float) : Range + fun rangeTo(other : Double) : DoubleRange + fun rangeTo(other : Float) : FloatRange fun rangeTo(other : Long) : LongRange fun rangeTo(other : Int) : IntRange fun rangeTo(other : Short) : ShortRange diff --git a/compiler/testData/codegen/regressions/kt765.kt b/compiler/testData/codegen/regressions/kt765.kt new file mode 100644 index 00000000000..e2869f81853 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt765.kt @@ -0,0 +1,13 @@ +fun box() : String { + System.out?.println(System.out?.println(10.flt..11.flt)) + + for(f in 10.flt..11.flt step 0.3.flt) { + System.out?.println(f) + } + + for(f in 10.dbl..11.dbl step 0.3.dbl) { + System.out?.println(f) + } + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java index d9bafd599bf..261e4450425 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java @@ -371,4 +371,8 @@ public class PrimitiveTypesTest extends CodegenTestCase { public void testKt925 () { blackBoxFile("regressions/kt925.kt"); } + + public void testKt765 () { + blackBoxFile("regressions/kt765.kt"); + } } diff --git a/stdlib/src/jet/ByteRange.java b/stdlib/src/jet/ByteRange.java index 4210b7d9f5f..bb81716170e 100644 --- a/stdlib/src/jet/ByteRange.java +++ b/stdlib/src/jet/ByteRange.java @@ -78,8 +78,15 @@ public final class ByteRange implements Range, ByteIterable, JetObject { public MyIterator(byte startValue, int count, int step) { cur = startValue; this.step = step; - reversed = count < 0; - this.count = reversed ? -count : count; + if(count < 0) { + reversed = true; + count = -count; + startValue += count; + } + else { + reversed = false; + } + this.count = count; } @Override diff --git a/stdlib/src/jet/CharRange.java b/stdlib/src/jet/CharRange.java index 53b41a5d542..f7721fb9140 100644 --- a/stdlib/src/jet/CharRange.java +++ b/stdlib/src/jet/CharRange.java @@ -78,8 +78,15 @@ public final class CharRange implements Range, CharIterable, JetObjec public MyIterator(char startValue, int count, int step) { cur = startValue; this.step = step; - reversed = count < 0; - this.count = reversed ? -count : count; + if(count < 0) { + reversed = true; + count = -count; + startValue += count; + } + else { + reversed = false; + } + this.count = count; } @Override diff --git a/stdlib/src/jet/DoubleRange.java b/stdlib/src/jet/DoubleRange.java new file mode 100644 index 00000000000..8020039f222 --- /dev/null +++ b/stdlib/src/jet/DoubleRange.java @@ -0,0 +1,117 @@ +package jet; + +public final class DoubleRange implements Range, JetObject { + private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(DoubleRange.class, false); + + private final double start; + private final double size; + + public DoubleRange(double startValue, double size) { + this.start = startValue; + this.size = size; + } + + @Override + public boolean contains(Double item) { + if (item == null) return false; + if (size >= 0) { + return item >= start && item < start + size; + } + return item <= start && item > start + size; + } + + public DoubleIterator step(double step) { + if(step < 0) + return new MyIterator(getEnd(), -size, -step); + else + return new MyIterator(start, size, step); + } + + public boolean getIsReversed() { + return size < 0; + } + + public double getStart() { + return start; + } + + public double getEnd() { + return size < 0 ? start + size: start + size; + } + + public double getSize() { + return size < 0 ? -size : size; + } + + public DoubleRange minus() { + return new DoubleRange(getEnd(), -size); + } + + @Override + public TypeInfo getTypeInfo() { + return typeInfo; + } + + @Override + public JetObject getOuterObject() { + return null; + } + + public static DoubleRange count(int length) { + return new DoubleRange(0, length); + } + + private static class MyIterator extends DoubleIterator { + private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); + + private double cur; + private double step; + private final double end; + + private final boolean reversed; + + public MyIterator(double startValue, double size, double step) { + cur = startValue; + this.step = step; + if(size < 0) { + reversed = true; + end = startValue-size; + startValue -= size; + } + else { + reversed = false; + this.end = startValue + size; + } + } + + @Override + public boolean getHasNext() { + if(reversed) + return cur >= end; + else + return cur <= end; + } + + @Override + public double nextDouble() { + if(reversed) { + cur -= step; + return cur + step; + } + else { + cur += step; + return cur - step; + } + } + + @Override + public TypeInfo getTypeInfo() { + return typeInfo; + } + + @Override + public JetObject getOuterObject() { + return null; + } + } +} diff --git a/stdlib/src/jet/FloatRange.java b/stdlib/src/jet/FloatRange.java new file mode 100644 index 00000000000..e6b3b8894b2 --- /dev/null +++ b/stdlib/src/jet/FloatRange.java @@ -0,0 +1,117 @@ +package jet; + +public final class FloatRange implements Range, JetObject { + private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(FloatRange.class, false); + + private final float start; + private final float size; + + public FloatRange(float startValue, float size) { + this.start = startValue; + this.size = size; + } + + @Override + public boolean contains(Float item) { + if (item == null) return false; + if (size >= 0) { + return item >= start && item < start + size; + } + return item <= start && item > start + size; + } + + public FloatIterator step(float step) { + if(step < 0) + return new MyIterator(getEnd(), -size, -step); + else + return new MyIterator(start, size, step); + } + + public boolean getIsReversed() { + return size < 0; + } + + public float getStart() { + return start; + } + + public float getEnd() { + return size < 0 ? start + size: start + size; + } + + public float getSize() { + return size < 0 ? -size : size; + } + + public FloatRange minus() { + return new FloatRange(getEnd(), -size); + } + + @Override + public TypeInfo getTypeInfo() { + return typeInfo; + } + + @Override + public JetObject getOuterObject() { + return null; + } + + public static FloatRange count(int length) { + return new FloatRange(0, length); + } + + private static class MyIterator extends FloatIterator { + private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); + + private float cur; + private float step; + private final float end; + + private final boolean reversed; + + public MyIterator(float startValue, float size, float step) { + cur = startValue; + this.step = step; + if(size < 0) { + reversed = true; + end = startValue-size; + startValue -= size; + } + else { + reversed = false; + this.end = startValue + size; + } + } + + @Override + public boolean getHasNext() { + if(reversed) + return cur >= end; + else + return cur <= end; + } + + @Override + public float nextFloat() { + if(reversed) { + cur -= step; + return cur + step; + } + else { + cur += step; + return cur - step; + } + } + + @Override + public TypeInfo getTypeInfo() { + return typeInfo; + } + + @Override + public JetObject getOuterObject() { + return null; + } + } +} diff --git a/stdlib/src/jet/IntRange.java b/stdlib/src/jet/IntRange.java index 0bc52ada3c5..68d127ded00 100644 --- a/stdlib/src/jet/IntRange.java +++ b/stdlib/src/jet/IntRange.java @@ -79,7 +79,7 @@ public final class IntRange implements Range, IntIterable, JetObject { cur = startValue; this.step = step; if(count < 0) { - reversed = count < 0; + reversed = true; count = -count; startValue += count; } diff --git a/stdlib/src/jet/LongRange.java b/stdlib/src/jet/LongRange.java index 6785f9ecded..50cf408d53f 100644 --- a/stdlib/src/jet/LongRange.java +++ b/stdlib/src/jet/LongRange.java @@ -78,8 +78,15 @@ public final class LongRange implements Range, LongIterable, JetObject { public MyIterator(long startValue, long count, long step) { cur = startValue; this.step = step; - reversed = count < 0; - this.count = reversed ? -count : count; + if(count < 0) { + reversed = true; + count = -count; + startValue += count; + } + else { + reversed = false; + } + this.count = count; } @Override diff --git a/stdlib/src/jet/ShortRange.java b/stdlib/src/jet/ShortRange.java index a3c95dd7258..b00fab53562 100644 --- a/stdlib/src/jet/ShortRange.java +++ b/stdlib/src/jet/ShortRange.java @@ -78,8 +78,15 @@ public final class ShortRange implements Range, ShortIterable, JetObject public MyIterator(short startValue, int count, int step) { cur = startValue; this.step = step; - reversed = count < 0; - this.count = reversed ? -count : count; + if(count < 0) { + reversed = true; + count = -count; + startValue += count; + } + else { + reversed = false; + } + this.count = count; } @Override diff --git a/stdlib/src/jet/runtime/Ranges.java b/stdlib/src/jet/runtime/Ranges.java index 19d20293a12..ff5952afe03 100644 --- a/stdlib/src/jet/runtime/Ranges.java +++ b/stdlib/src/jet/runtime/Ranges.java @@ -48,6 +48,14 @@ public class Ranges { } } + public static FloatRange rangeTo(byte from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange rangeTo(byte from, double to) { + return new DoubleRange(from, to-from); + } + public static CharRange rangeTo(byte from, char to) { if(from > to) { return new CharRange((char) from, to-from-1); @@ -93,6 +101,14 @@ public class Ranges { } } + public static FloatRange rangeTo(short from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange rangeTo(short from, double to) { + return new DoubleRange(from, to-from); + } + public static ShortRange rangeTo(short from, char to) { if(from > to) { return new ShortRange(from, to-from-1); @@ -138,6 +154,14 @@ public class Ranges { } } + public static FloatRange rangeTo(int from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange rangeTo(int from, double to) { + return new DoubleRange(from, to-from); + } + public static IntRange rangeTo(int from, char to) { if(from > to) { return new IntRange(from, to-from-1); @@ -183,6 +207,14 @@ public class Ranges { } } + public static FloatRange rangeTo(long from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange rangeTo(long from, double to) { + return new DoubleRange(from, to-from); + } + public static LongRange rangeTo(long from, char to) { if(from > to) { return new LongRange(from, to-from-1); @@ -192,6 +224,62 @@ public class Ranges { } } + public static FloatRange rangeTo(float from, byte to) { + return new FloatRange(from, to-from); + } + + public static FloatRange rangeTo(float from, short to) { + return new FloatRange(from, to-from); + } + + public static FloatRange rangeTo(float from, int to) { + return new FloatRange(from, to-from); + } + + public static FloatRange rangeTo(float from, long to) { + return new FloatRange(from, to-from); + } + + public static FloatRange rangeTo(float from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange rangeTo(float from, double to) { + return new DoubleRange(from, to-from); + } + + public static FloatRange rangeTo(float from, char to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange rangeTo(double from, byte to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange rangeTo(double from, short to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange rangeTo(double from, int to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange rangeTo(double from, long to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange rangeTo(double from, float to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange rangeTo(double from, double to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange rangeTo(double from, char to) { + return new DoubleRange(from, to-from); + } + public static CharRange rangeTo(char from, byte to) { if(from > to) { return new CharRange(from, to-from-1); @@ -228,6 +316,14 @@ public class Ranges { } } + public static FloatRange rangeTo(char from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange rangeTo(char from, double to) { + return new DoubleRange(from, to-from); + } + public static CharRange rangeTo(char from, char to) { if(from > to) { return new CharRange(from, to-from-1); @@ -238,7 +334,7 @@ public class Ranges { } public static void main(String[] args) { - List strings = Arrays.asList("byte", "short", "int", "long", /*"float", "double",*/ "char"); + List strings = Arrays.asList("byte", "short", "int", "long", "float", "double", "char"); for(String t1 : strings) for(String t2 : strings) { String resType; @@ -264,14 +360,21 @@ public class Ranges { resType = "ByteRange"; } - System.out.println("\npublic static " + resType + " rangeTo(" + t1 + " from, " + t2 + " to) {" + - "\n if(from > to) {\n" + - " return new " + resType + "(from, to-from-1);\n" + - " }\n" + - " else {\n" + - " return new " + resType + "(from, to-from+1);\n" + - " }\n" + - "}"); + if(resType.equals("FloatRange") || resType.equals("DoubleRange")) { + System.out.println("\npublic static " + resType + " rangeTo(" + t1 + " from, " + t2 + " to) {\n" + + " return new " + resType + "(from, to-from);\n" + + "}"); + } + else { + System.out.println("\npublic static " + resType + " rangeTo(" + t1 + " from, " + t2 + " to) {" + + "\n if(from > to) {\n" + + " return new " + resType + "(from, to-from-1);\n" + + " }\n" + + " else {\n" + + " return new " + resType + "(from, to-from+1);\n" + + " }\n" + + "}"); + } } } }