

//
// lines
//

lines(f:File) = LineSequence(f);



//
// LineSequence
//

private record LineSequence (
    f : File,
);

overload iterator(x:LineSequence) = LineIterator(&x.f, false, String());



//
// LineIterator
//

private record LineIterator (
    file : Pointer[File],
    queued? : Bool,
    string : String,
);

overload hasNext?(x:LineIterator) {
    if (not x.queued?) {
        x.queued? = true;
        clear(x.string);
        readLine(x.file^, x.string);
    }
    return size(x.string) > 0;
}

overload next(x:LineIterator) {
    if (not x.queued?) {
        clear(x.string);
        readLine(x.file^, x.string);
    }
    else {
        x.queued? = false;
    }
    return ref x.string;
}
