From 1d2e2373129a33692f9e8dec0c2a5c6c64b14646 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Fri, 6 Jan 2012 13:11:44 +0200 Subject: [PATCH] KT-925 step methods for integral ranges --- .../jet/codegen/ExpressionCodegen.java | 13 +- .../codegen/intrinsics/IntrinsicMethods.java | 1 + .../codegen/intrinsics/IteratorIterator.java | 21 ++ .../jet/codegen/intrinsics/RangeTo.java | 17 +- compiler/frontend/src/jet/Library.jet | 32 +- .../testData/codegen/regressions/kt925.kt | 54 ++++ .../jet/codegen/PrimitiveTypesTest.java | 4 + stdlib/src/jet/ByteRange.java | 18 +- stdlib/src/jet/CharRange.java | 18 +- stdlib/src/jet/IntRange.java | 18 +- stdlib/src/jet/LongRange.java | 31 +- stdlib/src/jet/ShortRange.java | 18 +- stdlib/src/jet/runtime/Ranges.java | 277 ++++++++++++++++++ 13 files changed, 467 insertions(+), 55 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorIterator.java create mode 100644 compiler/testData/codegen/regressions/kt925.kt create mode 100644 stdlib/src/jet/runtime/Ranges.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index cb4a2600153..da59861265d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1046,11 +1046,10 @@ public class ExpressionCodegen extends JetVisitor { isInterface = CodegenUtil.isInterface(containingDeclaration); } else { - if(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.OBJECT) - isInterface = false; + if(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.TRAIT) + isInterface = true; else { - JetClass jetClass = (JetClass) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, containingDeclaration); - isInterface = jetClass == null || jetClass.isTrait(); + isInterface = false; } } } @@ -2768,7 +2767,11 @@ If finally block is present, its last expression is the value of try expression. JetType jetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, rangeExpression); assert jetType != null; final DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor(); - if (isClass(descriptor, "IntRange")) { + if (isClass(descriptor, "IntRange") || + isClass(descriptor, "CharRange") || + isClass(descriptor, "ByteRange") || + isClass(descriptor, "LongRange") || + isClass(descriptor, "ShortRange")) { return true; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index 15da00768dd..2939e4ba879 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -92,6 +92,7 @@ public class IntrinsicMethods { declareOverload(myStdLib.getLibraryScope().getFunctions("Array"), 1, new NewArray()); declareOverload(myStdLib.getLibraryScope().getFunctions("sure"), 0, new Sure()); declareOverload(myStdLib.getLibraryScope().getFunctions("synchronized"), 1, new StupidSync()); + declareOverload(myStdLib.getLibraryScope().getFunctions("iterator"), 0, new IteratorIterator()); declareIntrinsicFunction("ByteIterator", "next", 0, ITERATOR_NEXT); declareIntrinsicFunction("ShortIterator", "next", 0, ITERATOR_NEXT); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorIterator.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorIterator.java new file mode 100644 index 00000000000..53a62983440 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorIterator.java @@ -0,0 +1,21 @@ +package org.jetbrains.jet.codegen.intrinsics; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.codegen.ExpressionCodegen; +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; + +/** + * @author alex.tkachman + */ +public class IteratorIterator implements IntrinsicMethod { + @Override + public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, @Nullable PsiElement element, @Nullable List arguments, StackValue receiver) { + return receiver; + } +} 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 c742cd0d633..7ed14f5bbef 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java @@ -19,19 +19,22 @@ public class RangeTo implements IntrinsicMethod { @Override public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List arguments, StackValue receiver) { if(arguments.size()==1) { + final Type leftType = receiver.type; + final Type rightType = codegen.expressionType(arguments.get(0)); receiver.put(Type.INT_TYPE, v); - codegen.gen(arguments.get(0), Type.INT_TYPE); - v.invokestatic("jet/IntRange", "rangeTo", "(II)Ljet/IntRange;"); - return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE); + codegen.gen(arguments.get(0), rightType); + v.invokestatic("jet/runtime/Ranges", "rangeTo", "(" + receiver.type.getDescriptor() + leftType.getDescriptor() + ")" + expectedType.getDescriptor()); + return StackValue.onStack(expectedType); } else { JetBinaryExpression expression = (JetBinaryExpression) element; final Type leftType = codegen.expressionType(expression.getLeft()); + final Type rightType = codegen.expressionType(expression.getRight()); if (JetTypeMapper.isIntPrimitive(leftType)) { - codegen.gen(expression.getLeft(), Type.INT_TYPE); - codegen.gen(expression.getRight(), Type.INT_TYPE); - v.invokestatic(expectedType.getInternalName(), "rangeTo", "(" + leftType.getDescriptor() + leftType.getDescriptor() + ")" + expectedType.getDescriptor()); - return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE); + 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"); diff --git a/compiler/frontend/src/jet/Library.jet b/compiler/frontend/src/jet/Library.jet index 48e139cbb96..520ab070b0c 100644 --- a/compiler/frontend/src/jet/Library.jet +++ b/compiler/frontend/src/jet/Library.jet @@ -22,53 +22,71 @@ fun T?.sure() : T fun String?.plus(other: Any?) : String +fun Iterator.iterator() : Iterator + trait Iterator { fun next() : T val hasNext : Boolean } +fun ByteIterator.iterator() : ByteIterator + abstract open class ByteIterator() : Iterator { abstract open fun nextByte() : Byte override fun next() : Byte } +fun ShortIterator.iterator() : ShortIterator + abstract open class ShortIterator() : Iterator { abstract open fun nextShort() : Short override fun next() : Short } +fun CharIterator.iterator() : CharIterator + abstract open class CharIterator() : Iterator { abstract open fun nextChar() : Char override fun next() : Char } +fun IntIterator.iterator() : IntIterator + abstract open class IntIterator() : Iterator { abstract open fun nextInt() : Int override fun next() : Int } +fun LongIterator.iterator() : LongIterator + abstract open class LongIterator() : Iterator { abstract open fun nextLong() : Long override fun next() : Long } +fun FloatIterator.iterator() : FloatIterator + abstract open class FloatIterator() : Iterator { abstract open fun nextFloat() : Float override fun next() : Float } +fun DoubleIterator.iterator() : DoubleIterator + abstract open class DoubleIterator() : Iterator { abstract open fun nextDouble() : Double override fun next() : Double } +fun BooleanIterator.iterator() : BooleanIterator + abstract open class BooleanIterator() : Iterator { abstract open fun nextBoolean() : Boolean @@ -247,7 +265,7 @@ class IntRange(val start : Int, val size : Int, val isReversed : Boolean = false fun minus() : IntRange - fun step(step: Int) : IntIterable + fun step(step: Int) : IntIterator } class LongRange(val start : Long, val size : Long, val isReversed : Boolean = false) : Range, LongIterable { @@ -259,7 +277,7 @@ class LongRange(val start : Long, val size : Long, val isReversed : Boolean = fa fun minus() : LongRange - fun step(step: Long) : LongIterable + fun step(step: Long) : LongIterator } class ByteRange(val start : Byte, val size : Int, val isReversed : Boolean = false) : Range, ByteIterable { @@ -271,7 +289,7 @@ class ByteRange(val start : Byte, val size : Int, val isReversed : Boolean = fal fun minus() : ByteRange - fun step(step: Int) : ByteIterable + fun step(step: Int) : ByteIterator } class ShortRange(val start : Short, val size : Int, val isReversed : Boolean = false) : Range, ShortIterable { @@ -283,7 +301,7 @@ class ShortRange(val start : Short, val size : Int, val isReversed : Boolean = f fun minus() : ShortRange - fun step(step: Int) : ShortIterable + fun step(step: Int) : ShortIterator } class CharRange(val start : Char, val size : Int, val isReversed : Boolean = false) : Range, CharIterable { @@ -295,7 +313,7 @@ class CharRange(val start : Char, val size : Int, val isReversed : Boolean = fal fun minus() : CharRange - fun step(step: Int) : CharIterable + fun step(step: Int) : CharIterator } abstract class Number : Hashable { @@ -635,8 +653,8 @@ class Char : Number, Comparable { fun rangeTo(other : Float) : Range 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) : CharRange fun rangeTo(other : Char) : CharRange fun inc() : Char diff --git a/compiler/testData/codegen/regressions/kt925.kt b/compiler/testData/codegen/regressions/kt925.kt new file mode 100644 index 00000000000..2db14c16b4b --- /dev/null +++ b/compiler/testData/codegen/regressions/kt925.kt @@ -0,0 +1,54 @@ +fun test1() : Boolean { + val r1 = 1..10 + var s1 = 0 + for(e in r1 step 2) { + s1 += e + } + return s1 == 25 +} + +fun test2() : Boolean { + val r1 = 1.byt..10.byt + var s1 = 0 + for(e in r1 step 2) { + s1 += e + } + return s1 == 25 +} + +fun test3() : Boolean { + val r1 = 1.byt..10.lng + var s1 = 0.lng + for(e in r1 step 2) { + s1 += e + } + return s1 == 25.lng +} + +fun test4() : Boolean { + val r1 = 1.byt..10.sht + var s1 = 0.sht + for(e in r1 step 2) { + s1 += e + } + return s1 == 25.sht +} + +fun test5() : Boolean { + val r1 = 'a'..'h' + var s1 = 0 + for(e in r1 step 2) { + s1 ++ + } + return s1 == 4 +} + +fun box() : String { + if(test1().not()) return "test1 failed" + if(test2().not()) return "test2 failed" + if(test3().not()) return "test3 failed" + if(test4().not()) return "test4 failed" + if(test5().not()) return "test4 failed" + + 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 6275a968154..d9bafd599bf 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java @@ -367,4 +367,8 @@ public class PrimitiveTypesTest extends CodegenTestCase { public void testKt821 () { blackBoxFile("regressions/kt821.kt"); } + + public void testKt925 () { + blackBoxFile("regressions/kt925.kt"); + } } diff --git a/stdlib/src/jet/ByteRange.java b/stdlib/src/jet/ByteRange.java index 754445a4459..8a1d94ca3cd 100644 --- a/stdlib/src/jet/ByteRange.java +++ b/stdlib/src/jet/ByteRange.java @@ -44,13 +44,17 @@ public final class ByteRange implements Range, ByteIterable, JetObject { return count < 0 ? -count : count; } + public ByteIterator step(int step) { + return new MyIterator(start, count, step); + } + public ByteRange minus() { return new ByteRange(getEnd(), -count); } @Override public ByteIterator iterator() { - return new MyIterator(start, count); + return new MyIterator(start, count, 1); } @Override @@ -80,12 +84,14 @@ public final class ByteRange implements Range, ByteIterable, JetObject { private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); private byte cur; + private int step; private int count; private final boolean reversed; - public MyIterator(byte startValue, int count) { + public MyIterator(byte startValue, int count, int step) { cur = startValue; + this.step = step; reversed = count < 0; this.count = reversed ? -count : count; } @@ -97,12 +103,14 @@ public final class ByteRange implements Range, ByteIterable, JetObject { @Override public byte nextByte() { - count--; + count -= step; if(reversed) { - return cur--; + cur -= step; + return (byte) (cur + step); } else { - return cur++; + cur += step; + return (byte) (cur - step); } } diff --git a/stdlib/src/jet/CharRange.java b/stdlib/src/jet/CharRange.java index e295795527e..357fa08dd14 100644 --- a/stdlib/src/jet/CharRange.java +++ b/stdlib/src/jet/CharRange.java @@ -48,9 +48,13 @@ public final class CharRange implements Range, CharIterable, JetObjec return new CharRange(getEnd(), -count); } + public CharIterator step(int step) { + return new MyIterator(start, count, step); + } + @Override public CharIterator iterator() { - return new MyIterator(start, count); + return new MyIterator(start, count, 1); } @Override @@ -80,12 +84,14 @@ public final class CharRange implements Range, CharIterable, JetObjec private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); private char cur; + private int step; private int count; private final boolean reversed; - public MyIterator(char startValue, int count) { + public MyIterator(char startValue, int count, int step) { cur = startValue; + this.step = step; reversed = count < 0; this.count = reversed ? -count : count; } @@ -97,12 +103,14 @@ public final class CharRange implements Range, CharIterable, JetObjec @Override public char nextChar() { - count--; + count -= step; if(reversed) { - return cur--; + cur -= step; + return (char) (cur + step); } else { - return cur++; + cur += step; + return (char) (cur - step); } } diff --git a/stdlib/src/jet/IntRange.java b/stdlib/src/jet/IntRange.java index 646a095e842..595ab2aef54 100644 --- a/stdlib/src/jet/IntRange.java +++ b/stdlib/src/jet/IntRange.java @@ -28,6 +28,10 @@ public final class IntRange implements Range, IntIterable, JetObject { return item <= start && item > start + count; } + public IntIterator step(int step) { + return new MyIterator(start, count, step); + } + public boolean getIsReversed() { return count < 0; } @@ -50,7 +54,7 @@ public final class IntRange implements Range, IntIterable, JetObject { @Override public IntIterator iterator() { - return new MyIterator(start, count); + return new MyIterator(start, count, 1); } @Override @@ -80,12 +84,14 @@ public final class IntRange implements Range, IntIterable, JetObject { private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); private int cur; + private int step; private int count; private final boolean reversed; - public MyIterator(int startValue, int count) { + public MyIterator(int startValue, int count, int step) { cur = startValue; + this.step = step; reversed = count < 0; this.count = reversed ? -count : count; } @@ -97,12 +103,14 @@ public final class IntRange implements Range, IntIterable, JetObject { @Override public int nextInt() { - count--; + count -= step; if(reversed) { - return cur--; + cur -= step; + return cur + step; } else { - return cur++; + cur += step; + return cur - step; } } diff --git a/stdlib/src/jet/LongRange.java b/stdlib/src/jet/LongRange.java index 3a047c7b65f..0d8224105d7 100644 --- a/stdlib/src/jet/LongRange.java +++ b/stdlib/src/jet/LongRange.java @@ -19,6 +19,10 @@ public final class LongRange implements Range, LongIterable, JetObject { this(startValue, reversed ? -count : count, (defaultMask & 4) == 0); } + public LongIterator step(long step) { + return new MyIterator(start, count, step); + } + @Override public boolean contains(Long item) { if (item == null) return false; @@ -50,7 +54,7 @@ public final class LongRange implements Range, LongIterable, JetObject { @Override public LongIterator iterator() { - return new MyIterator(start, count); + return new MyIterator(start, count, 1); } @Override @@ -63,29 +67,22 @@ public final class LongRange implements Range, LongIterable, JetObject { return null; } - public static IntRange count(int length) { - return new IntRange(0, length); - } - - public static IntRange rangeTo(int from, int to) { - if(from > to) { - return new IntRange(to, from-to+1, true); - } - else { - return new IntRange(from, to-from+1); - } + public static LongRange count(int length) { + return new LongRange(0, length); } private static class MyIterator extends LongIterator { private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); private long cur; + private long step; private long count; private final boolean reversed; - public MyIterator(long startValue, long count) { + public MyIterator(long startValue, long count, long step) { cur = startValue; + this.step = step; reversed = count < 0; this.count = reversed ? -count : count; } @@ -97,12 +94,14 @@ public final class LongRange implements Range, LongIterable, JetObject { @Override public long nextLong() { - count--; + count -= step; if(reversed) { - return cur--; + cur -= step; + return (cur + step); } else { - return cur++; + cur += step; + return (cur - step); } } diff --git a/stdlib/src/jet/ShortRange.java b/stdlib/src/jet/ShortRange.java index 0d96d652d88..a12e7ba032e 100644 --- a/stdlib/src/jet/ShortRange.java +++ b/stdlib/src/jet/ShortRange.java @@ -19,6 +19,10 @@ public final class ShortRange implements Range, ShortIterable, JetObject this(startValue, reversed ? -count : count, (defaultMask & 4) == 0); } + public ShortIterator step(int step) { + return new MyIterator(start, count, step); + } + @Override public boolean contains(Short item) { if (item == null) return false; @@ -50,7 +54,7 @@ public final class ShortRange implements Range, ShortIterable, JetObject @Override public ShortIterator iterator() { - return new MyIterator(start, count); + return new MyIterator(start, count, 1); } @Override @@ -80,12 +84,14 @@ public final class ShortRange implements Range, ShortIterable, JetObject private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); private short cur; + private int step; private int count; private final boolean reversed; - public MyIterator(short startValue, int count) { + public MyIterator(short startValue, int count, int step) { cur = startValue; + this.step = step; reversed = count < 0; this.count = reversed ? -count : count; } @@ -97,12 +103,14 @@ public final class ShortRange implements Range, ShortIterable, JetObject @Override public short nextShort() { - count--; + count -= step; if(reversed) { - return cur--; + cur -= step; + return (short) (cur + step); } else { - return cur++; + cur += step; + return (short) (cur - step); } } diff --git a/stdlib/src/jet/runtime/Ranges.java b/stdlib/src/jet/runtime/Ranges.java new file mode 100644 index 00000000000..8258615078b --- /dev/null +++ b/stdlib/src/jet/runtime/Ranges.java @@ -0,0 +1,277 @@ +package jet.runtime; + +import jet.*; + +import java.util.Arrays; +import java.util.List; + +/** +* @author alex.tkachman +*/ +public class Ranges { + private Ranges() { + } + + 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); + } + } + + public static ShortRange rangeTo(byte from, short to) { + if(from > to) { + return new ShortRange(to, from-to+1, true); + } + else { + return new ShortRange(from, to-from+1); + } + } + + public static IntRange rangeTo(byte from, int to) { + if(from > to) { + return new IntRange(to, from-to+1, true); + } + else { + return new IntRange(from, to-from+1); + } + } + + public static LongRange rangeTo(byte from, long to) { + if(from > to) { + return new LongRange(to, from-to+1, true); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static CharRange rangeTo(byte from, char to) { + if(from > to) { + return new CharRange(to, from-to+1, true); + } + else { + return new CharRange((char) from, to-from+1); + } + } + + public static ShortRange rangeTo(short from, byte to) { + if(from > to) { + return new ShortRange(to, from-to+1, true); + } + else { + return new ShortRange(from, to-from+1); + } + } + + 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); + } + } + + public static IntRange rangeTo(short from, int to) { + if(from > to) { + return new IntRange(to, from-to+1, true); + } + else { + return new IntRange(from, to-from+1); + } + } + + public static LongRange rangeTo(short from, long to) { + if(from > to) { + return new LongRange(to, from-to+1, true); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static ShortRange rangeTo(short from, char to) { + if(from > to) { + return new ShortRange((short) to, from-to+1, true); + } + else { + return new ShortRange(from, to-from+1); + } + } + + public static IntRange rangeTo(int from, byte to) { + if(from > to) { + return new IntRange(to, from-to+1, true); + } + else { + return new IntRange(from, to-from+1); + } + } + + public static IntRange rangeTo(int from, short to) { + if(from > to) { + return new IntRange(to, from-to+1, true); + } + else { + return new IntRange(from, to-from+1); + } + } + + public static IntRange rangeTo(int from, int to) { + if(from > to) { + return new IntRange(to, from-to+1, true); + } + else { + return new IntRange(from, to-from+1); + } + } + + public static LongRange rangeTo(int from, long to) { + if(from > to) { + return new LongRange(to, from-to+1, true); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static IntRange rangeTo(int from, char to) { + if(from > to) { + return new IntRange(to, from-to+1, true); + } + else { + return new IntRange(from, to-from+1); + } + } + + public static LongRange rangeTo(long from, byte to) { + if(from > to) { + return new LongRange(to, from-to+1, true); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static LongRange rangeTo(long from, short to) { + if(from > to) { + return new LongRange(to, from-to+1, true); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static LongRange rangeTo(long from, int to) { + if(from > to) { + return new LongRange(to, from-to+1, true); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static LongRange rangeTo(long from, long to) { + if(from > to) { + return new LongRange(to, from-to+1, true); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static LongRange rangeTo(long from, char to) { + if(from > to) { + return new LongRange(to, from-to+1, true); + } + else { + return new LongRange(from, to-from+1); + } + } + + public static CharRange rangeTo(char from, byte to) { + if(from > to) { + return new CharRange((char) to, from-to+1, true); + } + else { + return new CharRange(from, to-from+1); + } + } + + public static ShortRange rangeTo(char from, short to) { + if(from > to) { + return new ShortRange(to, from-to+1, true); + } + else { + return new ShortRange((short) from, to-from+1); + } + } + + public static IntRange rangeTo(char from, int to) { + if(from > to) { + return new IntRange(to, from-to+1, true); + } + else { + return new IntRange(from, to-from+1); + } + } + + public static LongRange rangeTo(char from, long to) { + if(from > to) { + return new LongRange(to, from-to+1, true); + } + else { + return new LongRange(from, to-from+1); + } + } + + 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); + } + } + + public static void main(String[] args) { + List strings = Arrays.asList("byte", "short", "int", "long", /*"float", "double",*/ "char"); + for(String t1 : strings) + for(String t2 : strings) { + String resType; + if(t1.equals("double") || t2.equals("double")) { + resType = "DoubleRange"; + } + else if(t1.equals("float") || t2.equals("float")) { + resType = "FloatRange"; + } + else if(t1.equals("long") || t2.equals("long")) { + resType = "LongRange"; + } + else if(t1.equals("int") || t2.equals("int")) { + resType = "IntRange"; + } + else if(t1.equals("short") || t2.equals("short")) { + resType = "ShortRange"; + } + else if(t1.equals("char") || t2.equals("char")) { + resType = "CharRange"; + } + else { + resType = "ByteRange"; + } + + System.out.println("\npublic static " + resType + " rangeTo(" + t1 + " from, " + t2 + " to) {" + + "\n if(from > to) {\n" + + " return new " + resType + "(to, from-to+1, true);\n" + + " }\n" + + " else {\n" + + " return new " + resType + "(from, to-from+1);\n" + + " }\n" + + "}"); + } + } +}