-
Julien Lopez authoredJulien Lopez authored
QIRList.java 1.78 KiB
package qir.ast.data;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Predicate;
import com.oracle.truffle.api.source.SourceSection;
import qir.ast.QIRNode;
import qir.driver.IQIRVisitor;
/**
* {@link QIRList} is the generic representation of a list in QIR.
*/
public abstract class QIRList extends QIRNode {
public QIRList(final SourceSection source) {
super(source);
}
private final QIRList iterate(final Predicate<QIRNode> p, final BiConsumer<Deque<QIRNode>, QIRNode> c) {
if (this instanceof QIRLnil)
return this;
final Deque<QIRNode> tmp = new ArrayDeque<>();
QIRList result = QIRLnil.getInstance();
for (QIRNode e = this; e instanceof QIRLcons && p.test(e); e = ((QIRLcons) e).getTail())
c.accept(tmp, ((QIRLcons) e).getValue());
for (QIRNode e : tmp)
result = new QIRLcons(null, e, result);
return result;
}
private final QIRList iterateAll(final BiConsumer<Deque<QIRNode>, QIRNode> c) {
return iterate(e -> true, c);
}
public final QIRList map(final Function<QIRNode, QIRNode> f) {
return iterateAll((stack, e) -> stack.push(f.apply(e)));
}
public final QIRList filter(final Function<QIRNode, Boolean> f) {
return iterateAll((stack, e) -> {
if (f.apply(e))
stack.push(e);
});
}
// TODO: That is ugly.
private long tmpLimit;
public final QIRList limit(final long limit) {
tmpLimit = limit;
return iterate(e -> tmpLimit-- > 0, (stack, e) -> stack.add(e));
}
@Override
public <T> T accept(final IQIRVisitor<T> visitor) {
return visitor.visit(this);
}
}