Provided by: gm2-9-alpha-linux-gnu_9.4.0-1ubuntu1~20.04cross1_amd64 bug

NAME

       gm2 - The GNU Modula-2 compiler.
       gm2l - GNU Modula-2 linker subcomponent.
       gm2lcc - GNU Modula-2 linker subcomponent.
       gm2lgen - GNU Modula-2 linker subcomponent.
       gm2lsub - GNU Modula-2 linker subcomponent.
       gm2m - GNU Modula-2 makefile generator.
       h2def - Transform a 'C' header file into a Modula-2 definition file.

DESCRIPTION

       NOTE: This document manual page may be out of date, check the texinfo file.

       GNU  Modula-2 is a front end ⟨http://gcc.gnu.org/frontends.html⟩ for GCC (the GNU Compiler
       Collection).  GCC contains 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 one.

       The GNU Modula-2 front end can perform a substantial amount  of  static  analysis  of  the
       source  code  (see  `-Wpedantic', `-Wpedantic-param-names', `-Wstudents', and `-Wpedantic-
       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.

       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.

       GNU  Modula-2  also  has  the  advantage  of  being  closely tied to GCC (the GNU Compiler
       Collection.)  Not only does this produce excellent code and  excellent  architectural  and
       operating  system  coverage,  but it also utilizes many of the GCC features.  For example,
       GNU Modula-2 can invoke the C preprocessor to manage conditional compilation; inlining  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 supports
       sets of any ordinal type (memory permitting).

       GNU  Modula-2  Reads source code from files containing either: (1) definition modules, (2)
       implementation modules, (3) main body module.  Definition modules usually use the standard
       extension  '.def'.   Whereas,  implementation  and  main  body  modules  use  the standard
       extension '.mod'.  When using legacy code which worked with a  different  compiler,  other
       extensions  may  have  been  used.  GNU Modula-2 can be told to search for those extension
       first , before defaulting to the standard extensions.  For example, use the  command  line
       options: '-fdef=.d2 -fmod=.m2'.

       GNU  Modula-2  imports definition modules by reading the definition module file every time
       (similar to C including .h header files).  Traditional Modula-2  compilers  would  require
       the compilation of every definition module into a symbol file before any import of symbols
       from that definition module.

   Purpose
       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.

   Current State
       Currently GNU Modula-2 (0.49) implements all PIM dialects of the language, eventually  GNU
       Modula-2  will  be  fully  compliant  with  ISO  Modula-2.  It 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.

       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  9.1,  Debian,  stable  and
       unstable) and 32 bit x86 FreeBSD.

       Work is underway to build and test it on DARWIN/i386, and DARWIN/powerpc.

       There  is even a project to extend GNU Modula-2 with object oriented constructs similar to
       Objective-C called 'Objective Modula-2' , or objM2 for short.

OPTIONS

       This section describes the compiler's command  line  options  specific  to  GNU  Modula-2,
       although many of the standard options are documented here.  For details on generic options
       see the manual page for gcc (The GNU C Compiler), and other members of  the  GNU  Compiler
       Collection.

   Overall Options
       --help Print (on the standard output) a description of the command line options understood
              by gm2 If the -v option is also specified then --help will also be passed on to the
              various processes invoked by gm2, so that they can display the command line options
              they accept.  If the -f option is also specified then command  line  options  which
              have no documentation associated with them will also be displayed.

       --target-help
              Print  (on  the  standard  output)  a  description  of target specific command line
              options for each tool.

       --version
              Display the version number and copyrights of the invoked GCC.

       -c     Compile and assemble the source files, but do not link.  The linking  stage  simply
              is  not done.  The ultimate output is in the form of an object file for each source
              file.

       -E     Stop after the preprocessing stage; do not run the compiler proper.  The output  is
              in the form of preprocessed source code, which is sent to the standard output.

       -g     Insert  debugging  symbols into the object files, and executable.  NOTE: When using
              the debugger, it may be useful to not optimize at a high level.

       -Ipath Adds an include path.  The GNU Modula-2  compiler  needs  to  import  symbols  from
              definition  module  files.  It include's the definition file, rather than reading a
              symbol file.

       -On    Set the optimization level and  kind.   -Os  optimizes  for  size  (desiring  small
              executables).   -O,-O1,-O2, ..., -O6 optimize for speed, with increasingly powerful
              techniques, such as loop unrolling and reordering of code.   When  debugging,  only
              use -O or at the most -O1.

       -o file
              Place  output  in file file.  This applies regardless to whatever sort of output is
              being produced, whether it be an executable file,  an  object  file,  an  assembler
              file, or preprocessed C code.

              Since  only one output file can be specified, it does not make sense to use -o when
              compiling more than one input file, unless you are producing an executable file  as
              output.

              If  -o  is  not  specified,  the default is to put an executable file in a.out, the
              object file for source.suffix in source.o, its assembly language file in  source.s,
              and all preprocessed C source on standard output.

       -S     Preprocess  and  compile  the  source code, but to not assemble.  Do not delete the
              temporary assembly language file.  Stop after the stage of compilation  proper;  do
              not assemble.  The output is in the form of an assembly language code file for each
              non-assembler input file specified.

       -v     Verbosely display all calls to subsidiary programs, such as the C preprocessor, the
              GNU  Modula-2  compiler  and  linker.   Also print the version of the compiler, and
              which specs file it is using.

       -fcpp  Preprocess the source with `cpp -lang-asm -traditional-cpp'.  If -fcpp is  supplied
              then  all  definition  modules  and implementation modules which are parsed will be
              preprocessed by `cpp'.

       -fdef= Recognize the specified suffix  as  a  definition  module  filename.   The  default
              definition  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= Recognize the specified suffix as implementation and module filenames.  The default
              implementation  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 implementation
              module  and  the  specified suffixed filename does not exist.  Both this option and
              -fdef= also work with the -fmakeall option.

       -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.

       -fmakeall
              Generate a temporary makefile and build all dependent modules and link.

       -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
              initialization  order  of  all modules which are to be linked. The actual link does
              not occur.  The GNU Modula-2 linker scans  all  IMPORT's  ,  generates  a  list  of
              dependencies  and produces an ordered list for initialization. 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.

       -fsources
              Displays the path to the source of each module.

       -fstatistics
              Generates   quadruple  information:  number  of  quadruples  generated,  number  of
              quadruples remaining after optimization.  Quadruples are the intermediate  language
              used internally by the GNU Modula-2 compiler.

       -fuselist
              Providing  `gm2' has been told to link the program module this option uses the file
              `modulename.lst' for the initialization order of modules.

       -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.

       -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.

   Runtime Checking Options
       -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  Generate code to detect at runtime any attempt to access data through a 'NIL' value
              pointer.

       -fcase Generate code to detect at runtime whether a 'CASE' statement  requires  an  'ELSE'
              clause  when  one  was not specified.  This generates an implicit 'ELSE' for 'CASE'
              statements which do not define one.  It simply prints an error message,  and  exits
              with an error code.

       -fsoft-check-all
              Turns  on  all  runtime checks. This is the same as invoking GNU Modula-2 using the
              command options -fbounds, -freturn, -fnil, -fcase, -frange, ,-findex, -fwholediv

   Style Checking Options
       -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.

   Language Dialect Options
       -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  behavior  of  'DIV'  and  'MOD'
              operators.

       -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 LANGUAGE DIALECTS.)

       -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 behavior of 'DIV' and 'MOD' operators.

       -fpim3 Turn on PIM-3 standard features. Currently this only effects the behavior of  `DIV'
              and `MOD' operators.

       -fpim4 Turn  on PIM-4 standard features. Currently this only effects the behavior of `DIV'
              and `MOD' operators.

       -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.
              NOTE: See the section LANGUAGE DIALECTS for a table describing these results.

   Library Search Path Options
       -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=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.

       -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=min
              Modifies  the  default  library  search  path  so  that  the minimal set of runtime
              libraries are searched before any others.  Useful  if  targetting  a  small  memory
              embedded device.

LANGUAGE 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
       behavior.

       The GNU Modula-2 compiler is based on the language as defined in:

       PIM2   ´Programming in Modula-2´, 2nd Edition,
               Springer Verlag, 1982, 1983 by Niklaus Wirth,

       PIM3   ´Programming in Modula-2´, 3rd Corrected Edition,
               Springer Verlag, 1985 by Niklaus Wirth, and

       PIM4   ´Programming in Modula-2´, 4th Edition,
               Springer Verlag, 1988, by Niklaus Wirth.

       ISO    The   International   Standards  Organization's  ISO/IEC  10514-1:1996  Information
              Technology -- Programming Languages -- Part-1: Modula-2, Base Language

       It also includes ISO M2 features and  GNU  Modula-2  extensions.  Currently  GNU  Modula-2
       (0.49)  implements all PIM dialects of the language, eventually GNU Modula-2 will be fully
       compliant with ISO Modula-2 Base Language.  It supports neither ISO Modula-2 Generics, nor
       ISO Object Oriented 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 aggressively fail  if  a  non
       mutually  exclusive  feature  is  used from another dialect. For example it is possible to
       specify -fpim2 and still utilize 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.

   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  behavior  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  pg24  of  PIM2, pg27 of PIM3, pg29 of PIM4,  and pg201 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.

   The PIM SYSTEM Module
       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.

            DEFINITION MODULE SYSTEM ;

            EXPORT QUALIFIED (* the following are built into the compiler: *)
                             ADDRESS, WORD, BYTE, BITSET, ADR, TSIZE, SIZE ;

            END SYSTEM.

   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, BYTE, WORD, BITSET, ADDRESS,
                             ADDADR, SUBADR, DIFADR, MAKEADR, ADR, ROTATE,
                             SHIFT, CAST, TSIZE,

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

            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; (* 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.
              *)
            *)

            (* 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: INTEGER) ;

            (*
               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: INTEGER) ;

            (*
               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: INTEGER) ;

            (*
               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: INTEGER) ;

            END SYSTEM.

GM2 LANGUAGE EXTENSIONS

       This section introduces the GNU Modula-2 language extensions.

   Abstract Types
       The GNU Modula-2 compiler allows abstract data types to be any type, not  just  restricted
       to a pointer type providing the -fextended-opaque command line option is supplied.

   Declaration Order
       Declarations  can  be  made  in  any order, whether they are types, constants, procedures,
       nested modules or variables.

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

       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”'.

            DEFINITION MODULE FOR "C" libprintf ;

            EXPORT UNQUALIFIED printf ;

            PROCEDURE printf (a: ARRAY OF CHAR; ...) ;

            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.

       The hello world program can be rewritten as:

            MODULE hello ;

            FROM libprintf IMPORT printf ;

            BEGIN
               printf("hello world0)
            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.

   Interfacing 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
       `CARDINAL's `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;

   Special Tokens
       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"

   Preprocessor
       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) ;
            VAR
               r: INTEGER ;
            BEGIN
               r := printf("%s:%d:fatal error, %s, in %s0,
                           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.

   Optional procedure parameter
       GNU Modula-2 allows the last  parameter  to  a  procedure  or  function  parameter  to  be
       optional.  This is achieved by enclosing the last formal parameter within square brackets,
       and providing an initializer (a constant assignment).

       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]);

       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 initializer 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.

   Builtins
       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 MODULE's 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  math
       library.  If  gcc  cannot  utilize  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 ;

            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__ 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__ 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 ;

            END Builtins.

       Although  this  module  exists  and  will  result  in  the  generation  of  inline 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  inlined
       you need to specify the `-ffast-math -O' options.

LIBRARIES

EXAMPLES

       This  section  describes  how  to  compile  and  link  a simple 'hello world' program.  It
       provides a few examples of using the different options mentioned above.

       Assume the file "hello.mod" contains the code:
            MODULE Hello;

            FROM StrIO IMPORT WriteString, WriteLn;

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

       You should be able to compile it by: gm2 -c hello.mod
        and link via: gm2 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.

FILES

ENVIRONMENT

CONFORMING TO

       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.

BUGS

COPYRIGHT

LICENCE

       The GNU Modula-2 compiler and associated software is released under the GNU PUBLIC LICENCE
       (GPL) which should be available in a file named COPYING.

       The  runtime  libraries  (pim, iso, and Logitech Compatable) are released under the LESSER
       GNU PUBLIC LICENCE (LGPL) which allows any user to  link  against  the  runtime  libraries
       without invoking all the clauses of the full GPL.

       The Ulm library is released under the GPL.

AUTHOR

       This  manual page was written (using the documentation from the texinfo files) by Peter P.
       Eiserloh ⟨peter@eiserloh.org

SEE ALSO

       The many fine books about Modula-2.

       The GNU Modula-2 web site at ⟨http://www.nongnu.org/gm2