KT-1076 reversed ranges
This commit is contained in:
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user