DefMod
------

   DefMod is the tool for generating all sorts of different files from
module interface files. A module interface file contains enough information
to specify, in a language-independent form, the interface to a RISC O S
module. This can be used to generate suitable files to enable the module to
be called from any high-level language. The whole of OSLib is derived from a
set of modules interface files and these DefMod options:

      -h    produces a C header file defining all the constants as macros,
               all the types as |typedef|s and all the SWI's as function
               prototypes
      -hdr  produces an assembler header file defining all the constants as
               symbols, all the types and structure offsets as
               symbols, and all the SWI's as symbols with comments
      -chelp
            produce a SrcEdit-compatible help file for the C interface
      -o    produce a directory containing ObjAsm source files defining the
               same entry points as the one made by the -s option, but as
               separate files; object files corresponding to them; and a
               text file ViaFile which may be ued as input to LibFile to
               combine them into a library
      -cstrong
            produce a StrongHelp-compatible help file for the C interface
      

For other options, see DefMod -help.

   DefMod can be most useful when used at the start of a project: it can
then be used to specify the whole of the module interface before any of
the module is written. The header files it generates can then be used to
write the module. This means that all the resources used by the module
are defined in one place only: the module interface file will then be
the master for things like SWI numbers, command numbers, error numbers,
structures, and SWI calling conventions.

Module interface files
------ --------- -----

   The format of a module interface file is described completely by the
Grammar which accompanies this document.

   A file consists of a series of declarations. There are 6 different types
of declaration. Each type may occur as many times as necessary. The way in
which commas and semi-colons are used may be a bit confusing: they are
separators, not terminators as in C, so, for example, a CONST section might
be

      CONST
         a = T: 0, 
         b = T: 1, 
         c = T: 2

and there is no comma at the end. If there were multiple sections in a
file, then semi-colons appear between them, but not at the end, like
this:

      CONST section; TYPE section; SWI section; another CONST section

TITLE
-----
   This gives the module a title. It is used to produce a comment in
output, and should always be the same as the module prefix. There can only
be one of these.

AUTHOR
------
   This gives a string which appears in the output, also as a comment. There
can only be one of these.

NEEDS
-----
   Contains the names of other module interfaces on which this one
depends. This does not cause the named module interface file to be read
by DefMod, but typically causes it to emit some kind of include
directive in the output.

CONST
-----
   Contains constant definitions. Constants may be of a built-in type or
one defined in this or another interface file.

TYPE
----
   Defines types. Types are built-in types (Int, Short, Byte, Char,
Bits, Bytes, Bool, String, Asm, Data) or derived types. They are
classified into "register," "non-register fixed-length" and
"non-register variable-length" types. The register types are: Int,
Short, Byte, Char, Bits, Bool, Ref <anything>, and unions of these;
non-register fixed-length types are: arrays, structs containing no
'...', and unions of anything so far; and non-register variable-length
types are: String, Asm, Data, Struct with '...', and unions not so far
mentioned.

   In fact, not all the checking that would be desirable can be done,
since DefMod deals with only one file at a time.

   The reasons for the distinctions are (a) that only register types may
be arguments of SWI calls; (b) special treatment is given to structures
whose last component is a repeating fixed-length element, in the form of
extra macros to deal with objects of those types.

   The built-in types must be provided by the target language. For C,
they are in the file "types.h," included by all headers. 

   Within unions only, the type 'void' is allowed, signifying that the
union may be "empty."

SWI
---
   Contains the registers needed on input, and produced on output, by
each SWI the module defines. For details of how the algorithm for
producing the A P C S veneers works, see APCStoSWI. Registers may be
specified as

      containing a value;
      pointing to a value;
      containing a constant (input only);
      corrupted (output only);
      disjoined with a constant (input only);
      added to a constant (input only).

   The two forms

      Rx = .Ref Thing: thing

('Rx contains a pointer to a "Thing" called "thing"') and

      Rx -> Thing: thing

('Rx points to a "Thing"') are closely related. The difference is one of
intent only: the second form is used when the "thing" must be valid on
input; so the SWI is accepting a value of type 'Thing' as an argument,
represented by a pointer to it ("input" arguments); the first form is
used when the value is not present, but the SWI will fill it in
("output" arguments). (A third form of syntax could be provided for
"update" arguments, but this has not been done.) In C, the first form
generates an ordinary pointer, the second a pointer-to-constant.

Syntax
------
   There is no separate lexical analyser: the grammar goes all the way
to the individual character level (this was only to avoid using two
tools where one would do). A consequence of this is that a "stropping"
convention is needed to keep reserved words grammatically distinct from
user-defined identifiers: since the grammar should be case-insensitive
but case-preserving (at least in the area of SWI names), it was decided
not to use case as the stropping mechanism: instead, reserved words
start with a full stop.

   There are some conventions (metarules, really) used in the grammar:

         'empty' is defined as nothing;

         any non-terminal of the form '<notion>_option' is defined as either
      a '<notion>', or else as absent ('empty');

         a '<notion>_sequence' is a sequence of '<notions>' with no other
      intervening tokens;

         a '<notion>_list' is a sequence of '<notions>' separated (but not
      terminated) by comma tokens;

         a '<notion>_series' is a sequence of '<notions>' separated (but not
      terminated) by semi-colon tokens;

         if '<notion>' is the name of a punctuation mark, it is defined as
      that mark followed by optional white space (which includes comments).

   The start symbol is 'file.'

   There is an example module interface file for ColourPicker.

Other notes
----- -----

   Case in the interface file is important, because it is used to decide
where to break up a name. SWI names must always be specified exactly in
the form used by the system. All symbols should begin with the module
prefix, or Error_, Event_, Message_, Service_, UpCall_ or else should
end in V (for vectors).

   The vector, upcall and service entries are useful for people making
the call, not the client. Even so, they are part of the module interface and
should be in the interface file. 

   A type_defn with no type defines an "abstract type." A struct type
may end with '...,' in which case various extra macros will be
generated.

   A SWI number may be followed with a textual description or with a
star (in which case a description will be made up): the same applies to
a reason code number. This controls the name given to the function.

   One output register may be marked with a pling, in which case the
non-x form will return it as its result.

   Constants may be provided in decimal, hex (& or 0x) or binary (% or
0b) or as a character value of up to 4 characters (e g, "TASK").

   In order to generate correct code, the width of all types used for
output needs to be known. (They must be stored as bytes, because the
output argument supplied might be in an array.) In order to avoid having
to read all 'NEEDS' files, a separate list of byte-wide types may be
provided. All other undefined types will be assumed to be register-wide,
and a warning will be given. For OSLib, the byte-wide file is
      
      Font_F
      OS_Action
      OS_F
      OS_GCOL
      OS_Tint
      Wimp_Colour

There is no support for 2-byte quantities on output.

   We assume that a non-x form will only be called in user mode:
therefore, no attempt is made to save LR over the SWI instruction.

   The output arguments are not written if a SWI fails.

   The case of P S R flags being required on input is not supported. The
only two calls where this is necessary are RemV and CnpV, which are
obsolescent.

   If a call has no output arguments, and exactly one input argument which
is a pointer to an unnamed structure with no '...' part, then the structure
elements are passed in in separate registers. See Wimp_SetIconState for an
example.

   If a SWI call happens also to be A P C S-compliant, it is rendered as
an inline SWI using the __swi() directive provided with C release 5. To
disable this feature for use with earlier compilers requires a header
file (e g, "types.h") containing the lines

      #ifdef  __swi 
      #undef  __swi 
      #define __swi(x) extern 
      #endif

and the -D__swi compiler flag must be provided when using the header
files so generated.
