# Module `course` - Course library

Course library.

The course library provides various simple utilities for occam programmers.

Strings (as handled by this library) are `BYTE` arrays left-justified with trailing `NULL`s. It is usually preferably to use mobile byte arrays (`MOBILE []BYTE`) to represent strings in modern occam-pi programs; the string features in this library exist for backwards compatibility.

To use this library:

    #INCLUDE "course.module"

## Index

- Group `ASCII` - Character values
  - Constant `BACK` - ASCII BS - backspace key
  - Constant `BELL` - ASCII BEL - terminal bell
  - Constant `DELETE` - ASCII DEL - delete key
  - Constant `ESCAPE` - ASCII ESC - escape key
  - Constant `NULL` - ASCII NUL
- Group `COMPARE.STRING` - Return values from
  - Constant `string.less` - Left less than right
  - Constant `string.more` - Left more than right
  - Constant `string.same` - Left and right the same
- Constant `END.OF.FILE` - End of file
- Constant `FLUSH` - Flush output buffer
- Process `ask.bool` - Read a boolean with a prompt
- Process `ask.byte` - Read a byte value in decimal with a prompt
- Process `ask.int` - Read an integer value in decimal with a prompt
- Process `ask.string` - Read a string with a prompt
- Process `black.hole` - Discard characters forever
- Process `buffer.set.bin8` - Adds a BYTE-sized integer to a string buffer in binary format
- Process `buffer.set.hex` - Adds an integer to a string buffer in hexadecimal format
- Process `buffer.set.int` - Adds an integer to a string buffer
- Process `buffer.set.real32` - Adds a REAL32 value to a string buffer
- Process `buffer.set.string` - Adds a string to a string buffer
- Function `byte.in.string` - Check if a string contains the given byte
- Function `compare.string` - Compares two strings for lexicographic ordering
- Process `copy.string` - Copy a string
- Process `course.HEXTOSTRING` - Format an INT as a hexadecimal string
- Process `course.REAL32TOSTRING` - Format a REAL32 number as a decimal string
- Process `course.REAL64TOSTRING` - Format a REAL64 number as a decimal string
- Process `cursor.down` - Move the cursor down
- Process `cursor.invisible` - Make cursor invisible
- Process `cursor.left` - Move the cursor left
- Process `cursor.right` - Move the cursor right
- Process `cursor.up` - Move the cursor up
- Process `cursor.visible` - Make cursor visible
- Process `cursor.x.y` - Place the cursor
- Function `ends.with.string` - Check if one string is a suffix of another
- Function `equal.string` - Compare two strings for equality
- Process `erase.bol` - Erase to beginning of line
- Process `erase.bos` - Erase to beginning of screen
- Process `erase.eol` - Erase to end of line
- Process `erase.eos` - Erase to end of screen
- Process `erase.line` - Erase whole line
- Process `erase.screen` - Erase whole screen
- Process `file.in.int` - Read an integer from a channel non-interactively
- Process `file.in.number` - Synonym for
- Process `file.in.string` - Read a string from a channel non-interactively
- Process `file.in.token` - Read a token from a channel non-interactively
- Process `flush` - Flush an output channel
- Process `goto.x.y` - Synonym for
- Process `in.bool` - Read a boolean
- Process `in.byte` - Read a byte value in decimal
- Process `in.digit` - Read a digit
- Process `in.int` - Read an integer value in decimal
- Process `in.skip` - Discard whitespace
- Process `in.string` - Read a string
- Process `make.string` - Converts a BYTE array into a string
- Process `out.bool` - Write a Boolean value to a channel (as TRUE / FALSE )
- Process `out.byte` - Write a byte in decimal to a channel
- Process `out.ch` - Write a character to a channel
- Process `out.hex` - Write an integer in hexadecimal to a channel
- Process `out.int` - Write an integer in decimal to a channel
- Process `out.number` - Synonym for
- Process `out.real32` - Write a REAL32 to a channel
- Process `out.real64` - Write a REAL64 to a channel
- Process `out.repeat` - Write a character repeatedly to a channel
- Process `out.string` - Write a string to a channel
- Process `out.yes.no` - Write a Boolean value to a channel (as yes / no )
- Process `pos.int` - Move cursor and write an integer
- Process `pos.yes.no` - Move cursor and write a Boolean value (as yes/no)
- Function `random` - Pseudorandom number generator
- Function `starts.with.string` - Check if one string is a prefix of another
- Function `string.to.int` - Convert a string containing a decimal integer to an INT
- Process `write.string` - Write a -padded string to a channel

## Declarations

### `random.occ`:46Function `random`

`INT, INT FUNCTION random (VAL INT upto, seed)`

Pseudorandom number generator. On 32-bit platforms, this is an implementation by David Morse of the "minimal standard" described in "Random number generators: Good ones are hard to find", Park, K.P. & Miller, K.W. (1988), Comm. ACM, 31(10), 1192-1201.

The routine must be called with a valid seed: an integer of between 1 and 2 147 483 647. The value of the seed must be preserved from one call of the function to the next. This implementation of the random number generator returns an integer lying between 0 and (`upto` - 1) inclusive as its first result, the seed is the second result.

The random number is full period, with a period of 2 ** 31, that is 2 147 483 647.

On 16-bit platforms, this is a much less impressive LFSR, with a period of (2 ** 16) - 1.

#### Parameters:

`VAL INT` | `upto` | The upper bound (exclusive) of the output value
`VAL INT` | `seed` | The input seed

#### Returns:

`INT` |  | The output value
`INT` |  | The output seed

### `file_in.occ`:31Process `file.in.string`

`PROC file.in.string ([]BYTE s, INT length, VAL INT max, CHAN BYTE in?)`

Read a string from a channel non-interactively. Lines are terminated by newline characters.

#### Parameters:

`[]BYTE` | `s` | Buffer to read into
`INT` | `length` | Number of bytes read
`VAL INT` | `max` | Maximum number of bytes to read
`CHAN BYTE` | `in` | Channel to read from

### `file_in.occ`:84Process `file.in.token`

`PROC file.in.token ([]BYTE t, INT length, VAL INT max, CHAN BYTE in?)`

Read a token from a channel non-interactively. Tokens are terminated by whitespace.

#### Parameters:

`[]BYTE` | `t` | Buffer to read into
`INT` | `length` | Number of bytes read
`VAL INT` | `max` | Maximum number of bytes to read
`CHAN BYTE` | `in` | Channel to read from

### `file_in.occ`:229Process `file.in.int`

`PROC file.in.int (INT n, VAL INT max, BOOL ok, CHAN BYTE in?)`

Read an integer from a channel non-interactively.

#### Parameters:

`INT` | `n` | Integer read
`VAL INT` | `max` | Maximum number of bytes to read
`BOOL` | `ok` | Whether a number was successfully read
`CHAN BYTE` | `in` | Channel to read from

### `file_in.occ`:257Process `file.in.number`

`PROC file.in.number (INT n, VAL INT max, BOOL ok, CHAN BYTE in?)`

Synonym for `file.in.int`.

Deprecated: do not use in new code.

### `stringbuf.occ`:31Process `buffer.set.string`

`PROC buffer.set.string ([]BYTE buf, INT len, VAL []BYTE to.add)`

Adds a string to a string buffer.

#### Parameters:

`[]BYTE` | `buf` | String buffer.
`INT` | `len` | Length of valid data in buffer.
`VAL []BYTE` | `to.add` | String to add.

### `stringbuf.occ`:51Process `buffer.set.int`

`PROC buffer.set.int ([]BYTE buf, INT len, VAL INT n)`

Adds an integer to a string buffer.

#### Parameters:

`[]BYTE` | `buf` | String buffer.
`INT` | `len` | Length of valid data in buffer.
`VAL INT` | `n` | Value of integer.

### `stringbuf.occ`:115Process `buffer.set.hex`

`PROC buffer.set.hex ([]BYTE buf, INT len, VAL INT n)`

Adds an integer to a string buffer in hexadecimal format.

#### Parameters:

`[]BYTE` | `buf` | String buffer.
`INT` | `len` | Length of valid data in buffer.
`VAL INT` | `n` | Value of integer.

### `stringbuf.occ`:159Process `buffer.set.bin8`

`PROC buffer.set.bin8 ([]BYTE buf, INT len, VAL BYTE n)`

Adds a BYTE-sized integer to a string buffer in binary format.

#### Parameters:

`[]BYTE` | `buf` | String buffer.
`INT` | `len` | Length of valid data in buffer.
`VAL BYTE` | `n` | Value of byte.

### `stringbuf.occ`:185Process `buffer.set.real32`

`PROC buffer.set.real32 ([]BYTE buf, INT len, VAL INT ip, dp, VAL REAL32 n)`

Adds a REAL32 value to a string buffer.

#### Parameters:

`[]BYTE` | `buf` | String buffer.
`INT` | `len` | Length of valid data in buffer.
`VAL INT` | `ip` | integer portion alignment.
`VAL INT` | `dp` | decimal portion alignment.
`VAL REAL32` | `n` | Value to put in buffer.

### `utils.occ`:34Process `out.repeat`

`PROC out.repeat (VAL BYTE ch, VAL INT n, CHAN BYTE out!)`

Write a character repeatedly to a channel. This outputs `ch` down the channel `out` `n` times. If `n` is negative, nothing happens.

#### Parameters:

`VAL BYTE` | `ch` | Character
`VAL INT` | `n` | Number of times to output (negative values result in no output)
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:55Process `out.ch`

`PROC out.ch (VAL BYTE ch, VAL INT field, CHAN BYTE out!)`

Write a character to a channel. This outputs `ch` in a fieldwidth `field` down `out`. If the fieldwidth is too wide for `ch`, it right-justifies `ch` with spaces on the left. If the field is not wide enough, it prints the `ch` anyway. These rules for fieldwidth are the same as those used by the Pascal `write` procedure.

#### Parameters:

`VAL BYTE` | `ch` | Character
`VAL INT` | `field` | Field width to right-justify in
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:69Process `out.string`

`PROC out.string (VAL []BYTE s, VAL INT field, CHAN BYTE out!)`

Write a string to a channel. This outputs `s` in a fieldwidth `field` down `out`.

#### Parameters:

`VAL []BYTE` | `s` | String
`VAL INT` | `field` | Field width to right-justify in
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:89Process `out.byte`

`PROC out.byte (VAL BYTE b, VAL INT field, CHAN BYTE out!)`

Write a byte in decimal to a channel. This outputs `b` in a fieldwidth `field` down `out`. If the fieldwidth is too wide for `b`, it right-justifies `b` with spaces on the left. If the field is not wide enough, it prints the `b` anyway. These rules for fieldwidth are the same as those used by the Pascal `write` procedure.

#### Parameters:

`VAL BYTE` | `b` | Byte
`VAL INT` | `field` | Field width to right-justify in
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:121Process `out.int`

`PROC out.int (VAL INT n, VAL INT field, CHAN BYTE out!)`

Write an integer in decimal to a channel. This outputs `n` in a fieldwidth `field` down `out`. The rules for fieldwidth are as `out.byte`.

#### Parameters:

`VAL INT` | `n` | Integer
`VAL INT` | `field` | Field width to right-justify in
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:186Process `out.hex`

`PROC out.hex (VAL INT n, VAL INT field, CHAN BYTE out!)`

Write an integer in hexadecimal to a channel. Aside from the output base, this behaves like `out.int`.

#### Parameters:

`VAL INT` | `n` | Integer
`VAL INT` | `field` | Field width to right-justify in
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:223Process `out.bool`

`PROC out.bool (VAL BOOL b, VAL INT field, CHAN BYTE out!)`

Write a Boolean value to a channel (as `TRUE`/`FALSE`). This outputs `b` as the string `TRUE` or `FALSE` in a fieldwidth `field` down `out`.

#### Parameters:

`VAL BOOL` | `b` | Boolean
`VAL INT` | `field` | Field width to right-justify in
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:240Process `out.yes.no`

`PROC out.yes.no (VAL BOOL b, VAL INT field, CHAN BYTE out!)`

Write a Boolean value to a channel (as `yes`/`no`). This outputs `b` as the string `yes` or `no` in a fieldwidth `field` down `out`.

#### Parameters:

`VAL BOOL` | `b` | Boolean
`VAL INT` | `field` | Field width to right-justify in
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:257Process `flush`

`PROC flush (CHAN BYTE out!)`

Flush an output channel. If `out` is (ultimately) connected to the external `stdout` or `stderr` channel, this forces UNIX to flush all outstanding output to that file descriptor. UNIX normally buffers this character output on a line-by-line basis.

#### Parameters:

`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:271Process `in.skip`

`PROC in.skip (BYTE ch, CHAN BYTE in?)`

Discard whitespace. This inputs from `in` until a non-space character is found. The non-space character is returned in `ch`.

#### Parameters:

`BYTE` | `ch` | The non-whitespace character
`CHAN BYTE` | `in` | Channel to read from

### `utils.occ`:288Process `in.digit`

`PROC in.digit (BYTE d, CHAN BYTE in?, out!)`

Read a digit. This inputs a digit from `in` into `d`. Non-digit characters are ignored and the `out` channel is beeped. The accepted digit is not echoed down `out`.

#### Parameters:

`BYTE` | `d` | The digit read
`CHAN BYTE` | `in` | Channel to read from
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:314Process `in.string`

`PROC in.string ([]BYTE s, INT length, VAL INT max, CHAN BYTE in?, out!)`

Read a string. This inputs a string of up to `max` characters from `in` into `s`. Input is terminated by a carriage-return or new-line (which is not included in `s`. The number of characters actually input is recorded in `length`. The string `s` is padded on the right with `NULL`s if necessary. All characters are echoed on `out`. The backspace (`BACK`) and delete (`DELETE`) characters are processed sensibly.

#### Parameters:

`[]BYTE` | `s` | Buffer to read into
`INT` | `length` | Number of bytes read
`VAL INT` | `max` | Maximum number of bytes to read
`CHAN BYTE` | `in` | Channel to read from
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:388Process `in.bool`

`PROC in.bool (BOOL b, CHAN BYTE in?, out!)`

Read a boolean. This reads a Boolean value as the characters `y` or `n` (or `Y` or `N`). Any other characters result in a `BELL` being sent to `out`. The value read is echoed as `yes` or `no`.

#### Parameters:

`BOOL` | `b` | The Boolean read
`CHAN BYTE` | `in` | Channel to read from
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:515Process `in.byte`

`PROC in.byte (BYTE b, VAL INT max, CHAN BYTE in?, out!)`

Read a byte value in decimal. This routine is used for inputting a BYTE value expressed as decimal digits. It inputs a string of up to `max` digits from `in` into `s`. If `max` is more than 3, it is truncated to 3. Input is terminated by a carriage-return, new-line or space. Input strings converting to values greater than 255 are rejected.

#### Parameters:

`BYTE` | `b` | Value read
`VAL INT` | `max` | Maximum number of bytes to read
`CHAN BYTE` | `in` | Channel to read from
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:735Process `in.int`

`PROC in.int (INT n, VAL INT max, CHAN BYTE in?, out!)`

Read an integer value in decimal. This routine is used for inputting an INT value expressed as decimal digits. It inputs a string of up to `max` characters from `in` into `s`. If `max` is more than 20, it is truncated to 20. The first character may be `+` or `-`. Input is terminated by a carriage-return, new-line or space. It does guard against overflow.

#### Parameters:

`INT` | `n` | Value read
`VAL INT` | `max` | Maximum number of bytes to read
`CHAN BYTE` | `in` | Channel to read from
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:783Process `black.hole`

`PROC black.hole (CHAN BYTE in?)`

Discard characters forever. This inputs characters from `in` forever. It is used to mask off unwanted `BYTE` streams.

#### Parameters:

`CHAN BYTE` | `in` | Channel to read from

### `utils.occ`:802Process `ask.string`

`PROC ask.string (VAL []BYTE prompt, []BYTE s, INT length, VAL INT max, CHAN BYTE in?, out!)`

Read a string with a prompt. This prints a prompt, calls `in.string`, then prints a newline.

#### Parameters:

`VAL []BYTE` | `prompt` | Prompt to print
`[]BYTE` | `s` | Buffer to read into
`INT` | `length` | Number of bytes read
`VAL INT` | `max` | Maximum number of bytes to read
`CHAN BYTE` | `in` | Channel to read from
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:822Process `ask.bool`

`PROC ask.bool (VAL []BYTE prompt, BOOL b, CHAN BYTE in?, out!)`

Read a boolean with a prompt. This prints a prompt, calls `in.bool`, then prints a newline.

#### Parameters:

`VAL []BYTE` | `prompt` | Prompt to print
`BOOL` | `b` | The Boolean read
`CHAN BYTE` | `in` | Channel to read from
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:842Process `ask.byte`

`PROC ask.byte (VAL []BYTE prompt, BYTE b, VAL INT max, CHAN BYTE in?, out!)`

Read a byte value in decimal with a prompt. This prints a prompt, calls `in.byte`, then prints a newline.

#### Parameters:

`VAL []BYTE` | `prompt` | Prompt to print
`BYTE` | `b` | Value read
`VAL INT` | `max` | Maximum number of bytes to read
`CHAN BYTE` | `in` | Channel to read from
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:861Process `ask.int`

`PROC ask.int (VAL []BYTE prompt, INT n, VAL INT max, CHAN BYTE in?, out!)`

Read an integer value in decimal with a prompt. This prints a prompt, calls `in.int`, then prints a newline.

#### Parameters:

`VAL []BYTE` | `prompt` | Prompt to print
`INT` | `n` | Value read
`VAL INT` | `max` | Maximum number of bytes to read
`CHAN BYTE` | `in` | Channel to read from
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:881Process `cursor.x.y`

`PROC cursor.x.y (VAL BYTE x, y, CHAN BYTE out!)`

Place the cursor. This outputs a VT220 control sequence down channel `out` to place the cursor at screen coordinates (`x`, `y`).

#### Parameters:

`VAL BYTE` | `x` | X coordinate
`VAL BYTE` | `y` | Y coordinate
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:899Process `cursor.up`

`PROC cursor.up (VAL BYTE n, CHAN BYTE out!)`

Move the cursor up. This outputs a VT220 control sequence down channel `out` to move the cursor up `n` positions.

#### Parameters:

`VAL BYTE` | `n` | Number of positions to move
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:915Process `cursor.down`

`PROC cursor.down (VAL BYTE n, CHAN BYTE out!)`

Move the cursor down. This outputs a VT220 control sequence down channel `out` to move the cursor down `n` positions.

#### Parameters:

`VAL BYTE` | `n` | Number of positions to move
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:931Process `cursor.right`

`PROC cursor.right (VAL BYTE n, CHAN BYTE out!)`

Move the cursor right. This outputs a VT220 control sequence down channel `out` to move the cursor right `n` positions.

#### Parameters:

`VAL BYTE` | `n` | Number of positions to move
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:947Process `cursor.left`

`PROC cursor.left (VAL BYTE n, CHAN BYTE out!)`

Move the cursor left. This outputs a VT220 control sequence down channel `out` to move the cursor left `n` positions.

#### Parameters:

`VAL BYTE` | `n` | Number of positions to move
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:962Process `erase.eol`

`PROC erase.eol (CHAN BYTE out!)`

Erase to end of line. This outputs a VT220 control sequence to erase characters from the current cursor position to the end of the screen line.

#### Parameters:

`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:977Process `erase.bol`

`PROC erase.bol (CHAN BYTE out!)`

Erase to beginning of line. This outputs a VT220 control sequence to erase characters from the current cursor position to the beginning of the screen line.

#### Parameters:

`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:992Process `erase.line`

`PROC erase.line (CHAN BYTE out!)`

Erase whole line. This outputs a VT220 control sequence to erase all characters on the current screen line.

#### Parameters:

`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:1007Process `erase.eos`

`PROC erase.eos (CHAN BYTE out!)`

Erase to end of screen. This outputs a VT220 control sequence to erase characters from the current cursor position to the end of the screen.

#### Parameters:

`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:1022Process `erase.bos`

`PROC erase.bos (CHAN BYTE out!)`

Erase to beginning of screen. This outputs a VT220 control sequence to erase characters from the current cursor position backwards to the start of the screen.

#### Parameters:

`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:1037Process `erase.screen`

`PROC erase.screen (CHAN BYTE out!)`

Erase whole screen. This outputs a VT220 control sequence to erase all characters from the screen.

#### Parameters:

`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:1051Process `cursor.visible`

`PROC cursor.visible (CHAN BYTE out!)`

Make cursor visible. This outputs a VT220 control sequence to make the cursor visible.

#### Parameters:

`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:1067Process `cursor.invisible`

`PROC cursor.invisible (CHAN BYTE out!)`

Make cursor invisible. This outputs a VT220 control sequence to make the cursor invisible.

#### Parameters:

`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:1089Process `pos.int`

`PROC pos.int (VAL INT col, row, n, field, CHAN BYTE out!)`

Move cursor and write an integer. This outputs a VT220 control sequence to place the cursor at screen coordinates (`col`, `row`) and output `n` in a fieldwidth of `field`.

#### Parameters:

`VAL INT` | `col` | X coordinate
`VAL INT` | `row` | Y coordinate
`VAL INT` | `n` | Integer
`VAL INT` | `field` | Field width to right-justify in
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:1107Process `pos.yes.no`

`PROC pos.yes.no (VAL INT col, row, VAL BOOL b, VAL INT field, CHAN BYTE out!)`

Move cursor and write a Boolean value (as yes/no). This outputs a VT220 control sequence to place the cursor at screen coordinates (`col`, `row`) and output `b` in a fieldwidth of `field`.

#### Parameters:

`VAL INT` | `col` | X coordinate
`VAL INT` | `row` | Y coordinate
`VAL BOOL` | `b` | Boolean
`VAL INT` | `field` | Field width to right-justify in
`CHAN BYTE` | `out` | Channel to write to

### `utils.occ`:1122Process `out.number`

`PROC out.number (VAL INT n, w, CHAN BYTE o!)`

Synonym for `out.int`.

Deprecated: do not use in new code.

### `utils.occ`:1127Process `goto.x.y`

`PROC goto.x.y (VAL INT x, y, CHAN BYTE o!)`

Synonym for `cursor.x.y`.

Deprecated: do not use in new code.

### `float_io.occ`:47Process `course.REAL32TOSTRING`

`PROC course.REAL32TOSTRING (RESULT INT len, RESULT []BYTE string, VAL REAL32 X, VAL INT Ip, Dp)`

Format a `REAL32` number as a decimal string.

`Ip` and `Dp` control how the number is formatted. If `Ip > 0` and `Dp > 0`, fixed-point format will be used with `Ip` digits before the point and `Dp` digits after the point. If `Ip = 0` and `Dp > 0`, exponential format will be used with `Dp` digits in the fraction. If `Ip = 0` and `Dp = 0`, a "reasonable" format will be chosen automatically.

#### Parameters:

`RESULT INT` | `len` | The number of characters (`BYTE`s) of string occupied by the formatted decimal representation of the real number
`RESULT []BYTE` | `string` | An array containing the formatted decimal representation of the real number in the first `len` bytes, the remaining bytes being undefined
`VAL REAL32` | `X` | The real number, in IEEE format, to be converted
`VAL INT` | `Ip` | The first of two formatting values
`VAL INT` | `Dp` | The second of two formatting values

### `float_io.occ`:1015Process `course.REAL64TOSTRING`

`PROC course.REAL64TOSTRING (RESULT INT len, RESULT []BYTE string, VAL REAL64 X, VAL INT Ip, Dp)`

Format a `REAL64` number as a decimal string.

`Ip` and `Dp` are interpreted as for `course.REAL32TOSTRING`.

#### Parameters:

`RESULT INT` | `len` | The number of characters (`BYTE`s) of string occupied by the formatted decimal representation of the real number
`RESULT []BYTE` | `string` | An array containing the formatted decimal representation of the real number in the first `len` bytes, the remaining bytes being undefined
`VAL REAL64` | `X` | The real number, in IEEE format, to be converted
`VAL INT` | `Ip` | The first of two formatting values
`VAL INT` | `Dp` | The second of two formatting values

### `float_io.occ`:2200Process `course.HEXTOSTRING`

`PROC course.HEXTOSTRING (INT len, []BYTE string, VAL INT n)`

Format an `INT` as a hexadecimal string.

#### Parameters:

`INT` | `len` | The number of characters written
`[]BYTE` | `string` | Buffer to write into
`VAL INT` | `n` | The number to write

### `float_io.occ`:2245Process `out.real32`

`PROC out.real32 (VAL REAL32 num, VAL INT ip, dp, CHAN BYTE out!)`

Write a `REAL32` to a channel. For the meaning of `ip` and `dp`, see `course.REAL32TOSTRING`.

#### Parameters:

`VAL REAL32` | `num` | The number to write
`VAL INT` | `ip` | First formatting parameter
`VAL INT` | `dp` | Second formatting parameter
`CHAN BYTE` | `out` | The channel to write to

### `float_io.occ`:2260Process `out.real64`

`PROC out.real64 (VAL REAL64 num, VAL INT ip, dp, CHAN BYTE out!)`

Write a `REAL64` to a channel. For the meaning of `ip` and `dp`, see `course.REAL32TOSTRING`.

#### Parameters:

`VAL REAL64` | `num` | The number to write
`VAL INT` | `ip` | First formatting parameter
`VAL INT` | `dp` | Second formatting parameter
`CHAN BYTE` | `out` | The channel to write to

### `string.occ`:34Process `make.string`

`PROC make.string ([]BYTE a, VAL INT length)`

Converts a `BYTE` array into a string. This is needed for strings that have been input using a counted-array protocol (where we know the length, but the string characters have been left-justified and the elements of the array after the string need setting to `NULL`).

#### Parameters:

`[]BYTE` | `a` | Array to convert
`VAL INT` | `length` | Length of string in `a`

### `string.occ`:52Process `copy.string`

`PROC copy.string (VAL []BYTE a, []BYTE b)`

Copy a string. This copies the string from `a` into `b`. If `a` is shorter than `b`, the string gets padded with `NULL`s. If `b` is shorter than `a`, the string gets truncated.

#### Parameters:

`VAL []BYTE` | `a` | Source string
`[]BYTE` | `b` | Destination string

### `string.occ`:78Function `equal.string`

`BOOL FUNCTION equal.string (VAL []BYTE a, b)`

Compare two strings for equality.

#### Parameters:

`VAL []BYTE` | `a` | One string
`VAL []BYTE` | `b` | Other string

#### Returns:

`BOOL` |  | Whether the two strings are equal

### `string.occ`:127Function `compare.string`

`INT FUNCTION compare.string (VAL []BYTE a, b)`

Compares two strings for lexicographic ordering.

#### Parameters:

`VAL []BYTE` | `a` | Left string
`VAL []BYTE` | `b` | Right string

#### Returns:

`INT` |  | `string.less` if `a` < `b`; `string.same` if `a` = `b`; `string.more` otherwise

### `string.occ`:191Function `starts.with.string`

`BOOL FUNCTION starts.with.string (VAL []BYTE needle, haystack)`

Check if one string is a prefix of another.

#### Parameters:

`VAL []BYTE` | `needle` | Possible prefix
`VAL []BYTE` | `haystack` | String to test

#### Returns:

`BOOL` |  | `TRUE` if `needle` is prefix of `haystack`, `FALSE` otherwise

### `string.occ`:212Function `ends.with.string`

`BOOL FUNCTION ends.with.string (VAL []BYTE needle, haystack)`

Check if one string is a suffix of another.

#### Parameters:

`VAL []BYTE` | `needle` | Possible suffix
`VAL []BYTE` | `haystack` | String to test

#### Returns:

`BOOL` |  | `TRUE` if `needle` is suffix of `haystack`, `FALSE` otherwise

### `string.occ`:233Function `byte.in.string`

`BOOL FUNCTION byte.in.string (VAL BYTE needle, VAL []BYTE haystack)`

Check if a string contains the given byte.

#### Parameters:

`VAL BYTE` | `needle` | Byte to search for
`VAL []BYTE` | `haystack` | String to search

#### Returns:

`BOOL` |  | `TRUE` if `needle` is in `haystack`, `FALSE` otherwise

### `string.occ`:251Function `string.to.int`

`BOOL, INT FUNCTION string.to.int (VAL []BYTE s)`

Convert a string containing a decimal integer to an `INT`.

#### Parameters:

`VAL []BYTE` | `s` | String to convert

#### Returns:

`BOOL` |  | `TRUE` if the conversion succeeded, `FALSE` otherwise
`INT` |  | The decimal number represented by the string, or `0` if the string could not be converted

### `string.occ`:275Process `write.string`

`PROC write.string (VAL []BYTE a, VAL INT field, CHAN BYTE out!)`

Write a `NULL`-padded string to a channel. This is similar to `out.string`, but correctly right-justifies the string when trailing `NULL`s are present.

#### Parameters:

`VAL []BYTE` | `a` | String to write
`VAL INT` | `field` | Field width to right-justify in
`CHAN BYTE` | `out` | Channel to write to

### `consts.inc`:37Group `ASCII`

``

Character values.

### `consts.inc`:38Constant `NULL`

`VAL BYTE NULL`

ASCII NUL

### `consts.inc`:39Constant `BELL`

`VAL BYTE BELL`

ASCII BEL - terminal bell

### `consts.inc`:40Constant `BACK`

`VAL BYTE BACK`

ASCII BS - backspace key

### `consts.inc`:41Constant `ESCAPE`

`VAL BYTE ESCAPE`

ASCII ESC - escape key

### `consts.inc`:42Constant `DELETE`

`VAL BYTE DELETE`

ASCII DEL - delete key

### `consts.inc`:46Constant `FLUSH`

`VAL BYTE FLUSH`

Flush output buffer

### `consts.inc`:47Constant `END.OF.FILE`

`VAL BYTE END.OF.FILE`

End of file

### `consts.inc`:50Group `COMPARE.STRING`

``

Return values from `compare.string`.

### `consts.inc`:51Constant `string.less`

`VAL INT string.less`

Left less than right

### `consts.inc`:52Constant `string.same`

`VAL INT string.same`

Left and right the same

### `consts.inc`:53Constant `string.more`

`VAL INT string.more`

Left more than right