Part of the modules in the standard library have to be supported by every implementation. All other modules may be supported, if they are provided, their form and meaning is fixed by the standard.
p1 Modula-2 V10.0 supports all defined modules.
The standard library has four parts:
The handling of runtime errors is done throughout the whole library by the concept of exceptions (cf. compiler manual, chapter 2.7). All modules, that may raise specific exceptions report these exceptions in the same way. Each of these modules exports a procedure with the name "Is<Modulename>Exceptions". In case of an exceptions, this procedure can be used to test whether the exception was raised by the module it belongs to. If "Is<Modulename>Exceptions" returns "TRUE" (exception was raised by this module), the reason for the exception can be obtained by "<Modulename>Exception". This function procedure has as result type an enumeration type, exported by the same module, that lists all reasons for exceptions. Some modules define only one reason for exceptions, in this case neither "<Modulename>Exception" nor the enumeration type are exported.
DEFINITION MODULE Storage; (* Facilities for making areas of storage available to a program at execution time *) IMPORT SYSTEM; PROCEDURE ALLOCATE (VAR addr: SYSTEM.ADDRESS; amount: CARDINAL); (* Makes available to the program an area of storage whose size, in units of SYSTEM.LOC, is given by amount, and assigns the address of this area to addr. If there is insufficient storage to do this, the value NIL is assigned to addr. *) PROCEDURE DEALLOCATE (VAR addr: SYSTEM.ADDRESS; amount: CARDINAL); (* Makes an area of storage currently available to the program inaccessible, and assigns the value NIL to addr. On entry addr must be an address of an area of storage previously delivered by ALLOCATE, whose size, in units of SYSTEM.LOC, is given by amount. *) TYPE StorageExceptions = (nilDeallocation, pointerToUnallocatedStorage, wrongStorageToUnallocate); PROCEDURE StorageException (): StorageExceptions; (* Returns a value indicating which exception has been raised by the module Storage. *) PROCEDURE IsStorageException (): BOOLEAN; (* Returns TRUE iff an exception has been raised by the module Storage *) END Storage."Storage" is the base module for heap management. The procedures "ALLOCATE" and "DEALLOCATE" fullfil all the compiler requirements, to be used as replacement for "NEW" and "DISPOSE".
"ALLOCATE" reserves an area of "n" LOCs on the heap and returns the starting address in "v", if sufficient space is available. Otherwise, "NIL" is returned in "v".
"DEALLOCATE" frees the storage area starting at "v" and length "n". The following exceptions may occur:
"Storage" uses its own management for the heap portions and is therefore faster than the heap procedures provided by the system.
DEFINITION MODULE LowReal; (* Access to underlying properties of the type REAL *) CONST radix = 2; places = 24; expoMin = -126; expoMax = 127; large = MAX (REAL); small = 1.2E-38; IEEE = TRUE; ISO = TRUE; rounds = TRUE; gUnderflow = TRUE; exception = TRUE; extend = FALSE; nModes = <32 for x86_64 and 64 for arm64>; TYPE Modes = SET OF [0 .. nModes-1]; PROCEDURE IsLowException (): BOOLEAN; (* Returns TRUE iff an exception has been raised by the module LowReal *) PROCEDURE exponent (x: REAL): INTEGER; (* Returns the exponent value of x *) PROCEDURE fraction (x: REAL): REAL; (* Returns the significand or mantissa part of x *) PROCEDURE sign (x: REAL): REAL; (* Returns the signum of x *) PROCEDURE succ (x: REAL): REAL; (* Returns the next value of the type REAL greater than x *) PROCEDURE ulp (x: REAL): REAL; (* Returns the value of the last digit of x *) PROCEDURE pred (x: REAL): REAL; (* Returns the previous value of the type REAL less than x *) PROCEDURE intpart (x: REAL): REAL; (* Returns the integer part of x *) PROCEDURE fractpart (x: REAL): REAL; (* Returns the fractional part of x *) PROCEDURE scale (x: REAL; n: INTEGER): REAL; (* Returns the value of x * radix ** n *) PROCEDURE trunc (x: REAL; n: INTEGER): REAL; (* Returns the value of the first n places of x *) PROCEDURE round (x: REAL; n: INTEGER): REAL; (* Returns the value of x rounded to the first n places *) PROCEDURE synthesize (exponent: INTEGER; fraction: REAL): REAL; (* Returns a value of the type REAL constructed from the given exponent and fraction *) PROCEDURE setMode (m: Modes); (* Sets status flags appropriate to the underlying implementation of the type REAL *) PROCEDURE currentMode (): Modes; (* Returns the current status flags in the form set by setMode *) END LowReal.The module "LowReal" defines the properties of the type "REAL" (representation, boundaries, arithmetic behavior). Additionally, procedures for the direct analysis and manipulation of values of type "REAL" are provided.
p1 Modula-2 uses the IEEE conforming FPU ("IEEE = TRUE") in mode "RoundToNearest" ("rounds = TRUE"), allows non normalized numbers ("gUnderflow = TRUE") and raises exceptions ("exception = TRUE") if necessary. Intermediate values are stored in single precision format ("extended = FALSE"). Infinities are included in type "REAL".
The type "Mode" is a direct representation of the FPU control register "mxcsr" resp. the neon state registers "fpsr, fpcr".
DEFINITION MODULE LowLong; (* Access to underlying properties of the type LONGREAL *) CONST radix = 2; places = 53; expoMin = -1022; expoMax = 1023; large = MAX (LONGREAL); small = 2.2E-308; IEEE = TRUE; ISO = TRUE; rounds = TRUE; gUnderflow = TRUE; exception = TRUE; extend = FALSE; nModes = <32 for x86_64 and 64 for arm64>; TYPE Modes = SET OF [0 .. nModes-1]; PROCEDURE IsLowException (): BOOLEAN; (* Returns TRUE iff an exception has been raised by the module LowLong *) PROCEDURE exponent (x: LONGREAL): INTEGER; (* Returns the exponent value of x *) PROCEDURE fraction (x: LONGREAL): LONGREAL; (* Returns the significand or mantissa part of x *) PROCEDURE sign (x: LONGREAL): LONGREAL; (* Returns the signum of x *) PROCEDURE succ (x: LONGREAL): LONGREAL; (* Returns the next value of the type LONGREAL greater than x *) PROCEDURE ulp (x: LONGREAL): LONGREAL; (* Returns the value of the last digit of x *) PROCEDURE pred (x: LONGREAL): LONGREAL; (* Returns the previous value of the type LONGREAL less than x *) PROCEDURE intpart (x: LONGREAL): LONGREAL; (* Returns the integer part of x *) PROCEDURE fractpart (x: LONGREAL): LONGREAL; (* Returns the fractional part of x *) PROCEDURE scale (x: LONGREAL; n: INTEGER): LONGREAL; (* Returns the value of x * radix ** n *) PROCEDURE trunc (x: LONGREAL; n: INTEGER): LONGREAL; (* Returns the value of the first n places of x *) PROCEDURE round (x: LONGREAL; n: INTEGER): LONGREAL; (* Returns the value of x rounded to the first n places *) PROCEDURE synthesize (exponent: INTEGER; fraction: LONGREAL): LONGREAL; (* Returns a value of the type LONGREAL constructed from the given exponent and fraction *) PROCEDURE setMode (m: Modes); (* Sets status flags appropriate to the underlying implementation of the type LONGREAL *) PROCEDURE currentMode (): Modes; (* Returns the current status flags in the form set by setMode *) END LowLong.The module "LowLong" corresponds in form and contents exactly the module "LowReal". The main difference is, that it describes the properties of type "LONGREAL".
DEFINITION MODULE CharClass; (* Classification of values of the pervasive type CHAR *) PROCEDURE IsNumeric (ch: CHAR): BOOLEAN; (* Tests if ch is classified as a numeric character *) PROCEDURE IsLetter (ch: CHAR): BOOLEAN; (* Tests if ch is classified as a letter *) PROCEDURE IsUpper (ch: CHAR): BOOLEAN; (* Tests if ch is classified as an upper case letter *) PROCEDURE IsLower (ch: CHAR): BOOLEAN; (* Tests if ch is classified as a lower case letter *) PROCEDURE IsControl (ch: CHAR): BOOLEAN; (* Tests if ch represents a control function *) PROCEDURE IsWhiteSpace (ch: CHAR): BOOLEAN; (* Tests if ch represents either a space character or a format effector *) END CharClass.The module "CharClass" defines some classes of values for type "CHAR". This division is given as information for the user; within the standard library no reference is made to this module (e.g. "TextIO. ReadToken" uses only " " as delimiter, not "IsWhiteSpace").
p1 Modula-2 treats only 7-bit ASCII values as letters. Besides Blank, also Tabs, line feeds, form feeds and carriage returns are treated as "WhiteSpace". This results in:
IsNumeric | ⇔ | "0" ≤ ch ≤ "9" |
IsLetter | ⇔ | "A" ≤ ch ≤ "Z" ∨ "a" ≤ ch ≤ "z" |
IsUpper | ⇔ | "A" ≤ ch ≤ "Z" |
IsLower | ⇔ | "a" ≤ ch ≤ "z" |
IsControl | ⇔ | ch < " " |
IsWhiteSpace | ⇔ | ch = " " ∨ ch = 11C ∨ ch = 12C ∨ ch = 14C ∨ ch = 15C (* Tab, LF, FF, CR *) |
DEFINITION MODULE RealMath; (* Mathematical functions for the type REAL *) CONST pi = 3.1415926535897932384626433832795028841972; exp1 = 2.7182818284590452353602874713526624977572; PROCEDURE IsRMathException (): BOOLEAN; (* Returns TRUE iff an exception has been raised by the module RealMath *) PROCEDURE sqrt (x: REAL): REAL; (* Returns the positive square root of x *) PROCEDURE exp (x: REAL): REAL; (* Returns the exponential of x *) PROCEDURE ln (x: REAL): REAL; (* Returns the natural logarithm of x *) (* The angle in all trigonometric functions is measured in radians *) PROCEDURE sin (x: REAL): REAL; (* Returns the sine of x *) PROCEDURE cos (x: REAL): REAL; (* Returns the cosine of x *) PROCEDURE tan (x: REAL): REAL; (* Returns the tangent of x *) PROCEDURE arcsin (x: REAL): REAL; (* Returns the arcsine of x *) PROCEDURE arccos (x: REAL): REAL; (* Returns the arccosine of x *) PROCEDURE arctan (x: REAL): REAL; (* Returns the arctangent of x *) PROCEDURE power (base, exponent: REAL): REAL; (* Returns the value of the number base raised to the power exponent *) PROCEDURE round (x: REAL): INTEGER; (* Returns the value of x rounded to the next integer *) END RealMath."RealMath" implements the mathematical functions square root, exponential function with base e, natural logarithm, sine, cosine, tangent, their reverse functions, "power" for all exponentiations and "round" for the normal rounding mode.
The trigonometric functions have arguments and results in radians.
Exceptions are raised if either a function is call with illegal arguments ("sqrt", "ln", "tan", "arcsin", "arccos", "power") or the result cannot be expressed as values of type "REAL" ("exp", "ln", "tan", "power").
The functions are implemented with the according functions of the runtime interface "math.h".
DEFINITION MODULE LongMath; (* Mathematical functions for the type LONGREAL *) CONST pi = 3.1415926535897932384626433832795028841972; exp1 = 2.7182818284590452353602874713526624977572; PROCEDURE IsRMathException (): BOOLEAN; (* Returns TRUE iff an exception has been raised by the module LongRealMath *) PROCEDURE sqrt (x: LONGREAL): LONGREAL; (* Returns the positive square root of x *) PROCEDURE exp (x: LONGREAL): LONGREAL; (* Returns the exponential of x *) PROCEDURE ln (x: LONGREAL): LONGREAL; (* Returns the natural logarithm of x *) (* The angle in all trigonometric functions is measured in radians *) PROCEDURE sin (x: LONGREAL): LONGREAL; (* Returns the sine of x *) PROCEDURE cos (x: LONGREAL): LONGREAL; (* Returns the cosine of x *) PROCEDURE tan (x: LONGREAL): LONGREAL; (* Returns the tangent of x *) PROCEDURE arcsin (x: LONGREAL): LONGREAL; (* Returns the arcsine of x *) PROCEDURE arccos (x: LONGREAL): LONGREAL; (* Returns the arccosine of x *) PROCEDURE arctan (x: LONGREAL): LONGREAL; (* Returns the arctangent of x *) PROCEDURE power (base, exponent: LONGREAL): LONGREAL; (* Returns the value of the number base raised to the power exponent *) PROCEDURE round (x: LONGREAL): INTEGER; (* Returns the value of x rounded to the next integer *) END LongMath."LongMath" corresponds "RealMath" for type "LONGREAL".
DEFINITION MODULE ComplexMath; (* Mathematical functions for the type COMPLEX *) CONST i = CMPLX (0.0, 1.0); one = CMPLX (1.0, 0.0); zero = CMPLX (0.0, 0.0); PROCEDURE IsCMathException(): BOOLEAN; (* Returns TRUE iff an exception has been raised by the module ComplexMath *) PROCEDURE abs (z: COMPLEX): REAL; (* Returns the length of z *) PROCEDURE arg (z: COMPLEX): REAL; (* Returns the angle that z subtends to the positive real axis *) PROCEDURE conj (z: COMPLEX): COMPLEX; (* Returns the complex conjugate of z *) PROCEDURE power (base: COMPLEX; exponent: REAL): COMPLEX; (* Returns the value of the number base raised to the power exponent *) PROCEDURE sqrt (z: COMPLEX): COMPLEX; (* Returns the principal square root of z *) PROCEDURE exp (z: COMPLEX): COMPLEX; (* Returns the complex exponential of z *) PROCEDURE ln (z: COMPLEX): COMPLEX; (* Returns the principal value of the natural logarithm of z *) PROCEDURE sin (z: COMPLEX): COMPLEX; (* Returns the sine of z *) PROCEDURE cos (z: COMPLEX): COMPLEX; (* Returns the cosine of z *) PROCEDURE tan (z: COMPLEX): COMPLEX; (* Returns the tangent of z *) PROCEDURE arcsin (z: COMPLEX): COMPLEX; (* Returns the arcsine of z *) PROCEDURE arccos (z: COMPLEX): COMPLEX; (* Returns the arccosine of z *) PROCEDURE arctan (z: COMPLEX): COMPLEX; (* Returns the arctangent of z *) PROCEDURE polarToComplex (abs, arg: REAL): COMPLEX; (* Returns the complex number with the specified polar coordinates *) PROCEDURE scalarMult (scalar: REAL; z: COMPLEX): COMPLEX; (* Returns the scalar product of scalar with z *) END ComplexMath."ComplexMath" supports the most common functions for complex numbers. The many-valued functions ("ln", "arcsin", "arccos", arctan") return—as usual—the principal value.
DEFINITION MODULE LongComplexMath; (* Mathematical functions for the type LONGCOMPLEX *) CONST i = CMPLX (0.0, 1.0); one = CMPLX (1.0, 0.0); zero = CMPLX (0.0, 0.0); PROCEDURE IsCMathException(): BOOLEAN; (* Returns TRUE iff an exception has been raised by the module LongComplexMath *) PROCEDURE abs (z: LONGCOMPLEX): LONGREAL; (* Returns the length of z *) PROCEDURE arg (z: LONGCOMPLEX): LONGREAL; (* Returns the angle that z subtends to the positive real axis *) PROCEDURE conj (z: LONGCOMPLEX): LONGCOMPLEX; (* Returns the complex conjugate of z *) PROCEDURE power (base: LONGCOMPLEX; exponent: LONGREAL): LONGCOMPLEX; (* Returns the value of the number base raised to the power exponent *) PROCEDURE sqrt (z: LONGCOMPLEX): LONGCOMPLEX; (* Returns the principal square root of z *) PROCEDURE exp (z: LONGCOMPLEX): LONGCOMPLEX; (* Returns the complex exponential of z *) PROCEDURE ln (z: LONGCOMPLEX): LONGCOMPLEX; (* Returns the principal value of the natural logarithm of z *) PROCEDURE sin (z: LONGCOMPLEX): LONGCOMPLEX; (* Returns the sine of z *) PROCEDURE cos (z: LONGCOMPLEX): LONGCOMPLEX; (* Returns the cosine of z *) PROCEDURE tan (z: LONGCOMPLEX): LONGCOMPLEX; (* Returns the tangent of z *) PROCEDURE arcsin (z: LONGCOMPLEX): LONGCOMPLEX; (* Returns the arcsine of z *) PROCEDURE arccos (z: LONGCOMPLEX): LONGCOMPLEX; (* Returns the arccosine of z *) PROCEDURE arctan (z: LONGCOMPLEX): LONGCOMPLEX; (* Returns the arctangent of z *) PROCEDURE polarToComplex (abs, arg: LONGREAL): LONGCOMPLEX; (* Returns the complex number with the specified polar coordinates *) PROCEDURE scalarMult (scalar: LONGREAL; z: LONGCOMPLEX): LONGCOMPLEX; (* Returns the scalar product of scalar with z *) END LongComplexMath.Corresponds with "ComplexMath" for complex numbers of type "LONGCOMPLEX".
The IO library may be divided into three groups.
The following graphic is a short summary of the modules. Bold borders and normal borders distinguish between subgroups within the main group (cf. text above).
In the following chapters, the modules are described in lexical order.
The implementation of the io library of p1 Modula-2 has two aspects worth knowing for the user, the implementation of the standard channels and the implementation of type "ChanId", variables of which identify the open channels.
DEFINITION MODULE ChanConsts; (* Common types and values for channel open requests and results *) (* Device modules may allow combinations of the following flags to be given when a channel is opened. A channel opening procedure may not be able to accept or honour all combinations. *) TYPE ChanFlags = ( readFlag, (* input operations are requested/available *) writeFlag, (* output operations are requested/available *) oldFlag, (* a file may/must/did exist before the channel is opened *) textFlag, (* text operations are requested/available *) rawFlag, (* raw operations are requested/available *) interactiveFlag, (* interactive use is requested/applies *) echoFlag (* echoing by interactive device on removal of characters from input stream requested/applies *) ); FlagSet = SET OF ChanFlags; (* Singleton values of FlagSet, to allow for example, read + write *) CONST read = FlagSet{readFlag}; (* input operations are requested/available *) write = FlagSet{writeFlag}; (* output operations are requested/available *) old = FlagSet{oldFlag}; (* a file may/must/did exist before the channel is opened *) text = FlagSet{textFlag}; (* text operations are requested/available *) raw = FlagSet{rawFlag}; (* raw operations are requested/available *) interactive = FlagSet{interactiveFlag}; (* interactive use is requested/applies *) echo = FlagSet{echoFlag}; (* echoing by interactive device on removal of characters from input stream requested/ applies *) (* Possible results of open requests *) TYPE OpenResults = (opened, (* the open succeeded as requested *) wrongNameFormat, (* given name is in the wrong format for the implementation *) wrongFlags, (* given flags include a value that does not apply to the device *) tooManyOpen, (* this device cannot support any more open channels *) outOfChans, (* no more channels can be allocated *) wrongPermissions,(* file or directory permissions do not allow request *) noRoomOnDevice, (* storage limits on the device prevent the open *) noSuchFile, (* a needed file does not exist *) fileExists, (* a file of the given name already exists when a new one is required *) wrongFileType, (* the file is of the wrong type to support the required operations *) noTextOperations,(* text operations have been requested, but are not supported *) noRawOperations, (* raw operations have been requested, but are not supported *) noMixedOperations,(* text and raw operations have been requested, but they are not supported in combination *) alreadyOpen, (* the source/destination is already open for operations not supported in combination with the requested operations *) otherProblem (* open failed for some other reason *) ); END ChanConsts.The type "ChanFlags" describes the properties of an open channel or the desired properties of a channel to open. All properties of an open channel are stores for this channel in a field of type "FlagSet". The flags are also provided as single element sets for use with the open procedures.
The type "OpenResults" is used as result parameter to signal possible errors while opening a channel. The result "opened" indicates, that the channel could be opened with the desired properties. All other results indicate an error during opening. In these cases the returned channel identifier has the value of "IOChan. InvalidChan ()".
The flags relevant to a device module and the type "OpenResults" are reexported by each device module, so that the user will have to import directly from this module only in rare cases.
DEFINITION MODULE IOChan; (* Types and procedures forming the interface to channels for device- independent data transfer modules *) IMPORT IOConsts, ChanConsts, SYSTEM; TYPE ChanId; (* Values of this type are used to identify channels *) (* There is one pre-defined value identifying an invalid channel on which no data transfer operations are available. It may be used to initialize variables of type ChanId. *) PROCEDURE InvalidChan (): ChanId; (* Returns the value identifying the invalid channel. *) (* For each of the following operations, if the device supports the operation on the channel, the behaviour of the procedure conforms with the description below. The full behaviour is defined for each device module. If the device does not support the operation on the channel, the behaviour of the procedure is to raise the exception notAvailable. *) (* Text operations - these perform any required translation between the internal and external representation of text. *) PROCEDURE Look (cid: ChanId; VAR ch: CHAR; VAR res: IOConsts.ReadResults); (* If there is a character as the next item in the input stream cid, assigns its value to ch without removing it from the stream; otherwise the value of ch is not defined. res (and the stored read result) are set to the value allRight, endOfLine, or endOfInput. *) PROCEDURE Skip (cid: ChanId); (* If the input stream cid has ended, the exception skipAtEnd is raised; otherwise the next character or line mark in cid is removed, and the stored read result is set to the value allRight. *) PROCEDURE SkipLook (cid: ChanId; VAR ch: CHAR; VAR res: IOConsts.ReadResults); (* If the input stream cid has ended, the exception skipAtEnd is raised; otherwise the next character or line mark in cid is removed. If there is a character as the next item in cid stream, assigns its value to ch without removing it from the stream. Otherwise, the value of ch is not defined. res (and the stored read result) are set to the value allRight, endOfLine, or endOfInput. *) PROCEDURE TextRead (cid: ChanId; to: SYSTEM.ADDRESS; maxChars: CARDINAL; VAR charsRead: CARDINAL); (* Reads at most maxChars characters from the current line in cid, and assigns corresponding values to successive locations, starting at the address given by to, and continuing thereafter at increments corresponding to the address difference between successive components of an ARRAY OF CHAR. The number of characters read is assigned to charsRead. The stored read result is set to the value allRight, endOfLine, or endOfInput. *) PROCEDURE TextWrite (cid: ChanId; from: SYSTEM.ADDRESS; charsToWrite: CARDINAL); (* Writes a number of characters given by the value of charsToWrite, starting at the address given by from, and continuing thereafter at increments corresponding to the address difference between successive components of an ARRAY OF CHAR. *) PROCEDURE WriteLn (cid: ChanId); (* Writes a line mark over the channel cid. *) (* Direct raw operations - these do not effect translation between the internal and external representation of data *) PROCEDURE RawRead (cid: ChanId; to: SYSTEM.ADDRESS; maxLocs: CARDINAL; VAR locsRead: CARDINAL); (* Reads at most maxLocs items from cid, and assigns corresponding values to successive locations, starting at the address given by to. The number of items read is assigned to locsRead. The stored read result is set to the value allRight, or endOfInput. *) PROCEDURE RawWrite (cid: ChanId; from: SYSTEM.ADDRESS; locsToWrite: CARDINAL); (* Writes a number of items to cid, given by the value of locsToWrite, from successive locations starting at the address given by from. *) (* Common operations *) PROCEDURE GetName (cid: ChanId; VAR s: ARRAY OF CHAR); (* Copies to s a name associated with the channel cid, possibly truncated (depending on the capacity of s). *) PROCEDURE Reset (cid: ChanId); (* Resets the channel cid to a state defined by the device module. *) PROCEDURE Flush (cid: ChanId); (* Flushes any data buffered by the device module out to the channel cid.*) (* Access to read results *) PROCEDURE SetReadResult (cid: ChanId; res: IOConsts.ReadResults); (* Sets the read result value for the channel cid to the value res. *) PROCEDURE ReadResult (cid: ChanId): IOConsts.ReadResults; (* Returns the stored read result value for the channel cid. (This is initially the value notKnown). *) (* Users can discover which flags actually apply to a channel *) PROCEDURE CurrentFlags (cid: ChanId): ChanConsts.FlagSet; (* Returns the set of flags that currently apply to the channel cid. *) (* The following exceptions are defined for this module and its clients *) TYPE ChanExceptions = (wrongDevice, (* device specific operation on wrong device *) notAvailable, (* operation attempted that is not available on that channel *) skipAtEnd, (* attempt to skip data from a stream that has ended *) softDeviceError, (* device specific recoverable error *) hardDeviceError, (* device specific non-recoverable error *) textParseError, (* input data does not correspond to a character or line mark - optional detection *) notAChannel (* given value does not identify a channel - optional detection *) ); PROCEDURE ChanException (): ChanExceptions; (* Returns the ChanExceptions value for the current context. *) PROCEDURE IsChanException (): BOOLEAN; (* Returns whether a ChanException has been raised in the current context. *) (* When a device procedure detects a device error, it raises the exception softDeviceError or hardDeviceError. If these exceptions are handled, the following facilities may be used to discover an implementation- defined error number for the channel. *) TYPE DeviceErrNum = INTEGER; PROCEDURE DeviceError (cid: ChanId): DeviceErrNum; (* If a device error exception has been raised for the channel cid, returns the error number stored by the device module. *) END IOChan.The module "IOChan" is the basic module of the front end of the io library. It implements procedural access to the elementary transfer procedures supplied by the device modules as well as some enquiry functions and the data types and procedures necessary for the exception handling.
Most users will not need to import directly from "IOChan".
The type "ChanId" is the type for identifiers of channels. The procedures "InvalidChan" returns the value of the "illegal channel", that is also returned e.g. from the open procedures of the device modules in case of an error.
The procedures "Look" and "Skip" implement the basic model for reading text. "Look" looks, which character (and if any) is the first character in the input stream and returns it without changing the state of that channel. Therefore "Look" never may cause errors. "Skip" removes the first character from the input stream. Calls to "Skip" at the end of a file result in the exception "skipAtEnd" being raised. "SkipLook" is a shortcut for the frequently used combination of "Skip; Look (...)". "TextRead" provides a more efficient possibility for reading strings than a repeated call of "Look" and "Skip".
"TextWrite" is used for the output of characters and strings. "WriteLn" writes a (device specific) end of line marker.
"RawRead" and "RawWrite" are the basic procedures for uninterpreted ("raw") data transfer.
"ReadResult" returns the state of the last read operation for the given channel. This state is set automatically by "Look", but may also be changed by "SetReadResult".
"GetName" returns the name of the device connected to the given channel. With p1 Modula-2, this is the full file name in the form "/folder_1/ … /folder_n/name". For channels not connected to files, the empty string is returned.
The reset operations done by "Reset" are device specific and explained within the device modules.
"Flush" ensures, that buffered data (if any) is written at once to the given device.
"CurrentFlags" allows to test for the actual properties of a channel.
Exceptions may be raised in the io library due to illegal channels, invalid operations, hardware errors or similar problems. The type "ChanExceptions" identifies the possible exceptions. "IsChanExceptions" returns, whether a exception has been raised by the io library. In this case, the function procedure "ChanException" returns the information about the current exception.
In the case of an exception, "DeviceError" returns the device specific error code stored with each channel. p1 Modula-2 stores the error code of the Macintosh runtime system in this field.
DEFINITION MODULE IOConsts; (* Types and constants for input/output modules *) TYPE ReadResults = (* This type is used to classify the result of an input operation *) ( notKnown, (* no read result is set *) allRight, (* data is as expected or as required *) outOfRange, (* data cannot be represented *) wrongFormat, (* data not in expected format *) endOfLine, (* end of line seen before expected data *) endOfInput (* end of input seen before expected data *) ); END IOConsts."IOConsts" defines the state type for read operations. This type has been put inside a separate module to avoid dependencies between other library modules. For the user, this type is reexported from "IOResult", description see there.
DEFINITION MODULE IOLink; (* Types and procedures for the standard implementation of channels *) IMPORT IOChan, IOConsts, ChanConsts, SYSTEM; (* Devices need to identify themselves in order to allow a check to be made that device-dependent operations are applied only for channels opened to that device. *) TYPE DeviceId; (* Values of this type are used to identify new device modules, and are normally obtained by them during their initialization. *) PROCEDURE AllocateDeviceId (VAR did: DeviceId); (* Allocates a unique value of type DeviceId, and assigns this value to did. *) (* A new device module open procedure obtains a channel by calling MakeChan. *) PROCEDURE MakeChan (did: DeviceId; VAR cid: IOChan.ChanId); (* Attempts to make a new channel for the device module identified by did. If no more channels can be made, the identity of the invalid channel is assigned to cid. Otherwise, the identity of a new channel is assigned to cid. *) (* If a channel is allocated, but the call of the device module open procedure is not successful, or on a successful call of a device module close procedure, the device module unmakes the channel, and returns the value identifying the invalid channel to its client. *) PROCEDURE UnMakeChan (did: DeviceId; VAR cid: IOChan.ChanId); (* If the device module identified by did is not the module that made the channel identified by cid, the exception wrongDevice is raised; otherwise the channel is deallocated, and the value identifying the invalid channel is assigned to cid. *) (* If the call of the device module open procedure is successful, the device module obtains a pointer to a device table for the channel, which will have been initialized by MakeChan. It then changes the fields of the device table to install its own values for the device data, supported operations, and flags, and returns to its client the identity of the channel. *) TYPE DeviceTablePtr = POINTER TO DeviceTable; (* Values of this type are used to refer to device tables *) (* Device modules supply procedures of the following types: *) TYPE LookProc = PROCEDURE (DeviceTablePtr, VAR CHAR, VAR IOConsts.ReadResults); SkipProc = PROCEDURE (DeviceTablePtr); SkipLookProc = PROCEDURE (DeviceTablePtr, VAR CHAR, VAR IOConsts.ReadResults); TextReadProc = PROCEDURE (DeviceTablePtr, SYSTEM.ADDRESS, CARDINAL, VAR CARDINAL); TextWriteProc = PROCEDURE (DeviceTablePtr, SYSTEM.ADDRESS, CARDINAL); WriteLnProc = PROCEDURE (DeviceTablePtr); RawReadProc = PROCEDURE (DeviceTablePtr, SYSTEM.ADDRESS, CARDINAL, VAR CARDINAL); RawWriteProc = PROCEDURE (DeviceTablePtr, SYSTEM.ADDRESS, CARDINAL); GetNameProc = PROCEDURE (DeviceTablePtr, VAR ARRAY OF CHAR); ResetProc = PROCEDURE (DeviceTablePtr); FlushProc = PROCEDURE (DeviceTablePtr); FreeProc = PROCEDURE (DeviceTablePtr); (* Carry out the operations involved in closing the corresponding channel, including flushing buffers, but do not unmake the channel. *) (* Device tables have: a field in which the device module can store private data, a field in which the value identifying the device module is stored, a field in which the value identifying the channel is stored, a field in which the read result is stored, a field in which device error numbers are stored prior to the raising of a device error exception, a field in which flags are stored indicating those which apply, a field for each device procedure. The fields are initialized by MakeChan to the values shown for the type DeviceTable. *) TYPE DeviceData = SYSTEM.ADDRESS; DeviceTable = RECORD cd: DeviceData; (* the value NIL *) did: DeviceId; (* the value given in the call of MakeChan *) cid: IOChan.ChanId; (* the identity of the channel *) result: IOConsts.ReadResults;(* the value notKnown *) errNum: IOChan.DeviceErrNum; (* undefined *) flags: ChanConsts.FlagSet; (* ChanConsts.FlagSet{} *) doLook: LookProc; (* raise exception notAvailable *) doSkip: SkipProc; (* raise exception notAvailable *) doSkipLook: SkipLookProc; (* raise exception notAvailable *) doLnWrite: WriteLnProc; (* raise exception notAvailable *) doTextRead: TextReadProc; (* raise exception notAvailable *) doTextWrite: TextWriteProc; (* raise exception notAvailable *) doRawRead: RawReadProc; (* raise exception notAvailable *) doRawWrite: RawWriteProc; (* raise exception notAvailable *) doGetName: GetNameProc; (* return the empty string *) doReset: ResetProc; (* do nothing *) doFlush: FlushProc; (* do nothing *) doFree: FreeProc; (* do nothing *) END; (* The pointer to the device table for a channel is obtained using the following procedure: *) PROCEDURE DeviceTablePtrValue (cid: IOChan.ChanId; did: DeviceId): DeviceTablePtr; (* If the device module identified by did is not the module that made the channel identified by cid, the exception wrongDevice is raised; otherwise returns a pointer to the device table for the channel. *) (* A device module can enquire whether it opened a given channel. It does this to implement a corresponding enquiry function that is exported from the device module *) PROCEDURE IsDevice (cid: IOChan.ChanId; did: DeviceId): BOOLEAN; (* Tests if the device module identified by did is the module that made the channel identified by cid. *) (* Client modules may raise appropriate exceptions *) PROCEDURE RAISEdevException (cid: IOChan.ChanId; did: DeviceId; x: IOChan.ChanExceptions; s: ARRAY OF CHAR); (* If the device module identified by did is not the module that made the channel identified by cid, the exception wrongDevice is raised; otherwise the given exception is raised, and the string value in s is included in the exception message. *) PROCEDURE IOException (): IOChan.ChanExceptions; (* Returns the ChanExceptions value for the current context. *) PROCEDURE IsIOException (): BOOLEAN; (* Returns whether a ChanException has been raised in the current context. *) END IOLink."IOLink" is the base module for the device modules. It defines the data structures for the implementation of new devices, and supplies the auxiliary functions necessary to create and destroy a channel. Most users of the io library will not import from "IOLink", this module is used only for writing additional device modules.
"DevicdId" is a data type used to identify the various device modules. Every device module may allocate its specific identifier with "AllocateDeviceId".
"MakeChan" and "UnMakeChan" open and close channels.
"DeviceTable" (and "DeviceTablePtr") defines the common part of the data structure of each channel. Besides some status data, the procedures for data transfer are defined here. These procedures have to be provided by each device module. "IOChan" passes these procedures to the front end of the library. The device modules get access to the data structures of their own channels with "DeviceTablePtrValue". For safety purposes there is no possibility to access the data structures of any channel directly. With "IsDevice" a device module may test, whether a channel is one of its own.
The procedures "RAISEdevException" is provided for raising exceptions. It test whether the given channel is correct and if so, raises the exception "x". "IsIOException" allows to inform, whether an exception has been raised by the io library, "IOException" returns the exact exception. "IsIOException" and "IOException" are identical with "IOChan. IsChanException" and "IOChan. ChanException".
DEFINITION MODULE IOResult; (* Read results for specified channels *) IMPORT IOConsts, IOChan; TYPE ReadResults = IOConsts.ReadResults; (* ReadResults = (* This type is used to classify the result of an input operation *) ( notKnown, (* no read result is set *) allRight, (* data is as expected or as required *) outOfRange, (* data cannot be represented *) wrongFormat, (* data not in expected format *) endOfLine, (* end of line seen before expected data *) endOfInput (* end of input seen before expected data *) ); *) PROCEDURE ReadResult (cid: IOChan.ChanId): ReadResults; (* Returns the result for the last read operation on the channel cid. *) END IOResult."IOResult" provides the procedure "ReadResult" and the type "ReadResults" for information about the read state of a given channel. The possible values are:
notKnown | undefined state, e.g. before the first read operation. |
allRight | last operation was successful. |
outOfRange | data could not be represented, e.g string too small or number too large. |
wrongFormat | wrong format, e.g. on reading number |
endOfLine | no data read because of end of line (possible only with text operations). |
endOfInput | no data read because of end of file. |
DEFINITION MODULE LongIO; (* Input and output of long real numbers in decimal text form over specified channels. The read result is of the type IOConsts.ReadResults. *) IMPORT IOChan; (* The text form of a signed fixed-point real number is ["+" | "-"], decimal digit, {decimal digit}, [".", {decimal digit}] The text form of a signed floating-point real number is signed fixed-point real number, "E", ["+" | "-"], decimal digit, {decimal digit} *) PROCEDURE ReadReal (cid: IOChan.ChanId; VAR real: LONGREAL); (* Skips leading spaces, and removes any remaining characters from cid that form part of a signed fixed or floating point number. The value of this number is assigned to real. The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or endOfInput. *) PROCEDURE WriteFloat (cid: IOChan.ChanId; real: LONGREAL; sigFigs: CARDINAL; width: CARDINAL); (* Writes the value of real to cid in floating-point text form, with sigFigs significant figures, in a field of the given minimum width. *) PROCEDURE WriteEng (cid: IOChan.ChanId; real: LONGREAL; sigFigs: CARDINAL; width: CARDINAL); (* As for WriteFloat, except that the number is scaled with one to three digits in the whole number part, and with an exponent that is a multiple of three. *) PROCEDURE WriteFixed (cid: IOChan.ChanId; real: LONGREAL; place: INTEGER; width: CARDINAL); (* Writes the value of real to cid in fixed-point text form, rounded to the given place relative to the decimal point, in a field of the given minimum width. *) PROCEDURE WriteReal (cid: IOChan.ChanId; real: LONGREAL; width: CARDINAL); (* Writes the value of real to cid, as WriteFixed if the sign and magnitude can be shown in the given width, or otherwise as WriteFloat. The number of places or significant digits depends on the given width. *) END LongIO.The module "LongIO" is corresponds to "RealIO" for input and output of values of type "LONGREAL".
"ReadReal" reads a real number from the given channel and sets the read state to the according value.
"WriteFloat" writes a real number in scientific notation with the given number of significant digits. "WriteEng" is analogous to "WriteFloat", but sets the exponent to a multiple of three.
"WriteFixed" writes a real number in fixed point notation. "place" is the number of digits the number is rounded to. A value greater than 0 signifies digits right to the decimal point, a value less than 0 signifies digits left to the decimal point.
"WriteReal" writes a real number in fixed point notation, if "width" is large enough to take the number. Otherwise the number is written in scientific notation.
DEFINITION MODULE ProgramArgs; (* Access to program arguments *) IMPORT IOChan; TYPE ChanId = IOChan.ChanId; PROCEDURE ArgChan (): ChanId; (* Returns a value that identifies a channel for reading program arguments *) PROCEDURE IsArgPresent (): BOOLEAN; (* Tests if there is a current argument to read from. If not, read <= IOChan.CurrentFlags() will be FALSE, and attempting to read from the argument channel will raise the exception notAvailable. *) PROCEDURE NextArg (); (* If there is another argument, causes subsequent input from the argument device to come from the start of the next argument. Otherwise there is no argument to read from, and a call of IsArgPresent will return FALSE. *) END ProgramArgs."ProgramArgs" provides access to the command line (of a MPW tool) via the channel returned by "ArgChan". "IsArgPresent" informs, wether there are (more) parameters available. "NextArg" switches to the next parameter.
For a application, "IsArgPresent" returns always "FALSE". Trying to read from the argument channel leads to the exception "notAvailable".
For command line tools the command line is split into arguments according to the shell rules. Each argument can be read separately until "IOResults. ReadResult" returns "endOfInput". "NextArg" switches to the next argument.
According to the shell conventions, the first argument is always the name of the tool.
"IOChan. Reset" switches back to the start of the argument list. Thus, multiple reads of the command line are possible.
DEFINITION MODULE RawIO; (* Reading and writing data over specified channels using raw operations, that is, with no conversion or interpretation. The read result is of the type IOConsts.ReadResults. *) IMPORT IOChan, SYSTEM; PROCEDURE Read (cid: IOChan.ChanId; VAR to: ARRAY OF SYSTEM.LOC); (* Reads storage units from cid, and assigns them to successive components of to. The read result is set to the value allRight, wrongFormat, or endOfInput. *) PROCEDURE Write (cid: IOChan.ChanId; from: ARRAY OF SYSTEM.LOC); (* Writes storage units to cid from successive components of from. *) END RawIO."RawIO" is the "high level" module for uninterpreted ("raw") data transfer.
"Write" writes to the given channel.
"Read" reads the appropriate number of LOCs into the given array. If the end of the file is encountered before the array is filled, the read result is set to "wrongFormat". A read result of "endOfInput" indicates, that no data at all could be read.
DEFINITION MODULE RealIO; (* Input and output of real numbers in decimal text form over specified channels. The read result is of the type IOConsts.ReadResults. *) IMPORT IOChan; (* The text form of a signed fixed-point real number is ["+" | "-"], decimal digit, {decimal digit}, [".", {decimal digit}] The text form of a signed floating-point real number is signed fixed-point real number, "E", ["+" | "-"], decimal digit, {decimal digit} *) PROCEDURE ReadReal (cid: IOChan.ChanId; VAR real: REAL); (* Skips leading spaces, and removes any remaining characters from cid that form part of a signed fixed or floating point number. The value of this number is assigned to real. The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or endOfInput. *) PROCEDURE WriteFloat (cid: IOChan.ChanId; real: REAL; sigFigs: CARDINAL; width: CARDINAL); (* Writes the value of real to cid in floating-point text form, with sigFigs significant figures, in a field of the given minimum width. *) PROCEDURE WriteEng (cid: IOChan.ChanId; real: REAL; sigFigs: CARDINAL; width: CARDINAL); (* As for WriteFloat, except that the number is scaled with one to three digits in the whole number part, and with an exponent that is a multiple of three. *) PROCEDURE WriteFixed (cid: IOChan.ChanId; real: REAL; place: INTEGER; width: CARDINAL); (* Writes the value of real to cid in fixed-point text form, rounded to the given place relative to the decimal point, in a field of the given minimum width. *) PROCEDURE WriteReal (cid: IOChan.ChanId; real: REAL; width: CARDINAL); (* Writes the value of real to cid, as WriteFixed if the sign and magnitude can be shown in the given width, or otherwise as WriteFloat. The number of places or significant digits depends on the given width. *) END RealIO.The module "RealIO" corresponds to "LongIO" for input and output of values of type "REAL".
"ReadReal" reads a real number from the given channel and sets the read state to the according value.
"WriteFloat" writes a real number in scientific notation with the given number of significant digits. "WriteEng" is analogous to "WriteFloat", but sets the exponent to a multiple of three.
"WriteFixed" writes a real number in fixed point notation. "place" is the number of digits the number is rounded to. A value greater than 0 signifies digits right to the decimal point, a value less than 0 signifies digits left to the decimal point.
"WriteReal" writes a real number in fixed point notation, if "width" is large enough to take the number. Otherwise the number is written in scientific notation.
DEFINITION MODULE RndFile; (* Random access files *) IMPORT IOChan, ChanConsts, SYSTEM; TYPE ChanId = IOChan.ChanId; FlagSet = ChanConsts.FlagSet; OpenResults = ChanConsts.OpenResults; (* Accepted singleton values of FlagSet *) CONST read = FlagSet{ChanConsts.readFlag}; (* input operations are requested/available *) write = FlagSet{ChanConsts.writeFlag}; (* output operations are requested/available *) old = FlagSet{ChanConsts.oldFlag}; (* a file may/must/did exist before the channel is opened *) text = FlagSet{ChanConsts.textFlag}; (* text operations are requested/available *) raw = FlagSet{ChanConsts.rawFlag}; (* raw operations are requested/available *) PROCEDURE OpenOld (VAR cid: ChanId; name: ARRAY OF CHAR; flags: FlagSet; VAR res: OpenResults); (* Attempts to obtain and open a channel connected to a stored random access file of the given name. The old flag is implied; without the write flag, read is implied; without the text flag, raw is implied. If successful, assigns to cid the identity of the opened channel, assigns the value opened to res, and sets the read/write position to the start of the file. If a channel cannot be opened as required, the value of res indicates the reason, and cid identifies the invalid channel. *) PROCEDURE OpenClean (VAR cid: ChanId; name: ARRAY OF CHAR; flags: FlagSet; VAR res: OpenResults); (* Attempts to obtain and open a channel connected to a stored random access file of the given name. The write flag is implied; without the text flag, raw is implied. If successful, assigns to cid the identity of the opened channel, assigns the value opened to res, and truncates the file to zero length. If a channel cannot be opened as required, the value of res indicates the reason, and cid identifies the invalid channel. *) PROCEDURE IsRndFile (cid: ChanId): BOOLEAN; (* Tests if the channel identified by cid is open to a random access file. *) PROCEDURE IsRndFileException (): BOOLEAN; (* Returns TRUE iff an exception has been raised by the module RndFile *) CONST FilePosSize = 8; TYPE FilePos = ARRAY [1 .. FilePosSize] OF SYSTEM.LOC; PROCEDURE StartPos (cid: ChanId): FilePos; (* If the channel identified by cid is not open to a random access file, the exception wrongDevice is raised; otherwise returns the position of the start of the file. *) PROCEDURE CurrentPos (cid: ChanId): FilePos; (* If the channel identified by cid is not open to a random access file, the exception wrongDevice is raised; otherwise returns the position of the current read/write position. *) PROCEDURE EndPos (cid: ChanId): FilePos; (* If the channel identified by cid is not open to a random access file, the exception wrongDevice is raised; otherwise returns the first position after which there have been no writes. *) PROCEDURE NewPos (cid: ChanId; chunks: INTEGER; chunkSize: CARDINAL; from: FilePos): FilePos; (* If the channel identified by cid is not open to a random access file, the exception wrongDevice is raised; otherwise returns the position (chunks * chunkSize) relative to the position given by from, or raises the exception posRange if the required position cannot be represented as a value of type FilePos. *) PROCEDURE SetPos (cid: ChanId; pos: FilePos); (* If the channel identified by cid is not open to a random access file, the exception wrongDevice is raised; otherwise sets the read/write position to the value given by pos. *) PROCEDURE Close (VAR cid: ChanId); (* If the channel identified by cid is not open to a random access file, the exception wrongDevice is raised; otherwise closes the channel, and assigns the value identifying the invalid channel to cid. *) END RndFile.The device module "RndFile" deals with random access files.
"OpenOld" opens a file that has to exist. If neither "write" nor "read" is passed in "flags", the files is opened for read access. If neither "text" nor "raw" is passed in "flags", only raw access is allowed. After successful opening, "cid" contains the opened channel, the read / write position is at the start of the file and "res" contains the value "opened". Otherwise, "res" indicates the error reason, and "cid" identifies the illegal channel.
"OpenClean" opens a file, that may exist only if "old" is given, and clears its contents if necessary. Write access is enabled automatically. If neither "text" nor "raw" is passed in "flags", only raw access is allowed. After successful opening, "cid" contains the opened channel, the read / write position is at the start of the file, and "res" contains the value "opened". Otherwise, "res" indicates the error reason, "cid" identifies the illegal channel.
"IsRndFile" tests whether a channel was opened by "RndFile".
An exception may be raised due to wrong positioning. "IsRndFileException" is the according enquiry function, a result of "TRUE" indicates a illegal file position.
File positions can be stored in variables of type "FilePos".
The procedure "StartPos" returns the position at the start of the file, "CurrentPos" returns the current read / write position, and "EndPos" the position after the last element in the file.
"NewPos" calculates a file position relative to "from". The distance is calculated from the element size "chunkSize" and the number of elements "chunks". A positive number of elements indicates a position towards the end of the file, a negative number of elements indicates a position towards the start of the file.
"NewPos" repositions the read / write marker within the file. As long as a file position is at the end of this file, read access is disabled
"Close" writes buffered data if necessary, closes the file, and destroys the assigned channel.
"IOChan. Reset (cid)" has the same effect as "SetPos (cid, StartPos (cid))".
For positioning in text files, the end-of-line marker (CR) counts as one character.
DEFINITION MODULE SeqFile; (* Rewindable sequential files *) IMPORT IOChan, ChanConsts; TYPE ChanId = IOChan.ChanId; FlagSet = ChanConsts.FlagSet; OpenResults = ChanConsts.OpenResults; (* Accepted singleton values of FlagSet *) CONST read = FlagSet{ChanConsts.readFlag}; (* input operations are requested/available *) write = FlagSet{ChanConsts.writeFlag}; (* output operations are requested/available *) old = FlagSet{ChanConsts.oldFlag}; (* a file may/must/did exist before the channel is opened *) text = FlagSet{ChanConsts.textFlag}; (* text operations are requested/available *) raw = FlagSet{ChanConsts.rawFlag}; (* raw operations are requested/available *) PROCEDURE OpenWrite (VAR cid: ChanId; name: ARRAY OF CHAR; flags: FlagSet; VAR res: OpenResults); (* Attempts to obtain and open a channel connected to a stored rewindable file of the given name. The write flag is implied; without the raw flag, text is implied. If successful, assigns to cid the identity of the opened channel, assigns the value opened to res, and selects output mode, with the write position at the start of the file (i.e. the file is of zero length). If a channel cannot be opened as required, the value of res indicates the reason, and cid identifies the invalid channel. *) PROCEDURE OpenAppend (VAR cid: ChanId; name: ARRAY OF CHAR; flags: FlagSet; VAR res: OpenResults); (* Attempts to obtain and open a channel connected to a stored rewindable file of the given name. The write and old flags are implied; without the raw flag, text is implied. If successful, assigns to cid the identity of the opened channel, assigns the value opened to res, and selects output mode, with the write position corresponding to the length of the file. If a channel cannot be opened as required, the value of res indicates the reason, and cid identifies the invalid channel. *) PROCEDURE OpenRead (VAR cid: ChanId; name: ARRAY OF CHAR; flags: FlagSet; VAR res: OpenResults); (* Attempts to obtain and open a channel connected to a stored rewindable file of the given name. The read and old flags are implied; without the raw flag, text is implied. If successful, assigns to cid the identity of the opened channel, assigns the value opened to res, and selects input mode, with the read position corresponding to the start of the file. If a channel cannot be opened as required, the value of res indicates the reason, and cid identifies the invalid channel. *) PROCEDURE IsSeqFile (cid: ChanId): BOOLEAN; (* Tests if the channel identified by cid is open to a rewindable sequential file. *) PROCEDURE Reread (cid: ChanId); (* If the channel identified by cid is not open to a rewindable sequential file, the exception wrongDevice is raised; otherwise attempts to set the read position to the start of the file, and to select input mode. If the operation cannot be performed (perhaps because of insufficient permissions) neither input mode nor output mode is selected. *) PROCEDURE Rewrite (cid: ChanId); (* If the channel identified by cid is not open to a rewindable sequential file, the exception wrongDevice is raised; otherwise, attempts to truncate the file to zero length, and to select output mode. If the operation cannot be performed (perhaps because of insufficient permissions) neither input mode nor output mode is selected. *) PROCEDURE Close (VAR cid: ChanId); (* If the channel identified by cid is not open to a rewindable sequential file, the exception wrongDevice is raised; otherwise closes the channel, and assigns the value identifying the invalid channel to cid. *) END SeqFile.The device module "SeqFile" deals with sequential files that allow positioning at the start or end of the file. An open channel is either in read or in write mode. Switching is possible (if the necessary flags were specified at opening of the file) via "Reread" or "Rewrite".
"OpenWrite" opens a file, that may exist only if "old" is given. Write access is enabled automatically. If neither "text" nor "raw" is passed in "flags", only text access is allowed. After successful opening, "cid" contains the opened channel, the write position is at the start of the file and "res" contains the value "opened". Otherwise, "res" indicates the error reason, and "cid" identifies the illegal channel.
"OpenAppend" opens a file that has to exist. Write access is enabled automatically. If neither "text" nor "raw" is passed in "flags", only text access is allowed. After successful opening, "cid" contains the opened channel, the write position is at the end of the file, and "res" contains the value "opened". Otherwise, "res" indicates the error reason and "cid" identifies the illegal channel.
"OpenRead" opens a file that has to exist. Read access is enabled automatically. If neither "text" nor "raw" is passed in "flags", only text access is allowed. After successful opening, "cid" contains the opened channel, the read position is at the start of the file, and "res" contains the value "opened". Otherwise, "res" indicates the error reason and "cid" identifies the illegal channel.
"IsSeqFile" tests whether a channel has been opened by "SeqFile".
If read access is specified, "Reread" positions to the start of the file and switches to read mode. Analogous, if write access is specified, "Rewrite" positions to the start of the file and switches to write mode.
"Close" writes buffered data if necessary, closes the file, and destroys the assigned channel.
"IOChan. Reset (cid)" has the same effekt as "Reread" or "Rewrite", depending on the mode (read or write).
DEFINITION MODULE SIOResult; (* Read results for the default input channel *) IMPORT IOConsts; TYPE ReadResults = IOConsts.ReadResults; (* ReadResults = (* This type is used to classify the result of an input operation *) ( notKnown, (* no read result is set *) allRight, (* data is as expected or as required *) outOfRange, (* data cannot be represented *) wrongFormat, (* data not in expected format *) endOfLine, (* end of line seen before expected data *) endOfInput (* end of input seen before expected data *) ); *) PROCEDURE ReadResult (): ReadResults; (* Returns the result for the last read operation on the default input channel. *) END SIOResult."SIOResult" implements the same functionality as "IOResult", but returns always the state of the standard input channel.
DEFINITION MODULE SLongIO; (* Input and output of long real numbers in decimal text form using default channels. The read result is of the type IOConsts.ReadResults. *) (* The text form of a signed fixed-point real number is ["+" | "-"], decimal digit, {decimal digit}, [".", {decimal digit}] The text form of a signed floating-point real number is signed fixed-point real number, "E", ["+" | "-"], decimal digit, {decimal digit} *) PROCEDURE ReadReal (VAR real: LONGREAL); (* Skips leading spaces, and removes any remaining characters from the default input channel that form part of a signed fixed or floating point number. The value of this number is assigned to real. The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or endOfInput. *) PROCEDURE WriteFloat (real: LONGREAL; sigFigs: CARDINAL; width: CARDINAL); (* Writes the value of real to the default output channel in floating-point text form, with sigFigs significant figures, in a field of the given minimum width. *) PROCEDURE WriteEng (real: LONGREAL; sigFigs: CARDINAL; width: CARDINAL); (* As for WriteFloat, except that the number is scaled with one to three digits in the whole number part, and with an exponent that is a multiple of three. *) PROCEDURE WriteFixed (real: LONGREAL; place: INTEGER; width: CARDINAL); (* Writes the value of real to the default output channel in fixed-point text form, rounded to the given place relative to the decimal point, in a field of the given minimum width. *) PROCEDURE WriteReal (real: LONGREAL; width: CARDINAL); (* Writes the value of real to the default output channel, as WriteFixed if the sign and magnitude can be shown in the given width, or otherwise as WriteFloat. The number of places or significant digits depends on the given width. *) END SLongIO."SLongIO" is the equivalent to "LongIO" with predefined standard in- and outchannel.
DEFINITION MODULE SRawIO; (* Reading and writing data over default channels using raw operations, that is, with no conversion or interpretation. The read result is of the type IOConsts.ReadResults. *) IMPORT SYSTEM; PROCEDURE Read (VAR to: ARRAY OF SYSTEM.LOC); (* Reads storage units from the default input channel, and assigns them to successive components of to. The read result is set to the value allRight, wrongFormat, or endOfInput. *) PROCEDURE Write (from: ARRAY OF SYSTEM.LOC); (* Writes storage units to the default output channel from successive components of from. *) END SRawIO."SRawIO" is the equivalent to "RawIO" with predefined standard in- and outchannel.
DEFINITION MODULE SRealIO; (* Input and output of real numbers in decimal text form over default channels. The read result is of the type IOConsts.ReadResults. *) (* The text form of a signed fixed-point real number is ["+" | "-"], decimal digit, {decimal digit}, [".", {decimal digit}] The text form of a signed floating-point real number is signed fixed-point real number, "E", ["+" | "-"], decimal digit, {decimal digit} *) PROCEDURE ReadReal (VAR real: REAL); (* Skips leading spaces, and removes any remaining characters from the default output channel that form part of a signed fixed or floating point number. The value of this number is assigned to real. The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or endOfInput. *) PROCEDURE WriteFloat (real: REAL; sigFigs: CARDINAL; width: CARDINAL); (* Writes the value of real to the default output channel in floating-point text form, with sigFigs significant figures, in a field of the given minimum width. *) PROCEDURE WriteEng (real: REAL; sigFigs: CARDINAL; width: CARDINAL); (* As for WriteFloat, except that the number is scaled with one to three digits in the whole number part, and with an exponent that is a multiple of three. *) PROCEDURE WriteFixed (real: REAL; place: INTEGER; width: CARDINAL); (* Writes the value of real to the default output channel in fixed-point text form, rounded to the given place relative to the decimal point, in a field of the given minimum width. *) PROCEDURE WriteReal (real: REAL; width: CARDINAL); (* Writes the value of real to the default output channel, as WriteFixed if the sign and magnitude can be shown in the given width, or otherwise as WriteFloat. The number of places or significant digits depends on the given width. *) END SRealIO."SRealIO" is the equivalent to "RealIO" with predefined standard in- and outchannel.
DEFINITION MODULE StdChans; (* Access to standard and default channels *) IMPORT IOChan; TYPE ChanId = IOChan.ChanId; (* Values of this type are used to identify channels *) (* The following functions return the standard channel values. These channels cannot be closed. *) PROCEDURE StdInChan (): ChanId; (* Returns the identity of the implementation-defined standard source for program input. *) PROCEDURE StdOutChan (): ChanId; (* Returns the identity of the implementation-defined standard source for program output. *) PROCEDURE StdErrChan (): ChanId; (* Returns the identity of the implementation-defined standard destination for program error messages. *) PROCEDURE NullChan (): ChanId; (* Returns the identity of a channel open to the null device. *) (* The following functions return the default channel values *) PROCEDURE InChan (): ChanId; (* Returns the identity of the current default input channel. *) PROCEDURE OutChan (): ChanId; (* Returns the identity of the current default output channel. *) PROCEDURE ErrChan (): ChanId; (* Returns the identity of the current default error message channel. *) (* The following procedures allow for redirection of the default channels *) PROCEDURE SetInChan (cid: ChanId); (* Sets the current default input channel to that identified by cid. *) PROCEDURE SetOutChan (cid: ChanId); (* Sets the current default output channel to that identified by cid. *) PROCEDURE SetErrChan (cid: ChanId); (* Sets the current default error channel to that identified by cid. *) END StdChans."StdChans" manages the standard channels.
"StdInChan", "StdOutChan", and "StdErrChan" identify the predefined standard channels. For command line tools they are assigned to the corresponding channels of the operating system, all redirections in the command line are passed to the program. For applications a simple text window is assigned to these channels if necessary.
At the start of a program, "InChan", "OutChan", and "ErrChan" are assigned to "StdInChan", "StdOutChan", and "StdErrChan". The value of these channels can be changed with "SetInChan", "SetOutChan", and "SetErrChan". The S-modules use "InChan" and "OutChan".
"NullChan" is a waste basket. All written data is thrown away and reading results always in reaching "endOfInput".
DEFINITION MODULE STextIO; (* Input and output of character and string types over default channels. The read result is of the type IOConsts.ReadResults. *) (* The following procedures do not read past line marks *) PROCEDURE ReadChar (VAR ch: CHAR); (* If possible, removes a character from the default input stream, and assigns the corresponding value to ch. The read result is set to allRight, endOfLine or endOfInput. *) PROCEDURE ReadRestLine (VAR s: ARRAY OF CHAR); (* Removes any remaining characters from the default input stream before the next line mark, copying to s as many as can be accommodated as a string value. The read result is set to the value allRight, outOfRange, endOfLine, or endOfInput. *) PROCEDURE ReadString (VAR s: ARRAY OF CHAR); (* Removes only those characters from the default input stream before the next line mark that can be accommodated in s as a string value, and copies them to s. The read result is set to the value allRight, endOfLine, or endOfInput. *) PROCEDURE ReadToken (VAR s: ARRAY OF CHAR); (* Skips leading spaces, and then removes characters from the default input stream before the next space or line mark, copying to s as many as can be accommodated as a string value. The read result is set to the value allRight, outOfRange, endOfLine, or endOfInput. *) (* The following procedure reads past the next line mark *) PROCEDURE SkipLine; (* Removes successive items from the default input stream up to and including the next line mark or until the end of input is reached. The read result is set to the value allRight, or endOfInput. *) (* Output procedures *) PROCEDURE WriteChar (ch: CHAR); (* Writes the value of ch to the default output stream. *) PROCEDURE WriteLn; (* Writes a line mark to the default output stream. *) PROCEDURE WriteString (s: ARRAY OF CHAR); (* Writes the string value of s to the default output stream. *) END STextIO."STextIO" is the equivalent to "TextIO" with predefined standard in- and outchannel.
DEFINITION MODULE StreamFile; (* Independent sequential data streams *) IMPORT IOChan, ChanConsts; TYPE ChanId = IOChan.ChanId; FlagSet = ChanConsts.FlagSet; OpenResults = ChanConsts.OpenResults; (* Accepted singleton values of FlagSet *) CONST read = FlagSet{ChanConsts.readFlag}; (* input operations are requested/available *) write = FlagSet{ChanConsts.writeFlag}; (* output operations are requested/available *) old = FlagSet{ChanConsts.oldFlag}; (* a file may/must/did exist before the channel is opened *) text = FlagSet{ChanConsts.textFlag}; (* text operations are requested/available *) raw = FlagSet{ChanConsts.rawFlag}; (* raw operations are requested/available *) PROCEDURE Open (VAR cid: ChanId; name: ARRAY OF CHAR; flags: FlagSet; VAR res: OpenResults); (* Attempts to obtain and open a channel connected to a sequential stream of the given name. The read flag implies old; without the raw flag, text is implied. If successful, assigns to cid the identity of the opened channel, and assigns the value opened to res. If a channel cannot be opened as required, the value of res indicates the reason, and cid identifies the invalid channel. *) PROCEDURE IsStreamFile (cid: ChanId): BOOLEAN; (* Tests if the channel identified by cid is open to a sequential stream. *) PROCEDURE Close (VAR cid: ChanId); (* If the channel identified by cid is not open to a sequential stream, the exception wrongDevice is raised; otherwise closes the channel, and assigns the value identifying the invalid channel to cid. *) END StreamFile."StreamFile" models sequential data streams. As disk files allow only either reading or writing, parallel reading and writing is available only for ttys, serial lines etc.
"Open" opens a file for reading or writing exclusively (specification necessary). "read" implies "old" and needs a existing file. "write + old" has to be specified for rewriting a file. If neither "text" nor "raw" is passed in "flags", only text access is allowed. After successful opening, "cid" contains the opened channel, the file position is at the start of the file, and "res" contains the value "opened". Otherwise, "res" indicates the error reason and "cid" identifies the illegal channel.
"IsStreamFile" tests whether a channel has been opened by "StreamFile".
"Close" writes buffered data if necessary, closes the file, and destroys the assigned channel.
"IOChan. Reset (cid)" does nothing.
DEFINITION MODULE SWholeIO; (* Input and output of whole numbers in decimal text form over default channels. The read result is of the type IOConsts.ReadResults. *) (* The text form of a signed whole number is ["+" | "-"], decimal digit, {decimal digit} The text form of an unsigned whole number is decimal digit, {decimal digit} *) PROCEDURE ReadInt (VAR int: INTEGER); (* Skips leading spaces, and removes any remaining characters from the default input channel that form part of a signed whole number. The value of this number is assigned to int. The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or endOfInput. *) PROCEDURE WriteInt (int: INTEGER; width: CARDINAL); (* Writes the value of int to the default output channel in text form, in a field of the given minimum width. *) PROCEDURE ReadCard (VAR card: CARDINAL); (* Skips leading spaces, and removes any remaining characters from the default input channel that form part of an unsigned whole number. The value of this number is assigned to card. The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or endOfInput. *) PROCEDURE WriteCard (card: CARDINAL; width: CARDINAL); (* Writes the value of card to the default output channel in text form, in a field of the given minimum width. *) END SWholeIO."SWholeIO" is the equivalent to "WholeIO" with predefined standard in- and outchannel.
DEFINITION MODULE TermFile; (* Access to the terminal device *) (* Channels opened by this module are connected to a single terminal device; typed characters are distributed between channels according to the sequence of read requests. *) IMPORT IOChan, ChanConsts; TYPE ChanId = IOChan.ChanId; FlagSet = ChanConsts.FlagSet; OpenResults = ChanConsts.OpenResults; (* Accepted singleton values of FlagSet *) CONST read = FlagSet{ChanConsts.readFlag}; (* input operations are requested/available *) write = FlagSet{ChanConsts.writeFlag}; (* output operations are requested/available *) text = FlagSet{ChanConsts.textFlag}; (* text operations are requested/available *) raw = FlagSet{ChanConsts.rawFlag}; (* raw operations are requested/available *) echo = FlagSet{ChanConsts.echoFlag}; (* echoing by interactive device on reading of characters from input stream requested/applies *) PROCEDURE Open (VAR cid: ChanId; flags: FlagSet; VAR res: OpenResults); (* Attempts to obtain and open a channel connected to the terminal. Without the raw flag, text is implied. Without the echo flag, line mode is requested, otherwise single character mode is requested. If successful, assigns to cid the identity of the opened channel, and assigns the value opened to res. If a channel cannot be opened as required, the value of res indicates the reason, and cid identifies the invalid channel. *) PROCEDURE IsTermFile (cid: ChanId): BOOLEAN; (* Tests if the channel identified by cid is open to the terminal. *) PROCEDURE Close (VAR cid: ChanId); (* If the channel identified by cid is not open to the terminal, the exception wrongDevice is raised; otherwise closes the channel and assigns the value identifying the invalid channel to cid. *) END TermFile."TermFile" offers access to either the terminal window of the current shell (for command line tools) or the terminal window opened by module "TermBase" (for applications, cf. section 2.1.10 / 2.2.4) with control of echoing and buffering. If channels are opened in line mode as well as in character mode, read operations in line mode always lead to buffering of a whole line. Characters not processed by this operation may than be read in single character mode.
DEFINITION MODULE TextIO; (* Input and output of character and string types over specified channels. The read result is of the type IOConsts.ReadResults. *) IMPORT IOChan; (* The following procedures do not read past line marks *) PROCEDURE ReadChar (cid: IOChan.ChanId; VAR ch: CHAR); (* If possible, removes a character from the input stream cid and assigns the corresponding value to ch. The read result is set to the value allRight, endOfLine, or endOfInput. *) PROCEDURE ReadRestLine (cid: IOChan.ChanId; VAR s: ARRAY OF CHAR); (* Removes any remaining characters from the input stream cid before the next line mark, copying to s as many as can be accommodated as a string value. The read result is set to the value allRight, outOfRange, endOfLine, or endOfInput. *) PROCEDURE ReadString (cid: IOChan.ChanId; VAR s: ARRAY OF CHAR); (* Removes only those characters from the input stream cid before the next line mark that can be accommodated in s as a string value, and copies them to s. The read result is set to the value allRight, endOfLine, or endOfInput. *) PROCEDURE ReadToken (cid: IOChan.ChanId; VAR s: ARRAY OF CHAR); (* Skips leading spaces, and then removes characters from the input stream cid before the next space or line mark, copying to s as many as can be accommodated as a string value. The read result is set to the value allRight, outOfRange, endOfLine, or endOfInput. *) (* The following procedure reads past the next line mark *) PROCEDURE SkipLine (cid: IOChan.ChanId); (* Removes successive items from the input stream cid up to and including the next line mark, or until the end of input is reached. The read result is set to the value allRight, or endOfInput. *) (* Output procedures *) PROCEDURE WriteChar (cid: IOChan.ChanId; ch: CHAR); (* Writes the value of ch to the output stream cid. *) PROCEDURE WriteLn (cid: IOChan.ChanId); (* Writes a line mark to the output stream cid. *) PROCEDURE WriteString (cid: IOChan.ChanId; s: ARRAY OF CHAR); (* Writes the string value in s to the output stream cid. *) END TextIO."TextIO" is the high level module for input and output of text. Success of each read operation can be tested with "IOResults. ReadResult".
"ReadChar" reads one character if not at end of line or at end of file.
"ReadString" reads a string of characters until either the given array is filled or end of line / end of file is reached. "endOfLine" or "endOfFile" are returned, if no character could be read.
"ReadRestLine" works similar to "ReadString", but discards the rest of the line (if any). If not all characters could be stored in the given array, a read result of "outOfRange" is set.
"ReadToken" skips leading blanks and tries to store the entire text up to the next blank, end of line, or end of input in the given array. A read result of "allRight", "endOfLine (no character has been read because end of line), "endOfInput" (no character has been read because end of input), or "outOfRange" (array too small for whole string) is set accordingly.
"SkipLine" skips all characters up to and including the next line mark (if not reaching the end of file first).
"WriteChar" and "WriteString" write the given character or string to the specified channel.
"WriteLn" writes a device dependent line mark.
The following example program copies a file character by character observing end of file and end of line results of "IOResult. ReadResult". Other examples (copying by line, copying with the procedures of "IOChan") can be found in the folder "Examples" of the distribution kit.
MODULE CopyByChar; (* Copies a text file character by character.*) FROM STextIO IMPORT WriteString, WriteChar, WriteLn, ReadString, SkipLine; FROM SeqFile IMPORT text, old, ChanId, OpenResults, OpenRead, OpenWrite, Close; FROM IOResult IMPORT ReadResults, ReadResult; IMPORT Text; VAR inFile, outFile: ChanId; inFileName, outFileName: ARRAY [0 .. 79] OF CHAR; ch: CHAR; ores: OpenResults; BEGIN WriteString ('Name of input file ?'); WriteLn; WriteChar (">"); ReadString (inFileName); SkipLine; WriteString ('Name of output file ?'); WriteLn; WriteChar (">"); ReadString (outFileName); SkipLine; OpenRead (inFile, inFileName, text, ores); (* open input file in text mode, only read operations are requested. *) IF ores <> opened THEN WriteString ('Could not open input file.'); WriteLn; HALT; END(*IF*); OpenWrite (outFile, outFileName, text + old, ores); (* open output file in text mode, the file may exist. *) IF ores <> opened THEN WriteString ('Could not open output file.'); WriteLn; HALT; END(*IF*); LOOP Text. ReadChar (inFile, ch); (* reads a character from the current line. *) CASE ReadResult (inFile) OF endOfInput: (* End of input stream encountered. *) EXIT; | endOfLine: (* End of current line encountered. *) Text. SkipLine (inFile); Text. WriteLn (outFile); ELSE (* Only "allRight" is possible here. *) Text. WriteChar (outFile, ch); END(*CASE*); END(*LOOP*); Close (inFile); Close (outFile); END CopyByChar.
DEFINITION MODULE WholeIO; (* Input and output of whole numbers in decimal text form over specified channels. The read result is of the type IOConsts.ReadResults. *) IMPORT IOChan; (* The text form of a signed whole number is ["+" | "-"], decimal digit, {decimal digit} The text form of an unsigned whole number is decimal digit, {decimal digit} *) PROCEDURE ReadInt (cid: IOChan.ChanId; VAR int: INTEGER); (* Skips leading spaces, and removes any remaining characters from cid that form part of a signed whole number. The value of this number is assigned to int. The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or endOfInput. *) PROCEDURE WriteInt (cid: IOChan.ChanId; int: INTEGER; width: CARDINAL); (* Writes the value of int to cid in text form, in a field of the given minimum width. *) PROCEDURE ReadCard (cid: IOChan.ChanId; VAR card: CARDINAL); (* Skips leading spaces, and removes any remaining characters from cid that form part of an unsigned whole number. The value of this number is assigned to card. The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or endOfInput. *) PROCEDURE WriteCard (cid: IOChan.ChanId; card: CARDINAL; width: CARDINAL); (* Writes the value of card to cid in text form, in a field of the given minimum width. *) END WholeIO."WholeIO" handles the input and output of whole numbers in textual form.
"ReadInt" and "ReadCard" read a number from the specified channel and set the according read result. "outOfRange" indicates, that the number has been too large (absolute value).
"WriteInt" and "WriteCard" write a number with at least "width" places. If "width" equals 0, exactly one leading blank is written.
The conversion modules "xxxConv" and "xxxStr", together with module "ConvTypes", provide the procedures for conversion of numerical data to strings and vice versa. The modules "xxxStr" are the high level modules with simple conversion procedures. The modules "xxxConv" provide the basic procedures for the conversion of string to numbers.
The modules "Processes" and "Semaphores" provide mechanisms for the management of (virtually) parallel processes.
"SysClock" date and time procedures.
DEFINITION MODULE Strings; (* Facilities for manipulating strings *) TYPE String1 = ARRAY [0..0] OF CHAR; (* String1 is provided for constructing a value of a single-character string type from a single character value in order to pass CHAR values to ARRAY OF CHAR parameters. *) PROCEDURE Length (stringVal: ARRAY OF CHAR): CARDINAL; (* Returns the length of stringVal (the same value as would be returned by the predefined function LENGTH). *) (* The following seven procedures construct a string value, and attempt to assign it to a variable parameter. They all have the property that if the length of the constructed string value exceeds the capacity of the variable parameter, a truncated value is assigned, while if the length of the constructed string value is less than the capacity of the variable parameter, a string terminator is appended before assignment is performed. *) PROCEDURE Assign (source: ARRAY OF CHAR; VAR destination: ARRAY OF CHAR); (* Copies source to destination *) PROCEDURE Extract (source: ARRAY OF CHAR; startIndex, numberToExtract: CARDINAL; VAR destination: ARRAY OF CHAR); (* Copies at most numberToExtract characters from source to destination, starting at position startIndex in source. *) PROCEDURE Delete (VAR stringVar: ARRAY OF CHAR; startIndex, numberToDelete: CARDINAL); (* Deletes at most numberToDelete characters from stringVar, starting at position startIndex. *) PROCEDURE Insert (source: ARRAY OF CHAR; startIndex: CARDINAL; VAR destination: ARRAY OF CHAR); (* Inserts source into destination at position startIndex *) PROCEDURE Replace (source: ARRAY OF CHAR; startIndex: CARDINAL; VAR destination: ARRAY OF CHAR); (* Copies source into destination, starting at position startIndex. Copying stops when all of source has been copied, or when the last character of the string value in destination has been replaced. *) PROCEDURE Append (source: ARRAY OF CHAR; VAR destination: ARRAY OF CHAR); (* Appends source to destination. *) PROCEDURE Concat (source1, source2: ARRAY OF CHAR; VAR destination: ARRAY OF CHAR); (* Concatenates source2 onto source1 and copy the result into destination. *) (* The following predicates provide for pre-testing of the operation- completion conditions for the procedures above. *) PROCEDURE CanAssignAll (sourceLength: CARDINAL; VAR destination: ARRAY OF CHAR): BOOLEAN; (* Returns TRUE if a number of characters, indicated by sourceLength, will fit into destination, and FALSE otherwise. *) PROCEDURE CanExtractAll (sourceLength, startIndex, numberToExtract: CARDINAL; VAR destination: ARRAY OF CHAR): BOOLEAN; (* Given the length of a string, sourceLength, the startIndex for extraction, and the number of characters to extract, numberToExtract, returns TRUE if, there are numberToExtract characters starting at startIndex and within the sourceLength, and if the capacity of destination is sufficient to hold numberToExtract characters. Otherwise it returns FALSE *) PROCEDURE CanDeleteAll (stringLength, startIndex, numberToDelete: CARDINAL) : BOOLEAN; (* Given the length of a string, stringLength, the startIndex for deletion, and the number of characters to delete, numberToDelete, returns TRUE if, there are numberToDelete characters starting at startIndex and within the stringLength. Otherwise it returns FALSE *) PROCEDURE CanInsertAll (sourceLength, startIndex: CARDINAL; VAR destination: ARRAY OF CHAR): BOOLEAN; (* Given the length of a string to insert, sourceLength, and the startIndex for insertion in the destination, returns TRUE if, there is room in the destination for the insertion. Otherwise it returns FALSE *) PROCEDURE CanReplaceAll (sourceLength, startIndex: CARDINAL; VAR destination: ARRAY OF CHAR): BOOLEAN; (* Given the length of a replacement string, sourceLength, and the startIndex for the replacement in the destination, returns TRUE if, there is room in the string value in. the destination. Otherwise it returns FALSE *) PROCEDURE CanAppendAll (sourceLength: CARDINAL; VAR destination: ARRAY OF CHAR): BOOLEAN; (* Returns TRUE if there is sufficient room in destination to append a string of length sourceLength to the string in destination and FALSE otherwise. *) PROCEDURE CanConcatAll (source1Length, source2Length: CARDINAL; VAR destination: ARRAY OF CHAR): BOOLEAN; (* Returns TRUE if there is sufficient room in destination for a two strings of lengths source1Length and source2Length and FALSE otherwise. *) (* The following type and procedures provide for the comparison of string values, and for the location of substrings within strings. *) TYPE CompareResults = (less, equal, greater); PROCEDURE Compare (stringVal1, stringVal2: ARRAY OF CHAR): CompareResults; (* Returns less, equal or greater according as stringVal1 is lexically less than, equal to, or greater than stringVal2. *) PROCEDURE Equal (stringVal1, stringVal2: ARRAY OF CHAR): BOOLEAN; (* Returns Strings.Compare(stringVal1, stringVal2) = Strings.equal *) PROCEDURE FindNext (pattern, stringToSearch: ARRAY OF CHAR; startIndex: CARDINAL; VAR patternFound: BOOLEAN; VAR posOfPattern: CARDINAL); (* Looks forward for next occurrence of pattern in stringToSearch, starting the search at position startIndex. If startIndex < LENGTH (stringToSearch) and pattern is found, patternFound is returned as TRUE, and posOfPattern contains the start position in stringToSearch of pattern. Otherwise patternFound is returned as FALSE, and posOfPattern is unchanged. *) PROCEDURE FindPrev (pattern, stringToSearch: ARRAY OF CHAR; startIndex: CARDINAL; VAR patternFound: BOOLEAN; VAR posOfPattern: CARDINAL); (* Looks backward for the previous occurrence of pattern in stringToSearch and returns the position of the first character of the pattern if found. The search for the pattern begins at startIndex.If pattern is found, patternFound is returned as TRUE, and posOfPattern contains the start position in stringToSearch of pattern in the range [0..startIndex]. Otherwise patternFound is returned as FALSE, and posOfPattern is unchanged. *) PROCEDURE FindDiff (stringVal1, stringVal2: ARRAY OF CHAR; VAR differenceFound: BOOLEAN; VAR posOfDifference: CARDINAL); (* Compares the string values in stringVal1 and stringVal2 for differences. If the are equal differenceFound is returned as FALSE and TRUE otherwise. If differenceFound is TRUE, posOfDifference is set to the position of the first difference; otherwise posOfDifference is unchanged. *) PROCEDURE Capitalize (VAR stringVar: ARRAY OF CHAR); (* Applies the function CAP to each character of the string value in stringVar. *) END Strings."Strings" provides procedures for the handling of strings, like comparison, search, concatenation etc. Procedures which have result strings use as many space as available in the result parameter, too long result strings are truncated. The user may—if necessary—use test functions to ask whether the result parameter is large enough to keep the whole result.
"Length" calculates the length of a string and is identical to the pervasive function "LENGTH".
"Assign" assigns the first string to the second one.
"Extract" copies a substring starting from position "startIndex" and of length "numberToExtract" from "source" to "destination."
"Delete" deletes a substring starting from position "startIndex" and of length "numberToExtract" from "source"
"Insert" inserts "source" into "destination" starting from position "startIndex".
"Append" appends "source" to "destination".
"Concat" concatenates "source1" and "source2" and assigns the result to "destination".
"Capitalize" changes all lowercase letters to capitals.
"Compare" compares "stringVal1" and "stringVal2" and returns the according result.
"Equal" compares "stringVal1" and "stringVal2" and returns "TRUE" if the strings are equal ("FALSE" otherwise).
"FindNext" searches the next occurrence of "pattern" in "stringVal", starting at position "startIndex". If the pattern is found ("patternFound = TRUE"), the starting position of the pattern is returned in "posOfPattern".
"FindPrev" is like "FindNext", but searches backwards.
"FindDiff" looks for the first difference between "stringVal1" and "stringVal2" ("differenceFound = TRUE") and returns this position in "posOfDifference". If the strings are equal, "differenceFound" returns "FALSE".
The "Can..." procedures test, whether a desired operation can be performed with the given parameters. A result of "TRUE" indicates, that the result string is large enough to keep the entire result.
The following examples are a short overview over usage and functionality of the procedures of this module. All examples use the following declarations:
VAR small: ARRAY [0 .. 4] OF CHAR; large: ARRAY [0 .. 255] OF CHAR; alpha: ARRAY ['A' .. 'E'] OF CHAR; ch: CHAR; found, arediff: BOOLEAN; pos: CARDINAL;
Examples for "Assign": | ||
---|---|---|
call | result | |
ch := "X"; Assign (String1{ch}, small) | small[0] = "X" | small[1] = "" |
Assign ("pq", small) |
small[0] = "p" small[2] = "" | small[1] = "q" |
Assign ("", small) | small[0] = "" | |
Assign ("Hello!", small) |
small[0] = "H" small[2] = "l" small[4] = "o" |
small[1] = "e" small[3] = "l" |
CanAssignAll (6, small) | FALSE | |
Assign ("Go", alpha) |
alpha['A'] = "G" alpha['C'] = "" | alpha['C'] = "o" |
small := "Hello"; large:=""; IF CanAssignAll (LENGTH (small), large) THEN Assign (small, large) END; |
large[0] = "H" large[2] = "l" large[4] = "o" |
large[1] = "e" large[3] = "l" |
Examples for "Extract": | ||
call | result | |
large := "ABCDE"; small := ""; IF CanExtractAll (LENGTH (large), 2, 3, small) THEN Extract (large, 2, 3, small) END; |
small[0] = "C" small[2] = "E" |
small[1] = "D" small[3] = "" |
large := "ABCDE"; small := ""; Extract (large, 2, 3, small) |
small[0] = "C" small[2] = "E" |
small[1] = "D" small[3] = "" |
Examples for "Delete": | ||
call | result | |
small := "ABCDE"; IF CanDeleteAll (LENGTH (small), 2, 2) THEN Delete (small, 2, 2) END; |
small[0] = "A" small[2] = "E" |
small[1] = "B" small[3] = "" |
small := "ABC"; CanDeleteAll (3, 2, 2) | FALSE | |
small := "ABC"; Delete (small, 2, 2) |
small[0] = "A" small[2] = "" | small[1] = "B" |
Examples for "Insert": | ||
call | result | |
small := "ABCD"; CanInsertAll (LENGTH ("XYZ"), 2, small) | FALSE | |
small := "ABCD"; Insert ("XYZ", 2, small) |
small[0] = "A" small[2] = "X" small[4] = "Z" |
small[1] = "B" small[3] = "Y" |
large := "ABC"; IF CanInsertAll (3, 2, large) THEN Insert ("XYZ", 2, large) END; |
large[0] = "A" large[2] = "X" large[4] = "Z" large[6] = "" |
large[1] = "B" large[3] = "Y" large[5] = "C" |
large := "ABCD"; ch := "X"; Insert (String1 {ch}, 2, large) |
large[0] = "A" large[2] = "X" large[4] = "D" |
large[1] = "B" large[3] = "C"; large[5] = "" |
Examples for "Replace": | ||
call | result | |
small := "ABC"; CanReplaceAll (LENGTH ("XY"), 2, small) | FALSE | |
small := "ABC"; Replace ("XY", 2, small) |
small[0] = "A" small[2] = "X" |
small[1] = "B" small[3] = "" |
large := "ABCDEF"; IF CanReplaceAll (3, 2, large) THEN Replace ("XYZ", 2, large) END; |
large[0] = "A" large[2] = "X" large[4] = "Z" large[6] = "" |
large[1] = "B" large[3] = "Y" large[5] = "F" |
Examples for "Append": | ||
call | result | |
small := "pqr"; CanAppendAll (LENGTH ("XYZ"), small) | FALSE | |
small := "pqr"; Append ("XYZ", small) |
small[0] = "p" small[2] = "r" small[4] = "Y" |
small[1] = "q" small[3] = "X" |
small := "pqr"; ch := "s"; Append (String1 {ch}, small) |
small[0] = "p" small[2] = "r" small[4] = "" |
small[1] = "q" small[3] = "s" |
Examples for "Concat": | ||
call | result | |
small := "pqr"; CanConcatAll (4, LENGTH (small), small) | FALSE | |
small := "pqr"; Concat ("WXYZ", small, small) |
small[0] = "W" small[2] = "Y" small[4] = "p" |
small[1] = "X" small[3] = "Z" |
small := "jk";
large := ""; ch := "s"; Concat (String1 {ch}, small, large) |
large[0] = "s" large[2] = "k" |
large[1] = "j" large[3] = "" |
Examples for "Capitalize": | ||
call | result | |
small := "pqr"; Capitalize (small) |
small[0] = "P" small[2] = "R" |
small[1] = "Q" small[3] = "" |
Examples for "Compare": | ||
call | result | |
Compare ("", "") | equal | |
Compare ("", "abc") | less | |
Compare ("abc", "") | greater | |
Compare ("pqr", "pqr") | equal | |
Compare ("pqr", "pqrstuv") | less | |
Compare ("pqrstuv", "pqr") | greater | |
Compare ("abc", "pqr") | less | |
Compare ("pqr", "abc") | greater | |
Compare ("abcdef", "p") | less | |
Compare ("p", "abcdef") | greater | |
Examples for "FindNext": | ||
call | result | |
large := "Hello hello hello"; FindNext ("ll", large, 0, found, pos) |
found = TRUE |
pos = 2 |
large := "Hello hello hello"; FindNext ("ll", large, 0, found, pos) FindNext ("ll", large, pos + 1, found, pos) |
found = TRUE |
pos = 8 |
large := "abcdefghijklmnopqrstuvwxyz"; ch := "x"; FindNext (String1 {ch}, large, 0, found, pos) |
found = TRUE |
pos = 23 |
large := "abcdefghijklmnopqrstuvwxyz"; ch := "x"; FindNext (String1 {ch}, large, 26, found, pos) |
found = FALSE |
pos = not changed |
Examples for "FindPrev": | ||
call | result | |
large := "aabbbcccc"; FindPrev ("cc", large, 200, found, pos) |
found = TRUE |
pos = 7 |
large := "aabbbcccc"; FindPrev ("cc", large, 200, found, pos) FindPrev ("cc", large, pos - 1, found, pos) |
found = TRUE |
pos = 6 |
large := "Maybe this makes sense"; FindPrev ("se", large, 200, found, pos) |
found = TRUE |
pos = 20 |
large := "Maybe this makes sense"; FindPrev ("se", large, 200, found, pos) FindPrev ("se", large, pos - 1, found, pos) |
found = TRUE |
pos = 17 |
Examples for "FindDiff": | ||
call | result | |
FindDiff ("", "", arediff, pos) | arediff = FALSE | pos = not changed |
FindDiff ("abc", "", arediff, pos) | arediff = TRUE | pos = 0 |
FindDiff ("", "abcd", arediff, pos) | arediff = TRUE | pos = 0 |
FindDiff ("pqr", "pqt", arediff, pos) | arediff = TRUE | pos = 2 |
FindDiff ("pqr", "pqrstu", arediff, pos) | arediff = TRUE | pos = 3 |
FindDiff ("pqrstu", "pqr", arediff, pos) | arediff = TRUE | pos = 3 |
DEFINITION MODULE ConvTypes; (* Common types used in the string conversion modules *) TYPE ConvResults = (* Values of this type are used to express the format of a string *) ( strAllRight, (* the string format is correct for the corresponding conversion *) strOutOfRange, (* the string is well-formed but the value cannot be represented *) strWrongFormat, (* the string is in the wrong format for the conversion *) strEmpty (* the given string is empty *) ); ScanClass = (* Values of this type are used to classify characters input to finite state scanners *) ( padding, (* a leading or padding character at this point in the scan - ignore it *) valid, (* a valid character at this point in the scan - accept it *) invalid, (* an invalid character at this point in the scan - reject it *) terminator (* a terminating character at this point in the scan (not part of token) *) ); ScanState = (* The type of lexical scanning control procedures *) PROCEDURE(CHAR, VAR ScanClass, VAR ScanState); END ConvTypes."ConvTypes" contains all data types used in the conversion modules.
"ConvResults" identities all errors possible during conversion ("all right", "out of range", "wrong format", "empty string").
"ScanClass" and "ScanResult" are used to implement a finite state machine to read a string with a given format character by character. "ScanClass" identifies the class of a character. "ScanState" is the procedure type for the action procedure representing the state of the machine.
DEFINITION MODULE WholeConv; IMPORT ConvTypes; TYPE ConvResults = ConvTypes.ConvResults; (* strAllRight, strOutOfRange, strWrongFormat, strEmpty *) PROCEDURE IsWholeConvException (): BOOLEAN; (* Returns TRUE iff an exception has been raised by the module WholeConv *) PROCEDURE ScanInt (inputCh: CHAR; VAR chClass: ConvTypes.ScanClass; VAR nextState: ConvTypes.ScanState); (* Represents the start state of a finite state scanner for signed whole numbers - assigns class of inputCh to chClass and a procedure representing the next state to nextState. *) PROCEDURE FormatInt (str: ARRAY OF CHAR): ConvResults; (* Returns the format of the string value for conversion to INTEGER *) PROCEDURE ValueInt (str: ARRAY OF CHAR): INTEGER; (* If str is well-formed, returns the value corresponding to the signed whole number string value str; otherwise raises an exception. *) PROCEDURE LengthInt (int: INTEGER): CARDINAL; (* Returns the number of characters in the string representation of int *) PROCEDURE ScanCard (inputCh: CHAR; VAR chClass: ConvTypes.ScanClass; VAR nextState: ConvTypes.ScanState); (* Represents the start state of a finite state scanner for unsigned whole numbers - assigns class of inputCh to chClass and a procedure representing the next state to nextState. *) PROCEDURE FormatCard (str: ARRAY OF CHAR): ConvResults; (* Returns the format of the string value for conversion to CARDINAL. *) PROCEDURE ValueCard (str: ARRAY OF CHAR): CARDINAL; (* If str is well-formed, returns the value corresponding to the unsigned whole number string value str; otherwise raises an exception. *) PROCEDURE LengthCard (card: CARDINAL): CARDINAL; (* Returns the number of characters in the string representation of card. *) END WholeConv."WholeConv" is the low level module for conversion between strings and whole numbers.
"ScanInt is the start procedure of a finite state machine to scan values of type "INTEGER" given as string. "inputCh" is the next character to be processed. The type of this character is returned in "chClass". The procedure that corresponds to the state of the scanner is stored in "nextState".
The following example demonstrates the use of the scanner. "GetCh" and "StoreCh" identify two procedures to read characters from the input stream and to store characters for further processing.
VAR scan: ConvTypes. ScanState; class: ConvTypes. ScanClass; ch: CHAR; scan := WholeConv. ScanInt; REPEAT GetCh (ch); scan (ch, class, scan); IF class = valid THEN StoreCh (ch); END(*IF*); UNTIL (class = invalid) OR (class = terminator ); IF class = invalid THEN (* report error *) ELSE (* process input *) END(*IF*);"FormatInt" tests, whether a string is a correct representation of a whole number.
"ValueInt" returns the "INTEGER" value of a input string or raises an exception.
"LengthInt" returns the number of places needed to represent "int" as a string.
The procedures "ScanCard", "FormatCard", "ValueCard", and "LengthCard" are similar to the procedures describes above, but take values of type "CARDINAL" as parameters.
DEFINITION MODULE RealConv; IMPORT ConvTypes; TYPE ConvResults = ConvTypes.ConvResults; (* strAllRight, strOutOfRange, strWrongFormat, strEmpty *) PROCEDURE IsRConvException (): BOOLEAN; (* Returns TRUE iff an exception has been raised by the module RealConv *) PROCEDURE ScanReal (inputCh: CHAR; VAR chClass: ConvTypes.ScanClass; VAR nextState: ConvTypes.ScanState); (* Represents the start state of a finite state scanner for real numbers - assigns class of inputCh to chClass and a procedure representing the next state to nextState. *) PROCEDURE FormatReal (str: ARRAY OF CHAR): ConvResults; (* Returns the format of the string value for conversion to REAL *) PROCEDURE ValueReal (str: ARRAY OF CHAR): REAL; (* If str is well-formed, returns the value corresponding to the real number string value str; otherwise raises an exception. *) PROCEDURE LengthFloatReal (real: REAL; sigFigs: CARDINAL): CARDINAL; (* Returns the number of characters in the floating-point string representation of real with sigFigs significant figures. *) PROCEDURE LengthEngReal (real: REAL; sigFigs: CARDINAL): CARDINAL; (* Returns the number of characters in the floating-point engineering string representation of real with sigFigs significant figures. *) PROCEDURE LengthFixedReal (real: REAL; place: INTEGER): CARDINAL; (* Returns the number of characters in the fixed-point string representation of real rounded to the given place relative to the decimal point. *) END RealConv."RealConv " is the low level module for conversion between strings and real numbers.
The procedures "ScanReal", "FormatReal", and "ValueReal" correspond in functionality and usage with the procedures "ScanInt", "FormatInt", and "ValueInt" of module "WholeConv" (cf. chapter 1.4.3).
"LengthFloat" calculates the number of characters necessary for the representation of "real" in scientific notation with "sigFigs" significant figures.
"LengthEng" is analogous to "LengthFloat", but with an exponent set to a multiple of three.
"LengthFixedReal" calculates the number of characters necessary for the representation of "real" in fixed point notation, if the number is rounded to "place" digits. "place > 0" indicates places to the right of the decimal point, "place < 0" means rounding to "ABS (place)" places left to the decimal point. Examples of this format are part of chapter 1.3.9 (module "RealIO").
DEFINITION MODULE LongConv; IMPORT ConvTypes; TYPE ConvResults = ConvTypes.ConvResults; (* strAllRight, strOutOfRange, strWrongFormat, strEmpty *) PROCEDURE IsRConvException (): BOOLEAN; (* Returns TRUE iff an exception has been raised by the module LongConv *) PROCEDURE ScanReal (inputCh: CHAR; VAR chClass: ConvTypes.ScanClass; VAR nextState: ConvTypes.ScanState); (* Represents the start state of a finite state scanner for real numbers - assigns class of inputCh to chClass and a procedure representing the next state to nextState. *) PROCEDURE FormatReal (str: ARRAY OF CHAR): ConvResults; (* Returns the format of the string value for conversion to LONGREAL *) PROCEDURE ValueReal (str: ARRAY OF CHAR): LONGREAL; (* If str is well-formed, returns the value corresponding to the real number string value str; otherwise raises an exception. *) PROCEDURE LengthFloatReal (real: LONGREAL; sigFigs: CARDINAL): CARDINAL; (* Returns the number of characters in the floating-point string representation of real with sigFigs significant figures. *) PROCEDURE LengthEngReal (real: LONGREAL; sigFigs: CARDINAL): CARDINAL; (* Returns the number of characters in the floating-point engineering string representation of real with sigFigs significant figures. *) PROCEDURE LengthFixedReal (real: LONGREAL; place: INTEGER): CARDINAL; (* Returns the number of characters in the fixed-point string representation of real rounded to the given place relative to the decimal point. *) END LongConv."LongConv" corresponds to "RealConv" for real numbers of type "LONGREAL".
DEFINITION MODULE WholeStr; (* Whole-number/string conversions *) IMPORT ConvTypes; TYPE ConvResults = ConvTypes.ConvResults; (* strAllRight, strOutOfRange, strWrongFormat, strEmpty *) (* the string form of a signed whole number is ["+" | "-"], decimal digit, {decimal digit} *) PROCEDURE StrToInt (str: ARRAY OF CHAR; VAR int: INTEGER; VAR res: ConvResults); (* Ignores any leading spaces in str. If the subsequent characters in str are in the format of a signed whole number, assigns a corresponding value to int. Assigns a value indicating the format of str to res. *) PROCEDURE IntToStr (int: INTEGER; VAR str: ARRAY OF CHAR); (* Converts the value of int to string form and copies the possibly truncated result to str. *) (* the string form of an unsigned whole number is decimal digit, {decimal digit} *) PROCEDURE StrToCard (str: ARRAY OF CHAR; VAR card: CARDINAL; VAR res: ConvResults); (* Ignores any leading spaces in str. If the subsequent characters in str are in the format of an unsigned whole number, assigns a corresponding value to card. Assigns a value indicating the format of str to res. *) PROCEDURE CardToStr (card: CARDINAL; VAR str: ARRAY OF CHAR); (* Converts the value of card to string form and copies the possibly truncated result to str. *) END WholeStr."WholeStr" provides simple procedures for conversions between strings and whole numbers.
"StrToInt" converts a string into a value of type "INTEGER". "res" indicates, whether the format of the string is correct.
"IntToStr" converts the value "int" into a string. If the variable "str" is too small to store the result, the string is truncated at the right.
"StrToCard" converts a string into a value of type "CARDINAL". "res" indicates, whether the format of the string is correct.
"CardToStr" converts the value "card" into a string. If the variable "str" is too small to store the result, the string is truncated at the right.
DEFINITION MODULE RealStr; (* REAL/string conversions *) IMPORT ConvTypes; TYPE ConvResults = ConvTypes.ConvResults; (* strAllRight, strOutOfRange, strWrongFormat, strEmpty *) (* the string form of a signed fixed-point real number is ["+" | "-"], decimal digit, {decimal digit}, [".", {decimal digit}] *) (* the string form of a signed floating-point real number is signed fixed-point real number, "E", ["+" | "-"], decimal digit, {decimal digit} *) PROCEDURE StrToReal (str: ARRAY OF CHAR; VAR real: REAL; VAR res: ConvResults); (* Ignores any leading spaces in str. If the subsequent characters in str are in the format of a signed real number, assigns a corresponding value to real. Assigns a value indicating the format of str to res. *) PROCEDURE RealToFloat (real: REAL; sigFigs: CARDINAL; VAR str: ARRAY OF CHAR); (* Converts the value of real to floating-point string form, with sigFigs significant figures, and copies the possibly truncated result to str. *) PROCEDURE RealToEng (real: REAL; sigFigs: CARDINAL; VAR str: ARRAY OF CHAR); (* Converts the value of real to floating-point string form, with sigFigs significant figures, and copies the possibly truncated result to str. The number is scaled with one to three digits in the whole number part and with an exponent that is a multiple of three. *) PROCEDURE RealToFixed (real: REAL; place: INTEGER; VAR str: ARRAY OF CHAR); (* Converts the value of real to fixed-point string form, rounded to the given place relative to the decimal point, and copies the possibly truncated result to str. *) PROCEDURE RealToStr (real: REAL; VAR str: ARRAY OF CHAR); (* Converts the value of real as RealToFixed if the sign and magnitude can be shown within the capacity of str, or otherwise as RealToFloat, and copies the possibly truncated result to str. The number of places or significant digits are implementation-defined. *) END RealStr."RealStr" provides simple procedures for conversion between strings and real numbers.
"StrToReal" converts a string into a value of type "REAL". "res" indicates, whether the format of the string is correct.
"RealToFloat" converts the value "real" into a string in scientific notation with "sigFigs" significant numbers. If the variable "str" is too small to store the result, the string is truncated at the right.
"RealToEng" converts the value "real" into a string in scientific notation with "sigFigs" significant numbers. The exponent is adjusted to a multiple of three. If the variable "str" is too small to store the result, the string is truncated at the right.
"RealToFixed" converts the value "real" into a string in fixed point notation rounded to "places" digits. "place > 0" indicates places to the right of the decimal point, "place < 0" means rounding to "ABS (place)" places left to the decimal point. If the variable "str" is too small to store the result, the string is truncated at the right.
DEFINITION MODULE LongStr; (* LONGREAL/string conversions *) IMPORT ConvTypes; TYPE ConvResults = ConvTypes.ConvResults; (* strAllRight, strOutOfRange, strWrongFormat, strEmpty *) (* the string form of a signed fixed-point real number is ["+" | "-"], decimal digit, {decimal digit}, [".", {decimal digit}] *) (* the string form of a signed floating-point real number is signed fixed-point real number, "E", ["+" | "-"], decimal digit, {decimal digit} *) PROCEDURE StrToReal (str: ARRAY OF CHAR; VAR real: LONGREAL; VAR res: ConvResults); (* Ignores any leading spaces in str. If the subsequent characters in str are in the format of a signed real number, assigns a corresponding value to real. Assigns a value indicating the format of str to res. *) PROCEDURE RealToFloat (real: LONGREAL; sigFigs: CARDINAL; VAR str: ARRAY OF CHAR); (* Converts the value of real to floating-point string form, with sigFigs significant figures, and copies the possibly truncated result to str. *) PROCEDURE RealToEng (real: LONGREAL; sigFigs: CARDINAL; VAR str: ARRAY OF CHAR); (* Converts the value of real to floating-point string form, with sigFigs significant figures, and copies the possibly truncated result to str. The number is scaled with one to three digits in the whole number part and with an exponent that is a multiple of three. *) PROCEDURE RealToFixed (real: LONGREAL; place: INTEGER; VAR str: ARRAY OF CHAR); (* Converts the value of real to fixed-point string form, rounded to the given place relative to the decimal point, and copies the possibly truncated result to str. *) PROCEDURE RealToStr (real: LONGREAL; VAR str: ARRAY OF CHAR); (* Converts the value of real as RealToFixed if the sign and magnitude can be shown within the capacity of str, or otherwise as RealToFloat, and copies the possibly truncated result to str. The number of places or significant digits depend on the capacity of str. *) END LongStr."LongStr" corresponds to "RealStr" for real numbers of type "LONGREAL".
DEFINITION MODULE Processes; (* This module allows concurrent algorithms to be expressed using processes. A process is a unit of a program that has the potential to run in parallel with other processes. *) IMPORT SYSTEM; TYPE ProcessId; (* Used to identify processes *) Parameter = SYSTEM.ADDRESS; (* Used to pass data between processes *) Body = PROC; (* Used as the type of a process body *) Urgency = INTEGER; (* Used by the internal scheduler *) Sources = CARDINAL; (* Used to identify event sources *) ProcExceptions = (* Exceptions raised by this module *) (procsNoException, notProcsException, passiveProgram, processError); (* The following procedures create processes and switch control between them. *) PROCEDURE Create (procBody: Body; extraSpace: CARDINAL; procUrg: Urgency; procParams: Parameter; VAR procId: ProcessId); (* Creates a new process with procBody as its body, and with urgency and parameters given by procUrg and procParams. At least as much workspace (in units of SYSTEM.LOC) as is specified by extraSpace is allocated to the process. An identity for the new process is returned in procId. The process is created in the passive state; it will not run until activated. *) PROCEDURE Start (procBody: Body; extraSpace: CARDINAL; procUrg: Urgency; procParams: Parameter; VAR procId: ProcessId); (* Creates a new process, with parameters as for Create. The process is created in the ready state; it is eligible to run immediately. *) PROCEDURE StopMe (); (* Terminates the calling process, and reclaims the workspace allocated when it was first created. The process must not be associated with a source of events. *) PROCEDURE SuspendMe (); (* Causes the calling process to enter the passive state. The procedure only returns when the calling process is again activated by another process. *) PROCEDURE Activate (procId: ProcessId); (* Causes the process identified by procId to enter the ready state, and thus to become eligible to run again. This process must not be currently be eligible to run. *) PROCEDURE SuspendMeAndActivate (procId: ProcessId); (* Executes an atomic sequence of SuspendMe() and Activate(procId). *) PROCEDURE Switch (procId: ProcessId; VAR info: Parameter ); (* Causes the calling process to enter the passive state; the process identified by procId becomes the currently executing process. info is used to pass parameter information from the calling to the activated process. On return, info will contain information from the process that chooses to switch back to this one (or will be NIL if Activate or SuspendMeAndActivate are used instead of Switch). *) PROCEDURE Wait (); (* Causes the calling process to enter the waiting state. The procedure will return when the calling process is activated by another process, or when one of its associated eventSources has generated an event. *) (* The following procedures allow the association of processes with sources of external events. *) PROCEDURE Attach (eventSource: Sources); (* Associates the specified eventSource with the calling process. *) PROCEDURE Detach (eventSource: Sources); (* Dissociates the specified eventSource from the program. *) PROCEDURE IsAttached (eventSource: Sources): BOOLEAN; (* Returns TRUE if and only if the specified eventSource is currently associated with one of the processes of the program. *) PROCEDURE Handler (eventSource: Sources): ProcessId; (* Returns the identity of the process, if any, that is associated with the specified eventSource. *) (* The following procedures allow processes to obtain their identity, parameters, and urgency. *) PROCEDURE Me (): ProcessId; (* Returns the identity of the calling process (as assigned when the process was first created). *) PROCEDURE MyParam (): Parameter; (* Returns the value specified as procParams when the calling process was created. *) PROCEDURE UrgencyOf (procId: ProcessId): Urgency; (* Returns the urgency established when the process identified by procId was first created. *) (* The following procedure provides facilities for exception handlers. *) PROCEDURE ProcessesException (): ProcessesExceptions; (* If the current coroutine is in the exceptional execution state because of the raising of a language exception, returns the corresponding enumeration value, and otherwise raises an exception. *) PROCEDURE IsProcessesException (): BOOLEAN; (* Returns TRUE if the current coroutine is in the exceptional execution state because of the raising of an exception in a routine from this module; otherwise returns FALSE. *) END Processes.This module is based on the Posix threads implemented in the Darwin kernel of MacOS X and reflects the features provided for by these threads.
"Create" creates a new suspended thread with the given procedure body as start routine. The stack space given in "extraSpace" is added to the minimum size a thread needs to execute.
"Start" same as Create but the thread is immediately activated.
"StopMe" terminates the actual thread; if this is the last remaining thread, program termination is invoked.
"SuspendMe" suspends the actual thread.
"Activate" activates the given thread.
"SuspendMeAndActivate" suspends the actual thread and activates the given thread.
"Switch" same as SuspendMeAndActivate but allows to pass a paramter address between the threads.
"Wait" same as SuspendMe, as no event sources are defined.
"Attach" always raises an exception, as no event sources are defined.
"Detach" always raises an exception, as no event sources are defined.
"IsAttached" always returns FALSE, as no event sources are defined
"Handler" always returns NIL, as no event sources are defined
"Me" returns the identity of the calling thread.
"MyParam" returns the parameter given when the thread was created.
"UrgencyOf" returns the urgency given when the thread was created.
"ProcessesException" returns the current exception given that is was raised by this module; otherwise raises an exception.
"IsProcessesException" returns TRUE iff the current exception was raised by this module.
DEFINITION MODULE Semaphores; (* This module provides mutual exclusion facilities for use by processes. *) TYPE SEMAPHORE; PROCEDURE Create (VAR s: SEMAPHORE; initialCount: CARDINAL ); (* Creates and returns s as the identity of a new semaphore that has its associated count initialized to initialCount, and has no processes yet waiting on it. *) PROCEDURE Destroy (VAR s: SEMAPHORE); (* Recovers the resources used to implement the semaphore s, provided that no process is waiting for s to become free. *) PROCEDURE Claim (s: SEMAPHORE); (* If the count associated with the semaphore s is non-zero, decrements this count and allows the calling process to continue; otherwise suspends the calling process until s is released. *) PROCEDURE Release (s: SEMAPHORE); (* If there are any processes waiting on the semaphore s, allows one of them to enter the ready state; otherwise increments the count associated with s. *) PROCEDURE CondClaim (s: SEMAPHORE): BOOLEAN; (* If the call Claim(s) s would cause the calling process to be suspended, the count associated with s is not changed, and the procedure returns FALSE. Otherwise the associated count is decremented, and the procedure returns TRUE. *) END Semaphores.The module "Semaphores" is implemented using the data structures "mutex" and "condition" in conjungtion with the Posix threads also used in module "Proceses".
DEFINITION MODULE SysClock; (* Facilities for accessing a system clock that records the date and time of day. *) CONST maxSecondParts = 0; 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; PROCEDURE CanGetClock (): BOOLEAN; (* Tests if a system clock can be read *) PROCEDURE CanSetClock (): BOOLEAN; (* Tests if a system clock can be set *) PROCEDURE IsValidDateTime (userData: DateTime): BOOLEAN; (* Tests if the value of userData represents a valid date and time *) PROCEDURE GetClock (VAR userData: DateTime); (* If possible, assigns system date and time of day to userData *) PROCEDURE SetClock (userData: DateTime); (* If possible, sets the system clock to the values of userData *) END SysClock.The module "SysClock" provides procedures to read and set the system clock. The constant "maxSecondParts" indicates the number of fractions a second is split into by the system clock. The system clock of the Apple Macintosh uses whole seconds, thus "maxSecondParts = 0".
"CanGetClock" indicates whether the system clock can be read. This result is always "TRUE" for the Mac OS.
"CanSetClock" indicates whether the system clock can be set. This result is always "FALSE" for the Mac OS.
"IsValidDateTime" checks, whether "userData" contains a correct date and time.
"GetClock" returns the actual time of the system clock.
"SetClock" sets the system clock to the time given in "userData".
table of contents (library) | start page | chapter 2 (library) |