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 int myEndVar;
private int myCountVar;
private int myDeltaVar;
private int myIndexVar;
public ForInRangeLoopGenerator(JetForExpression expression, Type loopRangeType) {
super(expression, loopRangeType);
@@ -522,41 +524,73 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override
protected void generatePrologue() {
myEndVar = myFrameMap.enterTemp();
myIndexVar = lookupLocal(parameterDescriptor);
myCountVar = myFrameMap.enterTemp();
myDeltaVar = myFrameMap.enterTemp();
if(isIntRangeExpr(expression.getLoopRange())) {
JetBinaryExpression rangeExpression = (JetBinaryExpression) expression.getLoopRange();
//noinspection ConstantConditions
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);
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 {
gen(expression.getLoopRange(), loopRangeType);
v.dup();
v.dup();
v.invokevirtual("jet/IntRange", "getIteratorStart", "()I");
v.store(lookupLocal(parameterDescriptor), Type.INT_TYPE);
v.invokevirtual("jet/IntRange", "getEnd", "()I");
v.store(myEndVar, Type.INT_TYPE);
v.invokevirtual("jet/IntRange", "getStart", "()I");
v.store(myIndexVar, Type.INT_TYPE);
v.invokevirtual("jet/IntRange", "getSize", "()I");
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
protected void generateCondition(Type asmParamType, Label end) {
v.load(lookupLocal(parameterDescriptor), Type.INT_TYPE);
v.load(myEndVar, Type.INT_TYPE);
v.ificmpgt(end);
v.load(myCountVar, Type.INT_TYPE);
v.ifeq(end);
}
@Override
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
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");
// 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
*/
/*
inline fun <T,U : Collection<in T>> java.lang.Iterable<T>.filterTo(var container: U, filter: fun(T): Boolean) : U {
inline fun <T,U : Collection<in T>> java.lang.Iterable<T>.filterTo(var container: U, filter: (T)->Boolean) : U {
for(element in this) {
if(filter(element))
container.add(element)
}
return container
}
*/
/*
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> {