Usage
textReader(f, g)
Signature
textReader: (() Character, Character ()) %
Parameter | Type | Description |
---|---|---|
f | () Character | the single-character read function |
g | Character () | the single-character pushback function |
Returns
Returns the input stream for which reads a character and pushes back the character c.
Example
textReader can be used to modify existing readers by ``hooking'' their read! and push! functions in order to customize their behavior. For example, the following function counter transforms any TextReader into one that keeps track of the number of characters and lines read from it.
macro COUNT == Record(chars:MachineInteger, lines:MachineInteger); counter(rd:TextReader, ct:COUNT):TextReader == { ct.chars := ct.lines := 0; -- initialize counts to 0 textReader(readAndCount!(rd, ct), pushAndCount!(rd, ct)); } local readAndCount!(rd:TextReader, ct:COUNT)():Character == { c := read! rd; if c ~= eof then ct.chars := next(ct.chars); if c = newline then ct.lines := next(ct.lines); c; } local pushAndCount!(rd:TextReader, ct:COUNT)(c:Character):() == { if c ~= eof then ct.chars := prev(ct.chars); if c = newline then ct.lines := prev(ct.lines); push!(c, rd); }
With the above function, the statements
cnt:COUNT := [0, 0]; countin := counter(stdin, cnt);
produces the reader countin that reads from stdin while side-effecting the variable cnt in order to keep track of the characters and lines read.