Skip to content

Commit

Permalink
newclay/lib-clay new module io.splitting: Splitting adapter to extrac…
Browse files Browse the repository at this point in the history
…t sequential subranges from a source or iterator
  • Loading branch information
jckarter committed Jun 20, 2011
1 parent 9110038 commit f3a71f8
Show file tree
Hide file tree
Showing 9 changed files with 234 additions and 3 deletions.
130 changes: 130 additions & 0 deletions newclay/lib-clay/io/splitting/splitting.clay
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import containers.(Container?, push, resize);
import io.transformers.(SlicedUpto);
import unsafe.coordinates.(Coordinate?, RandomAccessCoordinate?, CoordinateRange);
import vectors.(Vector);


//
// splitting interface
//

define getSplit;
define resetSplit;

detachSplit(ref i) {
var split = getSplit(i);
resetSplit(i);
return split;
}


//
// SplittingCoordinateRange
//

define SplittingCoordinateRange['C] as RecordType(
fromBegin:'C,
begin:'C,
end:'C,
);

overload #Savable?(SplittingCoordinateRange['C]) = true;
overload #Reliable?(SplittingCoordinateRange['C]) = Reliable?('C);

overload hasFront?(r:SplittingCoordinateRange['C]) | Coordinate?('C) = r.begin < r.end;
overload front(r:SplittingCoordinateRange['C]) | Coordinate?('C) {
assert(-> r.begin < r.end, "invalid ", SplittingCoordinateRange['C]);
return forward ..(r.begin^);
}
overload incFront(ref r:SplittingCoordinateRange['C])
| Coordinate?('C)
{ inc(r.begin); }

overload seekFront(ref r:SplittingCoordinateRange['C], distance:UInt)
| RandomAccessCoordinate?('C)
{ r.begin += distance; }

overload getSplit(r:SplittingCoordinateRange['C]) {
assert(-> r.fromBegin <= r.begin, "invalid ", SplittingCoordinateRange['C]);
return CoordinateRange(r.fromBegin, r.begin);
}

overload resetSplit(ref r:SplittingCoordinateRange['C]) {
r.fromBegin = r.begin;
}


//
// SplittingIterator (for savable iterators)
//

define SplittingIterator['I] as RecordType(
originalIterator:'I,
iterator:'I,
distance:UInt,
);

overload #Savable?(SplittingIterator['I]) = true;
overload #Reliable?(SplittingIterator['I]) = Reliable?('I);

overload hasFront?(i:SplittingIterator['I]) | Iterator?('I)
= hasFront?(i.iterator);
overload front(i:SplittingIterator['I]) | Iterator?('I)
= forward ..front(i.iterator);
overload incFront(ref i:SplittingIterator['I]) | Iterator?('I) {
incFront(i.iterator);
inc(i.distance);
}

overload seekFront(ref i:SplittingIterator['I], distance:UInt) | SeekableIterator?('I) {
seekFront(i.iterator, distance);
i.distance += distance;
}

overload getSplit(i:SplittingIterator['I]) = SlicedUpto(i.originalIterator, i.distance);
overload resetSplit(ref i:SplittingIterator['I]) {
i.originalIterator = save(i.iterator);
i.distance = 0u;
}


//
// SplittingSource (for non-savable iterators)
//

define SplittingSource['S, 'Container] as RecordType(
front:'Container,
source:'S,
);

overload read1(ref s:SplittingSource['S, 'C]) {
return maybe(read1(s.source),
(..elt) -> {
push(s.front, ..elt);
return just(..elt);
}
);
}

overload getSplit(s:SplittingSource['S, 'C]) = s.front;

overload resetSplit(ref s:SplittingSource['S, 'C]) {
resize(s.front, 0u);
}


//
// Splitting adapter
//

Splitting(forward s:'S) inline | Source?('S)
= SplittingSource['S, Vector[sourceValueType('S)]](Vector[sourceValueType('S)](), s);
overload Splitting(forward i:'I) inline | Iterator?('I) and Savable?('I) {
var savedi = save(i);
return SplittingIterator['I](savedi, savedi);
}
overload Splitting(forward r:CoordinateRange['C]) inline | Coordinate?('C) {
var begin, end = ..*r;
return SplittingCoordinateRange['C](begin, begin, end);
}

5 changes: 2 additions & 3 deletions newclay/lib-clay/io/transformers/transformers.clay
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,14 @@ overload size(x:Reversed['I]) inline
| SizedIterator?('I)
= size(*x);

overload #Savable?(Reversed['I]) = 'I;
overload #Reliable?(Reversed['I]) = 'I;
overload #Savable?(Reversed['I]) = Savable?('I);
overload #Reliable?(Reversed['I]) = Reliable?('I);


//
// zipped
//

// XXX capture sequences
define Zipped[..'I] as NewType(Tuple[..'I]);

private initializeZipped(forward ..seqs:'SS) inline = Zipped[..'SS]([..seqs]);
Expand Down
4 changes: 4 additions & 0 deletions newclay/test/io/splitting/File/foo.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fee
fie
foe
fum
26 changes: 26 additions & 0 deletions newclay/test/io/splitting/File/main.clay
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import io.stdio.(InputFile);
import io.splitting.(Splitting, detachSplit);
import printing.(printlnRepr, println);
import strings.(String);
import strings.encodings.utf8.(UTF8);

getline(ref splitter) {
while (maybe(read1(splitter),
(c) -> c != '\n',
-> false,
));

return detachSplit(splitter);
}

main() {
var file = UTF8(InputFile("foo.txt")), src = Splitting(source(file));

while (true) {
var line = getline(src);
if (empty?(line))
break;
printlnRepr(String(line));
}
println("fin");
}
5 changes: 5 additions & 0 deletions newclay/test/io/splitting/File/out.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
String("fee\n")
String("fie\n")
String("foe\n")
String("fum\n")
fin
26 changes: 26 additions & 0 deletions newclay/test/io/splitting/Range/main.clay
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import io.splitting.(Splitting, detachSplit);
import printing.(printlnRepr, println);
import vectors.(Vector);

powerof2?(x:Int) = bitand(x, x - 1) == 0;

getpowerof2(ref splitter) {
while (maybe(read1(splitter),
(x) -> not powerof2?(x),
-> false,
));

return detachSplit(splitter);
}

main() {
var range = Range(1, 17), iter = Splitting(range);

while (true) {
var line = getpowerof2(iter);
if (empty?(line))
break;
printlnRepr(Vector(line));
}
println("fin");
}
6 changes: 6 additions & 0 deletions newclay/test/io/splitting/Range/out.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Vector[Int](1i)
Vector[Int](2i)
Vector[Int](3i, 4i)
Vector[Int](5i, 6i, 7i, 8i)
Vector[Int](9i, 10i, 11i, 12i, 13i, 14i, 15i, 16i)
fin
29 changes: 29 additions & 0 deletions newclay/test/io/splitting/Vector/main.clay
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import io.splitting.(Splitting, detachSplit);
import printing.(printlnRepr, println);
import strings.(String);
import strings.encodings.utf8.(UTF8);
import vectors.(Vector);

getline(ref splitter) {
while (maybe(read1(splitter),
(c) -> c != '\n',
-> false,
));

return detachSplit(splitter);
}

main() {
var input = Vector[Char]("fee\nfie\nfoe\nfum\n"),
iter = Splitting(iterator(input));

printlnRepr(#type(-> iter));

while (true) {
var line = getline(iter);
if (empty?(line))
break;
printlnRepr(String(line));
}
println("fin");
}
6 changes: 6 additions & 0 deletions newclay/test/io/splitting/Vector/out.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#SplittingCoordinateRange[ContiguousCoordinate[Char]]
String("fee\n")
String("fie\n")
String("foe\n")
String("fum\n")
fin

0 comments on commit f3a71f8

Please sign in to comment.