[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

makeinfo texinfo-format-buffer

1. Using GNU Modula-2

This document contains the user and design issues relevant to the Modula-2 front end to gcc. Throughout this document the GNU Modula-2 front end is often referred to as `gm2-0.68' or `gm2' for short. This corresponds to GCC version 4.1.2 and GNU Modula-2 version 0.68.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.1 What is GNU Modula-2

GNU Modula-2 is a front end http://gcc.gnu.org/frontends.html for GCC. GCC is a retargetable C compiler which has been ported to a large number of architectures and operating systems. GNU Modula-2 utilizes the back end of GCC and replaces the C language front end with a Modula-2 front end. Consequently GNU Modula-2 has been built on i[3456]86 GNU/Linux, i[3456]86 BSD, Opteron LP64 GNU/Linux and sparc GNU/Linux systems. It has also been built as a cross compiler for MinGW and StrongARM GNU/Linux.

The GNU Modula-2 compiler is based on the language as defined in 'Programming in Modula-2' 2nd Edition, Springer Verlag, 1982, 1983 by Niklaus Wirth (PIM2), 'Programming in Modula-2', 3rd Corrected Edition, Springer Verlag, 1985 (PIM3) and 'Programming in Modula-2', 4th Edition, Springer Verlag, 1988 (PIM4) http://freepages.modula2.org/report4/modula-2.html. It also includes ISO M2 features and GNU Modula-2 extensions. Currently GNU Modula-2 (0.68) implements all PIM dialects of the language, eventually GNU Modula-2 will be fully compliant with ISO Modula-2.

There are currently three sets of libraries. The 'Programming in Modula-2' libraries, the 'University of ULM libraries' and the ISO libraries. The ISO libraries are still being written, however all definition modules for the three library sets are contained within this document.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2 Why use GNU Modula-2

This section is not designed to generate a language war, but rather map out some of the advantages of using GNU Modula-2 rather than translate Modula-2 sources into another language.

It is expected that the primary purpose of GNU Modula-2 will be to compile legacy code. Currently there are only a few commercial Modula-2 compilers being actively maintained. Code which was written ten or fifteen years ago may still be compiled by older commercial (possibly unmaintained) compilers. While the 32 bit x86 remains these compilers presumably can be run in compatibility mode (some compilers only produced 16 bit code). Time is running out as the computing industry is switching to 64 microprocessors. While x86 emulation or 16 bit backwards compatibility is always possible it has some serious drawbacks. In order for the older source to run natively the source code will either have to be translated into another high level language or alternatively a Modula-2 compiler which can target these new generation of microprocessors will have to be acquired. GNU Modula-2 builds and passes all its regression tests on Debian Pure 64 (LP64 architecture), 64 bit Solaris, 32 bit x86 GNU/Linux (Suse, Debian, stable and unstable) and 32 bit x86 FreeBSD.

GNU Modula-2 also has the advantage of being closely tied to GCC. Not only does this produce excellent code and excellent architectural and operating system coverage but it also utilises many of the GCC features. For example GNU Modula-2 can invoke the C preprocessor to manage conditional compilation; in-lining of SYSTEM procedures, intrinsic functions, memory copying routines are also exploited; access to assembly language using GCC syntax is also provided. GNU Modula-2 also support sets of any ordinal type (memory permitting).

GNU Modula-2 was based on a Modula-2 front end which performed a substantial amount of static analysis of the source code (see `-Wpedantic', `-Wpedantic-param-names', `-Wstudents' and `-Wpedentic-cast'.

Finally runtime checking has been implemented and can check: bounds of subranges and array indexes, functions execute a RETURN statement, a pointer does not dereference a NIL pointer value and that the expression within a CASE statement is correctly matched.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.3 Release map

This section attempts to give an idea of which releases points are likely in the future. Clearly this is a fairly fluid release map but hopefully it is more helpful than omitting it altogether. Please note that this is not set in stone and if you wish to see something different please email gaius@gnu.org with your ideas. Also please note that the actual release numbers do not have any correlation to the estimated time of release. For example please do not misunderstand that GM2-1.0 will take twice as long as GM2-0.5 to appear. It is worthing noting that some of the later points in the release life have already been addressed (in part) but are not yet complete.

0.50

compatible with gcc-3.3.6. GNU Modula-2 is stable and passes all regression tests on LP64 Opteron and 32 bit x86 GNU/Linux. The compiler is PIM-234 compatible (use `-fpim2', `-fpim3' and `-fpim4' to force mutually exclusive PIM features).

It is also able to compile the University of Ulm libraries which are now distributed as part of GNU Modula-2. To reference these libraries use the `-flibs=ulm' compiler switch.

0.60

many Logitech compatible libraries will be provided, which will be available when invoked by `-fpim'.

0.70

ISO exception handling working. Core exception handling ISO modules completed. Basic ISO IO libraries implemented.

0.80

a full set of ISO libraries will have been implemented. GNU Modula-2 will be sufficiently ISO compliant to compile the libraries but will not yet be able to fully conform to the ISO Modula-2 standard. COMPLEX types implemented.

0.90

Multi-dimensional dynamic arrays complete. This release marks the porting and bug fixing and rapid releasing count down towards..

1.0

GNU Modula-2 will be fully ISO compliant.

There will be releases inbetween those outlined above and these releases may occur when GNU Modula-2 builds using a different GCC source tree. It is a goal that backward compatibility to gcc-3.3.6 will be provided as far as it is possible. Releases will also occur if a key component of ISO Modula-2 is implemented (for example exception handling, complex types or `FINALLY' is implemented).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4 Compiler options

This section describes the compiler options specific to GNU Modula-2 for generic flags details see See (gcc)Invoking GCC.

-d

a GCC option See (gcc)Invoking GCC. It allows users to specify how the rtl passes should dump their internal state.

-I

used to specify the search path for definition and implementation modules. An example is: gm2 -g -c -I.:../../libs foo.mod. If this option is not specified then the default path is added which consists of the current directory followed by the appropriate language dialect library directories.

-fobject-path=

used to specify the path for objects during the linking stage. An example is: gm2 -g -fobject-path=.:../../libs/O2 -I.:../../libs foo.mod. The combination of -I and -fobject-path= allows projects to keep various styles of objects separate from their source counterparts. For example it would be possible to compile implementation modules with different levels of optimization and with/without debugging and keep them in separate directories. If the -fobject-path= option is not specified then it is set internally by using the path as specified by the -I option. If the -I was also not specified then it uses the current directory. In all cases the appropriate language dialect library directories are appended to the end of the path.

-fdump-system-exports

display all inbuilt system items. This is an internal command line option.

-fswig

generate a swig interface file.

-fshared

generate a shared library from the module.

-fmakeinit

generate the start up C code for the module, a file `_m2_modulename.c' is created. This is an internal command line option.

-fmakeall

generate a temporary makefile and build all dependent modules and link.

-fruntime-modules=

specify, using a comma separated list, the runtime modules and their order. These modules will initialized first before any other modules in the application dependancy. By default the runtime modules list is set to Storage,SYSTEM,M2RTS,RTExceptions.

-fbounds

generate code to check the bounds of subranges and array indexes.

-freturn

generate code to check that functions always exit with a RETURN and do not fall out at the end.

-fnil

turns on runtime checking to detect accessing data through a NIL value pointer.

-fcase

turns on runtime checking to check whether a CASE statement requires an ELSE clause when on was not specified.

-fcheck-all

turns on all runtime checks. This is the same as invoking GNU Modula-2 using the command options -fbounds -freturn -fnil -fcase.

-v

display all calls to subsidiary programs, such as the C preprocessor, the GNU Modula-2 linker and compiler.

-fstatistics

generates quadruple information: number of quadruples generated, number of quadruples remaining after optimisation.

-fmakelist

this option is only applicable when linking a program module. The compiler will generate a `modulename.lst' file which contains a list indicating the initialisation order of all modules which are to be linked. The actual link does not occur. The GNU Modula-2 linker scans all IMPORTs, generates a list of dependencies and produces an ordered list for initialisation. It will probably get the order wrong if your project has cyclic dependencies, but the `.lst' file is plain text and can be modified if required. Once the `.lst' file is created it can be used by the compiler to link your project via the `-fuselist' option. It has no effect if the `-c' option is present.

-fuselist

providing `gm2' has been told to link the program module this option uses the file `modulename.lst' for the initialisation order of modules.

-fcpp

preprocess the source with `cpp -lang-asm -traditional-cpp' For further details about these options see See (cpp)Invocation. If `-fcpp' is supplied then all definition modules and implementation modules which are parsed will be preprocessed by `cpp'.

-fiso

turn on ISO standard features. Currently this enables the ISO SYSTEM module and alters the default library search path so that the ISO libraries are searched before the PIM libraries. It also effects the behaviour of DIV and MOD operators. See See (gm2)Dialect.

-fpim

turn on PIM standard features. Currently this enables the PIM SYSTEM module and determines which identifiers are pervasive (declared in the base module). If no other `-fpim[234]' switch is used then division and modulus operators behave as defined in PIM4. See See (gm2)Dialect.

-fpim2

turn on PIM-2 standard features. Currently this removes SIZE from being a pervasive identifier (declared in the base module). It places SIZE in the SYSTEM module. It also effects the behaviour of DIV and MOD operators. See See (gm2)Dialect.

-fpim3

turn on PIM-3 standard features. Currently this only effects the behaviour of DIV and MOD operators. See See (gm2)Dialect.

-fpim4

turn on PIM-4 standard features. Currently this only effects the behaviour of DIV and MOD operators. See See (gm2)Dialect.

-fpositive-mod-floor-div

forces the DIV and MOD operators to behave as defined by PIM4. All modulus results are positive and the results from the division are rounded to the floor. See See (gm2)Dialect.

-flibs=ulm

modifies the default library search path so that the University of Ulm libraries are searched before the other PIM libraries.

-flibs=pim

modifies the default library search path so that the PIM libraries are searched before any others (the default).

-flibs=min

modifies the default library search path so that the absolute minimum of Modula-2 runtime libraries are loaded (a stripped down M2RTS, SYSTEM and libc).

-flibs=iso

modifies the default library search path so that the ISO libraries are searched before any others (not needed if `-fiso' was specified).

-flibs=logitech

modifies the default library search path so that the Logitech compatible libraries are searched before the base PIM libraries.

-flibs=pim-coroutine

modifies the default libraries search path so that the PIM SYSTEM module providing coroutine support is searched before the base PIM libraries. This directory also includes many coroutine related libraries.

-fextended-opaque

allows opaque types to be implemented as any type. This is a GNU Modula-2 extension and it requires that the implementation module defining the opaque type is available so that it can be resolved when compiling the module which imports the opaque type.

-fsources

displays the path to the source of each module. This option can be used at compile time to check the correct definition module is being used.

-fmodules

displays the path to each modules object file. This option is used at link time to check the correct object file is being linked.

-fdef=

recognise the specified suffix as a definition module filename. The default implmentation and module filename suffix is `.def'. If this option is used GNU Modula-2 will still fall back to this default if a requested definition module is not found.

-fmod=

recognise the specified suffix as implementation and module filenames. The default implmentation and module filename suffix is `.mod'. If this option is used GNU Modula-2 will still fall back to this default if it needs to read an implmentation module and the specified suffixed filename does not exist. Both this option and -fdef= also work with the -fmakeall option.

-fxcode

issues all errors and warnings in the `Xcode' format.

-funbounded-by-reference

enable optimization of unbounded parameters by attempting to pass non VAR unbounded parameters by reference. This optimization avoids the implicit copy inside the callee procedure. GNU Modula-2 will only allow unbounded parameters to be passed by reference if, inside the callee procedure, they are not written to, no address is calculated on the array and it is not passed as a VAR parameter. Note that it is possible to write code to break this optimization, therefore this option should be used carefully. For example it would be possible to take the address of an array, pass the address and the array to a procedure, read from the array in the procedure and write to the location using the address parameter.

Due to the dangerous nature of this option it is not enabled when the -O option is specified.

-Wverbose-unbounded

inform the user which non VAR unbounded parameters will be passed by reference. This only produces output if the option `-funbounded-by-reference' is also supplied on the command line.

-Wstudents

checks for bad programming style. This option is aimed at new users of Modula-2 in that it checks for situations which might cause confusion and thus mistakes. It checks whether variables of the same name are declared in different scopes and whether variables look like keywords. Experienced users might find this option too aggressive.

-Wpedantic

forces the compiler to reject nested WITH statements referencing the same record type. Does not allow multiple imports of the same item from a module. It also checks that: procedure variables are written to before being read; variables are not only written to but read from; variables are declared and used. If the compiler encounters a variable being read before written it will terminate with a message. It will check that FOR loop indices are not used outside the end of this loop without being reset.

-Wpedantic-param-names

procedure parameter names are checked in the definition module against their implementation module counterpart. This is not necessary in ISO or PIM versions of Modula-2, but it can be extremely useful, as long as code is intentionally written in this way.

-Wpedantic-cast

warns if the ISO system function is used and if the size of the variable is different from that of the type. This is legal in ISO Modula-2, however it can be dangerous. Some users may prefer to use VAL instead in these situations and use CAST exclusively for changes in type on objects which have the same size.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.5 Example compile and link

This section describes how to compile and link a simple hello world program. It provides a few examples of using the different options mentioned in See (gm2)Compiler options. Assuming that you have a file called `hello.mod' in your current directory which contains:

 
MODULE hello ;

FROM StrIO IMPORT WriteString, WriteLn ;

BEGIN
   WriteString('hello world') ; WriteLn
END hello.

You should be able to compile it by: `gm2 -c -g -I. hello.mod' and link via: `gm2 -g -I. hello.mod'. The result should be an `a.out' file created in your directory.

Alternatively it may be compiled by:

`gm2 -g -I. -fmakeall hello.mod' (1)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.6 GNU Modula-2 related environment variables

This section descibes the environment variables used by GNU Modula-2 and how they can be used to switch between releases of the compiler. Other environment variables can be set to modify the default library path. Initially we will consider environment variables most likely used by the end user. These two environment variables are GM2IPATH and GM2OPATH.

For example suppose a compile and link on the command line looks like this:

 
$ gm2 -g -c -I. -I../project:../project/unix foo.mod
$ gm2 -g -I. -I../project:../project/unix \
  -fobject-path=../project/obj:../project/unix/obj -I. foo.mod

they can be simplified by utilising two environment variables to do exactly the same compile and link.

 
$ export GM2IPATH=../project:../project/unix
$ export GM2OPATH=../project/obj:../project/unix/obj
$ gm2 -g -c -I. foo.mod
$ gm2 -g -I. foo.mod

It is important to note that the two environment variables GM2IPATH and GM2OPATH have a lower priority than any -I or -fobject-path= command line option. The search order for compiling and linking is: command line switches followed by environment variable paths followed by default runtime libraries or Modula-2 dialect libraries. If in doubt include the -v option to see the search path used between the compiler subcomponents.

Lastly there is the GM2_ROOT environment variable which determines where the compiler subcomponents reside in the filesystem. This environment variable overrides the compiler time configure option --prefix=. For example suppose the compiler was built to reside in `/usr/local' and the system administrator decided to move the entire compiler tree to `/architecture/i386/usr'. Once the tree is moved then a system wide environment variable (GM2_ROOT) could be set to:

 
$ export GM2_ROOT=/architecture/i386/usr

The system administrator needs to ensure that the front end binary `gm2' can be seen by the users path. At that point a user can invoke gm2 -g -c -I. hello.mod from the command line and all subcomponents will be picked up from `/architecture/i386/usr'. This allows users to try out different GNU Modula-2 releases and also allows system administrators to install compiler binaries at different locations to where they were initially configured to reside.

The environment variable GM2_ROOT has no effect if either the LIBRARY_PATH or COMPILE_PATH is set. The last two environment variables are used by gcc. However if by mistake GM2_ROOT and either LIBRARY_PATH or COMPILE_PATH is set then an error message is issued.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.7 Elementary data types

This section describes the elementary data types supported by GNU Modula-2. It also describes the relationship between these data types and the equivalent C data types.

The following data types are supported: INTEGER, LONGINT, SHORTINT, CARDINAL, LONGCARD, SHORTCARD, BOOLEAN, REAL, LONGREAL, SHORTREAL, COMPLEX, LONGCOMPLEX, SHORTCOMPLEX and CHAR.

An equivalence table is given below:

 
GNU Modula-2              GNU C
======================================
INTEGER                   int
LONGINT                   long long int
SHORTINT                  short int
CARDINAL                  unsigned int
LONGCARD                  long long unsigned int
SHORTCARD                 short unsigned int
BOOLEAN                   int
REAL                      double
LONGREAL                  long double
SHORTREAL                 float
CHAR                      char
SHORTCOMPLEX              complex float
COMPLEX                   complex double
LONGCOMPLEX               complex long double

Note that GNU Modula-2 also supports fixed sized data types which are exported from the SYSTEM module. See (gm2)The PIM system module. See (gm2)The ISO system module.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.8 Permanently accessible base procedures.

This section describes the procedures and functions which are always visible.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.8.1 Standard procedures and functions common to PIM and ISO

The following procedures are implemented and conform with Programming in Modula-2 and ISO Modula-2: NEW, DISPOSE, INC, DEC, INCL, EXCL and HALT. The standard functions are: HIGH, CAP, ABS, ODD, VAL, CHR, MIN, MAX. All these functions and procedures (except HALT, NEW, DISPOSE and, under non constant conditions, LENGTH) generate in-line code for efficiency.

 
(*
   NEW - the procedure NEW is replaced by:
         ALLOCATE(p, TSIZE(p^)) ;
         The user is expected to import the procedure ALLOCATE
         (normally found in the module, Storage.)

         In:  a variable p: of any pointer type.
         Out: variable, p, is set to some allocated memory
              which is large enough to hold all the contents of p^.
*)

PROCEDURE NEW (VAR p:<any pointer type>) ;
 
(*
   DISPOSE - the procedure DISPOSE is replaced by:
             DEALLOCATE(p, TSIZE(p^)) ;
             The user is expected to import the procedure DEALLOCATE
             (normally found in the module, Storage.)

             In:  a variable p: of any pointer type which has been
                  initialized by a call to NEW.
             Out: the area of memory
                  holding p^ is returned to the system.
                  Note that the underlying procedure DEALLOCATE
                  procedure in module Storage will assign p to NIL.
*)

PROCEDURE DISPOSE (VAR p:<any pointer type>) ;
 
(*
   INC - can take one or two parameters. If supplied with one
         parameter it adds 1 to the variable, v.
         If two parameters are supplied then the value, a, is
         added to, v.
*)

PROCEDURE INC (VAR v: <any base type>; [a: <any base type> = 1]) ;
 
(*
   DEC - can take one or two parameters. If supplied with one
         parameter it subtracts 1 from the variable, v.
         If two parameters are supplied then the value, a, is
         subtracted from, v.
*)

PROCEDURE DEC (VAR v: <any base type>; [a: <any base type> = 1]) ;
 
(*
   INCL - includes bit element, e, to a set type, s.
*)

PROCEDURE INCL (VAR s: <any set type>; e: <element of set type s>) ;
 
(*
   EXCL - excludes bit element, e, from a set type, s.
*)

PROCEDURE EXCL (VAR s: <any set type>; e: <element of set type s>) ;
 
(*
   HALT - will call the HALT procedure inside the module M2RTS.
          Users can replace M2RTS.
*)

PROCEDURE HALT ;

The following define the standard set of functions which conform with Programming in Modula-2 and ISO Modula-2.

 
(*
   HIGH - returns the last accessible index of an parameter declared as
          ARRAY OF CHAR. Thus

          PROCEDURE foo (a: ARRAY OF CHAR) ;
          VAR
             c: CARDINAL ;
          BEGIN
             c := HIGH(a)
          END foo ;

          BEGIN
             foo('hello')
          END

          will cause the local variable, c, to contain the value 4
*)

PROCEDURE HIGH (a: ARRAY OF CHAR) : CARDINAL ;
 
(*
   CAP - returns the capital of character, ch, providing
         ch lies within the range 'a'..'z'. Otherwise, ch,
         is returned unaltered.
*)

PROCEDURE CAP (ch: CHAR) : CHAR ;

 
(*
   ABS - returns the positive value of, i.
*)

PROCEDURE ABS (i: <any signed type>) : <any signed type> ;

 
(*
   VAL - converts data, i, of <any simple data type 2> to
         <any simple data type 1> and returns this value.
         No range checking is performed during this conversion.
*)

PROCEDURE VAL (<any simple data type 1>,
               i: <any simple data type 2>) : <any simple data type 1> ;

 
(*
   CHR - converts a value of a <whole number type> into a CHAR.
         CHR(x) is shorthand for VAL(CHAR, x).
*)

PROCEDURE CHR (x: <whole number type>) : CHAR ;

 
(*
   ODD - returns TRUE if the value is not divisible by 2.
*)

PROCEDURE ODD (x: <whole number type>) : BOOLEAN ;

 
(*
   MIN - returns the lowest legal value of an ordinal type.
*)

PROCEDURE MIN (t: <ordinal type>) : <ordinal type> ;

 
(*
   MAX - returns the largest legal value of an ordinal type.
*)

PROCEDURE MAX (t: <ordinal type>) : <ordinal type> ;


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.8.2 ISO specific standard procedures and functions

The standard function LENGTH is specific to ISO Modula-2 and is defined as:

 
(*
   LENGTH - returns the length of string, a.
*)

PROCEDURE LENGTH (a: ARRAY OF CHAR) : CARDINAL ;

This function is evaluated at compile time, providing that string a is a constant. If a cannot be evaluated then a call is made to M2RTS.Length.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.9 GNU Modula-2 supported dialects

This section describes the dialects understood by GNU Modula-2. It also describes the differences between the dialects and any command line switches which determine dialect behaviour.

The GNU Modula-2 compiler is based on the language as defined in 'Programming in Modula-2' 2nd Edition, Springer Verlag, 1982, 1983 by Niklaus Wirth (PIM2), 'Programming in Modula-2', 3rd Corrected Edition, Springer Verlag, 1985 (PIM3) and 'Programming in Modula-2', 4th Edition, Springer Verlag, 1988 (PIM4). It also includes ISO M2 features and GNU Modula-2 extensions. Currently GNU Modula-2 (0.68) implements all PIM dialects of the language, eventually GNU Modula-2 will be fully compliant with ISO Modula-2.

The command line switches `-fpim2', `-fpim3', `-fpim4' and `-fiso' can be used to force mutually exclusive features. However by default the compiler will not agressively fail if a non mutually exclusive feature is used from another dialect. For example it is possible to specify `-fpim2' and still utilise `DEFINITION' `MODULES' which have no export list.

Some dialect differences will force a compile time error, for example in PIM2 the user must IMPORT SIZE from the module SYSTEM, whereas in PIM3 and PIM4 SIZE is a pervasive function. Thus compiling PIM4 source code with the `-fpim2' switch will cause a compile time error. This can be fixed quickly with an additional IMPORT or alternatively by compiling with the `-fpim4' switch.

However there are some very important differences between the dialects which are mutually exclusive and therefore it is vital that users choose the dialects with care when these language features are used.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.9.1 Integer division, remainder and modulus

The most dangerous set of mutually exclusive features found in the four dialects supported by GNU Modula-2 are the INTEGER division, remainder and modulus arithmetic operators. It is important to note that the same source code can be compiled to give different runtime results depending upon these switches! The reference manual for the various dialects of Modula-2 are quite clear about this behaviour and sadly there are three distinct definitions.

The table below illustrates the problem when a negative operand is used.

 
                  Pim2/3          Pim4                ISO
               -----------    -----------    ----------------------
lval    rval   DIV     MOD    DIV     MOD    DIV    MOD    /    REM
 31      10      3       1      3       1      3      1     3     1
-31      10     -3      -1     -4       9     -4      9    -3    -1
 31     -10     -3       1     -3       1     Exception    -3     1
-31     -10      3      -1      4       9     Exception     3    -1

See also P24 of PIM2, P27 of PIM3, P29 of PIM4 and P201 of the ISO Standard. At present all dialect division, remainder and modulus are implemented as above, apart from the exception calling in the ISO dialect. Instead of exception handling the results are the same as the PIM4 dialect. This is a temporary implementation situation.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.10 GNU Modula-2 language extensions

This section introduces the GNU Modula-2 language extensions. The GNU Modula-2 compiler allows abstract data types to be any type, not just restricted to a pointer type providing the `-fextended-opaque' option is supplied See (gm2)Compiler options.

Declarations can be made in any order, whether they are types, constants, procedures, nested modules or variables (see See section Passes.)

GNU Modula-2 also allows programmers to interface to C and assembly language.

GNU Modula-2 provides support for the special tokens __LINE__, __FILE__, __FUNCTION__ and __DATE__. Support for these tokens will occur even if the `-fcpp' option is not supplied. A table of these identifiers and their data type and values is given below:

 
Scope       GNU Modula-2 token      Data type and example value

anywhere    __LINE__                Constant Literal compatible
                                    with CARDINAL, INTEGER and WORD.
                                    Example 1234

anywhere    __FILE__                Constant string compatible
                                    with parameter ARRAY OF CHAR or
                                    an ARRAY whose SIZE is >= string
                                    length. Example
                                    "hello.mod"

procedure   __FUNCTION__            Constant string compatible
                                    with parameter ARRAY OF CHAR or
                                    an ARRAY whose SIZE is >= string
                                    length. Example
                                    "calc"

module      __FUNCTION__            Example
                                    "module hello initialization"

anywhere    __DATE__                Constant string compatible
                                    with parameter ARRAY OF CHAR or
                                    an ARRAY whose SIZE is >= string
                                    length. Example
                                    "Thu Apr 29 10:07:16 BST 2004"

anywhere   __COLUMN__               Gives a contant literal number
                                    determining the column of the
                                    first token on the line.

The preprocessor `cpp' can be invoked via the `-fcpp' command line option. This in turn invokes `cpp' with the following arguments `-traditional -lang-asm'. These options preserve comments and all quotations. `gm2' treats a `#' character in the first column as a preprocessor directive.

For example here is a module which calls FatalError via the macro ERROR.

 
MODULE cpp ;

FROM SYSTEM IMPORT ADR, SIZE ;
FROM libc IMPORT exit, printf, malloc ;

PROCEDURE FatalError (a, file: ARRAY OF CHAR;
                         line: CARDINAL;
                         func: ARRAY OF CHAR) ;
BEGIN
   printf("%s:%d:fatal error, %s, in %s\n",
           ADR(file), line, ADR(a), ADR(func)) ;
   exit(1)
END FatalError ;

#define ERROR(X)  FatalError(X, __FILE__, __LINE__, __FUNCTION__)

VAR
   pc: POINTER TO CARDINAL;
BEGIN
   pc := malloc(SIZE(CARDINAL)) ;
   IF pc=NIL
   THEN
      ERROR('out of memory')
   END
END cpp.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.10.1 Optional procedure parameter

GNU Modula-2 allows the last parameter to a procedure or function parameter to be optional. For example in the ISO library `COROUTINES.def' the procedure NEWCOROUTINE is defined as having an optional fifth argument (initProtection) which, if absent, is automatically replaced by NIL.

 
PROCEDURE NEWCOROUTINE (procBody: PROC; workspace: SYSTEM.ADDRESS;
                        size: CARDINAL; VAR cr: COROUTINE;
                        [initProtection: PROTECTION = NIL]);

  (* Creates a new coroutine whose body is given by procBody,
     and returns the identity of the coroutine in cr.
     workspace is a pointer to the work space allocated to
     the coroutine; size specifies the size of this workspace
     in terms of SYSTEM.LOC.

     The optional fifth argument may contain a single parameter
     which specifies the initial protection level of the coroutine.
  *)

The implementation module `COROUTINES.mod' implements this procedure using the following syntax:

 
PROCEDURE NEWCOROUTINE (procBody: PROC; workspace: SYSTEM.ADDRESS;
                        size: CARDINAL; VAR cr: COROUTINE;
                        [initProtection: PROTECTION]);
BEGIN
   
END NEWCOROUTINE ;

Note that it is illegal for this declaration to contain an initialiser value for initProtection. However it is necessary to surround this parameter with the brackets [ and ]. This serves to remind the programmer that the last parameter was declared as optional in the definition module.

Local procedures can be declared to have an optional final parameter in which case the initializer is mandatory in the implementation or program module.

GNU Modula-2 also provides additional fixed sized data types which are all exported from the SYSTEM module. See (gm2)The PIM system module. See (gm2)The ISO system module.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.11 GNU Modula-2 language extensions

This section discuss the issues surrounding assignment, expression and parameter compatibility, their effect of the additional fixed sized datatypes and also their effect of runtime checking. The data types supported by the compiler are:

 
GNU Modula-2              scope      switches
=============================================
INTEGER                   pervasive
LONGINT                   pervasive
SHORTINT                  pervasive
CARDINAL                  pervasive
LONGCARD                  pervasive
SHORTCARD                 pervasive
BOOLEAN                   pervasive
REAL                      pervasive
LONGREAL                  pervasive
SHORTREAL                 pervasive
CHAR                      pervasive
SHORTCOMPLEX              pervasive
COMPLEX                   pervasive
LONGCOMPLEX               pervasive

BITSET                    SYSTEM
LOC                       SYSTEM     -fiso
BYTE                      SYSTEM
WORD                      SYSTEM
ADDRESS                   SYSTEM

The following extensions are supported for
most architectures (please check SYSTEM.def).
=============================================
INTEGER8                  SYSTEM
INTEGER16                 SYSTEM
INTEGER32                 SYSTEM
INTEGER64                 SYSTEM
CARDINAL8                 SYSTEM
CARDINAL16                SYSTEM
CARDINAL32                SYSTEM
CARDINAL64                SYSTEM
BITSET8                   SYSTEM
BITSET16                  SYSTEM
BITSET32                  SYSTEM
WORD16                    SYSTEM
WORD32                    SYSTEM
WORD64                    SYSTEM
REAL32                    SYSTEM
REAL64                    SYSTEM
REAL96                    SYSTEM
REAL128                   SYSTEM
COMPLEX32                 SYSTEM
COMPLEX64                 SYSTEM
COMPLEX96                 SYSTEM
COMPLEX128                SYSTEM

The compiler categorises compatibility between all these types into three components: assignment, parameter and expression.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.11.1 Assignment compatibility

This section discusses the assignment issues surrounding assignment compatibility of fundamental types. Obviously compatibility exists between the same sized types. Same type family of different sizes are also compatible as long as the MAX(type) and MIN(type) is known. So for example this includes the INTEGER family, CARDINAL family and the REAL family. The reason for this is that when the assignment is performed the compiler will check to see that the expression (on the right of the :=) lies within the bounds of the designator type (on the left hand side of the :=). Thus these ordinal types can be assignment compatible. However it does mean that WORD32 is not compatible with WORD16 as WORD32 does not have a minimum or maximum value and therefore cannot be checked. The compiler does not know which of the two bytes from WORD32 should be copied into WORD16 and which two should be ignored. Currently the types BITSET8, BITSET16 and BITSET32 are assignment incompatible. However this restriction maybe lifted when further runtime checking is achieved.

Modula-2 does allow INTEGER to be assignment compatible with WORD as they are the same size. Likewise GNU Modula-2 allows INTEGER16 to be compatible with WORD16 and the same for the other fixed sized types and their sized equivalent in either WORDn, BYTE or LOC types. However it prohibits assignment between WORD and WORD32 even though on many systems these sizes will be the same. The reasoning behind this rule is that the extended fixed sized types are meant to be used by applications requiring fixed sized data types and it is more portable to forbid the bluring of the boundaries between fixed sized and machine dependant sized types.

Intemediate code runtime checking is always generated by the front end. However this intemediate code is only translated into actual code if the appropriate command line switches are specified. This allows the compiler to perform limited range checking at compile time. In the future it will allow the extensive GCC optimisations to propagate constant values through to the range checks which if they are found to exceed the type bounds will result in a compile time error message.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.11.2 Expression compatibility

According to the various Modula-2 standards INTEGER and CARDINAL types are not expression compatible (http://freepages.modula2.org/report4/modula-2.html and ISO Modula-2). This is rule is also extended across the fixed sized data types.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.11.3 Parameter compatibility

Parameter compatibility is divided into two arenas, pass by value and pass by reference (VAR). In the case of pass by value the rules are exactly the same as assignment. However in the second case, pass by reference, the actual parameter and formal parameter must be the same size and family. Furthermore INTEGER and CARDINALs are not treated as compatible in the pass by reference case.

The types BYTE, LOC and WORD and sized their derivitives are assignment and parameter compatible with any data type of the same size.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.12 Unbounded by reference

This section documents a GNU Modula-2 compiler switch which implements a language optimisation surrounding the implementation of unbounded arrays. In GNU Modula-2 the unbounded array is implemented by utilising an internal structure struct {dataType *address, unsigned int high}. So given the Modula-2 procedure declaration:

 
PROCEDURE foo (VAR a: ARRAY OF dataType) ;
BEGIN
   IF a[2]= (* etc *)
END foo ;

it is translated into GCC trees, which can be represented in their C form thus:

 
void foo (struct {dataType *address, unsigned int high} a)
{
   if (a.address[2] == /* etc */
}

Whereas if the procedure foo was declared as:

 
PROCEDURE foo (a: ARRAY OF dataType) ;
BEGIN
   IF a[2]= (* etc *)
END foo ;

then it is implemented by being translated into the following GCC trees, which can be represented in their C form thus:

 
void foo (struct {dataType *address, unsigned int high} a)
{
   dataType *copyContents = (dataType *)alloca (a.high+1);
   memcpy(copyContents, a.address, a.high+1);
   a.address = copyContents;

   if (a.address[2] == /* etc */
}

This implementation works, but it makes a copy of each non VAR unbounded array when a procedure is entered. If the unbounded array is not changed during procedure foo then this implementation will be very inefficient. In effect Modula-2 lacks the REF keyword of Ada. Consequently the programmer maybe tempted to sacrifice semantic clarity for greater efficiency by declaring the parameter using the VAR keyword in place of REF.

The -funbounded-by-reference switch instructs the compiler to check and see if the programmer is modifying the content of any unbounded array. If it is modified then a copy will be made upon entry into the procedure. Conversely if the content is only read and never modified then this non VAR unbounded array is a candidate for being passed by reference. It is only a candidate as it is still possible that passing this parameter by reference could alter the meaning of the source code. For example consider the following case:

 
PROCEDURE StrConCat (VAR a: ARRAY OF CHAR; b, c: ARRAY OF CHAR) ;
BEGIN
   (* code which performs string a := b + c *)
END StrConCat ;

PROCEDURE foo ;
VAR
   a: ARRAY [0..3] OF CHAR ;
BEGIN
   a := 'q' ;
   StrConCat(a, a, a)
END foo ;

In the code above we see that the same parameter, a, is being passed three times to StrConCat. Clearly even though parameters b and c are never modified it would be incorrect to implement them as pass by reference. Therefore the compiler checks to see if any non VAR parameter is type compatible with any VAR parameter and if so it generates runtime procedure entry checks to determine whether the contents of parameters b or c matches the contents of a. If a match is detected then a copy is made and the address in the unbounded structure is modified.

The compiler will check the address range of each candidate against the address range of any VAR parameter, providing they are type compatible. For example consider:

 
PROCEDURE foo (a: ARRAY OF BYTE; VAR f: REAL) ;
BEGIN
   f := 3.14 ;
   IF a[0]=BYTE(0)
   THEN
      (* etc *)
   END
END foo ;

PROCEDURE bar ;
BEGIN
   r := 2.0 ;
   foo(r, r)
END bar ;

Here we see that although parameter, a, is a candidate for the passing by reference, it would be incorrect to use this transformation. Thus the compiler detects that parameters, a and f are type compatible and will produce runtime checking code to test whether the address range of their respective contents intersect.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.13 How to produce swig interface files

This section describes how your Modula-2 implementation modules can be called from Python (and other scripting languages such as TCL and Perl). GNU Modula-2 can be instructed to create a swig interface when it is compiling an implementation module. Swig then uses the interface file to generate all the necessary wrapping to that the desired scripting language may access your implementation module.

Here is an example of how you might call upon the services of the Modula-2 library module NumberIO from Python. This example can be found in the directory `gm2/examples/swig/full-strlib' and can be run using the commands:

 
$ cd gcc-4.1.2/gcc/gm2/examples/swig/full-strlib
$ make numberio

If you wanted to do this step by step without the `Makefile' then firstly you should compile the NumberIO module as a shared library. This can be achieved by using the following commands:

 
$ cd gcc-4.1.2/gcc/gm2/examples/swig/full-strlib
$ gm2 -fshared -I. -c -fPIC -g -fswig -I../../../gm2-libs \
    ../../../gm2-libs/NumberIO.mod

The example assumes that the source code for `NumberIO.mod' can be found in directory `../../../gm2-libs'. The first command produces two files: `NumberIO.i' and `NumberIO.o'. The file `NumberIO.o' is a position independant code object file whereas the file `NumberIO.i' is a swig interface file and contains a swig interpretation of the `NumberIO.def'. GNU Modula-2 uses the same mechanism for handling exceptions as GNU C++. The file `NumberIO.i' contains exception handling information therefore we need to ask swig to generate C++ wrappers for `NumberIO.mod'. This is achieved by:

 
$ swig -c++ -python NumberIO.i
$ gcc -c -fPIC NumberIO_wrap.cxx -I/usr/include/python2.4

The swig command line generates the necessary Python and C++ interface files using the interface file. The C++ interface file is also compiled into position independant code. Finally the module NumberIO is linked with all its dependants and `NumberIO_wrap.o'.

 
$ gm2 -shared -fshared -fPIC -g \
     ../../../gm2-libs/NumberIO.mod NumberIO_wrap.o -o _NumberIO.so

Now it is possible to run the following Python script (called `testnum.py'):

 
import NumberIO

print "1234 x 2 =", NumberIO.NumberIO_StrToInt("1234")*2

like this:

 
$ python testnum.py
1234 x 2 = 2468

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.13.1 Limitations of automatic generated of Swig files

This section discusses the limitations of automatically generating swig files. From the previous example we see that the module NumberIO had a swig interface file `NumberIO.i' automatically generated by the compiler. If we consider three of the procedure definitions in `NumberIO.def' we can see the success and limitations of the automatic interface generation.

 
PROCEDURE StrToHex (a: ARRAY OF CHAR; VAR x: CARDINAL) ;
PROCEDURE StrToInt (a: ARRAY OF CHAR; VAR x: INTEGER) ;
PROCEDURE ReadInt (VAR x: CARDINAL) ;

Below are the swig interface prototypes:

 
extern void NumberIO_StrToHex (char *_m2_address_a,
                               int _m2_high_a, unsigned int *OUTPUT);
/*  parameters: x is known to be an OUTPUT */
extern void NumberIO_StrToInt (char *_m2_address_a,
                               int _m2_high_a, int *OUTPUT);
/*  parameters: x is guessed to be an OUTPUT */
extern void NumberIO_ReadInt (int *x);
/*  parameters: x is unknown */

In the case of StrToHex it can be seen that the compiler detects that the last parameter is an output. It explicitly tells swig this by using the parameter name OUTPUT and in the following comment it informs the user that it knows this to be an output parameter. In the second procedure StrToInt it marks the final parameter as an output, but it tells the user that this is only a guess. Finally in ReadInt it informs the user that it does not know whether the parameter, x, is an output, input or an inout parameter.

The compiler decides whether to mark a parameter as either: INPUT, OUTPUT or INOUT if it is read before written or visa versa in the first basic block. At this point it will write output that the parameter is known. If it is not read or written in the first basic block then subsequent basic blocks are searched and the result is commented as a guess. Finally if no read or write occurs then the parameter is commented as unknown. However, clearly it is possible to fool this mechanism. Nevertheless automatic generation of implementation module into swig interface files was thought sufficiently useful despite these limitations.

In conclusion it would be wise to check all parameters in any automatically generated swig interface file. Furthermore you can force the automatic mechanism to generate correct interface files by reading or writing to the VAR parameter in the first basic block of a procedure.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.14 Interfacing GNU Modula-2 to C

The GNU Modula-2 compiler tries to use the C calling convention wherever possible however some parameters have no C equivalent and thus a language specific method is used. For example unbounded arrays are passed as a struct {void *address, unsigned int high} and the contents of these arrays are copied by callee functions when they are declared as non VAR parameters. The VAR equivalent unbounded array parameters need no copy, but still use the struct representation.

The recommended method of interfacing GNU Modula-2 to C is by telling the definition module that the implementation is in the C language. This is achieved by using the tokens DEFINITION MODULE FOR "C". Here is an example which can be found in the source tree `gcc-version/gcc/gm2/examples/callingC/libprintf.def'

 
DEFINITION MODULE FOR "C" libprintf ;

EXPORT UNQUALIFIED printf ;

PROCEDURE printf (a: ARRAY OF CHAR; ...) : [ INTEGER ] ;

END libprintf.

the UNQUALIFIED keyword in the definition module informs GNU Modula-2 not to prefix the module name to exported references in the object file.

The printf declaration states that the first parameter semantically matches ARRAY OF CHAR but since the module is for the C language it will be mapped onto char *. The token ... indicates a variable number of arguments (varargs) and all parameters passed here are mapped onto their C equivalents. Arrays and constant strings are passed as pointers. Lastly the [ INTEGER ] states that the caller can ignore the function return result if desired.

The hello world program can be rewritten as:

 
MODULE hello ;

FROM libprintf IMPORT printf ;

BEGIN
   printf("hello world\n")
END hello.

and it can be compiled by:

`gm2 -fmakeall -g -I. hello.mod -lc'

In reality the `-lc' is redundant as libc is always included in the linking process. It is shown here to emphasize that the C library or object file containing printf must be present.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.15 Interface to assembly language

The interface for GNU Modula-2 to assembly language is almost identical to GNU C. The only alterations are that the keywords asm and volatile are in capitals, following the Modula-2 convention.

A simple, but highly non optimal, example is given below. Here we want to add the two CARDINALs foo and bar together and return the result.

 
PROCEDURE Example (foo, bar: CARDINAL) : CARDINAL ;
VAR
   myout: CARDINAL ;
BEGIN
   ASM VOLATILE ("movl %1,%%eax; addl %2,%%eax; movl %%eax,%0"
      : "=g" (myout)           (* outputs *)
      : "g" (foo), "g" (bar)   (* inputs  *)
      : "eax") ;               (* we trash *)
   RETURN( myout )
END Example ;

For a full description of this interface we refer the reader to the GNU C manual.

See (gcc)Extended Asm.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.16 Accessing GNU Modula-2 Built-ins

This section describes the built-in constants and functions defined in GNU Modula-2. The following compiler constants can be accessed using the __ATTRIBUTE__ __BUILTIN__ keywords. These are not part of the Modula-2 language and they may differ depending upon the target architecture but they provide a method whereby common libraries can interface to a different underlying architecture.

The built-in constants are: BITS_PER_UNIT, BITS_PER_WORD, BITS_PER_CHAR and UNITS_PER_WORD. They are integrated into GNU Modula-2 by an extension to the ConstFactor rule:

 
ConstFactor := ConstQualidentOrSet | Number | ConstString |
               "(" ConstExpression ")" | "NOT" ConstFactor |
               ConstAttribute =:

ConstAttribute := "__ATTRIBUTE__" "__BUILTIN__" "(" "(" Ident ")" ")" =:

Here is an example taken from the ISO library SYSTEM.def:

 
CONST
   BITSPERLOC    = __ATTRIBUTE__ __BUILTIN__ ((BITS_PER_UNIT)) ;
   LOCSPERWORD   = __ATTRIBUTE__ __BUILTIN__ ((UNITS_PER_WORD)) ;

Built-in functions are transparent to the end user. All built-in functions are declared in DEFINITION MODULEs and are imported as and when required. Built-in functions are declared in definition modules by using the __BUILTIN__ keyword. Here is a section of the ISO library LongMath.def which demonstrates this feature.

 
PROCEDURE __BUILTIN__ sqrt (x: LONGREAL): LONGREAL;
  (* Returns the square root of x *)

This indicates that the function sqrt will be implemented using the gcc built-in maths library. If gcc cannot utilise the built-in function (for example if the programmer requested the address of sqrt) then code is generated to call the alternative function implemented in the IMPLEMENTATION MODULE.

Sometimes a function exported from the DEFINITION MODULE will have a different name from the built-in function within gcc. In such cases the mapping between the GNU Modula-2 function name and the gcc name is expressed using the keywords __ATTRIBUTE__ __BUILTIN__ ((Ident)). For example the function sqrt in LongMath.def maps onto the gcc built-in function sqrtl and this is expressed as:

 
PROCEDURE __ATTRIBUTE__ __BUILTIN__ ((sqrtl)) sqrt
                                    (x: LONGREAL) : LONGREAL;
  (* Returns the positive square root of x *)

The following module Builtins.def enumerates the list of built-in functions which can be accessed in GNU Modula-2. It also serves to define the parameter and return value for each function:

 
DEFINITION MODULE Builtins ;

(*
    Description: provides a convenient place to list all the GNU Modula-2
                 built-in functions. These functions should be copied into
                 more generic modules.

                 For example the mathematical functions can be applied to
                 gm2-iso/LongMath. But each built-in function is here for
                 reference.
*)

FROM SYSTEM IMPORT ADDRESS ;

PROCEDURE __BUILTIN__ sinf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ sin (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ sinl (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ cosf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ cos (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ cosl (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ sqrtf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ sqrt (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ sqrtl (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ fabsf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ fabs (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ fabsl (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ logf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ log (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ logl (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ expf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ exp (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ expl (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ log10f (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ log10 (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ log10l (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ exp10f (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ exp10 (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ exp10l (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ alloca (i: CARDINAL) : ADDRESS ;
PROCEDURE __BUILTIN__ memcpy (dest, src: ADDRESS; n: CARDINAL) : ADDRESS ;
PROCEDURE __BUILTIN__ index (s: ADDRESS; c: INTEGER) : ADDRESS ;
PROCEDURE __BUILTIN__ rindex (s: ADDRESS; c: INTEGER) : ADDRESS ;
PROCEDURE __BUILTIN__ memcmp (s1, s2: ADDRESS; n: CARDINAL) : INTEGER ;
PROCEDURE __BUILTIN__ memset (s: ADDRESS; c: INTEGER; n: CARDINAL) : ADDRESS ;
PROCEDURE __BUILTIN__ memmove (s1, s2: ADDRESS; n: CARDINAL) : ADDRESS ;
PROCEDURE __BUILTIN__ strcat (dest, src: ADDRESS) : ADDRESS ;
PROCEDURE __BUILTIN__ strncat (dest, src: ADDRESS; n: CARDINAL) : ADDRESS ;
PROCEDURE __BUILTIN__ strcpy (dest, src: ADDRESS) : ADDRESS ;
PROCEDURE __BUILTIN__ strncpy (dest, src: ADDRESS; n: CARDINAL) : ADDRESS ;
PROCEDURE __BUILTIN__ strcmp (s1, s2: ADDRESS) : INTEGER ;
PROCEDURE __BUILTIN__ strncmp (s1, s2: ADDRESS; n: CARDINAL) : INTEGER ;
PROCEDURE __BUILTIN__ strlen (s: ADDRESS) : INTEGER ;
PROCEDURE __BUILTIN__ strstr (haystack, needle: ADDRESS) : ADDRESS ;
PROCEDURE __BUILTIN__ strpbrk (s, accept: ADDRESS) : ADDRESS ;
PROCEDURE __BUILTIN__ strspn (s, accept: ADDRESS) : CARDINAL ;
PROCEDURE __BUILTIN__ strcspn (s, accept: ADDRESS) : CARDINAL ;
PROCEDURE __BUILTIN__ strchr (s: ADDRESS; c: INTEGER) : ADDRESS ;
PROCEDURE __BUILTIN__ strrchr (s: ADDRESS; c: INTEGER) : ADDRESS ;

PROCEDURE __BUILTIN__ huge_val (r: REAL) : REAL ;
PROCEDURE __BUILTIN__ huge_valf (s: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ huge_vall (l: LONGREAL) : LONGREAL ;

(*
   longjmp - this GCC builtin restricts the val to always 1.
*)
(* do not use these two builtins, as gcc, only really
   anticipates that the Ada front end should use them
   and it only uses them in its runtime exception handling.
   We leave them here in the hope that someday they will
   behave more like their libc counterparts. *)
PROCEDURE __BUILTIN__ longjmp (env: ADDRESS; val: INTEGER) ;
PROCEDURE __BUILTIN__ setjmp (env: ADDRESS) : INTEGER ;

(*
   frame_address - returns the address of the frame.
                   The current frame is obtained if level is 0,
                   the next level up if level is 1 etc.
*)

PROCEDURE __BUILTIN__ frame_address (level: CARDINAL) : ADDRESS ;


(*
   return_address - returns the return address of function.
                    The current function return address is
                    obtained if level is 0,
                    the next level up if level is 1 etc.
*)

PROCEDURE __BUILTIN__ return_address (level: CARDINAL) : ADDRESS ;


END Builtins.

Although this module exists and will result in the generation of in-line code if optimization flags are passed to GNU Modula-2, users are advised to utilize the same functions from more generic libraries. The built-in mechanism will be applied to these generic libraries where appropriate. Note for the mathematical routines to be in-lined you need to specify the `-ffast-math -O' options.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.17 The PIM system module

 
DEFINITION MODULE SYSTEM ;

(*
   Description: Implements the SYSTEM dependent module
                in the Modula-2 compiler.
*)

EXPORT QUALIFIED BITSPERBYTE, BYTESPERWORD,
                 LOC, WORD, BYTE, ADDRESS, BITSET,
                 INTEGER8, INTEGER16, INTEGER32, INTEGER64,
                 CARDINAL8, CARDINAL16, CARDINAL32, CARDINAL64,
                 WORD16, WORD32, WORD64, BITSET8,
                 BITSET16, BITSET32, REAL32, REAL64,
                 REAL96, REAL128, COMPLEX32, COMPLEX64,
                 COMPLEX96, COMPLEX128,
                 ADR, TSIZE, SIZE, ROTATE, SHIFT, THROW ;

CONST
  BITSPERBYTE   = __ATTRIBUTE__ __BUILTIN__ ((BITS_PER_UNIT)) ;
  BYTESPERWORD  = __ATTRIBUTE__ __BUILTIN__ ((UNITS_PER_WORD)) ;


(* all the following types are declared internally to gm2
TYPE
   LOC ;
   WORD ;
   BYTE ;
   ADDRESS ;
   BITSET ;
   INTEGER8 ;
   INTEGER16 ;
   INTEGER32 ;
   INTEGER64 ;
   CARDINAL8 ;
   CARDINAL16 ;
   CARDINAL32 ;
   CARDINAL64 ;
   WORD16 ;
   WORD32 ;
   WORD64 ;
   BITSET8 ;
   BITSET16 ;
   BITSET32 ;
   REAL32 ;
   REAL64 ;
   REAL96 ;
   REAL128 ;
   COMPLEX32 ;
   COMPLEX64 ;
   COMPLEX96 ;
   COMPLEX128 ;
*)


(*
   all the functions below are declared internally to gm2
   ====================================================

PROCEDURE ADR (VAR v: <anytype>): ADDRESS;
  (* Returns the address of variable v. *)

PROCEDURE SIZE (v: <type>) : ZType;
  (* Returns the number of BYTES used to store a v of
     any specified <type>.
  *)

PROCEDURE TSIZE (<type>) : CARDINAL;
  (* Returns the number of BYTES used to store a value of the
     specified <type>.
  *)

PROCEDURE ROTATE (val: <a set type>;
                  num: INTEGER): <type of first parameter>;
  (* Returns a bit sequence obtained from val by rotating up or down
     (left or right) by the absolute value of num.  The direction is
     down if the sign of num is negative, otherwise the direction is up.
  *)

PROCEDURE SHIFT (val: <a set type>;
                 num: INTEGER): <type of first parameter>;
  (* Returns a bit sequence obtained from val by shifting up or down
     (left or right) by the absolute value of num, introducing
     zeros as necessary.  The direction is down if the sign of
     num is negative, otherwise the direction is up.
  *)

PROCEDURE THROW (i: INTEGER) ;
  (*
     THROW is a GNU extension and was not part of the PIM or ISO
     standards.  It throws an exception which will be caught by the EXCEPT
     block (assuming it exists).  This is a compiler builtin function which
     interfaces to the GCC exception handling runtime system.
     GCC uses the term throw, hence the naming distinction between
     the GCC builtin and the Modula-2 runtime library procedure Raise.
     The later library procedure Raise will call SYSTEM.THROW after
     performing various housekeeping activities.
  *)
*)

(* The following procedures are invoked by GNU Modula-2 to
   shift non word sized set types. They are not strictly part
   of the core PIM Modula-2, however they are used by
   GNU Modula-2 to implement the SHIFT procedure defined above,
   which are in turn used by the Logitech compatible libraries.

   Users will access these procedures by using the procedure
   SHIFT above and GNU Modula-2 will map SHIFT onto one of
   the following procedures.
*)

(*
   ShiftVal - is a runtime procedure whose job is to implement
              the SHIFT procedure of ISO SYSTEM. GNU Modula-2 will
              inline a SHIFT of a single WORD sized set and will only
              call this routine for larger sets.
*)

PROCEDURE ShiftVal (VAR s, d: ARRAY OF BITSET;
                    SetSizeInBits: CARDINAL;
                    ShiftCount: INTEGER) ;


(*
   ShiftLeft - performs the shift left for a multi word set.
               This procedure might be called by the back end of
               GNU Modula-2 depending whether amount is known at compile
               time.
*)

PROCEDURE ShiftLeft (VAR s, d: ARRAY OF BITSET;
                     SetSizeInBits: CARDINAL;
                     ShiftCount: CARDINAL) ;

(*
   ShiftRight - performs the shift left for a multi word set.
                This procedure might be called by the back end of
                GNU Modula-2 depending whether amount is known at compile
                time.
*)

PROCEDURE ShiftRight (VAR s, d: ARRAY OF BITSET;
                     SetSizeInBits: CARDINAL;
                     ShiftCount: CARDINAL) ;


(*
   RotateVal - is a runtime procedure whose job is to implement
               the ROTATE procedure of ISO SYSTEM. GNU Modula-2 will
               inline a ROTATE of a single WORD (or less)
               sized set and will only call this routine for larger sets.
*)

PROCEDURE RotateVal (VAR s, d: ARRAY OF BITSET;
                     SetSizeInBits: CARDINAL;
                     RotateCount: INTEGER) ;


(*
   RotateLeft - performs the rotate left for a multi word set.
                This procedure might be called by the back end of
                GNU Modula-2 depending whether amount is known at compile
                time.
*)

PROCEDURE RotateLeft (VAR s, d: ARRAY OF BITSET;
                      SetSizeInBits: CARDINAL;
                      RotateCount: CARDINAL) ;


(*
   RotateRight - performs the rotate right for a multi word set.
                 This procedure might be called by the back end of
                 GNU Modula-2 depending whether amount is known at compile
                 time.
*)

PROCEDURE RotateRight (VAR s, d: ARRAY OF BITSET;
                       SetSizeInBits: CARDINAL;
                       RotateCount: CARDINAL) ;


END SYSTEM.

The different dialects of Modula-2 PIM-[234] and ISO Modula-2 declare the function SIZE in different places. PIM-[34] and ISO Modula-2 declare SIZE as a pervasive function (declared in the base module). PIM-2 defined SIZE in the SYSTEM module (as shown above).

GNU Modula-2 allows users to specify the dialect of Modula-2 by using the -fiso and -fpim2 command line switches.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.18 The ISO system module

 
DEFINITION MODULE SYSTEM;

  (* Gives access to system programming facilities that are probably
     non portable. *)

  (* The constants and types define underlying properties of storage *)

EXPORT QUALIFIED BITSPERLOC, LOCSPERWORD,
                 LOC, ADDRESS, BYTE, WORD, INTEGER8,
                 INTEGER16, INTEGER32, INTEGER64, CARDINAL8,
                 CARDINAL16, CARDINAL32, CARDINAL64, WORD16,
                 WORD32, WORD64, BITSET8, BITSET16,
                 BITSET32, REAL32, REAL64, REAL96,
                 REAL128, COMPLEX32, COMPLEX64, COMPLEX96,
                 COMPLEX128,
                 ADDADR, SUBADR, DIFADR, MAKEADR, ADR, ROTATE,
                 SHIFT, CAST, TSIZE,

                 (* Internal GM2 compiler functions *)
                 ShiftVal, ShiftLeft, ShiftRight,
                 RotateVal, RotateLeft, RotateRight,
                 THROW ;

CONST
                  (* <implementation-defined constant> ; *)
  BITSPERLOC    = __ATTRIBUTE__ __BUILTIN__ ((BITS_PER_UNIT)) ;
                  (* <implementation-defined constant> ; *)
  LOCSPERWORD   = __ATTRIBUTE__ __BUILTIN__ ((UNITS_PER_WORD)) ;
                  (* <implementation-defined constant> ; *)
  LOCSPERBYTE = 8 DIV BITSPERLOC ;

(*
   all the objects below are declared internally to gm2
   ====================================================

TYPE
   LOC ;
   ADDRESS ;
   BYTE ;
   WORD ;
   INTEGER8 ;
   INTEGER16 ;
   INTEGER32 ;
   INTEGER64 ;
   CARDINAL8 ;
   CARDINAL16 ;
   CARDINAL32 ;
   CARDINAL64 ;
   WORD16 ;
   WORD32 ;
   WORD64 ;
   BITSET8 ;
   BITSET16 ;
   BITSET32 ;
   REAL32 ;
   REAL64 ;
   REAL96 ;
   REAL128 ;
   COMPLEX32 ;
   COMPLEX64 ;
   COMPLEX96 ;
   COMPLEX128 ;

TYPE
  LOC; (* A system basic type. Values are the uninterpreted
          contents of the smallest addressable unit of storage *)
  ADDRESS = POINTER TO LOC;
  WORD = ARRAY [0 .. LOCSPERWORD-1] OF LOC;

  (* BYTE and LOCSPERBYTE are provided if appropriate for machine *)

TYPE
  BYTE = ARRAY [0 .. LOCSPERBYTE-1] OF LOC;

PROCEDURE ADDADR (addr: ADDRESS; offset: CARDINAL): ADDRESS;
  (* Returns address given by (addr + offset), or may raise
     an exception if this address is not valid.
  *)

PROCEDURE SUBADR (addr: ADDRESS; offset: CARDINAL): ADDRESS;
  (* Returns address given by (addr - offset), or may raise an
     exception if this address is not valid.
  *)

PROCEDURE DIFADR (addr1, addr2: ADDRESS): INTEGER;
  (* Returns the difference between addresses (addr1 - addr2),
     or may raise an exception if the arguments are invalid
     or address space is non-contiguous.
  *)

PROCEDURE MAKEADR (high: <some type>; ...): ADDRESS;
  (* Returns an address constructed from a list of values whose
     types are implementation-defined, or may raise an
     exception if this address is not valid.

     In GNU Modula-2, MAKEADR can take any number of arguments
     which are mapped onto the type ADDRESS. The first parameter
     maps onto the high address bits and subsequent parameters map
     onto lower address bits. For example:

     a := MAKEADR(BYTE(0FEH), BYTE(0DCH), BYTE(0BAH), BYTE(098H),
                  BYTE(076H), BYTE(054H), BYTE(032H), BYTE(010H)) ;

     then the value of, a, on a 64 bit machine is: 0FEDCBA9876543210H

     The parameters do not have to have the same type, but constants
     _must_ be typed.
  *)

PROCEDURE ADR (VAR v: <anytype>): ADDRESS;
  (* Returns the address of variable v. *)

PROCEDURE ROTATE (val: <a packedset type>;
                  num: INTEGER): <type of first parameter>;
  (* Returns a bit sequence obtained from val by rotating up or down
     (left or right) by the absolute value of num.  The direction is
     down if the sign of num is negative, otherwise the direction is up.
  *)

PROCEDURE SHIFT (val: <a packedset type>;
                 num: INTEGER): <type of first parameter>;
  (* Returns a bit sequence obtained from val by shifting up or down
     (left or right) by the absolute value of num, introducing
     zeros as necessary.  The direction is down if the sign of
     num is negative, otherwise the direction is up.
  *)

PROCEDURE CAST (<targettype>; val: <anytype>): <targettype>;
  (* CAST is a type transfer function.  Given the expression
     denoted by val, it returns a value of the type <targettype>.
     An invalid value for the target value or a
     physical address alignment problem may raise an exception.
  *)

PROCEDURE TSIZE (<type>; ... ): CARDINAL;
  (* Returns the number of LOCS used to store a value of the
     specified <type>.   The extra parameters, if present,
     are used to distinguish variants in a variant record.
  *)
PROCEDURE THROW (i: INTEGER) ;
  (*
     THROW is a GNU extension and was not part of the PIM or ISO
     standards.  It throws an exception which will be caught by the EXCEPT
     block (assuming it exists).  This is a compiler builtin function which
     interfaces to the GCC exception handling runtime system.
     GCC uses the term throw, hence the naming distinction between
     the GCC builtin and the Modula-2 runtime library procedure Raise.
     The later library procedure Raise will call SYSTEM.THROW after
     performing various housekeeping activities.
  *)
*)


(* The following procedures are invoked by GNU Modula-2 to
   shift non word set types. They are not part of ISO Modula-2
   but are used by GNU Modula-2 to implement the SHIFT procedure
   defined above. *)

(*
   ShiftVal - is a runtime procedure whose job is to implement
              the SHIFT procedure of ISO SYSTEM. GNU Modula-2 will
              inline a SHIFT of a single WORD sized set and will only
              call this routine for larger sets.
*)

PROCEDURE ShiftVal (VAR s, d: ARRAY OF BITSET;
                    SetSizeInBits: CARDINAL;
                    ShiftCount: INTEGER) ;


(*
   ShiftLeft - performs the shift left for a multi word set.
               This procedure might be called by the back end of
               GNU Modula-2 depending whether amount is known at compile
               time.
*)

PROCEDURE ShiftLeft (VAR s, d: ARRAY OF BITSET;
                     SetSizeInBits: CARDINAL;
                     ShiftCount: CARDINAL) ;

(*
   ShiftRight - performs the shift left for a multi word set.
                This procedure might be called by the back end of
                GNU Modula-2 depending whether amount is known at compile
                time.
*)

PROCEDURE ShiftRight (VAR s, d: ARRAY OF BITSET;
                     SetSizeInBits: CARDINAL;
                     ShiftCount: CARDINAL) ;


(*
   RotateVal - is a runtime procedure whose job is to implement
               the ROTATE procedure of ISO SYSTEM. GNU Modula-2 will
               inline a ROTATE of a single WORD (or less)
               sized set and will only call this routine for larger sets.
*)

PROCEDURE RotateVal (VAR s, d: ARRAY OF BITSET;
                     SetSizeInBits: CARDINAL;
                     RotateCount: INTEGER) ;


(*
   RotateLeft - performs the rotate left for a multi word set.
                This procedure might be called by the back end of
                GNU Modula-2 depending whether amount is known at compile
                time.
*)

PROCEDURE RotateLeft (VAR s, d: ARRAY OF BITSET;
                      SetSizeInBits: CARDINAL;
                      RotateCount: CARDINAL) ;


(*
   RotateRight - performs the rotate right for a multi word set.
                 This procedure might be called by the back end of
                 GNU Modula-2 depending whether amount is known at compile
                 time.
*)

PROCEDURE RotateRight (VAR s, d: ARRAY OF BITSET;
                       SetSizeInBits: CARDINAL;
                       RotateCount: CARDINAL) ;


END SYSTEM.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2. Obtaining GNU Modula-2.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.1 Warning

This code is currently in development and it is not yet complete. Nevertheless the compiler is sufficiently stable to support itself on Debian GNU/Linux x86 systems. The PIM libraries are complete but the ISO libraries and ISO language features are still in development. Patches and development volunteers highly welcome! See section Contributing to GNU Modula-2.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.2 Getting GNU Modula-2

The easiest way to obtain GNU Modula-2 is to install i386, amd64 or ppc64 Debian GNU/Linux and then add these repository descriptions to your `/etc/apt/sources.list' file.

 
#
#  GNU Modula-2 repo
#

deb http://floppsie.comp.glam.ac.uk/debian/ etch main non-free contrib
deb-src http://floppsie.comp.glam.ac.uk/debian/ etch main non-free contrib

Now as root type:

 
$ apt-get update
$ apt-get install gm2-doc gm2

As a normal user you can obtain the source code via:

 
$ apt-get source gm2

If you are not running Debian GNU/Linux then you can either download the source tarball and build it manually or checkout the latest sources using CVS and combine them with the appropriate gcc tarball and then finally build it manually.

Combined GNU Modula-2 and patched GCC tarballs exist at http://floppsie.comp.glam.ac.uk/pub/c. Search for files which look like `gm2+gcc-version.tar.gz'. For example you should be able to download the latest version of GNU Modula-2 and GCC using these commands.

 
$ wget http://floppsie.comp.glam.ac.uk/download/c/gcc-4.1.2+gm2-cvs-latest.tar.gz
$ tar zxf gcc-4.1.2+gm2-cvs-latest.tar.gz

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.3 Building GNU Modula-2 from source under GNU/Linux

On a GNU/Linux system you should also be able to build it using these commands. The following commands assume your shell is `/bin/bash'. To build GNU Modula-2 type:

 
$ mkdir -p $HOME/opt
$ mkdir -p build-4.1.2
$ cd build-4.1.2
$ ../gcc-4.1.2+gm2-cvs-latest/configure --enable-languages=c,c++,gm2 \
     --disable-multilib --enable-checking=all --prefix=$HOME/opt
$ make "SHELL=/bin/bash"

To install GNU Modula-2, after a successful build, type:

 
$ make "SHELL=/bin/bash" install
$ cd ..

Now you should be able to perform:

 
$ export PATH=$HOME/opt/bin:$PATH
$ cd gcc-4.1.2/gcc/gm2/examples/hello
$ make

which will create an `a.out' for the infamous hello world example.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.4 Development sources via CVS

Development sources can be downloaded via CVS but they must be grafted carefully onto an existing GCC release. The notes in this section document how this is achieved, however a prepared CVS and GCC release is available here http://floppsie.comp.glam.ac.uk/download/c/gcc-4.1.2+gm2-cvs-latest.tar.gz and it is created each night.

If you want to obtain the latest sources via CVS then type the following:

 
$ cvs -z3 -d:pserver:anoncvs@cvs.sv.gnu.org:/sources/gm2 co gm2

This will checkout a copy of GNU Modula-2 into one subdirectory, `gm2'. This version of GNU Modula-2 needs to be placed inside the GCC source tree in the position gcc-4.1.2/gcc before GNU Modula-2 can be built. Please check the GNU Modula-2 homepage http://www.nongnu.org/gm2 for details about which GCC releases are supported by GNU Modula-2.

Once you have downloaded the correct GCC release from http://gcc.gnu.org or a mirror site you should unpack the GCC archive. Assuming that both the `gcc-4.1.2' and `gm2' directories are at the same level, you can graft `gm2' onto `gcc-4.1.2' by:

 
$ mv gm2 gcc-4.1.2/gcc

If the directory `gcc-4.1.2/gcc/gm2/patches/gcc/4.1.2' exists then the patch files inside that directory can be applied to the `gcc-4.1.2' tree. This is done via:

 
$ cd gcc-4.1.2
$ if [ -d gcc/gm2/patches/gcc/4.1.2 ] ; then
     for i in gcc/gm2/patches/gcc/4.1.2/* ; do
        if [ -f $i ] ; then
           patch -p1 < $i
        fi
     done
  fi

Note that if you download a tarball from http://floppsie.comp.glam.ac.uk then any patching will have already been applied. See section Obtaining GNU Modula-2..


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.5 Stress testing GM2

Currently there are two automated methods to test GNU Modula-2. The first method is `make gm2.paranoid' in which gm2 builds itself and finally the test runs both parent and child generations of the compiler and compares the output. Be warned that this test can take some time to execute. This test is invoked by:

 
$ cd host-build/gcc ; make gm2.paranoid

The second method used to test GNU Modula-2 is to run the regression test suite. The GNU Modula-2 regression test suite is available for download. To install and run the GNU Modula-2 regression suite you need to have installed the `dejagnu' and `expect' packages. Note that you need to ensure that you have at least the following releases of dejagnu components:

 
$ runtest --version

Expect version is	5.42.1
Tcl version is		8.4
Framework version is	1.4.4

otherwise some of the tests may not run.

If you have downloaded the combined GCC and GNU Modula-2 tarball http://floppsie.comp.glam.ac.uk/download/c/gcc-4.1.2+gm2-cvs-latest.tar.gz then this will also contain the GNU Modula-2 testsuite. In this case you can skip over the following `cvs' and `tar' commands.

However if you have downloaded GNU Modula-2 using CVS then you will also need to download and position the testsuite. Assuming that the root of the GCC source tree is in the current working directory you can use the following commands to install the test suite:

 
$ cvs -z3 -d:pserver:anoncvs@cvs.sv.gnu.org:/sources/gm2 co testsuite
$ tar cf - testsuite | ( cd gcc-version/gcc ; tar xf - )

Do not simply move the directory `testsuite' into `gcc-version/gcc' as the GNU Modula-2 regression tests have to be overlaid on top of the gcc testsuite.

Thereafter you can run the GNU Modula-2 testsuite by:

 
$ cd host-build/gcc
$ make check-gm2

Depending on the speed of your computer these tests may take a while to complete.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.6 Building GNU Modula-2 under Cygwin

GNU Modula-2 now builds under Cygwin. The Cygwin version used was gcc version 3.4.4, gdc 0.12 using dmd 0.125. The following set of commands were used to build GNU Modula-2.

 
$ mkdir build
$ cd build
$ ../gcc-4.1.2+gm2-cvs-latest/configure --prefix=/gm2/opt \
  --disable-multilib --enable-checking=all \
  --enable-languages=c,c++,gm2
$ make

GNU Modula-2 can be installed by:

 
$ make install

You now need to modify your path to include `gm2'. This is done by:

 
$ export PATH=/gm2/opt/bin:$PATH

and now you can try out the hello world example:

 
$ cd ../gcc-4.1.2/gcc/gm2/examples/hello
$ make
$ ./a.exe

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.7 Moving the installation of GNU Modula-2 to another directory

This section documents how you can configure GNU Modula-2 to install in one directory and at a later time move the installation to another completely different directory. The example assumes the user has a bourne shell.

Let us assume that the build was configured as such:

 
$ mkdir build
$ cd build
$ ../gcc-4.1.2+gm2-cvs-latest/configure \
   --prefix=$HOME/private \
   --enable-languages=c,c++,gm2  --enable-checking \
   --disable-multilib

in this example we see that the installation directory would normally be `$HOME/private'. This is accomplished by the following commands:

 
$ make
$ make install

Now, assuming we have correct privileges, we may move the entire contents of `$HOME/private' to `/usr/local/public':

 
$ mv $HOME/private /usr/local/public

The new compiler and libraries can be referenced by modifying our PATH environment variable:

 
$ PATH=/usr/local/public/bin:$PATH
$ export PATH
$ GM2_ROOT=/usr/local/public
$ export GM2_ROOT

Finally we can rebuild the hello world example found in `../gcc-4.1.2/gcc/gm2/examples/hello' by:

 
$ cd ../gcc-4.1.2/gcc/gm2/examples/hello
$ make
$ ./a.out

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.8 Building GNU Modula-2 under FreeBSD

[This section is out of date and has not been verified against gcc-4.1.2 and GNU Modula-2 release gm2-0.68].

When building GNU Modula-2 under FreeBSD, there are essentially three issues that need to be addressed.

The first, is the system shell, `/bin/sh'. GNU Modula-2's build script uses some `bash' constructs that are not understood by `sh'. Therefore `bash' must be installed and this can be obtained from the ports package collection (ports:shells/bash).

The second, is the compiler used to bootstrap GNU Modula-2. On FreeBSD4.x the system compiler is from the 2.95.x generation, and should work without problems. On 5-RELEASE and 6-CURRENT, the system compiler is from the 3.4.x generation or greater, and it is known to create a faulty GNU Modula-2 compiler. Therefore you will need to install an earlier gcc on your machine. Known to work are gcc 3.2.3 (ports:lang/gcc32), gcc 3.3.4, 3.3.5 and 3.3.6 (ports:lang/gcc33).

Finally, `gmake' is required.

It is recommended that the same options are used to configure GNU Modula-2 as those suggested in the ports collection. A number of options are not relevant for building GNU Modula-2 and these can be safely omitted. The only two which apply directly to GNU Modula-2's build process are --with-system-zlib and --disable-nls.

The example below assumes that gcc-3.2.3 is installed (from the ports collection) and the compiler is called `gcc32'. The example assumes that the bash shell has been installed (as described above).

 
  mkdir host-build
  cd host-build
  env CONFIG_SHELL=/usr/local/bin/bash CC=gcc32 ../gcc-version/configure
      --with-system-zlib --disable-nls --enable-languages=c,c++,gm2
  gmake

If you choose to install the generated compiler, you are urged to make use of the name rewriting options of configure (--program-prefix and --program-suffix work fine), and to avoid possible conflicts with a port that installs it's own gcc, you may also want to add --host. Here is the author of this section's full configure line:

 
  env CONFIG_SHELL=/usr/local/bin/bash CC=gcc32 ../gcc-version/configure
      --with-system-zlib --disable-nls --enable-languages=c,c++,gm2
      --program-prefix=m2 --host=i386-gm2bld-freebsd5.3

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.9 Licence of GNU Modula-2


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

GNU GENERAL PUBLIC LICENSE

Version 2, June 1991

 
Copyright © 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

Preamble

The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.

To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.

For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.

We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.

Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.

Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.

The precise terms and conditions for copying, distribution and modification follow.

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  1. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".

    Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.

  2. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.

    You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.

  3. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
    1. You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
    2. You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
    3. If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)

    These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

    Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.

    In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

  4. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
    1. Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
    2. Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
    3. Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)

    The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.

    If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.

  5. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
  6. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
  7. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
  8. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.

    If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.

    It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.

    This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.

  9. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
  10. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

    Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.

  11. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

    NO WARRANTY

  12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

END OF TERMS AND CONDITIONS


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.

 
one line to give the program's name and a brief idea of what it does.
Copyright (C) year  name of author

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this when it starts in an interactive mode:

 
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:

 
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.

signature of Ty Coon, 1 April 1989
Ty Coon, President of Vice

This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

The GNU Project and GNU/Linux

The GNU Project was launched in 1984 to develop a complete Unix-like operating system which is free software: the GNU system. (GNU is a recursive acronym for "GNU's Not Unix"; it is pronounced "guh-NEW".) Variants of the GNU operating system, which use the kernel Linux, are now widely used; though these systems are often referred to as "Linux", they are more accurately called GNU/Linux systems.

For more information, see:

 
http://www.gnu.org/
http://www.gnu.org/gnu/linux-and-gnu.html

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.1 Contributing to GNU Modula-2

Please do. But also please read the GNU Emacs info under

 
* Standards: (standards).       GNU coding standards.
* Intellectual Property::       Keeping Free Software Free
* Reading Non-Free Code::       Referring to Proprietary Programs
* Contributions::               Accepting Contributions

You might consider joining the GM2 Mailing list available via a web brouser at

http://lists.nongnu.org/mailman/listinfo/gm2 available via email: mail:gm2-subscribe@nongnu.org before you start coding.

Many thanks and enjoy your coding!


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3. GNU Modula-2 Internals

This document is a small step in the long journey of documenting the GNU Modula-2 compiler and how it integrates with GCC. The document is still in it's infancy.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.1 History

The Modula-2 compiler sources have come from the m2f compiler which runs under GNU/Linux. The original m2f compiler was written in Modula-2 and was bootstrapped via a modified version of p2c 1.20. The m2f compiler was a recursive descent which generated quadruples as intermediate code. It also used C style calling convention wherever possible and utilized a C structure for dynamic arrays.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.2 Overview

GNU Modula-2 uses flex and a machine generated recursive descent parser. Most of the source code is written in Modula-2 and bootstrapping is achieved via a modified version of p2c-1.20. The modified p2c-1.20 is contained in the GNU Modula-2 source tree as are a number of other tools necessary for bootstrapping.

The changes to p2c include:

GNU Modula-2 comes with PIM and ISO style libraries. The compiler is built using PIM libraries and the source of the compiler complies with the PIM dialect together with a few C library calling extensions.

The compiler is a four pass compiler. The first pass tokenizes the source code, creates scope and enumeration type symbols. All tokens are placed into a dynamic buffer and subsequent passes reread tokens and build types, quadruples and resolve hidden types. See section Passes.

GNU Modula-2 uses a technique of double book keeping (2). See (gcc)Back end Access to Symbol Table. The front end builds a complete symbol table and a list of quadruples. Each symbol is translated into a gcc equivalent after which each quadruple is translated into a gcc tree.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.3 How the front end integrates with gcc

The M2Base and M2System modules contain base types and system types respectively they map onto GCC back-end data types.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.4 Passes

This section describes the general actions of each pass. The key to building up the symbol table correctly is to ensure that the symbols are only created in the scope where they were declared. This may seem obvious (and easy) but it is complicated by two issues: firstly GNU Modula-2 does not generate .sym files and so all imported definition modules are parsed after the module is parsed; secondly the import/export rules might mean that you can see and use a symbol before it is declared in a completely different scope.

Here is a brief description of the lists of symbols maintained within DefImp and Module symbols. It is these lists and actions at each pass which manipulate these lists which solve the scoping and visability of all symbols.

The DefImp symbol maintains the: ExportQualified, ExportUnQualified, ExportRequest, IncludeList, ImportTree, ExportUndeclared, NeedToBeImplemented, LocalSymbols, EnumerationScopeList, Unresolved, ListOfVars, ListOfProcs and ListOfModules lists.

The Module symbol maintains the: LocalSymbols, ExportTree, IncludeList, ImportTree, ExportUndeclared, EnumerationScopeList, Unresolved, ListOfVars, ListOfProcs and ListOfModules lists.

Initially we discuss the lists which are common to both DefImp and Module symbols, thereafter the lists peculiar to DefImp and Module symbols are discussed.

The ListOfVars, ListOfProcs and ListOfModules lists (common to both symbols) and simply contain a list of variables, procedures and inner modules which are declared with this definition/implementation or program module.

The LocalSymbols list (common to both symbols) contains a complete list of symbols visible in this modules scope. The symbols in this list may have been imported or exported from an inner module.

The EnumerationScope list (common to both symbols) defines all visible enumeration symbols. When this module is parsed the contents of these enumeration types are marked as visible. Internally to GNU Modula-2 these form a pseudo scope (rather like a WITH statement which temporarily makes the fields of the record visible).

The ExportUndeclared list (common to both symbols) contains a list of all symbols marked as exported but are as yet undeclared.

The IncludeList is (common to both symbols) contains a list of all modules imported by the IMPORT modulename ; construct.

The ImportTree (common to both symbols) contains a tree of all imported identifiers.

The ExportQualified and ExportUnQualified trees (only present in the DefImp symbol) contain identifiers which are marked as EXPORT QUALIFIED and EXPORT UNQUALIFIED respectively.

The NeedToBeImplemented list (only present in the DefImp symbol) and contains a list of all unresolved symbols which are exported.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.4.1 Pass 1

During pass 1 each DefImp and Module symbol is created. These are also placed into a list of outstanding sources to be parsed. The import and export lists are recorded and each object imported is created in the module from whence it is exported and added into the imported list of the current module. Any exported objects are placed into the export list and marked as qualified or unqualified.

Inner module symbols are also created and their import and export lists are also processed. An import list will result in a symbol being fetched (or created if it does not exist) from the outer scope and placed into the scope of the inner module. An export list results in each symbol being fetched or created in the current inner scope and added to the outer scope. If the symbol has not yet been declared then it is added to the current modules ExportUndeclared list.

Procedure symbols are created (the parameters are parsed but no more symbols are created). Enumerated types are created, hidden types in the definition modules are marked as such. All the rest of the Modula-2 syntax is parsed but no symbols are created.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.4.2 Pass 2

This section discuss varient records and their representation within the front end `gm2/gm2-compiler/SymbolTable.mod'. Records and varient records are declared in pass 2.

Ordinary records are represented by the following symbol table entries:

 
TYPE
   this = RECORD
             foo: CARDINAL ;
             bar: CHAR ;
          END ;


    SymRecord [1]
   +-------------+
   | Name = this |        SymRecordField [2]
   | ListOfSons  |       +-------------------+
   |    +--------|       | Name = foo        |
   |    | [2] [3]|       | Parent = [1]      |
   +-------------+       | Type = [Cardinal] |
   | LocalSymbols|       +-------------------+
   | +-----------+
   | | foo bar   |
   | +-----------+
   +-------------+


    SymRecordField [3]
   +-------------------+
   | Name = bar        |
   | Parent = [1]      |
   | Type = [Cardinal] |
   +-------------------+

Whereas varient records are represented by the following symbol table entries:

 
TYPE
   this = RECORD
             CASE tag: CHAR OF
             'a': foo: CARDINAL ;
                  bar: CHAR |
             'b': an:  REAL |
             ELSE
             END
          END ;


    SymRecord [1]
   +-------------+
   | Name = this |        SymRecordField [2]
   | ListOfSons  |       +-------------------+
   |    +--------|       | Name = tag        |
   |    | [2] [3]|       | Parent = [1]      |
   |    +--------+       | Type = [CHAR]     |
   | LocalSymbols|       +-------------------+
   | +-----------+
   | | tag foo   |
   | | bar an    |
   | +-----------+
   +-------------+

    SymVarient [3]          SymFieldVarient [4]
   +-------------------+   +-------------------+
   | Parent = [1]      |   | Parent = [1]      |
   | ListOfSons        |   | ListOfSons        |  
   |    +--------------|   |    +--------------|
   |    | [4] [5]      |   |    | [6] [7]      |
   +-------------------+   +-------------------+

    SymFieldVarient [5]
   +-------------------+
   | Parent = [1]      |
   | ListOfSons        |  
   |    +--------------|
   |    | [8]          |
   +-------------------+

    SymRecordField [6]      SymRecordField [7]
   +-------------------+   +-------------------+
   | Name = foo        |   | Name = bar        |
   | Parent = [1]      |   | Parent = [1]      |
   | Type = [CARDINAL] |   | Type = [CHAR]     |
   +-------------------+   +-------------------+

    SymRecordField [8]
   +-------------------+
   | Name = an         |
   | Parent = [1]      |
   | Type = [REAL]     |
   +-------------------+

Varient records which have nested CASE statements are represented by the following symbol table entries:

 
TYPE
   this = RECORD
             CASE tag: CHAR OF
             'a': foo: CARDINAL ;
                  CASE bar: BOOLEAN OF
                  TRUE : bt: INTEGER |
                  FALSE: bf: CARDINAL
                  END |
             'b': an:  REAL |
             ELSE
             END
          END ;


    SymRecord [1]
   +-------------+
   | Name = this |        SymRecordField [2]
   | ListOfSons  |       +-------------------+
   |    +--------|       | Name = tag        |
   |    | [2] [3]|       | Parent = [1]      |
   |    +--------+       | Type = [CHAR]     |
   | LocalSymbols|       +-------------------+
   | +-----------+
   | | tag foo   |
   | | bar bt bf |
   | | an        |
   | +-----------+
   +-------------+

      ('1st CASE')            ('a' selector)
    SymVarient [3]          SymFieldVarient [4]
   +-------------------+   +-------------------+
   | Parent = [1]      |   | Parent = [1]      |
   | ListOfSons        |   | ListOfSons        |  
   |    +--------------|   |    +--------------|
   |    | [4] [5]      |   |    | [6] [7] [8]  |
   +-------------------+   +-------------------+

     ('b' selector)
    SymFieldVarient [5]
   +-------------------+
   | Parent = [1]      |
   | ListOfSons        |  
   |    +--------------|
   |    | [9]          |
   +-------------------+

    SymRecordField [6]      SymRecordField [7]
   +-------------------+   +-------------------+
   | Name = foo        |   | Name = bar        |
   | Parent = [1]      |   | Parent = [1]      |
   | Type = [CARDINAL] |   | Type = [BOOLEAN]  |
   +-------------------+   +-------------------+

      ('2nd CASE')
    SymVarient [8]
   +-------------------+
   | Parent = [1]      |
   | ListOfSons        |
   |    +--------------|
   |    | [12] [13]    |
   +-------------------+

    SymRecordField [9]
   +-------------------+
   | Name = an         |
   | Parent = [1]      |
   | Type = [REAL]     |
   +-------------------+

    SymRecordField [10]     SymRecordField [11]
   +-------------------+   +-------------------+
   | Name = bt         |   | Name = bf         |
   | Parent = [1]      |   | Parent = [1]      |
   | Type = [REAL]     |   | Type = [REAL]     |
   +-------------------+   +-------------------+

    (TRUE selector)            (FALSE selector)
    SymFieldVarient [12]    SymFieldVarient [13]
   +-------------------+   +-------------------+
   | Parent = [1]      |   | Parent = [1]      |
   | ListOfSons        |   | ListOfSons        |
   |    +--------------|   |    +--------------|
   |    | [10]         |   |    | [11]         |
   +-------------------+   +-------------------+

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.4.3 Pass 3

To do


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.4.4 Pass H

To do


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.4.5 Declaration ordering

This section gives a few stress testing examples and walks though the mechanics of the passes and how the lists of symbols are created.

The first example contains a nested module in which an enumeration type is created and exported. A procedure declared before the nested module uses the enumeration type.

 
MODULE colour ;

   PROCEDURE make (VAR c: colours) ;
   BEGIN
      c := yellow
   END make ;

   MODULE inner ;
   EXPORT colours ;

   TYPE
      colours = (red, blue, yellow, white) ;
   END inner ;

VAR
   g: colours
BEGIN
   make(g)
END colour.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.5 Run time

This section describes how the GNU Modula-2 compiler interfaces with the run time system. The modules which must be common to all library collections are M2RTS and SYSTEM. In the PIM library collection an implementation of M2RTS and SYSTEM exist; likewise in the ISO library and ULM library collection these modules also exist.

The M2RTS module contains many of the base runtime features required by the GNU Modula-2 compiler. For example M2RTS contains the all the low level exception handling routines. These include exception handlers for run time range checks for: assignments, increments, decrements, static array access, dynamic array access, for loop begin, for loop to, for loop increment, pointer via nil, function without return, case value not specified and no exception. The M2RTS module also contains the HALT and LENGTH procedure. The ISO SYSTEM module contains a number of SHIFT and ROTATE procedures which GNU Modula-2 will call when wishing to shift and rotate multi-word set types.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.5.1 Exception handling

This section describes how exception handling is implemented in GNU Modula-2. We begin by including a simple Modula-2 program which uses exception handling and provide the same program written in C++. The compiler will translate the Modula-2 into the equivalent trees, just like the C++ frontend. This ensures that the Modula-2 frontend will not do anything that the middle and backend cannot process, which ensures that migration through the later gcc releases will be smooth.

Here is an example of Modula-2 using exception handling:

 
MODULE except ;

FROM libc IMPORT printf ;
FROM Storage IMPORT ALLOCATE, DEALLOCATE ;

PROCEDURE fly ;
BEGIN
   printf("fly main body\n") ;
   IF 4 DIV ip^ = 4
   THEN
      printf("yes it worked\n")
   ELSE
      printf("no it failed\n")
   END
END fly ;

PROCEDURE tryFlying ;
BEGIN
   printf("tryFlying main body\n");  
   fly ;
EXCEPT
   printf("inside tryFlying exception routine\n") ;
   IF (ip#NIL) AND (ip^=0)
   THEN
      ip^ := 1 ;
      RETRY
   END
END tryFlying ;

PROCEDURE keepFlying ;
BEGIN
   printf("keepFlying main body\n") ;
   tryFlying ;
EXCEPT
   printf("inside keepFlying exception routine\n") ;
   IF ip=NIL
   THEN
      NEW(ip) ;
      ip^ := 0 ;
      RETRY
   END
END keepFlying ;

VAR
   ip: POINTER TO INTEGER ;
BEGIN
   ip := NIL ;
   keepFlying ;
   printf("all done\n")
END except.

Now the same program implemented in GNU C++

 
#include <stdio.h>
#include <stdlib.h>

// a c++ example of Modula-2 exception handling

static int *ip = NULL;

void fly (void)
{
  printf("fly main body\n") ;
  if (ip == NULL)
    throw;
  if (*ip == 0)
    throw;
  if (4 / (*ip) == 4)
    printf("yes it worked\n");
  else
    printf("no it failed\n");
}

/*
 *   a C++ version of the Modula-2 example given in the ISO standard.
 */

void tryFlying (void)
{
 again_tryFlying:
  printf("tryFlying main body\n");  
  try {
    fly() ;
  }
  catch (...) {
    printf("inside tryFlying exception routine\n") ;
    if ((ip != NULL) && ((*ip) == 0)) {
      *ip = 1;
      // retry
      goto again_tryFlying;
    }
    printf("did't handle exception here so we will call the next exception routine\n") ;
    throw;  // unhandled therefore call previous exception handler
  }
}

void keepFlying (void)
{
 again_keepFlying:
  printf("keepFlying main body\n") ;
  try {
    tryFlying();
  }
  catch (...) {
    printf("inside keepFlying exception routine\n");
    if (ip == NULL) {
      ip = (int *)malloc(sizeof(int));
      *ip = 0;
      goto again_keepFlying;
    }
    throw;  // unhandled therefore call previous exception handler
  }
}

main ()
{
  keepFlying();
  printf("all done\n");
}

The equivalent program in GNU C is given below. However the use of setjmp and longjmp in creating an exception handler mechanism is not used used by GNU C++ and GNU Java. The GNU exception handling ABI uses TRY_CATCH_EXPR tree nodes. Thus GNU Modula-2 generates trees which model the C++ code above, rather than the C code shown below. The code here serves as a mental model (for readers who are familiar with C but not of C++) of what is happening in the C++ code above.

 
#include <setjmp.h>
#include <malloc.h>
#include <stdio.h>

typedef enum jmpstatus {
  jmp_normal,
  jmp_retry,
  jmp_exception,
} jmp_status;

struct setjmp_stack {
  jmp_buf  env;
  struct setjmp_stack *next;
} *head = NULL;

void pushsetjmp (void)
{
  struct setjmp_stack *p = (struct setjmp_stack *)
                           malloc (sizeof (struct setjmp_stack));

  p->next = head;
  head = p;
}

void exception (void)
{
  printf("invoking exception handler\n");
  longjmp (head->env, jmp_exception);
}

void retry (void)
{
  printf("retry\n");
  longjmp (head->env, jmp_retry);
}

void popsetjmp (void)
{
  struct setjmp_stack *p = head;

  head = head->next;
  free (p);
}

static int *ip = NULL;

void fly (void)
{
  printf("fly main body\n");
  if (ip == NULL) {
    printf("ip == NULL\n");
    exception();
  }
  if ((*ip) == 0) {
    printf("*ip == 0\n");
    exception();
  }
  if ((4 / (*ip)) == 4)
    printf("yes it worked\n");
  else
    printf("no it failed\n");
}

void tryFlying (void)
{
  void tryFlying_m2_exception () {
    printf("inside tryFlying exception routine\n");
    if ((ip != NULL) && ((*ip) == 0)) {
      (*ip) = 1;
      retry();
    }
  }

  int t;

  pushsetjmp ();
  do {
    t = setjmp (head->env);
  } while (t == jmp_retry);

  if (t == jmp_exception) {
    /* exception called */
    tryFlying_m2_exception ();
    /* exception has not been handled, invoke previous handler */
    printf("exception not handled here\n");
    popsetjmp();
    exception();
  }

  printf("tryFlying main body\n");  
  fly();
  popsetjmp();
}

void keepFlying (void)
{
  void keepFlying_m2_exception () {
    printf("inside keepFlying exception routine\n");
    if (ip == NULL) {
      ip = (int *)malloc (sizeof (int));
      *ip = 0;
      retry();
    }
  }
  int t;

  pushsetjmp ();
  do {
    t = setjmp (head->env);
  } while (t == jmp_retry);
  
  if (t == jmp_exception) {
    /* exception called */
    keepFlying_m2_exception ();
    /* exception has not been handled, invoke previous handler */
    popsetjmp();
    exception();
  }
  printf("keepFlying main body\n");
  tryFlying();
  popsetjmp();
}

main ()
{
  keepFlying();
  printf("all done\n");
}

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.6 Scope rules

This section describes my understanding of the Modula-2 scope rules with respect to enumerated types. If they are incorrect please correct me by email gaius@gnu.org. They also serve to document the behaviour of GNU Modula-2 in these cirumstances.

In GNU Modula-2 the syntax for a type declaration is defined as:

 
TypeDeclaration := Ident "=" Type =:

Type :=  SimpleType | ArrayType
          | RecordType          
          | SetType             
          | PointerType         
          | ProcedureType
      =:								   
									   
SimpleType := Qualident | Enumeration | SubrangeType =:

If the TypeDeclaration rule is satisfied by SimpleType and Qualident ie:

 
TYPE
   foo = bar ;

then foo is said to be equivalent to bar. Thus variables, parameters and record fields declared with either type will be compatible with each other.

If, however, the TypeDeclaration rule is satisfied by any alternative clause ArrayType, RecordType, SetType, PointerType, ProcedureType, Enumeration or SubrangeType then in these cases a new type is created which is distinct from all other types. It will be incompatible with all other user defined types.

It also has furthur consequences in that if bar was defined as an enumerated type and foo is imported by another module then the enumerated values are also visible in this module.

Consider the following modules:

 
DEFINITION MODULE impc ;

TYPE
   C = (red, blue, green) ;

END impc.
 
DEFINITION MODULE impb ;

IMPORT impc ;

TYPE
   C = impc.C ;

END impb.
 
MODULE impa ;

FROM impb IMPORT C ;

VAR
   a: C ;
BEGIN
   a := red
END impa.

Here we see that the type C defined in module impb is equivalent to the type C in module impc. Module impa imports the type C from module impb and at that point the enumeration values red, blue, green (declared in module impc) are also visible.

The ISO Standand (p.41) in section 6.1.8 Import Lists states:

"Following the module heading, a module may have a sequence of import lists. An import list includes a list of the identifiers that are to be explicitly imported into the module. Explicit import of an enumeration type identifier implicitly imports the enumeration constant identifiers of the enumeration type.

Imported identifiers are introduced into the module, thus extending their scope, but they have a defining occurrence that appears elsewhere.

Every kind of module may include a sequence of import lists, whether it is a program module, a definition module, an implementation module or a local module. In the case of any other kind of module, the imported identifiers may be used in the block of the module."

These statements confirm that the previous example is legal. But it prompts the question, what about implicit imports othersise known as qualified references.

In section 6.10 Implicit Import and Export of the ISO Modula-2 standard it says:

"The set of identifiers that is imported or exported if an identifier is explicitly imported or exported is called the (import and export) closure of that identifier. Normally, the closure includes only the explicitly imported or exported identifier. However, in the case of the explicit import or export of an identifier of an enumeration type, the closure also includes the identifiers of the values of that type.

Implicit export applies to the identifiers that are exported (qualified) from separate modules, by virtue of their being the subject of a definition module, as well as to export from a local module that uses an export list."

Clearly this means that the following is legal:

 
MODULE impd ;

IMPORT impc ;

VAR
   a: impc.C ;
BEGIN
   a := impc.red
END impd.

It also means that the following code is legal:

 
MODULE impe ;

IMPORT impb ;

VAR
   a: impb.C ;
BEGIN
   a := impb.red
END impe.

And also this code is legal:

 
MODULE impf ;

FROM impb IMPORT C ;

VAR
   a: C ;
BEGIN
   a := red
END impf.

And also that this code is legal:

 
DEFINITION MODULE impg ;

IMPORT impc;

TYPE
   C = impc.C ;

END impg.
 
IMPLEMENTATION MODULE impg ;

VAR
   t: C ;
BEGIN
   t := red
END impg.

Furthermore the following code is also legal as the new type, C is declared and exported. Once exported all its enumerated fields are also exported.

 
DEFINITION MODULE imph;

IMPORT impc;
TYPE
   C = impc.C;

END imph.

Here we see that the current scope is populated with the enumeration fields red, blue, green and also it is possible to reference these values via a qualified identifier.

 
IMPLEMENTATION MODULE imph;

IMPORT impc;

VAR
   a: C ;
   b: impc.C ;
BEGIN
   a := impc.red ;
   b := red ;
   a := b ;
   b := a
END imph.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.7 Done list

What has been done:


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.8 To do list

What needs to be done:


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4. EBNF of GNU Modula-2

This chapter contains the EBNF of GNU Modula-2. This grammer currently supports PIM and a number of ISO features. It is intended to be altered to become fully complient with ISO in the future. The rules here are automatically extracted from the grammer files in GNU Modula-2 and serve to document the syntax of the extensions described earlier and how they fit in with the base language.

Note that the first six productions are built into the lexical analysis phase.

 
PossiblyExportIdent := is a builtin which automatically exports an identifier
                     =: 
 
Ident := is a builtin and checks for an identifier
       =: 
 
IdentScope := a builtin which provides a context for error messages
            =: 
 
Integer := is a builtin and checks for an integer
         =: 
 
Real := is a builtin and checks for an real constant
      =: 
 
string := is a builtin and checks for an string constant
        =: 
 
FileUnit := ( DefinitionModule  | ImplementationOrProgramModule  ) 
            
          =: 
 
ProgramModule := 'MODULE' Ident [ Priority  ] ';' { Import  } 
                 Block Ident '.' 
               =: 
 
ImplementationModule := 'IMPLEMENTATION' 'MODULE' Ident [ Priority  ] 
                        ';' { Import  } Block Ident '.' 
                      =: 
 
ImplementationOrProgramModule := ImplementationModule  | 
                                 ProgramModule 
                               =: 
 
Number := Integer  | Real 
        =: 
 
Qualident := Ident { '.' Ident  } 
           =: 
 
ConstantDeclaration := PossiblyExportIdent '=' ConstExpression 
                     =: 
 
ConstExpression := SimpleConstExpr [ Relation SimpleConstExpr  ] 
                   
                 =: 
 
Relation := '='  | '#'  | '<>'  | '<'  | '<='  | '>'  | '>='  | 
            'IN' 
          =: 
 
SimpleConstExpr := UnaryOrConstTerm { AddOperator ConstTerm  } 
                 =: 
 
UnaryOrConstTerm := '+' ConstTerm  | '-' ConstTerm  | 
                    ConstTerm 
                  =: 
 
AddOperator := '+'  | '-'  | 'OR' 
             =: 
 
ConstTerm := ConstFactor { MulOperator ConstFactor  } 
           =: 
 
MulOperator := '*'  | '/'  | 'DIV'  | 'MOD'  | 'REM'  | 
               'AND'  | '&' 
             =: 
 
ConstFactor := Number  | ConstString  | ConstSetOrQualidentOrFunction  | 
               '(' ConstExpression ')'  | 
               'NOT' ConstFactor  | ConstAttribute 
             =: 
 
ConstString := string 
             =: 
 
ComponentElement := ConstExpression [ '..' ConstExpression  ] 
                  =: 
 
ComponentValue := ComponentElement [ 'BY' ConstExpression  ] 
                =: 
 
ArraySetRecordValue := ComponentValue { ',' ComponentValue  } 
                     =: 
 
Constructor := '{' [ ArraySetRecordValue  ] '}' 
             =: 
 
ConstSetOrQualidentOrFunction := SimpleSet  | Qualident [ Constructor  | 
                                                          ConstActualParameters  ] 
                               =: 
 
ConstActualParameters := '(' [ ExpList  ] ')' 
                       =: 
 
ConstAttribute := '__ATTRIBUTE__' '__BUILTIN__' '(' '(' Ident 
                  ')' ')' 
                =: 
 
Element := ConstExpression [ '..' ConstExpression  ] 
         =: 
 
TypeDeclaration := ( IdentScope '=' Type  ) 
                 =: 
 
Type := ( SimpleType  | ArrayType  | RecordType  | 
          SetType  | PointerType  | ProcedureType  ) 
      =: 
 
SimpleType := Qualident [ SubrangeType  ]  | 
              Enumeration  | SubrangeType 
            =: 
 
Enumeration := '(' ( PossiblyExportIdentList  ) ')' 
             =: 
 
IdentList := Ident { ',' Ident  } 
           =: 
 
IdentScopeList := IdentScope { ',' IdentScope  } 
                =: 
 
PossiblyExportIdentList := PossiblyExportIdent { ',' PossiblyExportIdent 
                                                   } 
                         =: 
 
SubrangeType := '[' ConstExpression '..' ConstExpression ']' 
              =: 
 
ArrayType := 'ARRAY' SimpleType { ',' SimpleType  } 'OF' Type 
           =: 
 
RecordType := 'RECORD' FieldListSequence 'END' 
            =: 
 
FieldListSequence := FieldListStatement { ';' FieldListStatement  } 
                   =: 
 
FieldListStatement := [ FieldList  ] 
                    =: 
 
FieldList := IdentList ':' Type  | 'CASE' TagIdent [ ':' Qualident  | 
                                                     '.' Qualident  ] 
             'OF' Varient { '|' Varient  } [ 'ELSE' FieldListSequence  ] 
             'END' 
           =: 
 
TagIdent := [ Ident  ] 
          =: 
 
Varient := [ CaseLabelList ':' FieldListSequence  ] 
         =: 
 
CaseLabelList := CaseLabels { ',' CaseLabels  } 
               =: 
 
CaseLabels := ConstExpression [ '..' ConstExpression  ] 
            =: 
 
SetType := 'SET' 'OF' SimpleType 
         =: 
 
PointerType := 'POINTER' 'TO' Type 
             =: 
 
ProcedureType := 'PROCEDURE' [ FormalTypeList  ] 
               =: 
 
FormalTypeList := '(' ( ')' FormalReturn  | 
                        ProcedureParameters ')' FormalReturn  ) 
                =: 
 
FormalReturn := [ ':' OptReturnType  ] 
              =: 
 
OptReturnType := '[' Qualident ']'  | Qualident 
               =: 
 
ProcedureParameters := ProcedureParameter { ',' ProcedureParameter  } 
                     =: 
 
ProcedureParameter := '...'  | 'VAR' FormalType  | 
                      FormalType 
                    =: 
 
VarIdent := PossiblyExportIdent [ '[' ConstExpression ']'  ] 
          =: 
 
VariableDeclaration := ( VarIdentList ':' Type  ) 
                     =: 
 
VarIdentList := VarIdent { ',' VarIdent  } 
              =: 
 
Designator := Qualident { SubDesignator  } 
            =: 
 
SubDesignator := '.' Ident  | '[' ExpList ']'  | 
                 '^' 
               =: 
 
ExpList := Expression { ',' Expression  } 
         =: 
 
Expression := SimpleExpression [ Relation SimpleExpression  ] 
              
            =: 
 
SimpleExpression := [ '+'  | '-'  ] Term { AddOperator Term  } 
                  =: 
 
Term := Factor { MulOperator Factor  } 
      =: 
 
Factor := Number  | string  | SetOrDesignatorOrFunction  | 
          '(' Expression ')'  | 'NOT' Factor  | 
          ConstAttribute 
        =: 
 
SimpleSet := '{' [ Element { ',' Element  }  ] '}' 
           =: 
 
SetOrDesignatorOrFunction := ( Qualident [ Constructor  | 
                                           SimpleDes [ ActualParameters  ]  ]  | 
                               Constructor  ) 
                           =: 
 
SimpleDes := { '.' Ident  | '[' ExpList ']'  | 
                '^'  } 
           =: 
 
ActualParameters := '(' [ ExpList  ] ')' 
                  =: 
 
Statement := [ AssignmentOrProcedureCall  | 
               IfStatement  | CaseStatement  | 
               WhileStatement  | RepeatStatement  | 
               LoopStatement  | ForStatement  | 
               WithStatement  | AsmStatement  | 
               'EXIT'  | 'RETURN' [ Expression  ]  | 
               RetryStatement  ] 
           =: 
 
RetryStatement := 'RETRY' 
                =: 
 
AssignmentOrProcedureCall := Designator ( ':=' Expression  | 
                                          ActualParameters  | 
                                           ) 
                           =: 
 
StatementSequence := Statement { ';' Statement  } 
                   =: 
 
IfStatement := 'IF' Expression 'THEN' StatementSequence { 'ELSIF' 
                                                           Expression 
                                                           'THEN' 
                                                           StatementSequence  } 
               [ 'ELSE' StatementSequence  ] 'END' 
             =: 
 
CaseStatement := 'CASE' Expression 'OF' Case { '|' Case  } 
                 [ 'ELSE' StatementSequence  ] 'END' 
               =: 
 
Case := [ CaseLabelList ':' StatementSequence  ] 
      =: 
 
WhileStatement := 'WHILE' Expression 'DO' StatementSequence 'END' 
                =: 
 
RepeatStatement := 'REPEAT' StatementSequence 'UNTIL' Expression 
                 =: 
 
ForStatement := 'FOR' Ident ':=' Expression 'TO' Expression [ 
   'BY' ConstExpression  ] 'DO' StatementSequence 'END' 
              =: 
 
LoopStatement := 'LOOP' StatementSequence 'END' 
               =: 
 
WithStatement := 'WITH' Designator 'DO' StatementSequence 'END' 
               =: 
 
ProcedureDeclaration := ProcedureHeading ';' ( ProcedureBlock 
                                               Ident  ) 
                      =: 
 
DefineBuiltinProcedure := '__ATTRIBUTE__' '__BUILTIN__' '(' '(' 
                          Ident ')' ')'  | 
                          '__INLINE__'  | 
                        =: 
 
ProcedureHeading := 'PROCEDURE' DefineBuiltinProcedure ( PossiblyExportIdent 
                                                         [ FormalParameters  ] 
                                                          ) 
                  =: 
 
Builtin := '__BUILTIN__'  | '__INLINE__'  | 
         =: 
 
DefProcedureHeading := 'PROCEDURE' Builtin ( PossiblyExportIdent 
                                             [ DefFormalParameters  ] 
                                              ) 
                     =: 
 
ProcedureBlock := { Declaration  } [ 'BEGIN' BlockBody  ] 'END' 
                =: 
 
Block := { Declaration  } InitialBlock FinalBlock 'END' 
       =: 
 
InitialBlock := [ 'BEGIN' BlockBody  ] 
              =: 
 
FinalBlock := [ 'FINALLY' BlockBody  ] 
            =: 
 
BlockBody := NormalPart [ 'EXCEPT' ExceptionalPart  ] 
           =: 
 
NormalPart := StatementSequence 
            =: 
 
ExceptionalPart := StatementSequence 
                 =: 
 
Declaration := 'CONST' { ConstantDeclaration ';'  }  | 
               'TYPE' { TypeDeclaration ';'  }  | 
               'VAR' { VariableDeclaration ';'  }  | 
               ProcedureDeclaration ';'  | 
               ModuleDeclaration ';' 
             =: 
 
DefFormalParameters := '(' [ DefMultiFPSection  ] ')' FormalReturn 
                     =: 
 
DefMultiFPSection := DefExtendedFP  | FPSection [ ';' DefMultiFPSection  ] 
                   =: 
 
FormalParameters := '(' [ MultiFPSection  ] ')' FormalReturn 
                  =: 
 
MultiFPSection := ExtendedFP  | FPSection [ ';' MultiFPSection  ] 
                =: 
 
FPSection := NonVarFPSection  | VarFPSection 
           =: 
 
DefExtendedFP := DefOptArg  | '...' 
               =: 
 
ExtendedFP := OptArg  | '...' 
            =: 
 
VarFPSection := 'VAR' IdentScopeList ':' FormalType 
              =: 
 
NonVarFPSection := IdentScopeList ':' FormalType 
                 =: 
 
OptArg := '[' IdentScope ':' FormalType [ '=' ConstExpression  ] 
          ']' 
        =: 
 
DefOptArg := '[' IdentScope ':' FormalType '=' ConstExpression 
             ']' 
           =: 
 
FormalType := [ 'ARRAY' 'OF'  ] Qualident 
            =: 
 
ModuleDeclaration := 'MODULE' Ident [ Priority  ] ';' { Import 
                                                          } 
                     [ Export  ] Block Ident 
                   =: 
 
Priority := '[' ConstExpression ']' 
          =: 
 
Export := 'EXPORT' ( 'QUALIFIED' IdentList  | 
                     'UNQUALIFIED' IdentList  | 
                     IdentList  ) ';' 
        =: 
 
Import := 'FROM' Ident 'IMPORT' IdentList ';'  | 
          'IMPORT' IdentList ';' 
        =: 
 
DefinitionModule := 'DEFINITION' 'MODULE' ( 'FOR' string  | 
                                             ) Ident ';' { Import 
                                                             } 
                    [ Export  ] { Definition  } 'END' Ident 
                    '.' 
                  =: 
 
Definition := 'CONST' { ConstantDeclaration ';'  }  | 
              'TYPE' { PossiblyExportIdent ( ';'  | '=' Type 
                                              ';'  )  }  | 
              'VAR' { VariableDeclaration ';'  }  | 
              DefProcedureHeading ';' 
            =: 
 
AsmStatement := 'ASM' [ 'VOLATILE'  ] '(' AsmOperands ')' 
              =: 
 
AsmOperands := string [ ':' AsmList [ ':' AsmList [ ':' TrashList  ]  ]  ] 
             =: 
 
AsmList := [ AsmElement  ] { ',' AsmElement  } 
         =: 
 
AsmElement := string '(' Expression ')' 
            =: 
 
TrashList := [ string  ] { ',' string  } 
           =: 

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5. PIM and ISO library definitions

This chapter contains M2F, ULM, PIM and ISO libraries. The ISO libraries are currently work in progress, many are incomplete and even more have no implementation module. The M2F libraries are very mature as the compiler uses them extensively. Permission has been kindly granted by the authors of the ULM libraries to include them with GNU Modula-2. These libraries (under the GNU GPL) were written at the University of Ulm and were originally shipped with the ULM sparc Modula-2 compiler.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1 Base libraries

These are the base libraries for the GNU Modula-2 compiler. These modules originally came from the M2F compiler and have been cleaned up and extended. They provide a basic interface to the underlying operating system via libc. They also include a number of libraries to allow access to compiler built-ins. Perhaps the largest difference to PIM and ISO libraries is the DynamicString module which declares the type String. The heavy use of this opaque data type results in a number of equivalent modules that can either handle ARRAY OF CHAR or String.

These modules have been extensively tested and are used throughout building the GNU Modula-2 compiler.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.1 gm2-libs/StrIO

 
DEFINITION MODULE StrIO ;

(*
   Description: Provides simple string input output routines.
*)

EXPORT QUALIFIED ReadString, WriteString,
                 WriteLn ;


(*
   WriteLn - writes a carriage return and a newline
             character.
*)

PROCEDURE WriteLn ;


(*
   ReadString - reads a sequence of characters into a string.
                Line editing accepts Del, Ctrl H, Ctrl W and
                Ctrl U.
*)

PROCEDURE ReadString (VAR a: ARRAY OF CHAR) ;


(*
   WriteString - writes a string to the default output.
*)

PROCEDURE WriteString (a: ARRAY OF CHAR) ;


END StrIO.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.2 gm2-libs/StrCase

 
DEFINITION MODULE StrCase ;


EXPORT QUALIFIED StrToUpperCase, StrToLowerCase, Cap, Lower ;


(*
   StrToUpperCase - converts string, a, to uppercase returning the
                    result in, b.
*)

PROCEDURE StrToUpperCase (a: ARRAY OF CHAR ; VAR b: ARRAY OF CHAR) ;


(*
   StrToLowerCase - converts string, a, to lowercase returning the
                    result in, b.
*)

PROCEDURE StrToLowerCase (a: ARRAY OF CHAR ; VAR b: ARRAY OF CHAR) ;


(*
   Cap - converts a lower case character into a capital character.
         If the character is not a lower case character 'a'..'z'
         then the character is simply returned unaltered.
*)

PROCEDURE Cap (ch: CHAR) : CHAR ;


(*
   Lower - converts an upper case character into a lower case character.
           If the character is not an upper case character 'A'..'Z'
           then the character is simply returned unaltered.
*)

PROCEDURE Lower (ch: CHAR) : CHAR ;


END StrCase.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.3 gm2-libs/Builtins

 
DEFINITION MODULE Builtins ;

(*
    Description: provides a convenient place to list all the GNU Modula-2
                 built-in functions. These functions should be copied into
                 more generic modules.

                 For example the mathematical functions can be applied to
                 gm2-iso/LongMath. But each built-in function is here for
                 reference.
*)

FROM SYSTEM IMPORT ADDRESS ;

PROCEDURE __BUILTIN__ sinf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ sin (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ sinl (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ cosf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ cos (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ cosl (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ sqrtf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ sqrt (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ sqrtl (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ fabsf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ fabs (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ fabsl (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ logf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ log (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ logl (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ expf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ exp (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ expl (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ log10f (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ log10 (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ log10l (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ exp10f (x: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ exp10 (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ exp10l (x: LONGREAL) : LONGREAL ;

PROCEDURE __BUILTIN__ alloca (i: CARDINAL) : ADDRESS ;
PROCEDURE __BUILTIN__ memcpy (dest, src: ADDRESS; n: CARDINAL) : ADDRESS ;
PROCEDURE __BUILTIN__ index (s: ADDRESS; c: INTEGER) : ADDRESS ;
PROCEDURE __BUILTIN__ rindex (s: ADDRESS; c: INTEGER) : ADDRESS ;
PROCEDURE __BUILTIN__ memcmp (s1, s2: ADDRESS; n: CARDINAL) : INTEGER ;
PROCEDURE __BUILTIN__ memset (s: ADDRESS; c: INTEGER; n: CARDINAL) : ADDRESS ;
PROCEDURE __BUILTIN__ memmove (s1, s2: ADDRESS; n: CARDINAL) : ADDRESS ;
PROCEDURE __BUILTIN__ strcat (dest, src: ADDRESS) : ADDRESS ;
PROCEDURE __BUILTIN__ strncat (dest, src: ADDRESS; n: CARDINAL) : ADDRESS ;
PROCEDURE __BUILTIN__ strcpy (dest, src: ADDRESS) : ADDRESS ;
PROCEDURE __BUILTIN__ strncpy (dest, src: ADDRESS; n: CARDINAL) : ADDRESS ;
PROCEDURE __BUILTIN__ strcmp (s1, s2: ADDRESS) : INTEGER ;
PROCEDURE __BUILTIN__ strncmp (s1, s2: ADDRESS; n: CARDINAL) : INTEGER ;
PROCEDURE __BUILTIN__ strlen (s: ADDRESS) : INTEGER ;
PROCEDURE __BUILTIN__ strstr (haystack, needle: ADDRESS) : ADDRESS ;
PROCEDURE __BUILTIN__ strpbrk (s, accept: ADDRESS) : ADDRESS ;
PROCEDURE __BUILTIN__ strspn (s, accept: ADDRESS) : CARDINAL ;
PROCEDURE __BUILTIN__ strcspn (s, accept: ADDRESS) : CARDINAL ;
PROCEDURE __BUILTIN__ strchr (s: ADDRESS; c: INTEGER) : ADDRESS ;
PROCEDURE __BUILTIN__ strrchr (s: ADDRESS; c: INTEGER) : ADDRESS ;

PROCEDURE __BUILTIN__ huge_val (r: REAL) : REAL ;
PROCEDURE __BUILTIN__ huge_valf (s: SHORTREAL) : SHORTREAL ;
PROCEDURE __BUILTIN__ huge_vall (l: LONGREAL) : LONGREAL ;

(*
   longjmp - this GCC builtin restricts the val to always 1.
*)
(* do not use these two builtins, as gcc, only really
   anticipates that the Ada front end should use them
   and it only uses them in its runtime exception handling.
   We leave them here in the hope that someday they will
   behave more like their libc counterparts. *)
PROCEDURE __BUILTIN__ longjmp (env: ADDRESS; val: INTEGER) ;
PROCEDURE __BUILTIN__ setjmp (env: ADDRESS) : INTEGER ;

(*
   frame_address - returns the address of the frame.
                   The current frame is obtained if level is 0,
                   the next level up if level is 1 etc.
*)

PROCEDURE __BUILTIN__ frame_address (level: CARDINAL) : ADDRESS ;


(*
   return_address - returns the return address of function.
                    The current function return address is
                    obtained if level is 0,
                    the next level up if level is 1 etc.
*)

PROCEDURE __BUILTIN__ return_address (level: CARDINAL) : ADDRESS ;


END Builtins.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.4 gm2-libs/Storage

 
DEFINITION MODULE Storage ;

(*
   Description: Implements the dynamic Storage handler for the
                Modula-2 compiler.
*)

FROM SYSTEM IMPORT ADDRESS ;

EXPORT QUALIFIED ALLOCATE, DEALLOCATE, REALLOCATE, Available ;



(*
   ALLOCATE - attempt to allocate memory from the heap.
              NIL is returned in, a, if ALLOCATE fails.
*)

PROCEDURE ALLOCATE (VAR a: ADDRESS ; Size: CARDINAL) ;


(*
   DEALLOCATE - return, Size, bytes to the heap.
                The variable, a, is set to NIL.
*)

PROCEDURE DEALLOCATE (VAR a: ADDRESS ; Size: CARDINAL) ;


(*
   REALLOCATE - attempts to reallocate storage. The address,
                a, should either be NIL in which case ALLOCATE
                is called, or alternatively it should have already
                been initialized by ALLOCATE. The allocated storage
                is resized accordingly.
*)

PROCEDURE REALLOCATE (VAR a: ADDRESS; Size: CARDINAL) ;


(*
   Available - returns TRUE if, Size, bytes can be allocated.
*)

PROCEDURE Available (Size: CARDINAL) : BOOLEAN ;


END Storage.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.5 gm2-libs/Environment

 
DEFINITION MODULE Environment ;

(*
    Description: provides access to the environment settings of a process.
*)

EXPORT QUALIFIED GetEnvironment ;


(*
   GetEnvironment - gets the environment variable, Env, and places
      	       	    a copy of its value into string, a.
*)

PROCEDURE GetEnvironment (Env: ARRAY OF CHAR; VAR a: ARRAY OF CHAR) : BOOLEAN ;


END Environment.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.6 gm2-libs/StrLib

 
DEFINITION MODULE StrLib ;

(*
   Description: Provides string manipulation
*)

EXPORT QUALIFIED StrConCat, StrLen, StrCopy, StrEqual, StrLess,
      	       	 IsSubString, StrRemoveWhitePrefix ;


(*
   StrConCat - combines a and b into c.
*)

PROCEDURE StrConCat (a, b: ARRAY OF CHAR; VAR c: ARRAY OF CHAR) ;


(*
   StrLess - returns TRUE if string, a, alphabetically occurs before
             string, b.
*)

PROCEDURE StrLess (a, b: ARRAY OF CHAR) : BOOLEAN ;


(*
   StrEqual - performs a = b on two strings.
*)

PROCEDURE StrEqual (a, b: ARRAY OF CHAR) : BOOLEAN ;


(*
   StrLen - returns the length of string, a.
*)

PROCEDURE StrLen (a: ARRAY OF CHAR) : CARDINAL ;


(*
   StrCopy - effectively performs b := a with two strings.
*)

PROCEDURE StrCopy (a: ARRAY OF CHAR ; VAR b: ARRAY OF CHAR) ;


(*
   IsSubString - returns true if b is a subcomponent of a.
*)

PROCEDURE IsSubString (a, b: ARRAY OF CHAR) : BOOLEAN ;


(*
   StrRemoveWhitePrefix - copies string, into string, b, excluding any white
                          space infront of a.
*)

PROCEDURE StrRemoveWhitePrefix (a: ARRAY OF CHAR; VAR b: ARRAY OF CHAR) ;


END StrLib.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.7 gm2-libs/MemUtils

 
DEFINITION MODULE MemUtils ;

(*
    Description: provides some basic memory utilities.
*)

FROM SYSTEM IMPORT ADDRESS ;
EXPORT QUALIFIED MemCopy, MemZero ;


(*
   MemCopy - copys a region of memory to the required destination.
*)

PROCEDURE MemCopy (from: ADDRESS; length: CARDINAL; to: ADDRESS) ;


(*
   MemZero - sets a region of memory: a..a+length to zero.
*)

PROCEDURE MemZero (a: ADDRESS; length: CARDINAL) ;


END MemUtils.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.8 gm2-libs/libc

 
DEFINITION MODULE FOR "C" libc ;

(*
   Description: Provides an interface to the C library functions.
*)

FROM SYSTEM IMPORT ADDRESS ;

EXPORT UNQUALIFIED time_t, timeb, tm, ptrToTM,
                   write, read,
                   system, abort,
                   malloc, free,
                   exit, isatty,
                   getenv, getpid,
                   dup, close, open, lseek,
                   readv, writev,
                   perror, creat,
                   getcwd, chown, strlen, strcpy, strncpy,
                   unlink,
                   memcpy, memset, printf, realloc,
                   rand, srand,
                   time, localtime, ftime,
                   shutdown, rename, setjmp, longjmp ;

TYPE
   time_t = LONGINT ;

   ptrToTM = POINTER TO tm ;
   tm = RECORD
           tm_sec: INTEGER ;     (* Seconds.     [0-60] (1 leap second) *)
           tm_min: INTEGER ;     (* Minutes.     [0-59]   *)
           tm_hour: INTEGER ;    (* Hours.       [0-23]   *)
           tm_mday: INTEGER ;    (* Day.         [1-31]   *)
           tm_mon: INTEGER ;     (* Month.       [0-11]   *)
           tm_year: INTEGER ;    (* Year - 1900.          *)
           tm_wday: INTEGER ;    (* Day of week. [0-6]    *)
           tm_yday: INTEGER ;    (* Days in year.[0-365]  *)
           tm_isdst: INTEGER ;   (* DST.         [-1/0/1] *)
           tm_gmtoff: LONGINT ;  (* Seconds east of UTC.  *)
           tm_zone: ADDRESS ;    (* char * zone name      *)
        END ;

   timeb = RECORD
              time    : time_t ;
              millitm : SHORTCARD ;
              timezone: SHORTCARD ;
              dstflag : SHORTCARD ;
           END ;


(*
     int write(d, buf, nbytes)
     int d;
     char *buf;
     int nbytes;
*)

PROCEDURE write (d: INTEGER; buf: ADDRESS; nbytes: INTEGER) : INTEGER ;


(*
     int read(d, buf, nbytes)
     int d;
     char *buf;
     int nbytes;
*)

PROCEDURE read (d: INTEGER; buf: ADDRESS; nbytes: INTEGER) : INTEGER ;


(*
     int system(string)
     char *string;
*)

PROCEDURE system (a: ADDRESS) : INTEGER ;


(*
     abort - generate a fault

     abort() first closes all open files if possible, then sends
     an IOT signal to the process.  This signal usually results
     in termination with a core dump, which may be used for
     debugging.

     It is possible for abort() to return control if is caught or
     ignored, in which case the value returned is that of the
     kill(2V) system call.
*)

PROCEDURE abort ;


(*
     malloc - memory allocator.

     char *malloc(size)
     unsigned size;

     malloc() returns a pointer to a block of at least size
     bytes, which is appropriately aligned.  If size is zero,
     malloc() returns a non-NULL pointer, but this pointer should
     not be dereferenced.
*)

PROCEDURE malloc (size: CARDINAL) : ADDRESS ;


(*
     free - memory deallocator.

     free(ptr)
     char *ptr;

     free() releases a previously allocated block.  Its argument
     is a pointer to a block previously allocated by malloc,
     calloc, realloc, malloc, or memalign.
*)

PROCEDURE free (ptr: ADDRESS) ;


(*
     void *realloc(void *ptr, size_t size);

     realloc changes the size of the memory block pointed to
     by ptr to size bytes. The contents will be  unchanged  to
     the minimum of the old and new sizes; newly allocated memory
     will be uninitialized. If ptr is NIL, the call is
     equivalent  to malloc(size); if size is equal to zero, the
     call is equivalent to free(ptr). Unless ptr is NIL, it
     must have been returned by an earlier call to malloc(),
     realloc.
*)

PROCEDURE realloc (ptr: ADDRESS; size: CARDINAL) : ADDRESS ;


(*
   isatty - does this descriptor refer to a terminal.
*)

PROCEDURE isatty (fd: INTEGER) : INTEGER ;


(*
   exit - returns control to the invoking process. Result, r, is
          returned.
*)

PROCEDURE exit (r: INTEGER) ;


(*
   getenv - returns the C string for the equivalent C environment
            variable.
*)

PROCEDURE getenv (s: ADDRESS) : ADDRESS ;


(*
   getpid - returns the UNIX process identification number.
*)

PROCEDURE getpid () : INTEGER ;


(*
   dup - duplicates the file descriptor, d.
*)

PROCEDURE dup (d: INTEGER) : INTEGER ;


(*
   close - closes the file descriptor, d.
*)

PROCEDURE close (d: INTEGER) : INTEGER ;


(*
   open - open the file, filename with flag and mode.
*)

PROCEDURE open (filename: ADDRESS; flag, mode: CARDINAL) : INTEGER ;


(*
   creat - creates a new file
*)

PROCEDURE creat (filename : ADDRESS; mode : CARDINAL) : INTEGER;


(*
   lseek - calls unix lseek:

           off_t lseek(int fildes, off_t offset, int whence);
*)

PROCEDURE lseek (fd: INTEGER; offset: LONGINT; whence: INTEGER) : LONGINT ;


(*
   perror - writes errno and string. (ARRAY OF CHAR is translated onto ADDRESS).
*)

PROCEDURE perror (string: ARRAY OF CHAR);


(*
   readv - reads an io vector of bytes.
*)

PROCEDURE readv (fd: INTEGER; v: ADDRESS; n: INTEGER) : INTEGER ;


(*
   writev - writes an io vector of bytes.
*)

PROCEDURE writev (fd: INTEGER; v: ADDRESS; n: INTEGER) : INTEGER ;


(*
   getcwd - copies the absolute pathname of the
            current working directory to the array pointed to by buf,
            which is of length size.

            If the current absolute path name would require a buffer
            longer than size elements, NULL is returned, and errno is
            set to ERANGE; an application should check for this error,
            and allocate a larger buffer if necessary.
*)

PROCEDURE getcwd (buf: ADDRESS; size: INTEGER) : ADDRESS ;


(*
   chown - The  owner  of  the  file  specified  by  path or by fd is
           changed.  Only the super-user may change the  owner  of  a
           file.   The  owner  of  a file may change the group of the
           file to any group of which that owner is  a  member.   The
           super-user may change the group arbitrarily.

           If  the owner or group is specified as -1, then that ID is
           not changed.

           On success, zero is returned.  On error, -1  is  returned,
           and errno is set appropriately.
*)

PROCEDURE chown (filename: ADDRESS; uid, gid: INTEGER) : INTEGER ;


(*
   strlen - returns the length of string, a.
*)

PROCEDURE strlen (a: ADDRESS) : INTEGER ;


(*
   strcpy - copies string, src, into, dest.
            It returns dest.
*)

PROCEDURE strcpy (dest, src: ADDRESS) : ADDRESS ;


(*
   strncpy - copies string, src, into, dest, copying at most, n, bytes.
             It returns dest.
*)

PROCEDURE strncpy (dest, src: ADDRESS; n: CARDINAL) : ADDRESS ;


(*
   unlink - removes file and returns 0 if successful.
*)

PROCEDURE unlink (file: ADDRESS) : INTEGER ;


(*
   memcpy - copy memory area

   SYNOPSIS

   #include <string.h>

   void *memcpy(void *dest, const void *src, size_t n);
   It returns dest.
*)

PROCEDURE memcpy (dest, src: ADDRESS; size: CARDINAL) : ADDRESS ;


(*
   memset - fill memory with a constant byte

   SYNOPSIS

   #include <string.h>

   void *memset(void *s, int c, size_t n);
*)

PROCEDURE memset (s: ADDRESS; c: INTEGER; size: CARDINAL) : ADDRESS ;


(*
   int printf(const char *format, ...);
*)

PROCEDURE printf (format: ARRAY OF CHAR; ...) : [ INTEGER ] ;


(*
   srand - initialize the random number seed.
*)

PROCEDURE srand (seed: INTEGER) ;


(*
   rand - return a random integer.
*)

PROCEDURE rand () : INTEGER ;


(*
   time - returns a pointer to the time_t value. If, a,
          is not NIL then the libc value is copied into
          memory at address, a.
*)

PROCEDURE time (a: ADDRESS) : time_t ;


(*
   localtime - returns a pointer to the libc copy of the tm
               structure.
*)

PROCEDURE localtime (VAR t: time_t) : ADDRESS ;


(*
   ftime - return date and time.
*)

PROCEDURE ftime (VAR t: timeb) : INTEGER ;


(*
   shutdown - shutdown a socket, s.
              if how = 0, then no more reads are allowed.
              if how = 1, then no more writes are allowed.
              if how = 2, then mo more reads or writes are allowed.
*)

PROCEDURE shutdown (s: INTEGER; how: INTEGER) : INTEGER ;


(*
   rename - change the name or location of a file
*)

PROCEDURE rename (oldpath, newpath: ADDRESS) : INTEGER ;


(*
   setjmp - returns 0 if returning directly, and non-zero
            when returning from longjmp using the saved
            context.
*)

PROCEDURE setjmp (env: ADDRESS) : INTEGER ;


(*
   longjmp - restores the environment saved by the last call
             of setjmp with the corresponding env argument.
             After longjmp is completed, program execution
             continues as if the corresponding call of setjmp
             had just returned the value val.  The value of
             val must not be zero.
*)

PROCEDURE longjmp (env: ADDRESS; val: INTEGER) ;


END libc.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.9 gm2-libs/PushBackInput

 
DEFINITION MODULE PushBackInput ;

(*
    Description: provides a method for pushing back and consuming input
                 from a standard file descriptor. Insipred by software
                 tools.
*)

FROM FIO IMPORT File ;
FROM DynamicStrings IMPORT String ;

EXPORT QUALIFIED Open, PutCh, GetCh, Error, WarnError, WarnString,
                 Close, SetDebug, GetExitStatus,
                 PutString, GetColumnPosition, GetCurrentLine ;


(*
   Open - opens a file for reading.
*)

PROCEDURE Open (a: ARRAY OF CHAR) : File ;


(*
   GetCh - gets a character from either the push back stack or
           from file, f.
*)

PROCEDURE GetCh (f: File) : CHAR ;


(*
   PutCh - pushes a character onto the push back stack, it also
           returns the character which has been pushed.
*)

PROCEDURE PutCh (f: File; ch: CHAR) : CHAR ;


(*
   PutString - pushes a string onto the push back stack.
*)

PROCEDURE PutString (f: File; a: ARRAY OF CHAR) ;


(*
   Error - emits an error message with the appropriate file, line combination.
*)

PROCEDURE Error (a: ARRAY OF CHAR) ;


(*
   WarnError - emits an error message with the appropriate file, line combination.
               It does not terminate but when the program finishes an exit status of
               1 will be issued.
*)

PROCEDURE WarnError (a: ARRAY OF CHAR) ;


(*
   WarnString - emits an error message with the appropriate file, line combination.
                It does not terminate but when the program finishes an exit status of
                1 will be issued.
*)

PROCEDURE WarnString (s: String) ;


(*
   Close - closes the opened file.
*)

PROCEDURE Close (f: File) ;


(*
   GetExitStatus - returns the exit status which will be 1 if any warnings were issued.
*)

PROCEDURE GetExitStatus () : CARDINAL ;


(*
   SetDebug - sets the debug flag on or off.
*)

PROCEDURE SetDebug (d: BOOLEAN) ;


(*
   GetColumnPosition - returns the column position of the current character.
*)

PROCEDURE GetColumnPosition () : CARDINAL ;


(*
   GetCurrentLine - returns the current line number.
*)

PROCEDURE GetCurrentLine () : CARDINAL ;


END PushBackInput.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.10 gm2-libs/IO

 
DEFINITION MODULE IO ;

(*
   Description: provides Read, Write, Errors procedures that map onto UNIX
                file descriptors 0, 1 and 2. This is achieved by using
                FIO if we are in buffered mode and using libc.write
                if not.
*)

EXPORT QUALIFIED Read, Write, Error,
                 IOInRawMode, IOInBufferedMode ;


PROCEDURE Read (VAR ch: CHAR) ;
PROCEDURE Write (ch: CHAR) ;
PROCEDURE Error (ch: CHAR) ;
PROCEDURE IOInRawMode ;
PROCEDURE IOInBufferedMode ;


END IO.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.11 gm2-libs/TimeString

 
DEFINITION MODULE TimeString ;

(*
    Description: Provides time related string manipulation procedures.
*)


EXPORT QUALIFIED GetTimeString ;


(*
   GetTimeString - places the time in ascii format into array, a.

*)

PROCEDURE GetTimeString (VAR a: ARRAY OF CHAR) ;


END TimeString.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.12 gm2-libs/Scan

 
DEFINITION MODULE Scan ;

(*
   Description: Provides a primitive symbol fetching from input.
                Symbols are delimited by spaces and tabs.
                Limitation - only allows one source file at
                             a time to deliver symbols.
*)


EXPORT QUALIFIED GetNextSymbol, WriteError,
                 OpenSource, CloseSource,
                 TerminateOnError, DefineComments ;


(* OpenSource - opens a source file for reading.                  *)

PROCEDURE OpenSource (a: ARRAY OF CHAR) : BOOLEAN ;


(* CloseSource - closes the current source file from reading.     *)

PROCEDURE CloseSource ;


(* GetNextSymbol gets the next source symbol and returns it in a. *)

PROCEDURE GetNextSymbol (VAR a: ARRAY OF CHAR) ;


(* WriteError writes a message, a, under the source line, which   *)
(* attempts to pinpoint the Symbol at fault.                      *)

PROCEDURE WriteError (a: ARRAY OF CHAR) ;


(*
   TerminateOnError - exits with status 1 if we call WriteError.
*)

PROCEDURE TerminateOnError ;


(*
   DefineComments - defines the start of comments within the source
                    file.

                    The characters in Start define the comment start
                    and characters in End define the end.
                    The BOOLEAN eoln determine whether the comment
                    is terminated by end of line. If eoln is TRUE
                    then End is ignored.

                    If this procedure is never called then no comments
                    are allowed.
*)

PROCEDURE DefineComments (Start, End: ARRAY OF CHAR; eoln: BOOLEAN) ;


END Scan.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.13 gm2-libs/dtoa

 
DEFINITION MODULE dtoa ;

(*
    Description: provides routines to convert between a C double
                 and an ascii string.  The reason we include this
                 module as well as the ldtoa is that the long doubles
                 might be implemented in software on some targets.
                 Hence the libraries should use dtoa if converting
                 REAL or SHORTREAL to/from ascii.
*)

FROM SYSTEM IMPORT ADDRESS ;

TYPE
   Mode = (shortest, stopping, maxsignificant, decimaldigits) ;


(*
   strtod - returns a REAL given a string, s.  It will set
            error to TRUE if the number is too large.
*)

PROCEDURE strtod (s: ARRAY OF CHAR; VAR error: BOOLEAN) : REAL ;
PROCEDURE strtod_string (s: ADDRESS; VAR error: BOOLEAN) : REAL ;


(*
   dtoa - converts a REAL, d, into a string.  The address of the
          string is returned.
          mode       indicates the type of conversion required.
          ndigits    determines the number of digits according to mode.
          decpt      the position of the decimal point.
          sign       does the string have a sign?
*)

PROCEDURE dtoa (d        : REAL;
                mode     : Mode;
                ndigits  : INTEGER;
	        VAR decpt: INTEGER;
	        VAR sign : BOOLEAN) : ADDRESS ;


END dtoa.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.14 gm2-libs/UnixArgs

 
DEFINITION MODULE UnixArgs ;

(*
   Description: Implements access to the C arguments argc and argv.
*)

FROM SYSTEM IMPORT ADDRESS ;

EXPORT QUALIFIED ArgC, ArgV ;


VAR
   ArgC: CARDINAL ;
   ArgV: ADDRESS ;


END UnixArgs.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.15 gm2-libs/errno

 
DEFINITION MODULE errno ;

(*
    Description: provides a Modula-2 interface to the C errno.
*)

EXPORT QUALIFIED EINTR, geterrno ;

CONST
    EINTR = 4 ;
    ERANGE = 34 ;   (* result is too large *)

PROCEDURE geterrno () : INTEGER ;


END errno.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.16 gm2-libs/Break

 
DEFINITION MODULE Break ;

END Break.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.17 gm2-libs/FormatStrings

 
DEFINITION MODULE FormatStrings ;

(*
    Description: provides a pseudo printf capability for GM2.
*)

FROM SYSTEM IMPORT BYTE ;
FROM DynamicStrings IMPORT String ;
EXPORT QUALIFIED Sprintf0, Sprintf1, Sprintf2, Sprintf3, Sprintf4 ;


(*
   Sprintf0 - returns a String containing, s, after it has had its
              escape sequences translated.
*)

PROCEDURE Sprintf0 (s: String) : String ;


(*
   Sprintf1 - returns a String containing, s, together with encapsulated
              entity, w. It only formats the first %s or %d with n.
*)

PROCEDURE Sprintf1 (s: String; w: ARRAY OF BYTE) : String ;


(*
   Sprintf2 - returns a string, s, which has been formatted.
*)

PROCEDURE Sprintf2 (s: String; w1, w2: ARRAY OF BYTE) : String ;


(*
   Sprintf3 - returns a string, s, which has been formatted.
*)

PROCEDURE Sprintf3 (s: String; w1, w2, w3: ARRAY OF BYTE) : String ;


(*
   Sprintf4 - returns a string, s, which has been formatted.
*)

PROCEDURE Sprintf4 (s: String; w1, w2, w3, w4: ARRAY OF BYTE) : String ;


END FormatStrings.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.18 gm2-libs/Selective

 
DEFINITION MODULE Selective ;

(*
    Description: provides Modula-2 with access to the select(2) primitive.
*)

FROM SYSTEM IMPORT ADDRESS ;

EXPORT QUALIFIED SetOfFd, Timeval,
                 InitSet, KillSet, InitTime, KillTime,
                 GetTime, SetTime,
                 FdZero, FdSet, FdClr, FdIsSet, Select,
                 MaxFdsPlusOne, WriteCharRaw, ReadCharRaw,
                 GetTimeOfDay ;

TYPE
   SetOfFd = ADDRESS ;    (* Hidden type in Selective.c *)
   Timeval = ADDRESS ;    (* Hidden type in Selective.c *)


PROCEDURE Select (nooffds: CARDINAL;
                  readfds, writefds, exceptfds: SetOfFd;
                  timeout: Timeval) : INTEGER ;

PROCEDURE InitTime (sec, usec: CARDINAL) : Timeval ;
PROCEDURE KillTime (t: Timeval) : Timeval ;
PROCEDURE GetTime (t: Timeval; VAR sec, usec: CARDINAL) ;
PROCEDURE SetTime (t: Timeval; sec, usec: CARDINAL) ;
PROCEDURE InitSet () : SetOfFd ;
PROCEDURE KillSet (s: SetOfFd) : SetOfFd ;
PROCEDURE FdZero (s: SetOfFd) ;
PROCEDURE FdSet (fd: INTEGER; s: SetOfFd) ;
PROCEDURE FdClr (fd: INTEGER; s: SetOfFd) ;
PROCEDURE FdIsSet (fd: INTEGER; s: SetOfFd) : BOOLEAN ;
PROCEDURE MaxFdsPlusOne (a, b: INTEGER) : INTEGER ;

(* you must use the raw routines with select - not the FIO buffered routines *)
PROCEDURE WriteCharRaw (fd: INTEGER; ch: CHAR) ;
PROCEDURE ReadCharRaw (fd: INTEGER) : CHAR ;

(*
   GetTimeOfDay - fills in a record, Timeval, filled in with the
                  current system time in seconds and microseconds.
                  It returns zero (see man 3p gettimeofday)
*)

PROCEDURE GetTimeOfDay (tv: Timeval) : INTEGER ;


END Selective.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.19 gm2-libs/SysStorage

 
DEFINITION MODULE SysStorage ;

(*
    Description: provides dynamic allocation for the system components
                 of a realtime system. This allows the application to
                 use the traditional Storage module which can be
                 handled differently.
*)

FROM SYSTEM IMPORT ADDRESS ;
EXPORT QUALIFIED ALLOCATE, DEALLOCATE, REALLOCATE, Available, Init ;


(*
   ALLOCATE - attempt to allocate memory from the heap.
              NIL is returned in, a, if ALLOCATE fails.
*)

PROCEDURE ALLOCATE (VAR a: ADDRESS ; Size: CARDINAL) ;


(*
   DEALLOCATE - return, Size, bytes to the heap.
                The variable, a, is set to NIL.
*)

PROCEDURE DEALLOCATE (VAR a: ADDRESS ; Size: CARDINAL) ;


(*
   REALLOCATE - attempts to reallocate storage. The address,
                a, should either be NIL in which case ALLOCATE
                is called, or alternatively it should have already
                been initialized by ALLOCATE. The allocated storage
                is resized accordingly.
*)

PROCEDURE REALLOCATE (VAR a: ADDRESS; Size: CARDINAL) ;


(*
   Available - returns TRUE if, Size, bytes can be allocated.
*)

PROCEDURE Available (Size: CARDINAL) : BOOLEAN;


(*
   Init - initializes the heap.
*)

PROCEDURE Init ;


END SysStorage.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.20 gm2-libs/FIO

 
DEFINITION MODULE FIO ;

(*
    Description: provides a simple buffered file input/output library.
*)


FROM SYSTEM IMPORT ADDRESS, BYTE ;

EXPORT QUALIFIED (* types *)
                 File,
                 (* procedures *)
                 OpenToRead, OpenToWrite, OpenForRandom, Close,
                 EOF, EOLN, IsNoError, Exists,
                 exists, openToRead, openToWrite, openForRandom,
                 SetPositionFromBeginning,
                 SetPositionFromEnd,
                 FindPosition,
                 ReadChar, ReadString,
                 WriteChar, WriteString, WriteLine,
                 WriteCardinal, ReadCardinal,
                 UnReadChar,
                 WriteNBytes, ReadNBytes,
                 FlushBuffer,
                 GetUnixFileDescriptor,
                 GetFileName,
                 (* variables *)
                 StdIn, StdOut, StdErr ;

TYPE
   File = CARDINAL ;

(* the following variables are initialized to their UNIX equivalents *)
VAR
   StdIn, StdOut, StdErr: File ;



(*
   IsNoError - returns a TRUE if no error has occured on file, f.
*)

PROCEDURE IsNoError (f: File) : BOOLEAN ;


(*
   Exists - returns TRUE if a file named, fname exists for reading.
*)

PROCEDURE Exists (fname: ARRAY OF CHAR) : BOOLEAN ;


(*
   OpenToRead - attempts to open a file, fname, for reading and
                it returns this file.
                The success of this operation can be checked by
                calling IsNoError.
*)

PROCEDURE OpenToRead (fname: ARRAY OF CHAR) : File ;


(*
   OpenToWrite - attempts to open a file, fname, for write and
                 it returns this file.
                 The success of this operation can be checked by
                 calling IsNoError.
*)

PROCEDURE OpenToWrite (fname: ARRAY OF CHAR) : File ;


(*
   OpenForRandom - attempts to open a file, fname, for random access
                   read or write and it returns this file.
                   The success of this operation can be checked by
                   calling IsNoError.
                   towrite, determines whether the file should be
                   opened for writing or reading.
*)

PROCEDURE OpenForRandom (fname: ARRAY OF CHAR; towrite: BOOLEAN) : File ;


(*
   Close - close a file which has been previously opened using:
           OpenToRead, OpenToWrite, OpenForRandom.
           It is correct to close a file which has an error status.
*)

PROCEDURE Close (f: File) ;


(* the following functions are functionally equivalent to the above
   except they allow C style names.
*)

PROCEDURE exists        (fname: ADDRESS; flength: CARDINAL) : BOOLEAN ;
PROCEDURE openToRead    (fname: ADDRESS; flength: CARDINAL) : File ;
PROCEDURE openToWrite   (fname: ADDRESS; flength: CARDINAL) : File ;
PROCEDURE openForRandom (fname: ADDRESS; flength: CARDINAL; towrite: BOOLEAN) : File ;


(*
   FlushBuffer - flush contents of the FIO file, f, to libc.
*)

PROCEDURE FlushBuffer (f: File) ;


(*
   ReadNBytes - reads nBytes of a file into memory area, a, returning
                the number of bytes actually read.
                This function will consume from the buffer and then
                perform direct libc reads. It is ideal for large reads.
*)

PROCEDURE ReadNBytes (f: File; nBytes: CARDINAL; a: ADDRESS) : CARDINAL ;


(*
   ReadAny - reads HIGH(a) bytes into, a. All input
             is fully buffered, unlike ReadNBytes and thus is more
             suited to small reads.
*)

PROCEDURE ReadAny (f: File; VAR a: ARRAY OF BYTE) ;


(*
   WriteNBytes - writes nBytes of a file into memory area, a, returning
                 the number of bytes actually written.
                 This function will flush the buffer and then
                 write the nBytes using a direct write from libc.
                 It is ideal for large writes.
*)

PROCEDURE WriteNBytes (f: File; nBytes: CARDINAL; a: ADDRESS) : CARDINAL ;


(*
   WriteAny - writes HIGH(a) bytes onto, file, f. All output
              is fully buffered, unlike WriteNBytes and thus is more
              suited to small writes.
*)

PROCEDURE WriteAny (f: File; VAR a: ARRAY OF BYTE) ;


(*
   WriteChar - writes a single character to file, f.
*)

PROCEDURE WriteChar (f: File; ch: CHAR) ;


(*
   EOF - tests to see whether a file, f, has reached end of file.
*)

PROCEDURE EOF (f: File) : BOOLEAN ;


(*
   EOLN - tests to see whether a file, f, is upon a newline.
          It does NOT consume the newline.
*)

PROCEDURE EOLN (f: File) : BOOLEAN ;


(*
   ReadChar - returns a character read from file, f.
              Sensible to check with IsNoError or EOF after calling
              this function.
*)

PROCEDURE ReadChar (f: File) : CHAR ;


(*
   UnReadChar - replaces a character, ch, back into file, f.
                This character must have been read by ReadChar
                and it does not allow successive calls.
*)

PROCEDURE UnReadChar (f: File ; ch: CHAR) ;


(*
   WriteLine - writes out a linefeed to file, f.
*)

PROCEDURE WriteLine (f: File) ;


(*
   WriteString - writes a string to file, f.
*)

PROCEDURE WriteString (f: File; a: ARRAY OF CHAR) ;


(*
   ReadString - reads a string from file, f, into string, a.
                It terminates the string if HIGH is reached or
                if a newline is seen or an error occurs.
*)

PROCEDURE ReadString (f: File; VAR a: ARRAY OF CHAR) ;


(*
   WriteCardinal - writes a CARDINAL to file, f.
                   It writes the binary image of the CARDINAL.
                   to file, f.
*)

PROCEDURE WriteCardinal (f: File; c: CARDINAL) ;


(*
   ReadCardinal - reads a CARDINAL from file, f.
                  It reads a bit image of a CARDINAL
                  from file, f.
*)

PROCEDURE ReadCardinal (f: File) : CARDINAL ;


(*
   GetUnixFileDescriptor - returns the UNIX file descriptor of a file.
                           Useful when combining FIO.mod with select
                           (in Selective.def - but note the comments in
                            Selective about using read/write primatives)
*)

PROCEDURE GetUnixFileDescriptor (f: File) : INTEGER ;


(*
   SetPositionFromBeginning - sets the position from the beginning of the file.
*)

PROCEDURE SetPositionFromBeginning (f: File; pos: LONGINT) ;


(*
   SetPositionFromEnd - sets the position from the end of the file.
*)

PROCEDURE SetPositionFromEnd (f: File; pos: LONGINT) ;


(*
   FindPosition - returns the current absolute position in file, f.
*)

PROCEDURE FindPosition (f: File) : CARDINAL ;


(*
   GetFileName - assigns, a, with the filename associated with, f.
*)

PROCEDURE GetFileName (f: File; VAR a: ARRAY OF CHAR) ;


END FIO.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.21 gm2-libs/NumberIO

 
DEFINITION MODULE NumberIO ;

(*
   Description: Provides all the input/output of numbers, and also the conversion
                of numbers to strings and visa versa.
*)

EXPORT QUALIFIED ReadCard, WriteCard, ReadHex, WriteHex, ReadInt, WriteInt,
                 CardToStr, StrToCard, StrToHex, HexToStr, StrToInt, IntToStr,
                 ReadOct, WriteOct, OctToStr, StrToOct,
                 ReadBin, WriteBin, BinToStr, StrToBin,
                 StrToBinInt, StrToHexInt, StrToOctInt ;


PROCEDURE ReadCard (VAR x: CARDINAL) ;

PROCEDURE WriteCard (x, n: CARDINAL) ;

PROCEDURE ReadHex (VAR x: CARDINAL) ;

PROCEDURE WriteHex (x, n: CARDINAL) ;

PROCEDURE ReadInt (VAR x: INTEGER) ;

PROCEDURE WriteInt (x: INTEGER ; n: CARDINAL) ;

PROCEDURE CardToStr (x, n: CARDINAL ; VAR a: ARRAY OF CHAR) ;

PROCEDURE StrToCard (a: ARRAY OF CHAR ; VAR x: CARDINAL) ;

PROCEDURE HexToStr (x, n: CARDINAL ; VAR a: ARRAY OF CHAR) ;

PROCEDURE StrToHex (a: ARRAY OF CHAR ; VAR x: CARDINAL) ;

PROCEDURE IntToStr (x: INTEGER ; n: CARDINAL ; VAR a: ARRAY OF CHAR) ;

PROCEDURE StrToInt (a: ARRAY OF CHAR ; VAR x: INTEGER) ;

PROCEDURE ReadOct (VAR x: CARDINAL) ;

PROCEDURE WriteOct (x, n: CARDINAL) ;

PROCEDURE OctToStr (x, n: CARDINAL ; VAR a: ARRAY OF CHAR) ;

PROCEDURE StrToOct (a: ARRAY OF CHAR ; VAR x: CARDINAL) ;

PROCEDURE ReadBin (VAR x: CARDINAL) ;

PROCEDURE WriteBin (x, n: CARDINAL) ;

PROCEDURE BinToStr (x, n: CARDINAL ; VAR a: ARRAY OF CHAR) ;

PROCEDURE StrToBin (a: ARRAY OF CHAR ; VAR x: CARDINAL) ;

PROCEDURE StrToBinInt (a: ARRAY OF CHAR ; VAR x: INTEGER) ;

PROCEDURE StrToHexInt (a: ARRAY OF CHAR ; VAR x: INTEGER) ;

PROCEDURE StrToOctInt (a: ARRAY OF CHAR ; VAR x: INTEGER) ;


END NumberIO.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.22 gm2-libs/M2EXCEPTION

 
DEFINITION MODULE M2EXCEPTION;

(* Provides facilities for identifying language exceptions *)

TYPE
  M2Exceptions =
    (indexException,     rangeException,         caseSelectException,  invalidLocation,
     functionException,  wholeValueException,    wholeDivException,    realValueException,
     realDivException,   complexValueException,  complexDivException,  protException,
     sysException,       coException,            exException
    );

PROCEDURE M2Exception (): M2Exceptions;
  (* 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 IsM2Exception (): BOOLEAN;
  (* If the current coroutine is in the exceptional execution state because of the raising
     of a language exception, returns TRUE, and otherwise returns FALSE.
  *)

END M2EXCEPTION.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.23 gm2-libs/StdIO

 
DEFINITION MODULE StdIO ;

(*
   Description: Exports a general Read and Write procedure that ALL character
                processes should use.
*)

EXPORT QUALIFIED ProcRead, ProcWrite,
                 Read, Write, PushOutput, PopOutput, GetCurrentOutput ;


TYPE
   ProcWrite = PROCEDURE (CHAR) ;
   ProcRead  = PROCEDURE (VAR CHAR) ;


(*
   Read - is the generic procedure that all higher application layers
          should use to receive a character.
*)

PROCEDURE Read (VAR ch: CHAR) ;


(*
   Write - is the generic procedure that all higher application layers
           should use to emit a character.
*)

PROCEDURE Write (ch: CHAR) ;


(*
   PushOutput - pushes the current Write procedure onto a stack,
                any future references to Write will actually invoke
                procedure, p.
*)

PROCEDURE PushOutput (p: ProcWrite) ;


(*
   PopOutput - restores Write to use the previous output procedure.
*)

PROCEDURE PopOutput ;


(*
   GetCurrentOutput - returns the current output procedure.
*)

PROCEDURE GetCurrentOutput () : ProcWrite ;


END StdIO.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.24 gm2-libs/wrapc

 
DEFINITION MODULE wrapc ;

(*
   Description: Provides a Modula-2 interface to the C
                library functionality.
*)

FROM SYSTEM IMPORT ADDRESS ;

EXPORT QUALIFIED strtime, filesize, getrand, getusername, filemtime,
                 getnameuidgid ;


(*
   strtime - returns the C string for the equivalent C asctime
             function.
*)

PROCEDURE strtime () : ADDRESS ;


(*
   filesize - assigns the size of a file, f, into low, high and
              returns zero if successful.
*)

PROCEDURE filesize (f: INTEGER; VAR low, high: CARDINAL) : INTEGER ;


(*
   filemtime - returns the mtime of a file, f.
*)

PROCEDURE filemtime (f: INTEGER) : INTEGER ;


(*
   getrand - returns a random number between 0..n-1
*)

PROCEDURE getrand (n: INTEGER) : INTEGER ;


(*
   getusername - returns a C string describing the current user.
*)

PROCEDURE getusername () : ADDRESS ;


(*
   getnameuidgid - fills in the, uid, and, gid, which represents
                   user, name.
*)

PROCEDURE getnameuidgid (name: ADDRESS; VAR uid, gid: INTEGER) ;


END wrapc.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.25 gm2-libs/cxxabi

 
DEFINITION MODULE FOR "C" cxxabi ;

(*
    Description: provides a minimal Modula-2 implementation of the
                 C++ABI exception handling routines used in g++.
                 This should only be used by the compiler.
*)

FROM SYSTEM IMPORT ADDRESS ;
EXPORT UNQUALIFIED __cxa_begin_catch, __cxa_end_catch, __cxa_rethrow ;


PROCEDURE __cxa_begin_catch (a: ADDRESS) : ADDRESS ;
PROCEDURE __cxa_end_catch ;
PROCEDURE __cxa_rethrow ;


END cxxabi.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.26 gm2-libs/StringConvert

 
DEFINITION MODULE StringConvert ;

(*
    Description: provides functions to convert numbers to and from strings.
*)

FROM DynamicStrings IMPORT String ;
EXPORT QUALIFIED IntegerToString, StringToInteger,
                 StringToLongInteger, LongIntegerToString,
                 StringToCardinal, CardinalToString,
                 StringToLongCardinal, LongCardinalToString,
                 StringToShortCardinal, ShortCardinalToString,
                 StringToLongreal, LongrealToString,
                 ToSigFig,
                 stoi, itos, ctos, stoc, hstoi, ostoi, bstoi,
                 hstoc, ostoc, bstoc,
                 stor, stolr ;


(*
   IntegerToString - converts INTEGER, i, into a String. The field with
                     can be specified if non zero. Leading characters
                     are defined by padding and this function will
                     prepend a + if sign is set to TRUE.
                     The base allows the caller to generate binary,
                     octal, decimal, hexidecimal numbers.
                     The value of lower is only used when hexidecimal
                     numbers are generated and if TRUE then digits
                     abcdef are used, and if FALSE then ABCDEF are used.
*)

PROCEDURE IntegerToString (i: INTEGER; width: CARDINAL; padding: CHAR; sign: BOOLEAN;
                           base: CARDINAL; lower: BOOLEAN) : String ;


(*
   CardinalToString - converts CARDINAL, c, into a String. The field
                      width can be specified if non zero. Leading
                      characters are defined by padding.
                      The base allows the caller to generate binary,
                      octal, decimal, hexidecimal numbers.
                      The value of lower is only used when hexidecimal
                      numbers are generated and if TRUE then digits
                      abcdef are used, and if FALSE then ABCDEF are used.
*)

PROCEDURE CardinalToString (c: CARDINAL; width: CARDINAL; padding: CHAR;
                            base: CARDINAL; lower: BOOLEAN) : String ;


(*
   StringToInteger - converts a string, s, of, base, into an INTEGER.
                     Leading white space is ignored. It stops converting
                     when either the string is exhausted or if an illegal
                     numeral is found.
                     The parameter found is set TRUE if a number was found.
*)

PROCEDURE StringToInteger (s: String; base: CARDINAL; VAR found: BOOLEAN) : INTEGER ;


(*
   StringToCardinal - converts a string, s, of, base, into a CARDINAL.
                      Leading white space is ignored. It stops converting
                      when either the string is exhausted or if an illegal
                      numeral is found.
                      The parameter found is set TRUE if a number was found.
*)

PROCEDURE StringToCardinal (s: String; base: CARDINAL; VAR found: BOOLEAN) : CARDINAL ;


(*
   LongIntegerToString - converts LONGINT, i, into a String. The field with
                         can be specified if non zero. Leading characters
                         are defined by padding and this function will
                         prepend a + if sign is set to TRUE.
                         The base allows the caller to generate binary,
                         octal, decimal, hexidecimal numbers.
                         The value of lower is only used when hexidecimal
                         numbers are generated and if TRUE then digits
                         abcdef are used, and if FALSE then ABCDEF are used.
*)

PROCEDURE LongIntegerToString (i: LONGINT; width: CARDINAL; padding: CHAR;
                               sign: BOOLEAN; base: CARDINAL; lower: BOOLEAN) : String ;



(*
   StringToLongInteger - converts a string, s, of, base, into an LONGINT.
                         Leading white space is ignored. It stops converting
                         when either the string is exhausted or if an illegal
                         numeral is found.
                         The parameter found is set TRUE if a number was found.
*)

PROCEDURE StringToLongInteger (s: String; base: CARDINAL; VAR found: BOOLEAN) : LONGINT ;


(*
   LongCardinalToString - converts LONGCARD, c, into a String. The field
                          width can be specified if non zero. Leading
                          characters are defined by padding.
                          The base allows the caller to generate binary,
                          octal, decimal, hexidecimal numbers.
                          The value of lower is only used when hexidecimal
                          numbers are generated and if TRUE then digits
                          abcdef are used, and if FALSE then ABCDEF are used.
*)

PROCEDURE LongCardinalToString (c: LONGCARD; width: CARDINAL; padding: CHAR;
                                base: CARDINAL; lower: BOOLEAN) : String ;


(*
   StringToLongCardinal - converts a string, s, of, base, into a LONGCARD.
                          Leading white space is ignored. It stops converting
                          when either the string is exhausted or if an illegal
                          numeral is found.
                          The parameter found is set TRUE if a number was found.
*)

PROCEDURE StringToLongCardinal (s: String; base: CARDINAL; VAR found: BOOLEAN) : LONGCARD ;


(*
   ShortCardinalToString - converts SHORTCARD, c, into a String. The field
                           width can be specified if non zero. Leading
                           characters are defined by padding.
                           The base allows the caller to generate binary,
                           octal, decimal, hexidecimal numbers.
                           The value of lower is only used when hexidecimal
                           numbers are generated and if TRUE then digits
                           abcdef are used, and if FALSE then ABCDEF are used.
*)

PROCEDURE ShortCardinalToString (c: SHORTCARD; width: CARDINAL; padding: CHAR;
                                 base: CARDINAL; lower: BOOLEAN) : String ;


(*
   StringToShortCardinal - converts a string, s, of, base, into a SHORTCARD.
                           Leading white space is ignored. It stops converting
                           when either the string is exhausted or if an illegal
                           numeral is found.
                           The parameter found is set TRUE if a number was found.
*)

PROCEDURE StringToShortCardinal (s: String; base: CARDINAL;
                                 VAR found: BOOLEAN) : SHORTCARD ;


(*
   stoi - decimal string to INTEGER
*)

PROCEDURE stoi (s: String) : INTEGER ;


(*
   itos - integer to decimal string.
*)

PROCEDURE itos (i: INTEGER; width: CARDINAL; padding: CHAR; sign: BOOLEAN) : String ;


(*
   ctos - cardinal to decimal string.
*)

PROCEDURE ctos (c: CARDINAL; width: CARDINAL; padding: CHAR) : String ;


(*
   stoc - decimal string to CARDINAL
*)

PROCEDURE stoc (s: String) : CARDINAL ;


(*
   hstoi - hexidecimal string to INTEGER
*)

PROCEDURE hstoi (s: String) : INTEGER ;


(*
   ostoi - octal string to INTEGER
*)

PROCEDURE ostoi (s: String) : INTEGER ;


(*
   bstoi - binary string to INTEGER
*)

PROCEDURE bstoi (s: String) : INTEGER ;


(*
   hstoc - hexidecimal string to CARDINAL
*)

PROCEDURE hstoc (s: String) : CARDINAL ;


(*
   ostoc - octal string to CARDINAL
*)

PROCEDURE ostoc (s: String) : CARDINAL ;


(*
   bstoc - binary string to CARDINAL
*)

PROCEDURE bstoc (s: String) : CARDINAL ;


(*
   StringToLongreal - returns a LONGREAL and sets found to TRUE
                      if a legal number is seen.
*)

PROCEDURE StringToLongreal (s: String; VAR found: BOOLEAN) : LONGREAL ;


(*
   LongrealToString - converts a LONGREAL number, Real, which has,
                      TotalWidth, and FractionWidth into a string.

                      So for example:

                      LongrealToString(1.0, 4, 2)  -> '1.00'
                      LongrealToString(12.3, 5, 2) -> '12.30'
                      LongrealToString(12.3, 6, 2) -> ' 12.30'
                      LongrealToString(12.3, 6, 3) -> '12.300'

                      if total width is too small then the fraction
                      becomes truncated.

                      LongrealToString(12.3, 5, 3) -> '12.30'

                      If TotalWidth is 0 then the function
                      will return the value of x which is converted
                      into as a fixed point number with exhaustive
                      precision.
*)

PROCEDURE LongrealToString (x: LONGREAL;
                            TotalWidth, FractionWidth: CARDINAL) : String ;


(*
   stor - returns a REAL given a string.
*)

PROCEDURE stor (s: String) : REAL ;


(*
   stolr - returns a LONGREAL given a string.
*)

PROCEDURE stolr (s: String) : LONGREAL ;


(*
   ToSigFig - returns a floating point or base 10 integer
              string which is accurate to, n, significat figures.
*)

PROCEDURE ToSigFig (s: String; n: CARDINAL) : String ;


END StringConvert.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.27 gm2-libs/Args

 
DEFINITION MODULE Args ;

(*
    Description: provides a simple interface to the command
                 line arguments.
*)

EXPORT QUALIFIED GetArg, Narg ;


(*
   GetArg - returns the nth argument from the command line.
            The success of the operation is returned.
*)

PROCEDURE GetArg (VAR a: ARRAY OF CHAR ; i: CARDINAL) : BOOLEAN ;


(*
   Narg - returns the number of arguments available from
          command line.
*)

PROCEDURE Narg() : CARDINAL ;


END Args.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.28 gm2-libs/MathLib0

 
DEFINITION MODULE MathLib0 ;

(*
    Description: provides access to math functions.
*)

CONST
   pi   = 3.1415926535897932384626433832795028841972;
   exp1 = 2.7182818284590452353602874713526624977572;


PROCEDURE __BUILTIN__ sqrt (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ sqrtl (x: LONGREAL) : LONGREAL ;
PROCEDURE __BUILTIN__ sqrts (x: SHORTREAL) : SHORTREAL ;

PROCEDURE exp (x: REAL) : REAL ;
PROCEDURE expl (x: LONGREAL) : LONGREAL ;
PROCEDURE exps (x: SHORTREAL) : SHORTREAL ;

PROCEDURE ln (x: REAL) : REAL ;
PROCEDURE lnl (x: LONGREAL) : LONGREAL ;
PROCEDURE lns (x: SHORTREAL) : SHORTREAL ;

PROCEDURE __BUILTIN__ sin (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ sinl (x: LONGREAL) : LONGREAL ;
PROCEDURE __BUILTIN__ sins (x: SHORTREAL) : SHORTREAL ;

PROCEDURE __BUILTIN__ cos (x: REAL) : REAL ;
PROCEDURE __BUILTIN__ cosl (x: LONGREAL) : LONGREAL ;
PROCEDURE __BUILTIN__ coss (x: SHORTREAL) : SHORTREAL ;

PROCEDURE tan (x: REAL) : REAL ;
PROCEDURE tanl (x: LONGREAL) : LONGREAL ;
PROCEDURE tans (x: SHORTREAL) : SHORTREAL ;

PROCEDURE arctan (x: REAL) : REAL ;
PROCEDURE arctanl (x: LONGREAL) : LONGREAL ;
PROCEDURE arctans (x: SHORTREAL) : SHORTREAL ;

PROCEDURE entier (x: REAL) : INTEGER ;
PROCEDURE entierl (x: LONGREAL) : INTEGER ;
PROCEDURE entiers (x: SHORTREAL) : INTEGER ;

END MathLib0.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.29 gm2-libs/RTExceptions

 
DEFINITION MODULE RTExceptions ;

(*
    Description: runtime exception handler routines.  This should
                 be considered as a system module for GNU Modula-2
                 and allow the compiler to interface with exception
                 handling.
*)

FROM SYSTEM IMPORT ADDRESS ;
EXPORT QUALIFIED EHBlock,
                 Raise, SetExceptionBlock, GetExceptionBlock,
                 GetTextBuffer, GetTextBufferSize, GetNumber,
                 InitExceptionBlock, KillExceptionBlock,
                 PushHandler, PopHandler,
                 BaseExceptionsThrow, DefaultErrorCatch,
                 IsInExceptionState, SetExceptionState,
                 SwitchExceptionState, GetBaseExceptionBlock ;

TYPE
   EHBlock ;
   ProcedureHandler = PROCEDURE ;


(*
   Raise - invoke the exception handler associated with, number,
           in the active EHBlock.  It keeps a record of the number
           and message in the EHBlock for later use.
*)

PROCEDURE Raise (number: CARDINAL;
                 file: ADDRESS; line: CARDINAL;
                 column: CARDINAL; function: ADDRESS;
                 message: ADDRESS) ;


(*
   SetExceptionBlock - sets, source, as the active EHB.
*)

PROCEDURE SetExceptionBlock (source: EHBlock) ;


(*
   GetExceptionBlock - returns the active EHB.
*)

PROCEDURE GetExceptionBlock () : EHBlock ;


(*
   GetTextBuffer - returns the address of the EHB buffer.
*)

PROCEDURE GetTextBuffer (e: EHBlock) : ADDRESS ;


(*
   GetTextBufferSize - return the size of the EHB text buffer.
*)

PROCEDURE GetTextBufferSize (e: EHBlock) : CARDINAL ;


(*
   GetNumber - return the exception number associated with,
               source.
*)

PROCEDURE GetNumber (source: EHBlock) : CARDINAL ;


(*
   InitExceptionBlock - creates and returns a new exception block.
*)

PROCEDURE InitExceptionBlock () : EHBlock ;


(*
   KillExceptionBlock - destroys the EHB, e, and all its handlers.
*)

PROCEDURE KillExceptionBlock (e: EHBlock) : EHBlock ;


(*
   PushHandler - install a handler in EHB, e.
*)

PROCEDURE PushHandler (e: EHBlock; number: CARDINAL; p: ProcedureHandler) ;


(*
   PopHandler - removes the handler associated with, number, from
                EHB, e.
*)

PROCEDURE PopHandler (e: EHBlock; number: CARDINAL) ;


(*
   DefaultErrorCatch - displays the current error message in
                       the current exception block and then
                       calls HALT.
*)

PROCEDURE DefaultErrorCatch ;


(*
   BaseExceptionsThrow - configures the Modula-2 exceptions to call
                         THROW which in turn can be caught by an
                         exception block.  If this is not called then
                         a Modula-2 exception will simply call an
                         error message routine and then HALT.
*)

PROCEDURE BaseExceptionsThrow ;


(*
   IsInExceptionState - returns TRUE if the program is currently
                        in the exception state.
*)

PROCEDURE IsInExceptionState () : BOOLEAN ;


(*
   SetExceptionState - returns the current exception state and
                       then sets the current exception state to,
                       to.
*)

PROCEDURE SetExceptionState (to: BOOLEAN) : BOOLEAN ;


(*
   SwitchExceptionState - assigns, from, with the current exception
                          state and then assigns the current exception
                          to, to.
*)

PROCEDURE SwitchExceptionState (VAR from: BOOLEAN; to: BOOLEAN) ;


(*
   GetBaseExceptionBlock - returns the initial language exception block
                           created.
*)

PROCEDURE GetBaseExceptionBlock ;


END RTExceptions.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.30 gm2-libs/Assertion

 
DEFINITION MODULE Assertion ;

(*
   Description: Provides an assert procedure.
*)

EXPORT QUALIFIED Assert ;


(*
   Assert - tests the boolean Condition, if it fails then HALT is called.
*)

PROCEDURE Assert (Condition: BOOLEAN) ;


END Assertion.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.31 gm2-libs/ASCII

 
DEFINITION MODULE ASCII ;

(*
   Desciption: Defines all ascii constants (as in man ASCII)
               Note that lf, eof and EOL are added
*)

EXPORT QUALIFIED
     nul, soh, stx, etx, eot, enq, ack, bel,
     bs , ht , nl , vt , np , cr , so , si ,
     dle, dc1, dc2, dc3, dc4, nak, syn, etb,
     can, em , sub, esc, fs , gs , rs , us ,
     sp ,  (* All the above are in order *)
     lf, ff, eof, del, tab, EOL ;

CONST
     nul=000C; soh=001C; stx=002C; etx=003C;
     eot=004C; enq=005C; ack=006C; bel=007C;
     bs =010C; ht =011C; nl =012C; vt =013C;
     np =014C; cr =015C; so =016C; si =017C;
     dle=020C; dc1=021C; dc2=022C; dc3=023C;
     dc4=024C; nak=025C; syn=026C; etb=027C;
     can=030C; em =031C; sub=032C; esc=033C;
     fs =034C; gs =035C; rs =036C; us =037C;
     sp =040C; (* All the above are in order *)
     lf =nl  ; ff =np  ; eof=eot ; tab=ht  ;
     del=177C; EOL=nl  ;

END ASCII.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.32 gm2-libs/cbuiltin

 
DEFINITION MODULE FOR "C" cbuiltin ;

(*
    Description: provides replacement routines in case the builtins are
                 not used by GNU Modula-2.  This module is called by
                 implementation modules which implement builtins
                 (see Builtins.mod for an example).
*)

FROM SYSTEM IMPORT ADDRESS ;
EXPORT UNQUALIFIED alloca, memcpy,
                   sinf, sinl, sin,
                   cosf, cosl, cos,
                   sqrtf, sqrtl, sqrt,
                   fabsf, fabsl, fabs,
                   logf, logl, log,
                   expf, expl, exp,
                   log10f, log10l, log10,
                   index, rindex,
                   memcmp, memset, memmove,
                   strcat, strncat, strcpy, strncpy, strcmp, strncmp,
                   strlen, strstr, strpbrk, strspn, strcspn, strchr, strrchr ;

PROCEDURE alloca (i: CARDINAL) : ADDRESS ;
PROCEDURE memcpy (dest, src: ADDRESS; n: CARDINAL) : ADDRESS ;
PROCEDURE sinf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE sin (x: REAL) : REAL ;
PROCEDURE sinl (x: LONGREAL) : LONGREAL ;
PROCEDURE cosf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE cos (x: REAL) : REAL ;
PROCEDURE cosl (x: LONGREAL) : LONGREAL ;
PROCEDURE sqrtf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE sqrt (x: REAL) : REAL ;
PROCEDURE sqrtl (x: LONGREAL) : LONGREAL ;
PROCEDURE fabsf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE fabs (x: REAL) : REAL ;
PROCEDURE fabsl (x: LONGREAL) : LONGREAL ;
PROCEDURE logf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE log (x: REAL) : REAL ;
PROCEDURE logl (x: LONGREAL) : LONGREAL ;
PROCEDURE expf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE exp (x: REAL) : REAL ;
PROCEDURE expl (x: LONGREAL) : LONGREAL ;
PROCEDURE log10f (x: SHORTREAL) : SHORTREAL ;
PROCEDURE log10 (x: REAL) : REAL ;
PROCEDURE log10l (x: LONGREAL) : LONGREAL ;
PROCEDURE exp10f (x: SHORTREAL) : SHORTREAL ;
PROCEDURE exp10 (x: REAL) : REAL ;
PROCEDURE exp10l (x: LONGREAL) : LONGREAL ;
PROCEDURE index (s: ADDRESS; c: INTEGER) : ADDRESS ;
PROCEDURE rindex (s: ADDRESS; c: INTEGER) : ADDRESS ;
PROCEDURE memcmp (s1, s2: ADDRESS; n: CARDINAL) : INTEGER ;
PROCEDURE memmove (s1, s2: ADDRESS; n: CARDINAL) : ADDRESS ;
PROCEDURE memset (s: ADDRESS; c: INTEGER; n: CARDINAL) : ADDRESS ;
PROCEDURE strcat (dest, src: ADDRESS) : ADDRESS ;
PROCEDURE strncat (dest, src: ADDRESS; n: CARDINAL) : ADDRESS ;
PROCEDURE strcpy (dest, src: ADDRESS) : ADDRESS ;
PROCEDURE strncpy (dest, src: ADDRESS; n: CARDINAL) : ADDRESS ;
PROCEDURE strcmp (s1, s2: ADDRESS) : INTEGER ;
PROCEDURE strncmp (s1, s2: ADDRESS; n: CARDINAL) : INTEGER ;
PROCEDURE strlen (s: ADDRESS) : INTEGER ;
PROCEDURE strstr (haystack, needle: ADDRESS) : ADDRESS ;
PROCEDURE strpbrk (s, accept: ADDRESS) : ADDRESS ;
PROCEDURE strspn (s, accept: ADDRESS) : CARDINAL ;
PROCEDURE strcspn (s, accept: ADDRESS) : CARDINAL ;
PROCEDURE strchr (s: ADDRESS; c: INTEGER) : ADDRESS ;
PROCEDURE strrchr (s: ADDRESS; c: INTEGER) : ADDRESS ;

END cbuiltin.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.33 gm2-libs/FpuIO

 
DEFINITION MODULE FpuIO ;

(*
   Description: Implements a fixed format input/output for REAL,
                LONGREAL and LONGINT numbers
*)

EXPORT QUALIFIED ReadReal, WriteReal, StrToReal, RealToStr,
                 ReadLongReal, WriteLongReal, StrToLongReal, LongRealToStr,
                 ReadLongInt, WriteLongInt, StrToLongInt, LongIntToStr ;


PROCEDURE ReadReal (VAR x: REAL) ;
PROCEDURE WriteReal (x: REAL; TotalWidth, FractionWidth: CARDINAL) ;
PROCEDURE StrToReal (a: ARRAY OF CHAR ; VAR x: REAL) ;
PROCEDURE RealToStr (x: REAL; TotalWidth, FractionWidth: CARDINAL; VAR a: ARRAY OF CHAR) ;

PROCEDURE ReadLongReal (VAR x: LONGREAL) ;
PROCEDURE WriteLongReal (x: LONGREAL; TotalWidth, FractionWidth: CARDINAL) ;
PROCEDURE StrToLongReal (a: ARRAY OF CHAR ; VAR x: LONGREAL) ;
PROCEDURE LongRealToStr (x: LONGREAL; TotalWidth, FractionWidth: CARDINAL; VAR a: ARRAY OF CHAR) ;

PROCEDURE ReadLongInt (VAR x: LONGINT) ;
PROCEDURE WriteLongInt (x: LONGINT; n: CARDINAL) ;
PROCEDURE StrToLongInt (a: ARRAY OF CHAR ; VAR x: LONGINT) ;
PROCEDURE LongIntToStr (x: LONGINT; n: CARDINAL; VAR a: ARRAY OF CHAR) ;


END FpuIO.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.34 gm2-libs/M2RTS

 
DEFINITION MODULE M2RTS ;

(*
   Description: Implements the run time system facilities of Modula-2.
*)

FROM SYSTEM IMPORT BITSET, ADDRESS ;
EXPORT QUALIFIED HALT, Halt,
                 InstallTerminationProcedure, Terminate,
                 ExitOnHalt, Length,
                 AssignmentException,
                 IncException, DecException, InclException, ExclException,
                 StaticArraySubscriptException, DynamicArraySubscriptException,
                 ForLoopBeginException, ForLoopToException, ForLoopEndException,
                 PointerNilException, NoReturnException,
                 WholeNonPosDivException, WholeNonPosModException,
                 WholeZeroDivException, WholeZeroRemException,
                 CaseException, NoException ;


(*
   HALT - terminate the current program.
          The procedure Terminate is called before the program is
          stopped.
*)

PROCEDURE HALT ;


(*
   Halt - provides a more user friendly version of HALT, which takes
          four parameters to aid debugging.
*)

PROCEDURE Halt (file: ARRAY OF CHAR; line: CARDINAL;
                function: ARRAY OF CHAR; description: ARRAY OF CHAR) ;


(*
   ExitOnHalt - if HALT is executed then call exit with the exit code, e.
*)

PROCEDURE ExitOnHalt (e: INTEGER) ;


(*
   InstallTerminationProcedure - installs a procedure, p, which will
                                 be called when the procedure Terminate
                                 is invoked.
*)

PROCEDURE InstallTerminationProcedure (p: PROC) ;


(*
   Terminate - calls each installed termination procedure in turn.
*)

PROCEDURE Terminate ;


(*
   Length - returns the length of a string, a. This is called whenever
            the user calls LENGTH and the parameter cannot be calculated
            at compile time.
*)

PROCEDURE Length (a: ARRAY OF CHAR) : CARDINAL ;


(*
   The following are the runtime exception handler routines.
*)

PROCEDURE AssignmentException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE IncException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE DecException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE InclException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE ExclException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE StaticArraySubscriptException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE DynamicArraySubscriptException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE ForLoopBeginException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE ForLoopToException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE ForLoopEndException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE PointerNilException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE NoReturnException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE CaseException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE WholeNonPosDivException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE WholeNonPosModException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE WholeZeroDivException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE WholeZeroRemException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;
PROCEDURE NoException (filename: ADDRESS; line, column: CARDINAL; scope: ADDRESS) ;


END M2RTS.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.35 gm2-libs/DynamicStrings

 
DEFINITION MODULE DynamicStrings ;

(*
    Description: provides a dynamic string type and common methods.
*)

FROM SYSTEM IMPORT ADDRESS ;
EXPORT QUALIFIED String,
                 InitString, KillString, Fin, InitStringCharStar, InitStringChar,
                 Index, RIndex,
                 Mark, Length, ConCat, ConCatChar, Assign, Dup, Add,
                 Equal, EqualCharStar, EqualArray, ToUpper, ToLower,
                 CopyOut, Mult, Slice,
                 RemoveWhitePrefix, RemoveWhitePostfix, RemoveComment,
                 char, string ;

TYPE
   String ;


(*
   InitString - creates and returns a String type object.
                Initial contents are, a.
*)

PROCEDURE InitString (a: ARRAY OF CHAR) : String ;


(*
   KillString - frees String, s, and its contents.
                NIL is returned.
*)

PROCEDURE KillString (s: String) : String ;


(*
   Fin - finishes with a string, it calls KillString with, s.
         The purpose of the procedure is to provide a short cut
         to calling KillString and then testing the return result.
*)

PROCEDURE Fin (s: String) ;


(*
   InitStringCharStar - initializes and returns a String to contain the C string.
*)

PROCEDURE InitStringCharStar (a: ADDRESS) : String ;


(*
   InitStringChar - initializes and returns a String to contain the single character, ch.
*)

PROCEDURE InitStringChar (ch: CHAR) : String ;


(*
   Mark - marks String, s, ready for garbage collection.
*)

PROCEDURE Mark (s: String) : String ;


(*
   Length - returns the length of the String, s.
*)

PROCEDURE Length (s: String) : CARDINAL ;


(*
   ConCat - returns String, a, after the contents of, b, have been appended.
*)

PROCEDURE ConCat (a, b: String) : String ;


(*
   ConCatChar - returns String, a, after character, ch, has been appended.
*)

PROCEDURE ConCatChar (a: String; ch: CHAR) : String ;


(*
   Assign - assigns the contents of, b, into, a.
            String, a, is returned.
*)

PROCEDURE Assign (a, b: String) : String ;


(*
   Dup - duplicate a String, s, returning the copy of s.
*)

PROCEDURE Dup (s: String) : String ;


(*
   Add - returns a new String which contains the contents of a and b.
*)

PROCEDURE Add (a, b: String) : String ;


(*
   Equal - returns TRUE if String, a, and, b, are equal.
*)

PROCEDURE Equal (a, b: String) : BOOLEAN ;


(*
   EqualCharStar - returns TRUE if contents of String, s, is the same as the
                   string, a.
*)

PROCEDURE EqualCharStar (s: String; a: ADDRESS) : BOOLEAN ;


(*
   EqualArray - returns TRUE if contents of String, s, is the same as the
                string, a.
*)

PROCEDURE EqualArray (s: String; a: ARRAY OF CHAR) : BOOLEAN ;


(*
   Mult - returns a new string which is n concatenations of String, s.
          If n<=0 then an empty string is returned.
*)

PROCEDURE Mult (s: String; n: CARDINAL) : String ;


(*
   Slice - returns a new string which contains the elements
           low..high-1

           strings start at element 0
           Slice(s, 0, 2)  will return elements 0, 1 but not 2
           Slice(s, 1, 3)  will return elements 1, 2 but not 3
           Slice(s, 2, 0)  will return elements 2..max
           Slice(s, 3, -1) will return elements 3..max-1
           Slice(s, 4, -2) will return elements 4..max-2
*)

PROCEDURE Slice (s: String; low, high: INTEGER) : String ;


(*
   Index - returns the indice of the first occurance of, ch, in
           String, s. -1 is returned if, ch, does not exist.
           The search starts at position, o.
*)

PROCEDURE Index (s: String; ch: CHAR; o: CARDINAL) : INTEGER ;


(*
   RIndex - returns the indice of the last occurance of, ch,
            in String, s. The search starts at position, o.
            -1 is returned if, ch, is not found.
*)

PROCEDURE RIndex (s: String; ch: CHAR; o: CARDINAL) : INTEGER ;


(*
   RemoveComment - assuming that, comment, is a comment delimiter
                   which indicates anything to its right is a comment
                   then strip off the comment and also any white space
                   on the remaining right hand side.
                   It leaves any white space on the left hand side alone.
*)

PROCEDURE RemoveComment (s: String; comment: CHAR) : String ;


(*
   RemoveWhitePrefix - removes any leading white space from String, s.
                       A new string is returned.
*)

PROCEDURE RemoveWhitePrefix (s: String) : String ;


(*
   RemoveWhitePostfix - removes any leading white space from String, s.
                        A new string is returned.
*)

PROCEDURE RemoveWhitePostfix (s: String) : String ;


(*
   ToUpper - returns string, s, after it has had its lower case characters
             replaced by upper case characters.
             The string, s, is not duplicated.
*)

PROCEDURE ToUpper (s: String) : String ;


(*
   ToLower - returns string, s, after it has had its upper case characters
             replaced by lower case characters.
             The string, s, is not duplicated.
*)

PROCEDURE ToLower (s: String) : String ;


(*
   CopyOut - copies string, s, to a.
*)

PROCEDURE CopyOut (VAR a: ARRAY OF CHAR; s: String) ;


(*
   char - returns the character, ch, at position, i, in String, s.
          As Slice the index can be negative so:

          char(s, 0) will return the first character
          char(s, 1) will return the second character
          char(s, -1) will return the last character
          char(s, -2) will return the penultimate character

          a nul character is returned if the index is out of range.
*)

PROCEDURE char (s: String; i: INTEGER) : CHAR ;


(*
   string - returns the C style char * of String, s.
*)

PROCEDURE string (s: String) : ADDRESS ;


END DynamicStrings.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.36 gm2-libs/CmdArgs

 
DEFINITION MODULE CmdArgs ;

(*
   Description: CmdArgs - implements procedures to retrieve arguments from
                a string.
*)

EXPORT QUALIFIED GetArg, Narg ;


(*
   GetArg - returns the nth argument from the command line, CmdLine
            the success of the operation is returned.
*)

PROCEDURE GetArg (CmdLine: ARRAY OF CHAR;
                  n: CARDINAL; VAR Argi: ARRAY OF CHAR) : BOOLEAN ;


(*
   Narg - returns the number of arguments available from
          command line, CmdLine.
*)

PROCEDURE Narg (CmdLine: ARRAY OF CHAR) : CARDINAL ;


END CmdArgs.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.37 gm2-libs/Debug

 
DEFINITION MODULE Debug ;

(*
    Description: provides some simple debugging routines.
*)

EXPORT QUALIFIED Halt, DebugString ;


(*
   Halt - writes a message in the format:
          Module:Line:Message

          It then terminates by calling HALT.
*)

PROCEDURE Halt (Message: ARRAY OF CHAR;
                LineNo: CARDINAL;
                Module: ARRAY OF CHAR) ;


(*
   DebugString - writes a string to the debugging device (Scn.Write).
                 It interprets \n as carriage return, linefeed.
*)

PROCEDURE DebugString (a: ARRAY OF CHAR) ;


END Debug.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.38 gm2-libs/SFIO

 
DEFINITION MODULE SFIO ;

(*
    Description: provides a String interface to the opening routines of FIO
*)

FROM DynamicStrings IMPORT String ;
FROM FIO IMPORT File ;

EXPORT QUALIFIED OpenToRead, OpenToWrite, OpenForRandom, Exists, WriteS, ReadS ;


(*
   Exists - returns TRUE if a file named, fname exists for reading.
*)

PROCEDURE Exists (fname: String) : BOOLEAN ;


(*
   OpenToRead - attempts to open a file, fname, for reading and
                it returns this file.
                The success of this operation can be checked by
                calling IsNoError.
*)

PROCEDURE OpenToRead (fname: String) : File ;


(*
   OpenToWrite - attempts to open a file, fname, for write and
                 it returns this file.
                 The success of this operation can be checked by
                 calling IsNoError.
*)

PROCEDURE OpenToWrite (fname: String) : File ;


(*
   OpenForRandom - attempts to open a file, fname, for random access
                   read or write and it returns this file.
                   The success of this operation can be checked by
                   calling IsNoError.
                   towrite, determines whether the file should be
                   opened for writing or reading.
*)

PROCEDURE OpenForRandom (fname: String; towrite: BOOLEAN) : File ;


(*
   WriteS - writes a string, s, to, file. It returns the String, s.
*)

PROCEDURE WriteS (file: File; s: String) : String ;


(*
   ReadS - reads a string, s, from, file. It returns the String, s.
           It stops reading the string at the end of line or end of file.
           It consumes the newline at the end of line but does not place
           this into the returned string.
*)

PROCEDURE ReadS (file: File) : String ;


END SFIO.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.39 gm2-libs/sckt

 
DEFINITION MODULE sckt ;

(*
    Description: provides a minimal interface to tcp sockets.
*)

FROM SYSTEM IMPORT ADDRESS ;
EXPORT UNQUALIFIED tcpServerState,
                   tcpServerEstablish, tcpServerEstablishPort,
                   tcpServerAccept, getLocalIP,
                   tcpServerPortNo, tcpServerIP, tcpServerSocketFd,
                   tcpServerClientIP, tcpServerClientPortNo,
                   tcpClientState,
                   tcpClientSocket, tcpClientSocketIP, tcpClientConnect,
                   tcpClientPortNo, tcpClientIP, tcpClientSocketFd ;

TYPE
   tcpServerState = ADDRESS ;
   tcpClientState = ADDRESS ;


(*
   tcpServerEstablish - returns a tcpState containing the relevant
                        information about a socket declared to receive
                        tcp connections.
*)

PROCEDURE tcpServerEstablish () : tcpServerState ;


(*
   tcpServerEstablishPort - returns a tcpState containing the relevant
                            information about a socket declared to recieve
                            tcp connections. This method attempts to use
                            the port specified by the parameter.
*)

PROCEDURE tcpServerEstablishPort (port: CARDINAL) : tcpServerState ;


(*
   tcpServerAccept - returns a file descriptor once a client has connected and
                     been accepted.
*)

PROCEDURE tcpServerAccept (s: tcpServerState) : INTEGER ;


(*
   tcpServerPortNo - returns the portNo from structure, s.
*)

PROCEDURE tcpServerPortNo (s: tcpServerState) : CARDINAL ;


(*
   tcpSocketFd - returns the sockFd from structure, s.
*)

PROCEDURE tcpServerSocketFd (s: tcpServerState) : INTEGER ;


(*
   getLocalIP - returns the IP address of this machine.
*)

PROCEDURE getLocalIP (s: tcpServerState) : CARDINAL ;


(*
   tcpServerIP - returns the IP address from structure, s.
*)

PROCEDURE tcpServerIP (s: tcpServerState) : CARDINAL ;


(*
   tcpServerClientIP - returns the IP address of the client who
                       has connected to server, s.
*)

PROCEDURE tcpServerClientIP (s: tcpServerState) : CARDINAL ;


(*
   tcpServerClientPortNo - returns the port number of the client who
                           has connected to server, s.
*)

PROCEDURE tcpServerClientPortNo (s: tcpServerState) : CARDINAL ;


(*
   tcpClientSocket - returns a file descriptor (socket) which has
                     connected to, serverName:portNo.
*)

PROCEDURE tcpClientSocket (serverName: ADDRESS; portNo: CARDINAL) : tcpClientState ;


(*
   tcpClientSocketIP - returns a file descriptor (socket) which has
                       connected to, ip:portNo.
*)

PROCEDURE tcpClientSocketIP (ip: CARDINAL; portNo: CARDINAL) : tcpClientState ;


(*
   tcpClientConnect - returns the file descriptor associated with, s,
                      once a connect has been performed.
*)

PROCEDURE tcpClientConnect (s: tcpClientState) : INTEGER ;


(*
   tcpClientPortNo - returns the portNo from structure, s.
*)

PROCEDURE tcpClientPortNo (s: tcpClientState) : INTEGER ;


(*
   tcpClientSocketFd - returns the sockFd from structure, s.
*)

PROCEDURE tcpClientSocketFd (s: tcpClientState) : INTEGER ;


(*
   tcpClientIP - returns the IP address from structure, s.
*)

PROCEDURE tcpClientIP (s: tcpClientState) : CARDINAL ;


END sckt.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.40 gm2-libs/SYSTEM

 
DEFINITION MODULE SYSTEM ;

(*
   Description: Implements the SYSTEM dependent module
                in the Modula-2 compiler.
*)

EXPORT QUALIFIED BITSPERBYTE, BYTESPERWORD,
                 LOC, WORD, BYTE, ADDRESS, BITSET,
                 INTEGER8, INTEGER16, INTEGER32, INTEGER64,
                 CARDINAL8, CARDINAL16, CARDINAL32, CARDINAL64,
                 WORD16, WORD32, WORD64, BITSET8,
                 BITSET16, BITSET32, REAL32, REAL64,
                 REAL96, REAL128, COMPLEX32, COMPLEX64,
                 COMPLEX96, COMPLEX128,
                 ADR, TSIZE, SIZE, ROTATE, SHIFT, THROW ;

CONST
  BITSPERBYTE   = __ATTRIBUTE__ __BUILTIN__ ((BITS_PER_UNIT)) ;
  BYTESPERWORD  = __ATTRIBUTE__ __BUILTIN__ ((UNITS_PER_WORD)) ;


(* all the following types are declared internally to gm2
TYPE
   LOC ;
   WORD ;
   BYTE ;
   ADDRESS ;
   BITSET ;
   INTEGER8 ;
   INTEGER16 ;
   INTEGER32 ;
   INTEGER64 ;
   CARDINAL8 ;
   CARDINAL16 ;
   CARDINAL32 ;
   CARDINAL64 ;
   WORD16 ;
   WORD32 ;
   WORD64 ;
   BITSET8 ;
   BITSET16 ;
   BITSET32 ;
   REAL32 ;
   REAL64 ;
   REAL96 ;
   REAL128 ;
   COMPLEX32 ;
   COMPLEX64 ;
   COMPLEX96 ;
   COMPLEX128 ;
*)


(*
   all the functions below are declared internally to gm2
   ====================================================

PROCEDURE ADR (VAR v: <anytype>): ADDRESS;
  (* Returns the address of variable v. *)

PROCEDURE SIZE (v: <type>) : ZType;
  (* Returns the number of BYTES used to store a v of
     any specified <type>.
  *)

PROCEDURE TSIZE (<type>) : CARDINAL;
  (* Returns the number of BYTES used to store a value of the
     specified <type>.
  *)

PROCEDURE ROTATE (val: <a set type>;
                  num: INTEGER): <type of first parameter>;
  (* Returns a bit sequence obtained from val by rotating up or down
     (left or right) by the absolute value of num.  The direction is
     down if the sign of num is negative, otherwise the direction is up.
  *)

PROCEDURE SHIFT (val: <a set type>;
                 num: INTEGER): <type of first parameter>;
  (* Returns a bit sequence obtained from val by shifting up or down
     (left or right) by the absolute value of num, introducing
     zeros as necessary.  The direction is down if the sign of
     num is negative, otherwise the direction is up.
  *)

PROCEDURE THROW (i: INTEGER) ;
  (*
     THROW is a GNU extension and was not part of the PIM or ISO
     standards.  It throws an exception which will be caught by the EXCEPT
     block (assuming it exists).  This is a compiler builtin function which
     interfaces to the GCC exception handling runtime system.
     GCC uses the term throw, hence the naming distinction between
     the GCC builtin and the Modula-2 runtime library procedure Raise.
     The later library procedure Raise will call SYSTEM.THROW after
     performing various housekeeping activities.
  *)
*)

(* The following procedures are invoked by GNU Modula-2 to
   shift non word sized set types. They are not strictly part
   of the core PIM Modula-2, however they are used by
   GNU Modula-2 to implement the SHIFT procedure defined above,
   which are in turn used by the Logitech compatible libraries.

   Users will access these procedures by using the procedure
   SHIFT above and GNU Modula-2 will map SHIFT onto one of
   the following procedures.
*)

(*
   ShiftVal - is a runtime procedure whose job is to implement
              the SHIFT procedure of ISO SYSTEM. GNU Modula-2 will
              inline a SHIFT of a single WORD sized set and will only
              call this routine for larger sets.
*)

PROCEDURE ShiftVal (VAR s, d: ARRAY OF BITSET;
                    SetSizeInBits: CARDINAL;
                    ShiftCount: INTEGER) ;


(*
   ShiftLeft - performs the shift left for a multi word set.
               This procedure might be called by the back end of
               GNU Modula-2 depending whether amount is known at compile
               time.
*)

PROCEDURE ShiftLeft (VAR s, d: ARRAY OF BITSET;
                     SetSizeInBits: CARDINAL;
                     ShiftCount: CARDINAL) ;

(*
   ShiftRight - performs the shift left for a multi word set.
                This procedure might be called by the back end of
                GNU Modula-2 depending whether amount is known at compile
                time.
*)

PROCEDURE ShiftRight (VAR s, d: ARRAY OF BITSET;
                     SetSizeInBits: CARDINAL;
                     ShiftCount: CARDINAL) ;


(*
   RotateVal - is a runtime procedure whose job is to implement
               the ROTATE procedure of ISO SYSTEM. GNU Modula-2 will
               inline a ROTATE of a single WORD (or less)
               sized set and will only call this routine for larger sets.
*)

PROCEDURE RotateVal (VAR s, d: ARRAY OF BITSET;
                     SetSizeInBits: CARDINAL;
                     RotateCount: INTEGER) ;


(*
   RotateLeft - performs the rotate left for a multi word set.
                This procedure might be called by the back end of
                GNU Modula-2 depending whether amount is known at compile
                time.
*)

PROCEDURE RotateLeft (VAR s, d: ARRAY OF BITSET;
                      SetSizeInBits: CARDINAL;
                      RotateCount: CARDINAL) ;


(*
   RotateRight - performs the rotate right for a multi word set.
                 This procedure might be called by the back end of
                 GNU Modula-2 depending whether amount is known at compile
                 time.
*)

PROCEDURE RotateRight (VAR s, d: ARRAY OF BITSET;
                       SetSizeInBits: CARDINAL;
                       RotateCount: CARDINAL) ;


END SYSTEM.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.41 gm2-libs/SArgs

 
DEFINITION MODULE SArgs ;

(*
    Description: provides a String interface to the command line arguments.
*)

FROM DynamicStrings IMPORT String ;
EXPORT QUALIFIED GetArg, Narg ;


(*
   GetArg - returns the nth argument from the command line.
            The success of the operation is returned.
            If TRUE is returned then the string, s, contains a
            new string, otherwise s is set to NIL.
*)

PROCEDURE GetArg (VAR s: String ; i: CARDINAL) : BOOLEAN ;


(*
   Narg - returns the number of arguments available from
          command line.
*)

PROCEDURE Narg() : CARDINAL ;


END SArgs.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.42 gm2-libs/ldtoa

 
DEFINITION MODULE ldtoa ;

(*
    Description: provides routines to convert between a C long double
                 and an ascii string.
*)


FROM SYSTEM IMPORT ADDRESS ;

TYPE
   Mode = (shortest, stopping, maxsignicant, decimaldigits) ;


(*
   strtold - returns a LONGREAL given a string, s.  It will set
             error to TRUE if the number is too large.
*)

PROCEDURE strtold (s: ARRAY OF CHAR; VAR error: BOOLEAN) : LONGREAL ;
PROCEDURE strtold_string (s: ADDRESS; VAR error: BOOLEAN) : LONGREAL ;


(*
   ldtoa - converts a LONGREAL, d, into a string.  The address of the
           string is returned.
           mode       indicates the type of conversion required.
           ndigits    determines the number of digits according to mode.
           decpt      the position of the decimal point.
           sign       does the string have a sign?
*)

PROCEDURE ldtoa (d        : LONGREAL;
                 mode     : Mode;
                 ndigits  : INTEGER;
                 VAR decpt: INTEGER;
                 VAR sign : BOOLEAN) : ADDRESS ;


END ldtoa.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.43 gm2-libs/libm

 
DEFINITION MODULE FOR "C" libm ;

(*
    Description: provides access to libm. Users are strongly advised to
                 use MathLib0 or RealMath as call to functions within
                 these modules will generate inline code. This module
                 is used by MathLib0 and RealMath when inline code cannot
                 be generated.
*)

EXPORT UNQUALIFIED sin, sinl, sinf,
                   cos, cosl, cosf,
                   tan, tanl, tanf,
                   sqrt, sqrtl, sqrtf,
                   asin, asinl, asinf,
                   acos, acosl, acosf,
                   atan, atanl, atanf,
                   exp, expl, expf,
                   log, logl, logf,
                   exp10, exp10l, exp10f,
                   pow, powl, powf,
                   floor, floorl, floorf,
                   ceil, ceill, ceilf ;

PROCEDURE sin (x: REAL) : REAL ;
PROCEDURE sinl (x: LONGREAL) : LONGREAL ;
PROCEDURE sinf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE cos (x: REAL) : REAL ;
PROCEDURE cosl (x: LONGREAL) : LONGREAL ;
PROCEDURE cosf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE tan (x: REAL) : REAL ;
PROCEDURE tanl (x: LONGREAL) : LONGREAL ;
PROCEDURE tanf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE sqrt (x: REAL) : REAL ;
PROCEDURE sqrtl (x: LONGREAL) : LONGREAL ;
PROCEDURE sqrtf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE asin (x: REAL) : REAL ;
PROCEDURE asinl (x: LONGREAL) : LONGREAL ;
PROCEDURE asinf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE acos (x: REAL) : REAL ;
PROCEDURE acosl (x: LONGREAL) : LONGREAL ;
PROCEDURE acosf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE atan (x: REAL) : REAL ;
PROCEDURE atanl (x: LONGREAL) : LONGREAL ;
PROCEDURE atanf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE exp (x: REAL) : REAL ;
PROCEDURE expl (x: LONGREAL) : LONGREAL ;
PROCEDURE expf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE log (x: REAL) : REAL ;
PROCEDURE logl (x: LONGREAL) : LONGREAL ;
PROCEDURE logf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE exp10 (x: REAL) : REAL ;
PROCEDURE exp10l (x: LONGREAL) : LONGREAL ;
PROCEDURE exp10f (x: SHORTREAL) : SHORTREAL ;
PROCEDURE pow (x, y: REAL) : REAL ;
PROCEDURE powl (x, y: LONGREAL) : LONGREAL ;
PROCEDURE powf (x, y: SHORTREAL) : SHORTREAL ;
PROCEDURE floor (x: REAL) : REAL ;
PROCEDURE floorl (x: LONGREAL) : LONGREAL ;
PROCEDURE floorf (x: SHORTREAL) : SHORTREAL ;
PROCEDURE ceil (x: REAL) : REAL ;
PROCEDURE ceill (x: LONGREAL) : LONGREAL ;
PROCEDURE ceilf (x: SHORTREAL) : SHORTREAL ;

END libm.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1.44 gm2-libs/SEnvironment

 
DEFINITION MODULE SEnvironment ;

(*
    Description: provides access to the environment settings of a process.
*)

FROM DynamicStrings IMPORT String ;
EXPORT QUALIFIED GetEnvironment ;


(*
   GetEnvironment - gets the environment variable, env, and places
      	       	    a copy of its value into String, s.
                    TRUE is returned if successful.
*)

PROCEDURE GetEnvironment (env: String; VAR s: String) : BOOLEAN ;


END SEnvironment.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2 PIM and Logitech 3.0 Compatible

These modules are provided to enable legacy Modula-2 applications to build with GNU Modula-2. It is advised that these module should not be used for new projects, maybe the ISO libraries or the native compiler PIM libraries (FIO) should be used instead.

Here is an outline of the module layering:

 
InOut  RealInOut  LongIO CardinalIO
    \     |       |      /
           Terminal
-----------------------------------
              |
           Termbase
           /      \
    Keyboard      Display

Above the line are user level PIM [234] and Logitech 3.0 compatible modules. Below the line Logitech 3.0 advised that these modules should be considered part of the runtime system. The libraries do not provide all the features found in the Logitech libraries as a number of these features were MS-DOS related. Essentially the basic input/output, file system, string manipulation and conversion routines are provided. Access to DOSCALL, graphics, time and date are not as these were constrained by the limitations of MS-DOS.

The following libraries are contained within the base GNU Modula-2 libraries but are also Logitech-3.0 compatible: ASCII, Storage and MathLib0.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.1 gm2-libs-pim/FileSystem

 
DEFINITION MODULE FileSystem ;

(*
    Description: provides GNU Modula-2 with a PIM [234] FileSystem
                 compatible module. Use this module sparingly,
                 FIO or the ISO file modules have a much cleaner
                 interface.
*)

FROM SYSTEM IMPORT WORD, BYTE, ADDRESS ;
IMPORT FIO ;
FROM DynamicStrings IMPORT String ;

EXPORT QUALIFIED File, Response, Flag, FlagSet,

                 Create, Close, Lookup, Rename, Delete,
                 SetRead, SetWrite, SetModify, SetOpen,
                 Doio, SetPos, GetPos, Length, Reset,

                 ReadWord, ReadChar, ReadByte, ReadNBytes,
                 WriteWord, WriteChar, WriteByte, WriteNBytes ;

TYPE
   File = RECORD
             res     : Response ;
             flags   : FlagSet ;
             eof     : BOOLEAN ;
             lastWord: WORD ;
             lastByte: BYTE ;
             fio     : FIO.File ;
             highpos,
             lowpos  : CARDINAL ;
             name    : String ;
          END ;

   Flag = (
           read,        (* read access mode *)
           write,       (* write access mode *)
           modify,
           truncate,    (* truncate file when closed *)
           again,       (* reread the last character *)
           temporary,   (* file is temporary *)
           opened       (* file has been opened *)
          );

   FlagSet = SET OF Flag;

   Response = (done, notdone, notsupported, callerror,
               unknownfile, paramerror, toomanyfiles,
               userdeverror) ;

   Command = (create, close, lookup, rename, delete,
              setread, setwrite, setmodify, setopen,
              doio, setpos, getpos, length) ;


(*
   Create - creates a temporary file. To make the file perminant
            the file must be renamed.
*)

PROCEDURE Create (VAR f: File) ;


(*
   Close - closes an open file.
*)

PROCEDURE Close (f: File) ;


(*
   Lookup - looks for a file, filename. If the file is found
            then, f, is opened. If it is not found and, newFile,
            is TRUE then a new file is created and attached to, f.
            If, newFile, is FALSE and no file was found then f.res
            is set to notdone.
*)

PROCEDURE Lookup (VAR f: File; filename: ARRAY OF CHAR; newFile: BOOLEAN) ;


(*
   Rename - rename a file and change a temporary file to a permanent
            file. f.res is set appropriately.
*)

PROCEDURE Rename (VAR f: File; newname: ARRAY OF CHAR) ;


(*
   Delete - deletes a file, name, and sets the f.res field.
            f.res is set appropriately.
*)

PROCEDURE Delete (name: ARRAY OF CHAR; VAR f: File) ;


(*
   ReadWord - reads a WORD, w, from file, f.
              f.res is set appropriately.
*)

PROCEDURE ReadWord (VAR f: File; VAR w: WORD) ;


(*
   WriteWord - writes one word to a file, f.
               f.res is set appropriately.
*)

PROCEDURE WriteWord (VAR f: File; w: WORD) ;


(*
   ReadChar - reads one character from a file, f.
*)

PROCEDURE ReadChar (VAR f: File; VAR ch: CHAR) ;


(*
   WriteChar - writes a character, ch, to a file, f.
               f.res is set appropriately.
*)

PROCEDURE WriteChar (VAR f: File; ch: CHAR) ;


(*
   ReadByte - reads a BYTE, b, from file, f.
              f.res is set appropriately.
*)

PROCEDURE ReadByte (VAR f: File; VAR b: BYTE) ;


(*
   WriteByte - writes one BYTE, b, to a file, f.
               f.res is set appropriately.
*)

PROCEDURE WriteByte (VAR f: File; b: BYTE) ;


(*
   ReadNBytes - reads a sequence of bytes from a file, f.
*)

PROCEDURE ReadNBytes (VAR f: File; a: ADDRESS; amount: CARDINAL;
                      VAR actuallyRead: CARDINAL) ;


(*
   WriteNBytes - writes a sequence of bytes to file, f.
*)

PROCEDURE WriteNBytes (VAR f: File; a: ADDRESS; amount: CARDINAL;
                       VAR actuallyWritten: CARDINAL) ;


(*
   Again - returns the last character read to the internal buffer
           so that it can be read again.
*)

PROCEDURE Again (VAR f: File) ;


(*
   SetRead - puts the file, f, into the read state.
             The file position is unchanged.
*)

PROCEDURE SetRead (VAR f: File) ;


(*
   SetWrite - puts the file, f, into the write state.
              The file position is unchanged.
*)

PROCEDURE SetWrite (VAR f: File) ;


(*
   SetModify - puts the file, f, into the modify state.
               The file position is unchanged but the file can be
               read and written.
*)

PROCEDURE SetModify (VAR f: File) ;


(*
   SetOpen - places a file, f, into the open state. The file may
             have been in the read/write/modify state before and
             in which case the previous buffer contents are flushed
             and the file state is reset to open. The position is
             unaltered.
*)

PROCEDURE SetOpen (VAR f: File) ;


(*
   Reset - places a file, f, into the open state and reset the
           position to the start of the file.
*)

PROCEDURE Reset (VAR f: File) ;


(*
   SetPos - lseek to a position within a file.
*)

PROCEDURE SetPos (VAR f: File; high, low: CARDINAL) ;


(*
   GetPos - return the position within a file.
*)

PROCEDURE GetPos (VAR f: File; VAR high, low: CARDINAL) ;


(*
   Length - returns the length of file, in, high, and, low.
*)

PROCEDURE Length (VAR f: File; VAR high, low: CARDINAL) ;


(*
   Doio - effectively flushes a file in write mode, rereads the
          current buffer from disk if in read mode and writes
          and rereads the buffer if in modify mode.
*)

PROCEDURE Doio (VAR f: File) ;


(*
   FileNameChar - checks to see whether the character, ch, is
                  legal in a filename. nul is returned if the
                  character was illegal.
*)

PROCEDURE FileNameChar (ch: CHAR) ;


END FileSystem.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.2 gm2-libs-pim/BitByteOps

 
DEFINITION MODULE BitByteOps ;

(*
    Description: provides a Logitech-3.0 compatible library for GNU Modula-2.
*)

FROM SYSTEM IMPORT BYTE ;


(*
   GetBits - returns the bits firstBit..lastBit from source.
             Bit 0 of byte maps onto the firstBit of source.
*)

PROCEDURE GetBits (source: BYTE; firstBit, lastBit: CARDINAL) : BYTE ;


(*
   SetBits - sets bits in, byte, starting at, firstBit, and ending at,
             lastBit, with, pattern.  The bit zero of, pattern, will
             be placed into, byte, at position, firstBit.
*)

PROCEDURE SetBits (VAR byte: BYTE; firstBit, lastBit: CARDINAL;
                   pattern: BYTE) ;


(*
   ByteAnd - returns a bitwise (left AND right)
*)

PROCEDURE ByteAnd (left, right: BYTE) : BYTE ;


(*
   ByteOr - returns a bitwise (left OR right)
*)

PROCEDURE ByteOr (left, right: BYTE) : BYTE ;


(*
   ByteXor - returns a bitwise (left XOR right)
*)

PROCEDURE ByteXor (left, right: BYTE) : BYTE ;


(*
   ByteNot - returns a byte with all bits inverted.
*)

PROCEDURE ByteNot (byte: BYTE) : BYTE ;


(*
   ByteShr - returns a, byte, which has been shifted, count
             bits to the right.
*)

PROCEDURE ByteShr (byte: BYTE; count: CARDINAL) : BYTE ;


(*
   ByteShl - returns a, byte, which has been shifted, count
             bits to the left.
*)

PROCEDURE ByteShl (byte: BYTE; count: CARDINAL) : BYTE ;


(*
   ByteSar - shift byte arthemetic right.  Preserves the top
             end bit and as the value is shifted right.
*)

PROCEDURE ByteSar (byte: BYTE; count: CARDINAL) : BYTE ;


(*
   ByteRor - returns a, byte, which has been rotated, count
             bits to the right.
*)

PROCEDURE ByteRor (byte: BYTE; count: CARDINAL) : BYTE ;


(*
   ByteRol - returns a, byte, which has been rotated, count
             bits to the left.
*)

PROCEDURE ByteRol (byte: BYTE; count: CARDINAL) : BYTE ;


(*
   HighNibble - returns the top nibble only from, byte.
                The top nibble of, byte, is extracted and
                returned in the bottom nibble of the return
                value.
*)

PROCEDURE HighNibble (byte: BYTE) : BYTE ;


(*
   LowNibble - returns the low nibble only from, byte.
               The top nibble is replaced by zeros.
*)

PROCEDURE LowNibble (byte: BYTE) : BYTE ;


(*
   Swap - swaps the low and high nibbles in the, byte.
*)

PROCEDURE Swap (byte: BYTE) : BYTE ;


END BitByteOps.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.3 gm2-libs-pim/Terminal

 
DEFINITION MODULE Terminal ;

(*
    Description: provides a Logitech 3.0 compatible and PIM [234] compatible
                 Terminal module. It provides simple terminal input output
                 routines which all utilize the TermBase module.
*)

EXPORT QUALIFIED Read, KeyPressed, ReadAgain, ReadString, Write,
                 WriteString, WriteLn ;


(*
   Read - reads a single character.
*)

PROCEDURE Read (VAR ch: CHAR) ;


(*
   KeyPressed - returns TRUE if a character can be read without blocking
                the caller.
*)

PROCEDURE KeyPressed () : BOOLEAN ;


(*
   ReadString - reads a sequence of characters.
                Tabs are expanded into 8 spaces and <cr> or <lf> terminates
                the string.
*)

PROCEDURE ReadString (VAR s: ARRAY OF CHAR) ;


(*
   ReadAgain - makes the last character readable again.
*)

PROCEDURE ReadAgain ;


(*
   Write - writes a single character to the Termbase module.
*)

PROCEDURE Write (ch: CHAR) ;


(*
   WriteString - writes out a string which is terminated by a <nul>
                 character or the end of string HIGH(s).
*)

PROCEDURE WriteString (s: ARRAY OF CHAR) ;


(*
   WriteLn - writes a lf character.
*)

PROCEDURE WriteLn ;


END Terminal.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.4 gm2-libs-pim/Random

 
DEFINITION MODULE Random ;

(*
    Description: provides a Logitech-3.0 compatible library
*)

FROM SYSTEM IMPORT BYTE ;
EXPORT QUALIFIED Randomize, RandomInit, RandomCard, RandomInt, RandomReal ;



(*
   Randomize - initialize the random number generator with a seed
               based on the microseconds.
*)

PROCEDURE Randomize ;


(*
   RandomInit - initialize the random number generator with value, seed.
*)

PROCEDURE RandomInit (seed: CARDINAL) ;


(*
   RandomBytes - fills in an array with random values.
*)

PROCEDURE RandomBytes (a: ARRAY OF BYTE) ;


(*
   RandomInt - return an INTEGER in the range 0..bound-1
*)

PROCEDURE RandomInt (bound: INTEGER) : INTEGER ;


(*
   RandomCard - return a CARDINAL in the range 0..bound-1
*)

PROCEDURE RandomCard (bound: CARDINAL) : CARDINAL ;


(*
   RandomReal - return a REAL number in the range 0.0..1.0
*)

PROCEDURE RandomReal () : REAL ;


(*
   RandomLongReal - return a LONGREAL number in the range 0.0..1.0
*)

PROCEDURE RandomLongReal () : LONGREAL ;


END Random.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.5 gm2-libs-pim/InOut

 
DEFINITION MODULE InOut ;

(*
    Description: provides a compatible PIM [234] InOut module.
*)

IMPORT ASCII ;
FROM DynamicStrings IMPORT String ;
EXPORT QUALIFIED EOL, Done, termCH, OpenInput, CloseInput, CloseOutput,
                 Read, ReadString, ReadInt, ReadCard,
                 Write, WriteLn, WriteString, WriteInt, WriteCard,
                 WriteOct, WriteHex,
                 ReadS, WriteS ;

CONST
   EOL = ASCII.EOL ;

VAR
   Done  : BOOLEAN ;
   termCH: CHAR ;


(*
   OpenInput - reads a string from stdin as the filename for reading.
               If the filename ends with `.' then it appends the defext
               extension. The global variable Done is set if all
               was successful.
*)

PROCEDURE OpenInput (defext: ARRAY OF CHAR) ;


(*
   CloseInput - closes an opened input file and returns input back to
                StdIn.
*)

PROCEDURE CloseInput ;


(*
   OpenOutput - reads a string from stdin as the filename for writing.
                If the filename ends with `.' then it appends the defext
                extension. The global variable Done is set if all
                was successful.
*)

PROCEDURE OpenOutput (defext: ARRAY OF CHAR) ;


(*
   CloseOutput - closes an opened output file and returns output back to
                 StdOut.
*)

PROCEDURE CloseOutput ;


(*
   Read - reads a single character from the current input file.
          Done is set to FALSE if end of file is reached or an
          error occurs.
*)

PROCEDURE Read (VAR ch: CHAR) ;


(*
   ReadString - reads a sequence of characters. Leading white space
                is ignored and the string is terminated with a character
                <= ' '
*)

PROCEDURE ReadString (VAR s: ARRAY OF CHAR) ;


(*
   WriteString - writes a string to the output file.
*)

PROCEDURE WriteString (s: ARRAY OF CHAR) ;


(*
   Write - writes out a single character, ch, to the current output file.
*)

PROCEDURE Write (ch: CHAR) ;


(*
   WriteLn - writes a newline to the output file.
*)

PROCEDURE WriteLn ;


(*
   ReadInt - reads a string and converts it into an INTEGER, x.
             Done is set if an INTEGER is read.
*)

PROCEDURE ReadInt (VAR x: INTEGER) ;


(*
   ReadInt - reads a string and converts it into an INTEGER, x.
             Done is set if an INTEGER is read.
*)

PROCEDURE ReadCard (VAR x: CARDINAL) ;


(*
   WriteCard - writes the CARDINAL, x, to the output file. It ensures
               that the number occupies, n, characters. Leading spaces
               are added if required.
*)

PROCEDURE WriteCard (x, n: CARDINAL) ;


(*
   WriteInt - writes the INTEGER, x, to the output file. It ensures
              that the number occupies, n, characters. Leading spaces
              are added if required.
*)

PROCEDURE WriteInt (x: INTEGER; n: CARDINAL) ;


(*
   WriteOct - writes the CARDINAL, x, to the output file in octal.
              It ensures that the number occupies, n, characters.
              Leading spaces are added if required.
*)

PROCEDURE WriteOct (x, n: CARDINAL) ;


(*
   WriteHex - writes the CARDINAL, x, to the output file in hexadecimal.
              It ensures that the number occupies, n, characters.
              Leading spaces are added if required.
*)

PROCEDURE WriteHex (x, n: CARDINAL) ;


(*
   ReadS - returns a string which has is a sequence of characters.
           The string is terminated with a character <= ' '
*)

PROCEDURE ReadS () : String ;


(*
   WriteS - writes a String to the output device.
            It returns the string, s.
*)

PROCEDURE WriteS (s: String) : String ;


END InOut.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.6 gm2-libs-pim/BlockOps

 
DEFINITION MODULE BlockOps ;

(*
    Description: provides a Logitech compatible module for moving blocks
                 of memory.
*)

FROM SYSTEM IMPORT ADDRESS ;


(*
   MoveBlockForward - moves, n, bytes from, src, to, dest.
                      Starts copying from src and keep copying
                      until, n, bytes have been copied.
*)

PROCEDURE BlockMoveForward (dest, src: ADDRESS; n: CARDINAL) ;


(*
   MoveBlockBackward - moves, n, bytes from, src, to, dest.
                       Starts copying from src+n and keeps copying
                       until, n, bytes have been copied.
                       The last datum to be copied will be the byte
                       at address, src.
*)

PROCEDURE BlockMoveBackward (dest, src: ADDRESS; n: CARDINAL) ;


(*
   BlockClear - fills, block..block+n-1, with zero's.
*)

PROCEDURE BlockClear (block: ADDRESS; n: CARDINAL) ;


(*
   BlockSet - fills, n, bytes starting at, block, with a pattern
              defined at address pattern..pattern+patternSize-1.
*)

PROCEDURE BlockSet (block: ADDRESS; n: CARDINAL;
                    pattern: ADDRESS; patternSize: CARDINAL) ;


(*
   BlockEqual - returns TRUE if the blocks defined, a..a+n-1, and,
                b..b+n-1 contain the same bytes.
*)

PROCEDURE BlockEqual (a, b: ADDRESS; n: CARDINAL) : BOOLEAN ;


(*
   BlockPosition - searches for a pattern as defined by
                   pattern..patternSize-1 in the block,
                   block..block+blockSize-1.  It returns
                   the offset from block indicating the
                   first occurence of, pattern.
                   MAX(CARDINAL) is returned if no match
                   is detected.
*)

PROCEDURE BlockPosition (block: ADDRESS; blockSize: CARDINAL;
                         pattern: ADDRESS; patternSize: CARDINAL) : CARDINAL ;


END BlockOps.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.7 gm2-libs-pim/TimeDate

 
DEFINITION MODULE TimeDate ;

(*
    Description: provides a Logitech-3.0 compatible library module.
                 Advised to use cleaner designed modules based on 'man 3 strtime'
                 and friends for new projects as the day value here is ugly
                 [maybe it mapped onto MSDOS].
*)

EXPORT QUALIFIED Time, GetTime, SetTime, CompareTime, TimeToZero,
                 TimeToString ;

TYPE
(*
   day holds:  bits 0..4 = day of month (1..31)
                    5..8 = month of year (1..12)
                    9..  = year - 1900
   minute holds:    hours * 60 + minutes
   millisec holds:  seconds * 1000 + millisec
                    which is reset to 0 every minute
*)

   Time = RECORD
             day, minute, millisec: CARDINAL ;
          END ;


(*
   GetTime - returns the current date and time.
*)

PROCEDURE GetTime (VAR curTime: Time) ;


(*
   SetTime - does nothing, but provides compatibility with
             the Logitech-3.0 library.
*)

PROCEDURE SetTime (curTime: Time) ;


(*
   CompareTime - compare two dates and time which returns:

                 -1  if t1 < t2
                  0  if t1 = t2
                  1  if t1 > t2
*)

PROCEDURE CompareTime (t1, t2: Time) : INTEGER ;


(*
   TimeToZero - initializes, t, to zero.
*)

PROCEDURE TimeToZero (VAR t: Time) ;


(*
   TimeToString - convert time, t, to a string.
                  The string, s, should be at least 19 characters
                  long and the returned string will be

                  yyyy-mm-dd hh:mm:ss
*)

PROCEDURE TimeToString (t: Time; VAR s: ARRAY OF CHAR) ;


END TimeDate.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.8 gm2-libs-pim/Conversions

 
DEFINITION MODULE Conversions ;

(*
    Description: provides a Logitech-3.0 compatible library.
*)

EXPORT QUALIFIED ConvertOctal, ConvertHex, ConvertCardinal,
                 ConvertInteger, ConvertLongInt, ConvertShortInt ;

(*
   ConvertOctal - converts a CARDINAL, num, into an octal/hex/decimal
                  string and right justifies the string. It adds
                  spaces rather than '0' to pad out the string
                  to len characters.

                  If the length of str is < num then the number is
                  truncated on the right.
*)

PROCEDURE ConvertOctal    (num, len: CARDINAL; VAR str: ARRAY OF CHAR) ;
PROCEDURE ConvertHex      (num, len: CARDINAL; VAR str: ARRAY OF CHAR) ;
PROCEDURE ConvertCardinal (num, len: CARDINAL; VAR str: ARRAY OF CHAR) ;

(*
   The INTEGER counterparts will add a '-' if, num, is <0
*)

PROCEDURE ConvertInteger  (num: INTEGER; len: CARDINAL; VAR str: ARRAY OF CHAR) ;
PROCEDURE ConvertLongInt  (num: LONGINT; len: CARDINAL; VAR str: ARRAY OF CHAR) ;
PROCEDURE ConvertShortInt (num: SHORTINT; len: CARDINAL; VAR str: ARRAY OF CHAR) ;


END Conversions.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.9 gm2-libs-pim/Display

 
DEFINITION MODULE Display ;

(*
    Description: provides a Logitech 3.0 compatible Display module.
*)

EXPORT QUALIFIED Write ;

(*
   Write - display a character to the stdout.
           ASCII.EOL moves to the beginning of the next line.
           ASCII.del erases the character to the left of the cursor.
*)

PROCEDURE Write (ch: CHAR) ;


END Display.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.10 gm2-libs-pim/Break

 
DEFINITION MODULE Break ;

(*
    Description: provides a Logitech compatible Break handler module
                 which catches ctrl-c.
*)

EXPORT QUALIFIED EnableBreak, DisableBreak, InstallBreak, UnInstallBreak ;


(*
   EnableBreak - enable the current break handler.
*)

PROCEDURE EnableBreak ;


(*
   DisableBreak - disable the current break handler (and all
                  installed handlers).
*)

PROCEDURE DisableBreak ;


(*
   InstallBreak - installs a procedure, p, to be invoked when
                  a ctrl-c is caught. Any number of these
                  procedures may be stacked. Only the top
                  procedure is run when ctrl-c is caught.
*)

PROCEDURE InstallBreak (p: PROC) ;


(*
   UnInstallBreak - pops the break handler stack.
*)

PROCEDURE UnInstallBreak ;


END Break.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.11 gm2-libs-pim/ErrorCode

 
DEFINITION MODULE ErrorCode ;

(*
    Description: provides a Logitech-3.0 compatible module which
                 handles exiting from an application with an exit
                 value.
*)

EXPORT QUALIFIED SetErrorCode, GetErrorCode, ExitToOS ;


(*
   SetErrorCode - sets the exit value which will be used if
                  the application terminates normally.
*)

PROCEDURE SetErrorCode (value: INTEGER) ;


(*
   GetErrorCode - returns the current value to be used upon
                  application termination.
*)

PROCEDURE GetErrorCode (VAR value: INTEGER) ;


(*
   ExitToOS - terminate the application and exit returning
              the last value set by SetErrorCode to the OS.
*)

PROCEDURE ExitToOS ;


END ErrorCode.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.12 gm2-libs-pim/RealConversions

 
DEFINITION MODULE RealConversions ;

(*
    Description: provides a Logitech-3.0 compatible module.
*)

EXPORT QUALIFIED RealToString, StringToReal,
                 LongRealToString, StringToLongReal ;


(*
   RealToString - converts a real, r, into a right justified string, str.
                  The number of digits to the right of the decimal point
                  is given in, digits. The value, width, represents the
                  maximum number of characters to be used in the string,
                  str.

                  If digits is negative then exponent notation is used
                  whereas if digits is positive then fixed point notation
                  is used.

                  If, r, is less than 0.0 then a '-' preceeds the value,
                  str. However, if, r, is >= 0.0 a '+' is not added.

                  If the conversion of, r, to a string requires more
                  than, width, characters then the string, str, is set
                  to a nul string and, ok is assigned FALSE.

                  For fixed point notation the minimum width required is
                  ABS(width)+8

                  For exponent notation the minimum width required is
                  ABS(digits)+2+log10(magnitude).
*)

PROCEDURE RealToString (r: REAL; digits, width: INTEGER;
                        VAR str: ARRAY OF CHAR; VAR ok: BOOLEAN) ;


(*
   LongRealToString - converts a real, r, into a right justified string, str.
                      The number of digits to the right of the decimal point
                      is given in, digits. The value, width, represents the
                      maximum number of characters to be used in the string,
                      str.

                      If digits is negative then exponent notation is used
                      whereas if digits is positive then fixed point notation
                      is used.

                      If, r, is less than 0.0 then a '-' preceeds the value,
                      str. However, if, r, is >= 0.0 a '+' is not added.

                      If the conversion of, r, to a string requires more
                      than, width, characters then the string, str, is set
                      to a nul string and, ok is assigned FALSE.

                      For fixed point notation the minimum width required is
                      ABS(width)+8

                      For exponent notation the minimum width required is
                      ABS(digits)+2+log10(magnitude).

                      Examples:
                      RealToString(100.0, 10, 10, a, ok)       ->  '100.000000'
                      RealToString(100.0, -5, 12, a, ok)       ->  '  1.00000E+2'

                      RealToString(123.456789, 10, 10, a, ok)  ->  '123.456789'
                      RealToString(123.456789, -5, 13, a, ok)  ->  '    1.23456E+2'

                      RealToString(123.456789, -2, 15, a, ok)  ->  '          1.23E+2'
*)

PROCEDURE LongRealToString (r: LONGREAL; digits, width: INTEGER;
                            VAR str: ARRAY OF CHAR; VAR ok: BOOLEAN) ;


(*
   StringToReal - converts, str, into a REAL, r. The parameter, ok, is
                  set to TRUE if the conversion was successful.
*)

PROCEDURE StringToReal (str: ARRAY OF CHAR; VAR r: REAL; VAR ok: BOOLEAN) ;


(*
   StringToLongReal - converts, str, into a LONGREAL, r. The parameter, ok, is
                      set to TRUE if the conversion was successful.
*)

PROCEDURE StringToLongReal (str: ARRAY OF CHAR; VAR r: LONGREAL; VAR ok: BOOLEAN) ;


END RealConversions.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.13 gm2-libs-pim/CardinalIO

 
DEFINITION MODULE CardinalIO ;

(*
    Description: provides a PIM and Logitech compatible module.
*)

EXPORT QUALIFIED Done,
                 ReadCardinal, WriteCardinal, ReadHex, WriteHex,
                 ReadLongCardinal, WriteLongCardinal, ReadLongHex,
                 WriteLongHex,
                 ReadShortCardinal, WriteShortCardinal, ReadShortHex,
                 WriteShortHex ;


VAR
   Done: BOOLEAN ;


(*
   ReadCardinal - read an unsigned decimal number from the terminal.
                  The read continues until a space, newline, esc or
                  end of file is reached.
*)

PROCEDURE ReadCardinal (VAR c: CARDINAL) ;


(*
   WriteCardinal - writes the value, c, to the terminal and ensures
                   that at least, n, characters are written. The number
                   will be padded out by preceeding spaces if necessary.
*)

PROCEDURE WriteCardinal (c: CARDINAL; n: CARDINAL) ;


(*
   ReadHex - reads in an unsigned hexadecimal number from the terminal.
             The read continues until a space, newline, esc or
             end of file is reached.
*)

PROCEDURE ReadHex (VAR c: CARDINAL) ;


(*
   WriteHex - writes out a CARDINAL, c, in hexadecimal format padding
              with, n, characters (leading with '0')
*)

PROCEDURE WriteHex (c: CARDINAL; n: CARDINAL) ;


(*
   ReadLongCardinal - read an unsigned decimal number from the terminal.
                      The read continues until a space, newline, esc or
                      end of file is reached.
*)

PROCEDURE ReadLongCardinal (VAR c: LONGCARD) ;


(*
   WriteLongCardinal - writes the value, c, to the terminal and ensures
                       that at least, n, characters are written. The number
                       will be padded out by preceeding spaces if necessary.
*)

PROCEDURE WriteLongCardinal (c: LONGCARD; n: CARDINAL) ;


(*
   ReadLongHex - reads in an unsigned hexadecimal number from the terminal.
                 The read continues until a space, newline, esc or
                 end of file is reached.
*)

PROCEDURE ReadLongHex (VAR c: LONGCARD) ;


(*
   WriteLongHex - writes out a LONGCARD, c, in hexadecimal format padding
                  with, n, characters (leading with '0')
*)

PROCEDURE WriteLongHex (c: LONGCARD; n: CARDINAL) ;


(*
   WriteShortCardinal - writes the value, c, to the terminal and ensures
                       that at least, n, characters are written. The number
                       will be padded out by preceeding spaces if necessary.
*)

PROCEDURE WriteShortCardinal (c: SHORTCARD; n: CARDINAL) ;


(*
   ReadShortCardinal - read an unsigned decimal number from the terminal.
                       The read continues until a space, newline, esc or
                       end of file is reached.
*)

PROCEDURE ReadShortCardinal (VAR c: SHORTCARD) ;


(*
   ReadShortHex - reads in an unsigned hexadecimal number from the terminal.
                 The read continues until a space, newline, esc or
                 end of file is reached.
*)

PROCEDURE ReadShortHex (VAR c: SHORTCARD) ;


(*
   WriteShortHex - writes out a SHORTCARD, c, in hexadecimal format padding
                  with, n, characters (leading with '0')
*)

PROCEDURE WriteShortHex (c: SHORTCARD; n: CARDINAL) ;


END CardinalIO.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.14 gm2-libs-pim/LongIO

 
DEFINITION MODULE LongIO ;

(*
    Description: provides a Logitech-3.0 compatible library for GNU Modula-2.
*)

EXPORT QUALIFIED Done, ReadLongInt, WriteLongInt ;

VAR
   Done: BOOLEAN ;

PROCEDURE ReadLongInt (VAR i: LONGINT) ;
PROCEDURE WriteLongInt (i: LONGINT; n: CARDINAL) ;


END LongIO.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.15 gm2-libs-pim/DebugPMD

 
DEFINITION MODULE DebugPMD ;

END DebugPMD.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.16 gm2-libs-pim/Delay

 
DEFINITION MODULE Delay ;

(*
    Description: provides a Logitech-3.0 compatible module for
                 GNU Modula-2.
*)

EXPORT QUALIFIED Delay ;


(*
   milliSec - delays the program by approximately, milliSec, milliseconds.
*)

PROCEDURE Delay (milliSec: INTEGER) ;


END Delay.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.17 gm2-libs-pim/Strings

 
DEFINITION MODULE Strings ;

(*
    Description: provides a Logitech-3.0 compatible library
*)

EXPORT QUALIFIED Assign, Insert, Delete, Pos, Copy, ConCat, Length,
                 CompareStr ;

(*
   Assign - source := dest.
*)

PROCEDURE Assign (VAR source: ARRAY OF CHAR; dest: ARRAY OF CHAR) ;


(*
   Insert - insert the string, substr, into str at position, index.
            substr, is added to the end of, str, if, index >= length(str)
*)

PROCEDURE Insert (substr: ARRAY OF CHAR; VAR str: ARRAY OF CHAR;
                  index: CARDINAL) ;


(*
   Delete - delete len characters from, str, starting at, index.
*)

PROCEDURE Delete (VAR str: ARRAY OF CHAR; index: CARDINAL; length: CARDINAL) ;


(*
   Pos - return the first position of, substr, in, str.
*)

PROCEDURE Pos (substr, str: ARRAY OF CHAR) : CARDINAL ;


(*
   Copy - copy at most, length, characters in, substr, to, str,
          starting at position, index.
*)

PROCEDURE Copy (str: ARRAY OF CHAR;
                index, length: CARDINAL; VAR result: ARRAY OF CHAR) ;

(*
   ConCat - concatenates two strings, s1, and, s2
            and places the result into, dest.
*)

PROCEDURE ConCat (s1, s2: ARRAY OF CHAR; VAR dest: ARRAY OF CHAR) ;


(*
   Length - return the length of string, s.
*)

PROCEDURE Length (s: ARRAY OF CHAR) : CARDINAL ;


(*
   CompareStr - compare two strings, left, and, right.
*)

PROCEDURE CompareStr (left, right: ARRAY OF CHAR) : INTEGER ;


END Strings.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.18 gm2-libs-pim/DebugTrace

 
DEFINITION MODULE DebugTrace ;

(*
    Description: provides a compatible module for the
                 Logitech-3.0 PIM Modula-2 compiler.
                 It does nothing other satisfy an import for
                 legacy source code.
*)

END DebugTrace.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.19 gm2-libs-pim/NumberConversion

 
DEFINITION MODULE NumberConversion ;

(*
    Description: provides a Logitech compatible NumberConversion library.
*)




END NumberConversion.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.20 gm2-libs-pim/FloatingUtilities

 
DEFINITION MODULE FloatingUtilities ;

(*
    Description: provides a Logitech-3.0 compatible library
*)

EXPORT QUALIFIED Frac, Round, Float, Trunc,
                 Fracl, Roundl, Floatl, Truncl ;


(*
   Frac - returns the fractional component of, r.
*)

PROCEDURE Frac (r: REAL) : REAL ;


(*
   Int - returns the integer part of r. It rounds the value towards zero.
*)

PROCEDURE Int (r: REAL) : INTEGER ;


(*
   Round - returns the number rounded to the nearest integer.
*)

PROCEDURE Round (r: REAL) : REAL ;


(*
   Float - returns a REAL value corresponding to, i.
*)

PROCEDURE Float (i: INTEGER) : REAL ;


(*
   Trunc - round to the nearest integer not larger in absolute
           value.
*)

PROCEDURE Trunc (r: REAL) : INTEGER ;


(*
   Fracl - returns the fractional component of, r.
*)

PROCEDURE Fracl (r: LONGREAL) : LONGREAL ;


(*
   Intl - returns the integer part of r. It rounds the value towards zero.
*)

PROCEDURE Intl (r: LONGREAL) : LONGINT ;


(*
   Roundl - returns the number rounded to the nearest integer.
*)

PROCEDURE Roundl (r: LONGREAL) : LONGREAL ;


(*
   Floatl - returns a REAL value corresponding to, i.
*)

PROCEDURE Floatl (i: INTEGER) : LONGREAL ;


(*
   Truncl - round to the nearest integer not larger in absolute
            value.
*)

PROCEDURE Truncl (r: LONGREAL) : LONGINT ;


END FloatingUtilities.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.21 gm2-libs-pim/Keyboard

 
DEFINITION MODULE Keyboard ;

(*
    Description: provides compatibility with Logitech 3.0 Keyboard module.
*)

EXPORT QUALIFIED Read, KeyPressed ;


(*
   Read - reads a character from StdIn. If necessary it will wait
          for a key to become present on StdIn.
*)

PROCEDURE Read (VAR ch: CHAR) ;


(*
   KeyPressed - returns TRUE if a character can be read from StdIn
                without blocking the caller.
*)

PROCEDURE KeyPressed () : BOOLEAN ;


END Keyboard.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.22 gm2-libs-pim/BitWordOps

 
DEFINITION MODULE BitWordOps ;

(*
    Description: provides a Logitech-3.0 compatible library for GNU Modula-2.
*)

FROM SYSTEM IMPORT WORD ;


(*
   GetBits - returns the bits firstBit..lastBit from source.
             Bit 0 of word maps onto the firstBit of source.
*)

PROCEDURE GetBits (source: WORD; firstBit, lastBit: CARDINAL) : WORD ;


(*
   SetBits - sets bits in, word, starting at, firstBit, and ending at,
             lastBit, with, pattern.  The bit zero of, pattern, will
             be placed into, word, at position, firstBit.
*)

PROCEDURE SetBits (VAR word: WORD; firstBit, lastBit: CARDINAL;
                   pattern: WORD) ;


(*
   WordAnd - returns a bitwise (left AND right)
*)

PROCEDURE WordAnd (left, right: WORD) : WORD ;


(*
   WordOr - returns a bitwise (left OR right)
*)

PROCEDURE WordOr (left, right: WORD) : WORD ;


(*
   WordXor - returns a bitwise (left XOR right)
*)

PROCEDURE WordXor (left, right: WORD) : WORD ;


(*
   WordNot - returns a word with all bits inverted.
*)

PROCEDURE WordNot (word: WORD) : WORD ;


(*
   WordShr - returns a, word, which has been shifted, count
             bits to the right.
*)

PROCEDURE WordShr (word: WORD; count: CARDINAL) : WORD ;


(*
   WordShl - returns a, word, which has been shifted, count
             bits to the left.
*)

PROCEDURE WordShl (word: WORD; count: CARDINAL) : WORD ;


(*
   WordSar - shift word arthemetic right.  Preserves the top
             end bit and as the value is shifted right.
*)

PROCEDURE WordSar (word: WORD; count: CARDINAL) : WORD ;


(*
   WordRor - returns a, word, which has been rotated, count
             bits to the right.
*)

PROCEDURE WordRor (word: WORD; count: CARDINAL) : WORD ;


(*
   WordRol - returns a, word, which has been rotated, count
             bits to the left.
*)

PROCEDURE WordRol (word: WORD; count: CARDINAL) : WORD ;


(*
   HighByte - returns the top byte only from, word.
              The byte is returned in the bottom byte
              in the return value.
*)

PROCEDURE HighByte (word: WORD) : WORD ;


(*
   LowByte - returns the low byte only from, word.
             The byte is returned in the bottom byte
             in the return value.
*)

PROCEDURE LowByte (word: WORD) : WORD ;


(*
   Swap - byte flips the contents of word.
*)

PROCEDURE Swap (word: WORD) : WORD ;


END BitWordOps.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.23 gm2-libs-pim/Termbase

 
DEFINITION MODULE Termbase ;

(*
    Description: provides GNU Modula-2 with a PIM 234 compatible Termbase
                 module. Definition module complies with Logitech 3.0.
                 Initially the read routines from Keyboard and the
                 write routine from Display is assigned to the Read,
                 KeyPressed and Write procedures.
*)

EXPORT QUALIFIED ReadProcedure, StatusProcedure, WriteProcedure,
                 AssignRead, AssignWrite, UnAssignRead, UnAssignWrite,
                 Read, KeyPressed, Write ;

TYPE
   ReadProcedure = PROCEDURE (VAR CHAR) ;
   WriteProcedure = PROCEDURE (CHAR) ;
   StatusProcedure = PROCEDURE () : BOOLEAN ;


(*
   AssignRead - assigns a read procedure and status procedure for terminal
                input. Done is set to TRUE if successful. Subsequent
                Read and KeyPressed calls are mapped onto the user supplied
                procedures. The previous read and status procedures are
                uncovered and reused after UnAssignRead is called.
*)

PROCEDURE AssignRead (rp: ReadProcedure; sp: StatusProcedure;
                      VAR Done: BOOLEAN) ;


(*
   UnAssignRead - undo the last call to AssignRead and set Done to TRUE
                  on success.
*)

PROCEDURE UnAssignRead (VAR Done: BOOLEAN) ;


(*
   Read - reads a single character using the currently active read
          procedure.
*)

PROCEDURE Read (VAR ch: CHAR) ;


(*
   KeyPressed - returns TRUE if a character is available to be read.
*)

PROCEDURE KeyPressed () : BOOLEAN ;


(*
   AssignWrite - assigns a write procedure for terminal output.
                 Done is set to TRUE if successful. Subsequent
                 Write calls are mapped onto the user supplied
                 procedure. The previous write procedure is
                 uncovered and reused after UnAssignWrite is called.
*)

PROCEDURE AssignWrite (wp: WriteProcedure; VAR Done: BOOLEAN) ;


(*
   UnAssignWrite - undo the last call to AssignWrite and set Done to TRUE
                   on success.
*)

PROCEDURE UnAssignWrite (VAR Done: BOOLEAN) ;


(*
   Write - writes a single character using the currently active write
           procedure.
*)

PROCEDURE Write (VAR ch: CHAR) ;


END Termbase.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.24 gm2-libs-pim/BitBlockOps

 
DEFINITION MODULE BitBlockOps ;

(*
    Description: provides a Logitech compatible module.
*)


FROM SYSTEM IMPORT ADDRESS ;


(*
   BlockAnd - performs a bitwise AND on blocks
              [dest..dest+size-1] := [dest..dest+size-1] AND
                                     [src..src+size-1]
*)

PROCEDURE BlockAnd (dest, src: ADDRESS; size: CARDINAL) ;


(*
   BlockOr - performs a bitwise OR on blocks
             [dest..dest+size-1] := [dest..dest+size-1] OR
                                    [src..src+size-1]
*)

PROCEDURE BlockOr (dest, src: ADDRESS; size: CARDINAL) ;


(*
   BlockXor - performs a bitwise XOR on blocks
              [dest..dest+size-1] := [dest..dest+size-1] XOR
                                     [src..src+size-1]
*)

PROCEDURE BlockXor (dest, src: ADDRESS; size: CARDINAL) ;


(*
   BlockNot - performs a bitsize NOT on the block as defined
              by:  [dest..dest+size-1]
*)

PROCEDURE BlockNot (dest: ADDRESS; size: CARDINAL) ;


(*
   BlockShr - performs a block shift right of, count, bits.
              Where the block is defined as:
              [dest..dest+size-1].
              The block is considered to be an ARRAY OF BYTEs
              which is shifted, bit at a time over each byte in
              turn.  The left most byte is considered the byte
              located at the lowest address.
              If you require an endianness SHIFT use
              the SYSTEM.SHIFT procedure and declare the
              block as a POINTER TO set type.
*)

PROCEDURE BlockShr (dest: ADDRESS; size, count: CARDINAL) ;


(*
   BlockShl - performs a block shift left of, count, bits.
              Where the block is defined as:
              [dest..dest+size-1].
              The block is considered to be an ARRAY OF BYTEs
              which is shifted, bit at a time over each byte in
              turn.  The left most byte is considered the byte
              located at the lowest address.
              If you require an endianness SHIFT use
              the SYSTEM.SHIFT procedure and declare the
              block as a POINTER TO set type.
*)

PROCEDURE BlockShl (dest: ADDRESS; size, count: CARDINAL) ;


(*
   BlockRor - performs a block rotate right of, count, bits.
              Where the block is defined as:
              [dest..dest+size-1].
              The block is considered to be an ARRAY OF BYTEs
              which is rotated, bit at a time over each byte in
              turn.  The left most byte is considered the byte
              located at the lowest address.
              If you require an endianness ROTATE use
              the SYSTEM.ROTATE procedure and declare the
              block as a POINTER TO set type.
*)

PROCEDURE BlockRor (dest: ADDRESS; size, count: CARDINAL) ;


(*
   BlockRol - performs a block rotate left of, count, bits.
              Where the block is defined as:
              [dest..dest+size-1].
              The block is considered to be an ARRAY OF BYTEs
              which is rotated, bit at a time over each byte in
              turn.  The left most byte is considered the byte
              located at the lowest address.
              If you require an endianness ROTATE use
              the SYSTEM.ROTATE procedure and declare the
              block as a POINTER TO set type.
*)

PROCEDURE BlockRol (dest: ADDRESS; size, count: CARDINAL) ;


END BitBlockOps.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.25 gm2-libs-pim/RealInOut

 
DEFINITION MODULE RealInOut ;

(*
    Description: provides a compatible RealInOut PIM 234 module.
*)

EXPORT QUALIFIED ReadReal, WriteReal, WriteRealOct,
                 ReadLongReal, WriteLongReal, WriteLongRealOct,
                 ReadShortReal, WriteShortReal, WriteShortRealOct,
                 Done ;

VAR
   Done: BOOLEAN ;


(*
   ReadReal - reads a real number, legal syntaxes include:
              100, 100.0, 100e0, 100E0, 100E-1, E2, +1E+2, 1e+2
*)

PROCEDURE ReadReal (VAR x: REAL) ;


(*
   WriteReal - writes a real to the terminal. The real number
               is right justified and, n, is the minimum field
               width.
*)

PROCEDURE WriteReal (x: REAL; n: CARDINAL) ;


(*
   WriteRealOct - writes the real to terminal in octal words.
*)

PROCEDURE WriteRealOct (x: REAL) ;


(*
   ReadLongReal - reads a LONGREAL number, legal syntaxes include:
                  100, 100.0, 100e0, 100E0, 100E-1, E2, +1E+2, 1e+2
*)

PROCEDURE ReadLongReal (VAR x: LONGREAL) ;


(*
   WriteLongReal - writes a LONGREAL to the terminal. The real number
                   is right justified and, n, is the minimum field
                   width.
*)

PROCEDURE WriteLongReal (x: LONGREAL; n: CARDINAL) ;


(*
   WriteLongRealOct - writes the LONGREAL to terminal in octal words.
*)

PROCEDURE WriteLongRealOct (x: LONGREAL) ;


(*
   ReadShortReal - reads a SHORTREAL number, legal syntaxes include:
                   100, 100.0, 100e0, 100E0, 100E-1, E2, +1E+2, 1e+2
*)

PROCEDURE ReadShortReal (VAR x: SHORTREAL) ;


(*
   WriteShortReal - writes a SHORTREAL to the terminal. The real number
                    is right justified and, n, is the minimum field
                    width.
*)

PROCEDURE WriteShortReal (x: SHORTREAL; n: CARDINAL) ;


(*
   WriteShortRealOct - writes the SHORTREAL to terminal in octal words.
*)

PROCEDURE WriteShortRealOct (x: SHORTREAL) ;


END RealInOut.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.3 PIM coroutine support

This directory contains a PIM SYSTEM containing the PROCESS primitives built on top of GNU Pthreads.

The justification for this approach is that it provides a SYSTEM compatible with Programming in Modula-2 [234] and the Logitech 3.0 compiler. It also allows higher level executives to be ported onto GM2 with little effort. The disadvantage with this approach is that IOTRANSFER is not preemptive. IOTRANSFER will only context switch when a call to LISTEN is made or a call to SYSTEM.TurnInterrupts is made.

In practice this limitation can be tolerated as long as processes perform IO at some point (or wait for a timer interrupt) or call SYSTEM.TurnInterrupts. But nevertheless a LOOP END will starve all other processes. However the great advantage is that GNU Modula-2 can offer users the ability to use IOTRANSFER, TRANSFER, NEWPROCESS in user space, on a multi-user operating system and across a range of platforms.

The GNU Modula-2 SYSTEM works by utilizing the user context switching mechanism provided by GNU Pthreads. NEWPROCESS creates a new context, TRANSFER switches contexts. IOTRANSFER is more complex. There is a support module SysVec which provides pseudo interrupt vectors. These can be created from input/output file descriptors or timer events timeval. This vector is then passed to IOTRANSFER which keeps track of which file descriptors and timevals are active. When a call to TurnInterrupts or LISTEN is made the sub system calls pth_select and tests for any ready file descriptor or timeout. A ready file descriptor or timeout will ultimately cause the backwards TRANSFER inside IOTRANSFER to take effect.

See the `gm2/examples/executive' directory for an executive and timerhandler module which provide higher level process creation, synchronisation and interrupt handling routines. These libraries have been tested with the examples shown in `gm2/examples/executive' and `gm2/gm2-libs-coroutines'.

Users of these libraries and the libraries in `gm2/examples/executive' must link their application against the GNU Pthread library (typically by using -lpth).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.3.1 gm2-libs-coroutines/SysVec

 
DEFINITION MODULE SysVec ;

(*
    Description: provides SYSTEM with the pseudo interrupt vector
                 manipulation routines. This module interface was
                 designed to allow SYSTEM to have the same interface
                 as PIM [234] and Logitech 3.0. It would have been
                 easier to include this functionality into SYSTEM
                 at the expense of stricter compatibility.
*)

FROM SYSTEM IMPORT ADDRESS ;
EXPORT QUALIFIED InitInputVector, InitOutputVector, InitTimeVector,
                 AttachVector,
                 ReArmTimeVector, GetTimeVector,
                 Listen, IncludeVector, ExcludeVector, DespatchVector ;

TYPE
   DespatchVector = PROCEDURE (CARDINAL, CARDINAL, ADDRESS) ;


(*
   InitInputVector - returns an interrupt vector which is associated
                     with the file descriptor, fd.
*)

PROCEDURE InitInputVector (fd: INTEGER; pri: CARDINAL) : CARDINAL ;


(*
   InitOutputVector - returns an interrupt vector which is associated
                      with the file descriptor, fd.
*)

PROCEDURE InitOutputVector (fd: INTEGER; pri: CARDINAL) : CARDINAL ;


(*
   InitTimeVector - returns an interrupt vector associated with
                    the relative time.
*)

PROCEDURE InitTimeVector (micro, secs: CARDINAL; pri: CARDINAL) : CARDINAL ;


(*
   ReArmTimeVector - reprimes the vector, vec, to deliver an interrupt
                     at the new relative time.
*)

PROCEDURE ReArmTimeVector (vec: CARDINAL; micro, secs: CARDINAL) ;


(*
   GetTimeVector - assigns, micro, and, secs, with the remaining
                   time before this interrupt will expire.
                   This value is only updated when a Listen
                   occurs.
*)

PROCEDURE GetTimeVector (vec: CARDINAL; VAR micro, secs: CARDINAL) ;


(*
   AttachVector - adds the pointer, p, to be associated with the interrupt
                  vector. It returns the previous value attached to this
                  vector.
*)

PROCEDURE AttachVector (vec: CARDINAL; p: ADDRESS) : ADDRESS ;


(*
   IncludeVector - includes, vec, into the despatcher list of
                   possible interrupt causes.
*)

PROCEDURE IncludeVector (vec: CARDINAL) ;


(*
   ExcludeVector - excludes, vec, from the despatcher list of
                   possible interrupt causes.
*)

PROCEDURE ExcludeVector (vec: CARDINAL) ;


(*
   Listen - will either block indefinitely (until an interrupt)
            or alteratively will test to see whether any interrupts
            are pending.
            If a pending interrupt was found then, call, is called
            and then this procedure returns.
            It only listens for interrupts > pri.
*)

PROCEDURE Listen (untilInterrupt: BOOLEAN;
                  call: DespatchVector;
                  pri: CARDINAL) ;


END SysVec.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.3.2 gm2-libs-coroutines/pth

 
DEFINITION MODULE FOR "C" pth ;

FROM SYSTEM IMPORT ADDRESS, BITSET ;

CONST
     PTH_VERSION_STR =  "1.4.1 (27-Jan-2002)" ;
     PTH_VERSION_HEX =  1065473 ;
     PTH_VERSION =  PTH_VERSION_HEX ;

TYPE
     fd_set =  ADDRESS ;
     __time_t =   INTEGER ;
     __useconds_t =   CARDINAL ;
     __suseconds_t =   INTEGER ;
     size_t =   CARDINAL ;
    timeval = RECORD
                 tv_sec : __time_t ;
                 tv_usec: __suseconds_t ;
              END ;

    sockaddr = RECORD
               END ;
     sigset_t =  ADDRESS ;
     pth_uctx_t =  POINTER TO   pth_uctx_st ;
    pth_uctx_st = RECORD
                  END ;
     pid_t =   INTEGER ;
     ssize_t =   CARDINAL ;
     socklen_t =   CARDINAL ;
     off_t =   INTEGER ;
     sig_atomic_t =   INTEGER ;
     nfds_t =   LONGCARD ;

CONST
     PTH_KEY_MAX =  256 ;
     PTH_ATFORK_MAX =  128 ;
     PTH_DESTRUCTOR_ITERATIONS =  4 ;
     PTH_SYSCALL_HARD =  0 ;
     PTH_SYSCALL_SOFT =  0 ;

TYPE
     pth_time_t =  ADDRESS ;
     pth_t =  ADDRESS ;
     pth_state_t =   pth_state_en ;
     pth_state_en =  ( PTH_STATE_SCHEDULER, PTH_STATE_NEW, PTH_STATE_READY, PTH_STATE_WAITING,