Super Prev Next

ISO Modula-2 standard libraries

It is our aim to provide the full set of ISO Modula-2 libraries. However, some modules are unimplemented on a particular hardware/sortware platform. System libraries are described in the XDS Modula-2 Chapter of the XDS User’s Guide.

This chapter does not contain a complete reference. A brief description and some samples are provided for each group of modules. For more information, refer to the ISO Modula-2 Library Reference.


Super Prev Next

Input/output library

The IO library allows one to read and write the data streams over one or more channels. Channels are connected to the source of input data, or to destination of output data, known as devices. A set of devices can be extended.

A group of modules is provided to operate on the default input and output channel (Reading and writing via default channels). Another group of modules provide facilities to operate on channels specified explicitly by a parameter (Reading and writing data). The device modules provide facilities to get a channel connected to a source (Device modules). The primitive device-independent operations are provided by the module IOChan; the module IOLink allows specialized device module to be implemented (See Low-level IO modules).


Super Prev Next

Reading and writing via default channels

The following modules provide procedures that operate via default input and output channels and do not take a parameter which identifies a channel:

IOConsts Types and constants for IO modules
SLongIO LONGREAL numbers IO operations
SRawIO Raw IO operations (no conversion or interpretation)
SRealIO REAL numbers IO operations
SResultIO Read results for the default input channel
STextIO Character and string types IO operations
SWholeIO Whole numbers IO operations

The module STextIO resembles the well-known InOut library. The Hello, World program is implemented in the following example:

MODULE Hello;

IMPORT  STextIO;

BEGIN
  STextIO.WriteString('Hello, World!');
  STextIO.WriteLn;
END Hello.

The modules SWholeIO, SRealIO, SLongIO provides facilities for the input and output of whole and real numbers in a decimal form using text operations on a channel.

PROCEDURE Print(stage: CARDINAL; val: REAL);
BEGIN
  STextIO.WriteString("On stage");
  SWholeIO.WriteCard(stage,0);
  STextIO.WriteString(" the value is equal to ");
  SRealIO.WriteReal(val,15);
  STextIO.WriteLn;
END Print;

The module SIOResult allows one to determine whether the last input operation from a default input channel succeed. Text operations produce or consume data streams as a sequence of characters and line marks. The text input procedures (such as ReadString never remove a line mark from the input stream. The procedure SkipLine should be used to pass a line mark.

The Copy procedure reads strings from the input channel and copies them to the output channel.

PROCEDURE Copy;
  VAR s: ARRAY [0..63] OF CHAR;
BEGIN
  LOOP
    STextIO.ReadString(s);
    CASE SIOResult.ReadResult() OF
     |SIOResult.allRight:
        STextIO.WriteString(s);
     |SIOResult.endOfLine:
        STextIO.SkipLine;
        STextIO.WriteLn;
     |SIOResult.endOfInput:
        EXIT
    END;
  END;
END Copy;

No procedure is provided to get the result of a ‘write’ operation. Device errors are reported by raising an exception (See module IOChan).


Super Prev Next

Reading and writing data

For all modules in this group a channel is specified by an actual parameter of the type IOChan.ChanId.

IOResult Read results for specified channels
LongIO LONGREAL numbers IO operations
RawIO Raw IO operations (no conversion or interpretation)
RealIO REAL numbers IO operations
TextIO Character and string types IO operations
WholeIO Whole numbers IO operations

The following procedure copies an input channel to an output channel byte by byte:

PROCEDURE CopyChars(in,out: IOChan.ChanId);
  VAR ch: CHAR;
BEGIN
  LOOP
    TextIO.ReadChar(in,ch);
    CASE IOResult.ReadResult(in) OF
     |IOResult.allRight:
        TextIO.WriteChar(out,ch);
     |IOResult.endOfLine:
        TextIO.SkipLine(in);
        TextIO.WriteLn(out);
     |IOResult.endOfInput:
        EXIT
    END;
  END;
END CopyChars;


Super Prev Next

Device modules

The device modules allows to get a channel connected to a stream, a file, program arguments and to default channels.

ChanConsts Common types and values for channel open
  requests and results
ProgramArgs Access to program arguments
RndFile Random access files
SeqFile Rewindable sequential files
StdChans Access to standard and default channels
StreamFile Independent sequential data streams

In the following example a channel connected to a rewindable file is opened:

MODULE Example;

IMPORT  SeqFile, STextIO, TextIO;

CONST flags = SeqFile.text + SeqFile.old;

VAR
  cid: SeqFile.ChanId;
  res: SeqFile.OpenResults;
  i  : CARDINAL;

BEGIN
  SeqFile.OpenWrite(cid,"example.dat",flags,res);
  IF res = SeqFile.opened THEN
    FOR i:=0 TO 9 DO
      TextIO.WriteString(cid,"Hello");
      TextIO.WriteLn(cid);
    END;
    SeqFile.Close(cid);
  ELSE
    STextIO.WriteString("Open error");
    STextIO.WriteLn;
  END;
END Example.

The module StdChans allows one to get channels already open to sources and destinations of standard input, standard output and standard error output. Default channels initially corresponds to the standard channels, but their values may be changed to redirect input or output.

PROCEDURE RedirectOutput(cid: StdChans.ChanId);
BEGIN
(* writing to the current default channel: *)
  STextIO.WriteString("Redirecting output...");
  STextIO.WriteLn;
(* redirecting output: *)
  StdChans.SetOutChan(cid);
END RedirectOutput;

After the call of RedirectOutput(cid) all subsequent output via modules STextIO, SWholeIO, etc will be written to the channel cid. To restore output call

  StdChans.SetOutChan(StdChans.StdOutChan());

The module ProgramArgs provides a channel to access program’s arguments. The following program prints all its arguments.

MODULE Args;

IMPORT ProgramArgs, TextIO, STextIO;

VAR
  str: ARRAY [0..255] OF CHAR;
  cid: ProgramArgs.ChanId;

BEGIN
  cid:=ProgramArgs.ArgChan();
  WHILE ProgramArgs.IsArgPresent() DO
    TextIO.ReadToken(cid,str);
    (* Note: read result test is omitted *)
    STextIO.WriteString(str); STextIO.WriteLn;
  END;
END Args.


Super Prev Next

Low-level IO modules

Two low-level modules are described in this section. The module IOChan defines the type ChanId that is used to identify channels and provides a set of procedures forming the channel’s interface in a device-independent manner.

The module IOLink provides facilities that allow one to define new device modules. Let us implement an encryption channel, i.e. a channel that encrypts all information that is written to it. To make the encryption device-independent we need a channel for input/output operations.

In the following example a sketch of the encryption device module is shown.

DEFINITION MODULE EncryptChan;

IMPORT IOChan, ChanConsts;

TYPE
  ChanId = IOChan.ChanId;
  OpenResults = ChanConsts.OpenResults;

PROCEDURE Connect(VAR cid: ChanId;
                       io: ChanId;
                  VAR res: OpenResults);
(* Attempts to open an encryption channel. All I/O
   operations will be made through "io" channel.
*)

PROCEDURE Close(VAR cid: ChanId);
(* Closes the channel. *)

END EncryptChan.

Values of the type DeviceId are used to identify device modules. By calling the procedure DeviceTablePtrValue, a device module can obtain a pointer to a device table for the channel. Each channel has it own copy of a device table. A device table contains a field in which the device module can store private data. In our example, the io channel will be stored in this field. The device table also serves as a method table (or virtual function table) in object-oriented languages. It contains the procedure variables for each device procedure. All fields are initialized by the call of MakeChan procedure. A device module has to assign its own device procedures to the fields of a device table. See the Connect procedure below.

IMPLEMENTATION MODULE EncryptChan;

IMPORT IOChan, IOLink, ChanConsts, SYSTEM;

(* "did" is used to identify the channel's kind: *)
VAR did: IOLink.DeviceId;

PROCEDURE EncryptChar(from: SYSTEM.ADDRESS;
                         i: CARDINAL;
                    VAR ch: CHAR);
BEGIN
  ch:='a'; (* very simple encryption :-) *)
END EncryptChar;

PROCEDURE TextWrite(x: IOLink.DeviceTablePtr;
                 from: SYSTEM.ADDRESS;
                  len: CARDINAL);
  VAR i: CARDINAL;
     ch: CHAR;
    cid: IOChan.ChanId;
BEGIN
  (* get the channel id *)
  cid:=SYSTEM.CAST(IOChan.ChanId,x^.cd);
  FOR i:=0 TO len-1 DO
    (* encrypt i-th character *)
    EncryptChar(from,i,ch);
    (* write an encrypted character *)
    IOChan.TextWrite(cid,SYSTEM.ADR(ch),1);
  END;
END TextWrite;

PROCEDURE Connect(VAR cid: ChanId;
                       io: ChanId;
                  VAR res: OpenResults);
  VAR x: IOLink.DeviceTablePtr;
BEGIN
  IOLink.MakeChan(did,cid);
  IF cid = IOChan.InvalidChan() THEN
    res:=ChanConsts.outOfChans
  ELSE
    (* get a pointer to the device table *)
    x:=IOLink.DeviceTablePtrValue(cid,did,
                       IOChan.notAvailable,"");
    (* store the channel id *)
    x^.cd:=SYSTEM.CAST(SYSTEM.ADDRESS,io);
    x^.doTextWrite:=TextWrite;
    (* ... *)
  END;
END Connect;

PROCEDURE Close(VAR cid: ChanId);
BEGIN
  IOLink.UnMakeChan(did,cid);
END Close;

BEGIN
  IOLink.AllocateDeviceId(did);
END EncryptChan.

The module EncryptChan can be used as any standard device module.


Super Prev Next

String conversions

The string conversion library admits the conversion of the values of numeric data types to and from the character string representation. It contains the following modules:

ConvTypes Common types used in the string conversion modules
LongConv Low-level LONGREAL/string conversions
LongStr LONGREAL/string conversions
RealConv Low-level REAL/string conversions
RealStr REAL/string conversions
WholeConv Low-level whole number/string conversions
WholeStr Whole number/string conversions

The module ConvTypes defines the enumeration type ConvResults. It also defines the types ScanClass and ScanState to use in the low-level conversion modules.

The low-level conversion modules allow to control lexical scanning of character sequences. For example, the WholeConv module implements procedures ScanInt and ScanCard representing the start state for a finite state scanner for signed and unsigned whole numbers. In the following example the procedure ScanInt is used to locate a position of the first character in a string which is not a part of an integer.

PROCEDURE SkipInt(str: ARRAY OF CHAR;
              VAR pos: CARDINAL);
  VAR len: CARDINAL;
    state: ConvTypes.ConvState;
    class: ConvTypes.ConvClass;
BEGIN
  pos:=0; len:=LENGTH(str);
  state:=WholeConv.ScanInt;
  WHILE pos < len DO
    state(str[pos],class,state);
    IF   (class = WholeConv.invalid)
      OR (class = WholeConv.terminator)
    THEN
      RETURN
    END;
    INC(pos);
  END;
END SkipInt;


Super Prev Next

Mathematical libraries

The following modules constitute a mathematical library:

ComplexMath COMPLEX mathematical functions
LongComplexMath LONGCOMPLEX mathematical functions
LongMath LONGREAL mathematical functions
RealMath REAL mathematical functions


Super Prev Next

Processes and Semaphores

The following modules allows concurrent algorithms to be expressed using processes:

Processes Provides process creation and manipulation facilities.
Semaphores Provides mutual exclusion facilities for use by processes.

Super Prev Next

Example

MODULE Test;

IMPORT Processes, Semaphores, STextIO;

VAR
  sig : Semaphores.SEMAPHORE;
  prs : Processes.ProcessId;
  main: Processes.ProcessId;

PROCEDURE Proc;
BEGIN
  STextIO.WriteString('Proc 1'); STextIO.WriteLn;
  Semaphores.Claim(sig); (* suspend until released *)
  STextIO.WriteString('Proc 2'); STextIO.WriteLn;
  Processes.StopMe;
END Proc;

BEGIN
  STextIO.WriteString('Main 1'); STextIO.WriteLn;
  Semaphores.Create(sig,0);
  main:=Processes.Me();
  Processes.Start(Proc,40000,Processes.UrgencyOf(main)+1,NIL,prs);
  STextIO.WriteString('Main 2'); STextIO.WriteLn;
  Semaphores.Release(sig);
  STextIO.WriteString('Main 3'); STextIO.WriteLn;
  Processes.StopMe;
END Test.


Super Prev Next

Other libraries

In this section we list the ISO modules that do not belong to any of the above groups:

CharClass provides predicates to test a value of a character type
Storage Facilities for allocating and deallocating storage
Strings Facilities for string manipulation
SysClock Access to a system clock