Input/Output Facilities

KEY Input/Output (I/O) facilities are provided to enable programs to read data from files or input devices, and send data to files or output devices. These facilities take the form of standard procedures, described below. (As explained in Section 7, standard procedures do not require to be specified before use; they are defined implicitly). All the procedures described refer to logical I/O channels to which numbers in the range 0-99 have been assigned. In some implementations certain channel numbers are reserved for system use. {EMAS IMP80: channels 0 and 81-99 are reserved for system defined devices. Channel numbers in the range 1-80 can be used for purposes defined by the user, subject only to the rule that a channel number can only refer to one channel at a time.} {IMP77: input channel n and output channel n are logically distinct.} Each implementation of the language provides facilities for linking these logical channels to particular files or I/O devices; refer to the relevant User Guide for information on this subject.
The primary I/O facilities in IMP use character information, that is, information that can be represented as sequences of characters. All the routines and functions use an Internal Character Code based on the ISO Code for the interchange of data (see Section 1). Some implementations of IMP may use other codes. Facilities are also provided to handle binary information, as a direct copy of the representation of values in the computer store. Two types of binary I/O are provided: Sequential Access for use when data is accessed (read or written) in the order in which it is held in the store, and Direct Access for use when data is accessed randomly from the store. All the binary I/O routines and functions are explicit, and so must be declared in each program in which they are used (see Section 5.2).

Character I/O

KEY All character handling routines and functions operate with respect to either the currently selected INPUT STREAM or the currently selected OUTPUT STREAM. An input or output stream corresponds to a logical I/O channel (described above), and is referenced by the appropriate channel number. All character I/O streams act upon continuous streams of ISO characters. Thus an input stream consists of a continuous stream of characters with an associated pointer which at any instant points to the next character to be input. Similarly, an output stream is able to accept a continuous stream of ISO characters. Naturally, there has to be some implementation-dependent mechanism for transferring these characters to and from files or physical devices, but this is hidden from the user. On entry to a program, default streams are selected for input and output. At any point in the program it is possible to redirect character input or output by a call of the standard procedure %routine SELECT INPUT(%integer I) or %routine SELECT OUTPUT(%integer I)
Each of these routines takes one integer parameter, the value of the logical channel number corresponding to the stream being selected. An event is signalled if the specified channel does not correspond to a valid input or output stream, as appropriate. Examples: SELECT OUTPUT(3) SELECT INPUT(I+17) After a call of SELECT INPUT, all calls of character input routines will operate on the selected input stream, until another call of SELECT INPUT is made or the end of the program is reached. The same rule applies to SELECT OUTPUT and character output routines and functions. In some implementations, both input and output characters may be buffered by the operating system into lines. This has the following unfortunate side effects when using SELECT INPUT and SELECT OUTPUT. If an input stream is reselected in a program, the first character read after reselection will be the first character in the line following the last line accessed, thus losing any characters not read from the previous line. When an output stream is selected, a newline character is output to the current output stream if there is anything in the line buffer, before the selection takes place.

Input of character data

KEY The procedures described below operate on the currently selected input stream. In all cases an event is signalled if an attempt is made to read beyond the end of the input stream. {EMAS IMP80: the following ISO codes (see Section 1) are ignored by these procedures: DEL (value 127), and all codes with values less than 32 apart from NL (10), EM (25) and SUB (26). If it is desired to read these codes, rather than ignore them, then the procedures READ CH and NEXT CH (described below) should be used.} %routine READ SYMBOL(%name I) This routine transfers the internal value of the next symbol from the current input stream into an integer variable of any permissible length (byte, long, etc). Example: READ SYMBOL(IN); ! IN is an %integer variable.
{IMP77: the actual parameter supplied can be of type %string, of any length, in which case a single character is read and held internally as a one-character string.} %integer %function NEXT SYMBOL This integer function returns the internal value of the next symbol on the current input stream. It does not move the pointer to the stream, so the next call of this or any other character input routine will access the same character again. Example: %if NEXT SYMBOL = 'a' %then .....
%routine SKIP SYMBOL This routine moves the pointer to the current input stream along one symbol without transferring any information to store. In the following example, SKIP SYMBOL and NEXTSYMBOL are used together to skip over a series of space characters. Example: SKIPSYMBOL %while NEXTSYMBOL = ' ' %routine READ STRING(%string(*)%name S) This routine is used to read a string into the string variable location specified by the parameter. The string should be in the format of an IMP80 string constant. Any spaces and newline characters which precede the double quote character at the start of the string will be ignored. An event will occur if the input stream does not contain a string constant, or if the input string overflows the location specified by the parameter.
{IMP77: READ STRING is not provided. Instead the routine READ, described below, is extended to accept a string name parameter and to read a string into it, as described above.} %routine READ ITEM(%string(*)%name S) This routine reads the next symbol from the current input stream and stores it as a string of length 1 in the string variable specified by the parameter. {IMP77: READ ITEM is not provided. Instead the routine READ SYMBOL has been extended, as described above, to accept a string name parameter.}
%string(*)%function NEXT ITEM This function reads the next symbol from the currently selected input stream without moving the pointer to the input stream (as with the function NEXTSYMBOL). The symbol is returned as a string of length 1. {IMP77: NEXT ITEM is not provided.}
{EMAS IMP80: the following '...CH' procedures are provided. They have the same effect as their '...SYMBOL' counterparts described above, except that they do not ignore any ISO characters. %routine READ CH(%integer %name I) This routine transfers the internal value of the next symbol from the current input stream into an %integer variable. %All characters of the ISO character set are passed back by READ CH. READ CH will pass back EM (the end message character) when end-of-file is reached and will signal an event if further reads on this file are requested. %routine NEXT CH This routine reads the next character from the input stream without moving the pointer to the stream (as with NEXTSYMBOL). All characters of the ISO character set, including End Message character (EM), are passed back by NEXT CH. }

Input of numeric data

KEY %routine READ(%name I) This routine is used to read numeric data into an arithmetic variable. The single parameter should be of type %integer or %real and of any length. The numbers being read should be written as described for decimal constants, except that no space characters may be included in the constants. Any space or newline characters which precede the number will be skipped by the routine; thus spaces and newlines can be freely used as separators between numbers. The number is terminated by any character in the input stream other than digit, +, -, . or @. On return from READ, the input stream pointer will be pointing to the character immediately following the number just read. Note that if an attempt is made to read either a real number, or a number with an exponent, into an integer variable, then the reading will stop at the decimal point or the "@" symbol, but no event will be signalled. However, an event will be signalled if the first character of a number is neither a sign, nor a decimal digit nor a decimal point. The same event will occur if the initial character is a decimal point but the parameter passed to READ is an integer. The range of values which can be read depends on the given parameter and on the implementation. {IMP77: the parameter to READ can be the name of a string, of any length, in which case the procedure behaves exactly like READ STRING, described above.}

Output of character data

KEY A number of procedures are provided to write individual characters or sequences of characters to the currently selected output stream. Note that when an interactive terminal is used, the symbols will only be transmitted when a 'trigger' character, normally newline (NL) or form feed (FF), is sent to the output stream. The basic character output procedure is PRINT SYMBOL; most of the other character output procedures operate via this procedure. %routine PRINT SYMBOL(%integer I) The parameter passed to this routine must be an integer expression which is evaluated by the routine. Any character whose value lies in the range 0-255 is transmitted to the output stream.
{EMAS IMP80: the parameter passed to this routine must be an integer expression. The expression is evaluated and the least significant 7 bits only are used by the routine. If the value of the expression corresponds to that of a symbol which could be read by READ SYMBOL (see above) then it is sent to the output stream; if not, the character SUB (code value 26) is sent.} Examples: PRINTSYMBOL('A') PRINTSYMBOL(I+J+32) %routine PRINT STRING(%string(255) S) This routine transmits to the currently selected output stream the string expression specified by the string parameter. {EMAS IMP80: PRINT STRING operates effectively as a series of PRINT SYMBOL calls. Thus certain characters will be replaced by SUB, as explained above.}
{EMAS IMP80: %routine PRINT CH(%integer I) This routine behaves exactly like the standard version of PRINT SYMBOL, i.e. any character whose code value lies in the range 0-255 is transmitted to the output stream. } There are a few other standard procedures provided to simplify the output of text. SPACE transmits one space character to the currently selected output stream SPACES(N) transmits N space characters to the currently selected output stream, where N is an integer expression. NEWLINE transmits one newline character to the currently selected output stream.
NEWLINES(N) transmits N newline characters to the currently selected output stream, where N is an integer expression. NEW PAGE transmits one Form Feed (FF) character to the currently selected output stream. {IMP77: NEW PAGE is not provided.}

Output of Numeric Data

KEY Three routines are provided to allow output of numeric information. WRITE is used to transmit the value of integer expressions; PRINT and PRINTFL transmit the values of real expressions in floating point form. %routine WRITE(%integer I, J) This routine transmits the value of the integer expression I to the currently selected output stream. The second parameter specifies the number of positions to be used. To simplify the alignment of positive and negative numbers, an additional position is allowed for a sign, but the sign is only printed in the case of negative numbers. If the number to be printed needs more positions than are specified by the second parameter, then more positions are used. Examples: WRITE(I, 4) WRITE(TOTAL+SUM+ROW(I), 6) WRITE(SNAP, POS+4)
{IMP77: the total number of print positions to be used is defined by the modulus of the second parameter. If this parameter is negative, no space character is output before a positive value.} %routine PRINT(%long %real X, %integer I, J) This routine transmits to the currently selected output stream the value of the real expression specified by the first parameter. The second and third parameters should be integer expressions specifying the number of places to be allowed before and after the decimal point. If the integer part needs more positions than are specified by the parameter, then more positions will be taken. One position is allowed for a sign which is printed only in the negative case. If necessary, the fractional part will be rounded. Examples: PRINT(A, 2, 3) PRINT(COS(A-B), 1, 10) {IMP77: The second parameter is interpreted in the same way as the second parameter of WRITE (described above).}
%routine PRINT FL(%longreal X, %integer I) This routine transmits to the currently selected output stream the value of the real expression specified by the first parameter. The second parameter specifies the number of places to be allowed after the decimal point. The printed number takes up the specified number of places, plus 7 additional places. Example: PRINT FL(X,4) If X has the value 17.63584, this would be printed as 1.7636@ 1. The number is standardised in the range 1 <= X < 10. One position each is allowed for signs for mantissa and exponent; in each case the sign is only printed when negative.

Closing streams

KEY All input and output streams are closed automatically when the program terminates. However, to close a stream during the running of a program, a call of the appropriate routine is necessary. {EMAS IMP80: %routine CLOSE STREAM(%integer I)} The parameter must be an integer expression which will evaluate to the number of the stream to be closed. The currently selected input or output stream cannot be closed, and any attempt to do so will cause an event to be signalled. {IMP77: %routine CLOSE INPUT %ROUTINE CLOSE OUTPUT In each case the routine closes the CURRENT stream, input or output as appropriate. The input or output stream then becomes null, until another channel is selected by use of SELECT INPUT or SELECT OUTPUT.
RESET INPUT This routine resets the current input stream to the start of the file. RESET OUTPUT This routine throws away all output on the current stream. } If a stream is closed and then reselected for input, the pointer to the stream will be positioned at the start of the file. Thus a file can be re-read, or a file written earlier in the program can be read. In the same way, if a stream is closed and then reselected for output, the pointer to the file is left at the start of the file. Thus any information in the file at the time it is reselected will be overwritten by data transmitted to the file after reselection.

Binary I/O

KEY Binary I/O facilities are provided by procedures which must be specified explicitly. They do not form part of the IMP80 language, but a list and brief explanation is given in Appendix B for some implementations. A more detailed description of the procedures can be found in the appropriate User Guide or Library Manual.