Permalink
Browse files

newclay/lib-clay new module io.splitting: Splitting adapter to extrac…

…t sequential subranges from a source or iterator
  • Loading branch information...
1 parent 22e1b35 commit 68248f95bbbd24c2d0ad3f4bf75dae3c7348e988 @jckarter jckarter committed Jun 20, 2011
View
130 newclay/lib-clay/io/splitting/splitting.clay
@@ -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);
+}
+
View
5 newclay/lib-clay/io/transformers/transformers.clay
@@ -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]);
View
4 newclay/test/io/splitting/File/foo.txt
@@ -0,0 +1,4 @@
+fee
+fie
+foe
+fum
View
26 newclay/test/io/splitting/File/main.clay
@@ -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");
+}
View
5 newclay/test/io/splitting/File/out.txt
@@ -0,0 +1,5 @@
+String("fee\n")
+String("fie\n")
+String("foe\n")
+String("fum\n")
+fin
View
26 newclay/test/io/splitting/Range/main.clay
@@ -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");
+}
View
6 newclay/test/io/splitting/Range/out.txt
@@ -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
View
29 newclay/test/io/splitting/Vector/main.clay
@@ -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");
+}
View
6 newclay/test/io/splitting/Vector/out.txt
@@ -0,0 +1,6 @@
+#SplittingCoordinateRange[ContiguousCoordinate[Char]]
+String("fee\n")
+String("fie\n")
+String("foe\n")
+String("fum\n")
+fin

0 comments on commit 68248f9

Please sign in to comment.