# Miscellaneous

- Module CharClass
- Modules LowReal and LowLong
- Module Storage
- Module SysClock

## Module CharClass

The full set of values of the character type (the elementary type denoted by the pervasive identifier `CHAR`) is implementation-defined. The module `CharClass` allows a program to determine the classification of a given value of the character type of an implementation in a way that does not rely on there being a known literal representation of all members of the character set.

The module `CharClass` provides predicates to test if a given value of the character type in an implementation is classified as a numeric, a letter, an upper-case letter, a lower-case letter, a value representing a control function, or as white space.

- IsNumeric - Test for numeric character
- IsLetter - Test for letter
- IsUpper - Test for upper case letter
- IsLower - Test for lower case letter
- IsControl - Test for control character
- IsWhiteSpace - Test for white space character

### IsNumeric - Test for numeric character

    PROCEDURE IsNumeric (ch: CHAR): BOOLEAN;

Module `CharClass`

The function procedure `IsNumeric` returns `TRUE` if `ch` is a member of an implementation-defined set of numeric characters that should include the decimal digits, and `FALSE` otherwise.

### IsLetter - Test for letter

    PROCEDURE IsLetter (ch: CHAR): BOOLEAN;

Module `CharClass`

The function procedure `IsLetter` returns `TRUE` if `ch` is a member of an implementation-defined set of letters that should include the required letters, and `FALSE` otherwise.

### IsUpper - Test for upper case letter

    PROCEDURE IsUpper (ch: CHAR): BOOLEAN;

Module `CharClass`

The function procedure `IsUpper` returns `TRUE` if `ch` is a member of an implementation-defined set of upper case letters that should include the required upper case letters, and `FALSE` otherwise.

### IsLower - Test for lower case letter

    PROCEDURE IsLower (ch: CHAR): BOOLEAN;

Module `CharClass`

The function procedure `IsLower` returns `TRUE` if `ch` is a member of an implementation-defined set of lower case letters that should include the required lower case letters, and `FALSE` otherwise.

### IsControl - Test for control character

    PROCEDURE IsControl (ch: CHAR): BOOLEAN;

Module `CharClass`

The function procedure `IsControl` returns `TRUE` if `ch` is a member of an implementation-defined set of characters that represent control functions, and `FALSE` otherwise.

### IsWhiteSpace - Test for white space character

    PROCEDURE IsWhiteSpace (ch: CHAR): BOOLEAN;

Module `CharClass`

The function procedure `IsWhiteSpace` returns `TRUE` if `ch` is either a space character or a member of an implementation-defined set of characters that represent format effectors, and `FALSE` otherwise.

## Modules LowReal and LowLong

Two modules are provided to give access to the underlying properties of the types `REAL` and `LONGREAL`. The two modules share common concepts, functions and values, and hence both modules are considered together.

The module `LowReal` gives access to the underlying properties of the type `REAL`, while `LowLong` gives access to the same properties for the type `LONGREAL`.

For implementations that conform to ISO/IEC 10967-1:199x Information technology - Language independent arithmetic - Part1: Integer and floating point arithmetic, a more precise specification is given in that International Standard.

If the implementation of the corresponding real number type conforms to ISO/IEC 10967-1:199x (LIA-1), procedure functions of a similar name correspond to the operations required by that International Standard.

- Constants and Types -
- exponent - Exponent value
- fraction - Significand part
- sign - Signum
- succ - Next greater value
- ulp - Unit in the last place
- pred - Previous less value
- intpart - Integral part
- fractpart - Fractional part
- scale - Scale
- trunc - Truncate
- round - Round
- synthesize - Construct value
- setMode - Set status flags
- currentMode - Current status flags
- IsLowException - Query exceptional state

### Constants and Types -

    CONST
      radix = <implementation-defined whole number value>;
      places = <implementation-defined whole number value>;
      expoMin = <implementation-defined whole number value>;
      expoMax = <implementation-defined whole number value>;
      large = <implementation-defined real number value>;
      small = <implementation-defined real number value>;
      IEC559 = <implementation-defined BOOLEAN value>;
      LIA1 = <implementation-defined BOOLEAN value>;
      rounds = <implementation-defined BOOLEAN value>;
      gUnderflow = <implementation-defined BOOLEAN value>;
      exception = <implementation-defined BOOLEAN value>;
      extend = <implementation-defined BOOLEAN value>;
      nModes = <implementation-defined whole number value>;
    TYPE
      Modes = PACKEDSET OF [0 .. nModes-1];

Modules: `LowReal`, `LowLong`

The values denoted by the constant identifiers exported from `LowReal` and `LowLong` are the implementation-defined values specified below.

If an implementation provides facilities for dynamically changing the properties of the real number types, the constant values refer to the default properties.

The value of `places`, and the other facilities in these modules, refer only to the representation used to store values.

NOTE: Some implementations may choose to compute expressions to greater precision than that used to store values.

If the implementation of the corresponding real number type conforms to ISO/IEC 10967-1:199x (LIA-1), the following correspondences hold:

NOTE: The value of the parameter `fmax`, required by ISO/IEC 10967-1:199x, is given by the predefined function `MAX` when applied to the corresponding real number type.

`radix`
  The whole number value of the radix used to represent the corresponding real number values.
`places`
  The whole number value of the number of `radix` places used to store values of the corresponding real number type.
`expoMin`
  The whole number value of the exponent minimum.
`expoMax`
  The whole number value of the exponent maximum. NOTE: An implementation may choose values such that `expoMin = expoMax` (which will presumably be the case for a fixed point representation).
`large`
  The largest value of the corresponding real number type. NOTE: On some implementations this may be a machine representation of infinity.
`small`
  The smallest positive value of the corresponding real number type, represented to maximal precision. NOTE: If an implementation has stored values strictly between 0.0 and `small`, then presumably the implementation supports gradual underflow.
`IEC559`
  A Boolean value that is true if and only if the implementation of the corresponding real number type conforms to IEC 559:1989 (IEEE 754:1987) in all regards.

  NOTES:

  - If `IEC559` is true, the value of radix is `2`.

  - If `LowReal.IEC559` is true, the 32-bit format of IEC 559:1989 is used for the type REAL.

  - If `LowLong.IEC559` is true, the 64-bit format of IEC 559:1989 is used for the type LONGREAL.
`LIA1`
  A Boolean value that is true if and only if the implementation of the corresponding real number type conforms to ISO/IEC 10967-1:199x (LIA-1) in all regards: parameters, arithmetic, exceptions, and notification.

  NOTE: For implementations not conforming to ISO/IEC 10967-1:199x, the corresponding properties are implementation-defined | see 6.8.2.2.

`rounds`
  A Boolean value that is true if and only if each operation produces a result that is one of the values of the corresponding real number type nearest to the mathematical result.

  NOTE: If `rounds` is true, and the mathematical result lies mid-way between two values of the corresponding real number type, then the selection from the two possible values is implementation-dependent.

`gUnderflow`
  A Boolean value that is true if and only if there are values of the corresponding real number type between 0.0 and `small`.
`exception`
  A Boolean value that is true if and only if every operation that attempts to produce a real value out of range raises an exception.
`extend`
  A Boolean value that is true if and only if expressions of the corresponding real number type are computed to higher precision than the stored values.

  NOTE: If `extend` is true, then values greater than `large` can be computed in expressions, but cannot be stored in variables.

`nModes`
  The whole number value giving the number of bit positions needed for the status flags for mode control.

### exponent - Exponent value

    PROCEDURE exponent (x: REAL): INTEGER;
    PROCEDURE exponent (x: LONGREAL): INTEGER;

Modules: `LowReal`, `LowLong`

The function procedure `exponent` returns the exponent value of `x` that lies between `expoMin` and `expoMax`. An exception occurs and may be raised if `x` is equal to 0.0.

### fraction - Significand part

    PROCEDURE fraction (x: REAL): REAL;
    PROCEDURE fraction (x: LONGREAL): LONGREAL;

Modules: `LowReal`, `LowLong`

The function procedure `fraction` returns the significand (or significant) part of `x`. Hence the following relationship shall hold:

`x = scale(fraction(x), exponent(x))`

### sign - Signum

    PROCEDURE sign (x: REAL): REAL;
    PROCEDURE sign (x: LONGREAL): LONGREAL;

Modules: `LowReal`, `LowLong`

The function procedure `sign` returns 1.0 if `x` is greater than 0.0, -1.0 if `x` is less than 0.0, or either 1.0 or -1.0 if `x` is equal to 0.0.

NOTE: The uncertainty about the handling of 0.0 is to allow for systems that distinguish between +0.0 and -0.0 (such as IEEE 754 systems).

### succ - Next greater value

    PROCEDURE succ (x: REAL): REAL;
    PROCEDURE succ (x: LONGREAL): LONGREAL;

Modules: `LowReal`, `LowLong`

The function procedure `succ` returns the next value of the corresponding real number type greater than `x`, if such a value exists; otherwise an exception occurs and may be raised.

### ulp - Unit in the last place

    PROCEDURE ulp (x: REAL): REAL;
    PROCEDURE ulp (x: LONGREAL): LONGREAL;

Modules: `LowReal`, `LowLong`

The function procedure `ulp` returns the value of the corresponding real number type equal to a unit in the last place of `x`, if such a value exists; otherwise an exception occurs and may be raised.

NOTE: Thus, when the value exists, either `ulp(x) = succ(x)-x` or `ulp(x) = x-pred(x)` or both is true.

### pred - Previous less value

    PROCEDURE pred (x: REAL): REAL;
    PROCEDURE pred (x: LONGREAL): LONGREAL;

Modules: `LowReal`, `LowLong`

The function procedure `pred` returns the next value of the corresponding real number type less than `x`, if such a value exists; otherwise an exception occurs and may be raised.

### intpart - Integral part

    PROCEDURE intpart (x: REAL): REAL;
    PROCEDURE intpart (x: LONGREAL): LONGREAL;

Modules: `LowReal`, `LowLong`

The function procedure `intpart` returns the integral part of `x`. For negative values, this shall be `-intpart(abs(x))`.

### fractpart - Fractional part

    PROCEDURE fractpart (x: REAL): REAL;
    PROCEDURE fractpart (x: LONGREAL): LONGREAL;

Modules: `LowReal`, `LowLong`

The function procedure `fractpart` returns the fractional part of `x`. This satisfies the relationship `fractpart(x)+intpart(x)=x`.

### scale - Scale

    PROCEDURE scale (x: REAL; n: INTEGER): REAL;
    PROCEDURE scale (x: LONGREAL; n: INTEGER): LONGREAL;

Modules: `LowReal`, `LowLong`

The function procedure `scale` returns the value `x * radix ** n` if such a value exists; otherwise an exception occurs and may be raised.

### trunc - Truncate

    PROCEDURE trunc (x: REAL; n: INTEGER): REAL;
    PROCEDURE trunc (x: LONGREAL; n: INTEGER): LONGREAL;

Modules: `LowReal`, `LowLong`

The function procedure `trunc` returns the value of the most significant `n` places of `x`. An exception occurs and may be raised if `n` is less than or equal to zero.

### round - Round

    PROCEDURE round (x: REAL; n: INTEGER): REAL;
    PROCEDURE round (x: LONGREAL; n: INTEGER): LONGREAL;

Modules: `LowReal`, `LowLong`

The function procedure `round` returns the value of `x` rounded to the most significant `n` places. An exception occurs and may be raised if such a value does not exist, or if `n` is less than or equal to zero.

### synthesize - Construct value

    PROCEDURE synthesize (expart : INTEGER;
                          frapart: REAL): REAL;
    PROCEDURE synthesize (expart : INTEGER;
                          frapart: LONGREAL): LONGREAL;

Modules: `LowReal`, `LowLong`

The function procedure `synthesize` returns a value of the corresponding real number type constructed from the values of `expart` and `frapart`. This value shall satisfy the relationship:
`synthesize(exponent(x),fraction(x))=x`

### setMode - Set status flags

    PROCEDURE setMode (m: Modes);
    PROCEDURE setMode (m: Modes);

Modules: `LowReal`, `LowLong`

The procedure setMode sets status flags from the value of `m`, appropriate to the underlying implementation of the corresponding real number type. NOTES:

- Many implementations of floating point provide options for setting status flags within the system which control details of the handling of the type. Although two procedures are provided, one for each real number type, the effect may be the same. Typical effects that can be obtained by this means are:

  - Ensuring that overflow will raise an exception;

  - Allowing underflow to raise an exception;

  - Controlling the rounding;

  - Allowing special values to be produced (e.g. NaNs in implementations conforming to IEC 559:1989 (IEEE 754:1987));

  - Ensuring that special value access will raise an exception;
  Since these effects are so varied, the values of type `Modes` that may be used are not specified by this International Standard.

- The effect of `setMode` on operations on values of the corresponding real number type in coroutines other than the calling coroutine is not defined. Implementations are not required to preserve the status flags (if any) with the coroutine state.

### currentMode - Current status flags

    PROCEDURE currentMode (): Modes;
    PROCEDURE currentMode (): Modes;

Modules: `LowReal`, `LowLong`

The function procedure `currentMode` returns the current status flags (in the form set by `setMode`), or the default status flags (if `setMode` is not used).

NOTE: The returned value is not necessarily the value set by `setMode`, since a call of `setMode` might attempt to set flags that cannot be set by the program.

### IsLowException - Query exceptional state

    PROCEDURE IsLowException (): BOOLEAN;
    PROCEDURE IsLowException (): BOOLEAN;

Modules: `LowReal`, `LowLong`

If the calling coroutine is in the state of exceptional execution because of the raising of the `LowReal` exception, the function procedure `LowReal.IsLowException` returns `TRUE`; otherwise is returns `FALSE`.

If the calling coroutine is in the state of exceptional execution because of the raising of the `LowLong` exception, the function procedure `LowLong.IsLowException` returns `TRUE`; otherwise is returns `FALSE`.

## Module Storage

The module `Storage` provides facilities for dynamically allocating and deallocating storage for variables that are not declared in variable declarations. Variables with storage allocated in this way are designated by dereferenced variable designators. The facilities are often invoked by using the predefined procedures `NEW` and `DISPOSE`. The facilities can also be used to allocate storage to be used as coroutine workspace.

The semantics are described in terms of allocating storage for a variable since the allocator must take account of any address alignment requirements for the storage of variables of the given size. CLARIFICATIONS

- Programming in Modula-2 adopts two approaches to handling situations where it is not possible to allocate sufficient storage; the procedure `Allocate` of Chapter 25 assigns `NIL` to the first parameter, whereas the procedure `ALLOCATE` of Appendix 2 causes the program to terminate. The International Standard requires the procedure `ALLOCATE` to assign the value `NIL` to its first parameter in this situation.
- Although the first parameter of the procedure `DEALLOCATE` given in Appendix 2 of Programming in Modula-2 is a variable parameter, it is not stated whether `DEALLOCATE` assigns a value to its parameter. The International Standard requires the procedure `DEALLOCATE` to assign the value `NIL` to its parameter.

- StorageExceptions - Storage exceptions identities
- ALLOCATE - Allocate storage
- DEALLOCATE - Deallocate storage
- IsStorageException - Query exceptional state
- StorageException - Query exception id

### StorageExceptions - Storage exceptions identities

    TYPE
      StorageExceptions = (
        nilDeallocation,
          (* first argument to DEALLOCATE is NIL *)
        pointerToUnallocatedStorage,
          (* storage to deallocate not allocated by ALLOCATE *)
        wrongStorageToUnallocate
          (* amount to deallocate is not amount allocated *)
    );

Module `Storage`

The exceptions raised by `Storage` are identified by the values of the enumeration type `StorageExceptions`.

The detection of the exception `wrongStorageToUnallocate` is implementation-defined.

### ALLOCATE - Allocate storage

    PROCEDURE ALLOCATE (VAR addr: SYSTEM.ADDRESS;
                        amount: CARDINAL);

Module `Storage`

The procedure `ALLOCATE` allocates storage for a variable of size `amount`, and assigns the address of this variable to `addr`. The allocated locations will not be in use for the storage of any other variable. If it is not possible to allocate this storage, the value `NIL` is assigned to `addr`.

NOTES:

1. If an address passed back by a call of `ALLOCATE` is assigned to a pointer variable `vp` that is to be dereferenced to designate a variable of type `T`, the value for the second parameter to `ALLOCATE` may be obtained from evaluation of the expression `SIZE(T)`. An equivalent effect may be obtained as `NEW(vp)`.
2. If an address passed back by a call of `ALLOCATE` is to be given directly as the workspace address in a call of `COROUTINES.NEWCOROUTINE`, the value for the second parameter to `ALLOCATE` is the size of workspace required.

### DEALLOCATE - Deallocate storage

    PROCEDURE DEALLOCATE (VAR addr: SYSTEM.ADDRESS;
                          amount: CARDINAL);

Module `Storage`

The procedure `DEALLOCATE` deallocates `amount` locations for the storage of the variable addressed by `addr` and assigns the value `NIL` to `addr`.

The exception `nilDeallocation` is raised if the given value of `addr` is the nil value. The exception `pointerToUnallocatedStorage` is raised if the given value of `addr` is not the address of a variable whose storage has been allocated by `ALLOCATE`. The exception `wrongStorageToUnallocate` occurs and may be raised if `amount` is not equal to the number of locations allocated for the storage of the variable addressed by `addr`.

NOTES:

1. If an address passed to a call of `DEALLOCATE` is the value of a pointer variable `vp` that is dereferenced to designate a variable of type `T`, the value for the second parameter to `DEALLOCATE` may be obtained from evaluation of the expression `SIZE(T)`. An equivalent effect may be obtained as `DISPOSE(vp)`.
2. The variable whose storage is deallocated no longer exists and hence an exception occurs, which may be raised, if there is a subsequent attempt to access the variable through a dereferenced designator.
3. This International Standard gives no meaning for a program that deallocates dynamic storage given as workspace in a call of `COROUTINES.NEWCOROUTINE` since the use made of coroutine workspace is implementation-dependent.
4. It need not be the case that storage locations deallocated by a call of `DEALLOCATE` are available for re-use by a subsequent call of `ALLOCATE`.

### IsStorageException - Query exceptional state

    PROCEDURE IsStorageException (): BOOLEAN;

Module `Storage`

If the calling coroutine is in the state of exceptional execution because of the raising of a `Storage` exception, the function procedure `IsStorageException` returns `TRUE`; otherwise it returns `FALSE`.

### StorageException - Query exception id

    PROCEDURE StorageException (): StorageExceptions;

Module `Storage`

If the calling coroutine is in the state of exceptional execution because of the raising of a `Storage` exception, the function procedure `StorageException` returns the value that identifies the raised exception; otherwise the language exception `exException` is raised.

## Module SysClock

The module `SysClock` provides facilities for accessing a system clock that records the date and time of day. NOTES:

- No provision is made for leap seconds.
- `UTC' is `Universal Coordinated Time'. This is the correct international designation for what was once called `GMT' (Greenwich Mean Time).

- The field `summerTimeFlag` is present for information only. UTC can always be obtained by subtracting the `UTCDiff` value from the time data, regardless of the value of the `summerTimeFlag`. However, its presence does allow a program to know whether or not the date and time data represents standard time for that location, or `summer time'. A program could therefore be written to change the system clock to summer time automatically on a certain date, provided it had not already been changed.

- The Constants and Types of SysClock
- CanGetClock - Query system clock read permission
- CanSetClock - Query system clock write permission
- IsValidDateTime - Verify date and time
- GetClock - Determine current date and time
- SetClock - Set current date and time

### The Constants and Types of SysClock

    CONST
      maxSecondParts = <implementation-defined integral value>;

    TYPE
      Month = [1 .. 12];
      Day = [1 .. 31];
      Hour = [0 .. 23];
      Min = [0 .. 59];
      Sec = [0 .. 59];
      Fraction = [0 .. maxSecondParts];
      UTCDiff = [-780 .. 720];
      DateTime =
        RECORD
          year:   CARDINAL;
          month:  Month;
          day:    Day;
          hour:   Hour;
          minute: Min;
          second: Sec;
          fractions: Fraction; (* parts of a second *)
          zone:   UTCDiff;
            (* Time zone differential factor which is the number
               of minutes to add to local time to obtain UTC. *)
          summerTimeFlag: BOOLEAN;
            (* Interpretation of flag depends on local usage. *)
        END;

### CanGetClock - Query system clock read permission

    PROCEDURE CanGetClock (): BOOLEAN;

Module `SysClock`

The function procedure `CanGetClock` returns an implementation-defined `BOOLEAN` value. If the value `TRUE` is returned, there is a system clock which the program is permitted to read.

### CanSetClock - Query system clock write permission

    PROCEDURE CanSetClock (): BOOLEAN;

Module `SysClock`

The function procedure `CanSetClock()` returns an implementation-defined `BOOLEAN` value. If the value `TRUE` is returned, there is a system clock which the program is permitted to set.

### IsValidDateTime - Verify date and time

    PROCEDURE IsValidDateTime (userData: DateTime): BOOLEAN;

Module `SysClock`

The function procedure `IsValidDateTime` returns `TRUE` if the value of `userData` represents a valid date and time, and is `FALSE` otherwise. NOTE: Only the date components of `userData` need to be validated since all combinations of values of the time components are known to be valid.

### GetClock - Determine current date and time

    PROCEDURE GetClock (VAR userData: DateTime);

Module `SysClock`

The function procedure `GetClock` assigns values for each field of the variable `userData` for which information is available. Each of the remaining fields of `userData` are set to zero, where this is a valid value, and otherwise are set to the lower bound of the range of allowed values.

### SetClock - Set current date and time

    PROCEDURE SetClock (userData: DateTime);

Module `SysClock`

The function procedure `SetClock` sets the system clock to the date and time specified by `userData`, provided that the program may set the system clock, and that the value of `userData` represents a valid date and time. If the program cannot set the system clock, a call of `SetClock` have no effect.

NOTE: The effect of a call of `SetClock` is implementation-dependent if it is permitted to set the system clock, but an invalid date and time is given.