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 functions, procedures, and tuples cannot be sent to streams.
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.1.2. Null and Identity
If null
or identity
is sent to a stream then the result is a
null or identity character being printed.
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.
12.2.1. Input Format
Whitespace will separate values in stdin, but take note that a whitespace character can also be read from stdin and assigned to a character variable.
A character
from stdin is the first byte that can be read from the stream.
If the end of the stream is encountered, then -1
is returned.
An integer
from stdin can take any legal format described in the
integer literal section. It may also be proceeded by
a single negative or positive sign.
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.
A boolean
input from stdin is either T
or F
.
When reading a value, if any other input were to be in the stream during the read then an error state is set. For example, the following program:
boolean b;
b <- std_input;
With the standard input stream containing this:
Ta
An error state would be set on the stream.
Type promotion is not performed for stream input.
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 value
returned is the type-appropriate null
.
Only when an error is encountered, the stream must be rewound to where it was
when the read started. This rewind includes any whitespace that may have been
skipped to in order to encounter the next token. This is because the subsequent
read may be for a character
which should successfully read the rewound
whitespace. For example, with this program:
integer i;
character c;
i <- std_input;
i <- std_input;
c <- std_input;
i -> std_output;
c -> std_output;
'$' -> std_output;
and the input stream (with *
representing ' '
):
5****10a
the output should be:
0 $
and the remaining input stream should be:
***10a
Because this means you may have to skip a potentially nearly-infinite amount of
whitespace, this specification limits the size of the “rewind
buffer” to 1024 characters. Therefore, no read from std_input
will require
more than 1KB of characters from the current stream position to the end of the
next token. This means that you will only ever need to maintain at most 1024
characters in a buffer (1025 if a '\0'
character is required).
Valid input that reaches the buffer end can be assumed to complete at that point and remain valid.
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 |
|
0 |
|
Integer |
error |
|
1 |
end of stream |
|
2 |
|
Real |
error |
|
1 |
end of stream |
|
2 |