KT-1076 reversed ranges

This commit is contained in:
Alex Tkachman
2012-01-18 20:01:18 +01:00
parent 1a6f018454
commit 86a33f8b16
4 changed files with 64 additions and 17 deletions
@@ -514,7 +514,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
} }
private class ForInRangeLoopGenerator extends ForLoopGenerator { private class ForInRangeLoopGenerator extends ForLoopGenerator {
private int myEndVar; private int myCountVar;
private int myDeltaVar;
private int myIndexVar;
public ForInRangeLoopGenerator(JetForExpression expression, Type loopRangeType) { public ForInRangeLoopGenerator(JetForExpression expression, Type loopRangeType) {
super(expression, loopRangeType); super(expression, loopRangeType);
@@ -522,41 +524,73 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override @Override
protected void generatePrologue() { protected void generatePrologue() {
myEndVar = myFrameMap.enterTemp(); myIndexVar = lookupLocal(parameterDescriptor);
myCountVar = myFrameMap.enterTemp();
myDeltaVar = myFrameMap.enterTemp();
if(isIntRangeExpr(expression.getLoopRange())) { if(isIntRangeExpr(expression.getLoopRange())) {
JetBinaryExpression rangeExpression = (JetBinaryExpression) expression.getLoopRange(); JetBinaryExpression rangeExpression = (JetBinaryExpression) expression.getLoopRange();
//noinspection ConstantConditions //noinspection ConstantConditions
gen(rangeExpression.getLeft(), Type.INT_TYPE); gen(rangeExpression.getLeft(), Type.INT_TYPE);
v.store(lookupLocal(parameterDescriptor), Type.INT_TYPE); v.store(myIndexVar, Type.INT_TYPE);
gen(rangeExpression.getRight(), Type.INT_TYPE); gen(rangeExpression.getRight(), Type.INT_TYPE);
v.store(myEndVar, Type.INT_TYPE); v.store(myCountVar, Type.INT_TYPE);
v.load(myCountVar, Type.INT_TYPE);
v.load(myIndexVar, Type.INT_TYPE);
v.sub(Type.INT_TYPE);
v.iconst(1);
v.add(Type.INT_TYPE);
v.store(myCountVar, Type.INT_TYPE);
v.load(myCountVar, Type.INT_TYPE);
v.iflt(end);
v.iconst(1);
v.store(myDeltaVar, Type.INT_TYPE);
} }
else { else {
gen(expression.getLoopRange(), loopRangeType); gen(expression.getLoopRange(), loopRangeType);
v.dup(); v.dup();
v.dup();
v.invokevirtual("jet/IntRange", "getIteratorStart", "()I"); v.invokevirtual("jet/IntRange", "getStart", "()I");
v.store(lookupLocal(parameterDescriptor), Type.INT_TYPE); v.store(myIndexVar, Type.INT_TYPE);
v.invokevirtual("jet/IntRange", "getEnd", "()I"); v.invokevirtual("jet/IntRange", "getSize", "()I");
v.store(myEndVar, Type.INT_TYPE); v.store(myCountVar, Type.INT_TYPE);
v.invokevirtual("jet/IntRange", "getIsReversed", "()Z");
Label down = new Label();
v.ifne(down);
v.iconst(1);
Label initEnd = new Label();
v.goTo(initEnd);
v.mark(down);
v.iconst(-1);
v.mark(initEnd);
v.store(myDeltaVar, Type.INT_TYPE);
} }
} }
@Override @Override
protected void generateCondition(Type asmParamType, Label end) { protected void generateCondition(Type asmParamType, Label end) {
v.load(lookupLocal(parameterDescriptor), Type.INT_TYPE); v.load(myCountVar, Type.INT_TYPE);
v.load(myEndVar, Type.INT_TYPE); v.ifeq(end);
v.ificmpgt(end);
} }
@Override @Override
protected void generateIncrement() { protected void generateIncrement() {
v.iinc(lookupLocal(parameterDescriptor), 1); // TODO support decreasing order v.load(myIndexVar, Type.INT_TYPE);
v.load(myDeltaVar, Type.INT_TYPE);
v.add(Type.INT_TYPE);
v.store(myIndexVar, Type.INT_TYPE);
v.iinc(myCountVar, -1);
} }
@Override @Override
protected void cleanupTemp() { protected void cleanupTemp() {
myFrameMap.leaveTemp(1); myFrameMap.leaveTemp();
myFrameMap.leaveTemp();
} }
} }
@@ -0,0 +1,11 @@
fun box() : String {
var cnt = 0
for (len in 4 downto 1) {
cnt++
}
for (n in -(1..5))
cnt++
return if(cnt == 9) "OK" else cnt.toString()
}
@@ -262,4 +262,8 @@ public class ControlStructuresTest extends CodegenTestCase {
blackBoxFile("controlStructures/ifInWhile.jet"); blackBoxFile("controlStructures/ifInWhile.jet");
// System.out.println(generateToText()); // System.out.println(generateToText());
} }
public void testKt1076() throws Exception {
blackBoxFile("regressions/kt1076.kt");
}
} }
+2 -4
View File
@@ -11,21 +11,19 @@ inline fun <T> java.util.Iterator<T>.filter(f: (T)-> Boolean) : java.util.Iterat
/* /*
Adds filtered elements in to given container Adds filtered elements in to given container
*/ */
/* inline fun <T,U : Collection<in T>> java.lang.Iterable<T>.filterTo(var container: U, filter: (T)->Boolean) : U {
inline fun <T,U : Collection<in T>> java.lang.Iterable<T>.filterTo(var container: U, filter: fun(T): Boolean) : U {
for(element in this) { for(element in this) {
if(filter(element)) if(filter(element))
container.add(element) container.add(element)
} }
return container return container
} }
*/
/* /*
Create iterator filtering given java.lang.Iterable Create iterator filtering given java.lang.Iterable
*/ */
/* /*
inline fun <T> java.lang.Iterable<T>.filter(f: fun(T): Boolean) : java.util.Iterator<T> = (iterator() as java.util.Iterator<T>).filter(f) inline fun <T> java.lang.Iterable<T>.filter(f: (T)->Boolean) : java.util.Iterator<T> = (iterator() as java.util.Iterator<T>).filter(f)
*/ */
private class FilterIterator<T>(val original: java.util.Iterator<T>, val filter: (T)-> Boolean) : java.util.Iterator<T> { private class FilterIterator<T>(val original: java.util.Iterator<T>, val filter: (T)-> Boolean) : java.util.Iterator<T> {