INTERFACE Text; TYPE T = TEXT;A non-nil TEXT represents a zero-based sequence of characters. NIL does not represent any sequence of characters, it will not be returned from any procedure in the interface, and it is a checked runtime error to pass it to any procedure in the interface.
PROCEDURE Cat(t, u: T): T;The concatenation of t and u.
PROCEDURE Equal(t, u: T): BOOLEAN;TRUE if t and u have the same length and (case-sensitive) contents.
PROCEDURE GetChar(t: T; i: CARDINAL): CHAR;Character i of t. A checked runtime error if i >= Length(t).
PROCEDURE Length(t: T): CARDINAL;The number of characters in t.
PROCEDURE Empty(t: T): BOOLEAN;TRUE if Length(t) = 0.
PROCEDURE Sub(t: T; start, length: CARDINAL): T;Return a subsequence of t: empty if start >= Length(t) or length = 0; otherwise the subsequence ranging from start to the minimum of start+length-1 and Length(t)-1.
PROCEDURE SetChars(VAR a: ARRAY OF CHAR; t: T);For each i from 0 to MIN(LAST(a), Length(t)-1), set a[i] to GetChar(t, i).
PROCEDURE FromChar(ch: CHAR): T;A text containing the single character ch.
PROCEDURE FromChars(READONLY a: ARRAY OF CHAR): T;A text containing the characters of a.
PROCEDURE Hash(t: T): INTEGER;Return a hash function of the contents of t.
END Text.
If a shared variable is written concurrently by two threads, or written by one and read concurrently by another, the effect is to set the variable to an implementation-dependent value of its type. For example, if one thread writes a[0] while another concurrently writes a[1], one of the writes might be lost. Thus, portable programs must use the Thread interface to provide mutual exclusion for shared variables.
INTERFACE Thread; TYPE T <: REFANY; Mutex = MUTEX; Condition <: ROOT; Closure = OBJECT METHODS apply(): REFANY END;A Thread.T is a handle on a thread. A Mutex is locked by some thread, or unlocked. A Condition is a set of waiting threads. A newly-allocated Mutex is unlocked; a newly-allocated Condition is empty. It is a checked runtime error to pass the NIL Mutex, Condition, or T to any procedure in this interface.
PROCEDURE Fork(cl: Closure): T;A handle on a newly-created thread executing cl.apply().
PROCEDURE Join(t: T): REFANY;Wait until t has terminated and return its result. It is a checked error to call this more than once for any t.
PROCEDURE Wait(m: Mutex; c: Condition);The calling thread must have m locked. Atomically unlocks m and waits on c. Then relocks m and returns.
PROCEDURE Acquire(m: Mutex);Wait until m is unlocked and then lock it.
PROCEDURE Release(m: Mutex);The calling thread must have m locked. Unlocks m.
PROCEDURE Broadcast(c: Condition);All threads waiting on c become eligible to run.
PROCEDURE Signal(c: Condition);One or more threads waiting on c become eligible to run.
PROCEDURE Self(): T;Return the handle of the calling thread.
EXCEPTION Alerted;Used to approximate asynchronous interrupts.
PROCEDURE Alert(t: T);Mark t as an alerted thread.
PROCEDURE TestAlert(): BOOLEAN;TRUE if the calling thread has been marked alerted.
PROCEDURE AlertWait(m: Mutex; c: Condition) RAISES {Alerted};
Like Wait, but if the thread is marked alerted at the time of
call or sometime during the wait, lock m and raise Alerted.
PROCEDURE AlertJoin(t: T): REFANY RAISES {Alerted};
Like Join, but if the calling thread is marked alerted at
the time of call or sometime during the wait, raise Alerted.
CONST AtomicSize = ...;An implementation-dependent integer constant: the number of bits in a memory-coherent block. If two components of a record or array fall in different blocks, they can be accessed concurrently by different threads without locking.
END Thread.
INTERFACE Word; TYPE T = INTEGER; CONST Size = BITSIZE(T);A Word.T w represents a sequence of Word.Size bits w_0, ..., w_(Word.Size-1). It also represents the unsigned number SUM (w_i * 2^i). Finally, it also represents a signed INTEGER by some implementation-dependent encoding (for example, two's complement). The built-in operations of the language deal with the signed value; the operations in this interface deal with the unsigned value or with the bit sequence.
Here are the arithmetic operations on unsigned words:
PROCEDURE Plus (x,y: T): T; (* (x + y) MOD 2^Word.Size *) PROCEDURE Times (x,y: T): T; (* (x * y) MOD 2^Word.Size *) PROCEDURE Minus (x,y: T): T; (* (x - y) MOD 2^Word.Size *) PROCEDURE Divide(x,y: T): T; (* x DIV y *) PROCEDURE Mod(x,y: T): T; (* x MOD y *) PROCEDURE LT(x,y: T): BOOLEAN; (* x < y *) PROCEDURE LE(x,y: T): BOOLEAN; (* x <= y *) PROCEDURE GT(x,y: T): BOOLEAN; (* x > y *) PROCEDURE GE(x,y: T): BOOLEAN; (* x >= y *)
And here are the logical operations on bit sequences:
PROCEDURE And(x,y: T): T; (* Bitwise AND of x and y *) PROCEDURE Or (x,y: T): T; (* Bitwise OR of x and y *) PROCEDURE Xor(x,y: T): T; (* Bitwise XOR of x and y *) PROCEDURE Not (x: T): T; (* Bitwise complement of x *)
And here are additional operations on bit sequences:
PROCEDURE Shift(x: T; n: INTEGER): T;For all i such that both i and i - n are in the range [0..Word.Size - 1], bit i of the result equals bit i - n of x. The other bits of the result are 0. Thus shifting by n > 0 is like multiplying by 2^n.
Since Modula-3 has no exponentiation operator, Word.Shift(1, n) is the usual way of writing 2^n in a constant expression.
PROCEDURE Rotate(x: T; n: INTEGER): T;Bit i of the result is bit ((i - n) MOD Word.Size) of x.
PROCEDURE Extract(x: T; i, n: CARDINAL): T;Take n bits from x, with bit i as the least significant bit, and return them as the least significant n bits of a word whose other bits are 0. A checked runtime error if n + i > Word.Size.
PROCEDURE Insert(x: T; y: T; i, n: CARDINAL): T;Result of replacing n bits of x, with bit i as the least significant bit, by the least significant n bits of y. The other bits of x are unchanged. A checked runtime error if n + i > Word.Size.
END Word.
For definitions of the terms used in these interfaces, see the ANSI/IEEE Standard 754-1985 for floating-point arithmetic.
These interfaces define constant attributes of the three built-in floating-point types:
INTERFACE Real; TYPE T = REAL;
CONST
Base: INTEGER = ...;
Precision: INTEGER = ...;
MaxFinite: T = ...;
MinPos: T = ...;
MinPosNormal: T = ...;
END Real.
INTERFACE LongReal; TYPE T = LONGREAL;
CONST
Base: INTEGER = ...;
Precision: INTEGER = ...;
MaxFinite: T = ...;
MinPos: T = ...;
MinPosNormal: T = ...;
END LongReal.
INTERFACE Extended; TYPE T = EXTENDED;
CONST
Base: INTEGER = ...;
Precision: INTEGER = ...;
MaxFinite: T = ...;
MinPos: T = ...;
MinPosNormal: T = ...;
END Extended.
The specification is the same for all three interfaces:
Base is the radix of the floating-point representation for T.
Precision is the number of base-Base digits of precision for T.
MaxFinite is the maximum finite value in T. For non-IEEE implementations, this is the same as LAST(T).
MinPos is the minimum positive value in T.
MinPosNormal is the minimum positive normal value in T; it differs from MinPos only for implementations (like IEEE) with denormalized numbers.
For definitions of the terms used in these interfaces, see the ANSI/IEEE Standard 754-1985 for floating-point arithmetic.
These interfaces define operations that depend on the floating-point representation. They are all are instances of a generic interface Float:
INTERFACE RealFloat = Float(Real) END RealFloat.
INTERFACE LongFloat = Float(LongReal) END LongFloat.
INTERFACE ExtendedFloat = Float(Extended) END ExtendedFloat.
GENERIC INTERFACE Float(R); TYPE T = R.T;This generic interface provides access to the floating-point operations required or recommended by the IEEE floating-point standard. Consult the standard for the precise specifications of the procedures, including when their arguments are NaNs, infinities, and signed zeros, and including what exceptions they can raise. The comments here specify their effect when the arguments are ordinary numbers and no exception is raised. Implementations on non-IEEE machines that have values similar to NaNs and infinities should explain how those values behave in an implementation guide.
PROCEDURE Scalb(x: T; n: INTEGER): T;Return x * 2^n.
PROCEDURE Logb(x: T): T;Return the exponent of x. More precisely, return the unique n such that the ratio ABS(x) / Base^n is in the range [1..Base-1], unless x is denormalized, in which case return the minimum exponent value for T.
PROCEDURE ILogb(x: T): INTEGER;Like Logb, but returns an integer, never raises an exception, and always returns the n such that ABS(x) / Base^n is in the range [1..Base-1], even for denormalized numbers.
PROCEDURE NextAfter(x, y: T): T;Return the next representable neighbor of x in the direction towards y. If x = y, return x.
PROCEDURE CopySign(x, y: T): T;Return x with the sign of y.
PROCEDURE Finite(x: T): BOOLEAN;Return TRUE if x is strictly between minus infinity and plus infinity. This always returns TRUE on non-IEEE machines.
PROCEDURE IsNaN(x: T): BOOLEAN;Return FALSE if x represents a numerical (possibly infinite) value, and TRUE if x does not represent a numerical value. For example, on IEEE implementations, returns TRUE if x is a NaN, FALSE otherwise.
PROCEDURE Sign(x: T): [0..1];Return the sign bit of x. For non-IEEE implementations, this is the same as ORD(x >= 0); for IEEE implementations, Sign(-0) = 1 and Sign(+0) = 0.
PROCEDURE Differs(x, y: T): BOOLEAN;Return (x < y OR y < x). Thus, for IEEE implementations, Differs(NaN,x) is always FALSE; for non-IEEE implementations, Differs(x,y) is the same as x # y.
PROCEDURE Unordered(x, y: T): BOOLEAN;Return NOT (x <= y OR y <= x).
PROCEDURE Sqrt(x: T): T;Return the square root of T. This must be correctly rounded if FloatMode.IEEE is TRUE.
TYPE IEEEClass =
{SignalingNaN, QuietNaN, Infinity, Normal, Denormal, Zero};
PROCEDURE Class(x: T): IEEEClass;Return the IEEE number class containing x.
END Float.
The FloatMode interface allows you to test the behavior of rounding and of numerical exceptions. On some implementations it also allows you to change the behavior, on a per-thread basis.
For definitions of the terms used in this interface, see the ANSI/IEEE Standard 754-1985 for floating-point arithmetic.
INTERFACE FloatMode; CONST IEEE: BOOLEAN = ...;TRUE for fully-compliant IEEE implementations.
EXCEPTION Failure;Raised by attempts to set modes that are not supported by the implementation.
TYPE RoundingMode =
{NearestElseEven, TowardMinusInfinity, TowardPlusInfinity,
TowardZero, NearestElseAwayFromZero, IBM370, Other};
Rounding modes. The first four are the IEEE modes.
CONST RoundDefault: RoundingMode = ...;Implementation-dependent: the default mode for rounding arithmetic operations, used by a newly forked thread. This also specifies the behavior of the ROUND operation in half-way cases.
PROCEDURE SetRounding(md: RoundingMode) RAISES {Failure};
Change the rounding mode for the calling thread to md, or raise
the exception if this cannot be done. This affects the implicit
rounding in floating-point operations; it does not affect the
ROUND operation. Generally this can be done only on IEEE
implementations and only if md is an IEEE mode.
PROCEDURE GetRounding(): RoundingMode;Return the rounding mode for the calling thread.
TYPE Flag =
{Invalid, Inexact, Overflow, Underflow,
DivByZero, IntOverflow, IntDivByZero};
Associated with each thread is a set of boolean status flags recording
whether the condition represented by the flag has occurred in the
thread since the flag was last reset. The meaning of the first
five flags is defined precisely in the IEEE floating point standard;
roughly they mean:
Invalid = invalid argument to an operation.Inexact = an operation produced an inexact result.
Overflow = a floating-point operation produced a result whose absolute value is too large to be represented.
Underflow = a floating-point operation produced a result whose absolute value is too small to be represented.
DivByZero = floating-point division by zero.
The meaning of the last two flags is:
IntOverflow = an integer operation produced a result whose absolute value is too large to be represented.IntDivByZero = integer DIV or MOD by zero.
CONST NoFlags = SET OF Flags {};
PROCEDURE GetFlags(): SET OF Flag;Return the set of flags for the current thread.
PROCEDURE SetFlags(s: SET OF Flag): SET OF Flag RAISES{Failure};
Set the flags for the current thread to s, and return their previous
values.
PROCEDURE ClearFlag(f: Flag);Turn off the flag f for the current thread.
EXCEPTION
Trap(Flag);
TYPE
Behavior = {Trap, SetFlag, Ignore};
The behavior of an operation that causes one of the flag conditions is either
Ignore = return some result and do nothing.SetFlag = return some result and set the condition flag. For IEEE implementations, the result of the operation is defined by the standard.
Trap = possibly set the condition flag; in any case raise the Trap exception with the appropriate flag as the argument.
PROCEDURE SetBehavior(f: Flag; b: Behavior) RAISES {Failure};
Set the behavior of the current thread for the flag f
to be b, or raise Failure if this cannot be done.
PROCEDURE GetBehavior(f: Flag): Behavior;Return the behavior of the current thread for the flag f.
END FloatMode.