12. Streams
Gazprea has two streams: std_output
and std_input
,
which are used for writting to stdout and reading from stdin respectively.
12.1. Output Stream
Output streams use the following syntax:
<exp> -> std_output;
12.1.1. Output Format
Values of the following base types are treated as follows when sent to an output stream:
Character: The character is printed.
Integer: Converted to a string representation, and then printed.
Real: Converted to a string representation, and then printed. This is the same behaviour as the %g specifier in printf.
Boolean: Prints T for true, and F for false.
Vectors print their contents according to the rules above, with square braces surrounding its elements and with spaces only between values. For example:
integer[*] v = 1..3;
v -> std_output;
prints the following:
[1 2 3]
Strings print their contents as a contiguous sequence of characters. For example:
string str = "Hello, World!";
str -> std_output;
prints the following:
Hello, World!
Matrices print like a vector of vectors. For example:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]] -> std_output;
prints the following:
[[1 2 3] [4 5 6] [7 8 9]]
No other type may be sent to a stream. For instance,
procedures with no return type and tuples cannot be sent to streams.
Also, empty vectors and matrices can be send to streams, but not empty
literals (e.g. []
), because they have no type.
Note that there is no automatic new line or spaces printed. To print a new line, a user must explicitly print the new line or space character. For example:
'\n' -> std_output;
' ' -> std_output;
12.2. Input Stream
Input streams use the following syntax:
<l-value> <- std_input;
An l-value may be anything that can appear on the left hand side of an assignment statement. Consider reading the discussion of an l-value here.
Input streams may only work on the following base types:
character
: Reads a single character from stdin. Note that there can be no error state for reading characters.integer
: Reads an integer from stdin. If an integer could not be read, an error state is set on this stream.real
: Reads a real from stdin. If a real could not be read, an error state is set on this stream.boolean
: Reads a boolean from stdin. If a boolean value could not be read, an error state is set on this stream.
Type promotion is not performed for stream input over any type.
12.2.1. Input Semantics
std_input
expects an input stream of values which do not need to be
whitespace separated. A read will consume the stream until a character or
EOF occurs that breaks the pattern match for the given types specifier. The longest
successful match is returned.
In general input stream semantics are designed for parity with scanf
.
The only differences are the Stream State, a boolean specifier
and a restriction on the maximum number of bytes that can be consumed in a single read to 512.
For each of the allowed types the semantics are given below.
Reading a character
from stdin consumes the first byte that can be read from the
stream. If the end of the stream is encountered, then a value of -1
is set. There
is no concept of skipping whitespace for characters, since space and escaped characters
must be readable.
An integer
from stdin can take any legal format described in the
integer literal section. It may also be preceded by
a single negative or positive sign. All preceeding whitespace before the number or
sign character may be skipped up to the limit imposed by the 512 byte read restriction.
A real
input from stdin can take any legal format described in the
real literal section with the exception that no
whitespace may be present. It may also be proceeded by a single negative or
positive sign. Preceeding whitespace may be skipped in the same way as integers.
A boolean
input from stdin is either T
or F
. Preceeding whitespace may be
skipped in the same way as integers and reals.
For the following program:
boolean b;
character c;
integer i;
real r;
b <- std_input;
i <- std_input;
c <- std_input;
r <- std_input;
format(b) || " " || format(r) -> std_output;
And this input (where ‘\t’ is TAB, ‘*’ is space, and each line ends with a newline (’\n’):
\tF\n
1\n
*1.\n
The output would be:
F 1.0
because the white space is consumed for characters and skipped for other types.
12.2.2. Error Handling
When reading boolean
, integer
, and real
from stdin, it is
possible that the end of the stream or an error is encountered. In order to
handle these situations Gazprea provides a built in procedure that is
implicitly defined in every file: stream_state
(see
Stream State).
Reading a character
can never cause an error. The character will either be
successfully read or the end of the stream will be reached and -1
will be
returned on this read.
Otherwise, when an error or the end of the stream is encountered, the the null value for the type is set and the input stream remains pointing where it was before the error occured.
The program below demonstrates 4 reads which set the error states 1,0,0,2 respectively.
integer ss;
integer i;
boolean b;
character c;
i <- std_input;
i -> std_output;
ss = stream_state(std_input);
ss -> std_output;
c <- std_input; //eat the .
i <- std_input;
i -> std_output;
c <- std_input;
ss = stream_state(std_input);
ss -> std_output;
With the input stream:
.7
And the expected output:
0172
This table summarizes an input stream’s possible error states after a read of a particular data type.
Type |
Situation |
Return |
|
---|---|---|---|
Boolean |
error |
|
1 |
end of stream |
|
2 |
|
Character |
error |
N/A |
N/A |
end of stream |
|
2 |
|
Integer |
error |
|
1 |
end of stream |
|
2 |
|
Real |
error |
|
1 |
end of stream |
|
2 |